Rabbit Remote Control 0.0.30
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 "Connecter.h"
19#include "FrmFullScreenToolBar.h"
20#include "ParameterDlgSettings.h"
21#include "FrmListConnects.h"
22
23#ifdef HAVE_ICE
24#include "Ice.h"
25#endif
26
27#include <QGridLayout>
28#include <QMessageBox>
29#include <QCheckBox>
30#include <QScreen>
31#include <QApplication>
32#include <QDebug>
33#include <QDesktopServices>
34#include <QWidgetAction>
35#include <QMouseEvent>
36#include <QDrag>
37#include <QMimeData>
38#include <QKeySequence>
39#include <QPushButton>
40#include <QDateTime>
41#include <QFileDialog>
42#include <QLoggingCategory>
43#include <QThread>
44
45static Q_LOGGING_CATEGORY(log, "App.MainWindow")
46static Q_LOGGING_CATEGORY(logRecord, "App.MainWindow.Record")
47
48MainWindow::MainWindow(QWidget *parent)
49 : QMainWindow(parent),
50 m_pActionConnecterMenu(nullptr),
51 m_pDockListConnects(nullptr),
52 m_pSignalStatus(nullptr),
53 ui(new Ui::MainWindow),
54 m_pView(nullptr),
55 m_pFullScreenToolBar(nullptr),
56 m_pRecentMenu(nullptr),
57 m_pDockFavorite(nullptr),
58 m_pFavoriteView(nullptr)
59{
60 bool check = false;
61
62 ui->setupUi(this);
63
64 setFocusPolicy(Qt::NoFocus);
65 //addToolBar(Qt::LeftToolBarArea, ui->toolBar);
66 setAcceptDrops(true);
67
68 m_pDockFavorite = new QDockWidget(this);
69 if(m_pDockFavorite)
70 {
71 m_pFavoriteView = new CFavoriteView(m_pDockFavorite);
72 if(m_pFavoriteView)
73 {
74 m_pDockFavorite->setTitleBarWidget(m_pFavoriteView->m_pDockTitleBar);
75 check = connect(m_pFavoriteView, SIGNAL(sigConnect(const QString&, bool)),
76 this, SLOT(slotOpenFile(const QString&, bool)));
77 Q_ASSERT(check);
78 check = connect(m_pFavoriteView, SIGNAL(sigFavorite()),
79 this, SLOT(on_actionAdd_to_favorite_triggered()));
80 Q_ASSERT(check);
81 check = connect(&m_Parameter, SIGNAL(sigFavoriteEditChanged(bool)),
82 m_pFavoriteView, SLOT(slotDoubleEditNode(bool)));
83 Q_ASSERT(check);
84 m_pDockFavorite->setWidget(m_pFavoriteView);
85 m_pDockFavorite->setWindowTitle(m_pFavoriteView->windowTitle());
86 }
87 // Must set ObjectName then restore it. See: saveState help document
88 m_pDockFavorite->setObjectName("dockFavorite");
89 //m_pDockFavorite->hide();
90 ui->menuView->addAction(m_pDockFavorite->toggleViewAction());
91 addDockWidget(Qt::DockWidgetArea::LeftDockWidgetArea, m_pDockFavorite);
92 }
93
94 m_pDockListConnects = new QDockWidget(this);
95 if(m_pDockListConnects)
96 {
97 CFrmListConnects* pListConnects = new CFrmListConnects(&m_Client, true, m_pDockListConnects);
98 if(pListConnects) {
99 if(pListConnects->m_pDockTitleBar)
100 m_pDockListConnects->setTitleBarWidget(pListConnects->m_pDockTitleBar);
101 check = connect(pListConnects, SIGNAL(sigConnect(const QString&, bool)),
102 this, SLOT(slotOpenFile(const QString&, bool)));
103 Q_ASSERT(check);
104 m_pDockListConnects->setWidget(pListConnects);
105 m_pDockListConnects->setWindowTitle(pListConnects->windowTitle());
106 }
107 // Must set ObjectName then restore it. See: saveState help document
108 m_pDockListConnects->setObjectName("dockListConnects");
109 //m_pDockListConnects->hide();
110 ui->menuView->addAction(m_pDockListConnects->toggleViewAction());
111 tabifyDockWidget(m_pDockFavorite, m_pDockListConnects);
112 }
113
114 RabbitCommon::CTools::AddStyleMenu(ui->menuTools);
115 ui->menuTools->addMenu(RabbitCommon::CTools::GetLogMenu(this));
116
117 m_pRecentMenu = new RabbitCommon::CRecentMenu(tr("Recently connected"),
118 QIcon::fromTheme("document-open-recent"),
119 this);
120 check = connect(m_pRecentMenu, SIGNAL(recentFileTriggered(const QString&)),
121 this, SLOT(slotOpenFile(const QString&)));
122 Q_ASSERT(check);
123 check = connect(&m_Parameter, SIGNAL(sigRecentMenuMaxCountChanged(int)),
124 m_pRecentMenu, SLOT(setMaxCount(int)));
125 Q_ASSERT(check);
126 QAction* pRecentAction = ui->menuRemote->insertMenu(
127 ui->actionOpenListConnections, m_pRecentMenu);
128 pRecentAction->setStatusTip(pRecentAction->text());
129 QToolButton* tbRecent = new QToolButton(ui->toolBar);
130 tbRecent->setFocusPolicy(Qt::NoFocus);
131 tbRecent->setPopupMode(QToolButton::InstantPopup);
132 tbRecent->setMenu(m_pRecentMenu);
133 tbRecent->setIcon(pRecentAction->icon());
134 tbRecent->setText(pRecentAction->text());
135 tbRecent->setToolTip(pRecentAction->toolTip());
136 tbRecent->setStatusTip(pRecentAction->statusTip());
137 ui->toolBar->insertWidget(ui->actionOpenListConnections, tbRecent);
138
139#ifdef HAVE_UPDATE
140 CFrmUpdater updater;
141 ui->actionUpdate->setIcon(updater.windowIcon());
142#endif
143
144 QToolButton* tbConnect = new QToolButton(ui->toolBar);
145 tbConnect->setFocusPolicy(Qt::NoFocus);
146 tbConnect->setPopupMode(QToolButton::InstantPopup);
147 //tbConnect->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
148 tbConnect->setMenu(ui->menuConnect_C);
149 tbConnect->setIcon(QIcon::fromTheme("network-wired"));
150 tbConnect->setText(tr("Connect"));
151 tbConnect->setToolTip(tr("Connect"));
152 tbConnect->setStatusTip(tr("Connect"));
153 m_pActionConnect = ui->toolBar->insertWidget(ui->actionDisconnect_D, tbConnect);
154
155 EnableMenu(false);
156
157 //TODO: Change view
158 m_pView = new CViewTable(this);
159 if(m_pView)
160 {
161 m_pView->setFocusPolicy(Qt::NoFocus);
162 check = connect(m_pView, SIGNAL(sigCloseView(const QWidget*)),
163 this, SLOT(slotCloseView(const QWidget*)));
164 Q_ASSERT(check);
165
166 check = connect(m_pView, SIGNAL(sigCurrentChanged(const QWidget*)),
167 this, SLOT(slotCurrentViewChanged(const QWidget*)));
168 Q_ASSERT(check);
169 check = connect(m_pView, SIGNAL(customContextMenuRequested(const QPoint&)),
170 this, SLOT(slotCustomContextMenuRequested(const QPoint&)));
171 Q_ASSERT(check);
172 this->setCentralWidget(m_pView);
173 }
174
175 m_Client.EnumPlugins(this);
176 m_Client.LoadSettings();
177
178 check = connect(&m_Parameter, SIGNAL(sigReceiveShortCutChanged()),
179 this, SLOT(slotShortCut()));
180 Q_ASSERT(check);
181 check = connect(&m_Parameter, SIGNAL(sigSystemTrayIconTypeChanged()),
182 this,
183 SLOT(slotSystemTrayIconTypeChanged()));
184 Q_ASSERT(check);
185 check = connect(&m_Parameter, SIGNAL(sigEnableSystemTrayIcon()),
186 this, SLOT(slotEnableSystemTrayIcon()));
187 Q_ASSERT(check);
188 check = connect(&m_Parameter, SIGNAL(sigEnableTabToolTipChanged()),
189 this, SLOT(slotUpdateName()));
190 Q_ASSERT(check);
191 check = connect(&m_Parameter, SIGNAL(sigEnableTabIconChanged()),
192 this, SLOT(slotUpdateName()));
193 Q_ASSERT(check);
194 m_Parameter.Load();
195 slotShortCut();
196#ifdef HAVE_ICE
197 if(CICE::Instance()->GetSignal())
198 {
199 check = connect(CICE::Instance()->GetSignal().data(),
200 SIGNAL(sigConnected()),
201 this, SLOT(slotSignalConnected()));
202 Q_ASSERT(check);
203 check = connect(CICE::Instance()->GetSignal().data(),
204 SIGNAL(sigDisconnected()),
205 this, SLOT(slotSignalDisconnected()));
206 Q_ASSERT(check);
207 check = connect(CICE::Instance()->GetSignal().data(),
208 SIGNAL(sigError(const int, const QString&)),
209 this, SLOT(slotSignalError(const int, const QString&)));
210 Q_ASSERT(check);
211 }
212 CICE::Instance()->slotStart();
213 m_pSignalStatus = new QPushButton();
214 m_pSignalStatus->setToolTip(tr("ICE signal status"));
215 m_pSignalStatus->setStatusTip(m_pSignalStatus->toolTip());
216 m_pSignalStatus->setWhatsThis(m_pSignalStatus->toolTip());
217 slotSignalDisconnected();
218 statusBar()->addPermanentWidget(m_pSignalStatus);
219#endif
220
221 if(m_Parameter.GetSaveMainWindowStatus())
222 {
223 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
224 QSettings::IniFormat);
225 QByteArray geometry
226 = set.value("MainWindow/Status/Geometry").toByteArray();
227 if(!geometry.isEmpty())
228 restoreGeometry(geometry);
229 QByteArray state = set.value("MainWindow/Status/State").toByteArray();
230 if(!state.isEmpty())
231 restoreState(state);
232
233 ui->actionStatus_bar_S->setChecked(m_Parameter.GetStatusBar());
234 statusBar()->setVisible(m_Parameter.GetStatusBar());
235 ui->actionTabBar_B->setChecked(m_Parameter.GetTabBar());
236 on_actionMain_menu_bar_M_toggled(m_Parameter.GetMenuBar());
237 ui->actionMain_menu_bar_M->setChecked(m_Parameter.GetMenuBar());
238 ui->actionToolBar_T->setChecked(!ui->toolBar->isHidden());
239 }
240
241 slotEnableSystemTrayIcon();
242
243 LoadConnectLasterClose();
244}
245
246MainWindow::~MainWindow()
247{
248 qDebug(log) << "MainWindow::~MainWindow()";
249 if(m_pFullScreenToolBar) m_pFullScreenToolBar->close();
250 delete ui;
251}
252
253void MainWindow::on_actionAbout_triggered()
254{
255#ifdef HAVE_ABOUT
256 CDlgAbout *about = new CDlgAbout(this);
257 QIcon icon = QIcon::fromTheme("app");
258 if(!icon.isNull()) {
259 auto sizeList = icon.availableSizes();
260 if(!sizeList.isEmpty()) {
261 QPixmap p = icon.pixmap(*sizeList.begin());
262 about->m_AppIcon = p.toImage();
263 }
264 }
265 about->m_szCopyrightStartTime = "2020";
266 about->m_szVersionRevision = RabbitRemoteControl_REVISION;
267 about->m_szDetails = m_Client.Details();
268 RC_SHOW_WINDOW(about);
269#endif
270}
271
272void MainWindow::on_actionUpdate_triggered()
273{
274#ifdef HAVE_UPDATE
275 CFrmUpdater* m_pfrmUpdater = new CFrmUpdater();
276 QIcon icon = QIcon::fromTheme("app");
277 if(!icon.isNull()) {
278 auto sizeList = icon.availableSizes();
279 if(!sizeList.isEmpty()) {
280 QPixmap p = icon.pixmap(*sizeList.begin());
281 m_pfrmUpdater->SetTitle(p.toImage());
282 }
283 }
284 m_pfrmUpdater->SetInstallAutoStartup();
285 RC_SHOW_WINDOW(m_pfrmUpdater);
286#endif
287}
288
289void MainWindow::on_actionFull_screen_F_triggered()
290{
291 CView* pTab = qobject_cast<CView*>(this->centralWidget());
292 if(pTab)
293 {
294 pTab->SetFullScreen(!isFullScreen());
295 }
296
297 if(isFullScreen())
298 {
299 qDebug(log) << "Exit full screen";
300 ui->actionFull_screen_F->setIcon(QIcon::fromTheme("view-fullscreen"));
301 ui->actionFull_screen_F->setText(tr("Full screen(&F)"));
302 ui->actionFull_screen_F->setToolTip(tr("Full screen"));
303 ui->actionFull_screen_F->setStatusTip(tr("Full screen"));
304 ui->actionFull_screen_F->setWhatsThis(tr("Full screen"));
305
306 ui->toolBar->setVisible(m_FullState.toolBar);
307 ui->statusbar->setVisible(m_FullState.statusbar);
308 ui->menubar->setVisible(m_FullState.menubar);
309
310 m_pDockListConnects->setVisible(m_FullState.dockListConnects);
311 m_pDockFavorite->setVisible(m_FullState.dockFavorite);
312 // This is hade code. it is in RabbitCommon
313 QDockWidget* pDockDebugLog = findChild<QDockWidget*>("dockDebugLog");
314 if(pDockDebugLog)
315 {
316 pDockDebugLog->setVisible(m_FullState.dockDebugLog);
317 }
318
319 if(m_pFullScreenToolBar)
320 {
321 // Delete it when the widget is close
322 m_pFullScreenToolBar->close();
323 m_pFullScreenToolBar = nullptr;
324 }
325
326 emit sigShowNormal();
327 this->showNormal();
328 this->activateWindow();
329
330 return;
331 }
332
333 qDebug(log) << "Entry full screen";
334 emit sigFullScreen();
335 //setWindowFlags(Qt::FramelessWindowHint | windowFlags());
336 this->showFullScreen();
337
338 ui->actionFull_screen_F->setIcon(QIcon::fromTheme("view-restore"));
339 ui->actionFull_screen_F->setText(tr("Exit full screen(&E)"));
340 ui->actionFull_screen_F->setToolTip(tr("Exit full screen"));
341 ui->actionFull_screen_F->setStatusTip(tr("Exit full screen"));
342 ui->actionFull_screen_F->setWhatsThis(tr("Exit full screen"));
343
344 m_FullState.toolBar = ui->toolBar->isVisible();
345 ui->toolBar->setVisible(false);
346 m_FullState.statusbar = ui->statusbar->isVisible();
347 ui->statusbar->setVisible(false);
348 m_FullState.menubar = ui->menubar->isVisible();
349 ui->menubar->setVisible(false);
350
351 m_FullState.dockListConnects = m_pDockListConnects->isVisible();
352 m_pDockListConnects->setVisible(false);
353 m_FullState.dockFavorite = m_pDockFavorite->isVisible();
354 m_pDockFavorite->setVisible(false);
355 // This is hade code. it is in RabbitCommon
356 QDockWidget* pDockDebugLog = findChild<QDockWidget*>("dockDebugLog");
357 if(pDockDebugLog)
358 {
359 m_FullState.dockDebugLog = pDockDebugLog->isVisible();
360 pDockDebugLog->setVisible(false);
361 }
362
363 if(m_pFullScreenToolBar) m_pFullScreenToolBar->close();
364 // Delete it when the widget is close
365 m_pFullScreenToolBar = new CFrmFullScreenToolBar(this);
366 QScreen* pScreen = qApp->primaryScreen();
367 if(pScreen) {
368 QPoint pos(pScreen->geometry().left()
369 + (pScreen->geometry().width()
370 - m_pFullScreenToolBar->frameGeometry().width()) / 2,
371 pScreen->geometry().top());
372 qDebug(log) << "Primary screen geometry:" << pScreen->geometry()
373 << "availableGeometry:" << pScreen->availableGeometry()
374 << pos << mapToGlobal(pos);
375 m_pFullScreenToolBar->move(pos);
376 }
377 bool check = connect(m_pFullScreenToolBar, SIGNAL(sigExitFullScreen()),
378 this, SLOT(on_actionFull_screen_F_triggered()));
379 Q_ASSERT(check);
380 check = connect(m_pFullScreenToolBar, SIGNAL(sigExit()),
381 this, SLOT(on_actionExit_E_triggered()));
382 Q_ASSERT(check);
383 check = connect(m_pFullScreenToolBar, SIGNAL(sigDisconnect()),
384 this, SLOT(on_actionDisconnect_D_triggered()));
385 Q_ASSERT(check);
386 check = connect(this, SIGNAL(sigConnecterMenuChanged(QAction*)),
387 m_pFullScreenToolBar,
388 SLOT(slotConnecterMenuChanged(QAction*)));
389 Q_ASSERT(check);
390 CViewTable* p = dynamic_cast<CViewTable*>(pTab);
391 if(p)
392 {
393 check = connect(m_pFullScreenToolBar, SIGNAL(sigShowTabBar(bool)),
394 SLOT(on_actionTabBar_B_toggled(bool)));
395 Q_ASSERT(check);
396 }
397
398 m_pFullScreenToolBar->show();
399}
400
401void MainWindow::slotCurrentViewChanged(const QWidget* pView)
402{
403 qDebug(log) << Q_FUNC_INFO;
404 if(m_pView && pView) {
405 EnableMenu(true);
406 } else
407 EnableMenu(false);
408}
409
410void MainWindow::EnableMenu(bool bEnable)
411{
412 qDebug(log) << Q_FUNC_INFO << bEnable;
413 ui->actionClone->setEnabled(bEnable);
414 ui->actionAdd_to_favorite->setEnabled(bEnable);
415 ui->actionCurrent_connect_parameters->setEnabled(bEnable);
416 ui->actionDisconnect_D->setEnabled(bEnable);
417 slotLoadConnecterMenu();
418}
419
420void MainWindow::slotLoadConnecterMenu()
421{
422 qDebug(log) << Q_FUNC_INFO;
423
424 if(m_pActionConnecterMenu) {
425 ui->menuTools->removeAction(m_pActionConnecterMenu);
426 ui->toolBar->removeAction(m_pActionConnecterMenu);
427 m_pActionConnecterMenu = nullptr;
428 }
429
430 if(!m_pView)
431 return;
432 auto pWin = m_pView->GetCurrentView();
433 if(!pWin) {
434 qDebug(log) << "The current view is empty";
435 return;
436 }
437 foreach(auto c, m_Connecters)
438 {
439 if(c->GetViewer() == pWin)
440 {
441 qDebug(log) << "Load plugin menu";
442 auto m = c->GetMenu(ui->menuTools);
443 if(!m) return;
444 m_pActionConnecterMenu = ui->menuTools->addMenu(m);
445 ui->toolBar->insertAction(ui->actionFull_screen_F, m_pActionConnecterMenu);
446 emit sigConnecterMenuChanged(m_pActionConnecterMenu);
447 }
448 }
449}
450
451void MainWindow::slotCustomContextMenuRequested(const QPoint &pos)
452{
453 if(!m_pView)
454 return;
455 auto pWin = m_pView->GetCurrentView();
456 if(!pWin) {
457 qDebug(log) << "The current view is empty";
458 return;
459 }
460 foreach(auto c, m_Connecters)
461 {
462 if(c->GetViewer() == pWin)
463 {
464 qDebug(log) << "Load plugin menu";
465 auto m = c->GetMenu(ui->menuTools);
466 if(!m) return;
467 m->exec(m_pView->mapToGlobal(pos));
468 }
469 }
470}
471
472void MainWindow::on_actionExit_E_triggered()
473{
474 close();
475}
476
477void MainWindow::keyReleaseEvent(QKeyEvent *event)
478{
479 switch(event->key())
480 {
481 case Qt::Key_Escape:
482 if(isFullScreen())
483 on_actionFull_screen_F_triggered();
484 break;
485 }
486 QMainWindow::keyReleaseEvent(event);
487}
488
489void MainWindow::slotUpdateParameters(CConnecter* pConnecter)
490{
491 auto it = m_ConfigureFiles.find(pConnecter);
492 if(m_ConfigureFiles.end() == it)
493 return;
494 m_Client.SaveConnecter(it.value(), pConnecter);
495}
496
497void MainWindow::on_actionClone_triggered()
498{
499 if(!m_pView) return;
500 QWidget* p = m_pView->GetCurrentView();
501 foreach(auto c, m_Connecters)
502 {
503 if(c->GetViewer() == p)
504 {
505 auto it = m_ConfigureFiles.find(c);
506 if(m_ConfigureFiles.end() == it)
507 return;
508 QString szFile = it.value();
509 auto pConnecter = m_Client.LoadConnecter(szFile);
510 if(!pConnecter) return;
511 Connect(pConnecter, false, szFile);
512 return;
513 }
514 }
515}
516
517void MainWindow::slotOpenFile(const QString& szFile, bool bOpenSettings)
518{
519 if(szFile.isEmpty()) return;
520 CConnecter* p = m_Client.LoadConnecter(szFile);
521 if(nullptr == p)
522 {
523 slotInformation(tr("Load file fail: ") + szFile);
524 return;
525 }
526
527 Connect(p, bOpenSettings, szFile);
528}
529
530void MainWindow::on_actionOpenRRCFile_triggered()
531{
532 QString szFile = QFileDialog::getOpenFileName(this,
533 tr("Open rabbit remote control file"),
534 RabbitCommon::CDir::Instance()->GetDirUserData(),
535 tr("Rabbit remote control Files (*.rrc);;All files(*.*)"));
536 if(szFile.isEmpty()) return;
537
538 CConnecter* p = m_Client.LoadConnecter(szFile);
539 if(nullptr == p)
540 {
541 slotInformation(tr("Load file fail: ") + szFile);
542 return;
543 }
544
545 Connect(p, true);
546}
547
548void MainWindow::slotConnect()
549{
550 if(nullptr == m_pView)
551 {
552 Q_ASSERT(false);
553 return;
554 }
555 QAction* pAction = dynamic_cast<QAction*>(this->sender());
556 CConnecter* p = m_Client.CreateConnecter(pAction->data().toString());
557 if(nullptr == p) return;
558 Connect(p, true);
559}
560
571int MainWindow::Connect(CConnecter *p, bool set, QString szFile)
572{
573 qDebug(log) << "MainWindow::Connect: set:" << set << "; File:" << szFile;
574 bool bSave = false; //whether is save configure file
575 Q_ASSERT(p);
576 bool check = connect(p, SIGNAL(sigConnected()),
577 this, SLOT(slotConnected()));
578 Q_ASSERT(check);
579 check = connect(p, SIGNAL(sigDisconnect()),
580 this, SLOT(slotDisconnect()));
581 Q_ASSERT(check);
582 check = connect(p, SIGNAL(sigDisconnected()),
583 this, SLOT(slotDisconnected()));
584 Q_ASSERT(check);
585 check = connect(p, SIGNAL(sigError(const int, const QString &)),
586 this, SLOT(slotError(const int, const QString&)));
587 Q_ASSERT(check);
588 check = connect(p, SIGNAL(sigShowMessageBox(const QString&, const QString&,
589 const QMessageBox::Icon&)),
590 this, SLOT(slotShowMessageBox(const QString&, const QString&,
591 const QMessageBox::Icon&)));
592 Q_ASSERT(check);
593 check = connect(p, SIGNAL(sigInformation(const QString&)),
594 this, SLOT(slotInformation(const QString&)));
595 Q_ASSERT(check);
596 check = connect(p, SIGNAL(sigUpdateName(const QString&)),
597 this, SLOT(slotUpdateName(const QString&)));
598 Q_ASSERT(check);
599 check = connect(p, SIGNAL(sigUpdateParameters(CConnecter*)),
600 this, SLOT(slotUpdateParameters(CConnecter*)));
601 Q_ASSERT(check);
602
603 if(set)
604 {
605 int nRet = p->OpenDialogSettings(this);
606 switch(nRet)
607 {
608 case QDialog::Rejected:
609 m_Client.DeleteConnecter(p);
610 return 0;
611 case QDialog::Accepted:
612 bSave = true;
613 break;
614 }
615 }
616
617 if(szFile.isEmpty())
618 szFile = RabbitCommon::CDir::Instance()->GetDirUserData()
619 + QDir::separator()
620 + p->Id()
621 + ".rrc";
622 m_ConfigureFiles[p] = szFile;
623
624 int nRet = 0;
625 if(bSave)
626 nRet = m_Client.SaveConnecter(szFile, p);
627 if(0 == nRet)
628 m_pRecentMenu->addRecentFile(szFile, p->Name());
629
630 if(!p->Name().isEmpty())
631 slotInformation(tr("Connecting to ") + p->Name());
632
633 //* Show view. \see: slotConnected()
634 if(m_pView)
635 {
636 m_pView->AddView(p->GetViewer());
637 m_pView->SetWidowsTitle(p->GetViewer(), p->Name(), p->Icon(), p->Description());
638 //qDebug(log) << "View:" << p->GetViewer();
639 }
640
641 m_Connecters.push_back(p);//*/
642
643 p->Connect();
644
645 return 0;
646}
647
649
653{
654 CConnecter* p = dynamic_cast<CConnecter*>(sender());
655 if(!p) return;
656
657 /* If you put it here, when connected, the view is not displayed.
658 So put it in the connect() display view.
659 See: Connect(CConnecter *p, bool set, QString szFile)
660 */
661 /*
662 if(m_pView)
663 {
664 m_pView->SetAdaptWindows(CFrmViewer::Auto, p->GetViewer());
665 m_pView->AddView(p->GetViewer());
666 m_pView->SetWidowsTitle(p->GetViewer(), p->Name(), p->Icon(), p->Description());
667 }
668 m_Connecters.push_back(p);//*/
669
670 slotLoadConnecterMenu();
671
672 slotInformation(tr("Connected to ") + p->Name());
673 qDebug(log) << "MainWindow::slotConnected()" << p->Name();
674}
676
677void MainWindow::slotCloseView(const QWidget* pView)
678{
679 qDebug(log) << "MainWindow::slotCloseView" << pView;
680 if(!pView) return;
681 foreach(auto c, m_Connecters)
682 {
683 if(c->GetViewer() == pView)
684 {
685 //TODO: Whether to save the setting
686 emit c->sigUpdateParameters(c);
687 c->DisConnect();
688 }
689 }
690}
691
692void MainWindow::on_actionDisconnect_D_triggered()
693{
694 qDebug(log) << "MainWindow::on_actionDisconnect_D_triggered()";
695 if(!m_pView) return;
696
697 QWidget* pView = m_pView->GetCurrentView();
698 slotCloseView(pView);
699}
700
701void MainWindow::slotDisconnect()
702{
703 qDebug(log) << "MainWindow::slotDisconnect()";
704 CConnecter* pConnecter = dynamic_cast<CConnecter*>(sender());
705 if(!pConnecter) return;
706 //TODO: Whether to save the setting
707 emit pConnecter->sigUpdateParameters(pConnecter);
708 pConnecter->DisConnect();
709}
710
711void MainWindow::slotDisconnected()
712{
713 qDebug(log) << "MainWindow::slotDisconnected()";
714 CConnecter* pConnecter = dynamic_cast<CConnecter*>(sender());
715 foreach(auto c, m_Connecters)
716 {
717 if(c == pConnecter)
718 {
719 m_pView->RemoveView(c->GetViewer());
720 m_Connecters.removeAll(c);
721 m_ConfigureFiles.remove(c);
722 m_Client.DeleteConnecter(c);
723 return;
724 }
725 }
726}
727
728void MainWindow::slotSignalConnected()
729{
730 m_pSignalStatus->setToolTip(tr("ICE signal status: Connected"));
731 m_pSignalStatus->setStatusTip(m_pSignalStatus->toolTip());
732 m_pSignalStatus->setWhatsThis(m_pSignalStatus->toolTip());
733 //m_pSignalStatus->setText(tr("Connected"));
734 m_pSignalStatus->setIcon(QIcon::fromTheme("newwork-wired"));
735}
736
737void MainWindow::slotSignalDisconnected()
738{
739 m_pSignalStatus->setToolTip(tr("ICE signal status: Disconnected"));
740 m_pSignalStatus->setStatusTip(m_pSignalStatus->toolTip());
741 m_pSignalStatus->setWhatsThis(m_pSignalStatus->toolTip());
742 //m_pSignalStatus->setText(tr("Disconnected"));
743 m_pSignalStatus->setIcon(QIcon::fromTheme("network-wireless"));
744}
745
746void MainWindow::slotSignalError(const int nError, const QString &szInfo)
747{
748 slotSignalDisconnected();
749 slotInformation(szInfo);
750}
751
752void MainWindow::slotSignalPushButtonClicked(bool checked)
753{
754#ifdef HAVE_ICE
755 if(checked)
756 CICE::Instance()->slotStart();
757 else
758 CICE::Instance()->slotStop();
759#endif
760}
761
762void MainWindow::slotError(const int nError, const QString &szInfo)
763{
764 Q_UNUSED(nError);
765 slotInformation(szInfo);
766}
767
769 const QString &title, const QString &message,
770 const QMessageBox::Icon &icon)
771{
772 slotInformation(message);
773 if(!m_Parameter.GetMessageBoxDisplayInformation())
774 return;
775
776 QMessageBox msg(icon, title, message, QMessageBox::Ok, this);
777 QCheckBox* cb = new QCheckBox(
778 tr("Use message box to display information"), this);
779 cb->setChecked(true);
780 msg.setCheckBox(cb);
781 RC_SHOW_WINDOW(&msg);
782 if(!cb->isChecked())
783 {
784 m_Parameter.SetMessageBoxDisplayInformation(false);
785 m_Parameter.Save();
786 }
787}
788
789void MainWindow::slotInformation(const QString& szInfo)
790{
791 statusBar()->showMessage(szInfo);
792}
793
794void MainWindow::slotUpdateName()
795{
796 foreach (auto pConnecter, m_Connecters)
797 {
798 m_pView->SetWidowsTitle(pConnecter->GetViewer(),
799 pConnecter->Name(),
800 pConnecter->Icon(),
801 pConnecter->Description());
802 }
803}
804
805void MainWindow::slotUpdateName(const QString& szName)
806{
807 CConnecter* pConnecter = dynamic_cast<CConnecter*>(sender());
808 if(!pConnecter) return;
809 m_pView->SetWidowsTitle(pConnecter->GetViewer(), szName,
810 pConnecter->Icon(), pConnecter->Description());
811}
812
813int MainWindow::onProcess(const QString &id, CPluginClient *pPlug)
814{
815 Q_UNUSED(id);
816 // Connect menu and toolbar
817 QAction* p = ui->menuConnect_C->addAction(pPlug->Protocol()
818 + ": " + pPlug->DisplayName(),
819 this, SLOT(slotConnect()));
820 p->setToolTip(pPlug->Description());
821 p->setStatusTip(pPlug->Description());
822 p->setData(id);
823 p->setIcon(pPlug->Icon());
824
825 return 0;
826}
827
828void MainWindow::closeEvent(QCloseEvent *event)
829{
830 qDebug(log) << "MainWindow::closeEvent()";
831
832 if(m_Parameter.GetSaveMainWindowStatus())
833 if(isFullScreen())
834 on_actionFull_screen_F_triggered();
835
836 SaveConnectLasterClose();
837
838 foreach (auto it, m_Connecters)
839 {
840 //TODO: Whether to save the setting
841 emit it->sigUpdateParameters(it);
842 it->DisConnect();
843 }
844
845 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
846 QSettings::IniFormat);
847 if(m_Parameter.GetSaveMainWindowStatus())
848 {
849 set.setValue("MainWindow/Status/Geometry", saveGeometry());
850 set.setValue("MainWindow/Status/State", saveState());
851 // Other parameters of main windows is saved CParameterApp::~CParameterApp()
852 } else {
853 set.remove("MainWindow/Status/Geometry");
854 set.remove("MainWindow/Status/State");
855 }
856 QMainWindow::closeEvent(event);
857
858 //TODO: Wait for the background thread to exit
859 QThread::sleep(1);
860}
861
862int MainWindow::LoadConnectLasterClose()
863{
864 if(!m_Parameter.GetOpenLasterClose())
865 return 0;
866
867 QFile f(RabbitCommon::CDir::Instance()->GetDirUserConfig()
868 + QDir::separator() + "LasterClose.dat");
869 if(f.open(QFile::ReadOnly))
870 {
871 QDataStream d(&f);
872 while(1){
873 QString szFile;
874 d >> szFile;
875 if(szFile.isEmpty())
876 break;
877 slotOpenFile(szFile);
878 }
879 f.close();
880 }
881 return 0;
882}
883
884int MainWindow::SaveConnectLasterClose()
885{
886 QFile f(RabbitCommon::CDir::Instance()->GetDirUserConfig()
887 + QDir::separator() + "LasterClose.dat");
888 f.open(QFile::WriteOnly);
889 if(m_Parameter.GetOpenLasterClose())
890 {
891 QDataStream d(&f);
892 foreach(auto it, m_ConfigureFiles)
893 {
894 d << it;
895 }
896 }
897 f.close();
898 return 0;
899}
900
901void MainWindow::on_actionSend_ctl_alt_del_triggered()
902{
903 if(m_pView)
904 m_pView->slotSystemCombination();
905}
906
907void MainWindow::on_actionTabBar_B_toggled(bool bShow)
908{
909 CViewTable* p = dynamic_cast<CViewTable*>(m_pView);
910 if(p)
911 {
912 p->ShowTabBar(bShow);
913 m_Parameter.SetTabBar(bShow);
914 }
915}
916
917void MainWindow::on_actionMain_menu_bar_M_toggled(bool checked)
918{
919 qDebug(log) << "MainWindow::on_actionMain_menu_bar_M_triggered:" << checked;
920 if(ui->toolBar->isHidden() && !checked)
921 {
922 if( QMessageBox::StandardButton::Yes
923 == QMessageBox::information(this, tr("Hide menu bar"),
924 tr("The menu bar will be hidden, the tool bar must be showed."),
925 QMessageBox::StandardButton::Yes
926 | QMessageBox::StandardButton::No))
927 {
928 ui->actionToolBar_T->setChecked(true);
929 } else
930 return;
931 }
932
933 menuBar()->setVisible(checked);
934 m_Parameter.SetMenuBar(checked);
935 if(checked)
936 {
937 ui->toolBar->removeAction(ui->actionMain_menu_bar_M);
938 }
939 else
940 {
941 ui->toolBar->insertAction(ui->actionTabBar_B,
942 ui->actionMain_menu_bar_M);
943 }
944}
945
946void MainWindow::on_actionToolBar_T_toggled(bool checked)
947{
948 qDebug(log) << "MainWindow::on_actionToolBar_T_triggered:" << checked;
949 if(menuBar()->isHidden() && !checked)
950 {
951 if( QMessageBox::StandardButton::Yes
952 == QMessageBox::information(this, tr("Hide tool bar"),
953 tr("The tool bar will be hidden, the menu bar must be showed."),
954 QMessageBox::StandardButton::Yes
955 | QMessageBox::StandardButton::No))
956 {
957 ui->actionMain_menu_bar_M->setChecked(true);
958 } else
959 return;
960 }
961 ui->toolBar->setVisible(checked);
962}
963
964void MainWindow::on_actionStatus_bar_S_toggled(bool checked)
965{
966 statusBar()->setVisible(checked);
967 m_Parameter.SetStatusBar(checked);
968}
969
970// [Get the widget that settings client parameters]
971void MainWindow::on_actionSettings_triggered()
972{
973 CParameterDlgSettings set(&m_Parameter, m_Client.GetSettingsWidgets(this), this);
974 if(CParameterDlgSettings::Accepted == RC_SHOW_WINDOW(&set))
975 {
976 m_Client.SaveSettings();
977 m_Parameter.Save();
978 }
979}
980// [Get the widget that settings client parameters]
981
982void MainWindow::slotShortCut()
983{
984 if(m_Parameter.GetReceiveShortCut())
985 {
986 setFocusPolicy(Qt::WheelFocus);
987#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
988 ui->actionFull_screen_F->setShortcut(
989 QKeySequence(QKeyCombination(Qt::CTRL, Qt::Key_R),
990 QKeyCombination(Qt::Key_F)));
991 ui->actionScreenshot->setShortcut(
992 QKeySequence(QKeyCombination(Qt::CTRL, Qt::Key_R),
993 QKeyCombination(Qt::Key_S)));
994#else
995 ui->actionFull_screen_F->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_R, Qt::Key_F));
996 ui->actionScreenshot->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_R, Qt::Key_S));
997#endif
998 } else {
999 setFocusPolicy(Qt::NoFocus);
1000 ui->actionFull_screen_F->setShortcut(QKeySequence());
1001 ui->actionScreenshot->setShortcut(QKeySequence());
1002 }
1003}
1004
1005void MainWindow::on_actionCurrent_connect_parameters_triggered()
1006{
1007 if(!m_pView) return;
1008 QWidget* p = m_pView->GetCurrentView();
1009 foreach(auto c, m_Connecters)
1010 {
1011 if(c->GetViewer() == p)
1012 {
1013 int nRet = c->OpenDialogSettings(this);
1014 if(QDialog::Accepted == nRet)
1015 {
1016 emit c->sigUpdateParameters(c);
1017 return;
1018 }
1019 }
1020 }
1021}
1022
1023void MainWindow::on_actionOpenListConnections_triggered()
1024{
1025 CFrmListConnects* p = new CFrmListConnects(&m_Client, false);
1026 if(!p) return;
1027 bool check = connect(p, SIGNAL(sigConnect(const QString&, bool)),
1028 this, SLOT(slotOpenFile(const QString&, bool)));
1029 Q_ASSERT(check);
1030
1031 QDialog d;
1032 d.resize(540, 400);
1033 d.setWindowIcon(windowIcon());
1034 QGridLayout* pLayout = new QGridLayout(&d);
1035 if(pLayout){
1036 pLayout->addWidget(p);
1037 check = connect(p, SIGNAL(destroyed()), &d, SLOT(reject()));
1038 d.setLayout(pLayout);
1039 }
1040 RC_SHOW_WINDOW(&d);
1041}
1042
1043void MainWindow::on_actionAdd_to_favorite_triggered()
1044{
1045 if(!m_pView || !m_pFavoriteView) return;
1046 QWidget* p = m_pView->GetCurrentView();
1047 foreach(auto c, m_Connecters)
1048 {
1049 if(c->GetViewer() == p)
1050 {
1051 auto it = m_ConfigureFiles.find(c);
1052 if(m_ConfigureFiles.end() == it)
1053 return;
1054 m_pFavoriteView->AddFavorite(c->Name(), it.value());
1055 }
1056 }
1057}
1058
1059void MainWindow::dragEnterEvent(QDragEnterEvent *event)
1060{
1061 qDebug(log) << "dragEnterEvent";
1062
1063 if(event->mimeData()->hasUrls())
1064 {
1065 qWarning(log) << event->mimeData()->urls();
1066 event->acceptProposedAction();
1067 }
1068}
1069
1070void MainWindow::dragMoveEvent(QDragMoveEvent *event)
1071{
1072 //qDebug(log) << "dragMoveEvent";
1073}
1074
1075void MainWindow::dropEvent(QDropEvent *event)
1076{
1077 qDebug(log) << "dropEvent";
1078 if(!event->mimeData()->hasUrls())
1079 return;
1080 auto urls = event->mimeData()->urls();
1081 foreach(auto url, urls)
1082 {
1083 if(url.isLocalFile())
1084 slotOpenFile(url.toLocalFile());
1085 }
1086}
1087
1088void MainWindow::slotSystemTrayIconActivated(QSystemTrayIcon::ActivationReason reason)
1089{
1090 //qDebug(log) << "MainWindow::slotSystemTrayIconActivated";
1091
1092 Q_UNUSED(reason)
1093#if defined(Q_OS_ANDROID)
1094 showMaximized();
1095#else
1096 switch(reason)
1097 {
1098 case QSystemTrayIcon::Trigger:
1099 {
1100 showNormal();
1101 activateWindow();
1102 break;
1103 }
1104 default:
1105 break;
1106 }
1107#endif
1108}
1109
1110void MainWindow::slotSystemTrayIconTypeChanged()
1111{
1112 //qDebug(log) << "MainWindow::slotSystemTrayIconTypeChanged:" << m_Parameter.GetEnableSystemTrayIcon();
1113 if(!QSystemTrayIcon::isSystemTrayAvailable())
1114 {
1115 qWarning(log) << "System tray is not available";
1116 return;
1117 }
1118
1119 if(!m_Parameter.GetEnableSystemTrayIcon())
1120 {
1121 qDebug(log) << "Disable system tray icon";
1122 return;
1123 }
1124
1125 if(m_TrayIcon)
1126 m_TrayIcon.reset();
1127
1128 m_TrayIcon = QSharedPointer<QSystemTrayIcon>(new QSystemTrayIcon(this));
1129 if(QSystemTrayIcon::isSystemTrayAvailable())
1130 {
1131 bool check = connect(
1132 m_TrayIcon.data(),
1133 SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
1134 this,
1135 SLOT(slotSystemTrayIconActivated(QSystemTrayIcon::ActivationReason)));
1136 Q_ASSERT(check);
1137 m_TrayIcon->setIcon(this->windowIcon());
1138 m_TrayIcon->setToolTip(windowTitle());
1139 m_TrayIcon->show();
1140 } else
1141 qWarning(log) << "System tray is not available";
1142
1143 switch (m_Parameter.GetSystemTrayIconMenuType())
1144 {
1145 case CParameterApp::SystemTrayIconMenuType::MenuBar:
1146 {
1147 QMenu* pMenu = new QMenu(this);
1148 pMenu->addMenu(ui->menuRemote);
1149 pMenu->addMenu(ui->menuView);
1150 pMenu->addMenu(ui->menuTools);
1151 m_TrayIcon->setContextMenu(pMenu);
1152 break;
1153 }
1154 case CParameterApp::SystemTrayIconMenuType::Remote:
1155 m_TrayIcon->setContextMenu(ui->menuRemote);
1156 break;
1157 case CParameterApp::SystemTrayIconMenuType::RecentOpen:
1158 m_TrayIcon->setContextMenu(m_pRecentMenu);
1159 break;
1160 case CParameterApp::SystemTrayIconMenuType::View:
1161 m_TrayIcon->setContextMenu(ui->menuView);
1162 break;
1163 case CParameterApp::SystemTrayIconMenuType::Tools:
1164 m_TrayIcon->setContextMenu(ui->menuTools);
1165 break;
1166 case CParameterApp::SystemTrayIconMenuType::No:
1167 m_TrayIcon->setContextMenu(nullptr);
1168 break;
1169 }
1170}
1171
1172void MainWindow::slotEnableSystemTrayIcon()
1173{
1174 //qDebug(log) << "MainWindow::slotEnableSystemTryIcon()";
1175 if(m_TrayIcon)
1176 {
1177 if(!m_Parameter.GetEnableSystemTrayIcon())
1178 m_TrayIcon.reset();
1179 } else
1180 slotSystemTrayIconTypeChanged();
1181}
virtual int SaveSettings(QString szFile=QString())
Save Client parameters to file.
Definition Client.cpp:356
virtual CConnecter * LoadConnecter(const QString &szFile)
New CConnecter pointer from file, the owner is caller.
Definition Client.cpp:273
virtual CConnecter * CreateConnecter(const QString &id)
New CConnecter pointer, the owner is caller.
Definition Client.cpp:202
virtual int SaveConnecter(QString szFile, CConnecter *pConnecter)
Accept connecter parameters to file.
Definition Client.cpp:308
virtual int DeleteConnecter(CConnecter *p)
Delete CConnecter.
Definition Client.cpp:256
virtual QList< QWidget * > GetSettingsWidgets(QWidget *parent)
Get parameter settings widget.
Definition Client.cpp:361
Connecter interface.
Definition Connecter.h:62
virtual int DisConnect()=0
Close connect.
virtual const QIcon Icon() const
Icon.
Definition Connecter.cpp:74
virtual int OpenDialogSettings(QWidget *parent=nullptr)
Open settings dialog.
Definition Connecter.cpp:93
virtual QWidget * GetViewer()=0
Get Viewer.
virtual const QString Description()
Description.
Definition Connecter.cpp:58
virtual const QString Id()
Identity.
Definition Connecter.cpp:47
virtual int Connect()=0
Start connect.
virtual const QString Name()
Name.
Definition Connecter.cpp:53
void sigUpdateParameters(CConnecter *pConnecter)
Update parameters, notify application to save or show parameters.
List the connect of be existed.
static CICE * Instance()
Single instance.
Definition Ice.cpp:55
The plugin interface.
virtual const QString DisplayName() const
The plugin display name.
virtual const QString Description() const =0
Plugin description.
virtual const QString Protocol() const =0
Plugin Protocol.
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:32
virtual int onProcess(const QString &id, CPluginClient *pPlug) override
Process plugins.
void slotInformation(const QString &szInfo)
Show information.
int Connect(CConnecter *p, bool set, QString szFile=QString())
Connect.
void slotConnected()
[MainWindow slotConnected]
virtual void slotShowMessageBox(const QString &title, const QString &message, const QMessageBox::Icon &icon)
Use message box display information.
void slotCloseView(const QWidget *pView)
[MainWindow slotConnected]