3#include <QPluginLoader>
9#include <QLoggingCategory>
12#include "RabbitCommonDir.h"
13#include "RabbitCommonTools.h"
14#include "FrmParameterClient.h"
17#include "ParameterRecordUI.h"
19static Q_LOGGING_CATEGORY(log,
"Client")
29 qApp->installEventFilter(
this);
31 m_Translator = RabbitCommon::CTools::Instance()->InstallTranslator(
32 "Client", RabbitCommon::CTools::TranslationType::Library);
34 CChannel::InitTranslation();
37 if(m_pParameterClient) {
38 check = connect(m_pParameterClient, SIGNAL(sigHookKeyboardChanged()),
39 this, SLOT(slotHookKeyboardChanged()));
42 if(m_pParameterClient->GetHookKeyboard())
43 m_Hook = QSharedPointer<CHook>(CHook::GetHook());
45 qCritical(log) <<
"new CParameterClient() fail";
46 Q_ASSERT(m_pParameterClient);
54 qDebug(log) <<
"CClient::~CClient()";
56 if(m_pParameterClient)
57 delete m_pParameterClient;
59 qApp->installEventFilter(
nullptr);
62 RabbitCommon::CTools::Instance()->RemoveTranslator(m_Translator);
64 CChannel::RemoveTranslation();
71int CClient::LoadPlugins()
74 foreach (QObject *plugin, QPluginLoader::staticInstances())
79 if(m_Plugins.find(p->
Id()) == m_Plugins.end())
81 qInfo(log) <<
"Success: Load plugin" << p->
Name();
85 qWarning(log) <<
"The plugin" << p->
Name() <<
" is exist.";
89 QString szPath = RabbitCommon::CDir::Instance()->GetDirPlugins();
90#if !defined (Q_OS_ANDROID)
91 szPath = szPath + QDir::separator() +
"Client";
95#if defined (Q_OS_WINDOWS) || defined(Q_OS_WIN)
96 filters <<
"*PluginClient*.dll";
98 filters <<
"*PluginClient*.so";
100 nRet = FindPlugins(szPath, filters);
101 if(!m_szDetails.isEmpty())
102 m_szDetails = tr(
"### Plugins") +
"\n" + m_szDetails;
104 qDebug(log) << (
"Client details:\n" + Details()).toStdString().c_str();
108int CClient::FindPlugins(QDir dir, QStringList filters)
111 if(filters.isEmpty())
113#if defined (Q_OS_WINDOWS) || defined(Q_OS_WIN)
114 filters <<
"*PluginClient*.dll";
116 filters <<
"*PluginClient*.so";
120 QString szCurrentPath = QDir::currentPath();
121 QStringList files = dir.entryList(filters, QDir::Files | QDir::NoDotAndDotDot);
127 QDir::setCurrent(QDir::cleanPath(dir.absolutePath()));
138 foreach (fileName, files) {
139 QString szPlugins = dir.absoluteFilePath(fileName);
140 QPluginLoader loader(szPlugins);
141 QObject *plugin = loader.instance();
146 if(m_Plugins.find(p->
Id()) == m_Plugins.end())
148 qInfo(log) <<
"Success: Load plugin"
149 << p->
Name() <<
"from" << szPlugins;
153 qWarning(log) <<
"The plugin [" << p->
Name() <<
"] is exist.";
157 szMsg =
"Error: Load plugin fail from " + szPlugins;
158 if(!loader.errorString().isEmpty())
159 szMsg +=
"; Error: " + loader.errorString();
160 qCritical(log) << szMsg.toStdString().c_str();
164 foreach (fileName, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
165 QDir pluginDir = dir;
166 if(pluginDir.cd(fileName))
167 FindPlugins(pluginDir, filters);
170 QDir::setCurrent(szCurrentPath);
178 m_Plugins.insert(p->
Id(), p);
181 bool bRet = QMetaObject::invokeMethod(
184 Qt::DirectConnection,
185 Q_RETURN_ARG(
int, val));
188 qCritical(log) <<
"The plugin" << p->
Name()
189 <<
"initial translator fail" << bRet << val;
193 + tr(
"Version:") +
" " + p->
Version() +
" \n"
196 m_szDetails += p->
Details() +
"\n";
204 auto it = m_Plugins.find(
id);
205 if(m_Plugins.end() != it)
208 qDebug(log) <<
"CreateConnecter id:" << id;
209 auto plugin = it.value();
213 bRet = QMetaObject::invokeMethod(
216 Qt::DirectConnection,
220 qCritical(log) <<
"Create CConnecter fail.";
228 qCritical(log) <<
"Connecter initial fail" << nRet;
234 qCritical(log) <<
"SetParameterClient fail" << nRet;
247 qDebug(log) << Q_FUNC_INFO;
252 qWarning(log) <<
"Connecter clean fail" << nRet;
260 if(szFile.isEmpty())
return nullptr;
262 QSettings set(szFile, QSettings::IniFormat);
263 m_FileVersion = set.value(
"Manage/FileVersion", m_FileVersion).toInt();
264 QString
id = set.value(
"Plugin/ID").toString();
265 QString protocol = set.value(
"Plugin/Protocol").toString();
266 QString name = set.value(
"Plugin/Name").toString();
268 qDebug(log) <<
"LoadConnecter protocol:" << protocol
269 <<
"name:" << name <<
"id:" << id;
272 int nRet = pConnecter->
Load(szFile);
274 qCritical(log) <<
"Load parameter fail" << nRet;
280 qCritical(log) <<
"Don't create connecter:" << protocol;
287 if(!pConnecter)
return -1;
290 szFile = RabbitCommon::CDir::Instance()->GetDirUserData()
295 QSettings set(szFile, QSettings::IniFormat);
298 bool bRet = QMetaObject::invokeMethod(
301 Qt::DirectConnection,
303 if(!bRet || !pPluginClient)
305 qCritical(log) <<
"Get plugin client fail";
307 Q_ASSERT(pPluginClient);
309 set.setValue(
"Manage/FileVersion", m_FileVersion);
310 set.setValue(
"Plugin/ID", pPluginClient->
Id());
311 set.setValue(
"Plugin/Protocol", pPluginClient->
Protocol());
312 set.setValue(
"Plugin/Name", pPluginClient->
Name());
313 int nRet = pConnecter->
Save(szFile);
315 qCritical(log) <<
"Save parameter fail" << nRet;
323 return m_pParameterClient->CParameter::Load(szFile);
328 return m_pParameterClient->CParameter::Save(szFile);
333 QList<QWidget*> lstWidget;
338 lstWidget.push_back(pClient);
343 pRecord->SetParameter(&m_pParameterClient->m_Record);
344 lstWidget.push_back(pRecord);
353 QMap<QString, CPluginClient*>::iterator it;
354 for(it = m_Plugins.begin(); it != m_Plugins.end(); it++)
356 nRet = handle->
onProcess(it.key(), it.value());
367 QMap<QString, CPluginClient*>::iterator it;
368 for(it = m_Plugins.begin(); it != m_Plugins.end(); it++)
370 nRet = cb(it.key(), it.value());
378const QString CClient::Details()
const
383void CClient::slotHookKeyboardChanged()
385 if(m_pParameterClient->GetHookKeyboard())
387 m_Hook = QSharedPointer<CHook>(CHook::GetHook());
394bool CClient::eventFilter(QObject *watched, QEvent *event)
396 if(QEvent::KeyPress == event->type() || QEvent::KeyRelease == event->type())
399 bool bProcess =
false;
400 QKeyEvent *keyEvent =
static_cast<QKeyEvent *
>(event);
401 int key = keyEvent->key();
405 key = Qt::Key_Super_L;
407#if defined(Q_OS_MACOS)
408 key = Qt::Key_Control;
421 switch(event->type()) {
422 case QEvent::KeyPress:
424 CFrmViewer* focus = qobject_cast<CFrmViewer*>(QApplication::focusWidget());
426 emit focus->sigKeyPressEvent(keyEvent);
430 case QEvent::KeyRelease:
432 CFrmViewer* focus = qobject_cast<CFrmViewer*>(QApplication::focusWidget());
434 emit focus->sigKeyReleaseEvent(keyEvent);
443 return QObject::eventFilter(watched, event);
virtual int onProcess(const QString &id, CPluginClient *pPlug)=0
Process plugins
virtual int SaveSettings(QString szFile=QString())
保存客户端参数到文件
virtual CConnecter * LoadConnecter(const QString &szFile)
从文件中新建 CConnecter 指针,所有者是调用者。 当不再使用时,调用者必须负责调用 DeleteConnecter() 删除此指针。 调用者必须连接信号 CConnecter::sigDisc...
virtual CConnecter * CreateConnecter(const QString &id)
新建 CConnecter 指针,所有者是调用者。 当不在使用时,调用者必调用 DeteleConnecter() 须释放指针。 调用者必须连接信号 CConnecter::sigDisconnecte...
virtual int SaveConnecter(QString szFile, CConnecter *pConnecter)
保存连接参数到文件
virtual int DeleteConnecter(CConnecter *p)
Delete CConnecter
virtual QList< QWidget * > GetSettingsWidgets(QWidget *parent)
得到设置参数窗口
virtual int LoadSettings(QString szFile=QString())
从文件中加载客户端参数
virtual int EnumPlugins(Handle *handle)
Enum plugins
virtual int Load(QSettings &set)
加载参数
virtual int SetParameterClient(CParameterClient *pPara)
Set CParameterClient
virtual int Clean()
Clean parameters and resource
virtual int Save(QSettings &set)
保存参数
virtual const QString Id()
Identity
virtual int Initial()
Initial parameters and resource
virtual int SetParameter(CParameter *pParameter) override
设置参数,并初始化界面
用于显示从 CConnectDesktop 输出的图像,和向 CConnectDesktop 发送键盘、鼠标事件。
客户端库 (CClient) 参数。仅在客户端库 (CClient) 和插件中使用。
客户端插件接口。用于建立 CConnecter 实例,它由协议插件实现。
virtual const QString Details() const
显示更多细节。 例如: 在关于对话框或日志中显示。 包括插件的依赖库的版本信息和描述
virtual const QString Id() const
标识。默认: Protocol() + ":" + Name()
virtual const QString DisplayName() const
在界面上显示的名称
virtual const QString Description() const =0
描述
virtual const QString Version() const =0
Version
virtual const QString Name() const =0
插件名,这个名一定要与工程名(${PROJECT_NAME})相同。 翻译文件(${PROJECT_NAME}_*.ts))名与其相关。
virtual const QString Protocol() const =0
协议