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();
39 if(m_pParameterClient) {
40 check = connect(m_pParameterClient, SIGNAL(sigHookKeyboardChanged()),
41 this, SLOT(slotHookKeyboardChanged()));
44 if(m_pParameterClient->GetHookKeyboard())
45 m_Hook = QSharedPointer<CHook>(CHook::GetHook());
47 qCritical(log) <<
"new CParameterClient() fail";
48 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.";
227 bRet = QMetaObject::invokeMethod(
230 Qt::DirectConnection,
231 Q_RETURN_ARG(
int, val));
233 qCritical(log) <<
"Connecter initial fail" << bRet << val;
238 bRet = QMetaObject::invokeMethod(
240 "SetParameterClient",
241 Qt::DirectConnection,
242 Q_RETURN_ARG(
int, val),
245 qCritical(log) <<
"SetParameterClient fail" << bRet << val;
258 qDebug(log) << Q_FUNC_INFO;
261 bool bRet = QMetaObject::invokeMethod(
264 Qt::DirectConnection,
265 Q_RETURN_ARG(
int, val)
268 qWarning(log) <<
"Connecter clean fail" << bRet << val;
276 if(szFile.isEmpty())
return nullptr;
278 QSettings set(szFile, QSettings::IniFormat);
279 m_FileVersion = set.value(
"Manage/FileVersion", m_FileVersion).toInt();
280 QString
id = set.value(
"Plugin/ID").toString();
281 QString protocol = set.value(
"Plugin/Protocol").toString();
282 QString name = set.value(
"Plugin/Name").toString();
284 qDebug(log) <<
"LoadConnecter protocol:" << protocol
285 <<
"name:" << name <<
"id:" << id;
290 bool bRet = QMetaObject::invokeMethod(
293 Qt::DirectConnection,
294 Q_RETURN_ARG(
int, val),
295 Q_ARG(QString, szFile));
297 qCritical(log) <<
"Load parameter fail" << bRet << val;
303 qCritical(log) <<
"Don't create connecter:" << protocol;
310 if(!pConnecter)
return -1;
313 szFile = RabbitCommon::CDir::Instance()->GetDirUserData()
318 QSettings set(szFile, QSettings::IniFormat);
321 bool bRet = QMetaObject::invokeMethod(
324 Qt::DirectConnection,
326 if(!bRet || !pPluginClient)
328 qCritical(log) <<
"Get plugin client fail";
330 Q_ASSERT(pPluginClient);
332 set.setValue(
"Manage/FileVersion", m_FileVersion);
333 set.setValue(
"Plugin/ID", pPluginClient->
Id());
334 set.setValue(
"Plugin/Protocol", pPluginClient->
Protocol());
335 set.setValue(
"Plugin/Name", pPluginClient->
Name());
338 bRet = QMetaObject::invokeMethod(
341 Qt::DirectConnection,
342 Q_RETURN_ARG(
int, val),
343 Q_ARG(QString, szFile));
345 qCritical(log) <<
"Save parameter fail" << bRet << val;
353 return m_pParameterClient->CParameter::Load(szFile);
358 return m_pParameterClient->CParameter::Save(szFile);
363 QList<QWidget*> lstWidget;
368 lstWidget.push_back(pClient);
373 pRecord->SetParameter(&m_pParameterClient->m_Record);
374 lstWidget.push_back(pRecord);
383 QMap<QString, CPluginClient*>::iterator it;
384 for(it = m_Plugins.begin(); it != m_Plugins.end(); it++)
386 nRet = handle->
onProcess(it.key(), it.value());
397 QMap<QString, CPluginClient*>::iterator it;
398 for(it = m_Plugins.begin(); it != m_Plugins.end(); it++)
400 nRet = cb(it.key(), it.value());
408const QString CClient::Details()
const
413void CClient::slotHookKeyboardChanged()
415 if(m_pParameterClient->GetHookKeyboard())
417 m_Hook = QSharedPointer<CHook>(CHook::GetHook());
424bool CClient::eventFilter(QObject *watched, QEvent *event)
426 if(QEvent::KeyPress == event->type() || QEvent::KeyRelease == event->type())
429 bool bProcess =
false;
430 QKeyEvent *keyEvent =
static_cast<QKeyEvent *
>(event);
431 int key = keyEvent->key();
435 key = Qt::Key_Super_L;
437#if defined(Q_OS_MACOS)
438 key = Qt::Key_Control;
451 switch(event->type()) {
452 case QEvent::KeyPress:
454 CFrmViewer* focus = qobject_cast<CFrmViewer*>(QApplication::focusWidget());
456 emit focus->sigKeyPressEvent(keyEvent);
460 case QEvent::KeyRelease:
462 CFrmViewer* focus = qobject_cast<CFrmViewer*>(QApplication::focusWidget());
464 emit focus->sigKeyReleaseEvent(keyEvent);
473 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 const QString Id()
Identity
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
协议