浏览代码

Merge branch 'master' of http://101.43.129.26:10880/chengxr/QFD2

zsf 1 年之前
父节点
当前提交
941c0c9bd2

+ 14 - 0
QFD/CCanvas/CCanvas.pri

@@ -0,0 +1,14 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+    $$PWD/CMind.h \
+    $$PWD/CMindView.h \
+    $$PWD/CNode.h \
+    $$PWD/CRectItem.h
+
+SOURCES += \
+    $$PWD/CMind.cpp \
+    $$PWD/CMindView.cpp \
+    $$PWD/CNode.cpp \
+    $$PWD/CRectItem.cpp
+

+ 70 - 0
QFD/CCanvas/CMind.cpp

@@ -0,0 +1,70 @@
+#include "CMind.h"
+
+CMind::CMind(QObject *parent) : QObject(parent) { }
+
+QList<CNodeData> CMind::nodeList() const
+{
+    return m_nodeList;
+}
+
+void CMind::setNodeList(QList<CNodeData> list)
+{
+    m_nodeList = list;
+}
+
+bool CMind::containsNode(CNodeData node) const
+{
+    if (node.id >= 0) {
+        return containsNodeWithId(node.id);
+    }
+    return containsNodeWithNumber(node.number);
+}
+
+bool CMind::containsNodeWithId(int id) const
+{
+    for (auto n : m_nodeList) {
+        if (n.id == id) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool CMind::containsNodeWithNumber(int num) const
+{
+    for (auto n : m_nodeList) {
+        if (n.number == num) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void CMind::addNode(CNodeData node)
+{
+    m_nodeList.append(node);
+}
+
+void CMind::removeNode(CNodeData node, bool removeChildren)
+{
+    removeNodeByNumber(node.number, removeChildren);
+}
+
+void CMind::removeNodeById(int id, bool removeChildren)
+{
+    for (auto n : m_nodeList) {
+        if (n.id == id) {
+            removeNodeByNumber(n.number, removeChildren);
+        }
+    }
+}
+
+void CMind::removeNodeByNumber(int number, bool removeChildren)
+{
+    for (int i = 0; i < m_nodeList.count(); i++) {
+        CNodeData n = m_nodeList[i];
+        if (n.number == number || (removeChildren && n.pNumber == number)) {
+            m_nodeList.removeAt(i);
+        }
+    }
+}

+ 40 - 0
QFD/CCanvas/CMind.h

@@ -0,0 +1,40 @@
+#ifndef CMIND_H
+#define CMIND_H
+
+#include <QObject>
+
+struct CNodeData
+{
+    int id        = -1;  // 节点 id, 对应数据库节点表中的 id, 数据库自动生成
+    int projectId = -1;  // 项目 id, 对应数据库项目表中的 id, 为脑图所属项目, 数据库自动生成
+    int evalType  = 0;   // 评估类型
+    int number    = -1;  // 节点编号, 作用域为当前脑图, 0 为根节点
+    int pNumber   = -1;  // 父节点编号
+    QString name;        // 名称
+    QString remark;      // 备注
+};
+
+class CMind : public QObject
+{
+    Q_OBJECT
+
+public:
+    explicit CMind(QObject *parent = nullptr);
+
+    // 节点数据
+    QList<CNodeData> nodeList() const;
+    void setNodeList(QList<CNodeData> list);
+
+    bool containsNode(CNodeData node) const;
+    bool containsNodeWithId(int id) const;
+    bool containsNodeWithNumber(int num) const;
+    void addNode(CNodeData node);
+    void removeNode(CNodeData node, bool removeChildren = true);
+    void removeNodeById(int id, bool removeChildren = true);
+    void removeNodeByNumber(int number, bool removeChildren = true);
+
+private:
+    QList<CNodeData> m_nodeList;
+};
+
+#endif  // CMIND_H

+ 32 - 0
QFD/CCanvas/CMindView.cpp

@@ -0,0 +1,32 @@
+#include "CMindView.h"
+
+#include <QGraphicsRectItem>
+
+CMindView::CMindView(QWidget *parent) : QGraphicsView(new QGraphicsScene(), parent)
+{
+    testItems();
+}
+
+CMind *CMindView::mind() const
+{
+    return m_mind;
+}
+
+void CMindView::setMind(CMind *mind)
+{
+    m_mind = mind;
+    refresh();
+}
+
+void CMindView::refresh() { }
+
+void CMindView::setALignment(CMindView::Alignment align)
+{
+    m_align = align;
+}
+
+void CMindView::testItems()
+{
+    QGraphicsRectItem *r = new QGraphicsRectItem(QRectF(0, 0, 100, 100));
+    scene()->addItem(r);
+}

+ 35 - 0
QFD/CCanvas/CMindView.h

@@ -0,0 +1,35 @@
+#ifndef CMINDVIEW_H
+#define CMINDVIEW_H
+
+#include <QGraphicsView>
+
+class CMind;
+
+class CMindView : public QGraphicsView
+{
+    enum Alignment
+    {
+        NoAlignment,
+        AlignLeft,
+        AlignRight,
+    };
+
+public:
+    CMindView(QWidget *parent = nullptr);
+
+    CMind *mind() const;
+    void setMind(CMind *mind);
+
+    void refresh();
+
+    void setALignment(Alignment align);
+
+private:
+    CMind *m_mind = nullptr;
+
+    Alignment m_align = NoAlignment;
+
+    void testItems();
+};
+
+#endif  // CMINDVIEW_H

+ 82 - 0
QFD/CCanvas/CNode.cpp

@@ -0,0 +1,82 @@
+#include "CNode.h"
+
+CNode::CNode(QObject *parent) : QObject(parent) { }
+
+const CNode *CNode::pNode() const
+{
+    return dynamic_cast<CNode *>(QObject::parent());
+}
+
+const CNode *CNode::rNode() const
+{
+    if (pNode() == nullptr) {
+        return this;
+    }
+    return pNode();
+}
+
+QList<CNode *> CNode::cNodes() const
+{
+    QList<CNode *> l;
+    for (QObject *o : children()) {
+        CNode *n = dynamic_cast<CNode *>(o);
+        if (n != nullptr) {
+            l.append(n);
+        }
+    }
+    return l;
+}
+
+int CNode::height() const
+{
+    int h = 1;
+    for (CNode *n : cNodes()) {
+        h = std::max(h, n->height() + 1);
+    }
+
+    return h;
+}
+
+int CNode::depth() const
+{
+    int d          = 1;
+    const CNode *n = this;
+
+    while (n->pNode() != nullptr) {
+        d++;
+        n = n->pNode();
+    }
+
+    return d;
+}
+
+int CNode::leafs() const
+{
+    int d = 1;
+    if (cNodes().count() > 0) {
+        d = 0;
+        for (CNode *n : cNodes()) {
+            d += n->leafs();
+        }
+    }
+
+    return d;
+}
+
+int CNode::sizeOfLevel(int lev) const
+{
+    if (lev < 1) {
+        return 0;
+    }
+
+    if (lev == 1) {
+        return 1;
+    }
+
+    int size = 0;
+    for (CNode *n : cNodes()) {
+        size += n->sizeOfLevel(lev - 1);
+    }
+
+    return size;
+}

+ 34 - 0
QFD/CCanvas/CNode.h

@@ -0,0 +1,34 @@
+#ifndef CNODE_H
+#define CNODE_H
+
+#include <QObject>
+
+class CNode : public QObject
+{
+    Q_OBJECT
+public:
+    explicit CNode(QObject *parent = nullptr);
+
+    const CNode *pNode() const;  // 父节点
+
+    const CNode *rNode() const;  // 根节点
+
+    QList<CNode *> cNodes() const;  // 孩子节点
+
+    int height() const;  // 节点的高度
+
+    int depth() const;  // 节点的深度
+
+    int leafs() const;  // 叶子节点个数或包含的路径条数
+
+    ///
+    /// \brief sizeOfLevel 以此节点为根节点的子树中,某一层的节点数
+    /// \param lev 节点层级,当前节点为1,向下递增
+    /// \return 节点数
+    ///
+    int sizeOfLevel(int lev) const;
+
+signals:
+};
+
+#endif  // CNODE_H

+ 5 - 0
QFD/CCanvas/CRectItem.cpp

@@ -0,0 +1,5 @@
+#include "CRectItem.h"
+
+CRectItem::CRectItem(QGraphicsItem *parent) : QGraphicsPathItem(parent) { }
+
+void CRectItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { }

+ 14 - 0
QFD/CCanvas/CRectItem.h

@@ -0,0 +1,14 @@
+#ifndef CRECTITEM_H
+#define CRECTITEM_H
+
+#include <QGraphicsPathItem>
+
+class CRectItem : public QGraphicsPathItem
+{
+public:
+    explicit CRectItem(QGraphicsItem *parent = nullptr);
+
+    void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
+};
+
+#endif  // CRECTITEM_H

+ 3 - 0
QFD/QFD.pro

@@ -124,6 +124,7 @@ HEADERS += \
 
 
 include(./mindmap/mindmap.pri)
+include(./CCanvas/CCanvas.pri)
 include(./shemeTable/shemeTable.pri)
 include(./QtAwesome/QtAwesome.pri)
 include(./EasyQtSql/EasyQtSql.pri)
@@ -147,3 +148,5 @@ RESOURCES += \
 FORMS +=
 
 VERSION = "2.1.2.1"
+
+DISTFILES +=

+ 7 - 1
QFD/common/ProjectManager.cpp

@@ -55,7 +55,6 @@ QList<ProjectManager::IndexType> ProjectManager::indexListOfEvalTypes(EvalTypes
 ProjectManager::EvalTypes ProjectManager::evalTypes(ProjectInfo proj)
 {
     int t           = proj.estimateType.toInt();
-    t               = 96;
     EvalTypes types = EvalTypes(t);
     return types;
 }
@@ -140,3 +139,10 @@ int ProjectManager::updateProject(ProjectInfo &proj)
     }
     return code;
 }
+
+int ProjectManager::deleteProject(int id)
+{
+    bool ret = ProjectService().DeleteById(id);
+    qDebug() << __FUNCTION__ << __LINE__ << "ret:" << ret;
+    return ret ? QF_CODE_SUCCEEDED : QF_CODE_PROJ_DELETE_FALIED;
+}

+ 1 - 0
QFD/common/ProjectManager.h

@@ -55,6 +55,7 @@ public:
 
     static int insertProject(ProjectInfo &proj);
     static int updateProject(ProjectInfo &proj);
+    static int deleteProject(int id);
 };
 
 #endif  // PROJECTMANAGER_H

+ 4 - 2
QFD/common/QFDAlert.cpp

@@ -43,11 +43,13 @@ void QFDAlert::showAlertWithCode(int code, QWidget *w)
     } else if (code == QF_CODE_NEED_PROJ_TYPE) {
         msg = "请选额评估类型";
     } else if (code == QF_CODE_PROJ_CREATE_FALIED) {
-        msg = "创建失败,数据库异常";
+        msg = "创建失败";
     } else if (code == QF_CODE_PROJ_NOT_EDITABLE) {
         msg = "该项目类型不支持修改";
     } else if (code == QF_CODE_PROJ_UPDATE_FALIED) {
-        msg = "更新失败,数据库异常";
+        msg = "更新失败";
+    } else if (code == QF_CODE_PROJ_DELETE_FALIED) {
+        msg = "删除失败";
     }
 
     if (!msg.isEmpty()) {

+ 1 - 0
QFD/dbService/ClassSet.h

@@ -29,6 +29,7 @@ const int QF_CODE_NEED_PROJ_TYPE     = 2022;
 const int QF_CODE_PROJ_CREATE_FALIED = 2023;
 const int QF_CODE_PROJ_NOT_EDITABLE  = 2024;
 const int QF_CODE_PROJ_UPDATE_FALIED = 2025;
+const int QF_CODE_PROJ_DELETE_FALIED = 2026;
 
 /**
  * @projectName   QFD

+ 3 - 1
QFD/dbService/ProjectService.cpp

@@ -42,7 +42,7 @@ bool ProjectService::UpdateProjectInfo(const ProjectInfo &proInfo)
                 .set("estimate_objective", proInfo.estimateObjective)
                 .set("estimate_dept", proInfo.estimateDept)
                 .set("estimatePerson", proInfo.estimatePerson)
-                .set("estimateType", proInfo.estimateType)
+                .set("estimatedType", proInfo.estimateType)
                 .set("positionalTitles", proInfo.positionalTitles)
                 .set("updateTime", proInfo.updateTime)
                 .where("id = ?", proInfo.id);
@@ -190,6 +190,8 @@ bool ProjectService::DeleteById(int id)
 {
     bool ret = false;
     try {
+        qDebug() << __FUNCTION__ << __LINE__
+                 << SqlDBHelper::getDatabase().driver()->hasFeature(QSqlDriver::Transactions) << endl;
         Transaction t(SqlDBHelper::getDatabase());
         t.deleteFrom("t_project_info").where("id = ?", id);
         t.commit();

文件差异内容过多而无法显示
+ 0 - 0
QFD/resource/svg/Project_black.svg


文件差异内容过多而无法显示
+ 0 - 0
QFD/resource/svg/Project_white.svg


+ 28 - 16
QFD/view/HomeView.cpp

@@ -10,6 +10,7 @@
 
 #include <Widgets/Button.h>
 #include <Widgets/LineEdit.h>
+#include <DialogBox/Dialog.h>
 
 #include <QBoxLayout>
 #include <QLabel>
@@ -87,10 +88,10 @@ void HomeView::connectSignalsAndSlots()
 {
     connect(m_create, &PushButton::clicked, this, &HomeView::slotCreateProjClicked);
     connect(m_search, &LineEdit::textChanged, this, &HomeView::slotSearchTextChanged);
-    connect(m_createProjWidget, &CreateProjWidget::signalCreate, this, &HomeView::slotConfirmCreate);
+    connect(m_createProjWidget, &CreateProjWidget::signalConfirm, this, &HomeView::slotProjInfoConfirmed);
     connect(m_projListWidget, &ProjectListWidget::sigOpen, this, &HomeView::slotOpenProject);
-    connect(m_projListWidget, &ProjectListWidget::sigEdit, this, &HomeView::slotEditProject);
     connect(m_projListWidget, &ProjectListWidget::sigInfo, this, &HomeView::slotProjectInfo);
+    connect(m_projListWidget, &ProjectListWidget::sigDelete, this, &HomeView::slotDeleteProject);
 }
 
 void HomeView::loadProjects()
@@ -104,7 +105,7 @@ void HomeView::loadProjects()
         return;
     }
 
-    m_projListWidget->showProjects(searchResult());
+    m_projListWidget->setProjects(searchResult());
 }
 
 QList<ProjectInfo *> HomeView::searchResult() const
@@ -129,19 +130,21 @@ void HomeView::slotCreateProjClicked()
 
 void HomeView::slotSearchTextChanged()
 {
-    m_projListWidget->showProjects(searchResult());
+    m_projListWidget->setProjects(searchResult());
 }
 
-void HomeView::slotConfirmCreate()
+/// @todo 修改或者新建项目后, 列表移到该条目
+void HomeView::slotProjInfoConfirmed()
 {
-    int code         = -1;
-    ProjectInfo info = m_createProjWidget->editedProjInfo();
+    int code               = -1;
+    ProjectInfo *info      = m_createProjWidget->projInfo();
+    ProjectInfo editedInfo = m_createProjWidget->editedProjInfo();
 
     if (m_createProjWidget->mode() == CreateProjWidget::Create) {
-        code = ProjectManager::insertProject(info);
+        code = ProjectManager::insertProject(editedInfo);
     } else if (m_createProjWidget->mode() == CreateProjWidget::Update) {
-        info.id = m_createProjWidget->projInfo()->id;
-        code    = ProjectManager::updateProject(info);
+        editedInfo.id = m_createProjWidget->projInfo()->id;
+        code          = ProjectManager::updateProject(editedInfo);
     } else {
         return;
     }
@@ -163,13 +166,22 @@ void HomeView::slotProjectInfo(ProjectInfo *proj)
     }
 }
 
-void HomeView::slotOpenProject(ProjectInfo *proj) { }
+void HomeView::slotOpenProject(ProjectInfo *proj)
+{
+    emit sigOpenProject(proj);
+}
 
-void HomeView::slotEditProject(ProjectInfo *proj)
+void HomeView::slotDeleteProject(ProjectInfo *proj)
 {
-    if (m_createProjWidget->isVisible() == false) {
-        m_createProjWidget->setMode(CreateProjWidget::Update);
-        m_createProjWidget->setProjectInfo(proj);
-        m_createProjWidget->show();
+    QString title = "删除工程 “" + proj->projectName + "” ?";
+    MessageBox *m = new MessageBox(title, "删除后无法恢复", this);
+
+    if (m->exec()) {
+        int code = ProjectManager::deleteProject(proj->id);
+        QFDAlert::showAlertWithCode(code, this);
+        if (code == QF_CODE_SUCCEEDED) {
+            m_projList.removeOne(proj);
+            m_projListWidget->removeProject(proj);
+        }
     }
 }

+ 5 - 2
QFD/view/HomeView.h

@@ -27,6 +27,9 @@ public:
     void showEvent(QShowEvent *event) override;
     void hideEvent(QHideEvent *event) override;
 
+signals:
+    void sigOpenProject(ProjectInfo *proj);
+
 private:
     void initWidgets();
     void initLayout();
@@ -39,10 +42,10 @@ private:
 private slots:
     void slotCreateProjClicked();
     void slotSearchTextChanged();
-    void slotConfirmCreate();
+    void slotProjInfoConfirmed();
     void slotProjectInfo(ProjectInfo *proj);
     void slotOpenProject(ProjectInfo *proj);
-    void slotEditProject(ProjectInfo *proj);
+    void slotDeleteProject(ProjectInfo *proj);
 
 private:
     bool m_initilized = false;

+ 56 - 70
QFD/view/MainWindow.cpp

@@ -10,8 +10,14 @@
 #include "SettingView.h"
 #include "UserView.h"
 
+#include "dbService/ClassSet.h"
+
+#include "QFDConfig.h"
+
 #include "common/QFDIcon.h"
 
+#include "CCanvas/CMindView.h"
+
 #include <QFramelessWindow.h>
 
 #include <Navigation/NavigationInterface.h>
@@ -57,6 +63,9 @@ void StackedWidget::setCurrentWidget(QWidget *widget, bool popOut)
 
 void StackedWidget::setCurrentIndex(int index, bool popOut)
 {
+    if (index < 0 || index >= view()->count()) {
+        return;
+    }
     setCurrentWidget(m_view->widget(index), popOut);
 }
 
@@ -65,6 +74,17 @@ PopUpAniStackedWidget *StackedWidget::view() const
     return m_view;
 }
 
+int StackedWidget::index(const QString routeKey)
+{
+    for (int i = 0; i < view()->count(); i++) {
+        QWidget *w = view()->widget(i);
+        if (w->objectName() == routeKey) {
+            return i;
+        }
+    }
+    return -1;
+}
+
 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
 {
     m_titleBar               = new CustomTitleBar(this);
@@ -83,7 +103,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
 
     initLoginPage();
 
-    setMinimumSize(QSize(1000, 800));
+    setMinimumSize(QSize(1200, 800));
 }
 
 MainWindow::~MainWindow() { }
@@ -105,16 +125,12 @@ void MainWindow::initMainPage()
     m_widgetLayout  = new QHBoxLayout();
     m_stackWidget   = new StackedWidget(m_mainWidget);
     m_naviInterface = new NavigationInterface(true, true, m_mainWidget);
-    m_naviInterface->panel->setExpandWidth(200);
 
     m_homeView = new HomeView(m_mainWidget);
 
-    m_projectView      = new ProjectView(m_mainWidget);
-    m_evaluateView     = new EvaluateView(m_mainWidget);
-    m_expertManageView = new ExpertManageView(m_mainWidget);
-    m_aboutView        = new AboutView(m_mainWidget);
-    m_settingView      = new SettingView(m_mainWidget);
-    m_userView         = new UserView(m_mainWidget);
+    m_aboutView   = new AboutView(m_mainWidget);
+    m_settingView = new SettingView(m_mainWidget);
+    m_userView    = new UserView(m_mainWidget);
 
     m_mainStackedWidget->addWidget(m_mainWidget);
 
@@ -128,54 +144,40 @@ void MainWindow::initMainPage()
     m_widgetLayout->setContentsMargins(0, 32, 0, 0);
 
     initNavigation();
+    m_naviInterface->panel->expand();
 
     connect(m_naviInterface, &NavigationInterface::displayModeChanged, m_titleBar, &StandardTitleBar::raise);
     connect(m_userView, &UserView::signalLogout, this, &MainWindow::slotLogout);
+    connect(m_homeView, &HomeView::sigOpenProject, this, &MainWindow::slotOpenProject);
 }
 
 void MainWindow::initNavigation()
 {
     m_homeView->setObjectName("homeView");
     m_stackWidget->addWidget(m_homeView);
-    m_naviInterface->addItem(m_homeView->objectName(), NEWFLICON(FluentIcon, HOME), "首页", this,
-                             SLOT(homeViewClicked()));
-
-    m_projectView->setObjectName("projectView");
-    m_stackWidget->addWidget(m_projectView);
-    m_naviInterface->addItem(m_projectView->objectName(), NEWFLICON(QFDIcon, Project), "项目管理", this,
-                             SLOT(projectViewClicked()));
-
-    m_expertManageView->setObjectName("expertManageView");
-    m_stackWidget->addWidget(m_expertManageView);
-    m_naviInterface->addItem(m_expertManageView->objectName(), NEWFLICON(QFDIcon, Expert), "专家信息管理", this,
-                             SLOT(expertViewClicked()));
+    m_naviInterface->addItem(m_homeView->objectName(), NEWFLICON(FluentIcon, HOME), "评估项目管理", this,
+                             SLOT(slotNaviItemClicked()));
 
-    m_evaluateView->setObjectName("evaluateView");
-    m_stackWidget->addWidget(m_evaluateView);
-    m_naviInterface->addItem(m_evaluateView->objectName(), NEWFLICON(QFDIcon, Data), "评估数据分析", this,
-                             SLOT(dataViewClicked()));
+    m_settingView->setObjectName("settingView");
+    m_stackWidget->addWidget(m_settingView);
+    m_naviInterface->addItem(m_settingView->objectName(), NEWFLICON(FluentIcon, SETTING), "系统资源管理", this,
+                             SLOT(slotNaviItemClicked()));
 
     m_naviInterface->addSeparator();
 
     m_userView->setObjectName("userView");
     m_stackWidget->addWidget(m_userView);
-    m_naviInterface->addItem(m_userView->objectName(), NEWFLICON(QFDIcon, User), "用户", this, SLOT(userViewClicked()),
-                             true, NavigationItemPosition::BOTTOM);
-
-    m_settingView->setObjectName("settingView");
-    m_stackWidget->addWidget(m_settingView);
-    m_naviInterface->addItem(m_settingView->objectName(), NEWFLICON(FluentIcon, SETTING), "设置", this,
-                             SLOT(settingViewClicked()), true, NavigationItemPosition::BOTTOM);
+    m_naviInterface->addItem(m_userView->objectName(), NEWFLICON(QFDIcon, User), "用户", this,
+                             SLOT(slotNaviItemClicked()), true, NavigationItemPosition::BOTTOM);
 
     m_aboutView->setObjectName("aboutView");
     m_stackWidget->addWidget(m_aboutView);
     m_naviInterface->addItem(m_aboutView->objectName(), NEWFLICON(FluentIcon, INFO), "关于", this,
-                             SLOT(aboutViewClicked()), true, NavigationItemPosition::BOTTOM);
-
-    m_naviInterface->setDefaultRouteKey(m_homeView->objectName());
+                             SLOT(slotNaviItemClicked()), true, NavigationItemPosition::BOTTOM);
 
     connect(m_stackWidget, &StackedWidget::currentWidgetChanged, this,
             [this](QWidget *w) { m_naviInterface->setCurrentItem(w->objectName()); });
+    m_naviInterface->setDefaultRouteKey(m_homeView->objectName());
     m_naviInterface->setCurrentItem(m_homeView->objectName());
     m_stackWidget->setCurrentIndex(0);
 }
@@ -189,7 +191,7 @@ void MainWindow::setNaviInterfaceHidden(bool hidden)
 int MainWindow::titleBarIndent() const
 {
     if (m_mainStackedWidget->currentIndex() > 0 && m_naviInterface != nullptr && m_naviInterface->isHidden() == false) {
-        return 46;
+        return 48;
     }
     return 0;
 }
@@ -200,12 +202,6 @@ void MainWindow::resizeEvent(QResizeEvent *event)
     m_titleBar->resize(width() - titleBarIndent(), m_titleBar->height());
 }
 
-void MainWindow::switchTo(QWidget *widget, bool triggerByUser)
-{
-    qDebug() << __FUNCTION__ << __LINE__;
-    m_stackWidget->setCurrentWidget(widget, !triggerByUser);
-}
-
 void MainWindow::slotLogin()
 {
     initMainPage();
@@ -217,6 +213,7 @@ void MainWindow::slotLogin()
 
 void MainWindow::slotLogout()
 {
+    qfReloadHomeProjectsAtShow = true;
     m_mainStackedWidget->setCurrentWidget(m_loginView);
     m_mainStackedWidget->removeWidget(m_mainWidget);
     delete m_mainWidget;
@@ -231,37 +228,26 @@ void MainWindow::slotCancelLogin()
     exit(0);
 }
 
-void MainWindow::homeViewClicked()
-{
-    switchTo(m_homeView);
-}
-
-void MainWindow::projectViewClicked()
+void MainWindow::slotNaviItemClicked()
 {
-    switchTo(m_projectView);
+    int index = m_stackWidget->index(sender()->property("routeKey").toString());
+    m_stackWidget->setCurrentIndex(index);
 }
 
-void MainWindow::expertViewClicked()
+void MainWindow::slotOpenProject(ProjectInfo *proj)
 {
-    switchTo(m_expertManageView);
-}
-
-void MainWindow::aboutViewClicked()
-{
-    switchTo(m_aboutView);
-}
-
-void MainWindow::dataViewClicked()
-{
-    switchTo(m_evaluateView);
-}
-
-void MainWindow::settingViewClicked()
-{
-    switchTo(m_settingView);
-}
-
-void MainWindow::userViewClicked()
-{
-    switchTo(m_userView);
+    QString n = QString("project_%1").arg(proj->id);
+    int index = m_stackWidget->index(n);
+    if (index >= 0) {
+        m_stackWidget->setCurrentIndex(index);
+    } else {
+        CMindView *m = new CMindView(m_mainWidget);
+        m->setObjectName(n);
+        m_stackWidget->addWidget(m);
+
+        QString t = QString("打开项目-%1").arg(proj->projectName);
+        m_naviInterface->addItem(m->objectName(), NEWFLICON(QFDIcon, Project), t, this, SLOT(slotNaviItemClicked()),
+                                 true, NavigationItemPosition::SCROLL);
+        m_stackWidget->setCurrentWidget(m);
+    }
 }

+ 10 - 13
QFD/view/MainWindow.h

@@ -4,13 +4,14 @@
 #include <QFrame>
 #include <QMainWindow>
 
+class ProjectInfo;
+
 class PopUpAniStackedWidget;
 class QHBoxLayout;
 class NavigationInterface;
 class CustomTitleBar;
 
 class HomeView;
-class ProjectView;
 class ExpertManageView;
 class EvaluateView;
 class LoginView;
@@ -34,6 +35,8 @@ public:
 
     PopUpAniStackedWidget *view() const;
 
+    int index(const QString routeKey);
+
 signals:
     void currentWidgetChanged(QWidget *);
 
@@ -62,20 +65,17 @@ private:
 
     void resizeEvent(QResizeEvent *event) override;
 
-    void switchTo(QWidget *widget, bool triggerByUser = true);
+    int routeIndex(const QString routeKey) const;
 
 private slots:
     void slotLogin();
     void slotLogout();
 
     void slotCancelLogin();
-    void homeViewClicked();
-    void projectViewClicked();
-    void expertViewClicked();
-    void aboutViewClicked();
-    void dataViewClicked();
-    void settingViewClicked();
-    void userViewClicked();
+
+    void slotNaviItemClicked();
+
+    void slotOpenProject(ProjectInfo *proj);
 
 private:
     CustomTitleBar *m_titleBar = 0;
@@ -90,10 +90,7 @@ private:
     StackedWidget *m_stackWidget         = 0;
     NavigationInterface *m_naviInterface = 0;
 
-    HomeView *m_homeView                 = 0;
-    ProjectView *m_projectView           = 0;
-    ExpertManageView *m_expertManageView = 0;
-    EvaluateView *m_evaluateView         = 0;
+    HomeView *m_homeView = 0;
 
     AboutView *m_aboutView     = 0;
     SettingView *m_settingView = 0;

+ 10 - 79
QFD/view/ProjectView.cpp

@@ -12,14 +12,12 @@
 
 #include <QDebug>
 
-ProjectView::ProjectView(QWidget *parent) : QWidget(parent) { }
+ProjectView::ProjectView(ProjectInfo *proj, QWidget *parent) : QWidget(parent), m_proj(proj) { }
 
 void ProjectView::showEvent(QShowEvent *event)
 {
-    qDebug() << __FUNCTION__ << __LINE__;
-
     if (m_initilized == false) {
-        initialize();
+        initWidgets();
         initLayout();
         connectSigalsAndSlots();
         m_initilized = true;
@@ -33,85 +31,18 @@ void ProjectView::hideEvent(QHideEvent *event)
     QWidget::hideEvent(event);
 }
 
-void ProjectView::initialize()
+ProjectInfo *ProjectView::proj() const
 {
-    m_hBoxLayout = new QHBoxLayout(this);
-
-    m_listWidget = new QWidget(this);
-    m_listWidget->setFixedWidth(260);
-
-    QPalette pal(m_listWidget->palette());
-    pal.setColor(QPalette::Background, QColor("#f3f3f3"));
-    m_listWidget->setAutoFillBackground(true);
-    m_listWidget->setPalette(pal);
-
-    m_listLayout = new QVBoxLayout(m_listWidget);
-
-    m_buttonLayout   = new QHBoxLayout();
-    m_searchLineEdit = new LineEdit(this);
-    m_searchLineEdit->setIsClearButtonEnabled(true);
-    m_searchLineEdit->setPlaceholderText("搜索工程");
-    m_renameButton = new ToolButton(NEWFLICON(FluentIcon, EDIT), this);
-    m_renameButton->setToolTip("修改工程名");
-    m_newProjButton = new ToolButton(NEWFLICON(FluentIcon, ADD), this);
-    m_newProjButton->setToolTip("新建工程");
-    m_deleteButton = new ToolButton(NEWFLICON(FluentIcon, DELETE), this);
-    m_deleteButton->setToolTip("删除工程");
-
-    m_projListWidget = new ProjectListWidget(this);
-
-    m_projDetailWidget = new QWidget(this);
-    m_projLayout       = new QVBoxLayout(m_projDetailWidget);
-
-    m_projNameLabel = new QLabel(this);
-    m_projNameLabel->setObjectName("projNameLabel");
-    m_projNameLabel->setText("工程1-技术方案评估");
-
-    m_separator = new QWidget(this);
-    m_separator->setFixedWidth(1);
-    m_separator->setStyleSheet("background-color:#dddddd");
-
-    m_configExpWidget = new ConfigExpertWidget(this);
-    m_configExpWidget->setFixedWidth(260);
-
-    m_renameWidget = new RenameWidget(this);
+    return m_proj;
 }
 
-void ProjectView::initLayout()
+void ProjectView::setProject(ProjectInfo *proj)
 {
-    m_hBoxLayout->setMargin(0);
-    m_hBoxLayout->setSpacing(0);
-
-    m_hBoxLayout->addWidget(m_listWidget);
-
-    m_listLayout->addLayout(m_buttonLayout);
-    m_buttonLayout->addWidget(m_searchLineEdit);
-    m_buttonLayout->addWidget(m_newProjButton);
-    m_buttonLayout->addWidget(m_renameButton);
-    m_buttonLayout->addWidget(m_deleteButton);
-
-    m_listLayout->addWidget(m_projListWidget);
-
-    m_hBoxLayout->addWidget(m_projDetailWidget);
-
-    m_projLayout->addWidget(m_projNameLabel);
-    m_projLayout->addStretch();
-
-    m_hBoxLayout->addWidget(m_separator, Qt::AlignRight);
-    m_hBoxLayout->addWidget(m_configExpWidget, Qt::AlignRight);
-
-    setStyleSheet("#projNameLabel {font-size:20px;font:bold;color:#333333}");
+    m_proj = proj;
 }
 
-void ProjectView::connectSigalsAndSlots()
-{
-    connect(m_renameButton, &ToolButton::clicked, this, &ProjectView::showRenameWidget);
-}
+void ProjectView::initWidgets() { }
 
-void ProjectView::showRenameWidget()
-{
-    if (m_renameWidget->isVisible() == false) {
-        m_renameWidget->clearInputs();
-        m_renameWidget->show();
-    }
-}
+void ProjectView::initLayout() { }
+
+void ProjectView::connectSigalsAndSlots() { }

+ 10 - 31
QFD/view/ProjectView.h

@@ -3,60 +3,39 @@
 
 #include <QWidget>
 
-class ProjectListWidget;
-class ConfigExpertWidget;
-
-class RenameWidget;
-
-class LineEdit;
-class ToolButton;
+class ProjectInfo;
 
 class QVBoxLayout;
 class QHBoxLayout;
 class QLabel;
 
 /// 工程视图
-/// 可以查看和编辑指标体系、配置专家
 class ProjectView : public QWidget
 {
     Q_OBJECT
 public:
-    explicit ProjectView(QWidget *parent = nullptr);
+    explicit ProjectView(ProjectInfo *proj = nullptr, QWidget *parent = nullptr);
 
     void showEvent(QShowEvent *event) override;
     void hideEvent(QHideEvent *event) override;
 
+    ProjectInfo *proj() const;
+
+    void setProject(ProjectInfo *proj);
+
 signals:
 
 private:
-    void initialize();
+    void initWidgets();
     void initLayout();
     void connectSigalsAndSlots();
-    void showRenameWidget();
 
 private:
-    bool m_initilized = false;
+    ProjectInfo *m_proj = nullptr;
 
-    QHBoxLayout *m_hBoxLayout = nullptr;
-
-    QWidget *m_listWidget               = nullptr;
-    QVBoxLayout *m_listLayout           = nullptr;
-    QHBoxLayout *m_buttonLayout         = nullptr;
-    LineEdit *m_searchLineEdit          = nullptr;
-    ToolButton *m_renameButton          = nullptr;
-    ToolButton *m_newProjButton         = nullptr;
-    ToolButton *m_deleteButton          = nullptr;
-    ProjectListWidget *m_projListWidget = nullptr;
-
-    QWidget *m_projDetailWidget = nullptr;
-    QVBoxLayout *m_projLayout   = nullptr;
-    QLabel *m_projNameLabel     = nullptr;
-
-    QWidget *m_separator = nullptr;
-
-    ConfigExpertWidget *m_configExpWidget = nullptr;
+    bool m_initilized = false;
 
-    RenameWidget *m_renameWidget = nullptr;
+    QHBoxLayout *m_layout = nullptr;
 };
 
 #endif  // PROJECTVIEW_H

+ 115 - 71
QFD/widgets/CreateProjWidget.cpp

@@ -39,7 +39,7 @@ void CreateProjWidget::setMode(CreateProjWidget::Mode mode)
     }
     case Update: {
         setWindowTitle("修改项目");
-        m_confirm->setText("修改");
+        m_confirm->setText("保存");
         break;
     }
     case Info: {
@@ -50,34 +50,36 @@ void CreateProjWidget::setMode(CreateProjWidget::Mode mode)
 
     bool c  = (mode == Create);
     bool cu = (mode == Update || mode == Create);
+    bool i  = (mode == Info);
 
-    m_taskName->setEnabled(cu);
-    m_evalTime->setEnabled(c);
-    m_evalPurpose->setEnabled(cu);
-    m_evalUnit->setEnabled(cu);
-    m_evalCrew->setEnabled(cu);
+    m_task->setEnabled(cu);
+    m_time->setEnabled(c);
+    m_purpose->setEnabled(cu);
+    m_unit->setEnabled(cu);
+    m_crew->setEnabled(cu);
     m_rank->setEnabled(cu);
     m_note->setEnabled(cu);
-    m_name->setEnabled(cu);
+    m_proj->setEnabled(cu);
     m_type1->setEnabled(c);
     m_type2->setEnabled(c);
     m_type3->setEnabled(c);
 
+    m_edit->setVisible(i);
     m_confirm->setVisible(cu);
     m_cancel->setVisible(cu);
 }
 
 void CreateProjWidget::resetInputs()
 {
-    m_taskName->clear();
-    m_evalTime->setDateTime(QDateTime::currentDateTime());
-    m_evalPurpose->clear();
-    m_evalUnit->clear();
-    m_evalCrew->clear();
+    m_task->clear();
+    m_time->setDateTime(QDateTime::currentDateTime());
+    m_purpose->clear();
+    m_unit->clear();
+    m_crew->clear();
     m_rank->clear();
     m_note->clear();
 
-    m_name->clear();
+    m_proj->clear();
     m_type1->setChecked(false);
     m_type2->setChecked(false);
     m_type3->setChecked(false);
@@ -91,15 +93,15 @@ ProjectInfo *CreateProjWidget::projInfo() const
 ProjectInfo CreateProjWidget::editedProjInfo() const
 {
     ProjectInfo proj;
-    proj.taskName          = m_taskName->text();
-    proj.estimateTime      = QString::number(m_evalTime->dateTime().toTime_t());
-    proj.estimateObjective = m_evalPurpose->text();
-    proj.estimateDept      = m_evalUnit->text();
-    proj.estimatePerson    = m_evalCrew->text();
+    proj.taskName          = m_task->text();
+    proj.estimateTime      = QString::number(m_time->dateTime().toTime_t());
+    proj.estimateObjective = m_purpose->text();
+    proj.estimateDept      = m_unit->text();
+    proj.estimatePerson    = m_crew->text();
     proj.positionalTitles  = m_rank->text();
     proj.remark            = m_note->toPlainText();
 
-    proj.projectName = m_name->text();
+    proj.projectName = m_proj->text();
 
     ProjectManager::EvalTypes t;
     t |= (m_type1->isChecked() ? ProjectManager::Requirements : ProjectManager::None);
@@ -115,19 +117,21 @@ ProjectInfo CreateProjWidget::editedProjInfo() const
 void CreateProjWidget::setProjectInfo(ProjectInfo *info)
 {
     m_projInfo = info;
-    m_taskName->setText(info->taskName);
+    m_task->setText(info->taskName);
     QDateTime time = QDateTime::fromTime_t(info->estimateTime.toUInt());
-    m_evalTime->setDateTime(time);
-    m_evalPurpose->setText(info->estimateObjective);
-    m_evalUnit->setText(info->estimateDept);
-    m_evalCrew->setText(info->estimatePerson);
+    m_time->setDateTime(time);
+    m_purpose->setText(info->estimateObjective);
+    m_unit->setText(info->estimateDept);
+    m_crew->setText(info->estimatePerson);
     m_rank->setText(info->positionalTitles);
     m_note->setPlainText(info->remark);
-    m_name->setText(info->projectName);
+    m_proj->setText(info->projectName);
+
     ProjectManager::EvalTypes types = ProjectManager::evalTypes(*info);
+
     m_type1->setChecked((types & ProjectManager::Requirements) == ProjectManager::Requirements);
-    m_type1->setChecked((types & ProjectManager::SchemeOptimization) == ProjectManager::SchemeOptimization);
-    m_type1->setChecked((types & ProjectManager::OverallEfficiency) == ProjectManager::OverallEfficiency);
+    m_type2->setChecked((types & ProjectManager::SchemeOptimization) == ProjectManager::SchemeOptimization);
+    m_type3->setChecked((types & ProjectManager::OverallEfficiency) == ProjectManager::OverallEfficiency);
 }
 
 void CreateProjWidget::initWindow()
@@ -139,51 +143,70 @@ void CreateProjWidget::initWindow()
     setModal(true);
     setWindowFlags(Qt::Dialog);
     setWindowFlag(Qt::WindowContextHelpButtonHint, false);
-    resize(400, 600);
+    setFixedSize(400, 600);
 }
 
 void CreateProjWidget::initWidgets()
 {
     m_summary = new QLabel(this);
     m_summary->setText("项目概要:");
-    m_taskName = new LineEdit(this);
-    m_taskName->setPlaceholderText("任务名称");
-    m_evalTime    = new DateTimeEdit(this);
-    m_evalPurpose = new LineEdit(this);
-    m_evalPurpose->setPlaceholderText("评估目的");
-    m_evalUnit = new LineEdit(this);
-    m_evalUnit->setPlaceholderText("评估单位");
-    m_evalCrew = new LineEdit(this);
-    m_evalCrew->setPlaceholderText("评估人员");
+    m_task = new LineEdit(this);
+    m_task->setPlaceholderText("任务名称");
+    m_time    = new DateTimeEdit(this);
+    m_purpose = new LineEdit(this);
+    m_purpose->setPlaceholderText("评估目的");
+    m_unit = new LineEdit(this);
+    m_unit->setPlaceholderText("评估单位");
+    m_crew = new LineEdit(this);
+    m_crew->setPlaceholderText("评估人员");
     m_rank = new LineEdit(this);
     m_rank->setPlaceholderText("职称");
     m_note = new TextEdit(this);
     m_note->setPlaceholderText("备注");
 
+    m_taskLabel = new QLabel(this);
+    m_taskLabel->setText("任务名称:");
+    m_timeLabel = new QLabel(this);
+    m_timeLabel->setText("评估时间:");
+    m_purposeLabel = new QLabel(this);
+    m_purposeLabel->setText("评估目的:");
+    m_unitLabel = new QLabel(this);
+    m_unitLabel->setText("评估单位:");
+    m_crewLabel = new QLabel(this);
+    m_crewLabel->setText("评估人员:");
+    m_rankLabel = new QLabel(this);
+    m_rankLabel->setText("职称:");
+    m_noteLabel = new QLabel(this);
+    m_noteLabel->setText("备注:");
+
     m_separator = new QWidget(this);
     m_separator->setFixedHeight(1);
     m_separator->setStyleSheet("background-color:#dddddd");
 
-    m_nameLabel = new QLabel(this);
-    m_nameLabel->setText("项目名称:");
-    m_name = new LineEdit(this);
-    m_name->setPlaceholderText("请输入项目名称");
+    m_projLabel = new QLabel(this);
+    m_projLabel->setText("项目名称:");
+    m_proj = new LineEdit(this);
+    m_proj->setPlaceholderText("请输入项目名称");
     m_typeLabel = new QLabel(this);
     m_typeLabel->setText("评估类型:");
     m_type1 = new CheckBox(EngineerInfo::nameOfEvalType(EngineerInfo::Requirements), this);
     m_type2 = new CheckBox(EngineerInfo::nameOfEvalType(EngineerInfo::SchemeOptimization), this);
     m_type3 = new CheckBox(EngineerInfo::nameOfEvalType(EngineerInfo::OverallEfficiency), this);
 
+    m_edit    = new PushButton("修改", this);
     m_confirm = new PushButton("创建", this);
     m_cancel  = new PushButton("取消", this);
 }
 
 void CreateProjWidget::initLayout()
 {
+    int minEditWidth = 220;
+
     // 总体布局
     m_layout = new QVBoxLayout(this);
     m_layout->setContentsMargins(50, 20, 50, 20);
-    m_summaryLayout = new QVBoxLayout();
+    m_layout->addWidget(m_summary);
+    m_summaryLayout = new QGridLayout();
     m_layout->addLayout(m_summaryLayout);
     m_layout->addWidget(m_separator);
     m_projLayout = new QGridLayout();
@@ -192,19 +215,37 @@ void CreateProjWidget::initLayout()
     m_layout->addLayout(m_btnLayout);
 
     // 项目概要布局
-    m_summaryLayout->addWidget(m_summary);
-    m_summaryLayout->addWidget(m_taskName);
-    m_summaryLayout->addWidget(m_evalTime);
-    m_summaryLayout->addWidget(m_evalPurpose);
-    m_summaryLayout->addWidget(m_evalUnit);
-    m_summaryLayout->addWidget(m_evalCrew);
-    m_summaryLayout->addWidget(m_rank);
-    m_summaryLayout->addWidget(m_note);
+    m_task->setMinimumWidth(minEditWidth);
+    m_time->setMinimumWidth(minEditWidth);
+    m_purpose->setMinimumWidth(minEditWidth);
+    m_unit->setMinimumWidth(minEditWidth);
+    m_crew->setMinimumWidth(minEditWidth);
+    m_rank->setMinimumWidth(minEditWidth);
+    m_note->setMinimumWidth(minEditWidth);
+    m_noteLabel->setContentsMargins(0, 10, 0, 10);
+
+    m_summaryLayout->setMargin(10);
+    m_summaryLayout->addWidget(m_taskLabel, 1, 0, 1, 1, Qt::AlignRight);
+    m_summaryLayout->addWidget(m_timeLabel, 2, 0, 1, 1, Qt::AlignRight);
+    m_summaryLayout->addWidget(m_purposeLabel, 3, 0, 1, 1, Qt::AlignRight);
+    m_summaryLayout->addWidget(m_unitLabel, 4, 0, 1, 1, Qt::AlignRight);
+    m_summaryLayout->addWidget(m_crewLabel, 5, 0, 1, 1, Qt::AlignRight);
+    m_summaryLayout->addWidget(m_rankLabel, 6, 0, 1, 1, Qt::AlignRight);
+    m_summaryLayout->addWidget(m_noteLabel, 7, 0, 1, 1, Qt::AlignRight | Qt::AlignTop);
+
+    m_summaryLayout->addWidget(m_task, 1, 1, 1, 1, Qt::AlignLeft);
+    m_summaryLayout->addWidget(m_time, 2, 1, 1, 1, Qt::AlignLeft);
+    m_summaryLayout->addWidget(m_purpose, 3, 1, 1, 1, Qt::AlignLeft);
+    m_summaryLayout->addWidget(m_unit, 4, 1, 1, 1, Qt::AlignLeft);
+    m_summaryLayout->addWidget(m_crew, 5, 1, 1, 1, Qt::AlignLeft);
+    m_summaryLayout->addWidget(m_rank, 6, 1, 1, 1, Qt::AlignLeft);
+    m_summaryLayout->addWidget(m_note, 7, 1, 1, 1, Qt::AlignLeft);
 
     // 项目信息布局
-    m_projLayout->addWidget(m_nameLabel, 0, 0, 1, 1, Qt::AlignLeft);
-    m_projLayout->addWidget(m_name, 0, 1, 1, 5, Qt::AlignLeft);
-    m_name->setMinimumWidth(200);
+    m_projLayout->setMargin(10);
+    m_proj->setMinimumWidth(minEditWidth);
+    m_projLayout->addWidget(m_projLabel, 0, 0, 1, 1, Qt::AlignLeft);
+    m_projLayout->addWidget(m_proj, 0, 1, 1, 5, Qt::AlignLeft);
     m_projLayout->addWidget(new QWidget(this), 1, 1, 4, 1, Qt::AlignLeft);
     m_projLayout->addWidget(m_typeLabel, 4, 0, 1, 1, Qt::AlignLeft);
     m_projLayout->addWidget(m_type1, 4, 1, 1, 5, Qt::AlignLeft);
@@ -213,35 +254,28 @@ void CreateProjWidget::initLayout()
 
     // 按钮布局
     m_btnLayout->addStretch();
+    m_btnLayout->addWidget(m_edit);
     m_btnLayout->addWidget(m_confirm);
     m_btnLayout->addWidget(m_cancel);
 }
 
 void CreateProjWidget::connectSignalsAndSlots()
 {
-    connect(m_taskName, &LineEdit::textChanged, this, &CreateProjWidget::slotTextChanged);
-    connect(m_evalPurpose, &LineEdit::textChanged, this, &CreateProjWidget::slotTextChanged);
-    connect(m_evalUnit, &LineEdit::textChanged, this, &CreateProjWidget::slotTextChanged);
-    connect(m_evalCrew, &LineEdit::textChanged, this, &CreateProjWidget::slotTextChanged);
+    connect(m_task, &LineEdit::textChanged, this, &CreateProjWidget::slotTextChanged);
+    connect(m_purpose, &LineEdit::textChanged, this, &CreateProjWidget::slotTextChanged);
+    connect(m_unit, &LineEdit::textChanged, this, &CreateProjWidget::slotTextChanged);
+    connect(m_crew, &LineEdit::textChanged, this, &CreateProjWidget::slotTextChanged);
     connect(m_rank, &LineEdit::textChanged, this, &CreateProjWidget::slotTextChanged);
     connect(m_note, &TextEdit::textChanged, this, &CreateProjWidget::slotTextChanged);
-    connect(m_name, &LineEdit::textChanged, this, &CreateProjWidget::slotTextChanged);
+    connect(m_proj, &LineEdit::textChanged, this, &CreateProjWidget::slotTextChanged);
     connect(m_type1, &CheckBox::stateChanged, this, &CreateProjWidget::slotCheckBoxChanged);
     connect(m_type2, &CheckBox::stateChanged, this, &CreateProjWidget::slotCheckBoxChanged);
     connect(m_type3, &CheckBox::stateChanged, this, &CreateProjWidget::slotCheckBoxChanged);
-    connect(m_confirm, &PushButton::clicked, this, &CreateProjWidget::slotCreateClicked);
+    connect(m_edit, &PushButton::clicked, this, &CreateProjWidget::slotEditClicked);
+    connect(m_confirm, &PushButton::clicked, this, &CreateProjWidget::slotConfirmClicked);
     connect(m_cancel, &PushButton::clicked, this, &CreateProjWidget::slotCancelClicked);
 }
 
-void CreateProjWidget::updateCreateButtonState()
-{
-    bool summaryValid = false;
-    bool nameValid;
-    bool typeValid;
-
-    m_confirm->setEnabled(summaryValid && nameValid && typeValid);
-}
-
 void CreateProjWidget::slotTextChanged()
 {
     LineEdit *lineEdit = dynamic_cast<LineEdit *>(sender());
@@ -252,16 +286,26 @@ void CreateProjWidget::slotTextChanged()
 
 void CreateProjWidget::slotCheckBoxChanged() { }
 
-void CreateProjWidget::slotCreateClicked()
+void CreateProjWidget::slotEditClicked()
+{
+    setMode(Update);
+}
+
+void CreateProjWidget::slotConfirmClicked()
 {
     ProjectInfo p = editedProjInfo();
     qDebug() << __FUNCTION__ << p.taskName << p.estimateTime << p.estimateObjective << p.estimateDept
              << p.estimatePerson << p.positionalTitles << p.remark << p.projectName << p.estimateType;
 
-    emit signalCreate();
+    emit signalConfirm();
 }
 
 void CreateProjWidget::slotCancelClicked()
 {
-    close();
+    if (m_mode == Update) {
+        setMode(Info);
+        setProjectInfo(m_projInfo);
+    } else {
+        close();
+    }
 }

+ 24 - 14
QFD/widgets/CreateProjWidget.h

@@ -40,19 +40,19 @@ public:
     void setProjectInfo(ProjectInfo *info);
 
 signals:
-    void signalCreate();
+    void signalConfirm();
 
 private:
     void initWindow();
     void initWidgets();
     void initLayout();
     void connectSignalsAndSlots();
-    void updateCreateButtonState();
 
 private slots:
     void slotTextChanged();
     void slotCheckBoxChanged();
-    void slotCreateClicked();
+    void slotEditClicked();
+    void slotConfirmClicked();
     void slotCancelClicked();
 
 private:
@@ -61,32 +61,42 @@ private:
     ProjectInfo *m_projInfo = nullptr;
 
     // 项目概要
-    QLabel *m_summary        = nullptr;  // 项目概要
-    LineEdit *m_taskName     = nullptr;  // 任务名称
-    DateTimeEdit *m_evalTime = nullptr;  // 评估时间
-    LineEdit *m_evalPurpose  = nullptr;  // 评估目的
-    LineEdit *m_evalUnit     = nullptr;  // 评估单位
-    LineEdit *m_evalCrew     = nullptr;  // 评估人员
-    LineEdit *m_rank         = nullptr;  // 职称
-    TextEdit *m_note         = nullptr;  // 备注
+
+    QLabel *m_summary    = nullptr;  // 项目概要
+    LineEdit *m_task     = nullptr;  // 任务名称
+    DateTimeEdit *m_time = nullptr;  // 评估时间
+    LineEdit *m_purpose  = nullptr;  // 评估目的
+    LineEdit *m_unit     = nullptr;  // 评估单位
+    LineEdit *m_crew     = nullptr;  // 评估人员
+    LineEdit *m_rank     = nullptr;  // 职称
+    TextEdit *m_note     = nullptr;  // 备注
+
+    QLabel *m_taskLabel    = nullptr;
+    QLabel *m_timeLabel    = nullptr;
+    QLabel *m_purposeLabel = nullptr;
+    QLabel *m_unitLabel    = nullptr;
+    QLabel *m_crewLabel    = nullptr;
+    QLabel *m_rankLabel    = nullptr;
+    QLabel *m_noteLabel    = nullptr;
 
     QWidget *m_separator = nullptr;  // 分隔线
 
     // 项目信息
-    QLabel *m_nameLabel = nullptr;
-    LineEdit *m_name    = nullptr;
+    QLabel *m_projLabel = nullptr;
+    LineEdit *m_proj    = nullptr;
     QLabel *m_typeLabel = nullptr;
     CheckBox *m_type1   = nullptr;
     CheckBox *m_type2   = nullptr;
     CheckBox *m_type3   = nullptr;
 
     // 按钮
+    PushButton *m_edit    = nullptr;
     PushButton *m_confirm = nullptr;
     PushButton *m_cancel  = nullptr;
 
     // 布局
     QVBoxLayout *m_layout        = nullptr;
-    QVBoxLayout *m_summaryLayout = nullptr;
+    QGridLayout *m_summaryLayout = nullptr;
     QGridLayout *m_projLayout    = nullptr;
     QHBoxLayout *m_btnLayout     = nullptr;
 };

+ 67 - 49
QFD/widgets/ProjectListWidget.cpp

@@ -15,7 +15,7 @@
 
 #include <QDebug>
 
-ProjectListItemWidget::ProjectListItemWidget(int index, QWidget *parent) : QWidget(parent), m_index(index)
+ProjectListItemWidget::ProjectListItemWidget(QWidget *parent) : QWidget(parent)
 {
     initWidgets();
     initLayout();
@@ -42,15 +42,15 @@ void ProjectListItemWidget::initWidgets()
     m_info->setObjectName("info");
     m_open = new PushButton("打开", NEWFLICON(QFDIcon, Open), this);
     m_open->setObjectName("open");
-    m_edit = new PushButton("修改", NEWFLICON(FluentIcon, EDIT), this);
-    m_edit->setObjectName("edit");
-
-    setStyleSheet("#name {color:#1196db; font-size:15px; font:bold}"
-                  "#time {color:gray}"
-                  "#taskLabel {color: gray;}"
-                  "#task {color: gray;}"
-                  "#typeLabel {color: gray;}"
-                  "#type {color: gray;}");
+    m_delete = new PushButton("删除", NEWFLICON(FluentIcon, DELETE), this);
+    m_delete->setObjectName("delete");
+
+    setStyleSheet("#name {color:#1196db; font-size:17px; font:bold}"
+                  "#time {color:gray; font-size:12px;}"
+                  "#taskLabel {color: gray; font-size:14px;}"
+                  "#task {color: gray; font-size:14px;}"
+                  "#typeLabel {color: gray; font-size:14px;}"
+                  "#type {color: gray; font-size:14px;}");
 }
 
 void ProjectListItemWidget::initLayout()
@@ -94,20 +94,21 @@ void ProjectListItemWidget::initLayout()
     // 按钮
     m_buttonLayout->addStretch();
     m_buttonLayout->addWidget(m_info);
-    m_buttonLayout->addWidget(m_edit);
     m_buttonLayout->addWidget(m_open);
+    m_buttonLayout->addWidget(m_delete);
 }
 
 void ProjectListItemWidget::connectSignalsAndSlots()
 {
     connect(m_info, &PushButton::clicked, this, &ProjectListItemWidget::sigInfo);
     connect(m_open, &PushButton::clicked, this, &ProjectListItemWidget::sigOpen);
-    connect(m_edit, &PushButton::clicked, this, &ProjectListItemWidget::sigEdit);
+    connect(m_delete, &PushButton::clicked, this, &ProjectListItemWidget::sigDelete);
 }
 
-void ProjectListItemWidget::setInfo(ProjectInfo *info)
+void ProjectListItemWidget::setProj(ProjectInfo *info)
 {
     m_proj = info;
+
     if (info == nullptr) {
         return;
     }
@@ -115,7 +116,7 @@ void ProjectListItemWidget::setInfo(ProjectInfo *info)
     m_name->setText(info->projectName);
 
     QDateTime t = QDateTime::fromTime_t(info->estimateTime.toUInt());
-    m_time->setText(t.toString("yyyy-M-d"));
+    m_time->setText(t.toString("yyyy-M-d H:mm"));
 
     m_task->setText(info->taskName);
 
@@ -130,11 +131,6 @@ void ProjectListItemWidget::setInfo(ProjectInfo *info)
     m_type->setText(tStr);
 }
 
-int ProjectListItemWidget::index() const
-{
-    return m_index;
-}
-
 ProjectInfo *ProjectListItemWidget::proj() const
 {
     return m_proj;
@@ -147,29 +143,61 @@ ProjectListWidget::ProjectListWidget(QWidget *parent) : QWidget(parent)
     connectSiganlsAndSlots();
 }
 
-void ProjectListWidget::showProjects(QList<ProjectInfo *> list)
+void ProjectListWidget::setProjects(QList<ProjectInfo *> list)
 {
+    m_projList.clear();
     m_listWidget->clear();
 
-    for (int i = 0; i < list.count(); i++) {
-        ProjectListItemWidget *w = new ProjectListItemWidget(i, m_listWidget);
-        w->setInfo(list[i]);
-        connect(w, &ProjectListItemWidget::sigInfo, this, &ProjectListWidget::slotInfo);
-        connect(w, &ProjectListItemWidget::sigOpen, this, &ProjectListWidget::slotOpen);
-        connect(w, &ProjectListItemWidget::sigEdit, this, &ProjectListWidget::slotEdit);
+    for (auto proj : list) {
+        addProject(proj);
+    }
+}
 
-        QListWidgetItem *item = new QListWidgetItem(m_listWidget);
-        item->setSizeHint(QSize(300, 135));
-        m_listWidget->setItemWidget(item, w);
+void ProjectListWidget::showLast() const
+{
+    if (m_projList.count() > 0) {
+        m_listWidget->setCurrentRow(m_projList.count() - 1);
     }
 }
 
-ProjectListItemWidget *ProjectListWidget::itemWidget(QListWidgetItem *item) const
+void ProjectListWidget::addProject(ProjectInfo *proj)
+{
+    m_projList.append(proj);
+
+    ProjectListItemWidget *w = new ProjectListItemWidget(m_listWidget);
+    w->setProj(proj);
+    connect(w, &ProjectListItemWidget::sigInfo, this, &ProjectListWidget::slotInfo);
+    connect(w, &ProjectListItemWidget::sigOpen, this, &ProjectListWidget::slotOpen);
+    connect(w, &ProjectListItemWidget::sigDelete, this, &ProjectListWidget::slotDelete);
+
+    QListWidgetItem *item = new QListWidgetItem(m_listWidget);
+    item->setSizeHint(QSize(300, 135));
+    m_listWidget->setItemWidget(item, w);
+}
+
+void ProjectListWidget::removeProject(ProjectInfo *proj)
+{
+    int index = m_projList.indexOf(proj);
+    m_listWidget->takeItem(index);
+}
+
+ProjectListItemWidget *ProjectListWidget::widgetOfItem(QListWidgetItem *item) const
 {
     QWidget *w = m_listWidget->itemWidget(item);
     return dynamic_cast<ProjectListItemWidget *>(w);
 }
 
+QListWidgetItem *ProjectListWidget::itemOfWidget(ProjectListItemWidget *widget) const
+{
+    for (int i = 0; i < m_listWidget->count(); i++) {
+        QListWidgetItem *item = m_listWidget->item(i);
+        if (m_listWidget->itemWidget(item) == widget) {
+            return item;
+        }
+    }
+    return nullptr;
+}
+
 void ProjectListWidget::initWidgets()
 {
     QPalette pal(palette());
@@ -203,45 +231,35 @@ void ProjectListWidget::connectSiganlsAndSlots()
 
 void ProjectListWidget::slotItemDoubleClicked(QListWidgetItem *item)
 {
-    qDebug() << __FUNCTION__ << __LINE__;
     ProjectListItemWidget *w = dynamic_cast<ProjectListItemWidget *>(m_listWidget->itemWidget(item));
     emit sigInfo(w->proj());
 }
 
-void ProjectListWidget::slotItemClicked(QListWidgetItem *item)
-{
-    qDebug() << __FUNCTION__ << __LINE__;
-}
+void ProjectListWidget::slotItemClicked(QListWidgetItem *item) { }
 
-void ProjectListWidget::slotCurrentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
-{
-    qDebug() << __FUNCTION__ << __LINE__;
-}
+void ProjectListWidget::slotCurrentItemChanged(QListWidgetItem *current, QListWidgetItem *previous) { }
 
-void ProjectListWidget::slotCurrentRowChanged(int currentRow)
-{
-    qDebug() << __FUNCTION__ << __LINE__;
-}
+void ProjectListWidget::slotCurrentRowChanged(int currentRow) { }
 
-void ProjectListWidget::slotItemSelectionChanged()
-{
-    qDebug() << __FUNCTION__ << __LINE__;
-}
+void ProjectListWidget::slotItemSelectionChanged() { }
 
 void ProjectListWidget::slotInfo()
 {
     ProjectListItemWidget *w = dynamic_cast<ProjectListItemWidget *>(sender());
+    itemOfWidget(w)->setSelected(true);
     emit sigInfo(w->proj());
 }
 
 void ProjectListWidget::slotOpen()
 {
     ProjectListItemWidget *w = dynamic_cast<ProjectListItemWidget *>(sender());
+    itemOfWidget(w)->setSelected(true);
     emit sigOpen(w->proj());
 }
 
-void ProjectListWidget::slotEdit()
+void ProjectListWidget::slotDelete()
 {
     ProjectListItemWidget *w = dynamic_cast<ProjectListItemWidget *>(sender());
-    emit sigEdit(w->proj());
+    itemOfWidget(w)->setSelected(true);
+    emit sigDelete(w->proj());
 }

+ 19 - 12
QFD/widgets/ProjectListWidget.h

@@ -21,17 +21,16 @@ class ProjectListItemWidget : public QWidget
 {
     Q_OBJECT
 public:
-    explicit ProjectListItemWidget(int index, QWidget *parent = nullptr);
+    explicit ProjectListItemWidget(QWidget *parent = nullptr);
 
-    void setInfo(ProjectInfo *info);
+    void setProj(ProjectInfo *info);
 
-    int index() const;
     ProjectInfo *proj() const;
 
 signals:
     void sigInfo();
     void sigOpen();
-    void sigEdit();
+    void sigDelete();
 
 private:
     void initWidgets();
@@ -39,7 +38,6 @@ private:
     void connectSignalsAndSlots();
 
 private:
-    int m_index         = 0;
     ProjectInfo *m_proj = nullptr;
 
     QLabel *m_name      = nullptr;
@@ -49,9 +47,9 @@ private:
     QLabel *m_typeLabel = nullptr;
     QLabel *m_type      = nullptr;
 
-    PushButton *m_info = nullptr;
-    PushButton *m_edit = nullptr;
-    PushButton *m_open = nullptr;
+    PushButton *m_info   = nullptr;
+    PushButton *m_open   = nullptr;
+    PushButton *m_delete = nullptr;
 
     QVBoxLayout *m_layout       = nullptr;
     QHBoxLayout *m_nameLayout   = nullptr;
@@ -67,14 +65,21 @@ class ProjectListWidget : public QWidget
 public:
     explicit ProjectListWidget(QWidget *parent = nullptr);
 
-    void showProjects(QList<ProjectInfo *> list);
+    void setProjects(QList<ProjectInfo *> list);
 
-    ProjectListItemWidget *itemWidget(QListWidgetItem *item) const;
+    void showLast() const;
+
+    void addProject(ProjectInfo *proj);
+
+    void removeProject(ProjectInfo *proj);
+
+    ProjectListItemWidget *widgetOfItem(QListWidgetItem *item) const;
+    QListWidgetItem *itemOfWidget(ProjectListItemWidget *widget) const;
 
 signals:
     void sigInfo(ProjectInfo *project);
     void sigOpen(ProjectInfo *project);
-    void sigEdit(ProjectInfo *project);
+    void sigDelete(ProjectInfo *project);
 
 private:
     void initWidgets();
@@ -91,13 +96,15 @@ private slots:
 
     void slotInfo();
     void slotOpen();
-    void slotEdit();
+    void slotDelete();
 
 signals:
 
 private:
     QVBoxLayout *m_vBoxLayout = nullptr;
     QListWidget *m_listWidget = nullptr;
+
+    QList<ProjectInfo *> m_projList;
 };
 
 #endif  // PROJECTLISTWIDGET_H

部分文件因为文件数量过多而无法显示