3#include <QPluginLoader>
9#include <QLoggingCategory>
13#include "RabbitCommonDir.h"
14#include "RabbitCommonTools.h"
15#include "ParameterPluginUI.h"
16#include "ParameterRecordUI.h"
17#if defined(HAVE_QTERMWIDGET)
18 #include "ParameterTerminalUI.h"
19 #include "OperateTerminal.h"
22 #include "ChannelSSH.h"
32static Q_LOGGING_CATEGORY(log,
"Manager")
43 m_Translator = RabbitCommon::CTools::Instance()->InstallTranslator(
44 "Plugin", RabbitCommon::CTools::TranslationType::Library);
47 m_szSettingsFile = szFile;
50 LoadSettings(m_szSettingsFile);
55#if defined(Q_OS_ANDROID)
58#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0) && defined(Q_OS_WIN)
59 szSnap = qEnvironmentVariable(
"SNAP");
60 szFlatpak = qEnvironmentVariable(
"FLATPAK_ID");
62 szSnap = QString::fromLocal8Bit(qgetenv(
"SNAP"));
63 szFlatpak = QString::fromLocal8Bit(qgetenv(
"FLATPAK_ID"));
65 if(!szSnap.isEmpty() || !szFlatpak.isEmpty())
67 if(bReboot && !RabbitCommon::CTools::Instance()->HasAdministratorPrivilege()
68 && m_pParameter->GetPromptAdministratorPrivilege())
72 szMsg = tr(
"The programe is not administrator privilege.\n"
73 "Some features are limited.\n");
75 szMsg += tr(
"Eg: Can not disable system shortcuts(eg: Ctrl+Alt+del).") +
"\n";
77 szMsg += tr(
"Eg: Can not use the wake on LAN feature.") +
"\n";
79 szMsg += tr(
"Restart program by administrator?");
80 QMessageBox msg(QMessageBox::Warning, tr(
"Warning"), szMsg,
81 QMessageBox::Yes | QMessageBox::No);
82 msg.setCheckBox(
new QCheckBox(tr(
"Always shown"), &msg));
83 msg.checkBox()->setCheckable(
true);
84 msg.checkBox()->setChecked(
85 m_pParameter->GetPromptAdministratorPrivilege());
88 m_pParameter->SetPromptAdministratorPrivilege(
89 msg.checkBox()->isChecked());
90 SaveSettings(m_szSettingsFile);
92 if(QMessageBox::Yes == nRet) {
93 RabbitCommon::CTools::Instance()->StartWithAdministratorPrivilege(
true);
98 check = connect(m_pParameter, SIGNAL(sigNativeWindowRecieveKeyboard()),
99 this, SLOT(slotNativeWindowRecieveKeyboard()));
101 m_pHook = CHook::GetHook(m_pParameter,
this);
103 m_pHook->RegisterKeyboard();
105 qCritical(log) <<
"new CParameterPlugin() fail";
106 Q_ASSERT(m_pParameter);
114 qDebug(log) <<
"CManager::~CManager()";
116 qApp->removeEventFilter(
this);
119 m_pHook->UnRegisterKeyboard();
120 m_pHook->deleteLater();
125 m_pParameter->deleteLater();
126 m_pParameter =
nullptr;
130 RabbitCommon::CTools::Instance()->RemoveTranslator(m_Translator);
139int CManager::LoadPlugins()
142 foreach (QObject *plugin, QPluginLoader::staticInstances())
144 CPlugin* p = qobject_cast<CPlugin*>(plugin);
147 if(m_Plugins.find(p->
Id()) == m_Plugins.end())
149 qInfo(log) <<
"Success: Load plugin" << p->
Name();
153 qWarning(log) <<
"The plugin" << p->
Name() <<
" is exist.";
157 QString szPath = RabbitCommon::CDir::Instance()->GetDirPlugins();
160 if(filters.isEmpty())
162#if defined (Q_OS_WINDOWS) || defined(Q_OS_WIN)
163 filters <<
"*Plugin*.dll";
164#elif defined(Q_OS_MACOS) || defined(Q_OS_MAC)
165 filters <<
"*Plugin*.dylib";
167 filters <<
"*Plugin*.so";
170 nRet = FindPlugins(szPath, filters);
171 if(!m_szDetails.isEmpty())
172 m_szDetails =
"## " + tr(
"Plugins") +
"\n" + m_szDetails;
174 qDebug(log) << (
"Client details:\n" + Details()).toStdString().c_str();
178int CManager::FindPlugins(QDir dir, QStringList filters)
182 QString szCurrentPath = QDir::currentPath();
183 QStringList files = dir.entryList(filters, QDir::Files | QDir::NoDotAndDotDot);
189 QDir::setCurrent(QDir::cleanPath(dir.absolutePath()));
200 foreach (fileName, files) {
201 QString szPlugins = dir.absoluteFilePath(fileName);
202 QPluginLoader loader(szPlugins);
203 QObject *plugin = loader.instance();
205 CPlugin* p = qobject_cast<CPlugin*>(plugin);
208 if(m_Plugins.find(p->
Id()) == m_Plugins.end())
210 qInfo(log) <<
"Success: Load plugin"
211 << p->
Name() <<
"from" << szPlugins;
215 qWarning(log) <<
"The plugin [" << p->
Name() <<
"] is exist.";
219 szMsg =
"Error: Load plugin fail from " + szPlugins;
220 if(!loader.errorString().isEmpty())
221 szMsg +=
"; Error: " + loader.errorString();
222 qCritical(log) << szMsg.toStdString().c_str();
226 foreach (fileName, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
227 QDir pluginDir = dir;
228 if(pluginDir.cd(fileName))
229 FindPlugins(pluginDir, filters);
232 QDir::setCurrent(szCurrentPath);
237int CManager::AppendPlugin(
CPlugin *p)
240 m_Plugins.insert(p->
Id(), p);
243 bool bRet = QMetaObject::invokeMethod(
246 Qt::DirectConnection,
247 Q_RETURN_ARG(
int, val));
250 qCritical(log) <<
"The plugin" << p->
Name()
251 <<
"initial translator fail" << bRet << val;
255 + tr(
"Version:") +
" " + p->
Version() +
" \n"
258 m_szDetails += p->
Details() +
"\n";
267 auto it = m_Plugins.find(
id);
268 if(m_Plugins.end() != it)
271 qDebug(log) <<
"CreateOperate id:" << id;
272 auto plugin = it.value();
275 bRet = QMetaObject::invokeMethod(
278 Qt::DirectConnection,
283 qCritical(log) <<
"Create COperate fail.";
294 qDebug(log) << Q_FUNC_INFO;
299 bool bRet = QMetaObject::invokeMethod(
302 Qt::DirectConnection,
303 Q_RETURN_ARG(
CPlugin*, pPlugin));
305 if(bRet && pPlugin) {
308 bRet = QMetaObject::invokeMethod(
311 Qt::DirectConnection,
312 Q_RETURN_ARG(
int, nRet),
316 qCritical(log) <<
"Call pPlugin->DeleteOperate(p) fail";
321 qCritical(log) <<
"Get CManager fail.";
328 if(szFile.isEmpty())
return nullptr;
329 qDebug(log) <<
"Load operate configure file:"<< szFile;
330 QSettings set(szFile, QSettings::IniFormat);
331 m_FileVersion = set.value(
"Manage/FileVersion", m_FileVersion).toInt();
332 QString
id = set.value(
"Plugin/ID").toString();
333 QString protocol = set.value(
"Plugin/Protocol").toString();
334 QString name = set.value(
"Plugin/Name").toString();
335 qDebug(log) <<
"LoadOperate protocol:" << protocol
336 <<
"name:" << name <<
"id:" << id;
341 bool bRet = QMetaObject::invokeMethod(
344 Qt::DirectConnection,
345 Q_RETURN_ARG(
int, nRet),
346 Q_ARG(QString, szFile));
348 qCritical(log) <<
"Call pOperate->Load(szFile) fail.";
352 qCritical(log) <<
"Load parameter fail" << nRet;
356 pOperate->SetSettingsFile(szFile);
359 qCritical(log) <<
"Don't create Operate:" << name << protocol <<
id << szFile;
366 if(!pOperate)
return -1;
368 QString szFile = pOperate->GetSettingsFile();
370 szFile = RabbitCommon::CDir::Instance()->GetDirUserData()
375 QSettings set(szFile, QSettings::IniFormat);
378 bool bRet = QMetaObject::invokeMethod(
381 Qt::DirectConnection,
382 Q_RETURN_ARG(
CPlugin*, pPlugin));
383 if(!bRet || !pPlugin)
385 qCritical(log) <<
"Get plugin client fail";
389 set.setValue(
"Manage/FileVersion", m_FileVersion);
390 set.setValue(
"Plugin/ID", pPlugin->
Id());
391 set.setValue(
"Plugin/Protocol", pPlugin->
Protocol());
392 set.setValue(
"Plugin/Name", pPlugin->
Name());
395 bRet = QMetaObject::invokeMethod(
398 Qt::DirectConnection,
399 Q_RETURN_ARG(
int, nRet),
400 Q_ARG(QString, szFile));
402 qCritical(log) <<
"Call pOperate->Save(szFile) fail.";
406 qCritical(log) <<
"Save parameter fail" << nRet;
415 qCritical(log) <<
"The m_pParameter is nullptr";
416 Q_ASSERT_X(m_pParameter,
"CManager",
"The m_pParameter is nullptr");
422 s = m_szSettingsFile;
423 return m_pParameter->
Load(s);
429 qCritical(log) <<
"The m_pParameter is nullptr";
430 Q_ASSERT_X(m_pParameter,
"CManager",
"The m_pParameter is nullptr");
436 s = m_szSettingsFile;
437 return m_pParameter->
Save(s);
442 QList<QWidget*> lstWidget;
447 lstWidget.push_back(pClient);
449#if defined(HAVE_QTERMWIDGET)
453 pTermina->setWindowTitle(tr(
"Terminal"));
454 lstWidget.push_back(pTermina);
459 pRecord->SetParameter(&m_pParameter->m_Record);
460 lstWidget.push_back(pRecord);
469 QMap<QString, CPlugin*>::iterator it;
470 for(it = m_Plugins.begin(); it != m_Plugins.end(); it++)
472 nRet = handle->
onProcess(it.key(), it.value());
483 QMap<QString, CPlugin*>::iterator it;
484 for(it = m_Plugins.begin(); it != m_Plugins.end(); it++)
486 nRet = cb(it.key(), it.value());
494const QString CManager::Details()
const
498 szDetail += COperateTerminal::Details();
502 szDetail += channel.GetDetails();
505 szDetail +=
"- QtKeyChain\n" +
506 QString(
" - ") + tr(
"Version:")
507 +
" 0x" + QString::number(QTKEYCHAIN_VERSION, 16) +
"\n";
510 if(!szDetail.isEmpty()) {
511 szDetail =
"## " + tr(
"Dependency libraries:") +
"\n" + szDetail;
513 szDetail += m_szDetails;
517void CManager::slotNativeWindowRecieveKeyboard()
519 Q_ASSERT(m_pParameter);
520 if(m_pParameter->GetNativeWindowReceiveKeyboard()) {
522 m_pHook->UnRegisterKeyboard();
523 m_pHook->deleteLater();
528 m_pHook = CHook::GetHook(m_pParameter,
this);
530 m_pHook->RegisterKeyboard();
static int RemoveTranslation()
Remove translation
static int InitTranslation()
Initial translation
virtual int onProcess(const QString &id, CPlugin *pPlugin)=0
Process plugins
virtual QList< QWidget * > GetSettingsWidgets(QWidget *parent)
得到设置参数窗口
virtual int EnumPlugins(Handle *handle)
Enum plugins
virtual COperate * CreateOperate(const QString &id)
新建 COperate 指针,所有者是调用者。 当不在使用时,调用者必调用 DeteleOperate() 须释放指针。 调用者必须连接信号 COperate::sigFinished 。 释放指针 (...
virtual COperate * LoadOperate(const QString &szFile)
从文件中新建 COperate 指针,所有者是调用者。 当不再使用时,调用者必须负责调用 DeleteOperate() 删除此指针。 调用者必须连接信号 COperate::sigFinished 。...
virtual int DeleteOperate(COperate *p)
Delete COperate
virtual int SaveOperate(COperate *pOperate)
保存连接参数到文件
virtual int SaveSettings(const QString szFile=QString())
保存客户端参数到文件
virtual int LoadSettings(const QString szFile=QString())
从文件中加载客户端参数
virtual const QString Id()
Identity
virtual int SetParameter(CParameter *pParameter) override
[override functions]
virtual int SetParameter(CParameter *pParameter) override
[override functions]
virtual int Save(QString szFile=QString(), bool bForce=true)
Save to file
virtual int Load(QString szFile=QString())
Load from file
virtual const QString Version() const =0
Version
virtual const QString Details() const
显示更多细节。 例如: 在关于对话框或日志中显示。 包括插件的依赖库的版本信息和描述
virtual const QString Id()
标识。默认: Type() + ":" + Protocol() + ":" + Name()
virtual const QString Name() const =0
插件名,这个名一定要与工程名(${PROJECT_NAME})相同。 翻译文件(${PROJECT_NAME}_*.ts))名与其相关。
virtual const QString DisplayName() const
在界面上显示的名称
virtual const QString Protocol() const =0
协议
virtual const QString Description() const =0
描述