notepad--/patchs/base-39b61c737a6f38aaf4bb59...

2882 lines
83 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From 39b61c737a6f38aaf4bb59e8eb6f8c438e48c06e Mon Sep 17 00:00:00 2001
From: matheuter <210880040@qq.com>
Date: Thu, 20 Apr 2023 16:39:20 +0800
Subject: [PATCH 1/4] add actor to plugin_v2
---
src/actor.h | 129 +++++
src/actorprocessor.cpp | 67 +++
src/actorprocessor.h | 67 +++
src/cceditor/ccnotepad.cpp | 73 ++-
src/cceditor/ccnotepad.h | 9 +-
src/functiontraits.h | 81 +++
src/plugin.h | 2 +
src/plugin/CMakeLists.txt | 16 +-
src/plugin/filetreeview/CMakeLists.txt | 74 +++
src/plugin/filetreeview/abstractfile.cpp | 6 +
src/plugin/filetreeview/abstractfile.h | 11 +
src/plugin/filetreeview/actor.h | 120 ++++
src/plugin/filetreeview/actorprocessor.cpp | 67 +++
src/plugin/filetreeview/actorprocessor.h | 66 +++
src/plugin/filetreeview/filesystemmodel.cpp | 526 ++++++++++++++++++
src/plugin/filetreeview/filesystemmodel.h | 193 +++++++
src/plugin/filetreeview/filetreeview.cpp | 195 +++++++
src/plugin/filetreeview/filetreeview.h | 73 +++
.../filetreeview/filetreeviewexport.cpp | 77 +++
.../filetreeview/filetreeviewplugin.cpp | 121 ++++
src/plugin/filetreeview/filetreeviewplugin.h | 40 ++
21 files changed, 2001 insertions(+), 12 deletions(-)
create mode 100644 src/actor.h
create mode 100644 src/actorprocessor.cpp
create mode 100644 src/actorprocessor.h
create mode 100644 src/functiontraits.h
create mode 100644 src/plugin/filetreeview/CMakeLists.txt
create mode 100644 src/plugin/filetreeview/abstractfile.cpp
create mode 100644 src/plugin/filetreeview/abstractfile.h
create mode 100644 src/plugin/filetreeview/actor.h
create mode 100644 src/plugin/filetreeview/actorprocessor.cpp
create mode 100644 src/plugin/filetreeview/actorprocessor.h
create mode 100644 src/plugin/filetreeview/filesystemmodel.cpp
create mode 100644 src/plugin/filetreeview/filesystemmodel.h
create mode 100644 src/plugin/filetreeview/filetreeview.cpp
create mode 100644 src/plugin/filetreeview/filetreeview.h
create mode 100644 src/plugin/filetreeview/filetreeviewexport.cpp
create mode 100644 src/plugin/filetreeview/filetreeviewplugin.cpp
create mode 100644 src/plugin/filetreeview/filetreeviewplugin.h
diff --git a/src/actor.h b/src/actor.h
new file mode 100644
index 0000000..86378d0
--- /dev/null
+++ b/src/actor.h
@@ -0,0 +1,129 @@
+#pragma once
+#include <cstdint>
+#include <string>
+#include <memory>
+#include <tuple>
+#include <functional>
+
+#include "functiontraits.h"
+
+/**
+ * @brief Actor class, which encapsulates the event model
+ * @note enable_shared_from_this allows us to get safe Pointers internally
+ */
+class Actor : public std::enable_shared_from_this<Actor>
+{
+public:
+ using Ptr = std::shared_ptr<Actor>;
+ using FunctionWapper = std::function<void(void*, void*)>;
+
+public:
+ Actor(){}
+ ~Actor(){}
+
+ /**
+ * @brief Register the callback function and construct the anonymous function with std::bind
+ */
+ template<typename Function>
+ void operator+=(Function&& function_any) noexcept
+ {
+ m_invokeFunctionWapper = { std::bind(&invoker<Function>::apply, function_any, std::placeholders::_1, std::placeholders::_2) };
+ }
+
+ /**
+ * @brief Register the callback function and construct the anonymous function with std::bind
+ */
+ template<typename Function>
+ void registerFunction(Function&& function_any) noexcept
+ {
+ m_invokeFunctionWapper = { std::bind(&invoker<Function>::apply, function_any, std::placeholders::_1, std::placeholders::_2) };
+ }
+
+ /**
+ * @brief Register the callback function and construct the anonymous function with std::bind
+ */
+ template<typename ... Args>
+ void invoke(Args&& ... args) const noexcept
+ {
+ auto args_tuple = std::make_tuple(std::forward<Args>(args)...);
+ m_invokeFunctionWapper(&args_tuple, nullptr);
+ }
+
+ /**
+ * @brief Register the callback function and construct the anonymous function with std::bind
+ */
+ template<typename R, typename ... Args>
+ R invoke(Args&& ...args) const
+ {
+ using tuple_args_type = std::tuple<Args...>;
+ char data[sizeof(tuple_args_type)];
+ std::tuple<Args...>* tuples_pointer = new (data) tuple_args_type;
+
+ *tuples_pointer = std::make_tuple(std::forward<Args>(args)...);
+
+ R return_value;
+ m_invokeFunctionWapper(tuples_pointer, &return_value);
+ return return_value;
+ }
+
+ Ptr getSharedPtr()
+ {
+ return shared_from_this();
+ }
+
+public:
+ /**
+ * @brief This struct encapsulates a function,
+ * essentially storing the return value and parameters in two variables
+ * which can unify the way the function is stored.
+ */
+ template<typename Function>
+ struct invoker
+ {
+ /**
+ * @brief
+ */
+ static inline void apply(const Function& func, void* bl, void* result)
+ {
+ using tuple_type = typename function_traits<Function>::tuple_type;
+ const tuple_type* tp = static_cast<tuple_type*>(bl);
+ call(func, *tp, result);
+ }
+
+ /**
+ * @brief
+ */
+ template<typename F, typename ... Args>
+ static typename std::enable_if<std::is_void<typename std::result_of<F(Args...)>::type>::value>::type
+ call(const F& f, const std::tuple<Args...>& tp, void*)
+ {
+ call_helper(f, std::make_index_sequence<sizeof... (Args)>{}, tp);
+ }
+
+ /**
+ * @brief
+ */
+ template<typename F, typename ... Args>
+ static typename std::enable_if<!std::is_void<typename std::result_of<F(Args...)>::type>::value>::type
+ call(const F& f, const std::tuple<Args...>& tp, void* result)
+ {
+ auto r = call_helper(f, std::make_index_sequence<sizeof... (Args)>{}, tp);
+ *(decltype(r)*)result = r;
+ }
+
+ /**
+ * @brief
+ */
+ template<typename F, size_t... I, typename ... Args>
+ static auto call_helper(const F& f, const std::index_sequence<I...>& h, const std::tuple<Args...>& tup)
+ {
+ return f(std::get<I>(tup)...);
+ }
+ };
+private:
+ /**
+ * @note m_invokeFunctions is an anonymous lamba expression that encapsulates a function
+ * Functions include Lamba expressions, member functions, funtor, ordinary functions, and function Pointers
+ */
+ FunctionWapper m_invokeFunctionWapper;
+};
diff --git a/src/actorprocessor.cpp b/src/actorprocessor.cpp
new file mode 100644
index 0000000..099d1f6
--- /dev/null
+++ b/src/actorprocessor.cpp
@@ -0,0 +1,67 @@
+#include "actorprocessor.h"
+ActorProcessor::ActorProcessor():
+ m_actorMap(new std::unordered_map<std::string, Actor*>)
+{}
+
+/**
+ * @brief
+ */
+ActorProcessor::~ActorProcessor()
+{
+ for (auto& item : (*m_actorMap))
+ {
+ if(item.second != nullptr)
+ delete item.second;
+ }
+ if (m_actorMap)
+ delete m_actorMap;
+}
+
+/**
+ * @brief
+ */
+void ActorProcessor::registerActor(const std::string &route, Actor *actor)
+{
+ m_actorMap->insert(std::make_pair(route,actor));
+}
+
+/**
+ * @brief
+ */
+void ActorProcessor::removeActor(const std::string &route)
+{
+ auto iter = (*m_actorMap).find(route);
+ if(iter != m_actorMap->end())
+ {
+ m_actorMap->erase(route);
+ delete iter->second;
+ }
+}
+
+/**
+ * @brief
+ */
+Actor *ActorProcessor::findActor(const std::string &route)
+{
+ auto iter = (*m_actorMap).find(route);
+ if(iter != m_actorMap->end())
+ {
+ return (*m_actorMap)[route];
+ }
+ return nullptr;
+}
+
+/**
+ * @brief
+ */
+bool ActorProcessor::resetActor(const std::string &route, Actor *actor)
+{
+ auto iter = (*m_actorMap).find(route);
+ if(iter != m_actorMap->end())
+ {
+ m_actorMap->erase(route);
+ delete iter->second;
+ return true;
+ }
+ return false;
+}
diff --git a/src/actorprocessor.h b/src/actorprocessor.h
new file mode 100644
index 0000000..9026909
--- /dev/null
+++ b/src/actorprocessor.h
@@ -0,0 +1,67 @@
+#ifndef EVENTPROCESSOR_H
+#define EVENTPROCESSOR_H
+
+#include <string>
+#include <functional>
+#include <map>
+#include <iostream>
+#include <unordered_map>
+#include "actor.h"
+
+class ActorProcessor
+{
+public:
+ ActorProcessor();
+ ~ActorProcessor();
+public:
+
+ /**
+ * @brief Register the callback function and construct the anonymous function with std::bind
+ */
+ template<typename ... Args>
+ void invoke(const std::string& route,Args&& ... args) const noexcept
+ {
+ if (m_actorMap->find(route) != m_actorMap->end())
+ (*m_actorMap)[route]->invoke(std::forward<Args>(args)...);
+ }
+
+ /**
+ * @brief Register the callback function and construct the anonymous function with std::bind
+ */
+ template<typename R, typename ... Args>
+ R invoke(const std::string& route,Args&& ...args) const
+ {
+ if (m_actorMap->find(route) != m_actorMap->end())
+ return (*m_actorMap)[route]->invoke(std::forward<Args>(args)...);
+ return nullptr;
+ }
+
+ /**
+ * @brief 注册一个actor其中route是唯一的
+ */
+ void registerActor(const std::string& route, Actor*actor);
+
+ /**
+ * @brief 删除一个actor
+ */
+ void removeActor(const std::string& route);
+
+ /**
+ * @brief 查找一个actor 返回其指针
+ */
+ Actor* findActor(const std::string& route);
+
+ /**
+ * @brief 重置一个actor注意原有的actor会被删除
+ */
+ bool resetActor(const std::string& route,Actor*actor);
+
+private:
+ std::unordered_map<std::string, Actor*>* m_actorMap;
+private:
+ // not allow copy constroct
+ ActorProcessor(ActorProcessor&&)=delete;
+ ActorProcessor& operator=(const ActorProcessor&)=delete;
+};
+
+#endif // EVENTPROCESSOR_H
diff --git a/src/cceditor/ccnotepad.cpp b/src/cceditor/ccnotepad.cpp
index eb3ad4f..b74f1ca 100755
--- a/src/cceditor/ccnotepad.cpp
+++ b/src/cceditor/ccnotepad.cpp
@@ -32,6 +32,8 @@
#include "pluginmgr.h"
#include "plugin.h"
#include "pluginGl.h"
+#include "actor.h"
+#include "actorprocessor.h"
#endif
#ifdef Q_OS_WIN
@@ -1211,6 +1213,10 @@ CCNotePad::CCNotePad(bool isMainWindows, QWidget *parent)
restoreGeometry(lastGeo);
}
#endif
+
+#ifdef NO_PLUGIN
+ processor = new ActorProcessor();
+#endif
}
CCNotePad::~CCNotePad()
@@ -1748,9 +1754,10 @@ void CCNotePad::onPlugFound(NDD_PROC_DATA& procData, QMenu* pUserData)
{
QAction* pAction = new QAction(procData.m_strPlugName, pMenu);
pMenu->addAction(pAction);
- pAction->setText(procData.m_strPlugName);
- pAction->setData(procData.m_strFilePath);
- connect(pAction, &QAction::triggered, this, &CCNotePad::onPlugWork);
+ pAction->setText(procData.m_strPlugName);
+ pAction->setData(procData.m_strFilePath);
+ connect(pAction, &QAction::triggered, this, &CCNotePad::onPlugWork);
+ connect(pAction, &QAction::triggered, this, &CCNotePad::onPlugWorkV2);
}
else if (procData.m_menuType == 1)
{
@@ -1761,6 +1768,7 @@ void CCNotePad::onPlugFound(NDD_PROC_DATA& procData, QMenu* pUserData)
//菜单句柄通过procData传递到插件中
procData.m_rootMenu = pluginMenu;
sendParaToPlugin(procData);
+ sendParaToPluginV2(procData);
}
else
{
@@ -1796,6 +1804,39 @@ void CCNotePad::onPlugWork(bool check)
}
}
+//真正执行插件的工作
+void CCNotePad::onPlugWorkV2(bool check)
+{
+
+ qDebug() << "test1";
+ QAction* pAct = dynamic_cast<QAction*>(sender());
+ if (pAct != nullptr)
+ {
+ QString plugPath = pAct->data().toString();
+
+ QLibrary* pLib = new QLibrary(plugPath);
+
+ NDD_PROC_MAIN_V2_CALLBACK pMainCallBack;
+ pMainCallBack = (NDD_PROC_MAIN_V2_CALLBACK)pLib->resolve("NDD_PROC_MAIN_V2");
+
+ if (pMainCallBack != NULL)
+ {
+ std::function<QsciScintilla* ()> foundCallBack = std::bind(&CCNotePad::getCurEditView, this);
+ Actor* actor = new Actor;
+
+ actor->registerFunction([this](QString name, int num){openFile(name,num);});
+
+ processor->registerActor("openFile",actor);
+ pMainCallBack(this, plugPath, processor, nullptr);
+ }
+ else
+ {
+ ui.statusBar->showMessage(tr("plugin %1 load failed !").arg(plugPath), 10000);
+ }
+
+ }
+}
+
//把插件需要的参数,传递到插件中去
void CCNotePad::sendParaToPlugin(NDD_PROC_DATA& procData)
{
@@ -1818,6 +1859,32 @@ void CCNotePad::sendParaToPlugin(NDD_PROC_DATA& procData)
}
}
+
+void CCNotePad::sendParaToPluginV2(NDD_PROC_DATA& procData)
+{
+ qDebug() <<"test5";
+ QString plugPath = procData.m_strFilePath;
+
+ QLibrary* pLib = new QLibrary(plugPath);
+
+ NDD_PROC_MAIN_V2_CALLBACK pMainCallBack;
+ pMainCallBack = (NDD_PROC_MAIN_V2_CALLBACK)pLib->resolve("NDD_PROC_MAIN_V2");
+
+ if (pMainCallBack != NULL)
+ {
+ Actor* actor = new Actor;
+
+ actor->registerFunction([this](QString name, int num){openFile(name,num);});
+
+ processor->registerActor("openFile",actor);
+ pMainCallBack(this, plugPath, processor, &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);
diff --git a/src/cceditor/ccnotepad.h b/src/cceditor/ccnotepad.h
index 58e5eec..d2939ad 100755
--- a/src/cceditor/ccnotepad.h
+++ b/src/cceditor/ccnotepad.h
@@ -34,6 +34,7 @@ struct HexFileMgr;
struct TextFileMgr;
struct BigTextEditFileMgr;
class QtLangSet;
+class ActorProcessor;
static const char* Tail_Thread = "tailthread";
@@ -349,8 +350,10 @@ private slots:
void on_loadReceneFile();
void slot_pluginMgr();
#ifdef NO_PLUGIN
+ void onPlugWorkV2(bool check);
void onPlugWork(bool check);
- void sendParaToPlugin(NDD_PROC_DATA& procData);
+ void sendParaToPlugin(NDD_PROC_DATA& procData);
+ void sendParaToPluginV2(NDD_PROC_DATA& procData);
#endif
void slot_showWebAddr(bool check);
void slot_langFileSuffix();
@@ -524,6 +527,10 @@ private:
QSharedMemory* m_shareMem;
+#ifdef NO_PLUGIN
+ //actor执行与存储单元
+ ActorProcessor* processor;
+#endif
//最近打开的对比文件和目录列表。做一个环形区
diff --git a/src/functiontraits.h b/src/functiontraits.h
new file mode 100644
index 0000000..314b58b
--- /dev/null
+++ b/src/functiontraits.h
@@ -0,0 +1,81 @@
+#ifndef FUNCTIONTRAITS_H
+#define FUNCTIONTRAITS_H
+
+#include <utility>
+#include <functional>
+#include <algorithm>
+#include <tuple>
+
+template<typename T>
+struct function_traits;
+
+template<typename ReturnType, typename... Args>
+struct function_traits<ReturnType(Args...)>
+{
+public:
+ enum {
+ value = sizeof...(Args)
+ };
+ using function_type = ReturnType(*)(Args...);
+ using return_type = ReturnType;
+ using stl_function_type = std::function<function_type>;
+ using function_pointer_type = ReturnType(*)(Args...);
+ using lambda_function_type = ReturnType(*)(Args...);
+
+ using tuple_type = std::tuple<std::remove_cv_t<std::remove_reference_t<Args>>...> ;
+ using bare_tuple_type = std::tuple<std::remove_const_t<std::remove_reference_t<Args>>...>;
+
+ template<std::size_t N, typename = typename std::enable_if<(N < value)>::type>
+ using args = typename std::tuple_element<N, std::tuple<Args...>>;
+
+ template <std::size_t N>
+ struct arguments
+ {
+ static_assert(N < value, "[error]:invalid parameter index.");
+ using type = typename std::tuple_element<N, std::tuple<Args...>>::type;
+ };
+};
+
+template<typename ReturnType, typename... Args>
+struct function_traits<ReturnType(*)(Args...)> : function_traits<ReturnType(Args...)> {};
+
+template<typename ReturnType, typename... Args>
+struct function_traits<std::function<ReturnType(Args...)>> : function_traits<ReturnType(Args...)> {};
+
+template <typename ReturnType, typename ClassType, typename... Args>
+struct function_traits<ReturnType(ClassType::*)(Args...)> : function_traits<ReturnType(Args...)>{};
+
+template <typename ReturnType, typename ClassType, typename... Args>
+struct function_traits<ReturnType(ClassType::*)(Args...) const> : function_traits<ReturnType(Args...)> {};
+
+template <typename ReturnType, typename ClassType, typename... Args>
+struct function_traits<ReturnType(ClassType::*)(Args...) volatile> : function_traits<ReturnType(Args...)> {};
+
+template <typename ReturnType, typename ClassType, typename... Args>
+struct function_traits<ReturnType(ClassType::*)(Args...) const volatile> : function_traits<ReturnType(Args...)> {};
+
+template<typename Callable>
+struct function_traits : function_traits<decltype(&Callable::operator())> {};
+
+template<typename Function>
+typename function_traits<Function>::stl_function_type
+function_cast(const Function& lambda)
+{
+ return static_cast<typename function_traits<Function>::stl_function_type>(std::forward<Function>(lambda));
+}
+
+template<typename Function>
+typename function_traits<Function>::stl_function_type
+function_cast(Function&& lambda)
+{
+ return static_cast<typename function_traits<Function>::stl_function_type>(lambda);
+}
+
+template<typename Function>
+typename function_traits<Function>::function_pointer_type
+function_cast(const Function& lambda)
+{
+ return static_cast<typename function_traits<Function>::pointer>(lambda);
+}
+
+#endif // FUNCTIONTRAITS_H
diff --git a/src/plugin.h b/src/plugin.h
index c2731be..0f417a9 100755
--- a/src/plugin.h
+++ b/src/plugin.h
@@ -4,7 +4,9 @@
class QMenu;
class QsciScintilla;
class QWidget;
+class ActorProcessor;
typedef int (*NDD_PROC_MAIN_CALLBACK)(QWidget* parent, const QString& strFileName, std::function<QsciScintilla*()>getCurEdit, NDD_PROC_DATA* procData);
+typedef int (*NDD_PROC_MAIN_V2_CALLBACK)(QWidget* parent, const QString& strFileName,ActorProcessor*processor, NDD_PROC_DATA* procData);
int loadProc(const QString& strDirOut, std::function<void(NDD_PROC_DATA&, QMenu*)> funcallback, QMenu* pUserData);
diff --git a/src/plugin/CMakeLists.txt b/src/plugin/CMakeLists.txt
index c9b8d26..8e1db46 100644
--- a/src/plugin/CMakeLists.txt
+++ b/src/plugin/CMakeLists.txt
@@ -1,4 +1,4 @@
-
+
option(USE_NOTEPAD_PLUGIN "构建 Notepad-- 内部插件" ON)
option(USE_NOTEPAD_PLUGIN_BASE "构建 Notepad-- 内部的插件基础模板" OFF)
@@ -19,12 +19,12 @@ if(USE_NOTEPAD_PLUGIN)
add_subdirectory(template-plugins/base-secondary-menu-ui-plugin-v1)
endif(USE_NOTEPAD_PLUGIN_BASE)
- # 一个简单的插件示例,但依赖于外部的 opencc 项目(基于 git)
- add_subdirectory(opencc-demo-plugin)
- # 一个简单的版本更新检查的插件
- add_subdirectory(versionUpdate)
- # 一个简单的可二次扩展的插件
- add_subdirectory(external-plugin)
+# # 一个简单的插件示例,但依赖于外部的 opencc 项目(基于 git)
+# add_subdirectory(opencc-demo-plugin)
+# # 一个简单的版本更新检查的插件
+# add_subdirectory(versionUpdate)
+# # 一个简单的可二次扩展的插件
+# add_subdirectory(external-plugin)
# Linux 可构建的插件
if(UNIX AND NOT APPLE)
@@ -33,6 +33,6 @@ if(USE_NOTEPAD_PLUGIN)
endif(UNIX AND NOT APPLE)
# TTS 语音合成
- add_subdirectory(TTS-plugin)
+ add_subdirectory(filetreeview)
endif(USE_NOTEPAD_PLUGIN)
diff --git a/src/plugin/filetreeview/CMakeLists.txt b/src/plugin/filetreeview/CMakeLists.txt
new file mode 100644
index 0000000..d74905a
--- /dev/null
+++ b/src/plugin/filetreeview/CMakeLists.txt
@@ -0,0 +1,74 @@
+set(LOCAL_PLUGIN_NAME "filetreeview")
+
+# TTS-plugin 核心构建
+# 在模块化构建中,这个部分代表着构建 TTS-plugin 插件
+# 1. 默认构建时产出的目标为 TTS-plugin
+# 2. 在此处可对 TTS-plugin 目标进行详细的构建计划
+
+if(TRUE)
+ # 准备构建 TTS-plugin 主程序扩展
+ spark_file_glob(LocalSources
+ ./*.h ./*.cpp ./*.ui
+ )
+ spark_add_library(${LOCAL_PLUGIN_NAME} SHARED ${LocalSources})
+ target_include_directories(${LOCAL_PLUGIN_NAME} PRIVATE
+ ${PROJECT_SOURCE_DIR}/src
+ ${PROJECT_SOURCE_DIR}/src/cceditor
+
+ ${PROJECT_SOURCE_DIR}/src/qscint/src
+ ${PROJECT_SOURCE_DIR}/src/qscint/src/Qsci
+ ${PROJECT_SOURCE_DIR}/src/qscint/scintilla/src
+ ${PROJECT_SOURCE_DIR}/src/qscint/scintilla/include
+ ${PROJECT_SOURCE_DIR}/src/qscint/scintilla/lexlib
+ ${PROJECT_SOURCE_DIR}/src/qscint/scintilla/boostregex
+ )
+ # target_link_libraries(${LOCAL_PLUGIN_NAME} QSci)
+ target_link_QSci(${LOCAL_PLUGIN_NAME})
+ if(USE_QT6)
+ # target_link_qt6_Core5Compat(${LOCAL_PLUGIN_NAME}) # 兼容性: Qt6 可使用 Core5Compat 少量更改 Qt5 部分
+ # target_link_qt6_PrintSupport(${LOCAL_PLUGIN_NAME})
+ # target_link_qt6_XmlPatterns(${LOCAL_PLUGIN_NAME}) # Bug 初期配置时无此依赖要求
+ else()
+ # target_link_qt5_PrintSupport(${LOCAL_PLUGIN_NAME})
+ # target_link_qt5_XmlPatterns(${LOCAL_PLUGIN_NAME})
+ endif(USE_QT6)
+
+ # 确保生成到 Notepad-- 的相对 plugin 目录下
+ set_target_properties(${LOCAL_PLUGIN_NAME}
+ PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY $<TARGET_FILE_DIR:${PROJECT_NAME}>/plugin
+ LIBRARY_OUTPUT_DIRECTORY $<TARGET_FILE_DIR:${PROJECT_NAME}>/plugin
+ ARCHIVE_OUTPUT_DIRECTORY $<TARGET_FILE_DIR:${PROJECT_NAME}>/plugin)
+
+ # 控制是否安装到 bin/plugin 而各种配方之下,每个位置或许都不一样(特别是 Linux)
+ # install(TARGETS ${LOCAL_PLUGIN_NAME} DESTINATION bin/plugin)
+endif(TRUE)
+
+
+# ----------------- TTS-plugin 构建宏支持相关 ----------------- #
+
+if(WIN32 AND NOTEPAD_BUILD_BY_SHARED)
+ # 在 Windows 中构建时需要关注此库的构建形式QScintilla 应该以何种方式编译
+ target_compile_definitions(${LOCAL_PLUGIN_NAME}
+ PRIVATE
+ NOTEPAD_PLUGIN_MANAGER
+ QSCINTILLA_DLL # 目前在 Windows 中使用 QSci 库时应该采用 Q_DECL_IMPORT
+ # 控制 QSCINTILLA_EXPORT 符号应为 Q_DECL_IMPORT
+ )
+else()
+ # 在 Windows 中构建时需要关注此库的构建形式QScintilla 应该以何种方式编译
+ target_compile_definitions(${LOCAL_PLUGIN_NAME}
+ PRIVATE
+ NOTEPAD_PLUGIN_MANAGER
+ # QSCINTILLA_DLL # 目前在 Windows 中使用 QSci 库时应该采用 Q_DECL_IMPORT
+ # 控制 QSCINTILLA_EXPORT 符号应为 Q_DECL_IMPORT
+ )
+endif(WIN32 AND NOTEPAD_BUILD_BY_SHARED)
+
+if(UNIX)
+ # 默认在 Unix/Linux 中仅需要定义一个内部插件宏管理器
+ target_compile_definitions(${LOCAL_PLUGIN_NAME}
+ PRIVATE
+ NOTEPAD_PLUGIN_MANAGER
+ )
+endif(UNIX)
diff --git a/src/plugin/filetreeview/abstractfile.cpp b/src/plugin/filetreeview/abstractfile.cpp
new file mode 100644
index 0000000..9b8673f
--- /dev/null
+++ b/src/plugin/filetreeview/abstractfile.cpp
@@ -0,0 +1,6 @@
+#include "abstractfile.h"
+
+AbstractFile::AbstractFile()
+{
+
+}
diff --git a/src/plugin/filetreeview/abstractfile.h b/src/plugin/filetreeview/abstractfile.h
new file mode 100644
index 0000000..94ae7dc
--- /dev/null
+++ b/src/plugin/filetreeview/abstractfile.h
@@ -0,0 +1,11 @@
+#ifndef ABSTRACTFILE_H
+#define ABSTRACTFILE_H
+
+
+class AbstractFile
+{
+public:
+ AbstractFile();
+};
+
+#endif // ABSTRACTFILE_H
diff --git a/src/plugin/filetreeview/actor.h b/src/plugin/filetreeview/actor.h
new file mode 100644
index 0000000..d3901a2
--- /dev/null
+++ b/src/plugin/filetreeview/actor.h
@@ -0,0 +1,120 @@
+#pragma once
+#include <cstdint>
+#include <string>
+#include <memory>
+#include <tuple>
+#include <functional>
+
+#include "functiontraits.h"
+
+/**
+ * @brief Actor class, which encapsulates the event model
+ * @note enable_shared_from_this allows us to get safe Pointers internally
+ */
+class Actor : public std::enable_shared_from_this<Actor>
+{
+public:
+ using Ptr = std::shared_ptr<Actor>;
+ using FunctionWapper = std::function<void(void*, void*)>;
+
+public:
+ Actor(){}
+ ~Actor(){}
+
+ /**
+ * @brief Register the callback function and construct the anonymous function with std::bind
+ */
+ template<typename Function>
+ void registerFunction(Function&& function_any) noexcept
+ {
+ m_invokeFunctionWapper = { std::bind(&invoker<Function>::apply, function_any, std::placeholders::_1, std::placeholders::_2) };
+ }
+
+ /**
+ * @brief Register the callback function and construct the anonymous function with std::bind
+ */
+ template<typename ... Args>
+ void invoke(Args&& ... args) const noexcept
+ {
+ auto args_tuple = std::make_tuple(std::forward<Args>(args)...);
+ m_invokeFunctionWapper(&args_tuple, nullptr);
+ }
+
+ /**
+ * @brief Register the callback function and construct the anonymous function with std::bind
+ */
+ template<typename R, typename ... Args>
+ R invoke(Args&& ...args) const
+ {
+ using tuple_args_type = std::tuple<Args...>;
+ char data[sizeof(tuple_args_type)];
+ std::tuple<Args...>* tuples_pointer = new (data) tuple_args_type;
+
+ *tuples_pointer = std::make_tuple(std::forward<Args>(args)...);
+
+ R return_value;
+ m_invokeFunctionWapper(tuples_pointer, &return_value);
+ return return_value;
+ }
+
+ Ptr getSharedPtr()
+ {
+ return shared_from_this();
+ }
+
+public:
+ /**
+ * @brief This struct encapsulates a function,
+ * essentially storing the return value and parameters in two variables
+ * which can unify the way the function is stored.
+ */
+ template<typename Function>
+ struct invoker
+ {
+ /**
+ * @brief
+ */
+ static inline void apply(const Function& func, void* bl, void* result)
+ {
+ using tuple_type = typename function_traits<Function>::tuple_type;
+ const tuple_type* tp = static_cast<tuple_type*>(bl);
+ call(func, *tp, result);
+ }
+
+ /**
+ * @brief
+ */
+ template<typename F, typename ... Args>
+ static typename std::enable_if<std::is_void<typename std::result_of<F(Args...)>::type>::value>::type
+ call(const F& f, const std::tuple<Args...>& tp, void*)
+ {
+ call_helper(f, std::make_index_sequence<sizeof... (Args)>{}, tp);
+ }
+
+ /**
+ * @brief
+ */
+ template<typename F, typename ... Args>
+ static typename std::enable_if<!std::is_void<typename std::result_of<F(Args...)>::type>::value>::type
+ call(const F& f, const std::tuple<Args...>& tp, void* result)
+ {
+ auto r = call_helper(f, std::make_index_sequence<sizeof... (Args)>{}, tp);
+ *(decltype(r)*)result = r;
+ }
+
+ /**
+ * @brief
+ */
+ template<typename F, size_t... I, typename ... Args>
+ static auto call_helper(const F& f, const std::index_sequence<I...>& h, const std::tuple<Args...>& tup)
+ {
+ return f(std::get<I>(tup)...);
+ }
+ };
+private:
+ /**
+ * @note m_invokeFunctions is an anonymous lamba expression that encapsulates a function
+ * Functions include Lamba expressions, member functions, funtor, ordinary functions, and function Pointers
+ */
+ FunctionWapper m_invokeFunctionWapper;
+};
diff --git a/src/plugin/filetreeview/actorprocessor.cpp b/src/plugin/filetreeview/actorprocessor.cpp
new file mode 100644
index 0000000..099d1f6
--- /dev/null
+++ b/src/plugin/filetreeview/actorprocessor.cpp
@@ -0,0 +1,67 @@
+#include "actorprocessor.h"
+ActorProcessor::ActorProcessor():
+ m_actorMap(new std::unordered_map<std::string, Actor*>)
+{}
+
+/**
+ * @brief
+ */
+ActorProcessor::~ActorProcessor()
+{
+ for (auto& item : (*m_actorMap))
+ {
+ if(item.second != nullptr)
+ delete item.second;
+ }
+ if (m_actorMap)
+ delete m_actorMap;
+}
+
+/**
+ * @brief
+ */
+void ActorProcessor::registerActor(const std::string &route, Actor *actor)
+{
+ m_actorMap->insert(std::make_pair(route,actor));
+}
+
+/**
+ * @brief
+ */
+void ActorProcessor::removeActor(const std::string &route)
+{
+ auto iter = (*m_actorMap).find(route);
+ if(iter != m_actorMap->end())
+ {
+ m_actorMap->erase(route);
+ delete iter->second;
+ }
+}
+
+/**
+ * @brief
+ */
+Actor *ActorProcessor::findActor(const std::string &route)
+{
+ auto iter = (*m_actorMap).find(route);
+ if(iter != m_actorMap->end())
+ {
+ return (*m_actorMap)[route];
+ }
+ return nullptr;
+}
+
+/**
+ * @brief
+ */
+bool ActorProcessor::resetActor(const std::string &route, Actor *actor)
+{
+ auto iter = (*m_actorMap).find(route);
+ if(iter != m_actorMap->end())
+ {
+ m_actorMap->erase(route);
+ delete iter->second;
+ return true;
+ }
+ return false;
+}
diff --git a/src/plugin/filetreeview/actorprocessor.h b/src/plugin/filetreeview/actorprocessor.h
new file mode 100644
index 0000000..d057e6d
--- /dev/null
+++ b/src/plugin/filetreeview/actorprocessor.h
@@ -0,0 +1,66 @@
+#ifndef EVENTPROCESSOR_H
+#define EVENTPROCESSOR_H
+
+#include <string>
+#include <functional>
+#include <map>
+#include <iostream>
+#include <unordered_map>
+#include "actor.h"
+
+class ActorProcessor
+{
+public:
+ ActorProcessor();
+ ~ActorProcessor();
+public:
+
+ /**
+ * @brief Register the callback function and construct the anonymous function with std::bind
+ */
+ template<typename ... Args>
+ void invoke(const std::string& route,Args&& ... args) const noexcept
+ {
+ if (m_actorMap->find(route) != m_actorMap->end())
+ (*m_actorMap)[route]->invoke(std::forward<Args>(args)...);
+ }
+
+ /**
+ * @brief Register the callback function and construct the anonymous function with std::bind
+ */
+ template<typename R, typename ... Args>
+ R invoke(const std::string& route,Args&& ...args) const
+ {
+ if (m_actorMap->find(route) != m_actorMap->end())
+ return (*m_actorMap)[route]->invoke(std::forward<Args>(args)...);
+ return nullptr;
+ }
+
+ /**
+ * @brief 注册一个actor其中route是唯一的
+ */
+ void registerActor(const std::string& route, Actor*actor);
+
+ /**
+ * @brief 删除一个actor
+ */
+ void removeActor(const std::string& route);
+
+ /**
+ * @brief 查找一个actor 返回其指针
+ */
+ Actor* findActor(const std::string& route);
+
+ /**
+ * @brief 重置一个actor注意原有的actor会被删除
+ */
+ bool resetActor(const std::string& route,Actor*actor);
+
+private:
+ std::unordered_map<std::string, Actor*>* m_actorMap;
+private:
+ ActorProcessor(ActorProcessor&&)=delete;
+ ActorProcessor& operator=(const ActorProcessor&)=delete;
+};
+
+#endif // EVENTPROCESSOR_H
diff --git a/src/plugin/filetreeview/filesystemmodel.cpp b/src/plugin/filetreeview/filesystemmodel.cpp
new file mode 100644
index 0000000..5b825b5
--- /dev/null
+++ b/src/plugin/filetreeview/filesystemmodel.cpp
@@ -0,0 +1,526 @@
+#include "filesystemmodel.h"
+
+#include <QFileInfo>
+#include <QDir>
+#include <QIcon>
+#include <QFont>
+#include <QFileIconProvider>
+#include <QFileSystemWatcher>
+#include <QMutexLocker>
+#include <QDebug>
+
+FileNode::FileNode(FileSystemModel *model) :
+ m_model(model),
+ m_parent(0),
+ m_children(0),
+ m_bWatcher(false)
+{
+
+}
+
+FileNode::FileNode(FileSystemModel *model, const QString &path, FileNode *parent) :
+ m_model(model),
+ m_parent(parent),
+ m_children(0),
+ m_path(path),
+ m_bWatcher(false)
+{
+ QFileInfo info(path);
+ if (m_model->isRootPathNodeFillPath() && parent && parent->getNodeParent() == 0) {
+ m_text = QDir::toNativeSeparators(info.filePath());
+ } else {
+ m_text = info.fileName();
+ }
+}
+
+FileNode::~FileNode()
+{
+ clear();
+ if (m_children) {
+ delete m_children;
+ }
+ if (m_bWatcher) {
+ m_model->removeWatcher(m_path);
+ }
+}
+
+QList<FileNode*>* FileNode::getChildrenList()
+{
+ if (m_children == 0) {
+ m_children = new QList<FileNode*>();
+ if (!m_path.isEmpty()) {
+ QFileInfo info(m_path);
+ if (info.isDir()) {
+ QDir dir(m_path);
+ foreach(QFileInfo childInfo, dir.entryInfoList(this->m_model->filter(),this->m_model->dirSort())) {
+ if (!this->m_model->isShowHideFiles() && childInfo.isDir() && childInfo.fileName().startsWith(".")) {
+ continue;
+ }
+ m_children->append(new FileNode(this->m_model,childInfo.filePath(),this));
+ }
+ }
+ }
+ if (!m_children->isEmpty() && !m_bWatcher) {
+ m_bWatcher = true;
+ m_model->addWatcher(m_path);
+ }
+ }
+ return m_children;
+}
+
+FileNode* FileNode::getNodeParent()
+{
+ return m_parent;
+}
+
+FileNode* FileNode::getChild(int row)
+{
+ return getChildrenList()->at(row);
+}
+
+int FileNode::childCount()
+{
+ return getChildrenList()->count();
+}
+
+int FileNode::row() const
+{
+ if (m_parent) {
+ return m_parent->getChildrenList()->indexOf(const_cast<FileNode*>(this));
+ }
+ return 0;
+}
+
+QString FileNode::getNodePath() const
+{
+ return m_path;
+}
+
+QString FileNode::text() const
+{
+ return m_text;
+}
+
+bool FileNode::isDir() const
+{
+ return QFileInfo(m_path).isDir();
+}
+
+bool FileNode::isFile() const
+{
+ return QFileInfo(m_path).isFile();
+}
+
+QFileInfo FileNode::getFileInformation() const
+{
+ return QFileInfo(m_path);
+}
+
+bool FileNode::isExist() const
+{
+ return QFileInfo(m_path).exists();
+}
+
+void FileNode::clear()
+{
+ if (m_children) {
+ qDeleteAll(m_children->begin(),m_children->end());
+ m_children->clear();
+ }
+}
+
+void FileNode::reload()
+{
+ clear();
+ if (m_children == 0) {
+ m_children = new QList<FileNode*>();
+ }
+ if (!m_path.isEmpty()) {
+ QFileInfo info(m_path);
+ if (info.isDir()) {
+ QDir dir(m_path);
+ foreach(QFileInfo childInfo, dir.entryInfoList(this->m_model->filter(),this->m_model->dirSort())) {
+ if (!this->m_model->isShowHideFiles() && childInfo.isDir() && childInfo.fileName().startsWith(".")) {
+ continue;
+ }
+ m_children->append(new FileNode(this->m_model,childInfo.filePath(),this));
+ }
+ }
+ }
+ if (!m_children->isEmpty() && !m_bWatcher) {
+ m_bWatcher = true;
+ m_model->addWatcher(m_path);
+ }
+}
+
+FileNode *FileNode::findPath(const QString &path)
+{
+ if (!path.startsWith(m_path)) {
+ return 0;
+ }
+ if (path == m_path) {
+ return this;
+ }
+ QStringList nameList = path.right(path.length()-m_path.length()).split("/",QString::SkipEmptyParts);
+ FileNode *parent = this;
+ bool find = false;
+ foreach (QString name,nameList) {
+ find = false;
+ QList<FileNode*>* chilren = parent->getChildrenList();
+ for (int i = 0; i < chilren->count(); i++) {
+ FileNode *node = chilren->at(i);
+ if (!node->isDir()) {
+ continue;
+ }
+ if (node->m_text == name) {
+ parent = node;
+ find = true;
+ break;
+ }
+ }
+ if (!find) {
+ return 0;
+ }
+ }
+ return parent;
+}
+
+FileSystemModel::FileSystemModel(QObject *parent) :
+ QAbstractItemModel(parent),
+ m_rootNode(new FileNode(this)),
+ m_iconProvider(new QFileIconProvider),
+ m_fileWatcher(0)
+{
+ m_dirFilter = QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot;
+ m_sorts = QDir::DirsFirst | QDir::Name | QDir::IgnoreCase;// | QDir::Type;
+ // connect(m_fileWatcher,SIGNAL(directoryChanged(QString)),this,SLOT(directoryChanged(QString)));
+}
+
+FileSystemModel::~FileSystemModel()
+{
+ delete m_rootNode;
+ delete m_iconProvider;
+ if (m_fileWatcher) {
+ delete m_fileWatcher;
+ }
+}
+
+void FileSystemModel::reloadDirectory(const QString &path)
+{
+ this->beginResetModel();
+ QDir dir(path);
+ bool b = dir.exists();
+ if (!b) {
+ m_fileWatcher->removePath(path);
+ }
+ foreach(QModelIndex index,this->findPaths(path)) {
+ FileNode *node = nodeFromIndex(index);
+ if (b) {
+ node->reload();
+ } else {
+ FileNode *parent = node->getNodeParent();
+ if (parent) {
+ parent->reload();
+ }
+ }
+ }
+ this->endResetModel();
+}
+
+FileNode *FileSystemModel::nodeFromIndex(const QModelIndex &index) const
+{
+ if (index.isValid()) {
+ return static_cast<FileNode*>(index.internalPointer());
+ }
+ return m_rootNode;
+}
+
+void FileSystemModel::setStartIndex(const QModelIndex &index)
+{
+ m_startPath = filePath(index);
+}
+
+void FileSystemModel::setStartPath(const QString &path)
+{
+ m_startPath = path;
+}
+
+QModelIndex FileSystemModel::startIndex() const
+{
+ return findPath(m_startPath);
+}
+
+QString FileSystemModel::startPath() const
+{
+ return m_startPath;
+}
+
+QString FileSystemModel::filePath(const QModelIndex &index) const
+{
+ return nodeFromIndex(index)->getNodePath();
+}
+
+void FileSystemModel::setFilter(QDir::Filters filters)
+{
+ if (m_dirFilter != filters) {
+ m_dirFilter = filters;
+ this->reload();
+ }
+}
+
+void FileSystemModel::setDirSort(QDir::SortFlags flags)
+{
+ if (m_sorts != flags) {
+ m_sorts = flags;
+ this->reload();
+ }
+}
+
+QDir::Filters FileSystemModel::filter() const
+{
+ return m_dirFilter;
+}
+
+bool FileSystemModel::isShowHideFiles() const
+{
+ return m_dirFilter & QDir::Hidden;
+}
+
+QDir::SortFlags FileSystemModel::dirSort() const
+{
+ return m_sorts;
+}
+
+void FileSystemModel::clear()
+{
+ this->beginResetModel();
+ m_rootNode->clear();
+ m_pathList.clear();
+ m_startPath.clear();
+ this->endResetModel();
+}
+
+void FileSystemModel::reload()
+{
+ this->setRootPathList(this->rootPathList());
+}
+
+void FileSystemModel::setRootPath(const QString &path)
+{
+ this->setRootPathList(QStringList() << path);
+}
+
+bool FileSystemModel::removeRootPath(const QString &path)
+{
+ QString pathName = QDir::fromNativeSeparators(path);
+ FileNode *node = 0;
+ int index = -1;
+ for (int i = 0; i < m_rootNode->childCount(); i++) {
+ node = m_rootNode->getChildrenList()->at(i);
+ if (node && (node->getNodePath() == pathName)) {
+ index = i;
+ break;
+ }
+ }
+ if (index == -1) {
+ return false;
+ }
+ if (!m_pathList.removeAll(pathName)) {
+ return false;
+ }
+ this->beginRemoveRows(QModelIndex(),index,index);
+ m_rootNode->getChildrenList()->removeAt(index);
+ delete node;
+ this->endRemoveRows();
+ return true;
+}
+
+
+bool FileSystemModel::addRootPath(const QString &path)
+{
+ QString pathName = QDir::fromNativeSeparators(QDir::cleanPath(path));
+ if (m_pathList.contains(pathName)) {
+ return false;
+ }
+ this->beginInsertRows(QModelIndex(),m_rootNode->childCount(),m_rootNode->childCount());
+ m_pathList.append(pathName);
+ m_rootNode->getChildrenList()->append(new FileNode(this,pathName,m_rootNode));
+ this->endInsertRows();
+ return true;
+}
+
+void FileSystemModel::setRootPathList(const QStringList &pathList)
+{
+ this->beginResetModel();
+ m_rootNode->clear();
+ m_fileWatcherMap.clear();
+ m_pathList.clear();
+ if (m_fileWatcher) {
+ disconnect(m_fileWatcher,0);
+ delete m_fileWatcher;
+ }
+ m_fileWatcher = new QFileSystemWatcher;
+ connect(m_fileWatcher,SIGNAL(directoryChanged(QString)),this,SIGNAL(direcotryChanged(QString)));
+
+ foreach (QString path, pathList) {
+ m_pathList.append(QDir::fromNativeSeparators(QDir::cleanPath(path)));
+ }
+ m_pathList.removeDuplicates();
+
+ foreach(QString path, m_pathList) {
+ m_rootNode->getChildrenList()->append(new FileNode(this,path,m_rootNode));
+ }
+
+ if (m_startPath.isEmpty() && !pathList.isEmpty()) {
+ m_startPath = pathList.first();
+ }
+
+ this->endResetModel();
+}
+
+QStringList FileSystemModel::rootPathList() const
+{
+ return m_pathList;
+}
+
+QModelIndex FileSystemModel::findPathHelper(const QString &path, const QModelIndex &parentIndex) const
+{
+ FileNode *node = nodeFromIndex(parentIndex);
+ if (!path.startsWith(node->getNodePath())) {
+ return QModelIndex();
+ }
+ if (path == node->getNodePath()) {
+ return parentIndex;
+ }
+ QStringList nameList = path.right(path.length()-node->getNodePath().length()).split("/",QString::SkipEmptyParts);
+ QModelIndex parent = parentIndex;
+ bool find = false;
+ int count = nameList.count();
+ for (int i = 0; i < count; i++) {
+ find = false;
+ for (int j = 0; j < this->rowCount(parent); j++) {
+ QModelIndex index = this->index(j,0,parent);
+ FileNode *node = nodeFromIndex(index);
+ if ( ( (i == count-1) || node->isDir()) && node->text() == nameList.at(i)) {
+ parent = index;
+ find = true;
+ break;
+ }
+ }
+ if (!find) {
+ return QModelIndex();
+ }
+ }
+ return parent;
+}
+
+QList<QModelIndex> FileSystemModel::findPaths(const QString &path) const
+{
+ QList<QModelIndex> list;
+ QString cpath = QDir::fromNativeSeparators(QDir::cleanPath(path));
+ for (int i = 0; i < this->rowCount(); i++) {
+ QModelIndex find = findPathHelper(cpath,this->index(i,0));
+ if (find.isValid()) {
+ list.append(find);
+ }
+ }
+ return list;
+}
+
+QModelIndex FileSystemModel::findPath(const QString &path) const
+{
+ QList<QModelIndex> list = this->findPaths(path);
+ if (!list.isEmpty()) {
+ return list.last();
+ }
+ return QModelIndex();
+}
+
+int FileSystemModel::rowCount(const QModelIndex &parent) const
+{
+ FileNode *node = nodeFromIndex(parent);
+ return node->childCount();
+}
+
+int FileSystemModel::columnCount(const QModelIndex&) const
+{
+ return 1;
+}
+
+QModelIndex FileSystemModel::parent(const QModelIndex &child) const
+{
+ FileNode *node = nodeFromIndex(child);
+ FileNode *parent = node->getNodeParent();
+ if (parent == m_rootNode) {
+ return QModelIndex();
+ }
+ return createIndex(parent->row(),0,parent);
+}
+
+QModelIndex FileSystemModel::index(int row, int column,const QModelIndex &parent) const
+{
+ if (!hasIndex(row,column,parent))
+ return QModelIndex();
+ FileNode *node = nodeFromIndex(parent);
+ return createIndex(row,column,node->getChild(row));
+}
+
+QVariant FileSystemModel::data(const QModelIndex &index, int role) const
+{
+ FileNode *node = nodeFromIndex(index);
+ if (!node) {
+ return QVariant();
+ }
+ switch(role) {
+ case Qt::DisplayRole:
+ return node->text();
+ case Qt::ToolTipRole:
+ return QDir::toNativeSeparators(node->getNodePath());
+ case Qt::DecorationRole:
+ return m_iconProvider->icon(node->getFileInformation());
+/*
+ case Qt::FontRole: {
+ QFont font;
+ if (node->path() == m_startPath) {
+ font.setBold(true);
+ }
+ return font;
+ }
+*/
+ }
+ return QVariant();
+}
+
+bool FileSystemModel::isRootPathNode(FileNode *node) const
+{
+ return node->getNodeParent() == m_rootNode;
+}
+
+bool FileSystemModel::isRootPathNodeFillPath() const
+{
+ return false;
+}
+
+void FileSystemModel::addWatcher(const QString &path)
+{
+ QMutexLocker _(&m_mutex);
+ QString cpath = QDir::fromNativeSeparators(QDir::cleanPath(path));
+ int value = m_fileWatcherMap[cpath];
+ value++;
+ m_fileWatcherMap[cpath] = value;
+ if (value > 1) {
+ return;
+ }
+ m_fileWatcher->addPath(path);
+}
+void FileSystemModel::removeWatcher(const QString &path)
+{
+ QMutexLocker _(&m_mutex);
+ QString cpath = QDir::fromNativeSeparators(QDir::cleanPath(path));
+ int value = m_fileWatcherMap[cpath];
+ value--;
+ m_fileWatcherMap[cpath] = value;
+ if (value == 0) {
+ m_fileWatcher->removePath(cpath);
+ }
+}
diff --git a/src/plugin/filetreeview/filesystemmodel.h b/src/plugin/filetreeview/filesystemmodel.h
new file mode 100644
index 0000000..f8816f8
--- /dev/null
+++ b/src/plugin/filetreeview/filesystemmodel.h
@@ -0,0 +1,193 @@
+#ifndef FILESYSTEMMODEL_H
+#define FILESYSTEMMODEL_H
+
+#include <QAbstractItemModel>
+#include <QStringList>
+#include <QIcon>
+#include <QFileInfo>
+#include <QDir>
+#include <QMutex>
+
+class FileSystemModel;
+class QFileSystemWatcher;
+
+class QFileIconProvider;
+class QFileSystemWatcher;
+class QTreeView;
+
+class FileNode
+{
+public:
+
+ FileNode(FileSystemModel *model);
+ FileNode(FileSystemModel *model,const QString &path, FileNode *parent);
+ virtual ~FileNode();
+
+ // 返回父节点
+ FileNode* getNodeParent();
+
+ // 按照index返回
+ FileNode* getChild(int row);
+
+ //! returns the number of children this node has.
+ int childCount();
+
+ //! returns the row number of this node.
+ int row() const;
+
+ //! returns a list of all the children of this node. The list will be empty if this node has no children.
+ QList<FileNode*>* getChildrenList();
+
+ //! returns the path of this node.
+ QString getNodePath() const;
+
+ //! returns the text of this node.
+ QString text() const;
+
+ //! returns the QFileInfo for this node.
+ QFileInfo getFileInformation() const;
+
+ //! returns true if this node exists on the file system.
+ bool isExist() const;
+
+ //! returns true if this node is a directory.
+ bool isDir() const;
+
+ //! returns true if this node is a file.
+ bool isFile() const;
+
+ //! clears this node.
+ void clear();
+
+ //! recreates the node from the file system.
+ void reload();
+
+ //! returns the node for the path specified.
+ FileNode *findPath(const QString &path);
+
+protected:
+
+ //! The FileSystemModel is a QAbstractItemModel that provides a hierarchical view of the file system.
+ FileSystemModel *m_model;
+
+ //! The FileNode is a node in the tree of FileNodes.
+ FileNode *m_parent;
+
+ //! The list of FileNodes.
+ QList<FileNode*> *m_children;
+
+ //! The path of the FileNode.
+ QString m_path;
+
+ //! The text of the FileNode.
+ QString m_text;
+
+ //!< true if this node is being watched. If so, the model will watch the node and will need to be manually updated.
+ bool m_bWatcher;
+};
+
+class FileSystemModel : public QAbstractItemModel
+{
+ Q_OBJECT
+public:
+ explicit FileSystemModel(QObject *parent = 0);
+
+ ~FileSystemModel();
+
+ void clear();
+
+ void reload();
+
+ void setFilter(QDir::Filters filters);
+
+ void setDirSort(QDir::SortFlags flags);
+
+ QDir::Filters filter() const;
+
+ bool isShowHideFiles() const;
+
+ QDir::SortFlags dirSort() const;
+
+ bool removeRootPath(const QString &path);
+
+ bool addRootPath(const QString &path);
+
+ void setRootPathList(const QStringList &pathList);
+
+ void setRootPath(const QString &path);
+
+ QStringList rootPathList() const;
+
+ QList<QModelIndex> findPaths(const QString &path) const;
+
+ QModelIndex findPath(const QString &path) const;
+
+ QString filePath(const QModelIndex &index) const;
+
+ FileNode *nodeFromIndex(const QModelIndex &index) const;
+
+ void setStartIndex(const QModelIndex &index);
+
+ void setStartPath(const QString &path);
+
+ QModelIndex startIndex() const;
+
+ QString startPath() const;
+
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+
+ virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
+
+ virtual QModelIndex parent(const QModelIndex &child) const;
+
+ virtual QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const;
+
+ virtual QVariant data(const QModelIndex &index, int role) const;
+
+ bool isRootPathNode(FileNode *node) const;
+
+ bool isRootPathNodeFillPath() const;
+
+ void addWatcher(const QString &path);
+
+ void removeWatcher(const QString &path);
+signals:
+ void direcotryChanged(QString);
+public slots:
+ void reloadDirectory(const QString &path);
+protected:
+ //! Finds the node at the given \a path in the model.
+ QModelIndex findPathHelper(const QString &path, const QModelIndex &parentIndex) const;
+
+ //! The list of paths that are currently being watched.
+ QStringList m_pathList;
+
+ //! The root node of the model.
+ FileNode *m_rootNode;
+
+ //! The path to the directory to watch.
+ QString m_startPath;
+
+ //! The file icon provider.
+ QFileIconProvider *m_iconProvider;
+
+ //! The file system watcher.
+ QFileSystemWatcher *m_fileWatcher;
+
+ //! A map of watched files and their watcher indices.
+ QMap<QString,int> m_fileWatcherMap;
+
+ //! The tree view.
+ QTreeView *m_treeView;
+
+ //! The filters to apply to the directory.
+ QDir::Filters m_dirFilter;
+
+ //! The sort order to apply to the directory.
+ QDir::SortFlags m_sorts;
+
+ //! The mutex to protect the model.
+ QMutex m_mutex;
+};
+
+#endif // FILESYSTEMMODEL_H
diff --git a/src/plugin/filetreeview/filetreeview.cpp b/src/plugin/filetreeview/filetreeview.cpp
new file mode 100644
index 0000000..a1afb12
--- /dev/null
+++ b/src/plugin/filetreeview/filetreeview.cpp
@@ -0,0 +1,195 @@
+/**
+ ** This file is part of the NoteBook project.
+ ** Copyright 2022 ji wang <matheuter@gmail.com>.
+ **
+ ** This program is free software: you can redistribute it and/or modify
+ ** it under the terms of the GNU Lesser General Public License as
+ ** published by the Free Software Foundation, either version 3 of the
+ ** License, or (at your option) any later version.
+ **
+ ** This program is distributed in the hope that it will be useful,
+ ** but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ** GNU Lesser General Public License for more details.
+ **
+ ** You should have received a copy of the GNU Lesser General Public License
+ ** along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "filetreeview.h"
+
+#include <QTreeView>
+#include <QJsonObject>
+#include <QFileDialog>
+#include <QMenu>
+#include <QApplication>
+#include <QMessageBox>
+#include <QProcess>
+
+#include"actorprocessor.h"
+#include "filesystemmodel.h"
+
+class FileTreeViewPrivate
+{
+public:
+ FileTreeViewPrivate(FileTreeView *parent):
+ q_ptr(parent)
+ {}
+
+public:
+ ActorProcessor* m_processor;
+ QMenu* m_fileMenu;
+ QMenu* m_dirMenu;
+ QWidget* m_notepadWidget;
+
+private:
+ FileTreeView * const q_ptr;
+ Q_DECLARE_PUBLIC(FileTreeView);
+};
+
+FileTreeView::FileTreeView(QWidget *parent):
+ d_ptr(new FileTreeViewPrivate(this)),
+ QTreeView(parent)
+{
+ bindAction();
+ setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(this, SIGNAL(doubleClicked(QModelIndex)),this, SLOT(slotDoubleCliecked(QModelIndex)));
+ connect(this,SIGNAL(customContextMenuRequested(const QPoint &)),this, SLOT(slotCustomContextMenu(const QPoint &)));
+}
+
+FileTreeView::~FileTreeView()
+{}
+
+void FileTreeView::onNewWorkspaceItem(bool)
+{
+ QString srcDirPath = QFileDialog::getExistingDirectory(
+ this, "choose src Directory",
+ "/");
+ if (srcDirPath.isEmpty()){
+ return;
+ }
+ FileSystemModel* model = static_cast<FileSystemModel*> (this->model());
+ model->addRootPath(srcDirPath);
+ model->reload();
+ this->update();
+}
+
+void FileTreeView::slotCustomContextMenu(const QPoint & pos)
+{
+ Q_D(FileTreeView);
+ auto model = static_cast<FileSystemModel*>(this->model());
+ auto index= this->indexAt(pos);
+ if (model->nodeFromIndex(index)->isDir()){
+ d->m_dirMenu->exec(QCursor::pos());
+ }
+ else {
+ d->m_fileMenu->exec(QCursor::pos());
+ }
+}
+
+void FileTreeView::slotTerminal(bool)
+{
+}
+
+void FileTreeView::slotNewFile(bool)
+{
+
+}
+
+void FileTreeView::slotRemoveFile(bool)
+{
+}
+
+void FileTreeView::slotAddDir(bool)
+{
+
+}
+
+void FileTreeView::slotRemoveDir(bool)
+{
+ Q_D(FileTreeView);
+ auto model = static_cast<FileSystemModel*>(this->model());
+ auto index= this->currentIndex();
+ if (model->nodeFromIndex(index)->isDir()){
+ (d->m_dirMenu)->exec(QCursor::pos());
+ }
+ else {
+ (d->m_fileMenu)->exec(QCursor::pos());
+ }
+}
+
+void FileTreeView::slotupdateDir(bool)
+{
+ auto model = static_cast<FileSystemModel*>(this->model());
+ auto index= this->currentIndex();
+ if (model->nodeFromIndex(index)->isDir()){
+ model->reloadDirectory(model->nodeFromIndex(index)->getNodePath());
+ }
+}
+
+void FileTreeView::initMenuFile(QMenu *menu)
+{
+ Q_D(FileTreeView);
+ d->m_fileMenu = menu;
+}
+
+void FileTreeView::initDirMenu(QMenu *menu)
+{
+ Q_D(FileTreeView);
+ d->m_dirMenu = menu;
+}
+
+void FileTreeView::bindAction()
+{
+ Q_D(FileTreeView);
+ QMenu* fileTreeMenu = new QMenu("menu",this);
+ QMenu* dirTreeMenu = new QMenu("file",this);
+
+ QAction *fileRename = new QAction(tr("Rename"),fileTreeMenu);
+ QAction *fileDelete = new QAction(tr("Delete"),fileTreeMenu);
+ QAction *fileOpenInExporter = new QAction(tr("OpenInExporter"),fileTreeMenu);
+
+ QAction *removeDir = new QAction(tr("Remove Dir"),dirTreeMenu);
+ QAction *update = new QAction(tr("Update"),dirTreeMenu);
+ QAction *fold = new QAction(tr("Fold Dir"),dirTreeMenu);
+ QAction *unfold = new QAction(tr("Unfold Dir"),dirTreeMenu);
+ QAction *terminal = new QAction(tr("terminal"));
+
+ d->m_dirMenu = dirTreeMenu;
+ d->m_dirMenu->addActions({removeDir,update,fold,unfold,terminal});
+ d->m_fileMenu = fileTreeMenu;
+ d->m_fileMenu->addActions({fileRename,fileDelete,fileOpenInExporter,terminal});
+}
+
+void FileTreeView::setActorProcessor(ActorProcessor *processor)
+{
+ Q_D(FileTreeView);
+ d->m_processor = processor;
+}
+
+void FileTreeView::setMainWindow(QWidget *notepadWidget)
+{
+ Q_D(FileTreeView);
+ d->m_notepadWidget = notepadWidget;
+}
+
+
+
+void FileTreeView::slotCliecked(const QModelIndex &index)
+{
+}
+
+void FileTreeView::slotDoubleCliecked(const QModelIndex &index)
+{
+ Q_D(FileTreeView);
+ auto model = static_cast<FileSystemModel*>(this->model());
+ if (model->nodeFromIndex(index)->isDir()){
+ }
+ else {
+ d->m_processor->invoke("openFile",model->nodeFromIndex(index)->getNodePath(),-1);
+ }
+}
+
+
+
+
diff --git a/src/plugin/filetreeview/filetreeview.h b/src/plugin/filetreeview/filetreeview.h
new file mode 100644
index 0000000..0a0e5e1
--- /dev/null
+++ b/src/plugin/filetreeview/filetreeview.h
@@ -0,0 +1,73 @@
+/**
+ ** This file is part of the NoteBook project.
+ ** Copyright 2022 ji wang <matheuter@gmail.com>.
+ **
+ ** This program is free software: you can redistribute it and/or modify
+ ** it under the terms of the GNU Lesser General Public License as
+ ** published by the Free Software Foundation, either version 3 of the
+ ** License, or (at your option) any later version.
+ **
+ ** This program is distributed in the hope that it will be useful,
+ ** but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ** GNU Lesser General Public License for more details.
+ **
+ ** You should have received a copy of the GNU Lesser General Public License
+ ** along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#ifndef WORKSPACE_H
+#define WORKSPACE_H
+
+#include <QObject>
+#include <QTreeView>
+
+class QModelIndex;
+class QWidget;
+class QMenu;
+class ActorProcessor;
+
+class FileTreeViewPrivate;
+
+class FileTreeView : public QTreeView
+{
+ Q_OBJECT
+public:
+ FileTreeView(QWidget* parent = nullptr);
+
+ ~FileTreeView();
+
+ void initMenuFile(QMenu*);
+ void initDirMenu(QMenu*);
+
+ void bindAction();
+ void setActorProcessor(ActorProcessor*processor);
+
+ void setMainWindow(QWidget* notepadWidget);
+
+public slots:
+ void onNewWorkspaceItem(bool);
+ void slotCliecked(const QModelIndex &);
+ void slotDoubleCliecked(const QModelIndex &);
+ void slotCustomContextMenu(const QPoint &);
+ void slotTerminal(bool);
+ void slotNewFile(bool);
+ void slotRemoveFile(bool);
+ void slotAddDir(bool);
+ void slotRemoveDir(bool);
+ void slotupdateDir(bool);
+signals:
+ void signalNewFile();
+ void signalRemoveFile();
+ void signalAddDir();
+
+private:
+ FileTreeViewPrivate * const d_ptr;
+ Q_DECLARE_PRIVATE(FileTreeView);
+
+ FileTreeView(const FileTreeView &) = delete;
+ FileTreeView &operator=(const FileTreeView &) = delete;
+};
+
+#endif // WORKSPACE_H
diff --git a/src/plugin/filetreeview/filetreeviewexport.cpp b/src/plugin/filetreeview/filetreeviewexport.cpp
new file mode 100644
index 0000000..4c43c84
--- /dev/null
+++ b/src/plugin/filetreeview/filetreeviewexport.cpp
@@ -0,0 +1,77 @@
+#include <qobject.h>
+#include <qstring.h>
+#include <pluginGl.h>
+#include <functional>
+#include <qsciscintilla.h>
+#include <QAction>
+#include <QDebug>
+
+#include "filetreeviewplugin.h"
+#include "actorprocessor.h"
+#define NDD_EXPORTDLL
+
+#if defined(Q_OS_WIN)
+#if defined(NDD_EXPORTDLL)
+#define NDD_EXPORT __declspec(dllexport)
+#else
+#define NDD_EXPORT __declspec(dllimport)
+#endif
+#else
+#define NDD_EXPORT __attribute__((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#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_PROC_DATA* procData);
+NDD_EXPORT int NDD_PROC_MAIN_V2(QWidget* pNotepad, const QString& strFileName,ActorProcessor* processor, 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)
+ {
+ return false;
+ }
+ pProcData->m_strPlugName = QObject::tr("File Tree");
+ pProcData->m_strComment = QObject::tr("file tree plugin");
+
+ pProcData->m_version = QString("1.0");
+ pProcData->m_auther = QString("matheuter@gmail.com");
+
+ pProcData->m_menuType = 1;
+ return true;
+}
+
+int NDD_PROC_MAIN_V2(QWidget* pNotepad, const QString& strFileName,ActorProcessor* processor,NDD_PROC_DATA* pProcData)
+{
+ qDebug() << "test plugin";
+ //务必拷贝一份pProcData在外面会释放。
+ if (pProcData != nullptr)
+ {
+ s_procData = *pProcData;
+ }
+ else
+ {
+ return -1;
+ }
+
+ s_pMainNotepad = pNotepad;
+ FileTreeViewPlugin* plugin = new FileTreeViewPlugin();
+ plugin->setPluginModulePath(strFileName);
+ plugin->setActorProcessor(processor);
+ plugin->setTopMenu(pProcData->m_rootMenu);
+ plugin->setMenuActions(s_procData.m_rootMenu);
+ plugin->setNotepad(s_pMainNotepad);
+
+ return 0;
+}
diff --git a/src/plugin/filetreeview/filetreeviewplugin.cpp b/src/plugin/filetreeview/filetreeviewplugin.cpp
new file mode 100644
index 0000000..97eda35
--- /dev/null
+++ b/src/plugin/filetreeview/filetreeviewplugin.cpp
@@ -0,0 +1,121 @@
+#include "filetreeviewplugin.h"
+
+#include <QDockWidget>
+#include <QObject>
+#include <QAction>
+#include <QFileInfo>
+#include <QMainWindow>
+#include <QDir>
+#include <QTreeView>
+#include <QDebug>
+
+#include <qsciscintilla.h>
+
+#include "filetreeview.h"
+#include "filesystemmodel.h"
+#include "qheaderview.h"
+#include "actorprocessor.h"
+
+class FileTreeViewPluginPrivate
+{
+public:
+ FileTreeViewPluginPrivate(FileTreeViewPlugin *parent):
+ q_ptr(parent)
+ {}
+
+public:
+ ActorProcessor* m_processor;
+ QWidget* m_notepadWidget;
+ QMenu* m_topMenu;
+ QString m_pluginModulePath;
+ QDockWidget* m_dockWidget;
+ FileTreeView*m_treeview;
+ FileSystemModel * m_model;
+
+ std::function<QsciScintilla* ()> getCurrentEditFunc;
+
+private:
+ FileTreeViewPlugin * const q_ptr;
+ Q_DECLARE_PUBLIC(FileTreeViewPlugin);
+};
+
+FileTreeViewPlugin::FileTreeViewPlugin(QObject *parent):
+ d_ptr(new FileTreeViewPluginPrivate(this))
+{}
+
+FileTreeViewPlugin::~FileTreeViewPlugin()
+{
+}
+
+void FileTreeViewPlugin::setActorProcessor(ActorProcessor *processor)
+{
+ Q_D(FileTreeViewPlugin);
+ d->m_processor = processor;
+}
+
+void FileTreeViewPlugin::setPluginModulePath(const QString &newPluginModulePath)
+{
+ Q_D(FileTreeViewPlugin);
+ d->m_pluginModulePath = newPluginModulePath;
+}
+
+void FileTreeViewPlugin::bindAction()
+{
+}
+
+void FileTreeViewPlugin::setTopMenu(QMenu *newTopMenu)
+{
+ Q_D(FileTreeViewPlugin);
+ d->m_topMenu = newTopMenu;
+}
+
+void FileTreeViewPlugin::setNotepad(QWidget *newNotepad)
+{
+ Q_D(FileTreeViewPlugin);
+ d->m_notepadWidget = newNotepad;
+}
+
+void FileTreeViewPlugin::setMenuActions(QMenu *menu)
+{
+ Q_D(FileTreeViewPlugin);
+ QAction* pAction = new QAction("File Tree", menu);
+ menu->addAction(pAction);
+ connect(pAction, SIGNAL(triggered()),this,SLOT(slotMenuItemClick()));
+}
+
+void FileTreeViewPlugin::setCurrentEditFunc(std::function<QsciScintilla *()> func)
+{
+ Q_D(FileTreeViewPlugin);
+ d->getCurrentEditFunc = func;
+}
+
+void FileTreeViewPlugin::slotMenuItemClick()
+{
+ Q_D(FileTreeViewPlugin);
+
+ auto action = qobject_cast<QAction*>(sender());
+ auto mainWindow = dynamic_cast<QMainWindow*>(d->m_notepadWidget);
+ if (!mainWindow)
+ return;
+
+ if (!d->m_dockWidget) {
+ d->m_dockWidget = new QDockWidget(mainWindow);
+ mainWindow->addDockWidget(Qt::LeftDockWidgetArea, d->m_dockWidget);
+
+ d->m_treeview = new FileTreeView();
+ d->m_treeview->setActorProcessor(d->m_processor);
+ d->m_treeview->setMainWindow(d->m_notepadWidget);
+ d->m_treeview->header()->setVisible(false);
+ d->m_model = new FileSystemModel(d->m_treeview);
+ d->m_model->setRootPath("C:");
+
+ QAction* pAction = new QAction("Open Fold", d->m_topMenu);
+ d->m_topMenu->addAction(pAction);
+ connect(pAction, SIGNAL(triggered(bool)),d->m_treeview,SLOT(onNewWorkspaceItem(bool)));
+ d->m_treeview->setModel(d->m_model);
+ d->m_dockWidget->setWidget(d->m_treeview);
+ }
+
+ if (!d->m_dockWidget->isVisible())
+ d->m_dockWidget->show();
+}
diff --git a/src/plugin/filetreeview/filetreeviewplugin.h b/src/plugin/filetreeview/filetreeviewplugin.h
new file mode 100644
index 0000000..fd35186
--- /dev/null
+++ b/src/plugin/filetreeview/filetreeviewplugin.h
@@ -0,0 +1,40 @@
+#ifndef FILETREEWIDGET_H
+#define FILETREEWIDGET_H
+
+#include <QWidget>
+#include <QMenu>
+#include <QString>
+
+class QsciScintilla;
+class FileTreeViewPluginPrivate;
+class ActorProcessor;
+
+class FileTreeViewPlugin :public QObject
+{
+ Q_OBJECT
+public:
+ FileTreeViewPlugin(QObject *parent = nullptr);
+ ~FileTreeViewPlugin();
+
+public:
+ void setActorProcessor(ActorProcessor*processor);
+ void setMenuActions(QMenu *menu);
+ void setCurrentEditFunc(std::function<QsciScintilla* ()> func);
+ void setNotepad(QWidget *newNotepad);
+ void setTopMenu(QMenu *newTopMenu);
+ void setPluginModulePath(const QString &newPluginModulePath);
+private:
+ void bindAction();
+
+public slots:
+ void slotMenuItemClick();
+
+private:
+ FileTreeViewPluginPrivate * const d_ptr;
+ Q_DECLARE_PRIVATE(FileTreeViewPlugin);
+
+ FileTreeViewPlugin(const FileTreeViewPlugin &) = delete;
+ FileTreeViewPlugin &operator=(const FileTreeViewPlugin &) = delete;
+};
+
+#endif // FILETREEWIDGET_H
--
2.33.1
From 527db1baa78809845ce4589841d4e327ae6b5c1b Mon Sep 17 00:00:00 2001
From: matheuter <210880040@qq.com>
Date: Thu, 20 Apr 2023 17:01:50 +0800
Subject: [PATCH 2/4] add actor to plugin_v2
---
src/plugin/filetreeview/actor.h | 35 +++++++++++++++++----------------
1 file changed, 18 insertions(+), 17 deletions(-)
diff --git a/src/plugin/filetreeview/actor.h b/src/plugin/filetreeview/actor.h
index d3901a2..70cd9ff 100644
--- a/src/plugin/filetreeview/actor.h
+++ b/src/plugin/filetreeview/actor.h
@@ -1,3 +1,21 @@
+/**
+ ** This file is part of ndd file tree view plugin
+ ** Copyright 2022-2023 ji wang <matheuter@gmail.com>.
+ **
+ ** This program is free software: you can redistribute it and/or modify
+ ** it under the terms of the GNU Lesser General Public License as
+ ** published by the Free Software Foundation, either version 3 of the
+ ** License, or (at your option) any later version.
+ **
+ ** This program is distributed in the hope that it will be useful,
+ ** but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ** GNU Lesser General Public License for more details.
+ **
+ ** You should have received a copy of the GNU Lesser General Public License
+ ** along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
#pragma once
#include <cstdint>
#include <string>
@@ -57,11 +75,6 @@ public:
return return_value;
}
- Ptr getSharedPtr()
- {
- return shared_from_this();
- }
-
public:
/**
* @brief This struct encapsulates a function,
@@ -71,9 +84,6 @@ public:
template<typename Function>
struct invoker
{
- /**
- * @brief
- */
static inline void apply(const Function& func, void* bl, void* result)
{
using tuple_type = typename function_traits<Function>::tuple_type;
@@ -81,9 +91,6 @@ public:
call(func, *tp, result);
}
- /**
- * @brief
- */
template<typename F, typename ... Args>
static typename std::enable_if<std::is_void<typename std::result_of<F(Args...)>::type>::value>::type
call(const F& f, const std::tuple<Args...>& tp, void*)
@@ -91,9 +98,6 @@ public:
call_helper(f, std::make_index_sequence<sizeof... (Args)>{}, tp);
}
- /**
- * @brief
- */
template<typename F, typename ... Args>
static typename std::enable_if<!std::is_void<typename std::result_of<F(Args...)>::type>::value>::type
call(const F& f, const std::tuple<Args...>& tp, void* result)
@@ -102,9 +106,6 @@ public:
*(decltype(r)*)result = r;
}
- /**
- * @brief
- */
template<typename F, size_t... I, typename ... Args>
static auto call_helper(const F& f, const std::index_sequence<I...>& h, const std::tuple<Args...>& tup)
{
--
2.33.1
From 4ab86338f19fcd2e4d4b8565ba34af189174eb82 Mon Sep 17 00:00:00 2001
From: matheuter <210880040@qq.com>
Date: Thu, 20 Apr 2023 17:19:00 +0800
Subject: [PATCH 3/4] update command
---
src/actor.h | 24 +----------
src/actorprocessor.cpp | 19 ++-------
src/actorprocessor.h | 23 ++---------
src/plugin/filetreeview/abstractfile.cpp | 6 ---
src/plugin/filetreeview/abstractfile.h | 11 -----
src/plugin/filetreeview/actor.h | 5 ++-
src/plugin/filetreeview/actorprocessor.cpp | 19 +++++++++
src/plugin/filetreeview/actorprocessor.h | 41 ++++++++++---------
src/plugin/filetreeview/filetreeview.cpp | 4 +-
src/plugin/filetreeview/filetreeview.h | 5 +--
.../filetreeview/filetreeviewplugin.cpp | 18 ++++++++
src/plugin/filetreeview/filetreeviewplugin.h | 21 +++++++++-
12 files changed, 93 insertions(+), 103 deletions(-)
delete mode 100644 src/plugin/filetreeview/abstractfile.cpp
delete mode 100644 src/plugin/filetreeview/abstractfile.h
diff --git a/src/actor.h b/src/actor.h
index 86378d0..0fb51c3 100644
--- a/src/actor.h
+++ b/src/actor.h
@@ -1,4 +1,4 @@
-#pragma once
+
#include <cstdint>
#include <string>
#include <memory>
@@ -7,10 +7,6 @@
#include "functiontraits.h"
-/**
- * @brief Actor class, which encapsulates the event model
- * @note enable_shared_from_this allows us to get safe Pointers internally
- */
class Actor : public std::enable_shared_from_this<Actor>
{
public:
@@ -21,27 +17,18 @@ public:
Actor(){}
~Actor(){}
- /**
- * @brief Register the callback function and construct the anonymous function with std::bind
- */
template<typename Function>
void operator+=(Function&& function_any) noexcept
{
m_invokeFunctionWapper = { std::bind(&invoker<Function>::apply, function_any, std::placeholders::_1, std::placeholders::_2) };
}
- /**
- * @brief Register the callback function and construct the anonymous function with std::bind
- */
template<typename Function>
void registerFunction(Function&& function_any) noexcept
{
m_invokeFunctionWapper = { std::bind(&invoker<Function>::apply, function_any, std::placeholders::_1, std::placeholders::_2) };
}
- /**
- * @brief Register the callback function and construct the anonymous function with std::bind
- */
template<typename ... Args>
void invoke(Args&& ... args) const noexcept
{
@@ -49,9 +36,6 @@ public:
m_invokeFunctionWapper(&args_tuple, nullptr);
}
- /**
- * @brief Register the callback function and construct the anonymous function with std::bind
- */
template<typename R, typename ... Args>
R invoke(Args&& ...args) const
{
@@ -66,12 +50,8 @@ public:
return return_value;
}
- Ptr getSharedPtr()
- {
- return shared_from_this();
- }
-
public:
+
/**
* @brief This struct encapsulates a function,
* essentially storing the return value and parameters in two variables
diff --git a/src/actorprocessor.cpp b/src/actorprocessor.cpp
index 099d1f6..6dfd1f4 100644
--- a/src/actorprocessor.cpp
+++ b/src/actorprocessor.cpp
@@ -1,11 +1,9 @@
-#include "actorprocessor.h"
+#include "actorprocessor.h"
+
ActorProcessor::ActorProcessor():
m_actorMap(new std::unordered_map<std::string, Actor*>)
{}
-/**
- * @brief
- */
ActorProcessor::~ActorProcessor()
{
for (auto& item : (*m_actorMap))
@@ -17,17 +15,11 @@ ActorProcessor::~ActorProcessor()
delete m_actorMap;
}
-/**
- * @brief
- */
void ActorProcessor::registerActor(const std::string &route, Actor *actor)
{
m_actorMap->insert(std::make_pair(route,actor));
}
-/**
- * @brief
- */
void ActorProcessor::removeActor(const std::string &route)
{
auto iter = (*m_actorMap).find(route);
@@ -38,9 +30,6 @@ void ActorProcessor::removeActor(const std::string &route)
}
}
-/**
- * @brief
- */
Actor *ActorProcessor::findActor(const std::string &route)
{
auto iter = (*m_actorMap).find(route);
@@ -51,9 +40,7 @@ Actor *ActorProcessor::findActor(const std::string &route)
return nullptr;
}
-/**
- * @brief
- */
+
bool ActorProcessor::resetActor(const std::string &route, Actor *actor)
{
auto iter = (*m_actorMap).find(route);
diff --git a/src/actorprocessor.h b/src/actorprocessor.h
index 9026909..def5b06 100644
--- a/src/actorprocessor.h
+++ b/src/actorprocessor.h
@@ -1,5 +1,5 @@
-#ifndef EVENTPROCESSOR_H
-#define EVENTPROCESSOR_H
+#ifndef _PROCESSOR_H
+#define _PROCESSOR_H
#include <string>
#include <functional>
@@ -25,9 +25,6 @@ public:
(*m_actorMap)[route]->invoke(std::forward<Args>(args)...);
}
- /**
- * @brief Register the callback function and construct the anonymous function with std::bind
- */
template<typename R, typename ... Args>
R invoke(const std::string& route,Args&& ...args) const
{
@@ -36,30 +33,16 @@ public:
return nullptr;
}
- /**
- * @brief 注册一个actor其中route是唯一的
- */
void registerActor(const std::string& route, Actor*actor);
- /**
- * @brief 删除一个actor
- */
void removeActor(const std::string& route);
-
- /**
- * @brief 查找一个actor 返回其指针
- */
Actor* findActor(const std::string& route);
-
- /**
- * @brief 重置一个actor注意原有的actor会被删除
- */
bool resetActor(const std::string& route,Actor*actor);
private:
std::unordered_map<std::string, Actor*>* m_actorMap;
+
private:
- // not allow copy constroct
ActorProcessor(ActorProcessor&&)=delete;
ActorProcessor& operator=(const ActorProcessor&)=delete;
};
diff --git a/src/plugin/filetreeview/abstractfile.cpp b/src/plugin/filetreeview/abstractfile.cpp
deleted file mode 100644
index 9b8673f..0000000
--- a/src/plugin/filetreeview/abstractfile.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "abstractfile.h"
-
-AbstractFile::AbstractFile()
-{
-
-}
diff --git a/src/plugin/filetreeview/abstractfile.h b/src/plugin/filetreeview/abstractfile.h
deleted file mode 100644
index 94ae7dc..0000000
--- a/src/plugin/filetreeview/abstractfile.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef ABSTRACTFILE_H
-#define ABSTRACTFILE_H
-
-
-class AbstractFile
-{
-public:
- AbstractFile();
-};
-
-#endif // ABSTRACTFILE_H
diff --git a/src/plugin/filetreeview/actor.h b/src/plugin/filetreeview/actor.h
index 70cd9ff..30b6f00 100644
--- a/src/plugin/filetreeview/actor.h
+++ b/src/plugin/filetreeview/actor.h
@@ -1,6 +1,6 @@
/**
- ** This file is part of ndd file tree view plugin
- ** Copyright 2022-2023 ji wang <matheuter@gmail.com>.
+ ** This file is part of ndd plugin file tree view
+ ** Copyright ji wang <matheuter@gmail.com>.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as
@@ -16,6 +16,7 @@
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
+
#pragma once
#include <cstdint>
#include <string>
diff --git a/src/plugin/filetreeview/actorprocessor.cpp b/src/plugin/filetreeview/actorprocessor.cpp
index 099d1f6..96af367 100644
--- a/src/plugin/filetreeview/actorprocessor.cpp
+++ b/src/plugin/filetreeview/actorprocessor.cpp
@@ -1,3 +1,22 @@
+/**
+ ** This file is part of ndd plugin file tree view
+ ** Copyright ji wang <matheuter@gmail.com>.
+ **
+ ** This program is free software: you can redistribute it and/or modify
+ ** it under the terms of the GNU Lesser General Public License as
+ ** published by the Free Software Foundation, either version 3 of the
+ ** License, or (at your option) any later version.
+ **
+ ** This program is distributed in the hope that it will be useful,
+ ** but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ** GNU Lesser General Public License for more details.
+ **
+ ** You should have received a copy of the GNU Lesser General Public License
+ ** along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
#include "actorprocessor.h"
ActorProcessor::ActorProcessor():
m_actorMap(new std::unordered_map<std::string, Actor*>)
diff --git a/src/plugin/filetreeview/actorprocessor.h b/src/plugin/filetreeview/actorprocessor.h
index d057e6d..76c6035 100644
--- a/src/plugin/filetreeview/actorprocessor.h
+++ b/src/plugin/filetreeview/actorprocessor.h
@@ -1,5 +1,24 @@
-#ifndef EVENTPROCESSOR_H
-#define EVENTPROCESSOR_H
+/**
+ ** This file is part of ndd plugin file tree view
+ ** Copyright ji wang <matheuter@gmail.com>.
+ **
+ ** This program is free software: you can redistribute it and/or modify
+ ** it under the terms of the GNU Lesser General Public License as
+ ** published by the Free Software Foundation, either version 3 of the
+ ** License, or (at your option) any later version.
+ **
+ ** This program is distributed in the hope that it will be useful,
+ ** but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ** GNU Lesser General Public License for more details.
+ **
+ ** You should have received a copy of the GNU Lesser General Public License
+ ** along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#ifndef _PROCESSOR_H
+#define _PROCESSOR_H
#include <string>
#include <functional>
@@ -15,9 +34,6 @@ public:
~ActorProcessor();
public:
- /**
- * @brief Register the callback function and construct the anonymous function with std::bind
- */
template<typename ... Args>
void invoke(const std::string& route,Args&& ... args) const noexcept
{
@@ -25,9 +41,6 @@ public:
(*m_actorMap)[route]->invoke(std::forward<Args>(args)...);
}
- /**
- * @brief Register the callback function and construct the anonymous function with std::bind
- */
template<typename R, typename ... Args>
R invoke(const std::string& route,Args&& ...args) const
{
@@ -36,24 +49,12 @@ public:
return nullptr;
}
- /**
- * @brief 注册一个actor其中route是唯一的
- */
void registerActor(const std::string& route, Actor*actor);
- /**
- * @brief 删除一个actor
- */
void removeActor(const std::string& route);
- /**
- * @brief 查找一个actor 返回其指针
- */
Actor* findActor(const std::string& route);
- /**
- * @brief 重置一个actor注意原有的actor会被删除
- */
bool resetActor(const std::string& route,Actor*actor);
private:
diff --git a/src/plugin/filetreeview/filetreeview.cpp b/src/plugin/filetreeview/filetreeview.cpp
index a1afb12..1259296 100644
--- a/src/plugin/filetreeview/filetreeview.cpp
+++ b/src/plugin/filetreeview/filetreeview.cpp
@@ -1,6 +1,6 @@
/**
- ** This file is part of the NoteBook project.
- ** Copyright 2022 ji wang <matheuter@gmail.com>.
+ ** This file is part of ndd plugin file tree view
+ ** Copyright ji wang <matheuter@gmail.com>.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as
diff --git a/src/plugin/filetreeview/filetreeview.h b/src/plugin/filetreeview/filetreeview.h
index 0a0e5e1..9a1eda2 100644
--- a/src/plugin/filetreeview/filetreeview.h
+++ b/src/plugin/filetreeview/filetreeview.h
@@ -1,6 +1,6 @@
/**
- ** This file is part of the NoteBook project.
- ** Copyright 2022 ji wang <matheuter@gmail.com>.
+ ** This file is part of ndd plugin file tree view
+ ** Copyright ji wang <matheuter@gmail.com>.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as
@@ -16,7 +16,6 @@
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
-
#ifndef WORKSPACE_H
#define WORKSPACE_H
diff --git a/src/plugin/filetreeview/filetreeviewplugin.cpp b/src/plugin/filetreeview/filetreeviewplugin.cpp
index 97eda35..83efcec 100644
--- a/src/plugin/filetreeview/filetreeviewplugin.cpp
+++ b/src/plugin/filetreeview/filetreeviewplugin.cpp
@@ -8,6 +8,24 @@
#include <QDir>
#include <QTreeView>
#include <QDebug>
+/**
+ ** This file is part of ndd plugin file tree view
+ ** Copyright ji wang <matheuter@gmail.com>.
+ **
+ ** This program is free software: you can redistribute it and/or modify
+ ** it under the terms of the GNU Lesser General Public License as
+ ** published by the Free Software Foundation, either version 3 of the
+ ** License, or (at your option) any later version.
+ **
+ ** This program is distributed in the hope that it will be useful,
+ ** but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ** GNU Lesser General Public License for more details.
+ **
+ ** You should have received a copy of the GNU Lesser General Public License
+ ** along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
#include <qsciscintilla.h>
diff --git a/src/plugin/filetreeview/filetreeviewplugin.h b/src/plugin/filetreeview/filetreeviewplugin.h
index fd35186..336bbc6 100644
--- a/src/plugin/filetreeview/filetreeviewplugin.h
+++ b/src/plugin/filetreeview/filetreeviewplugin.h
@@ -1,4 +1,23 @@
-#ifndef FILETREEWIDGET_H
+/**
+ ** This file is part of ndd plugin file tree view
+ ** Copyright ji wang <matheuter@gmail.com>.
+ **
+ ** This program is free software: you can redistribute it and/or modify
+ ** it under the terms of the GNU Lesser General Public License as
+ ** published by the Free Software Foundation, either version 3 of the
+ ** License, or (at your option) any later version.
+ **
+ ** This program is distributed in the hope that it will be useful,
+ ** but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ** GNU Lesser General Public License for more details.
+ **
+ ** You should have received a copy of the GNU Lesser General Public License
+ ** along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#ifndef FILETREEWIDGET_H
#define FILETREEWIDGET_H
#include <QWidget>
--
2.33.1
From 2ad291e9753690727cf92ae18c0bcaa87d5ac169 Mon Sep 17 00:00:00 2001
From: matheuter <210880040@qq.com>
Date: Thu, 20 Apr 2023 17:31:42 +0800
Subject: [PATCH 4/4] fix actor error
---
src/actor.h | 6 +++++-
src/plugin/filetreeview/actor.h | 5 ++++-
src/plugin/filetreeview/actorprocessor.cpp | 1 -
3 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/src/actor.h b/src/actor.h
index 0fb51c3..17f1f16 100644
--- a/src/actor.h
+++ b/src/actor.h
@@ -1,4 +1,6 @@
-
+#ifndef _ACTOR_H_
+#define _ACTOR_H_
+
#include <cstdint>
#include <string>
#include <memory>
@@ -107,3 +109,5 @@ private:
*/
FunctionWapper m_invokeFunctionWapper;
};
+
+#endif
diff --git a/src/plugin/filetreeview/actor.h b/src/plugin/filetreeview/actor.h
index 30b6f00..4de5752 100644
--- a/src/plugin/filetreeview/actor.h
+++ b/src/plugin/filetreeview/actor.h
@@ -16,8 +16,9 @@
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
+#ifndef _ACTOR_H_
+#define _ACTOR_H_
-#pragma once
#include <cstdint>
#include <string>
#include <memory>
@@ -120,3 +121,5 @@ private:
*/
FunctionWapper m_invokeFunctionWapper;
};
+
+#endif
diff --git a/src/plugin/filetreeview/actorprocessor.cpp b/src/plugin/filetreeview/actorprocessor.cpp
index 96af367..972af41 100644
--- a/src/plugin/filetreeview/actorprocessor.cpp
+++ b/src/plugin/filetreeview/actorprocessor.cpp
@@ -16,7 +16,6 @@
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
-
#include "actorprocessor.h"
ActorProcessor::ActorProcessor():
m_actorMap(new std::unordered_map<std::string, Actor*>)
--
2.33.1