3#include <QPluginLoader>
9#include <QLoggingCategory>
14#include "RabbitCommonDir.h"
15#include "RabbitCommonTools.h"
16#include "FrmParameterClient.h"
19#include "ParameterRecordUI.h"
21static Q_LOGGING_CATEGORY(log,
"Client")
23CClient::
CClient(QObject *parent, QString szFile) : QObject(parent),
31 qApp->installEventFilter(
this);
33 m_Translator = RabbitCommon::CTools::Instance()->InstallTranslator(
34 "Client", RabbitCommon::CTools::TranslationType::Library);
36 CChannel::InitTranslation();
37 m_szSettingsFile = szFile;
39 if(m_pParameterClient) {
40 LoadSettings(m_szSettingsFile);
41 check = connect(m_pParameterClient, SIGNAL(sigHookKeyboardChanged()),
42 this, SLOT(slotHookKeyboardChanged()));
44 slotHookKeyboardChanged();
46 qCritical(log) <<
"new CParameterClient() fail";
47 Q_ASSERT(m_pParameterClient);
55 qDebug(log) <<
"CClient::~CClient()";
57 if(m_pParameterClient)
58 delete m_pParameterClient;
60 qApp->installEventFilter(
nullptr);
63 RabbitCommon::CTools::Instance()->RemoveTranslator(m_Translator);
65 CChannel::RemoveTranslation();
72int CClient::LoadPlugins()
75 foreach (QObject *plugin, QPluginLoader::staticInstances())
80 if(m_Plugins.find(p->
Id()) == m_Plugins.end())
82 qInfo(log) <<
"Success: Load plugin" << p->
Name();
86 qWarning(log) <<
"The plugin" << p->
Name() <<
" is exist.";
90 QString szPath = RabbitCommon::CDir::Instance()->GetDirPlugins();
91#if !defined (Q_OS_ANDROID)
92 szPath = szPath + QDir::separator() +
"Client";
96#if defined (Q_OS_WINDOWS) || defined(Q_OS_WIN)
97 filters <<
"*PluginClient*.dll";
99 filters <<
"*PluginClient*.so";
101 nRet = FindPlugins(szPath, filters);
102 if(!m_szDetails.isEmpty())
103 m_szDetails = tr(
"### Plugins") +
"\n" + m_szDetails;
105 qDebug(log) << (
"Client details:\n" + Details()).toStdString().c_str();
109int CClient::FindPlugins(QDir dir, QStringList filters)
112 if(filters.isEmpty())
114#if defined (Q_OS_WINDOWS) || defined(Q_OS_WIN)
115 filters <<
"*PluginClient*.dll";
117 filters <<
"*PluginClient*.so";
121 QString szCurrentPath = QDir::currentPath();
122 QStringList files = dir.entryList(filters, QDir::Files | QDir::NoDotAndDotDot);
128 QDir::setCurrent(QDir::cleanPath(dir.absolutePath()));
139 foreach (fileName, files) {
140 QString szPlugins = dir.absoluteFilePath(fileName);
141 QPluginLoader loader(szPlugins);
142 QObject *plugin = loader.instance();
147 if(m_Plugins.find(p->
Id()) == m_Plugins.end())
149 qInfo(log) <<
"Success: Load plugin"
150 << p->
Name() <<
"from" << szPlugins;
154 qWarning(log) <<
"The plugin [" << p->
Name() <<
"] is exist.";
158 szMsg =
"Error: Load plugin fail from " + szPlugins;
159 if(!loader.errorString().isEmpty())
160 szMsg +=
"; Error: " + loader.errorString();
161 qCritical(log) << szMsg.toStdString().c_str();
165 foreach (fileName, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
166 QDir pluginDir = dir;
167 if(pluginDir.cd(fileName))
168 FindPlugins(pluginDir, filters);
171 QDir::setCurrent(szCurrentPath);
179 m_Plugins.insert(p->
Id(), p);
182 bool bRet = QMetaObject::invokeMethod(
185 Qt::DirectConnection,
186 Q_RETURN_ARG(
int, val));
189 qCritical(log) <<
"The plugin" << p->
Name()
190 <<
"initial translator fail" << bRet << val;
194 + tr(
"Version:") +
" " + p->
Version() +
" \n"
197 m_szDetails += p->
Details() +
"\n";
206 auto it = m_Plugins.find(
id);
207 if(m_Plugins.end() != it)
210 qDebug(log) <<
"CreateConnecter id:" << id;
211 auto plugin = it.value();
214 bRet = QMetaObject::invokeMethod(
217 Qt::DirectConnection,
222 qCritical(log) <<
"Create CConnecter fail.";
233 qDebug(log) << Q_FUNC_INFO;
238 bool bRet = QMetaObject::invokeMethod(
241 Qt::DirectConnection,
244 if(bRet && pPluginClient) {
247 bRet = QMetaObject::invokeMethod(
250 Qt::DirectConnection,
251 Q_RETURN_ARG(
int, nRet),
255 qCritical(log) <<
"Call pPluginClient->DeleteConnecter(p) fail";
260 qCritical(log) <<
"Get CClient fail.";
267 if(szFile.isEmpty())
return nullptr;
269 QSettings set(szFile, QSettings::IniFormat);
270 m_FileVersion = set.value(
"Manage/FileVersion", m_FileVersion).toInt();
271 QString
id = set.value(
"Plugin/ID").toString();
272 QString protocol = set.value(
"Plugin/Protocol").toString();
273 QString name = set.value(
"Plugin/Name").toString();
275 qDebug(log) <<
"LoadConnecter protocol:" << protocol
276 <<
"name:" << name <<
"id:" << id;
281 bool bRet = QMetaObject::invokeMethod(
284 Qt::DirectConnection,
285 Q_RETURN_ARG(
int, nRet),
286 Q_ARG(QString, szFile));
288 qCritical(log) <<
"Call pConnecter->Load(szFile) fail.";
292 qCritical(log) <<
"Load parameter fail" << nRet;
296 pConnecter->SetSettingsFile(szFile);
299 qCritical(log) <<
"Don't create connecter:" << protocol;
306 if(!pConnecter)
return -1;
308 QString szFile = pConnecter->GetSettingsFile();
310 szFile = RabbitCommon::CDir::Instance()->GetDirUserData()
315 QSettings set(szFile, QSettings::IniFormat);
318 bool bRet = QMetaObject::invokeMethod(
321 Qt::DirectConnection,
323 if(!bRet || !pPluginClient)
325 qCritical(log) <<
"Get plugin client fail";
327 Q_ASSERT(pPluginClient);
329 set.setValue(
"Manage/FileVersion", m_FileVersion);
330 set.setValue(
"Plugin/ID", pPluginClient->
Id());
331 set.setValue(
"Plugin/Protocol", pPluginClient->
Protocol());
332 set.setValue(
"Plugin/Name", pPluginClient->
Name());
335 bRet = QMetaObject::invokeMethod(
338 Qt::DirectConnection,
339 Q_RETURN_ARG(
int, nRet),
340 Q_ARG(QString, szFile));
342 qCritical(log) <<
"Call pConnecter->Save(szFile) fail.";
346 qCritical(log) <<
"Save parameter fail" << nRet;
354 if(!m_pParameterClient) {
355 qCritical(log) <<
"The m_pParameterClient is nullptr";
356 Q_ASSERT_X(m_pParameterClient,
"CClient",
"The m_pParameterClient is nullptr");
362 s = m_szSettingsFile;
363 return m_pParameterClient->CParameter::Load(s);
368 if(!m_pParameterClient) {
369 qCritical(log) <<
"The m_pParameterClient is nullptr";
370 Q_ASSERT_X(m_pParameterClient,
"CClient",
"The m_pParameterClient is nullptr");
376 s = m_szSettingsFile;
377 return m_pParameterClient->CParameter::Save(s);
382 QList<QWidget*> lstWidget;
387 lstWidget.push_back(pClient);
392 pRecord->SetParameter(&m_pParameterClient->m_Record);
393 lstWidget.push_back(pRecord);
402 QMap<QString, CPluginClient*>::iterator it;
403 for(it = m_Plugins.begin(); it != m_Plugins.end(); it++)
405 nRet = handle->
onProcess(it.key(), it.value());
416 QMap<QString, CPluginClient*>::iterator it;
417 for(it = m_Plugins.begin(); it != m_Plugins.end(); it++)
419 nRet = cb(it.key(), it.value());
427const QString CClient::Details()
const
432void CClient::slotHookKeyboardChanged()
434 if(m_pParameterClient->GetHookKeyboard())
436 if(!RabbitCommon::CTools::Instance()->HasAdministratorPrivilege()
437 && m_pParameterClient->GetHookShowAdministratorPrivilege())
441 QMessageBox::Warning, tr(
"Warning"),
442 tr(
"The programe is not administrator privilege.\n"
443 "Don't disable system shortcuts(eg: Ctrl+Alt+del).\n"
444 "Restart program by administrator?"),
445 QMessageBox::Yes | QMessageBox::No);
446 msg.setCheckBox(
new QCheckBox(tr(
"Always shown"), &msg));
447 msg.checkBox()->setCheckable(
true);
448 msg.checkBox()->setChecked(
449 m_pParameterClient->GetHookShowAdministratorPrivilege());
451 if(QMessageBox::Yes == nRet) {
452 RabbitCommon::CTools::Instance()->StartWithAdministratorPrivilege(
true);
454 if(m_pParameterClient->GetHookShowAdministratorPrivilege()
455 != msg.checkBox()->isChecked()) {
456 m_pParameterClient->SetHookShowAdministratorPrivilege(
457 msg.checkBox()->isChecked());
461 m_Hook = QSharedPointer<CHook>(CHook::GetHook());
468bool CClient::eventFilter(QObject *watched, QEvent *event)
470 if(QEvent::KeyPress == event->type() || QEvent::KeyRelease == event->type())
473 bool bProcess =
false;
474 QKeyEvent *keyEvent =
static_cast<QKeyEvent *
>(event);
475 int key = keyEvent->key();
479 key = Qt::Key_Super_L;
481#if defined(Q_OS_MACOS)
482 key = Qt::Key_Control;
495 switch(event->type()) {
496 case QEvent::KeyPress:
498 CFrmViewer* focus = qobject_cast<CFrmViewer*>(QApplication::focusWidget());
500 emit focus->sigKeyPressEvent(keyEvent);
504 case QEvent::KeyRelease:
506 CFrmViewer* focus = qobject_cast<CFrmViewer*>(QApplication::focusWidget());
508 emit focus->sigKeyReleaseEvent(keyEvent);
517 return QObject::eventFilter(watched, event);
The Handle CConnecter class.
virtual int onProcess(const QString &id, CPluginClient *pPlug)=0
Process plugins.
manage plugins and connecter
virtual CConnecter * LoadConnecter(const QString &szFile)
New CConnecter pointer from file, the owner is caller.
virtual CConnecter * CreateConnecter(const QString &id)
New CConnecter pointer, the owner is caller.
virtual int LoadSettings(const QString szFile=QString())
Load Client parameters from file.
virtual int DeleteConnecter(CConnecter *p)
Delete CConnecter.
virtual QList< QWidget * > GetSettingsWidgets(QWidget *parent)
Get parameter settings widget.
virtual int SaveConnecter(CConnecter *pConnecter)
Accept connecter parameters to file.
virtual int SaveSettings(const QString szFile=QString())
Save Client parameters to file.
virtual int EnumPlugins(Handle *handle)
Enum plugins.
virtual const QString Id()
Identity.
virtual int SetParameter(CParameter *pParameter) override
Set the parameters and initialize the user interface.
A widget which displays output image from a CConnectDesktop and sends input keypresses and mouse acti...
The parameters of client.
virtual const QString Details() const
Display more information in About dialog or log.
virtual const QString Id() const
ID. Default: Protocol() + ":" + Name()
virtual const QString DisplayName() const
The plugin display name.
virtual const QString Description() const =0
Plugin description.
virtual const QString Version() const =0
Version.
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 Protocol() const =0
Plugin Protocol.