Rabbit Remote Control 0.0.35
Loading...
Searching...
No Matches
ConnecterThread.cpp
1// Author: Kang Lin <kl222@126.com>
2
3#include <QLoggingCategory>
4#include <QDesktopServices>
5#include <QUrl>
6
7#include <QWidgetAction>
8#include <QActionGroup>
9
10#include "ConnecterThread.h"
11#include "ConnectThread.h"
12#include "PluginClient.h"
13
14static Q_LOGGING_CATEGORY(log, "Client.Connecter.Thread")
15
17 : CConnecterConnect(plugin)
18 , m_pThread(nullptr)
19 , m_pFrmViewer(nullptr)
20 , m_pScroll(nullptr)
21 , m_pZoomToWindow(nullptr)
22 , m_pZoomAspectRatio(nullptr)
23 , m_pZoomOriginal(nullptr)
24 , m_pZoomIn(nullptr)
25 , m_pZoomOut(nullptr)
26 , m_psbZoomFactor(nullptr)
27 , m_pScreenShot(nullptr)
28#if HAVE_QT6_RECORD
29 , m_pRecord(nullptr)
30 , m_pRecordPause(nullptr)
31#endif
32{
33 qDebug(log) << Q_FUNC_INFO;
34}
35
36CConnecterThread::~CConnecterThread()
37{
38 qDebug(log) << Q_FUNC_INFO;
39}
40
42{
43 qDebug(log) << Q_FUNC_INFO;
44 int nRet = 0;
45 bool check = false;
46
48 if(nRet)
49 return nRet;
50
51 Q_ASSERT(!(m_pFrmViewer && m_pScroll));
52 m_pFrmViewer = new CFrmViewer();
53 m_pScroll = new CFrmScroll(m_pFrmViewer);
54
55 check = connect(m_pFrmViewer, SIGNAL(sigViewerFocusIn(QWidget*)),
56 this, SIGNAL(sigViewerFocusIn(QWidget*)));
57 Q_ASSERT(check);
58
59 nRet = InitialMenu();
60
61 return nRet;
62}
63
65{
66 qDebug(log) << Q_FUNC_INFO;
67 int nRet = 0;
68 if(m_pScroll)
69 {
70 delete m_pScroll;
71 m_pScroll = nullptr;
72 }
73
75 return nRet;
76}
77
78int CConnecterThread::InitialMenu()
79{
80 int nRet = 0;
81 bool check = false;
82
83 QMenu* pMenuZoom = new QMenu(&m_Menu);
84 pMenuZoom->setTitle(tr("Zoom"));
85 pMenuZoom->setIcon(QIcon::fromTheme("zoom"));
86 m_pMenuZoom = m_Menu.addMenu(pMenuZoom);
87 m_pZoomToWindow = pMenuZoom->addAction(
88 QIcon::fromTheme("zoom-fit-best"), tr("Zoom to window"));
89 m_pZoomToWindow->setCheckable(true);
90 check = connect(m_pZoomToWindow, &QAction::toggled, this,
91 [&](){
92 m_pScroll->slotSetAdaptWindows(
94 });
95 Q_ASSERT(check);
96 m_pZoomAspectRatio = pMenuZoom->addAction(
97 QIcon::fromTheme("zoom-aspect-ratio"),
98 tr("Keep aspect ration to windows"));
99 m_pZoomAspectRatio->setCheckable(true);
100 check = connect(m_pZoomAspectRatio, &QAction::toggled, this,
101 [&](){
102 m_pScroll->slotSetAdaptWindows(
104 });
105 Q_ASSERT(check);
106 m_pZoomOriginal = pMenuZoom->addAction(
107 QIcon::fromTheme("zoom-original"), tr("Original"));
108 m_pZoomOriginal->setCheckable(true);
109 check = connect(m_pZoomOriginal, &QAction::toggled, this,
110 [&](){
111 m_pScroll->slotSetAdaptWindows(
113 });
114 Q_ASSERT(check);
115 m_pZoomIn = pMenuZoom->addAction(QIcon::fromTheme("zoom-in"), tr("Zoom in"));
116 m_pZoomIn->setCheckable(true);
117 check = connect(
118 m_pZoomIn, &QAction::toggled, this,
119 [&](){
120 if(m_psbZoomFactor)
121 m_psbZoomFactor->setValue((m_pFrmViewer->GetZoomFactor() + 0.1) * 100);
122 });
123 Q_ASSERT(check);
124 m_pZoomOut = pMenuZoom->addAction(
125 QIcon::fromTheme("zoom-out"), tr("Zoom out"));
126 m_pZoomOut->setCheckable(true);
127 check = connect(
128 m_pZoomOut, &QAction::toggled, this,
129 [&](){
130 if(m_psbZoomFactor)
131 m_psbZoomFactor->setValue((m_pFrmViewer->GetZoomFactor() - 0.1) * 100);
132 });
133 Q_ASSERT(check);
134 QActionGroup* pGBViewZoom = new QActionGroup(this);
135 if(pGBViewZoom) {
136 pGBViewZoom->addAction(m_pZoomToWindow);
137 pGBViewZoom->addAction(m_pZoomAspectRatio);
138 pGBViewZoom->addAction(m_pZoomOriginal);
139 pGBViewZoom->addAction(m_pZoomIn);
140 pGBViewZoom->addAction(m_pZoomOut);
141 }
142 m_psbZoomFactor = new QSpinBox(pMenuZoom);
143 m_psbZoomFactor->setRange(0, 9999999);
144 m_psbZoomFactor->setValue(100);
145 m_psbZoomFactor->setSuffix("%");
146 m_psbZoomFactor->setEnabled(false);
147 m_psbZoomFactor->setFocusPolicy(Qt::NoFocus);
148 check = connect(
149 m_psbZoomFactor, SIGNAL(valueChanged(int)),
150 this, SLOT(slotValueChanged(int)));
151 Q_ASSERT(check);
152 QWidgetAction* pFactor = new QWidgetAction(pMenuZoom);
153 pFactor->setDefaultWidget(m_psbZoomFactor);
154 pMenuZoom->insertAction(m_pZoomOut, pFactor);
155
156 QMenu* pMenuShortCut = new QMenu(&m_Menu);
157 pMenuShortCut->setTitle(tr("Send shortcut key"));
158 m_Menu.addMenu(pMenuShortCut);
159 pMenuShortCut->addAction(
160 tr("Send Ctl+Alt+Del"), this, SLOT(slotShortcutCtlAltDel()));
161 pMenuShortCut->addAction(
162 tr("Send lock screen (Win+L)"), this, SLOT(slotShortcutLock()));
163
164 m_Menu.addSeparator();
165 m_pScreenShot = new QAction(QIcon::fromTheme("camera-photo"),
166 tr("ScreenShot"), &m_Menu);
167 check = connect(m_pScreenShot, SIGNAL(triggered()),
168 this, SLOT(slotScreenShot()));
169 Q_ASSERT(check);
170 m_Menu.addAction(m_pScreenShot);
171#if HAVE_QT6_RECORD
172 m_pRecord = new QAction(
173 QIcon::fromTheme("media-record"), tr("Start record"), &m_Menu);
174 m_pRecord->setCheckable(true);
175 check = connect(m_pRecord, SIGNAL(toggled(bool)),
176 this, SLOT(slotRecord(bool)));
177 Q_ASSERT(check);
178 m_Menu.addAction(m_pRecord);
179 m_pRecordPause = new QAction(
180 QIcon::fromTheme("media-playback-pause"), tr("Record pause"), &m_Menu);
181 m_pRecordPause->setCheckable(true);
182 m_pRecordPause->setEnabled(false);
183 check = connect(m_pRecordPause, SIGNAL(toggled(bool)),
184 this, SIGNAL(sigRecordPause(bool)));
185 Q_ASSERT(check);
186 m_Menu.addAction(m_pRecordPause);
187#endif
188
189 m_Menu.addSeparator();
190 if(m_pSettings)
191 m_Menu.addAction(m_pSettings);
192
193 return nRet;
194}
195
197{
198 return m_pScroll;
199}
200
202{
203 qDebug(log) << Q_FUNC_INFO;
204 int nRet = 0;
205 m_pThread = new CConnectThread(this);
206 if(!m_pThread) {
207 qCritical(log) << "new CConnectThread fail";
208 return -2;
209 }
210
211 m_pThread->start();
212
213 return nRet;
214}
215
217{
218 qDebug(log) << Q_FUNC_INFO;
219 int nRet = 0;
220 if(m_pThread)
221 {
222 m_pThread->quit();
223 //Don't delete m_pThread, See CConnectThread
224 m_pThread = nullptr;
225 }
226 return nRet;
227}
228
230{
231 if(GetParameter())
232 if(!GetParameter()->GetShowServerName()
233 || CConnecterConnect::ServerName().isEmpty())
234 {
235 if(!GetParameter()->m_Net.GetHost().isEmpty())
236 return GetParameter()->m_Net.GetHost() + ":"
237 + QString::number(GetParameter()->m_Net.GetPort());
238 }
240}
241
242int CConnecterThread::Load(QSettings &set)
243{
244 int nRet = 0;
245 Q_ASSERT(m_pFrmViewer);
246 nRet = CConnecterConnect::Load(set);
247 if(m_pFrmViewer && GetParameter())
248 {
249 m_pFrmViewer->slotSetZoomFactor(GetParameter()->GetZoomFactor());
250 if(m_psbZoomFactor)
251 m_psbZoomFactor->setValue(m_pFrmViewer->GetZoomFactor() * 100);
252 CFrmViewer::ADAPT_WINDOWS aw = GetParameter()->GetAdaptWindows();
254 if(m_pZoomToWindow)
255 m_pZoomToWindow->setChecked(true);
257 if(m_pZoomAspectRatio)
258 m_pZoomAspectRatio->setChecked(true);
259 } else if(CFrmViewer::ADAPT_WINDOWS::Original == aw) {
260 if(m_pZoomOriginal)
261 m_pZoomOriginal->setChecked(true);
262 } else if(CFrmViewer::ADAPT_WINDOWS::Zoom == aw) {
263 if(m_pZoomIn)
264 m_pZoomIn->setChecked(true);
265 }
266 }
267 return nRet;
268}
269
270int CConnecterThread::Save(QSettings &set)
271{
272 int nRet = 0;
273 Q_ASSERT(GetParameter());
274 if(GetParameter() && m_pFrmViewer)
275 {
276 GetParameter()->SetAdaptWindows(m_pFrmViewer->GetAdaptWindows());
277 GetParameter()->SetZoomFactor(m_pFrmViewer->GetZoomFactor());
278 }
279 nRet = CConnecterConnect::Save(set);
280 return nRet;
281}
282
283#if HAVE_QT6_RECORD
284void CConnecterThread::slotRecord(bool checked)
285{
286 qDebug(log) << Q_FUNC_INFO << checked;
287 QAction* pRecord = qobject_cast<QAction*>(sender());
288 if(pRecord)
289 {
290 if(checked) {
291 //pRecord->setIcon(QIcon::fromTheme("media-playback-stop"));
292 pRecord->setText(tr("Stop record"));
293 } else {
294 //pRecord->setIcon(QIcon::fromTheme("media-playback-start"));
295 pRecord->setText(tr("Start record"));
296 }
297 m_pRecordPause->setEnabled(checked);
298 emit sigRecord(checked);
299 }
300}
301
302void CConnecterThread::slotRecorderStateChanged(
303 QMediaRecorder::RecorderState state)
304{
305 qDebug(log) << Q_FUNC_INFO << state;
306 if(QMediaRecorder::StoppedState == state)
307 {
308 m_pRecord->setChecked(false);
309 m_pRecordPause->setChecked(false);
310 }
311}
312#endif
313
315{
316 if(!m_pScroll || !m_pFrmViewer) return;
317 m_pFrmViewer->slotSetZoomFactor(((double)v) / 100);
318 m_pScroll->slotSetAdaptWindows(CFrmViewer::ADAPT_WINDOWS::Zoom);
319}
320
321void CConnecterThread::slotScreenShot()
322{
323 if(!GetParameter() || !m_pFrmViewer)
324 return;
325 auto &record = GetParameter()->m_Record;
326 QString szFile = record.GetImageFile(true);
327 bool bRet = m_pFrmViewer->GrabImage().save(szFile);
328 if(bRet)
329 qDebug(log) << "Success: save screenshot to" << szFile;
330 else
331 qCritical(log) << "Fail: save screenshot to" << szFile;
332 if(record.GetEndAction() != CParameterRecord::ENDACTION::No)
333 QDesktopServices::openUrl(QUrl::fromLocalFile(szFile));
334}
335
336void CConnecterThread::slotShortcutCtlAltDel()
337{
338 if(!m_pFrmViewer)
339 return;
340
341 // Send ctl+alt+del
342 emit m_pFrmViewer->sigKeyPressEvent(new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Control, Qt::ControlModifier));
343 emit m_pFrmViewer->sigKeyPressEvent(new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Alt, Qt::AltModifier));
344 emit m_pFrmViewer->sigKeyPressEvent(new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Delete, Qt::ControlModifier | Qt::AltModifier));
345 emit m_pFrmViewer->sigKeyPressEvent(new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Control, Qt::ControlModifier));
346 emit m_pFrmViewer->sigKeyPressEvent(new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Alt, Qt::AltModifier));
347 emit m_pFrmViewer->sigKeyPressEvent(new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Delete, Qt::ControlModifier | Qt::AltModifier));
348}
349
350void CConnecterThread::slotShortcutLock()
351{
352 if(!m_pFrmViewer)
353 return;
354
355 // Send ctl+alt+del
356 emit m_pFrmViewer->sigKeyPressEvent(new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Super_L, Qt::NoModifier));
357 emit m_pFrmViewer->sigKeyPressEvent(new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_L, Qt::NoModifier));
358 emit m_pFrmViewer->sigKeyPressEvent(new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Super_L, Qt::NoModifier));
359 emit m_pFrmViewer->sigKeyPressEvent(new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_L, Qt::NoModifier));
360}
The class only is used by CConnecterThread.
The connector interface of the plug-in, which is only used by the plug-in.
virtual CParameterBase * GetParameter()
Get parameter.
virtual QString ServerName()
Current connect server name (remote desktop name, if not present, then IP:PORT).
It starts a background thread by default.
virtual int Load(QSettings &set) override
Load parameters.
virtual QWidget * GetViewer() override
Get Viewer.
virtual int Initial() override
Initial parameters and resource.
void slotValueChanged(int v)
emit by zoom menu in the class
virtual int Clean() override
Clean parameters and resource.
virtual int DisConnect() override
emit sigConnected() in CConnectThread::run()
virtual QString ServerName() override
Current connect server name (remote desktop name, if not present, then IP:PORT).
virtual int Connect() override
Start a background thread, and create an instance of CConnect .
virtual int Save(QSettings &set) override
Save parameters.
virtual int Load(QSettings &set)
Load parameters.
virtual Q_INVOKABLE int Clean()
Clean parameters and resource.
virtual int Save(QSettings &set)
Save parameters.
virtual Q_INVOKABLE int Initial()
Initial parameters and resource.
void sigViewerFocusIn(QWidget *pView)
The view is focus.
The scroll form class.
Definition FrmScroll.h:17
A widget which displays output image from a CConnectDesktop and sends input keypresses and mouse acti...
Definition FrmViewer.h:49
ADAPT_WINDOWS
The ADAPT_WINDOWS enum.
Definition FrmViewer.h:61
@ Original
Original desktop size, the left-top of the desktop is aligned with the left-top of the window.
@ Zoom
zoom windows = desktop size * factor
@ KeepAspectRationToWindow
Keep desktop aspectration adapt to windows.
@ ZoomToWindow
Desktop adapt to windows.
double GetZoomFactor() const
Adjust the zoom factor.
The plugin interface.