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;
47 +
"_" + QString::number(
GetParameter()->m_Net.GetPort());
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,
"_");
93 &&
GetParameter()->GetGlobalParameters()->GetShowProtocolPrefix()
104 QString szDescription;
105 if(!
Name().isEmpty())
106 szDescription = tr(
"Name: ") +
Name() +
"\n";
109 szDescription += tr(
"Type:") +
GetTypeName() +
"\n";
112 szDescription += tr(
"Protocol: ") +
Protocol();
114 if(!
GetPlugin()->DisplayName().isEmpty())
117 szDescription +=
"\n";
121 szDescription += tr(
"Server name: ") +
ServerName() +
"\n";
125 szDescription += tr(
"Server address: ") +
GetParameter()->m_Net.GetHost() +
":"
126 + QString::number(
GetParameter()->m_Net.GetPort()) +
"\n";
128 QString szProxy(tr(
"Proxy") +
" ");
130 switch(proxy.GetUsedType()) {
131 case CParameterProxy::TYPE::SSHTunnel:
133 auto &sshNet = proxy.m_SSH.m_Net;
134 szProxy +=
"(" + tr(
"SSH tunnel") +
"): " + sshNet.GetHost() +
":"
135 + QString::number(sshNet.GetPort());
138 case CParameterProxy::TYPE::SockesV5:
140 auto &sockesV5 = proxy.m_SockesV5;
141 szProxy +=
"(" + tr(
"Sockes v5") +
"): " + sockesV5.GetHost() +
":"
142 + QString::number(sockesV5.GetPort());
150 if(!szProxy.isEmpty())
151 szDescription += szProxy +
"\n";
154 if(GetSecurityLevel() != SecurityLevel::No)
155 szDescription += tr(
"Security level: ") + GetSecurityLevelString() +
"\n";
160 return szDescription;
170 qDebug(log) << Q_FUNC_INFO;
178 Q_ASSERT(!(m_pFrmViewer && m_pScroll));
186 nRet = InitialMenu();
193 qDebug(log) << Q_FUNC_INFO;
204int COperateDesktop::InitialMenu()
209 QMenu* pMenuZoom =
new QMenu(&m_Menu);
210 pMenuZoom->setTitle(tr(
"Zoom"));
211 pMenuZoom->setIcon(QIcon::fromTheme(
"zoom"));
212 pMenuZoom->setStatusTip(tr(
"Zoom"));
213 m_pMenuZoom = m_Menu.addMenu(pMenuZoom);
214 m_pZoomToWindow = pMenuZoom->addAction(
215 QIcon::fromTheme(
"zoom-fit-best"), tr(
"Zoom to window"));
216 m_pZoomToWindow->setCheckable(
true);
217 m_pZoomToWindow->setStatusTip(tr(
"Zoom to window"));
218 m_pZoomToWindow->setToolTip(tr(
"Zoom to window"));
219 check = connect(m_pZoomToWindow, &QAction::triggered,
this,
221 m_pScroll->slotSetAdaptWindows(
225 m_pZoomAspectRatio = pMenuZoom->addAction(
226 QIcon::fromTheme(
"zoom-aspect-ratio"),
227 tr(
"Keep aspect ration to windows"));
228 m_pZoomAspectRatio->setCheckable(
true);
229 m_pZoomAspectRatio->setStatusTip(tr(
"Keep aspect ration to windows"));
230 m_pZoomAspectRatio->setToolTip(tr(
"Keep aspect ration to windows"));
231 check = connect(m_pZoomAspectRatio, &QAction::triggered,
this,
233 m_pScroll->slotSetAdaptWindows(
237 m_pZoomOriginal = pMenuZoom->addAction(
238 QIcon::fromTheme(
"zoom-original"), tr(
"Original"));
239 m_pZoomOriginal->setCheckable(
true);
240 m_pZoomOriginal->setStatusTip(tr(
"Original"));
241 m_pZoomOriginal->setToolTip(tr(
"Original"));
242 check = connect(m_pZoomOriginal, &QAction::triggered,
this,
244 m_pScroll->slotSetAdaptWindows(
248 m_pZoomIn = pMenuZoom->addAction(QIcon::fromTheme(
"zoom-in"), tr(
"Zoom in"));
249 m_pZoomIn->setCheckable(
true);
250 m_pZoomIn->setStatusTip(tr(
"Zoom in"));
251 m_pZoomIn->setToolTip(tr(
"Zoom in"));
253 m_pZoomIn, &QAction::triggered,
this,
256 if(m_psbZoomFactor) {
258 qDebug(log) <<
"Zoom in:" << factor;
259 m_psbZoomFactor->setValue(factor);
263 m_pZoomOut = pMenuZoom->addAction(
264 QIcon::fromTheme(
"zoom-out"), tr(
"Zoom out"));
265 m_pZoomOut->setCheckable(
true);
266 m_pZoomOut->setStatusTip(tr(
"Zoom out"));
267 m_pZoomOut->setToolTip(tr(
"Zoom out"));
269 m_pZoomOut, &QAction::triggered,
this,
272 if(m_psbZoomFactor) {
274 qDebug(log) <<
"Zoom out:" << factor;
275 m_psbZoomFactor->setValue(factor);
279 QActionGroup* pGBViewZoom =
new QActionGroup(
this);
281 pGBViewZoom->addAction(m_pZoomToWindow);
282 pGBViewZoom->addAction(m_pZoomAspectRatio);
283 pGBViewZoom->addAction(m_pZoomOriginal);
284 pGBViewZoom->addAction(m_pZoomIn);
285 pGBViewZoom->addAction(m_pZoomOut);
286 check = connect(pGBViewZoom, &QActionGroup::triggered,
287 this, [&](QAction* a){
288 if(a == m_pZoomIn || a == m_pZoomOut)
289 m_psbZoomFactor->setEnabled(
true);
291 m_psbZoomFactor->setEnabled(
false);
295 m_psbZoomFactor =
new QSpinBox(pMenuZoom);
296 m_psbZoomFactor->setRange(0, 9999999);
297 m_psbZoomFactor->setValue(100);
298 m_psbZoomFactor->setSuffix(
"%");
299 m_psbZoomFactor->setEnabled(
false);
302 m_psbZoomFactor, SIGNAL(valueChanged(
int)),
305 QWidgetAction* pFactor =
new QWidgetAction(pMenuZoom);
306 pFactor->setDefaultWidget(m_psbZoomFactor);
307 pMenuZoom->insertAction(m_pZoomOut, pFactor);
309 QMenu* pMenuShortCut =
new QMenu(&m_Menu);
310 pMenuShortCut->setTitle(tr(
"Send shortcut key"));
311 m_Menu.addMenu(pMenuShortCut);
312 pMenuShortCut->addAction(
313 tr(
"Send Ctl+Alt+Del"),
this, SLOT(slotShortcutCtlAltDel()));
314 pMenuShortCut->addAction(
315 tr(
"Send lock screen (Win+L)"),
this, SLOT(slotShortcutLock()));
317 m_Menu.addSeparator();
318 m_pScreenShot =
new QAction(QIcon::fromTheme(
"camera-photo"),
319 tr(
"ScreenShot"), &m_Menu);
320 m_pScreenShot->setStatusTip(tr(
"ScreenShot"));
321 m_pScreenShot->setToolTip(tr(
"ScreenShot"));
322 check = connect(m_pScreenShot, SIGNAL(triggered()),
323 this, SLOT(slotScreenShot()));
325 m_Menu.addAction(m_pScreenShot);
327 m_pRecord =
new QAction(
328 QIcon::fromTheme(
"media-record"), tr(
"Start record"), &m_Menu);
329 m_pRecord->setCheckable(
true);
330 m_pRecord->setStatusTip(tr(
"Start record"));
331 m_pRecord->setToolTip(tr(
"Start record"));
332 check = connect(m_pRecord, SIGNAL(triggered(
bool)),
333 this, SLOT(slotRecord(
bool)));
335 m_Menu.addAction(m_pRecord);
336 m_pRecordPause =
new QAction(
337 QIcon::fromTheme(
"media-playback-pause"), tr(
"Record pause"), &m_Menu);
338 m_pRecordPause->setToolTip(tr(
"Record pause"));
339 m_pRecordPause->setStatusTip(tr(
"Record pause"));
340 m_pRecordPause->setCheckable(
true);
341 m_pRecordPause->setEnabled(
false);
342 check = connect(m_pRecordPause, SIGNAL(triggered(
bool)),
343 this, SIGNAL(sigRecordPause(
bool)));
345 m_Menu.addAction(m_pRecordPause);
348 m_Menu.addSeparator();
349 if(m_pActionSettings)
350 m_Menu.addAction(m_pActionSettings);
360int COperateDesktop::Start()
362 qDebug(log) << Q_FUNC_INFO;
366 qCritical(log) <<
"new CBackendThread fail";
375int COperateDesktop::Stop()
377 qDebug(log) << Q_FUNC_INFO;
397 QString szMsg =
"There is not parameters! "
398 "please first create parameters, "
399 "then call SetParameter() in the ";
400 szMsg += metaObject()->className() + QString(
"::")
401 + metaObject()->className();
402 szMsg += QString(
"() or ") + metaObject()->className()
403 + QString(
"::") +
"Initial()";
404 szMsg +=
" to set the parameters pointer. "
405 "Default set CParameterClient for the parameters of operate "
406 "(CParameterOperate or its derived classes) "
407 "See CManager::CreateOperate. "
408 "If you are sure the parameter of operate "
409 "does not need CParameterClient. "
410 "Please overload the SetGlobalParameters() in the ";
411 szMsg += QString(metaObject()->className()) +
" . don't set it";
412 qCritical(log) << szMsg.toStdString().c_str();
430 check = connect(
GetParameter(), SIGNAL(sigNameChanged()),
431 this, SLOT(slotUpdateName()));
433 check = connect(
GetParameter(), SIGNAL(sigShowServerNameChanged()),
434 this, SLOT(slotUpdateName()));
443 check = connect(
GetParameter(), SIGNAL(sigZoomFactorChanged(
double)),
444 pViewer, SLOT(slotSetZoomFactor(
double)));
451 check = connect(
GetParameter(), SIGNAL(sigEnableInputMethod(
bool)),
452 pViewer, SLOT(slotEnableInputMethod(
bool)));
459int COperateDesktop::LoadAdaptWindows()
463 m_pFrmViewer->slotSetZoomFactor(
GetParameter()->GetZoomFactor());
465 m_psbZoomFactor->setValue(m_pFrmViewer->
GetZoomFactor() * 100);
468 if(m_pZoomToWindow) {
469 m_pZoomToWindow->trigger();
472 if(m_pZoomAspectRatio) {
473 m_pZoomAspectRatio->trigger();
476 if(m_pZoomOriginal) {
477 m_pZoomOriginal->trigger();
481 m_pZoomIn->trigger();
491 Q_ASSERT(m_pFrmViewer);
494 nRet = m_pPara->
Load(set);
496 QString szMsg =
"There is not parameters! "
497 "please first create parameters, "
498 "then call SetParameter() in the ";
499 szMsg += metaObject()->className() + QString(
"::")
500 + metaObject()->className();
501 szMsg += QString(
"() or ") + metaObject()->className()
502 + QString(
"::") +
"Initial()";
503 szMsg +=
" to set the parameters pointer. ";
504 qWarning(log) << szMsg.toStdString().c_str();
518 GetParameter()->SetAdaptWindows(m_pFrmViewer->GetAdaptWindows());
523 nRet = m_pPara->
Save(set);
528void COperateDesktop::slotRecord(
bool checked)
530 qDebug(log) << Q_FUNC_INFO << checked;
531 QAction* pRecord = qobject_cast<QAction*>(sender());
536 pRecord->setText(tr(
"Stop record"));
539 pRecord->setText(tr(
"Start record"));
541 m_pRecordPause->setEnabled(checked);
542 emit sigRecord(checked);
546void COperateDesktop::slotRecorderStateChanged(
547 QMediaRecorder::RecorderState state)
549 qDebug(log) << Q_FUNC_INFO << state;
550 if(QMediaRecorder::StoppedState == state)
552 m_pRecord->setChecked(
false);
553 m_pRecordPause->setChecked(
false);
560 qDebug(log) <<
"zoom:" << v;
561 if(!m_pScroll || !m_pFrmViewer)
return;
562 m_pFrmViewer->slotSetZoomFactor(((
double)v) / 100);
566void COperateDesktop::slotScreenShot()
571 QString szFile = record.GetImageFile(
true);
572 bool bRet = m_pFrmViewer->GrabImage().save(szFile);
574 qDebug(log) <<
"Success: save screenshot to" << szFile;
576 qCritical(log) <<
"Fail: save screenshot to" << szFile;
577 if(record.GetEndAction() != CParameterRecord::ENDACTION::No)
578 QDesktopServices::openUrl(QUrl::fromLocalFile(szFile));
581void COperateDesktop::slotShortcutCtlAltDel()
586 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Control, Qt::ControlModifier));
587 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Alt, Qt::AltModifier));
588 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Delete, Qt::ControlModifier | Qt::AltModifier));
589 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Control, Qt::ControlModifier));
590 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Alt, Qt::AltModifier));
591 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Delete, Qt::ControlModifier | Qt::AltModifier));
594void COperateDesktop::slotShortcutLock()
599 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Super_L, Qt::NoModifier));
600 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_L, Qt::NoModifier));
601 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Super_L, Qt::NoModifier));
602 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_L, Qt::NoModifier));
610 || m_szServerName.isEmpty())
617 &&
GetParameter()->GetGlobalParameters()->GetShowIpPortInName())
620 +
":" + QString::number(
GetParameter()->m_Net.GetPort());
624 return m_szServerName;
629 if(m_szServerName == szName)
632 m_szServerName = szName;
用于显示从 CConnectDesktop 输出的图像,和向 CConnectDesktop 发送键盘、鼠标事件。
@ Original
原始桌面大小,桌面的左上点与窗口的左上点对齐
@ KeepAspectRationToWindow
保持长宽比缩放到窗口大小,窗口是固定的
@ ZoomToWindow
桌面缩放到窗口大小,窗口是固定的
double GetZoomFactor() const
调整缩放系数。 调整完成后需要调用 SetAdaptWindows(FrmViewer::Zoom) 缩放窗口大小。
virtual QString ServerName()
当前连接名(远程桌面的名称,如果没有,则是 IP:端口)。例如:服务名或 IP:端口
virtual int SetParameter(CParameterBase *p)
设置参数指针
virtual void slotSetServerName(const QString &szName)
virtual int Save(QSettings &set) override
保存参数
virtual const QString Name() override
Name
virtual const qint16 Version() const override
Version
virtual int Load(QSettings &set) override
加载参数
virtual const QString Id() override
Identity
virtual int Initial() override
Initial parameters and resource
virtual QWidget * GetViewer() override
得到显示视图
void slotValueChanged(int v)
emit by zoom menu in the class
virtual int SetGlobalParameters(CParameterPlugin *pPara) override
应用插件全局参数
virtual const QString Description() override
Description
virtual int Clean() override
Clean parameters and resource
virtual CParameterBase * GetParameter()
Get parameter
virtual int Load(QSettings &set)
加载参数
virtual int Save(QSettings &set)
保存参数
virtual Q_INVOKABLE int Initial()
Initial parameters and resource
virtual const QString Protocol() const
Protocol
virtual Q_INVOKABLE int SetGlobalParameters(CParameterPlugin *pPara)=0
应用插件全局参数
virtual Q_INVOKABLE int Clean()
Clean parameters and resource
void sigViewerFocusIn(QWidget *pView)
视图获得焦点
Q_INVOKABLE CPlugin * GetPlugin() const
Get plugin
void sigUpdateParameters(COperate *pOperate)
更新参数,通知应用程序保存或显示参数
virtual const QString Id()
Identity
void sigUpdateName(const QString &szName)
virtual const QString GetTypeName() const
Get type name
连接基础参数接口。包括基本参数(网络参数等)。 所有插件的连接参数都应从此类派生。
网络连接参数接口。此类仅在插件内有效。 其界面为 CParameterNetUI
virtual int Save(QString szFile=QString(), bool bForce=true)
Save to file
void sigChanged()
当参数改变时,触发 通常如果需要,则相应的参数会对应一个改变事件。
virtual int Load(QString szFile=QString())
Load from file
virtual const QString DisplayName() const
在界面上显示的名称
virtual const QString Description() const =0
描述