فهرست منبع

重新调整插件的功能

爬山虎 2 سال پیش
والد
کامیت
c8c0a8be8b
8فایلهای تغییر یافته به همراه151 افزوده شده و 59 حذف شده
  1. 51 23
      src/cceditor/ccnotepad.cpp
  2. 1 0
      src/cceditor/ccnotepad.h
  3. 12 16
      src/cceditor/ccnotepad.ui
  4. 9 1
      src/include/pluginGl.h
  5. 1 1
      src/plugin.h
  6. 32 3
      src/plugin/helloworld/helloworldexport.cpp
  7. 31 9
      src/plugin/test/test.cpp
  8. 14 6
      src/pluginGl.h

+ 51 - 23
src/cceditor/ccnotepad.cpp

@@ -1475,21 +1475,14 @@ void CCNotePad::setUserDefShortcutKey(int shortcutId)
 			ui.actionGoline->setShortcut(keySeq);
 		
 		break;
+
 	case File_Compare_ID:
-		keySeq = ShortcutKeyMgr::getUserDefShortcutKey(File_Compare);
-		m_fileCompare->setShortcut(keySeq);
-	
 		break;
 	case Dir_Compare_ID:
-		keySeq = ShortcutKeyMgr::getUserDefShortcutKey(Dir_Compare);
-		m_dirCompare->setShortcut(keySeq);
-		
 		break;
 	case Bin_Compare_ID:
-		keySeq = ShortcutKeyMgr::getUserDefShortcutKey(Bin_Compare);
-		m_binCompare->setShortcut(keySeq);
-		
 		break;
+
 	case Trans_code_ID:
 		keySeq = ShortcutKeyMgr::getUserDefShortcutKey(Trans_code);
 			m_transcode->setShortcut(keySeq);
@@ -1545,7 +1538,7 @@ void CCNotePad::slot_dynamicLoadToolMenu()
 		m_isToolMenuLoaded = true;
 
 #ifdef NO_PLUGIN
-		ui.menuTools->addAction(tr("Plugin Manager"), this, &CCNotePad::slot_pluginMgr);
+		connect(ui.actionPlugin_Manager, &QAction::triggered, this, &CCNotePad::slot_pluginMgr);
 #endif
 
 		QMenu* formatMenu = new QMenu(tr("Format Language"), this);
@@ -1581,7 +1574,7 @@ void CCNotePad::loadPluginLib()
 	{
 		strDir = dir.absolutePath();
 
-		loadPluginProcs(strDir,ui.menuTools);
+		loadPluginProcs(strDir,ui.menuPlugin);
 	}
 }
 
@@ -1594,11 +1587,31 @@ void CCNotePad::onPlugFound(NDD_PROC_DATA& procData, QMenu* pUserData)
 		return;
 	}
 
-	QAction* pAction = new QAction(pMenu);
+	//创建action
+	if (procData.m_menuType == 0)
+	{
+		QAction* pAction = new QAction(procData.m_strPlugName, pMenu);
+		pMenu->addAction(pAction);
 	pAction->setText(procData.m_strPlugName);
 	pAction->setData(procData.m_strFilePath);
-	pMenu->addAction(pAction);
 	connect(pAction, &QAction::triggered, this, &CCNotePad::onPlugWork);
+	}
+	else if (procData.m_menuType == 1)
+	{
+		//创建二级菜单
+		QMenu* pluginMenu = new QMenu(procData.m_strPlugName, pMenu);
+		pMenu->addMenu(pluginMenu);
+
+		//菜单句柄通过procData传递到插件中
+		procData.m_rootMenu = pluginMenu;
+		sendParaToPlugin(procData);
+	}
+	else
+	{
+		return;
+	}
+
+	
 
 	m_pluginList.append(procData);
 }
@@ -1620,7 +1633,7 @@ void CCNotePad::onPlugWork(bool check)
 		{
 			std::function<QsciScintilla* ()> foundCallBack = std::bind(&CCNotePad::getCurEditView, this);
 
-			pMainCallBack(this, plugPath, foundCallBack);
+			pMainCallBack(this, plugPath, foundCallBack, nullptr);
 		}
 		else
 		{
@@ -1630,21 +1643,36 @@ void CCNotePad::onPlugWork(bool check)
 	}
 }
 
