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 ratio to window"));
228 m_pZoomAspectRatio->setCheckable(
true);
229 m_pZoomAspectRatio->setStatusTip(tr(
"Keep aspect ratio to window"));
230 m_pZoomAspectRatio->setToolTip(tr(
"Keep aspect ratio to window"));
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;
396 bool check = connect(pPara, SIGNAL(sigShowProtocolPrefixChanged()),
397 this, SLOT(slotUpdateName()));
399 check = connect(pPara, SIGNAL(sigSHowIpPortInNameChanged()),
400 this, SLOT(slotUpdateName()));
407 QString szMsg =
"There is not parameters! "
408 "please first create parameters, "
409 "then call SetParameter() in the ";
410 szMsg += metaObject()->className() + QString(
"::")
411 + metaObject()->className();
412 szMsg += QString(
"() or ") + metaObject()->className()
413 + QString(
"::") +
"Initial()";
414 szMsg +=
" to set the parameters pointer. "
415 "Default set CParameterClient for the parameters of operate "
416 "(CParameterOperate or its derived classes) "
417 "See CManager::CreateOperate. "
418 "If you are sure the parameter of operate "
419 "does not need CParameterClient. "
420 "Please overload the SetGlobalParameters() in the ";
421 szMsg += QString(metaObject()->className()) +
" . don't set it";
422 qCritical(log) << szMsg.toStdString().c_str();
440 check = connect(
GetParameter(), SIGNAL(sigNameChanged()),
441 this, SLOT(slotUpdateName()));
443 check = connect(
GetParameter(), SIGNAL(sigShowServerNameChanged()),
444 this, SLOT(slotUpdateName()));
453 check = connect(
GetParameter(), SIGNAL(sigZoomFactorChanged(
double)),
454 pViewer, SLOT(slotSetZoomFactor(
double)));
461 check = connect(
GetParameter(), SIGNAL(sigEnableInputMethod(
bool)),
462 pViewer, SLOT(slotEnableInputMethod(
bool)));
469int COperateDesktop::LoadAdaptWindows()
473 m_pFrmViewer->slotSetZoomFactor(
GetParameter()->GetZoomFactor());
475 m_psbZoomFactor->setValue(m_pFrmViewer->
GetZoomFactor() * 100);
478 if(m_pZoomToWindow) {
479 m_pZoomToWindow->trigger();
482 if(m_pZoomAspectRatio) {
483 m_pZoomAspectRatio->trigger();
486 if(m_pZoomOriginal) {
487 m_pZoomOriginal->trigger();
491 m_pZoomIn->trigger();
501 Q_ASSERT(m_pFrmViewer);
504 nRet = m_pPara->
Load(set);
506 QString szMsg =
"There is not parameters! "
507 "please first create parameters, "
508 "then call SetParameter() in the ";
509 szMsg += metaObject()->className() + QString(
"::")
510 + metaObject()->className();
511 szMsg += QString(
"() or ") + metaObject()->className()
512 + QString(
"::") +
"Initial()";
513 szMsg +=
" to set the parameters pointer. ";
514 qWarning(log) << szMsg.toStdString().c_str();
528 GetParameter()->SetAdaptWindows(m_pFrmViewer->GetAdaptWindows());
533 nRet = m_pPara->
Save(set);
538void COperateDesktop::slotRecord(
bool checked)
540 qDebug(log) << Q_FUNC_INFO << checked;
541 QAction* pRecord = qobject_cast<QAction*>(sender());
546 pRecord->setText(tr(
"Stop record"));
549 pRecord->setText(tr(
"Start record"));
551 m_pRecordPause->setEnabled(checked);
552 emit sigRecord(checked);
556void COperateDesktop::slotRecorderStateChanged(
557 QMediaRecorder::RecorderState state)
559 qDebug(log) << Q_FUNC_INFO << state;
560 if(QMediaRecorder::StoppedState == state)
562 m_pRecord->setChecked(
false);
563 m_pRecordPause->setChecked(
false);
570 qDebug(log) <<
"zoom:" << v;
571 if(!m_pScroll || !m_pFrmViewer)
return;
572 m_pFrmViewer->slotSetZoomFactor(((
double)v) / 100);
576void COperateDesktop::slotScreenShot()
581 QString szFile = record.GetImageFile(
true);
582 bool bRet = m_pFrmViewer->GrabImage().save(szFile);
584 qDebug(log) <<
"Success: save screenshot to" << szFile;
586 qCritical(log) <<
"Fail: save screenshot to" << szFile;
587 if(record.GetEndAction() != CParameterRecord::ENDACTION::No)
588 QDesktopServices::openUrl(QUrl::fromLocalFile(szFile));
591void COperateDesktop::slotShortcutCtlAltDel()
596 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Control, Qt::ControlModifier));
597 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Alt, Qt::AltModifier));
598 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Delete, Qt::ControlModifier | Qt::AltModifier));
599 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Control, Qt::ControlModifier));
600 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Alt, Qt::AltModifier));
601 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Delete, Qt::ControlModifier | Qt::AltModifier));
604void COperateDesktop::slotShortcutLock()
609 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Super_L, Qt::NoModifier));
610 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_L, Qt::NoModifier));
611 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_Super_L, Qt::NoModifier));
612 emit m_pFrmViewer->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyRelease, Qt::Key_L, Qt::NoModifier));
620 || m_szServerName.isEmpty())
627 &&
GetParameter()->GetGlobalParameters()->GetShowIpPortInName())
630 +
":" + QString::number(
GetParameter()->m_Net.GetPort());
634 return m_szServerName;
639 if(m_szServerName == szName)
642 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 Save(QSettings &set)=0
保存参数
virtual int Load(QSettings &set)=0
加载参数
virtual Q_INVOKABLE int Initial()
Initial parameters and resource
virtual const QString Protocol() const
Protocol
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
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
描述