#ifndef DBTREEVIEWMANAGER_H #define DBTREEVIEWMANAGER_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class OriginalWnd; ///< 前向声明 /** * @class DbTreeViewManager * @brief 管理树状视图、导航栏、以及与数据库交互的相关逻辑。 * * 该类负责从数据库加载目录树 ,并根据用户权限和配置 ID 显示相应的字段与控件。 * 同时还支持切换 Home 界面或其他配置界面、隐藏/显示按钮与分隔线等功能。 */ class DbTreeViewManager : public QWidget { Q_OBJECT public: /** * @brief 构造函数 * @param originalWnd 指向 OriginalWnd 对象的指针 * @param widget2 另一个父级或容器部件,用于添加子控件 * @param parent 父窗口指针,可为空 */ explicit DbTreeViewManager(OriginalWnd* originalWnd, QWidget* widget2, QWidget* parent = nullptr); /** * @brief 析构函数,清理资源 */ ~DbTreeViewManager(); /** * @brief 初始化目录树,从数据库加载数据 * @param configId 配置ID,对应数据库中的 Configurations 表 * @param userPrivilege 当前用户的权限等级 */ void initializeTree(int configId, const int &userPrivilege); /** * @brief 清理所有分隔线(内部调用,用于清除旧有的一级目录分隔线等) */ void clearAllSeparators(); /** * @brief 收集所有第三层目录的 QStandardItem * @return 包含第三层目录项的列表 */ QList collectAllThirdLevelItems(); /** * @brief 保存所有当前已展开的路径 * 对应 expandedPaths 中的路径保存到持久化存储(如 QSettings) */ void saveExpandedPaths(); /** * @brief 加载已展开的路径 * 从持久化存储(如 QSettings)中读取展开路径并恢复 */ void loadExpandedPaths(); /** * @brief 将日志写入文件中 * */ void writeLogToFile(const QString& logMessage, const QString& filePath); void loginput(const QString& fieldTableName,const int& fieldId,const QString& modifies); /** * @brief 存储已展开路径的容器 * 格式通常为 "Root/Child/Child" 的字符串 */ QSet expandedPaths; signals: private slots: /** * @brief 当树中某个项目被点击时触发 * @param index 被点击的 QModelIndex */ void onTreeViewClicked(const QModelIndex &index); /** * @brief 当树中某个项目被点击时触发,专门给up和down按钮使用 * @param index 被点击的 QModelIndex */ void onTreeViewClicked_updown(const QModelIndex &index); /** * @brief “返回”按钮点击槽函数 * 用于在第三层目录与上层目录间进行返回逻辑 */ void onButtonBackClicked(); /** * @brief “上”按钮点击槽函数 * 用于在所有第三层目录间向上移动 */ void onButtonUpClicked(); /** * @brief “下”按钮点击槽函数 * 用于在所有第三层目录间向下移动 */ void onButtonDownClicked(); /** * @brief “左”按钮点击槽函数 * 用于目录层级的向左逻辑(如果有需要) */ void onButtonLeftClicked(); /** * @brief “右”按钮点击槽函数 * 用于目录层级的向右逻辑(如果有需要) */ void onButtonRightClicked(); /** * @brief 当树状模型中某个 QStandardItem 的复选框状态发生变化时触发 * @param item 发生变化的 QStandardItem */ void onItemChanged(QStandardItem *item); private: /** * @brief 指向 OriginalWnd 对象的指针,用于访问或联动其它窗口功能 */ OriginalWnd* m_originalWnd; /** * @brief widget2 外部传入的父级/容器,用于承载子控件 */ QWidget *widget2; /** * @brief 树视图控件 */ QTreeView *treeViewDown; /** * @brief 导航栏 QWidget,用于显示路径信息 */ QWidget *navigationWidget; /** * @brief 树状模型,用于存放目录层级 */ QStandardItemModel *model; /** * @brief 用于存储第三层字段展示窗口的指针(单实例) */ QWidget* m_thirdLevelFieldWnd = nullptr; /** * @brief 上部的几个操作按钮(例如 “返回”、“上”、“下”、“左”、“右”) */ QPushButton *ButtonBack; ///< 返回按钮 QPushButton *buttonUp; ///< 上按钮 QPushButton *buttonDown; ///< 下按钮 QPushButton *buttonLeft; ///< 左按钮 QPushButton *buttonRight; ///< 右按钮 // 定义一个结构来记录当前所处页面的信息 struct PageState { QStringList path; // 记录目录的文本路径 bool isThirdLevel; // 是否是第三层目录 int directoryId; // 第三层目录ID }; // 存储“后退栈”和“前进栈”, QList m_backStack; QList m_forwardStack; // 每次切换控制屏幕时,清空历史 void clearHistory(); // 用于把当前选中的目录或第三层界面封装成 PageState PageState getCurrentPageState(); // 加载指定 PageState,相当于“跳转”到该状态 void loadPageState(const PageState &st, bool isByHistoryNav = false); /** * @brief restoring 标记是否在恢复阶段 */ bool restoring; /** * @brief 存储“一级目录”和相应分隔线的映射,用于更新和控制分隔线位置、可见性等 */ QMap firstLevelSeparators; /** * @brief 标记是否阻止触发 onItemChanged 等复选框变更响应 */ bool m_blockItemChanged; /** * @brief 用于存储第三层界面生成的控件列表,方便统一管理和销毁 */ QList m_fieldWidgets; /** * @brief 当前正在使用的配置ID */ int m_currentConfigId = -1; /** * @brief 特定分隔线,Home 界面时隐藏,其他界面时显示 */ QFrame* lineFrame1; /** * @brief 从数据库加载指定 configId 下的目录记录,并构建树状结构 * @param configId 配置ID * @param userPrivilege 当前用户权限 */ void loadDirectories(int configId, const int &userPrivilege); /** * @brief 在给定父节点内,DFS 查找第一个第三层目录项 * @param parentItem 父节点 * @return 若找到第三层节点则返回指针,否则返回 nullptr */ QStandardItem* findFirstThirdLevelItemDFS(QStandardItem *parentItem); /** * @brief 递归更新父级目录的复选框状态 * @param item 当前变更的子项 */ void updateParentItems(QStandardItem *parentItem); /** * @brief 由 loadDirectories 获取的目录列表,构建树模型 * @param directories 包含目录信息的 QJsonObject 列表 */ void buildTreeFromDirectories(const QList &directories); /** * @brief 更新父项的复选框状态(如果所有子项选中则父项也选中,否则取消) * @param item 当前变更的子项 */ void updateParentCheckState(QStandardItem *item); /** * @brief 更新按钮可见性:Home 界面隐藏,其他配置显示 */ void updateButtonsVisibility(); /** * @brief 清理并隐藏第三层菜单内容 */ void clearThirdLevelMenu(); /** * @brief 由给定的 DirectoryId 查询数据库中的字段信息(BondHead、Buttons)并返回 * @param directoryId 目录ID * @param userPrivilege 当前用户权限 * @return 包含第三层目录字段和按钮信息的 QJsonObject */ QJsonObject fetchThirdLevelData(int directoryId, const int &userPrivilege); /** * @brief 自定义事件过滤器,用于在 QTreeView 上绘制虚线等 * @param watched 监视的对象 * @param event 事件 * @return 是否拦截事件 */ bool eventFilter(QObject *watched, QEvent *event) override; /** * @brief 递归绘制所有分支 * @param parentIndex 父节点索引 * @param painter QPainter 引用 */ void paintAllBranches(const QModelIndex &parentIndex, QPainter &painter); /** * @brief 绘制父节点到子节点的“拐角线” * @param childIndex 子节点索引 * @param painter QPainter 引用 */ void drawParentChildLine(const QModelIndex &childIndex, QPainter &painter); /** * @brief 兄弟节点之间的竖线连接 * @param childIndex 当前节点索引 * @param painter QPainter 引用 */ void drawSiblingLine(const QModelIndex &childIndex, QPainter &painter); /** * @brief 应用自定义样式(例如树的图标、复选框等) */ void applyCustomStyles(); /** * @brief 创建顶部按钮,并绑定槽函数 */ void setupButton(); /** * @brief 创建并返回一个统一样式的分隔线 QFrame * @param parent 父对象 * @param height 分隔线高度 * @return 分隔线 QFrame 指针 */ QFrame* createUnifiedSeparator(QWidget *parent, int height); /** * @brief 更新分隔线位置和可见性(主要针对一级目录和其子项) */ void updateSeparatorLine(); /** * @brief 查找父节点下最后一个可见子项,用于放置分隔线 * @param parentIndex 父节点索引 * @return 最后一个可见子节点的索引 */ QModelIndex findLastVisibleChild(const QModelIndex &parentIndex); /** * @brief 更新导航栏,显示选中的路径信息 * @param index 选中节点的 QModelIndex */ void updateNavigationBar(const QModelIndex &index); /** * @brief 加载第三层目录按钮配置并在 widget_left 显示 * @param thirdLevelObj 包含第三层目录 button 信息的 JSON */ void loadButtonConfigForThirdLevel(const QJsonObject &thirdLevelObj); /** * @brief 显示第三层目录的字段信息 * @param data 第三层目录数据(包含 fields, buttons 等) * @param isHome 是否是 Home 界面,若是则填满 widget2 */ void displayThirdLevelFields(const QJsonObject &data, bool isHome); /** * @brief 保存当前选中的复选框路径到 QSettings */ void saveCheckedPaths(); /** * @brief 从 QSettings 中加载复选框选中路径,并恢复 */ void loadCheckedPaths(); /** * @brief 收集所有被选中的复选框路径 * @return 被选中的路径列表,每项为 "Root/Child/Child" */ QStringList collectCheckedPaths(); /** * @brief 递归收集选中的路径 * @param item 当前节点 * @param path 当前路径 * @return 收集到的选中路径列表 */ QStringList collectCheckedPathsRecursive(QStandardItem *item, QStringList path); /** * @brief 批量设置选中的复选框 * @param checkedPathsList 已选中的路径列表 */ void setCheckedPaths(const QStringList &checkedPathsList); /** * @brief 构建节点的完整路径 * @param item 当前 QStandardItem * @return 路径列表,如 ["Root", "Child", "Child2"] */ QStringList buildItemPath(QStandardItem *item); /** * @brief 根据路径查找对应的节点索引 * @param path 路径列表 * @return 对应的 QModelIndex,若未找到则无效 */ QModelIndex findItemByPath(const QStringList &path); /** * @brief 检查权限,用于判断某字段/按钮是否可见 * @param UserGrade 数据库中存储的权限列表,如 "1,2,3" * @param userPrivilege 当前用户权限 * @return 是否包含此权限 */ bool hasPrivilege(const int &UserGrade, const int &userPrivilege); /** * @brief 实时的数据写入库 * @param TableName 数据所在表的name * @param Id 在表中的id * @param currentValue 当前修改的id */ void updateDb(const QString &TableName, const int &Id,const QString currentValue); public: struct menuInfo{ int menuId; bool isthird; int index; }; int currentMenuId; std::array menuArray; void loadpage(const int &configId); QList thirdLevelListtest; QStandardItem* deepCopyItem(const QStandardItem *item); }; #endif // DBTREEVIEWMANAGER_H