-void CCNotePad::loadPluginProcs(QString strLibDir, QMenu* pMenu)
+//把插件需要的参数,传递到插件中去
+void CCNotePad::sendParaToPlugin(NDD_PROC_DATA& procData)
 {
-	QMenu* pSubMenu = new QMenu(tr("Plugin"), pMenu);
+	QString plugPath = procData.m_strFilePath;
 
-	std::function<void(NDD_PROC_DATA&, QMenu*)> foundCallBack = std::bind(&CCNotePad::onPlugFound, this, std::placeholders::_1, std::placeholders::_2);
+	QLibrary* pLib = new QLibrary(plugPath);
 
-	int nRet = loadProc(strLibDir, foundCallBack, pSubMenu);
+	NDD_PROC_MAIN_CALLBACK pMainCallBack;
+	pMainCallBack = (NDD_PROC_MAIN_CALLBACK)pLib->resolve("NDD_PROC_MAIN");
 
+		if (pMainCallBack != NULL)
+		{
+			std::function<QsciScintilla* ()> foundCallBack = std::bind(&CCNotePad::getCurEditView, this);
+
+			pMainCallBack(this, plugPath, foundCallBack, &procData);
+		}
+		else
+		{
+			ui.statusBar->showMessage(tr("plugin %1 load failed !").arg(plugPath), 10000);
+		}
+}
+
+void CCNotePad::loadPluginProcs(QString strLibDir, QMenu* pMenu)
+{
+	std::function<void(NDD_PROC_DATA&, QMenu*)> foundCallBack = std::bind(&CCNotePad::onPlugFound, this, std::placeholders::_1, std::placeholders::_2);
+
+	int nRet = loadProc(strLibDir, foundCallBack, pMenu);
 	if (nRet > 0)
 	{
-		pMenu->addMenu(pSubMenu);
-	}
-	else
-	{
-		delete pSubMenu;
+		ui.statusBar->showMessage(tr("load plugin in dir %1 success, plugin num %2").arg(strLibDir).arg(nRet));
 	}
 }
 #endif

+ 1 - 0
src/cceditor/ccnotepad.h

@@ -341,6 +341,7 @@ private slots:
 #ifdef NO_PLUGIN
 	void slot_pluginMgr();
 	void onPlugWork(bool check);
+	void sendParaToPlugin(NDD_PROC_DATA& procData);
 #endif
 	void slot_showWebAddr(bool check);
 	void slot_langFileSuffix();

+ 12 - 16
src/cceditor/ccnotepad.ui

@@ -507,6 +507,12 @@
      <string>T&amp;ools</string>
     </property>
    </widget>
+   <widget class="QMenu" name="menuPlugin">
+    <property name="title">
+     <string>Plugin</string>
+    </property>
+    <addaction name="actionPlugin_Manager"/>
+   </widget>
    <addaction name="menuFile"/>
    <addaction name="menuEdit"/>
    <addaction name="menuSearch"/>
@@ -515,6 +521,7 @@
    <addaction name="menuLanguage"/>
    <addaction name="menuSet"/>
    <addaction name="menuTools"/>
+   <addaction name="menuPlugin"/>
    <addaction name="menuCompare"/>
    <addaction name="menuAbout"/>
    <addaction name="menuAbout_2"/>
@@ -2048,6 +2055,11 @@
     <string>test</string>
    </property>
   </action>
+  <action name="actionPlugin_Manager">
+   <property name="text">
+    <string>Plugin Manager</string>
+   </property>
+  </action>
  </widget>
  <layoutdefault spacing="6" margin="11"/>
  <resources>
@@ -2711,22 +2723,6 @@
    </hints>
   </connection>
   <connection>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    <sender>actionLanguage_Format</sender>
    <signal>triggered()</signal>
    <receiver>CCNotePad</receiver>

+ 9 - 1
src/include/pluginGl.h

@@ -1,5 +1,6 @@
 #pragma once
 #include <QString>
+#include <QMenu>
 
 #define NDD_EXPORTDLL
 
@@ -16,10 +17,17 @@
 struct ndd_proc_data
 {
 	QString m_strPlugName; //插件名称 必选
-	QString m_strFilePath; //lib 插件的全局路径。必选
+	QString m_strFilePath; //lib 插件的全局路径。必选。插件内部不用管,主程序传递下来
 	QString m_strComment; //插件说明
 	QString m_version; //版本号码。可选
 	QString m_auther;//作者名称。可选
+	int m_menuType;//菜单类型。0:不使用二级菜单 1:创建二级菜单
+	QMenu* m_rootMenu;//如果m_menuType = 1,给出二级根菜单的地址。其他值nullptr
+
+	ndd_proc_data(): m_rootMenu(nullptr), m_menuType(0)
+	{
+
+	}
 };
 
 

