玉兔远程控制 0.1.0-alpha.2
载入中...
搜索中...
未找到
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("newwork-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 if(!m_Parameter.GetMenuBar())
354 ui->toolBar->insertAction(ui->actionTabBar_B,
355 ui->actionMain_menu_bar_M);
356 }
357
358 slotEnableSystemTrayIcon();
359
360 LoadOperateLasterClose();
361}
362
363MainWindow::~MainWindow()
364{
365 qDebug(log) << "MainWindow::~MainWindow()";
366 if(m_pFullScreenToolBar) m_pFullScreenToolBar->close();
367 delete ui;
368}
369
370void MainWindow::SetView(CView* pView)
371{
372 qDebug(log) << Q_FUNC_INFO;
373 if(!pView)
374 return;
375 if(m_pView)
376 m_pView->disconnect();
377
378 m_pView = pView;
379 setCentralWidget(m_pView);
380
381 bool check = false;
382 //m_pView->setFocusPolicy(Qt::NoFocus);
383 check = connect(m_pView, SIGNAL(sigCloseView(const QWidget*)),
384 this, SLOT(slotCloseView(const QWidget*)));
385 Q_ASSERT(check);
386 check = connect(m_pView, SIGNAL(sigCurrentChanged(const QWidget*)),
387 this, SLOT(slotCurrentViewChanged(const QWidget*)));
388 Q_ASSERT(check);
389 if(m_pFrmActive) {
390 check = connect(m_pView, SIGNAL(sigCurrentChanged(const QWidget*)),
391 m_pFrmActive, SLOT(slotViewChanged(const QWidget*)));
392 Q_ASSERT(check);
393 }
394 check = connect(m_pView, SIGNAL(customContextMenuRequested(const QPoint&)),
395 this, SLOT(slotCustomContextMenuRequested(const QPoint&)));
396 Q_ASSERT(check);
397
398 foreach (auto c, m_Operates) {
399 m_pView->AddView(c->GetViewer());
400 m_pView->SetWidowsTitle(
401 c->GetViewer(), c->Name(), c->Icon(), c->Description());
402 }
403 m_pView->SetVisibleTab(m_Parameter.GetTabBar());
404}
405
406void MainWindow::on_actionViewTab_triggered()
407{
408 qDebug(log) << Q_FUNC_INFO;
409 if(!ui->actionViewTab->isChecked()) return;
410 m_Parameter.SetViewType(CParameterApp::ViewType::Tab);
411 SetView(new CViewTable(&m_Parameter, this));
412}
413
414void MainWindow::on_actionViewSplit_triggered()
415{
416 qDebug(log) << Q_FUNC_INFO;
417 if(!ui->actionViewSplit->isChecked()) return;
418 m_Parameter.SetViewType(CParameterApp::ViewType::Splitter);
419 SetView(new CViewSplitter(&m_Parameter, this));
420}
421
422void MainWindow::on_actionAbout_triggered()
423{
424#ifdef HAVE_ABOUT
425 CDlgAbout *about = new CDlgAbout(this);
426 QIcon icon = QIcon::fromTheme("app");
427 if(!icon.isNull()) {
428 auto sizeList = icon.availableSizes();
429 if(!sizeList.isEmpty()) {
430 QPixmap p = icon.pixmap(*sizeList.begin());
431 about->m_AppIcon = p.toImage();
432 }
433 }
434 about->m_szCopyrightStartTime = "2020";
435 about->m_szVersionRevision = RabbitRemoteControl_REVISION;
436 about->m_szDetails = m_Manager.Details();
437 RC_SHOW_WINDOW(about);
438#endif
439}
440
441void MainWindow::on_actionUpdate_triggered()
442{
443 if(!qEnvironmentVariable("SNAP").isEmpty()) {
444 QDesktopServices::openUrl(QUrl("https://snapcraft.io/rabbitremotecontrol"));
445 } else if(!qEnvironmentVariable("FLATPAK_ID").isEmpty()) {
446 QDesktopServices::openUrl(QUrl("https://flathub.org/apps/io.github.KangLin.RabbitRemoteControl"));
447 } else {
448#ifdef HAVE_UPDATE
449 CFrmUpdater* m_pfrmUpdater = new CFrmUpdater();
450 QIcon icon = QIcon::fromTheme("app");
451 if(!icon.isNull()) {
452 auto sizeList = icon.availableSizes();
453 if(!sizeList.isEmpty()) {
454 QPixmap p = icon.pixmap(*sizeList.begin());
455 m_pfrmUpdater->SetTitle(p.toImage());
456 }
457 }
458 m_pfrmUpdater->SetInstallAutoStartup();
459 RC_SHOW_WINDOW(m_pfrmUpdater);
460#endif
461 }
462}
463
464void MainWindow::on_actionFull_screen_F_triggered()
465{
466 CView* pView = qobject_cast<CView*>(this->centralWidget());
467 if(pView)
468 {
469 pView->SetFullScreen(!isFullScreen());
470 }
471
472 if(isFullScreen())
473 {
474 qDebug(log) << "Exit full screen";
475 ui->actionFull_screen_F->setIcon(QIcon::fromTheme("view-fullscreen"));
476 ui->actionFull_screen_F->setText(tr("Full screen(&F)"));
477 ui->actionFull_screen_F->setToolTip(tr("Full screen"));
478 ui->actionFull_screen_F->setStatusTip(tr("Full screen"));
479 ui->actionFull_screen_F->setWhatsThis(tr("Full screen"));
480
481 ui->toolBar->setVisible(m_FullState.toolBar);
482 ui->statusbar->setVisible(m_FullState.statusbar);
483 ui->menubar->setVisible(m_FullState.menubar);
484
485 m_pDockActive->setVisible(m_FullState.dockListActive);
486 m_pDockListRecent->setVisible(m_FullState.dockListRecent);
487 m_pDockFavorite->setVisible(m_FullState.dockFavorite);
488 // TODO: This is hade code. it is in RabbitCommon
489 QDockWidget* pDockDebugLog = findChild<QDockWidget*>("dockDebugLog");
490 if(pDockDebugLog)
491 {
492 pDockDebugLog->setVisible(m_FullState.dockDebugLog);
493 }
494
495 if(m_pFullScreenToolBar)
496 {
497 // Delete it when the widget is close
498 m_pFullScreenToolBar->close();
499 m_pFullScreenToolBar = nullptr;
500 }
501
502 emit sigShowNormal();
503 this->showNormal();
504 this->activateWindow();
505
506 return;
507 }
508
509 qDebug(log) << "Entry full screen";
510 emit sigFullScreen();
511 //setWindowFlags(Qt::FramelessWindowHint | windowFlags());
512 this->showFullScreen();
513
514 ui->actionFull_screen_F->setIcon(QIcon::fromTheme("view-restore"));
515 ui->actionFull_screen_F->setText(tr("Exit full screen(&E)"));
516 ui->actionFull_screen_F->setToolTip(tr("Exit full screen"));
517 ui->actionFull_screen_F->setStatusTip(tr("Exit full screen"));
518 ui->actionFull_screen_F->setWhatsThis(tr("Exit full screen"));
519
520 m_FullState.toolBar = ui->toolBar->isVisible();
521 ui->toolBar->setVisible(false);
522 m_FullState.statusbar = ui->statusbar->isVisible();
523 ui->statusbar->setVisible(false);
524 m_FullState.menubar = ui->menubar->isVisible();
525 ui->menubar->setVisible(false);
526
527 m_FullState.dockListActive = m_pDockActive->isVisible();
528 m_pDockActive->setVisible(false);
529 m_FullState.dockListRecent = m_pDockListRecent->isVisible();
530 m_pDockListRecent->setVisible(false);
531 m_FullState.dockFavorite = m_pDockFavorite->isVisible();
532 m_pDockFavorite->setVisible(false);
533 // This is hade code. it is in RabbitCommon
534 QDockWidget* pDockDebugLog = findChild<QDockWidget*>("dockDebugLog");
535 if(pDockDebugLog)
536 {
537 m_FullState.dockDebugLog = pDockDebugLog->isVisible();
538 pDockDebugLog->setVisible(false);
539 }
540
541 if(m_pFullScreenToolBar) m_pFullScreenToolBar->close();
542 // Delete it when the widget is close
543 m_pFullScreenToolBar = new CFrmFullScreenToolBar(this);
544 QScreen* pScreen = qApp->primaryScreen();
545 if(pScreen) {
546 QPoint pos(pScreen->geometry().left()
547 + (pScreen->geometry().width()
548 - m_pFullScreenToolBar->frameGeometry().width()) / 2,
549 pScreen->geometry().top());
550 qDebug(log) << "Primary screen geometry:" << pScreen->geometry()
551 << "availableGeometry:" << pScreen->availableGeometry()
552 << pos << mapToGlobal(pos);
553 m_pFullScreenToolBar->move(pos);
554 }
555 bool check = connect(m_pFullScreenToolBar, SIGNAL(sigExitFullScreen()),
556 this, SLOT(on_actionFull_screen_F_triggered()));
557 Q_ASSERT(check);
558 check = connect(m_pFullScreenToolBar, SIGNAL(sigExit()),
559 this, SLOT(on_actionExit_E_triggered()));
560 Q_ASSERT(check);
561 Q_ASSERT(check);
562 check = connect(this, SIGNAL(sigOperateMenuChanged(QAction*)),
563 m_pFullScreenToolBar,
564 SLOT(slotOperateMenuChanged(QAction*)));
565 Q_ASSERT(check);
566
567 m_pFullScreenToolBar->show();
568}
569
570void MainWindow::slotViewerFocusIn(QWidget *pView)
571{
572 COperate* c = qobject_cast<COperate*>(sender());
573 qDebug(log) << Q_FUNC_INFO << "Focus:" << c << pView;
574 if(c && m_pView) {
575 m_pView->SetCurrentView(c->GetViewer());
576 }
577}
578
579void MainWindow::slotOperateChanged(COperate *o)
580{
581 if(o && m_pView) {
582 m_pView->SetCurrentView(o->GetViewer());
583 }
584}
585
586void MainWindow::slotCurrentViewChanged(const QWidget* pView)
587{
588 qDebug(log) << Q_FUNC_INFO;
589 if(m_pView && pView)
590 EnableMenu(true);
591 else
592 EnableMenu(false);
593
594 foreach(auto o, m_Operates) {
595 if(o->GetViewer() == pView) {
596 SetSecureLevel(o);
597 SetStatsVisible(o->GetStats());
598 foreach (auto a, ui->menuActivity->actions()) {
599 if(a->data().value<COperate*>() == o)
600 a->setChecked(true);
601 }
602 }
603 }
604}
605
606void MainWindow::EnableMenu(bool bEnable)
607{
608 qDebug(log) << Q_FUNC_INFO << bEnable;
609 ui->actionClone->setEnabled(bEnable);
610 ui->actionAdd_to_favorite->setEnabled(bEnable);
611 ui->actionStop->setEnabled(bEnable);
612 ui->actionTabBar_B->setEnabled(bEnable);
613 ui->menuActivity->setEnabled(bEnable);
614 m_ptbMenuActivity->setEnabled(bEnable);
615 slotLoadOperateMenu();
616}
617
618void MainWindow::slotMenuActivity()
619{
620 QAction* pAction = qobject_cast<QAction*>(sender());
621 Q_ASSERT(pAction);
622 if(!pAction) return;
623 COperate* p = pAction->data().value<COperate*>();
624 if(p)
625 slotOperateChanged(p);
626}
627
628void MainWindow::slotLoadOperateMenu()
629{
630 qDebug(log) << Q_FUNC_INFO;
631
632 if(m_pActionOperateMenu) {
633 ui->menuOperate->removeAction(m_pActionOperateMenu);
634 m_pActionOperateMenu = nullptr;
635 }
636 ui->toolBar->removeAction(m_pActionTBOperate);
637
638 if(!m_pView)
639 return;
640 auto pWin = m_pView->GetCurrentView();
641 if(!pWin) {
642 qDebug(log) << "The current view is empty";
643 return;
644 }
645 foreach(auto op, m_Operates)
646 {
647 if(op->GetViewer() == pWin)
648 {
649 qDebug(log) << "Load plugin menu";
650 auto m = op->GetMenu(ui->menuTools);
651 if(!m) return;
652 // Menu tool bar
653 m_pActionOperateMenu = ui->menuOperate->insertMenu(ui->actionAdd_to_favorite, m);
654 // ToolBar
655 if(!m_pTBOperate)
656 m_pTBOperate = new QToolButton(ui->toolBar);
657 if(m_pTBOperate) {
658 m_pTBOperate->setFocusPolicy(Qt::NoFocus);
659 m_pTBOperate->setPopupMode(QToolButton::InstantPopup);
660 m_pTBOperate->setMenu(m);
661 m_pTBOperate->setIcon(m->icon());
662 m_pTBOperate->setText(m->title());
663 m_pTBOperate->setToolTip(m->toolTip());
664 m_pTBOperate->setStatusTip(m->statusTip());
665 m_pTBOperate->show();
666 m_pActionTBOperate = ui->toolBar->insertWidget(ui->actionAdd_to_favorite, m_pTBOperate);
667 }
668 emit sigOperateMenuChanged(m_pActionOperateMenu);
669 }
670 }
671}
672
680{
681 if(!m_pView)
682 return;
683 auto pWin = m_pView->GetCurrentView();
684 if(!pWin) {
685 qDebug(log) << "The current view is empty";
686 return;
687 }
688 foreach(auto p, m_Operates)
689 {
690 if(p->GetViewer() == pWin)
691 {
692 qDebug(log) << "Load plugin menu";
693 auto m = p->GetMenu(ui->menuTools);
694 if(!m) return;
695 // Note: The view is converted to global coordinates
696 m->exec(pos);
697 }
698 }
699}
700
701void MainWindow::on_actionExit_E_triggered()
702{
703 close();
704}
705
706void MainWindow::keyReleaseEvent(QKeyEvent *event)
707{
708 switch(event->key())
709 {
710 case Qt::Key_Escape:
711 if(isFullScreen())
712 on_actionFull_screen_F_triggered();
713 break;
714 }
715 QMainWindow::keyReleaseEvent(event);
716}
717
718void MainWindow::slotUpdateParameters(COperate *pOperate)
719{
720 m_Manager.SaveOperate(pOperate);
721}
722
723void MainWindow::on_actionClone_triggered()
724{
725 if(!m_pView) return;
726 QWidget* p = m_pView->GetCurrentView();
727 foreach(auto pOperate, m_Operates)
728 {
729 if(pOperate->GetViewer() == p)
730 {
731 QString szFile = pOperate->GetSettingsFile();
732 auto pOperate = m_Manager.LoadOperate(szFile);
733 if(!pOperate) return;
734 Start(pOperate, false, szFile);
735 return;
736 }
737 }
738}
739
740void MainWindow::slotOpenFile(const QString& szFile, bool bOpenSettings)
741{
742 if(szFile.isEmpty()) return;
743 COperate* p = m_Manager.LoadOperate(szFile);
744 if(nullptr == p)
745 {
746 slotStatusMessage(tr("Load file fail: ") + szFile, MessageLevel::Error);
747 return;
748 }
749
750 Start(p, bOpenSettings, szFile);
751}
752
753void MainWindow::on_actionOpenRRCFile_triggered()
754{
755 QString szFile = QFileDialog::getOpenFileName(
756 this,
757 tr("Open rabbit remote control file"),
758 RabbitCommon::CDir::Instance()->GetDirUserData(),
759 tr("Rabbit remote control Files (*.rrc);;All files(*.*)"));
760 if(szFile.isEmpty()) return;
761
762 COperate* p = m_Manager.LoadOperate(szFile);
763 if(nullptr == p)
764 {
765 slotStatusMessage(tr("Load file fail: ") + szFile, MessageLevel::Error);
766 return;
767 }
768
769 Start(p, true);
770}
771
772void MainWindow::slotStart()
773{
774 if(nullptr == m_pView)
775 {
776 Q_ASSERT(false);
777 return;
778 }
779 QAction* pAction = qobject_cast<QAction*>(this->sender());
780 Q_ASSERT(pAction);
781 COperate* p = m_Manager.CreateOperate(pAction->data().toString());
782 if(nullptr == p) return;
783 Start(p, true);
784}
785
796int MainWindow::Start(COperate *pOperate, bool set, QString szFile)
797{
798 qDebug(log) << "MainWindow::Start: set:" << set << "; File:" << szFile;
799 bool bSave = false; //whether is save configure file
800 Q_ASSERT(pOperate);
801 bool check = connect(pOperate, SIGNAL(sigRunning()),
802 this, SLOT(slotRunning()));
803 Q_ASSERT(check);
804 check = connect(pOperate, SIGNAL(sigStop()),
805 this, SLOT(slotStop()));
806 Q_ASSERT(check);
807 check = connect(pOperate, SIGNAL(sigFinished()),
808 this, SLOT(slotFinished()));
809 Q_ASSERT(check);
810 check = connect(pOperate, SIGNAL(sigError(const int, const QString &)),
811 this, SLOT(slotError(const int, const QString&)));
812 Q_ASSERT(check);
813 check = connect(pOperate, SIGNAL(sigShowMessageBox(const QString&, const QString&,
814 const QMessageBox::Icon&)),
815 this, SLOT(slotShowMessageBox(const QString&, const QString&,
816 const QMessageBox::Icon&)));
817 Q_ASSERT(check);
818 check = connect(pOperate, SIGNAL(sigInformation(const QString&)),
819 this, SLOT(slotInformation(const QString&)));
820 Q_ASSERT(check);
821 check = connect(pOperate, SIGNAL(sigUpdateName(const QString&)),
822 this, SLOT(slotUpdateName(const QString&)));
823 Q_ASSERT(check);
824 check = connect(pOperate, SIGNAL(sigUpdateParameters(COperate*)),
825 this, SLOT(slotUpdateParameters(COperate*)));
826 Q_ASSERT(check);
827
828 if(set)
829 {
830 int nRet = pOperate->OpenDialogSettings(this);
831 switch(nRet)
832 {
833 case QDialog::Rejected:
834 m_Manager.DeleteOperate(pOperate);
835 return 0;
836 case QDialog::Accepted:
837 bSave = true;
838 break;
839 }
840 }
841
842 if(szFile.isEmpty())
843 szFile = pOperate->GetSettingsFile();
844 else
845 pOperate->SetSettingsFile(szFile);
846
847 int nRet = 0;
848 if(bSave)
849 nRet = m_Manager.SaveOperate(pOperate);
850 if(0 == nRet)
851 m_pRecentMenu->addRecentFile(szFile, pOperate->Name());
852
853 if(!pOperate->Name().isEmpty())
854 slotInformation(tr("Starting: ") + pOperate->Name());
855
856 //* Show view. \see: slotRunning()
857 if(-1 < m_Operates.indexOf(pOperate)) {
858 if(m_pView)
859 m_pView->SetCurrentView(pOperate->GetViewer());
860 return 0;
861 }
862 if(m_pView)
863 {
864 m_pView->AddView(pOperate->GetViewer());
865 m_pView->SetWidowsTitle(pOperate->GetViewer(), pOperate->Name(),
866 pOperate->Icon(), pOperate->Description());
867 //qDebug(log) << "View:" << p->GetViewer();
868 check = connect(pOperate, SIGNAL(sigViewerFocusIn(QWidget*)),
869 this, SLOT(slotViewerFocusIn(QWidget*)));
870 Q_ASSERT(check);
871 }
872 m_Operates.push_back(pOperate);
873 StartTimer();
874
875 m_pFrmActive->slotLoad();
876 m_pFrmActive->slotViewChanged(m_pView->GetCurrentView());
877
878 QVariant vOperate;
879 vOperate.setValue(pOperate);
880 QAction* m_pActionmenuActivity = ui->menuActivity->addAction(
881 pOperate->Icon(), pOperate->Name(), this, SLOT(slotMenuActivity()));
882 m_pActionmenuActivity->setData(vOperate);
883 m_pActionmenuActivity->setCheckable(true);
884 m_pMenuActivityGroup->addAction(m_pActionmenuActivity);
885 m_pActionmenuActivity->setChecked(true);
886 //*/
887
888 nRet = pOperate->Start();
889 if(nRet)
890 pOperate->Stop();
891 return nRet;
892}
893
895
899{
900 COperate* p = qobject_cast<COperate*>(sender());
901 if(!p) return;
902
903 /* If you put it here, when running, the view is not displayed.
904 So put it in the Start() display view.
905 See: Start(COperate *p, bool set, QString szFile)
906 */
907 /*
908 if(-1 == m_Operates.indexOf(p)) {
909 m_Operates.push_back(p);
910 if(m_pView)
911 {
912 m_pView->AddView(p->GetViewer());
913 m_pView->SetWidowsTitle(p->GetViewer(), p->Name(), p->Icon(), p->Description());
914 }
915 } else {
916 m_pView->SetCurrentView(p->GetViewer());
917 }
918 //*/
919
920 SetSecureLevel(p);
921
922 auto m = p->GetMenu();
923 m->addSeparator();
924 m->addAction(ui->actionClone);
925
926 slotLoadOperateMenu();
927
928 slotInformation(tr("Connected to ") + p->Name());
929 qDebug(log) << Q_FUNC_INFO << p->Name();
930}
932
933void MainWindow::slotCloseView(const QWidget* pView)
934{
935 qDebug(log) << "MainWindow::slotCloseView" << pView;
936 if(!pView) return;
937 foreach(auto p, m_Operates)
938 {
939 if(p->GetViewer() == pView)
940 {
941 //TODO: Whether to save the setting
942 emit p->sigUpdateParameters(p);
943 p->Stop();
944 }
945 }
946}
947
948void MainWindow::on_actionStop_triggered()
949{
950 qDebug(log) << Q_FUNC_INFO;
951 if(!m_pView) return;
952
953 QWidget* pView = m_pView->GetCurrentView();
954 slotCloseView(pView);
955}
956
957void MainWindow::slotStop()
958{
959 COperate* pOperate = qobject_cast<COperate*>(sender());
960 if(!pOperate) return;
961 qDebug(log) << Q_FUNC_INFO << pOperate->Name();
962 //TODO: Whether to save the setting
963 emit pOperate->sigUpdateParameters(pOperate);
964 pOperate->Stop();
965}
966
967void MainWindow::slotFinished()
968{
969 COperate* pOperate = qobject_cast<COperate*>(sender());
970 if(!pOperate) return;
971
972 qDebug(log) << Q_FUNC_INFO << pOperate->Name();
973 foreach(auto a, ui->menuActivity->actions()) {
974 COperate* o = a->data().value<COperate*>();
975 if(o == pOperate) {
976 ui->menuActivity->removeAction(a);
977 m_pMenuActivityGroup->removeAction(a);
978 }
979 }
980 foreach(auto p, m_Operates)
981 {
982 if(p == pOperate)
983 {
984 m_pView->RemoveView(p->GetViewer());
985 m_Operates.removeAll(p);
986 m_Manager.DeleteOperate(p);
987 m_pFrmActive->slotLoad();
988 m_pFrmActive->slotViewChanged(m_pView->GetCurrentView());
989 break;
990 }
991 }
992 if(m_Operates.isEmpty())
993 if(m_pActionOperateMenu) {
994 ui->menuTools->removeAction(m_pActionOperateMenu);
995 ui->toolBar->removeAction(m_pActionOperateMenu);
996 m_pActionOperateMenu = nullptr;
997 }
998
999 StartTimer();
1000}
1001
1002// 该函数将label控件变成一个圆形指示灯,需要指定颜色color以及直径size
1003// size 单位是像素
1004void SetIndicator(QLabel* label, QColor color, int size)
1005{
1006 QString min_width = QString("min-width: %1px;").arg(size); // 最小宽度:size
1007 QString min_height = QString("min-height: %1px;").arg(size); // 最小高度:size
1008 QString max_width = QString("max-width: %1px;").arg(size); // 最小宽度:size
1009 QString max_height = QString("max-height: %1px;").arg(size); // 最小高度:size
1010 // 再设置边界形状及边框
1011 QString border_radius = QString("border-radius: %1px;").arg(size / 2); // 边框是圆角,半径为size/2
1012 QString border = QString("border:1px solid ") + color.name() + ";"; // 边框为1px
1013 // 最后设置背景颜色
1014 QString background = "background-color: ";
1015 background += color.name() + ";";
1016 QString SheetStyle = min_width + min_height + max_width + max_height + border_radius + border + background;
1017 label->setStyleSheet(SheetStyle);
1018}
1019
1020void MainWindow::SetSecureLevel(COperate* o)
1021{
1022 if(!m_pSecureLevel) return;
1023 if(o) {
1024 if(COperate::SecurityLevel::No == o->GetSecurityLevel())
1025 {
1026 m_pSecureLevel->hide();
1027 return;
1028 }
1029 SetIndicator(m_pSecureLevel, o->GetSecurityLevelColor(), statusBar()->height() / 2);
1030 m_pSecureLevel->setToolTip(o->GetSecurityLevelString());
1031 m_pSecureLevel->setStatusTip(o->GetSecurityLevelString());
1032 m_pSecureLevel->show();
1033 } else
1034 m_pSecureLevel->hide();
1035}
1036
1037void MainWindow::slotSignalConnected()
1038{
1039 m_pSignalStatus->setToolTip(tr("ICE signal status: Connected"));
1040 m_pSignalStatus->setStatusTip(m_pSignalStatus->toolTip());
1041 m_pSignalStatus->setWhatsThis(m_pSignalStatus->toolTip());
1042 //m_pSignalStatus->setText(tr("Connected"));
1043 m_pSignalStatus->setIcon(QIcon::fromTheme("newwork-wired"));
1044}
1045
1046void MainWindow::slotSignalDisconnected()
1047{
1048 m_pSignalStatus->setToolTip(tr("ICE signal status: Disconnected"));
1049 m_pSignalStatus->setStatusTip(m_pSignalStatus->toolTip());
1050 m_pSignalStatus->setWhatsThis(m_pSignalStatus->toolTip());
1051 //m_pSignalStatus->setText(tr("Disconnected"));
1052 m_pSignalStatus->setIcon(QIcon::fromTheme("network-wireless"));
1053}
1054
1055void MainWindow::slotSignalError(const int nError, const QString &szInfo)
1056{
1057 slotSignalDisconnected();
1058 slotError(nError, szInfo);
1059}
1060
1061void MainWindow::slotSignalPushButtonClicked(bool checked)
1062{
1063#ifdef HAVE_ICE
1064 if(checked)
1065 CICE::Instance()->slotStart();
1066 else
1067 CICE::Instance()->slotStop();
1068#endif
1069}
1070
1071void MainWindow::slotError(const int nError, const QString &szInfo)
1072{
1073 Q_UNUSED(nError);
1074 slotStatusMessage(szInfo, MessageLevel::Error);
1075}
1076
1078 const QString &title, const QString &message,
1079 const QMessageBox::Icon &icon)
1080{
1081 slotInformation(message);
1082 if(!m_Parameter.GetMessageBoxDisplayInformation())
1083 return;
1084
1085 QMessageBox msg(icon, title, message, QMessageBox::Ok, this);
1086 QCheckBox* cb = new QCheckBox(
1087 tr("Use message box to display information"), this);
1088 cb->setChecked(true);
1089 msg.setCheckBox(cb);
1090 RC_SHOW_WINDOW(&msg);
1091 if(!cb->isChecked())
1092 {
1093 m_Parameter.SetMessageBoxDisplayInformation(false);
1094 m_Parameter.Save();
1095 }
1096}
1097
1098void MainWindow::slotInformation(const QString& szInfo)
1099{
1100 slotStatusMessage(szInfo, MessageLevel::Normal);
1101}
1102
1103void MainWindow::slotStatusMessage(QString szMessage, MessageLevel level)
1104{
1105 QPalette pe;
1106 switch ((MessageLevel)level) {
1107 case MessageLevel::Error:
1108 pe.setColor(QPalette::WindowText, Qt::red);
1109 break;
1110 case MessageLevel::Warning:
1111 pe.setColor(QPalette::WindowText, Qt::yellow);
1112 break;
1113 default:
1114 break;
1115 }
1116
1117 m_StatusBarMessage.setPalette(pe);
1118 m_StatusBarMessage.setToolTip(szMessage);
1119 QFontMetrics metrics(m_StatusBarMessage.font());
1120
1121 szMessage = metrics.elidedText(szMessage, Qt::ElideRight, m_StatusBarMessage.width());
1122
1123 m_StatusBarMessage.setText(szMessage);
1124}
1125
1126void MainWindow::slotUpdateName()
1127{
1128 foreach (auto p, m_Operates)
1129 {
1130 m_pView->SetWidowsTitle(p->GetViewer(),
1131 p->Name(),
1132 p->Icon(),
1133 p->Description());
1134 }
1135}
1136
1137void MainWindow::slotUpdateName(const QString& szName)
1138{
1139 COperate* p = qobject_cast<COperate*>(sender());
1140 if(!p) return;
1141 m_pView->SetWidowsTitle(p->GetViewer(), szName,
1142 p->Icon(), p->Description());
1143 foreach(auto a, ui->menuActivity->actions()) {
1144 if(a->data().value<COperate*>() == p) {
1145 a->setText(szName);
1146 break;
1147 }
1148 }
1149}
1150
1151QAction* MainWindow::GetStartAction(QMenu* pMenu, CPlugin *pPlug)
1152{
1153 QString szTitle;
1154 if(!pPlug->Protocol().isEmpty())
1155 szTitle = pPlug->Protocol() + ": ";
1156 szTitle += pPlug->DisplayName();
1157 QAction* p = pMenu->addAction(szTitle);
1158 p->setToolTip(pPlug->Description());
1159 p->setStatusTip(pPlug->Description());
1160 p->setData(pPlug->Id());
1161 p->setIcon(pPlug->Icon());
1162 return p;
1163}
1164
1165void MainWindow::slotStartByType()
1166{
1167 qDebug(log) << Q_FUNC_INFO;
1168 auto m = ui->menuStart->actions();
1169 foreach(auto a, m) {
1170 a->deleteLater();
1171 }
1172 foreach (auto a, m_MenuStartByType) {
1173 a->deleteLater();
1174 }
1175 ui->menuStart->clear();
1176 m_MenuStartByType.clear();
1177 m_Manager.EnumPlugins(this);
1178}
1179
1180int MainWindow::onProcess(const QString &id, CPlugin *pPlugin)
1181{
1182 Q_UNUSED(id);
1183 QMenu* m = ui->menuStart;
1184 if(m_Parameter.GetStartByType()) {
1185 auto it = m_MenuStartByType.find(pPlugin->Type());
1186 if(it == m_MenuStartByType.end()) {
1187 m = new QMenu(pPlugin->TypeName(pPlugin->Type()), ui->menuStart);
1188 m_MenuStartByType[pPlugin->Type()] = m;
1189 ui->menuStart->addMenu(m);
1190 } else
1191 m = *it;
1192 }
1193 // Start menu and toolbar
1194 QAction* p = GetStartAction(m, pPlugin);
1195 bool check = false;
1196 check = connect(p, SIGNAL(triggered()), this, SLOT(slotStart()));
1197 Q_ASSERT(check);
1198 return 0;
1199}
1200
1201void MainWindow::closeEvent(QCloseEvent *event)
1202{
1203 qDebug(log) << "MainWindow::closeEvent()";
1204
1205 if(m_Parameter.GetSaveMainWindowStatus())
1206 if(isFullScreen())
1207 on_actionFull_screen_F_triggered();
1208
1209 SaveOperateLasterClose();
1210
1211 foreach (auto it, m_Operates)
1212 {
1213 //TODO: Whether to save the setting
1214 emit it->sigUpdateParameters(it);
1215 it->Stop();
1216 }
1217
1218 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
1219 QSettings::IniFormat);
1220 if(m_Parameter.GetSaveMainWindowStatus())
1221 {
1222 set.setValue("MainWindow/Status/Geometry", saveGeometry());
1223 set.setValue("MainWindow/Status/State", saveState());
1224
1225 m_Parameter.SetTabBar(ui->actionTabBar_B->isChecked());
1226 m_Parameter.SetMenuBar(menuBar()->isVisible());
1227 m_Parameter.SetStatusBar(statusBar()->isVisible());
1228 } else {
1229 set.remove("MainWindow/Status/Geometry");
1230 set.remove("MainWindow/Status/State");
1231 }
1232
1233 m_Manager.SaveSettings();
1234 m_Parameter.Save();
1235
1236 QMainWindow::closeEvent(event);
1237
1238 //TODO: Wait for the background thread to exit
1239 QThread::sleep(1);
1240}
1241
1242int MainWindow::LoadOperateLasterClose()
1243{
1244 if(!m_Parameter.GetOpenLasterClose())
1245 return 0;
1246
1247 QFile f(RabbitCommon::CDir::Instance()->GetDirUserConfig()
1248 + QDir::separator() + "LasterClose.dat");
1249 if(f.open(QFile::ReadOnly))
1250 {
1251 QDataStream d(&f);
1252 while(1){
1253 QString szFile;
1254 d >> szFile;
1255 if(szFile.isEmpty())
1256 break;
1257 slotOpenFile(szFile);
1258 }
1259 f.close();
1260 }
1261 return 0;
1262}
1263
1264int MainWindow::SaveOperateLasterClose()
1265{
1266 QFile f(RabbitCommon::CDir::Instance()->GetDirUserConfig()
1267 + QDir::separator() + "LasterClose.dat");
1268 f.open(QFile::WriteOnly);
1269 if(m_Parameter.GetOpenLasterClose())
1270 {
1271 QDataStream d(&f);
1272 foreach(auto it, m_Operates)
1273 {
1274 d << it->GetSettingsFile();
1275 }
1276 }
1277 f.close();
1278 return 0;
1279}
1280
1281void MainWindow::on_actionTabBar_B_toggled(bool bShow)
1282{
1283 if(m_pView)
1284 {
1285 m_pView->SetVisibleTab(bShow);
1286 m_Parameter.SetTabBar(bShow);
1287 } else {
1288 if(m_pDockActive)
1289 m_pDockActive->setVisible(bShow);
1290 }
1291}
1292
1293void MainWindow::on_actionMain_menu_bar_M_toggled(bool checked)
1294{
1295 qDebug(log) << Q_FUNC_INFO << checked;
1296 if(ui->toolBar->isHidden() && !checked)
1297 {
1298 if( QMessageBox::StandardButton::Yes
1299 == QMessageBox::information(this, tr("Hide menu bar"),
1300 tr("The menu bar will be hidden, the tool bar must be showed."),
1301 QMessageBox::StandardButton::Yes
1302 | QMessageBox::StandardButton::No))
1303 {
1304 ui->actionToolBar_T->setChecked(true);
1305 } else {
1306 ui->actionMain_menu_bar_M->setChecked(true);
1307 return;
1308 }
1309 }
1310
1311 menuBar()->setVisible(checked);
1312 m_Parameter.SetMenuBar(checked);
1313 if(checked)
1314 {
1315 ui->toolBar->removeAction(ui->actionMain_menu_bar_M);
1316 }
1317 else
1318 {
1319 ui->toolBar->insertAction(ui->actionTabBar_B,
1320 ui->actionMain_menu_bar_M);
1321 }
1322}
1323
1324void MainWindow::on_actionToolBar_T_toggled(bool checked)
1325{
1326 qDebug(log) << Q_FUNC_INFO << checked;
1327 if(menuBar()->isHidden() && !checked)
1328 {
1329 if( QMessageBox::StandardButton::Yes
1330 == QMessageBox::information(this, tr("Hide tool bar"),
1331 tr("The tool bar will be hidden, the menu bar must be showed."),
1332 QMessageBox::StandardButton::Yes
1333 | QMessageBox::StandardButton::No))
1334 {
1335 ui->actionMain_menu_bar_M->setChecked(true);
1336 } else {
1337 ui->actionToolBar_T->setChecked(true);
1338 return;
1339 }
1340 }
1341 ui->toolBar->setVisible(checked);
1342}
1343
1344void MainWindow::on_actionStatus_bar_S_toggled(bool checked)
1345{
1346 statusBar()->setVisible(checked);
1347 m_Parameter.SetStatusBar(checked);
1348}
1349
1350// [Get the widget that settings client parameters]
1351void MainWindow::on_actionSettings_triggered()
1352{
1353 CParameterDlgSettings set(&m_Parameter, m_Manager.GetSettingsWidgets(this), this);
1354 if(CParameterDlgSettings::Accepted == RC_SHOW_WINDOW(&set))
1355 {
1356 m_Manager.SaveSettings();
1357 m_Parameter.Save();
1358 }
1359}
1360// [Get the widget that settings client parameters]
1361
1362void MainWindow::slotShortCut()
1363{
1364 if(m_Parameter.GetReceiveShortCut())
1365 {
1366 setFocusPolicy(Qt::WheelFocus);
1367#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
1368 ui->actionFull_screen_F->setShortcut(
1369 QKeySequence(QKeyCombination(Qt::CTRL, Qt::Key_R),
1370 QKeyCombination(Qt::Key_F)));
1371 ui->actionScreenshot->setShortcut(
1372 QKeySequence(QKeyCombination(Qt::CTRL, Qt::Key_R),
1373 QKeyCombination(Qt::Key_S)));
1374#else
1375 ui->actionFull_screen_F->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_R, Qt::Key_F));
1376 ui->actionScreenshot->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_R, Qt::Key_S));
1377#endif
1378 } else {
1379 setFocusPolicy(Qt::NoFocus);
1380 ui->actionFull_screen_F->setShortcut(QKeySequence());
1381 ui->actionScreenshot->setShortcut(QKeySequence());
1382 }
1383}
1384
1385void MainWindow::on_actionOpenListRecent_triggered()
1386{
1387 CFrmListRecent* p = new CFrmListRecent(this, &m_Manager, m_Parameter, false);
1388 if(!p) return;
1389 bool check = connect(p, SIGNAL(sigStart(const QString&, bool)),
1390 this, SLOT(slotOpenFile(const QString&, bool)));
1391 Q_ASSERT(check);
1392 check = connect(p, SIGNAL(sigAddToFavorite(QString,QString,QIcon,QString)),
1393 m_pFavoriteView, SLOT(slotAddToFavorite(QString,QString,QIcon,QString)));
1394 Q_ASSERT(check);
1395
1396 QDialog d;
1397 d.resize(540, 400);
1398 d.setWindowIcon(windowIcon());
1399 d.setWindowTitle(p->windowTitle());
1400 QGridLayout* pLayout = new QGridLayout(&d);
1401 if(pLayout){
1402 pLayout->addWidget(p);
1403 check = connect(p, SIGNAL(destroyed()), &d, SLOT(reject()));
1404 d.setLayout(pLayout);
1405 }
1406 RC_SHOW_WINDOW(&d);
1407}
1408
1409void MainWindow::on_actionAdd_to_favorite_triggered()
1410{
1411 if(!m_pView || !m_pFavoriteView) return;
1412 QWidget* p = m_pView->GetCurrentView();
1413 foreach(auto c, m_Operates)
1414 {
1415 if(c->GetViewer() == p)
1416 {
1417 m_pFavoriteView->slotAddToFavorite(c->Name(), c->Description(),
1418 c->Icon(), c->GetSettingsFile());
1419 }
1420 }
1421}
1422
1423void MainWindow::dragEnterEvent(QDragEnterEvent *event)
1424{
1425 qDebug(log) << "dragEnterEvent";
1426
1427 if(event->mimeData()->hasUrls())
1428 {
1429 qWarning(log) << event->mimeData()->urls();
1430 event->acceptProposedAction();
1431 }
1432}
1433
1434void MainWindow::dragMoveEvent(QDragMoveEvent *event)
1435{
1436 //qDebug(log) << "dragMoveEvent";
1437}
1438
1439void MainWindow::dropEvent(QDropEvent *event)
1440{
1441 qDebug(log) << "dropEvent";
1442 if(!event->mimeData()->hasUrls())
1443 return;
1444 auto urls = event->mimeData()->urls();
1445 foreach(auto url, urls)
1446 {
1447 if(url.isLocalFile())
1448 slotOpenFile(url.toLocalFile());
1449 }
1450}
1451
1452void MainWindow::slotSystemTrayIconActivated(QSystemTrayIcon::ActivationReason reason)
1453{
1454 //qDebug(log) << "MainWindow::slotSystemTrayIconActivated";
1455
1456 Q_UNUSED(reason)
1457#if defined(Q_OS_ANDROID)
1458 showMaximized();
1459#else
1460 switch(reason)
1461 {
1462 case QSystemTrayIcon::Trigger:
1463 {
1464 showNormal();
1465 activateWindow();
1466 break;
1467 }
1468 default:
1469 break;
1470 }
1471#endif
1472}
1473
1474void MainWindow::slotSystemTrayIconTypeChanged()
1475{
1476 //qDebug(log) << "MainWindow::slotSystemTrayIconTypeChanged:" << m_Parameter.GetEnableSystemTrayIcon();
1477 if(!QSystemTrayIcon::isSystemTrayAvailable())
1478 {
1479 qWarning(log) << "System tray is not available";
1480 return;
1481 }
1482
1483 if(!m_Parameter.GetEnableSystemTrayIcon())
1484 {
1485 qDebug(log) << "Disable system tray icon";
1486 return;
1487 }
1488
1489 if(m_TrayIcon)
1490 m_TrayIcon.reset();
1491
1492 m_TrayIcon = QSharedPointer<QSystemTrayIcon>(new QSystemTrayIcon(this));
1493 if(QSystemTrayIcon::isSystemTrayAvailable())
1494 {
1495 bool check = connect(
1496 m_TrayIcon.data(),
1497 SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
1498 this,
1499 SLOT(slotSystemTrayIconActivated(QSystemTrayIcon::ActivationReason)));
1500 Q_ASSERT(check);
1501 m_TrayIcon->setIcon(this->windowIcon());
1502 m_TrayIcon->setToolTip(windowTitle());
1503 m_TrayIcon->show();
1504 } else
1505 qWarning(log) << "System tray is not available";
1506
1507 switch (m_Parameter.GetSystemTrayIconMenuType())
1508 {
1509 case CParameterApp::SystemTrayIconMenuType::MenuBar:
1510 {
1511 QMenu* pMenu = new QMenu(this);
1512 pMenu->addMenu(ui->menuOperate);
1513 pMenu->addMenu(ui->menuView);
1514 pMenu->addMenu(ui->menuTools);
1515 m_TrayIcon->setContextMenu(pMenu);
1516 break;
1517 }
1518 case CParameterApp::SystemTrayIconMenuType::Operate:
1519 m_TrayIcon->setContextMenu(ui->menuOperate);
1520 break;
1521 case CParameterApp::SystemTrayIconMenuType::RecentOpen:
1522 m_TrayIcon->setContextMenu(m_pRecentMenu);
1523 break;
1524 case CParameterApp::SystemTrayIconMenuType::View:
1525 m_TrayIcon->setContextMenu(ui->menuView);
1526 break;
1527 case CParameterApp::SystemTrayIconMenuType::Tools:
1528 m_TrayIcon->setContextMenu(ui->menuTools);
1529 break;
1530 case CParameterApp::SystemTrayIconMenuType::No:
1531 m_TrayIcon->setContextMenu(nullptr);
1532 break;
1533 }
1534}
1535
1536void MainWindow::slotEnableSystemTrayIcon()
1537{
1538 //qDebug(log) << "MainWindow::slotEnableSystemTryIcon()";
1539 if(m_TrayIcon)
1540 {
1541 if(!m_Parameter.GetEnableSystemTrayIcon())
1542 m_TrayIcon.reset();
1543 } else
1544 slotSystemTrayIconTypeChanged();
1545}
1546
1547void MainWindow::slotTimeOut()
1548{
1549 auto pWin = m_pView->GetCurrentView();
1550 if(!pWin) {
1551 qDebug(log) << "The current view is empty";
1552 return;
1553 }
1554 foreach(auto p, m_Operates)
1555 {
1556 if(p->GetViewer() == pWin)
1557 {
1558 auto pStats = p->GetStats();
1559 if(!pStats) {
1560 SetStatsVisible(false);
1561 break;
1562 }
1563 SetStatsVisible(true);
1564 pStats->slotCalculating();
1565 m_TotalSends.setText("⇈ " + pStats->TotalSends());
1566 m_TotalReceives.setText("⇊ " + pStats->TotalReceives());
1567 m_SendRate.setText("↑ " + pStats->SendRate());
1568 m_ReceivesRate.setText("↓ " + pStats->ReceiveRate());
1569 break;
1570 }
1571 }
1572}
1573
1574void MainWindow::SetStatsVisible(bool visible)
1575{
1576 if(m_SendRate.isVisible() == visible)
1577 return;
1578 m_SendRate.setVisible(visible);
1579 m_ReceivesRate.setVisible(visible);
1580 m_TotalSends.setVisible(visible);
1581 m_TotalReceives.setVisible(visible);
1582}
1583
1584void MainWindow::StartTimer()
1585{
1586 bool bStart = false;
1587 int nMinInterval = 60;
1588 foreach(auto o, m_Operates) {
1589 if(o && o->GetStats()) {
1590 nMinInterval = qMin(nMinInterval, o->GetStats()->GetInterval());
1591 bStart = true;
1592 }
1593 }
1594 if(bStart)
1595 m_Timer.start(1000);
1596 else
1597 m_Timer.stop();
1598}
列出存在的连接配置
static CICE * Instance()
Single instance
Definition Ice.cpp:55
virtual QList< QWidget * > GetSettingsWidgets(QWidget *parent)
得到设置参数窗口
Definition Manager.cpp:383
virtual int EnumPlugins(Handle *handle)
Enum plugins
Definition Manager.cpp:409
virtual COperate * CreateOperate(const QString &id)
新建 COperate 指针,所有者是调用者。 当不在使用时,调用者必调用 DeteleOperate() 须释放指针。 调用者必须连接信号 COperate::sigFinished 。 释放指针 (...
Definition Manager.cpp:207
virtual COperate * LoadOperate(const QString &szFile)
从文件中新建 COperate 指针,所有者是调用者。 当不再使用时,调用者必须负责调用 DeleteOperate() 删除此指针。 调用者必须连接信号 COperate::sigFinished 。...
Definition Manager.cpp:268
virtual int DeleteOperate(COperate *p)
Delete COperate
Definition Manager.cpp:235
virtual int SaveOperate(COperate *pOperate)
保存连接参数到文件
Definition Manager.cpp:307
virtual int SaveSettings(const QString szFile=QString())
保存客户端参数到文件
Definition Manager.cpp:369
操作接口。
Definition Operate.h:51
virtual int OpenDialogSettings(QWidget *parent=nullptr)
打开设置对话框
Definition Operate.cpp:87
virtual const QIcon Icon() const
Icon
Definition Operate.cpp:82
virtual int Start()=0
开始
virtual QWidget * GetViewer()=0
得到显示视图
virtual const QString Name()
Name
Definition Operate.cpp:41
virtual int Stop()=0
关闭
virtual const QString Description()
Description
Definition Operate.cpp:46
void sigUpdateParameters(COperate *pOperate)
更新参数,通知应用程序保存或显示参数
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
插件接口
Definition Plugin.h:15
virtual const QString Id()
标识。默认: Type() + ":" + Protocol() + ":" + Name()
Definition Plugin.cpp:68
virtual const QString DisplayName() const
在界面上显示的名称
Definition Plugin.cpp:73
virtual const QString Protocol() const =0
协议
virtual const QString Description() const =0
描述
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)
显示信息。暂时在状态栏显示。
virtual void slotShowMessageBox(const QString &title, const QString &message, const QMessageBox::Icon &icon)
用消息对话框(QMessageBox)显示信息
void slotRunning()
[MainWindow slotRunning]
void slotCloseView(const QWidget *pView)
[MainWindow slotRunning]
void slotCustomContextMenuRequested(const QPoint &pos)
MainWindow::slotCustomContextMenuRequested