3#include <QLoggingCategory>
4#include <QDesktopServices>
6#include <QWidgetAction>
9#include "OperateDesktop.h"
10#include "BackendThread.h"
13static Q_LOGGING_CATEGORY(log,
"Operate.Desktop")
18 , m_pFrmViewer(
nullptr)
20 , m_pZoomToWindow(
nullptr)
21 , m_pZoomAspectRatio(
nullptr)
22 , m_pZoomOriginal(
nullptr)
25 , m_psbZoomFactor(
nullptr)
26 , m_pScreenShot(
nullptr)
29 , m_pRecordPause(
nullptr)
32 qDebug(log) << Q_FUNC_INFO;
35COperateDesktop::~COperateDesktop()
37 qDebug(log) << Q_FUNC_INFO;
49 +
"_" + QString::number(
GetParameter()->m_Net.GetPort());
54 case CParameterProxy::TYPE::Http: {
59 case CParameterProxy::TYPE::SockesV5:
65 case CParameterProxy::TYPE::SSHTunnel:
74 if(!szType.isEmpty() && !net->GetHost().isEmpty()) {
75 szId +=
"_" + szType +
"_";
76 szId += net->GetHost() +
"_" + QString::number(net->GetPort());
79 static QRegularExpression exp(
"[-@:/#%!^&* \\.]");
80 szId = szId.replace(exp,
"_");
88 &&
GetParameter()->GetGlobalParameters()->GetShowProtocolPrefix())
99 QString szDescription;
100 if(!
Name().isEmpty())
101 szDescription = tr(
"Name: ") +
Name() +
"\n";
104 szDescription += tr(
"Type:") +
GetTypeName() +
"\n";
107 szDescription += tr(
"Protocol: ") +
Protocol();
109 if(!
GetPlugin()->DisplayName().isEmpty())
112 szDescription +=
"\n";
116 szDescription += tr(
"Server name: ") +
ServerName() +
"\n";
120 szDescription += tr(
"Server address: ") +
GetParameter()->m_Net.GetHost() +
":"
121 + QString::number(
GetParameter()->m_Net.GetPort()) +
"\n";
123 QString szProxy(tr(
"Proxy") +
" ");
125 switch(proxy.GetUsedType()) {
126 case CParameterProxy::TYPE::SSHTunnel:
128 auto &sshNet = proxy.m_SSH.m_Net;
129 szProxy +=
"(" + tr(
"SSH tunnel") +
"): " + sshNet.GetHost() +
":"
130 + QString::number(sshNet.GetPort());
133 case CParameterProxy::TYPE::SockesV5:
135 auto &sockesV5 = proxy.m_SockesV5;
136 szProxy +=
"(" + tr(
"Sockes v5") +
"): " + sockesV5.GetHost() +
":"
137 + QString::number(sockesV5.GetPort());
145 if(!szProxy.isEmpty())
146 szDescription += szProxy +
"\n";
149 if(GetSecurityLevel() != SecurityLevel::No)
150 szDescription += tr(
"Security level: ") + GetSecurityLevelString() +
"\n";
155 return szDescription;
165 qDebug(log) << Q_FUNC_INFO;
173 Q_ASSERT(!(m_pFrmViewer && m_pScroll));
181 nRet = InitialMenu();
188 qDebug(log) << Q_FUNC_INFO;
199int COperateDesktop::InitialMenu()
204 QMenu* pMenuZoom =
new QMenu(&m_Menu);
205 pMenuZoom->setTitle(tr(
"Zoom"));
206 pMenuZoom->setIcon(QIcon::fromTheme(
"zoom"));
207 pMenuZoom->setStatusTip(tr(
"Zoom"));
208 m_pMenuZoom = m_Menu.addMenu(pMenuZoom);
209 m_pZoomToWindow = pMenuZoom->addAction(
210 QIcon::fromTheme(
"zoom-fit-best"), tr(
"Zoom to window"));
211 m_pZoomToWindow->setCheckable(
true);
212 m_pZoomToWindow->setStatusTip(tr(
"Zoom to window"));
213 m_pZoomToWindow->setToolTip(tr(
"Zoom to window"));
214 check = connect(m_pZoomToWindow, &QAction::triggered,
this,
216 m_pScroll->slotSetAdaptWindows(
220 m_pZoomAspectRatio = pMenuZoom->addAction(
221 QIcon::fromTheme(
"zoom-aspect-ratio"),
222 tr(
"Keep aspect ration to windows"));
223 m_pZoomAspectRatio->setCheckable(
true);
224 m_pZoomAspectRatio->setStatusTip(tr(
"Keep aspect ration to windows"));
225 m_pZoomAspectRatio->setToolTip(tr(
"Keep aspect ration to windows"));
226 check = connect(m_pZoomAspectRatio, &QAction::triggered,
this,
228 m_pScroll->slotSetAdaptWindows(
232 m_pZoomOriginal = pMenuZoom->addAction(
233 QIcon::fromTheme(
"zoom-original"), tr(
"Original"));
234 m_pZoomOriginal->setCheckable(
true);
235 m_pZoomOriginal->setStatusTip(tr(
"Original"));
236 m_pZoomOriginal->setToolTip(tr(
"Original"));
237 check = connect(m_pZoomOriginal, &QAction::triggered,
this,
239 m_pScroll->slotSetAdaptWindows(
243 m_pZoomIn = pMenuZoom->addAction(QIcon::fromTheme(
"zoom-in"), tr(
"Zoom in"));
244 m_pZoomIn->setCheckable(
true);
245 m_pZoomIn->setStatusTip(tr(
"Zoom in"));
246 m_pZoomIn->setToolTip(tr(
"Zoom in"));
248 m_pZoomIn, &QAction::triggered,
this,
251 if(m_psbZoomFactor) {
253 qDebug(log) <<
"Zoom in:" << factor;
254 m_psbZoomFactor->setValue(factor);
258 m_pZoomOut = pMenuZoom->addAction(
259 QIcon::fromTheme(
"zoom-out"), tr(
"Zoom out"));
260 m_pZoomOut->setCheckable(
true);
261 m_pZoomOut->setStatusTip(tr(
"Zoom out"));
262 m_pZoomOut->setToolTip(tr(
"Zoom out"));
264 m_pZoomOut, &QAction::triggered,
this,
267 if(m_psbZoomFactor) {
269 qDebug(log) <<
"Zoom out:" << factor;
270 m_psbZoomFactor->setValue(factor);
274 QActionGroup* pGBViewZoom =
new QActionGroup(
this);
276 pGBViewZoom->addAction(m_pZoomToWindow);
277 pGBViewZoom->addAction(m_pZoomAspectRatio);
278 pGBViewZoom->addAction(m_pZoomOriginal);
279 pGBViewZoom->addAction(m_pZoomIn);
280 pGBViewZoom->addAction(m_pZoomOut);
281 check = connect(pGBViewZoom, &QActionGroup::triggered,
282 this, [&](QAction* a){
283 if(a == m_pZoomIn || a == m_pZoomOut)
284 m_psbZoomFactor->setEnabled(
true);
286 m_psbZoomFactor->setEnabled(
false);
290 m_psbZoomFactor =
new QSpinBox(pMenuZoom);
291 m_psbZoomFactor->setRange(0, 9999999);
292 m_psbZoomFactor->setValue(100);
293 m_psbZoomFactor->setSuffix(
"%");
294 m_psbZoomFactor->setEnabled(
false);
297 m_psbZoomFactor, SIGNAL(valueChanged(
int)),
300 QWidgetAction* pFactor =
new QWidgetAction(pMenuZoom);
301 pFactor->setDefaultWidget(m_psbZoomFactor);
302 pMenuZoom->insertAction(m_pZoomOut, pFactor);
304 QMenu* pMenuShortCut =
new QMenu(&m_Menu);
305 pMenuShortCut->setTitle(tr(
"Send shortcut key"));
306 m_Menu.addMenu(pMenuShortCut);
307 pMenuShortCut->addAction(
308 tr(
"Send Ctl+Alt+Del"),
this, SLOT(slotShortcutCtlAltDel()));
309 pMenuShortCut->addAction(
310 tr(
"Send lock screen (Win+L)"),
this, SLOT(slotShortcutLock()));
312 m_Menu.addSeparator();
313 m_pScreenShot =
new QAction(QIcon::fromTheme(
"camera-photo"),
314 tr(
"ScreenShot"), &m_Menu);
315 m_pScreenShot->setStatusTip(tr(
"ScreenShot"));
316 m_pScreenShot->setToolTip(tr(
"ScreenShot"));
317 check = connect(m_pScreenShot, SIGNAL(triggered()),
318 this, SLOT(slotScreenShot()));
320 m_Menu.addAction(m_pScreenShot);
322 m_pRecord =
new QAction(
323 QIcon::fromTheme(
"media-record"), tr(
"Start record"), &m_Menu);
324 m_pRecord->setCheckable(
true);
325 m_pRecord->setStatusTip(tr(
"Start record"));
326 m_pRecord->setToolTip(tr(
"Start record"));
327 check = connect(m_pRecord, SIGNAL(triggered(
bool)),
328 this, SLOT(slotRecord(
bool)));
330 m_Menu.addAction(m_pRecord);
331 m_pRecordPause =
new QAction(
332 QIcon::fromTheme(
"media-playback-pause"), tr(
"Record pause"), &m_Menu);
333 m_pRecordPause->setToolTip(tr(
"Record pause"));
334 m_pRecordPause->setStatusTip(tr(
"Record pause"));
335 m_pRecordPause->setCheckable(
true);
336 m_pRecordPause->setEnabled(
false);
337 check = connect(m_pRecordPause, SIGNAL(triggered(
bool)),
338 this, SIGNAL(sigRecordPause(
bool)));
340 m_Menu.addAction(m_pRecordPause);
343 m_Menu.addSeparator();
344 if(m_pActionSettings)
345 m_Menu.addAction(m_pActionSettings);
355int COperateDesktop::Start()
357 qDebug(log) << Q_FUNC_INFO;
361 qCritical(log) <<
"new CBackendThread fail";
370int COperateDesktop::Stop()
372 qDebug(log) << Q_FUNC_INFO;
392 QString szMsg =
"There is not parameters! "
393 "please first create parameters, "
394 "then call SetParameter() in the ";
395 szMsg += metaObject()->className() + QString(
"::")
396 + metaObject()->className();
397 szMsg += QString(
"() or ") + metaObject()->className()
398 + QString(
"::") +
"Initial()";
399 szMsg +=
" to set the parameters pointer. "
400 "Default set CParameterClient for the parameters of operate "
401 "(CParameterOperate or its derived classes) "
402 "See CManager::CreateOperate. "
403 "If you are sure the parameter of operate "
404 "does not need CParameterClient. "
405 "Please overload the SetGlobalParameters() in the ";
406 szMsg += QString(metaObject()->className()) +
" . don't set it";
407 qCritical(log) << szMsg.toStdString().c_str();
425 check = connect(
GetParameter(), SIGNAL(sigNameChanged()),
426 this, SLOT(slotUpdateName()));
428 check = connect(
GetParameter(), SIGNAL(sigShowServerNameChanged()),
429 this, SLOT(slotUpdateName()));
438 check = connect(
GetParameter(), SIGNAL(sigZoomFactorChanged(
double)),
439 pViewer, SLOT(slotSetZoomFactor(
double)));
446 check = connect(
GetParameter(), SIGNAL(sigEnableInputMethod(
bool)),
447 pViewer, SLOT(slotEnableInputMethod(
bool)));
454int COperateDesktop::LoadAdaptWindows()
458 m_pFrmViewer->slotSetZoomFactor(
GetParameter()->GetZoomFactor());
460 m_psbZoomFactor->setValue(m_pFrmViewer->
GetZoomFactor() * 100);
463 if(m_pZoomToWindow) {
464 m_pZoomToWindow->trigger();
467 if(m_pZoomAspectRatio) {
468 m_pZoomAspectRatio->trigger();
471 if(m_pZoomOriginal) {
472 m_pZoomOriginal->trigger();
476 m_pZoomIn->trigger();
486 Q_ASSERT(m_pFrmViewer);
489 nRet = m_pPara->
Load(set);
491 QString szMsg =
"There is not parameters! "
492 "please first create parameters, "
493 "then call SetParameter() in the ";
494 szMsg += metaObject()->className() + QString(
"::")
495 + metaObject()->className();
496 szMsg += QString(
"() or ") + metaObject()->className()
497 + QString(
"::") +
"Initial()";
498 szMsg +=
" to set the parameters pointer. ";
499 qWarning(log) << szMsg.toStdString().c_str();
513 GetParameter()->SetAdaptWindows(m_pFrmViewer->GetAdaptWindows());
518 nRet = m_pPara->
Save(set);
523void COperateDesktop::slotRecord(
bool checked)
525 qDebug(log) << Q_FUNC_INFO << checked;
526 QAction* pRecord = qobject_cast<QAction*>(sender());
531 pRecord->setText(tr(
"Stop record"));
534 pRecord->setText(tr(
"Start record"));
536 m_pRecordPause->setEnabled(checked);
537 emit sigRecord(checked);
541void COperateDesktop::slotRecorderStateChanged(
542 QMediaRecorder::RecorderState state)
544 qDebug(log) << Q_FUNC_INFO << state;
545 if(QMediaRecorder::StoppedState == state)
547 m_pRecord->setChecked(
false);
548 m_pRecordPause->setChecked(
false);
555 qDebug(log) <<
"zoom:" << v;
556 if(!m_pScroll || !m_pFrmViewer)
return;
557 m_pFrmViewer->slotSetZoomFactor(((
double)v) / 100);
561void COperateDesktop::slotScreenShot()
566 QString szFile = record.GetImageFile(
true);
567 bool bRet = m_pFrmViewer->GrabImage().save(szFile);
569 qDebug(log) <<
"Success: save screenshot to" << szFile;
571 qCritical(log) <<
"Fail: save screenshot to" << szFile;
572 if(record.GetEndAction() != CParameterRecord::ENDACTION::No)
573 QDesktopServices::openUrl(QUrl::fromLocalFile(szFile));
576void COperateDesktop::slotShortcutCtlAltDel()
581 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Control, Qt::ControlModifier));
582 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Alt, Qt::AltModifier));
583 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Delete, Qt::ControlModifier | Qt::AltModifier));
584 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Control, Qt::ControlModifier));
585 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Alt, Qt::AltModifier));
586 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Delete, Qt::ControlModifier | Qt::AltModifier));
589void COperateDesktop::slotShortcutLock()
594 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Super_L, Qt::NoModifier));
595 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_L, Qt::NoModifier));
596 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Super_L, Qt::NoModifier));
597 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_L, Qt::NoModifier));
605 || m_szServerName.isEmpty())
612 &&
GetParameter()->GetGlobalParameters()->GetShowIpPortInName())
615 +
":" + QString::number(
GetParameter()->m_Net.GetPort());
619 return m_szServerName;
624 if(m_szServerName == szName)
627 m_szServerName = szName;
A widget which displays output image from a CConnectDesktop and sends input keypresses and mouse acti...
ADAPT_WINDOWS
The ADAPT_WINDOWS enum.
@ 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.
Remote desktop operate interface.
virtual QString ServerName()
Current connect server name (remote desktop name, if not present, then IP:PORT).
virtual int SetParameter(CParameterBase *p)
Set parameter pointer.
virtual void slotSetServerName(const QString &szName)
virtual int Save(QSettings &set) override
Save parameters.
virtual const QString Name() override
Name.
virtual const qint16 Version() const override
Version.
virtual int Load(QSettings &set) override
Load parameters.
virtual const QString Id() override
Identity.
virtual int Initial() override
Initial parameters and resource.
virtual QWidget * GetViewer() override
Get Viewer.
void slotValueChanged(int v)
emit by zoom menu in the class
virtual int SetGlobalParameters(CParameterPlugin *pPara) override
Apply the global parameters of the plug-in.
virtual const QString Description() override
Description.
virtual int Clean() override
Clean parameters and resource.
virtual CParameterBase * GetParameter()
Get parameter.
virtual int Load(QSettings &set)
Load parameters.
virtual int Save(QSettings &set)
Save parameters.
virtual Q_INVOKABLE int Initial()
Initial parameters and resource.
virtual const QString Protocol() const
Protocol.
virtual Q_INVOKABLE int SetGlobalParameters(CParameterPlugin *pPara)=0
Apply the global parameters of the plug-in.
virtual Q_INVOKABLE int Clean()
Clean parameters and resource.
void sigViewerFocusIn(QWidget *pView)
The view is focus.
Q_INVOKABLE CPlugin * GetPlugin() const
Get plugin.
void sigUpdateParameters(COperate *pOperate)
Update parameters, notify application to save or show parameters.
virtual const QString Id()
Identity.
void sigUpdateName(const QString &szName)
virtual const QString GetTypeName() const
Get type name.
The interface of connecter parameters.
Basic network parameters.
Global parameters of plugins.
virtual int Save(QString szFile=QString(), bool bForce=true)
Save to file.
void sigChanged()
emit when the parameter changes Usually if required, the corresponding parameter corresponds to a cha...
virtual int Load(QString szFile=QString())
Load from file.
virtual const QString DisplayName() const
The plugin display name.
virtual const QString Description() const =0
Plugin description.