+ 1 - 1
src/plugin.h

@@ -5,6 +5,6 @@ class QMenu;
 class QsciScintilla;
 class QWidget;
 
-typedef int (*NDD_PROC_MAIN_CALLBACK)(QWidget* parent, const QString& strFileName, std::function<QsciScintilla*()>getCurEdit);
+typedef int (*NDD_PROC_MAIN_CALLBACK)(QWidget* parent, const QString& strFileName, std::function<QsciScintilla*()>getCurEdit, NDD_PROC_DATA* procData);
 
 int loadProc(const QString& strDirOut, std::function<void(NDD_PROC_DATA&, QMenu*)> funcallback, QMenu* pUserData);

+ 32 - 3
src/plugin/helloworld/helloworldexport.cpp

@@ -22,13 +22,17 @@
 #endif
 
 	NDD_EXPORT bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData);
-	NDD_EXPORT int NDD_PROC_MAIN(QWidget* pNotepad, const QString& strFileName, std::function<QsciScintilla* ()>getCurEdit);
+	NDD_EXPORT int NDD_PROC_MAIN(QWidget* pNotepad, const QString& strFileName, std::function<QsciScintilla* ()>getCurEdit, NDD_PROC_DATA* procData);
 
 
 #ifdef __cplusplus
 	}
 #endif
 
+static NDD_PROC_DATA s_procData;
+static QWidget* s_pMainNotepad = nullptr;
+std::function<QsciScintilla* ()> s_getCurEdit;
+
 bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData)
 {
 	if(pProcData == NULL)
@@ -40,13 +44,38 @@ bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData)
 
 	pProcData->m_version = QString("v1.0");
 	pProcData->m_auther = QString("zuowei.yin");
+
+	pProcData->m_menuType = 0;
+
 	return true;
 }
 
-//插件的入口点函数
-int NDD_PROC_MAIN(QWidget* pNotepad, const QString &strFileName, std::function<QsciScintilla*()>getCurEdit)
+//则点击菜单栏按钮时,会自动调用到该插件的入口点函数。
+//pNotepad:就是CCNotepad的主界面指针
+//strFileName:当前插件DLL的全路径,如果不关心,则可以不使用
+//getCurEdit:从NDD主程序传递过来的仿函数,通过该函数获取当前编辑框操作对象QsciScintilla
+//pProcData:如果pProcData->m_menuType = 0 ,则该指针为空;如果pProcData->m_menuType = 1,则该指针有值。目前需要关心s_procData.m_rootMenu
+//开发者可以在该菜单下面,自行创建二级菜单
+int NDD_PROC_MAIN(QWidget* pNotepad, const QString &strFileName, std::function<QsciScintilla*()>getCurEdit, NDD_PROC_DATA* pProcData)
 {
 	QsciScintilla* pEdit = getCurEdit();
+	if (pEdit == nullptr)
+	{
+		return -1;
+	}
+
+	//务必拷贝一份pProcData,在外面会释放。
+	if (pProcData != nullptr)
+	{
+		s_procData = *pProcData;
+	}
+
+	s_pMainNotepad = pNotepad;
+	s_getCurEdit = getCurEdit;
+
+	//如果pProcData->m_menuType = 1;是自己要创建二级菜单的场景。则通过s_procData.m_rootMenu 获取该插件的菜单根节点。
+	//插件开发者自行在s_procData.m_rootMenu下添加新的二级菜单项目
+
 
 	//做一个简单的转大写的操作
 	QtTestClass* p = new QtTestClass(pNotepad,pEdit);

+ 31 - 9
src/plugin/test/test.cpp

@@ -3,6 +3,7 @@
 #include <pluginGl.h>
 #include <functional>
 #include <qsciscintilla.h>
+#include <QAction>
 
 #define NDD_EXPORTDLL
 
@@ -21,13 +22,16 @@
 #endif
 
 	NDD_EXPORT bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData);
-	NDD_EXPORT int NDD_PROC_MAIN(QWidget* parent, const QString& strFileName, std::function<QsciScintilla* ()>getCurEdit);
-
+	NDD_EXPORT int NDD_PROC_MAIN(QWidget* pNotepad, const QString& strFileName, std::function<QsciScintilla* ()>getCurEdit, NDD_PROC_DATA* procData);
 
 #ifdef __cplusplus
 	}
 #endif
 
