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;
40const QString COperateDesktop::Id()
42 QString szId = COperate::Id();
47 +
"_" + QString::number(
GetParameter()->m_Net.GetPort());
48 CParameterNet* net =
nullptr;
52 case CParameterProxy::TYPE::Http: {
57 case CParameterProxy::TYPE::SockesV5:
63 case CParameterProxy::TYPE::SSHTunnel:
72 if(!szType.isEmpty() && !net->GetHost().isEmpty()) {
73 szId +=
"_" + szType +
"_";
74 szId += net->GetHost() +
"_" + QString::number(net->GetPort());
80 static QRegularExpression exp(
"[-@:/#%!^&* \\.]");
81 szId = szId.replace(exp,
"_");
95 && (
GetParameter()->GetPluginParameters()->GetNameStyles()
96 & CParameterPlugin::NameStyle::Protocol)
97 && !Protocol().isEmpty())
98 szName = Protocol() +
": ";
107 QString szSecurityLevel;
109 if((
GetParameter()->GetPluginParameters()->GetNameStyles()
110 & CParameterPlugin::NameStyle::SecurityLevel)
112 && !sl.GetUnicodeIcon().isEmpty())
113 szSecurityLevel = sl.GetUnicodeIcon().left(2);
115 return szSecurityLevel + szName;
122 QString szDescription;
123 if(!
Name().isEmpty())
124 szDescription = tr(
"Name: ") +
Name() +
"\n";
126 if(!GetTypeName().isEmpty())
127 szDescription += tr(
"Type: ") + GetTypeName() +
"\n";
129 if(!Protocol().isEmpty()) {
130 szDescription += tr(
"Protocol: ") + Protocol();
132 if(!
GetPlugin()->DisplayName().isEmpty())
135 szDescription +=
"\n";
139 szDescription += tr(
"Server name: ") +
ServerName() +
"\n";
143 szDescription += tr(
"Server address: ") +
GetParameter()->m_Net.GetHost() +
":"
144 + QString::number(
GetParameter()->m_Net.GetPort()) +
"\n";
146 QString szProxy(tr(
"Proxy") +
" ");
148 switch(proxy.GetUsedType()) {
149 case CParameterProxy::TYPE::SSHTunnel:
151 auto &sshNet = proxy.m_SSH.m_Net;
152 szProxy +=
"(" + tr(
"SSH tunnel") +
"): " + sshNet.GetHost() +
":"
153 + QString::number(sshNet.GetPort());
156 case CParameterProxy::TYPE::SockesV5:
158 auto &sockesV5 = proxy.m_SockesV5;
159 szProxy +=
"(" + tr(
"Sockes v5") +
"): " + sockesV5.GetHost() +
":"
160 + QString::number(sockesV5.GetPort());
168 if(!szProxy.isEmpty())
169 szDescription += szProxy +
"\n";
174 szDescription += tr(
"Security level: ");
175 if(!sl.GetUnicodeIcon().isEmpty())
176 szDescription += sl.GetUnicodeIcon() +
" ";
177 szDescription += sl.GetString() +
"\n";
183 return szDescription;
194 qDebug(log) << Q_FUNC_INFO;
202 Q_ASSERT(!(m_pFrmViewer && m_pScroll));
210 nRet = InitialMenu();
217 qDebug(log) << Q_FUNC_INFO;
228int COperateDesktop::InitialMenu()
233 QMenu* pMenuZoom =
new QMenu(&m_Menu);
234 pMenuZoom->setTitle(tr(
"Zoom"));
235 pMenuZoom->setIcon(QIcon::fromTheme(
"zoom"));
236 pMenuZoom->setStatusTip(tr(
"Zoom"));
237 m_pMenuZoom = m_Menu.addMenu(pMenuZoom);
238 m_pZoomToWindow = pMenuZoom->addAction(
239 QIcon::fromTheme(
"zoom-fit-best"), tr(
"Zoom to window"));
240 m_pZoomToWindow->setCheckable(
true);
241 m_pZoomToWindow->setStatusTip(tr(
"Zoom to window"));
242 m_pZoomToWindow->setToolTip(tr(
"Zoom to window"));
243 check = connect(m_pZoomToWindow, &QAction::triggered,
this,
245 m_pScroll->slotSetAdaptWindows(
249 m_pZoomAspectRatio = pMenuZoom->addAction(
250 QIcon::fromTheme(
"zoom-aspect-ratio"),
251 tr(
"Keep aspect ratio to window"));
252 m_pZoomAspectRatio->setCheckable(
true);
253 m_pZoomAspectRatio->setStatusTip(tr(
"Keep aspect ratio to window"));
254 m_pZoomAspectRatio->setToolTip(tr(
"Keep aspect ratio to window"));
255 check = connect(m_pZoomAspectRatio, &QAction::triggered,
this,
257 m_pScroll->slotSetAdaptWindows(
261 m_pZoomOriginal = pMenuZoom->addAction(
262 QIcon::fromTheme(
"zoom-original"), tr(
"Original"));
263 m_pZoomOriginal->setCheckable(
true);
264 m_pZoomOriginal->setStatusTip(tr(
"Original"));
265 m_pZoomOriginal->setToolTip(tr(
"Original"));
266 check = connect(m_pZoomOriginal, &QAction::triggered,
this,
268 m_pScroll->slotSetAdaptWindows(
272 m_pZoomIn = pMenuZoom->addAction(QIcon::fromTheme(
"zoom-in"), tr(
"Zoom in"));
273 m_pZoomIn->setCheckable(
true);
274 m_pZoomIn->setStatusTip(tr(
"Zoom in"));
275 m_pZoomIn->setToolTip(tr(
"Zoom in"));
277 m_pZoomIn, &QAction::triggered,
this,
280 if(m_psbZoomFactor) {
281 factor = (m_pFrmViewer->GetZoomFactor() + 0.1) * 100;
282 qDebug(log) <<
"Zoom in:" << factor;
283 m_psbZoomFactor->setValue(factor);
287 m_pZoomOut = pMenuZoom->addAction(
288 QIcon::fromTheme(
"zoom-out"), tr(
"Zoom out"));
289 m_pZoomOut->setCheckable(
true);
290 m_pZoomOut->setStatusTip(tr(
"Zoom out"));
291 m_pZoomOut->setToolTip(tr(
"Zoom out"));
293 m_pZoomOut, &QAction::triggered,
this,
296 if(m_psbZoomFactor) {
297 factor = (m_pFrmViewer->GetZoomFactor() - 0.1) * 100;
298 qDebug(log) <<
"Zoom out:" << factor;
299 m_psbZoomFactor->setValue(factor);
303 QActionGroup* pGBViewZoom =
new QActionGroup(
this);
305 pGBViewZoom->addAction(m_pZoomToWindow);
306 pGBViewZoom->addAction(m_pZoomAspectRatio);
307 pGBViewZoom->addAction(m_pZoomOriginal);
308 pGBViewZoom->addAction(m_pZoomIn);
309 pGBViewZoom->addAction(m_pZoomOut);
310 check = connect(pGBViewZoom, &QActionGroup::triggered,
311 this, [&](QAction* a){
312 if(a == m_pZoomIn || a == m_pZoomOut)
313 m_psbZoomFactor->setEnabled(
true);
315 m_psbZoomFactor->setEnabled(
false);
319 m_psbZoomFactor =
new QSpinBox(pMenuZoom);
320 m_psbZoomFactor->setRange(0, 9999999);
321 m_psbZoomFactor->setValue(100);
322 m_psbZoomFactor->setSuffix(
"%");
323 m_psbZoomFactor->setEnabled(
false);
326 m_psbZoomFactor, SIGNAL(valueChanged(
int)),
329 QWidgetAction* pFactor =
new QWidgetAction(pMenuZoom);
330 pFactor->setDefaultWidget(m_psbZoomFactor);
331 pMenuZoom->insertAction(m_pZoomOut, pFactor);
333 QMenu* pMenuShortCut =
new QMenu(&m_Menu);
334 pMenuShortCut->setTitle(tr(
"Send shortcut key"));
335 m_Menu.addMenu(pMenuShortCut);
336 pMenuShortCut->addAction(
337 tr(
"Send Ctl+Alt+Del"),
this, SLOT(slotShortcutCtlAltDel()));
338 pMenuShortCut->addAction(
339 tr(
"Send lock screen (Win+L)"),
this, SLOT(slotShortcutLock()));
341 m_Menu.addSeparator();
342 m_pScreenShot =
new QAction(QIcon::fromTheme(
"camera-photo"),
343 tr(
"ScreenShot"), &m_Menu);
344 m_pScreenShot->setStatusTip(tr(
"ScreenShot"));
345 m_pScreenShot->setToolTip(tr(
"ScreenShot"));
346 check = connect(m_pScreenShot, SIGNAL(triggered()),
347 this, SLOT(slotScreenShot()));
349 m_Menu.addAction(m_pScreenShot);
351 m_pRecord =
new QAction(
352 QIcon::fromTheme(
"media-record"), tr(
"Start record"), &m_Menu);
353 m_pRecord->setCheckable(
true);
354 m_pRecord->setStatusTip(tr(
"Start record"));
355 m_pRecord->setToolTip(tr(
"Start record"));
356 check = connect(m_pRecord, SIGNAL(triggered(
bool)),
357 this, SLOT(slotRecord(
bool)));
359 m_Menu.addAction(m_pRecord);
360 m_pRecordPause =
new QAction(
361 QIcon::fromTheme(
"media-playback-pause"), tr(
"Record pause"), &m_Menu);
362 m_pRecordPause->setToolTip(tr(
"Record pause"));
363 m_pRecordPause->setStatusTip(tr(
"Record pause"));
364 m_pRecordPause->setCheckable(
true);
365 m_pRecordPause->setEnabled(
false);
366 check = connect(m_pRecordPause, SIGNAL(triggered(
bool)),
367 this, SIGNAL(sigRecordPause(
bool)));
369 m_Menu.addAction(m_pRecordPause);
372 m_Menu.addSeparator();
373 if(m_pActionSettings)
374 m_Menu.addAction(m_pActionSettings);
386 qDebug(log) << Q_FUNC_INFO;
393 qCritical(log) <<
"new CBackendThread fail";
402 qDebug(log) << Q_FUNC_INFO;
420 bool check = connect(pPara, SIGNAL(sigNameStylesChanged()),
421 this, SLOT(slotUpdateName()));
428 QString szMsg =
"There is not parameters! "
429 "please first create parameters, "
430 "then call SetParameter() in the ";
431 szMsg += metaObject()->className() + QString(
"::")
432 + metaObject()->className();
433 szMsg += QString(
"() or ") + metaObject()->className()
434 + QString(
"::") +
"Initial()";
435 szMsg +=
" to set the parameters pointer. "
436 "Default set CParameterClient for the parameters of operate "
437 "(CParameterOperate or its derived classes) "
438 "See CManager::CreateOperate. "
439 "If you are sure the parameter of operate "
440 "does not need CParameterClient. "
441 "Please overload the SetPluginParameters() in the ";
442 szMsg += QString(metaObject()->className()) +
" . don't set it";
443 qCritical(log) << szMsg.toStdString().c_str();
462 check = connect(
GetParameter(), SIGNAL(sigNameChanged()),
463 this, SLOT(slotUpdateName()));
465 check = connect(
GetParameter(), SIGNAL(sigShowServerNameChanged()),
466 this, SLOT(slotUpdateName()));
475 check = connect(
GetParameter(), SIGNAL(sigZoomFactorChanged(
double)),
476 pViewer, SLOT(slotSetZoomFactor(
double)));
483 check = connect(
GetParameter(), SIGNAL(sigEnableInputMethod(
bool)),
484 pViewer, SLOT(slotEnableInputMethod(
bool)));
491int COperateDesktop::LoadAdaptWindows()
495 m_pFrmViewer->slotSetZoomFactor(
GetParameter()->GetZoomFactor());
497 m_psbZoomFactor->setValue(m_pFrmViewer->
GetZoomFactor() * 100);
500 if(m_pZoomToWindow) {
501 m_pZoomToWindow->trigger();
504 if(m_pZoomAspectRatio) {
505 m_pZoomAspectRatio->trigger();
508 if(m_pZoomOriginal) {
509 m_pZoomOriginal->trigger();
513 m_pZoomIn->trigger();
523 Q_ASSERT(m_pFrmViewer);
525 nRet = m_pPara->Load(set);
527 QString szMsg =
"There is not parameters! "
528 "please first create parameters, "
529 "then call SetParameter() in the ";
530 szMsg += metaObject()->className() + QString(
"::")
531 + metaObject()->className();
532 szMsg += QString(
"() or ") + metaObject()->className()
533 + QString(
"::") +
"Initial()";
534 szMsg +=
" to set the parameters pointer. ";
535 qWarning(log) << szMsg.toStdString().c_str();
536 Q_ASSERT_X(
false,
"COperateDesktop", szMsg.toStdString().c_str());
549 GetParameter()->SetAdaptWindows(m_pFrmViewer->GetAdaptWindows());
550 GetParameter()->SetZoomFactor(m_pFrmViewer->GetZoomFactor());
553 nRet = m_pPara->Save(set);
558void COperateDesktop::slotRecord(
bool checked)
560 qDebug(log) << Q_FUNC_INFO << checked;
561 QAction* pRecord = qobject_cast<QAction*>(sender());
566 pRecord->setText(tr(
"Stop record"));
569 pRecord->setText(tr(
"Start record"));
571 m_pRecordPause->setEnabled(checked);
572 emit sigRecord(checked);
576void COperateDesktop::slotRecorderStateChanged(
577 QMediaRecorder::RecorderState state)
579 qDebug(log) << Q_FUNC_INFO << state;
580 if(QMediaRecorder::StoppedState == state)
582 m_pRecord->setChecked(
false);
583 m_pRecordPause->setChecked(
false);
590 qDebug(log) <<
"zoom:" << v;
591 if(!m_pScroll || !m_pFrmViewer)
return;
592 m_pFrmViewer->slotSetZoomFactor(((
double)v) / 100);
596void COperateDesktop::slotScreenShot()
601 QString szFile = record.GetImageFile(
true);
602 bool bRet = m_pFrmViewer->GrabImage().save(szFile);
604 qDebug(log) <<
"Success: save screenshot to" << szFile;
606 qCritical(log) <<
"Fail: save screenshot to" << szFile;
607 if(record.GetEndAction() != CParameterRecord::ENDACTION::No)
608 QDesktopServices::openUrl(QUrl::fromLocalFile(szFile));
611void COperateDesktop::slotShortcutCtlAltDel()
616 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Control, Qt::ControlModifier));
617 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Alt, Qt::AltModifier));
618 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Delete, Qt::ControlModifier | Qt::AltModifier));
619 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Control, Qt::ControlModifier));
620 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Alt, Qt::AltModifier));
621 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Delete, Qt::ControlModifier | Qt::AltModifier));
624void COperateDesktop::slotShortcutLock()
629 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Super_L, Qt::NoModifier));
630 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_L, Qt::NoModifier));
631 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Super_L, Qt::NoModifier));
632 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_L, Qt::NoModifier));
641 || m_szServerName.isEmpty())
648 && !(
GetParameter()->GetPluginParameters()->GetNameStyles()
649 & CParameterPlugin::NameStyle::ServerName))
652 +
":" + QString::number(
GetParameter()->m_Net.GetPort());
658 return m_szServerName;
665 if(m_szServerName == szName)
668 m_szServerName = szName;
CBackendThread(COperate *pOperate, QObject *pParent=nullptr)
CBackendThread.
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 int SetPluginParameters(CParameterPlugin *pPara) override
Set Global Parameters.
virtual QString ServerName()
Current connect server name (remote desktop name, if not present, then IP:PORT).
virtual void slotSetServerName(const QString &szName)
[Get server name]
virtual Q_INVOKABLE int Save(QSettings &set) override
Save parameters.
virtual const QString Name() override
[The name of the desktop operate]
virtual CParameterDesktop * GetParameter() const
Get parameter.
virtual int SetParameter(CParameterDesktop *p)
Set parameter pointer.
virtual const qint16 Version() const override
[The description of the desktop operate]
virtual Q_INVOKABLE int Load(QSettings &set) override
Load parameters.
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 const QString Description() override
[The name of the desktop operate]
virtual int Clean() override
Clean parameters and resource.
virtual CSecurityLevel::Levels GetSecurityLevel() const
Get Security Level.
virtual int Start()=0
Start.
virtual Q_INVOKABLE int Initial()
Initial parameters and resource.
virtual Q_INVOKABLE int Clean()
Clean parameters and resource.
void sigViewerFocusIn(QWidget *pView)
The view is focus.
Q_INVOKABLE CPlugin * GetPlugin() const
Get plugin.
virtual int Stop()=0
Stop.
void sigUpdateParameters(COperate *pOperate)
Update parameters, notify application to save or show parameters.
The interface of remote desktop base parameters.
Global parameters of plugins.
void sigChanged()
emit when the parameter changes Usually if required, the corresponding parameter corresponds to a cha...
virtual const QString Name() const =0
This name must be the same as the project name (${PROJECT_NAME}). The translation file (${PROJECT_NAM...
virtual const QString DisplayName() const
The plugin display name.
virtual const QString Description() const =0
Plugin description.