+static NDD_PROC_DATA s_procData;
+static QWidget* s_pMainNotepad = nullptr;
+std::function<QsciScintilla* ()> s_getCurEdit;
+
 bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData)
 {
 	if(pProcData == NULL)
@@ -39,21 +43,39 @@ bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData)
 
 	pProcData->m_version = QString("v1.0");
 	pProcData->m_auther = QString("zuowei.yin");
+
+	pProcData->m_menuType = 1;
 	return true;
 }
 
-//插件的入口点函数
-int NDD_PROC_MAIN(QWidget* parent, const QString &strFileName, std::function<QsciScintilla*()>getCurEdit)
+//则点击菜单栏按钮时,会自动调用到该插件的入口点函数。
+//pNotepad:就是CCNotepad的主界面指针
+//strFileName:当前插件DLL的全路径,如果不关心,则可以不使用
+//getCurEdit:从NDD主程序传递过来的仿函数,通过该函数获取当前编辑框操作对象QsciScintilla
+//pProcData:如果pProcData->m_menuType = 0 ,则该指针为空;如果pProcData->m_menuType = 1,则该指针有值。目前需要关心s_procData.m_rootMenu
+//开发者可以在该菜单下面,自行创建二级菜单
+int NDD_PROC_MAIN(QWidget* pNotepad, const QString& strFileName, std::function<QsciScintilla* ()>getCurEdit, NDD_PROC_DATA* pProcData)
 {
-	QsciScintilla* pEidt = getCurEdit();
 
-	QString text = pEidt->text();
+	//务必拷贝一份pProcData,在外面会释放。
+	if (pProcData != nullptr)
+	{
+		s_procData = *pProcData;
+	}
+	else
+	{
+		return -1;
+	}
 
-	//做一个简单的转大写的操作
+	s_pMainNotepad = pNotepad;
+	s_getCurEdit = getCurEdit;
 
-	text = text.toLower();
+	//如果pProcData->m_menuType = 1;是自己要创建二级菜单的场景。则通过s_procData.m_rootMenu 获取该插件的菜单根节点。
+	//插件开发者自行在s_procData.m_rootMenu下添加新的二级菜单项目
 
-	pEidt->setText(text);
+	QAction* pAction = new QAction(s_procData.m_strPlugName, s_procData.m_rootMenu);
+	s_procData.m_rootMenu->addAction(pAction);
+	pAction->setText("Secondary Menu Example");
 
 	return 0;
 }

+ 14 - 6
src/pluginGl.h

@@ -1,13 +1,21 @@
 #pragma once
 #include <QString>
+#include <QMenu>
 
 struct ndd_proc_data
 {
-	QString m_strPlugName; //插件名称 必选
-	QString m_strFilePath; //lib 插件的全局路径。必选
-	QString m_strComment; //插件说明
-	QString m_version; //版本号码。可选
-	QString m_auther;//作者名称。可选
+	QString m_strPlugName; //插件名称 必选。插件里面需填写
+	QString m_strFilePath; //lib 插件的全局路径。必选。插件内部不用填写,主程序传递下来
+	QString m_strComment; //插件说明;插件里面需填写
+	QString m_version; //版本号码。可选;插件里面需填写
+	QString m_auther;//作者名称。可选;插件里面需填写
+	int m_menuType;//菜单类型。0:不使用二级菜单 1:创建二级菜单;插件里面需填写
+	QMenu* m_rootMenu;//如果m_menuType = 1,给出二级根菜单的地址。其他值nullptr 插件内部不用填写,主程序传递下来
+
+	ndd_proc_data(): m_rootMenu(nullptr), m_menuType(0)
+	{
+
+	}
 };
 
 //#define NDD_PROC_IDENTIFY ("nddProc")
@@ -15,4 +23,4 @@ struct ndd_proc_data
 typedef struct ndd_proc_data NDD_PROC_DATA;
 
 typedef bool (*NDD_PROC_IDENTIFY_CALLBACK)(NDD_PROC_DATA* pProcData);
-typedef void (*NDD_PROC_FOUND_CALLBACK)(NDD_PROC_DATA* pProcData, void* pUserData);
+typedef void (*NDD_PROC_FOUND_CALLBACK)(NDD_PROC_DATA* pProcData, void* pUserData);