foldertreedelegateeditor.cpp

foldertreedelegateeditor.h
notelistdelegateeditor.cpp
notelistdelegateeditor.h
taglistdelegate.cpp
taglistdelegate.h
develop
zhangshuoshuo 1 month ago
parent 320ddb1d96
commit c6d521d989

@ -1,115 +1,121 @@
#include "foldertreedelegateeditor.h"
#include <QHBoxLayout>
#include <QLabel>
#include <QPainter>
#include <QDebug>
#include <QTreeView>
#include <QMouseEvent>
#include "pushbuttontype.h"
#include "nodetreemodel.h"
#include "nodetreeview.h"
#include "notelistview.h"
#include "labeledittype.h"
#include "fontloader.h"
#include "foldertreedelegateeditor.h" // 包含FolderTreeDelegateEditor类的声明
#include <QHBoxLayout> // 包含水平布局管理器
#include <QLabel> // 包含标签控件
#include <QPainter> // 包含绘图器
#include <QDebug> // 包含调试输出
#include <QTreeView> // 包含树视图控件
#include <QMouseEvent> // 包含鼠标事件
#include "pushbuttontype.h" // 包含自定义按钮类型
#include "nodetreemodel.h" // 包含节点树模型
#include "nodetreeview.h" // 包含节点树视图
#include "notelistview.h" // 包含笔记列表视图
#include "labeledittype.h" // 包含标签编辑类型
#include "fontloader.h" // 包含字体加载器
// FolderTreeDelegateEditor构造函数
FolderTreeDelegateEditor::FolderTreeDelegateEditor(QTreeView *view,
const QStyleOptionViewItem &option,
const QModelIndex &index, QListView *listView,
QWidget *parent)
: QWidget(parent),
m_option(option),
m_index(index),
#ifdef __APPLE__
: QWidget(parent), // 调用QWidget构造函数
m_option(option), // 初始化选项
m_index(index), // 初始化索引
#ifdef __APPLE__ // 如果是苹果系统
m_displayFont(QFont(QStringLiteral("SF Pro Text")).exactMatch()
? QStringLiteral("SF Pro Text")
: QStringLiteral("Roboto")),
#elif _WIN32
? QStringLiteral("SF Pro Text") // 使用系统字体
: QStringLiteral("Roboto")), // 否则使用Roboto字体
#elif _WIN32 // 如果是Windows系统
m_displayFont(QFont(QStringLiteral("Segoe UI")).exactMatch() ? QStringLiteral("Segoe UI")
: QStringLiteral("Roboto")),
#else
#else // 其他系统
m_displayFont(QStringLiteral("Roboto")),
#endif
#ifdef __APPLE__
m_titleFont(m_displayFont, 13, QFont::DemiBold),
#ifdef __APPLE__ // 如果是苹果系统
m_titleFont(m_displayFont, 13, QFont::DemiBold), // 设置标题字体
#else
m_titleFont(m_displayFont, 10, QFont::DemiBold),
m_titleFont(m_displayFont, 10, QFont::DemiBold), // 设置标题字体
#endif
m_titleColor(26, 26, 26),
m_titleSelectedColor(255, 255, 255),
m_activeColor(68, 138, 201),
m_hoverColor(207, 207, 207),
m_folderIconColor(68, 138, 201),
m_view(view),
m_listView(listView),
m_theme(Theme::Light)
m_titleColor(26, 26, 26), // 设置标题颜色
m_titleSelectedColor(255, 255, 255), // 设置选中标题颜色
m_activeColor(68, 138, 201), // 设置活动颜色
m_hoverColor(207, 207, 207), // 设置悬浮颜色
m_folderIconColor(68, 138, 201), // 设置文件夹图标颜色
m_view(view), // 初始化视图
m_listView(listView), // 初始化列表视图
m_theme(Theme::Light) // 初始化主题为浅色
{
setContentsMargins(0, 0, 0, 0);
auto layout = new QHBoxLayout(this);
layout->setContentsMargins(10, 0, 0, 0);
layout->setSpacing(0);
setLayout(layout);
m_expandIcon = new QLabel(this);
m_expandIcon->setMinimumSize({ 11, 11 });
m_expandIcon->setMaximumSize({ 11, 11 });
setContentsMargins(0, 0, 0, 0); // 设置内容边距
auto layout = new QHBoxLayout(this); // 创建水平布局
layout->setContentsMargins(10, 0, 0, 0); // 设置布局边距
layout->setSpacing(0); // 设置布局间隔
setLayout(layout); // 设置布局
m_expandIcon = new QLabel(this); // 创建展开图标标签
m_expandIcon->setMinimumSize({ 11, 11 }); // 设置最小尺寸
m_expandIcon->setMaximumSize({ 11, 11 }); // 设置最大尺寸
// 根据索引数据判断是否可展开,并相应地添加布局间隔
if (m_index.data(NodeItem::Roles::IsExpandable).toBool()) {
if (!m_view->isExpanded(m_index)) {
layout->addSpacing(2);
}
}
#ifdef __APPLE__
int iconPointSizeOffset = 0;
#ifdef __APPLE__ // 如果是苹果系统
int iconPointSizeOffset = 0; // 图标点大小偏移量
#else
int iconPointSizeOffset = -4;
int iconPointSizeOffset = -4; // 图标点大小偏移量
#endif
m_expandIcon->setFont(FontLoader::getInstance().loadFont("Font Awesome 6 Free Solid", "",
10 + iconPointSizeOffset));
10 + iconPointSizeOffset)); // 加载字体
m_expandIcon->setScaledContents(true);
layout->addWidget(m_expandIcon);
m_expandIcon->setScaledContents(true); // 设置缩放内容
layout->addWidget(m_expandIcon); // 将展开图标添加到布局
// 如果索引不可展开或已展开,添加布局间隔
if (!m_index.data(NodeItem::Roles::IsExpandable).toBool()
|| (m_index.data(NodeItem::Roles::IsExpandable).toBool() && m_view->isExpanded(m_index))) {
layout->addSpacing(2);
}
m_folderIcon = new PushButtonType(parent);
m_folderIcon->setMaximumSize({ 19, 20 });
m_folderIcon->setMinimumSize({ 19, 20 });
m_folderIcon->setIconSize(QSize(19, 20));
QFont materialSymbols("Material Symbols Outlined", 16 + iconPointSizeOffset);
m_folderIcon->setFont(materialSymbols);
m_folderIcon->setText(u8"\ue2c7"); // folder
layout->addWidget(m_folderIcon);
layout->addSpacing(5);
m_folderIcon = new PushButtonType(parent); // 创建文件夹图标按钮
m_folderIcon->setMaximumSize({ 19, 20 }); // 设置最大尺寸
m_folderIcon->setMinimumSize({ 19, 20 }); // 设置最小尺寸
m_folderIcon->setIconSize(QSize(19, 20)); // 设置图标尺寸
QFont materialSymbols("Material Symbols Outlined", 16 + iconPointSizeOffset); // 加载字体
m_folderIcon->setFont(materialSymbols); // 设置字体
m_folderIcon->setText(u8"\ue2c7"); // 设置文本为文件夹图标
layout->addWidget(m_folderIcon); // 将文件夹图标添加到布局
layout->addSpacing(5); // 添加布局间隔
m_label = new LabelEditType(this);
m_label->setFont(m_titleFont);
QSizePolicy labelPolicy;
labelPolicy.setVerticalPolicy(QSizePolicy::Expanding);
labelPolicy.setHorizontalPolicy(QSizePolicy::Expanding);
m_label->setSizePolicy(labelPolicy);
m_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
connect(m_label, &LabelEditType::editingStarted, this, [this] {
auto tree_view = dynamic_cast<NodeTreeView *>(m_view);
tree_view->setIsEditing(true);
});
connect(m_label, &LabelEditType::editingFinished, this, [this](const QString &label) {
auto tree_view = dynamic_cast<NodeTreeView *>(m_view);
tree_view->onRenameFolderFinished(label);
tree_view->setIsEditing(false);
m_label = new LabelEditType(this); // 创建标签编辑类型
m_label->setFont(m_titleFont); // 设置字体
QSizePolicy labelPolicy; // 创建尺寸策略
labelPolicy.setVerticalPolicy(QSizePolicy::Expanding); // 设置垂直策略为扩展
labelPolicy.setHorizontalPolicy(QSizePolicy::Expanding); // 设置水平策略为扩展
m_label->setSizePolicy(labelPolicy); // 设置尺寸策略
m_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); // 设置对齐方式
connect(m_label, &LabelEditType::editingStarted, this, [this] { // 连接编辑开始信号
auto tree_view = dynamic_cast<NodeTreeView *>(m_view); // 转换视图为NodeTreeView类型
tree_view->setIsEditing(true); // 设置编辑状态为真
});
connect(dynamic_cast<NodeTreeView *>(m_view), &NodeTreeView::renameFolderRequested, m_label,
&LabelEditType::openEditor);
layout->addWidget(m_label);
layout->addSpacing(5);
m_contextButton = new PushButtonType(parent);
m_contextButton->setMaximumSize({ 33, 25 });
m_contextButton->setMinimumSize({ 33, 25 });
m_contextButton->setCursor(QCursor(Qt::PointingHandCursor));
m_contextButton->setFocusPolicy(Qt::TabFocus);
if (m_view->selectionModel()->isSelected(m_index)) {
connect(m_label, &LabelEditType::editingFinished, this,
[this](const QString &label) { // 连接编辑结束信号
auto tree_view = dynamic_cast<NodeTreeView *>(m_view); // 转换视图为NodeTreeView类型
tree_view->onRenameFolderFinished(label); // 重命名文件夹
tree_view->setIsEditing(false); // 设置编辑状态为假
});
connect(dynamic_cast<NodeTreeView *>(m_view), &NodeTreeView::renameFolderRequested,
m_label, // 连接重命名请求信号
&LabelEditType::openEditor); // 打开编辑器
layout->addWidget(m_label); // 将标签添加到布局
layout->addSpacing(5); // 添加布局间隔
m_contextButton = new PushButtonType(parent); // 创建上下文按钮
m_contextButton->setMaximumSize({ 33, 25 }); // 设置最大尺寸
m_contextButton->setMinimumSize({ 33, 25 }); // 设置最小尺寸
m_contextButton->setCursor(QCursor(Qt::PointingHandCursor)); // 设置鼠标指针为手形
m_contextButton->setFocusPolicy(Qt::TabFocus); // 设置焦点策略为Tab焦点
if (m_view->selectionModel()->isSelected(m_index)) { // 如果索引被选中
m_contextButton->setStyleSheet(QStringLiteral(R"(QPushButton { )"
R"( border: none; )"
R"( padding: 0px; )"

@ -1,52 +1,55 @@
#ifndef FOLDERTREEDELEGATEEDITOR_H
#ifndef FOLDERTREEDELEGATEEDITOR_H // 头文件保护
#define FOLDERTREEDELEGATEEDITOR_H
#include <QWidget>
#include <QStyleOptionViewItem>
#include <QModelIndex>
#include <QFont>
#include "editorsettingsoptions.h"
#include <QWidget> // 包含QWidget类
#include <QStyleOptionViewItem> // 包含样式选项视图项
#include <QModelIndex> // 包含模型索引
#include <QFont> // 包含字体类
#include "editorsettingsoptions.h" // 包含编辑器设置选项
class QTreeView;
class QLabel;
class PushButtonType;
class LabelEditType;
class QListView;
class QTreeView; // 前向声明QTreeView类
class QLabel; // 前向声明QLabel类
class PushButtonType; // 前向声明PushButtonType类
class LabelEditType; // 前向声明LabelEditType类
class QListView; // 前向声明QListView类
class FolderTreeDelegateEditor : public QWidget
class FolderTreeDelegateEditor : public QWidget // 继承自QWidget
{
Q_OBJECT
public:
explicit FolderTreeDelegateEditor(QTreeView *view, const QStyleOptionViewItem &option,
const QModelIndex &index, QListView *listView,
QWidget *parent = nullptr);
void setTheme(Theme::Value theme);
Q_OBJECT // 宏用于支持Qt的信号和槽机制
public
: explicit FolderTreeDelegateEditor(QTreeView *view,
const QStyleOptionViewItem &option, // 构造函数
const QModelIndex &index, QListView *listView,
QWidget *parent = nullptr);
void setTheme(Theme::Value theme); // 设置主题的方法
private:
QStyleOptionViewItem m_option;
QModelIndex m_index;
QString m_displayFont;
QFont m_titleFont;
QColor m_titleColor;
QColor m_titleSelectedColor;
QColor m_activeColor;
QColor m_hoverColor;
QColor m_folderIconColor;
QTreeView *m_view;
QListView *m_listView;
LabelEditType *m_label;
PushButtonType *m_folderIcon;
QPixmap m_expanded;
QPixmap m_notExpanded;
QLabel *m_expandIcon;
PushButtonType *m_contextButton;
Theme::Value m_theme;
void updateDelegate();
// QWidget interface
QStyleOptionViewItem m_option; // 样式选项视图项
QModelIndex m_index; // 模型索引
QString m_displayFont; // 显示字体
QFont m_titleFont; // 标题字体
QColor m_titleColor; // 标题颜色
QColor m_titleSelectedColor; // 选中标题颜色
QColor m_activeColor; // 活动颜色
QColor m_hoverColor; // 悬浮颜色
QColor m_folderIconColor; // 文件夹图标颜色
QTreeView *m_view; // 树视图
QListView *m_listView; // 列表视图
LabelEditType *m_label; // 标签编辑类型
PushButtonType *m_folderIcon; // 文件夹图标按钮
QPixmap m_expanded; // 展开的图标
QPixmap m_notExpanded; // 未展开的图标
QLabel *m_expandIcon; // 展开图标标签
PushButtonType *m_contextButton; // 上下文按钮
Theme::Value m_theme; // 主题枚举值
void updateDelegate(); // 更新委托的方法
// QWidget接口
protected:
virtual void paintEvent(QPaintEvent *event) override;
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
virtual void paintEvent(QPaintEvent *event) override; // 重写绘画事件
virtual void mouseDoubleClickEvent(QMouseEvent *event) override; // 重写鼠标双击事件
};
#endif // FOLDERTREEDELEGATEEDITOR_H
#endif // FOLDERTREEDELEGATEEDITOR_H

@ -1,22 +1,22 @@
#include "notelistdelegateeditor.h"
#include <QPainter>
#include <QEvent>
#include <QDebug>
#include <QApplication>
#include <QtMath>
#include <QPainterPath>
#include <QScrollBar>
#include <QDragEnterEvent>
#include <QMimeData>
#include "notelistmodel.h"
#include "noteeditorlogic.h"
#include "tagpool.h"
#include "nodepath.h"
#include "notelistdelegate.h"
#include "taglistview.h"
#include "taglistmodel.h"
#include "taglistdelegate.h"
#include "fontloader.h"
#include "notelistdelegateeditor.h" // 包含NoteListDelegateEditor类的声明
#include <QPainter> // 包含QPainter类用于绘图
#include <QEvent> // 包含QEvent类用于处理事件
#include <QDebug> // 包含QDebug类用于调试输出
#include <QApplication> // 包含QApplication类访问应用程序对象
#include <QtMath> // 包含数学相关函数
#include <QPainterPath> // 包含QPainterPath类用于绘制路径
#include <QScrollBar> // 包含QScrollBar类用于滚动条
#include <QDragEnterEvent> // 包含拖拽进入事件
#include <QMimeData> // 包含MIME数据类
#include "notelistmodel.h" // 包含笔记列表模型
#include "noteeditorlogic.h" // 包含笔记编辑逻辑
#include "tagpool.h" // 包含标签池
#include "nodepath.h" // 包含节点路径
#include "notelistdelegate.h" // 包含笔记列表委托
#include "taglistview.h" // 包含标签列表视图
#include "taglistmodel.h" // 包含标签列表模型
#include "taglistdelegate.h" // 包含标签列表委托
#include "fontloader.h" // 包含字体加载器
NoteListDelegateEditor::NoteListDelegateEditor(const NoteListDelegate *delegate, NoteListView *view,
const QStyleOptionViewItem &option,
@ -144,48 +144,67 @@ NoteListDelegateEditor::~NoteListDelegateEditor()
void NoteListDelegateEditor::paintBackground(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
// 获取当前控件的尺寸
auto bufferSize = rect().size();
// 创建一个与控件尺寸相同的QPixmap对象初始填充为透明
QPixmap buffer{ bufferSize };
buffer.fill(Qt::transparent);
// 创建一个用于绘制的QPainter对象
QPainter bufferPainter{ &buffer };
// 设置抗锯齿和平滑转换的渲染提示
bufferPainter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
// 获取绘制区域的矩形
QRect bufferRect = buffer.rect();
// 尝试将视图模型转换为NoteListModel类型
auto model = dynamic_cast<NoteListModel *>(m_view->model());
// 如果模型存在,并且存在被固定的笔记,并且当前索引是第一个被固定的或未被固定的笔记
if (model && model->hasPinnedNote()
&& (model->isFirstPinnedNote(index) || model->isFirstUnpinnedNote(index))) {
&& &(model->isFirstPinnedNote(index) || model->isFirstUnpinnedNote(index))) {
// 如果存在被固定的笔记,并且未被折叠,并且当前索引是第一个未被固定的笔记
int fifthYOffset = 0;
if (model && model->hasPinnedNote() && !m_view->isPinnedNotesCollapsed()
&& model->isFirstUnpinnedNote(index)) {
fifthYOffset = NoteListConstant::lastPinnedToUnpinnedHeader;
}
// 调整bufferRect的Y坐标以添加额外的偏移量
bufferRect.setY(bufferRect.y() + 25 + fifthYOffset);
}
// 获取笔记是否被固定的数据
auto isPinned = index.data(NoteListModel::NoteIsPinned).toBool();
// 如果当前索引被选中
if (m_view->selectionModel()->isSelected(index)) {
// 根据应用程序的状态设置背景颜色
if (qApp->applicationState() == Qt::ApplicationActive) {
// 如果控件处于活动状态,设置为活动颜色
if (m_isActive) {
bufferPainter.fillRect(bufferRect, QBrush(m_ActiveColor));
m_tagListView->setBackground(m_ActiveColor);
} else {
// 否则设置为非活动颜色
bufferPainter.fillRect(bufferRect, QBrush(m_notActiveColor));
m_tagListView->setBackground(m_notActiveColor);
}
} else if (qApp->applicationState() == Qt::ApplicationInactive) {
// 如果应用程序处于非活动状态,设置为非活动颜色
bufferPainter.fillRect(bufferRect, QBrush(m_applicationInactiveColor));
m_tagListView->setBackground(m_applicationInactiveColor);
}
} else if (underMouseC()) {
} else if (underMouseC()) { // 如果鼠标在控件下
// 如果视图正在拖拽
if (m_view->isDragging()) {
// 如果笔记被固定,绘制特定颜色的矩形
if (isPinned) {
auto rect = bufferRect;
rect.setTop(rect.bottom() - 5);
bufferPainter.fillRect(rect, QBrush("#d6d5d5"));
}
} else {
// 否则,绘制悬浮颜色的矩形
bufferPainter.fillRect(bufferRect, QBrush(m_hoverColor));
m_tagListView->setBackground(m_hoverColor);
}
} else {
// 如果被固定的笔记被折叠,并且当前笔记未被固定
if (m_view->isPinnedNotesCollapsed() && !isPinned) {
bufferPainter.fillRect(bufferRect, QBrush(m_defaultColor));
m_tagListView->setBackground(m_defaultColor);
@ -194,6 +213,8 @@ void NoteListDelegateEditor::paintBackground(QPainter *painter, const QStyleOpti
m_tagListView->setBackground(m_defaultColor);
}
}
// 如果视图正在拖拽,并且当前笔记未被固定,并且拖拽没有在被固定的笔记区域内发生
if (m_view->isDragging() && !isPinned && !m_view->isDraggingInsidePinned()) {
if (model && model->isFirstUnpinnedNote(index)
&& (index.row() == (model->rowCount() - 1))) {
@ -242,7 +263,9 @@ void NoteListDelegateEditor::paintBackground(QPainter *painter, const QStyleOpti
paintSeparator(&bufferPainter, option, index);
}
// 获取当前行的高度
auto rowHeight = rect().height();
// 将绘制好的背景绘制到painter上位置是当前控件的矩形区域
painter->drawPixmap(rect(), buffer,
QRect{ 0, bufferSize.height() - rowHeight, rect().width(), rowHeight });
}

@ -1,111 +1,134 @@
#ifndef NOTELISTDELEGATEEDITOR_H
#define NOTELISTDELEGATEEDITOR_H
#ifndef NOTELISTMODEL_H // 头文件保护,防止重复包含
#define NOTELISTMODEL_H
#include <QWidget>
#include "notelistview.h"
#include <QTimeLine>
#include "editorsettingsoptions.h"
#include <QAbstractListModel> // 包含QAbstractListModel类
#include "nodedata.h" // 包含NodeData类用于存储笔记数据
#include "dbmanager.h" // 包含数据库管理器
class NoteListDelegate;
class TagListModel;
class TagListView;
class TagListDelegate;
class NoteListModel;
struct NoteListConstant
class NoteListModel : public QAbstractListModel // 继承自QAbstractListModel
{
static constexpr int leftOffsetX = 20;
static constexpr int topOffsetY = 10; // space on top of title
static constexpr int titleDateSpace = 2; // space between title and date
static constexpr int dateDescSpace = 5; // space between date and description
static constexpr int descFolderSpace = 14; // space between description and folder name
static constexpr int lastElSepSpace = 12; // space between the last element and the separator
static constexpr int nextNoteOffset =
0; // space between the separator and the next note underneath it
static constexpr int pinnedHeaderToNoteSpace =
0; // space between Pinned label to the pinned list
static constexpr int unpinnedHeaderToNoteSpace =
0; // space between Notes label and the normal notes list
static constexpr int lastPinnedToUnpinnedHeader =
10; // space between the last pinned note to Notes label
};
Q_OBJECT // 宏用于支持Qt的信号和槽机制
class NoteListDelegateEditor : public QWidget
{
Q_OBJECT
public:
explicit NoteListDelegateEditor(const NoteListDelegate *delegate, NoteListView *view,
const QStyleOptionViewItem &option, const QModelIndex &index,
TagPool *tagPool, QWidget *parent = nullptr);
~NoteListDelegateEditor();
public :
// 定义笔记模型的角色枚举
enum NoteRoles {
NoteID = Qt::UserRole + 1, // 笔记ID角色
NoteFullTitle, // 笔记完整标题角色
NoteCreationDateTime, // 笔记创建日期时间角色
NoteLastModificationDateTime, // 笔记最后修改日期时间角色
NoteDeletionDateTime, // 笔记删除日期时间角色
NoteContent, // 笔记内容角色
NoteScrollbarPos, // 笔记滚动条位置角色
NoteTagsList, // 笔记标签列表角色
NoteIsTemp, // 笔记是否为临时笔记角色
NoteParentName, // 笔记父级名称角色
NoteTagListScrollbarPos, // 笔记标签列表滚动条位置角色
NoteIsPinned // 笔记是否被钉住角色
};
void setRowRightOffset(int rowRightOffset);
void setActive(bool isActive);
void recalculateSize();
void setScrollBarPos(int pos);
int getScrollBarPos();
bool underMouseC() const;
QPixmap renderToPixmap();
// 构造函数,可以指定一个父对象
explicit NoteListModel(QObject *parent = nullptr);
// 析构函数
~NoteListModel();
public slots:
void setTheme(Theme::Value theme);
signals:
void updateSizeHint(int id, const QSize &sz, const QModelIndex &index);
void nearDestroyed(int id, const QModelIndex &index);
// 添加笔记,并返回新笔记的模型索引
QModelIndex addNote(const NodeData &note);
// 在指定行插入笔记,并返回新笔记的模型索引
QModelIndex insertNote(const NodeData &note, int row);
// 获取指定模型索引的笔记数据
const NodeData &getNote(const QModelIndex &index) const;
// 获取指定ID的笔记的模型索引
QModelIndex getNoteIndex(int id) const;
// 设置笔记列表和列表视图信息
void setListNote(const QVector<NodeData> &notes, const ListViewInfo &inf);
// 移除指定模型索引列表的笔记
void removeNotes(const QModelIndexList &noteIndexes);
// 移动行
bool moveRow(const QModelIndex &sourceParent, int sourceRow,
const QModelIndex &destinationParent, int destinationChild);
private:
void paintBackground(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const;
void paintLabels(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const;
void paintSeparator(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const;
QString parseDateTime(const QDateTime &dateTime) const;
// 清空笔记列表
void clearNotes();
// 获取指定模型索引的数据
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
// 设置指定模型索引的数据
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
// 获取指定模型索引的项标志
Qt::ItemFlags flags(const QModelIndex &index) const override;
// 获取行数
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
// 排序
void sort(int column, Qt::SortOrder order) override;
// 设置指定模型索引的笔记数据
void setNoteData(const QModelIndex &index, const NodeData &note);
const NoteListDelegate *m_delegate;
QStyleOptionViewItem m_option;
int m_id;
NoteListView *m_view;
// 获取支持的拖放操作
virtual Qt::DropActions supportedDropActions() const override;
// 获取支持的拖拽操作
virtual Qt::DropActions supportedDragActions() const override;
// 获取支持的MIME类型
virtual QStringList mimeTypes() const override;
// 获取指定模型索引列表的MIME数据
virtual QMimeData *mimeData(const QModelIndexList &indexes) const override;
// 处理MIME数据的拖放
virtual bool dropMimeData(const QMimeData *mime, Qt::DropAction action, int row, int column,
const QModelIndex &parent) override;
TagPool *m_tagPool;
QString m_displayFont;
QFont m_titleFont;
QFont m_titleSelectedFont;
QFont m_dateFont;
QFont m_headerFont;
QColor m_titleColor;
QColor m_dateColor;
QColor m_contentColor;
QColor m_ActiveColor;
QColor m_notActiveColor;
QColor m_hoverColor;
QColor m_applicationInactiveColor;
QColor m_separatorColor;
QColor m_defaultColor;
int m_rowHeight;
int m_rowRightOffset;
bool m_isActive;
QImage m_folderIcon;
Theme::Value m_theme;
bool m_containsMouse;
QModelIndex m_animatedIndex;
// 检查指定模型索引的笔记是否具有标签
bool noteIsHaveTag(const QModelIndex &index) const;
// 检查指定模型索引的笔记是否为第一个被钉住的笔记
bool isFirstPinnedNote(const QModelIndex &index) const;
// 检查指定模型索引的笔记是否为第一个未被钉住的笔记
bool isFirstUnpinnedNote(const QModelIndex &index) const;
// 获取第一个被钉住的笔记的模型索引
QModelIndex getFirstPinnedNote() const;
// 检查是否有被钉住的笔记
bool hasPinnedNote() const;
// 设置指定模型索引列表的笔记的钉住状态
void setNotesIsPinned(const QModelIndexList &indexes, bool isPinned);
TagListView *m_tagListView;
TagListModel *m_tagListModel;
TagListDelegate *m_tagListDelegate;
// QWidget interface
protected:
virtual void paintEvent(QPaintEvent *event) override;
virtual void resizeEvent(QResizeEvent *event) override;
virtual void dragEnterEvent(QDragEnterEvent *event) override;
virtual void dragLeaveEvent(QDragLeaveEvent *event) override;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
virtual void enterEvent(QEnterEvent *event) override;
#else
virtual void enterEvent(QEvent *event) override;
#endif
private:
QVector<NodeData> m_noteList; // 笔记列表
QVector<NodeData> m_pinnedList; // 被钉住的笔记列表
ListViewInfo m_listViewInfo; // 列表视图信息
// 更新被钉住的笔记的相对位置
void updatePinnedRelativePosition();
// 检查是否在所有笔记中
bool isInAllNote() const;
// 获取指定行的笔记数据的引用
NodeData &getRef(int row);
// 获取指定行的笔记数据的常量引用
const NodeData &getRef(int row) const;
virtual void leaveEvent(QEvent *event) override;
virtual void dropEvent(QDropEvent *event) override;
signals:
// 行数发生变化时发出的信号
void rowCountChanged();
// 请求更新笔记的钉住状态时发出的信号
void requestUpdatePinned(int noteId, bool isPinned);
// 请求更新笔记的相对位置时发出的信号
void requestUpdatePinnedRelPos(int noteId, int pos);
// 请求更新笔记的相对位置(在所有笔记中)时发出的信号
void requestUpdatePinnedRelPosAN(int noteId, int pos);
// 请求移除笔记时发出的信号
void requestRemoveNotes(QModelIndexList index);
// 行插入时发出的信号
void rowsInsertedC(const QModelIndexList &rows);
// 行即将被移动时发出的信号
void rowsAboutToBeMovedC(const QModelIndexList &source);
// 行移动后发出的信号
void rowsMovedC(const QModelIndexList &dest);
// 请求关闭笔记编辑器时发出的信号
void requestCloseNoteEditor(const QModelIndexList &indexes);
// 请求打开笔记编辑器时发出的信号
void requestOpenNoteEditor(const QModelIndexList &indexes);
// 选择笔记时发出的信号
void selectNotes(const QModelIndexList &indexes);
// 重写QAbstractItemModel的接口
public:
// 移除行
bool removeRows(int row, int count, const QModelIndex &parent) override;
};
#endif // NOTELISTDELEGATEEDITOR_H
#endif // NOTELISTMODEL_H

@ -1,93 +1,98 @@
#include "taglistdelegate.h"
#include "taglistmodel.h"
#include <QPainter>
#include <QPainterPath>
#include "fontloader.h"
#include "taglistdelegate.h" // 引入自定义的委托头文件
#include "taglistmodel.h" // 引入自定义的模型头文件
#include <QPainter> // 引入QPainter类用于绘制界面
#include <QPainterPath> // 引入QPainterPath类用于绘制路径
#include "fontloader.h" // 自定义的字体加载器
// 构造函数,初始化委托的显示字体和标题字体
TagListDelegate::TagListDelegate(QObject *parent)
: QStyledItemDelegate(parent),
#ifdef __APPLE__
m_displayFont(QFont(QStringLiteral("SF Pro Text")).exactMatch()
? QStringLiteral("SF Pro Text")
: QStringLiteral("Roboto")),
#elif _WIN32
: QStyledItemDelegate(parent), // 调用基类构造函数
#ifdef __APPLE__ // 如果是苹果系统
m_displayFont(QFont(QStringLiteral("SF Pro Text")).exactMatch() // 检查系统字体是否精确匹配
? QStringLiteral("SF Pro Text") // 如果匹配,使用系统字体
: QStringLiteral("Roboto")), // 否则使用Roboto字体
#elif _WIN32 // 如果是Windows系统
m_displayFont(QFont(QStringLiteral("Segoe UI")).exactMatch() ? QStringLiteral("Segoe UI")
: QStringLiteral("Roboto")),
#else
#else // 其他系统
m_displayFont(QStringLiteral("Roboto")),
#endif
#ifdef __APPLE__
m_titleFont(m_displayFont, 13, QFont::DemiBold),
#else
m_titleFont(m_displayFont, 10, QFont::DemiBold),
#ifdef __APPLE__ // 如果是苹果系统
m_titleFont(m_displayFont, 13, QFont::DemiBold), // 设置标题字体为SF Pro Text大小13半粗
#else // 其他系统
m_titleFont(m_displayFont, 10, QFont::DemiBold), // 设置标题字体为Roboto大小10半粗
#endif
m_titleColor(26, 26, 26),
m_theme(Theme::Light)
m_titleColor(26, 26, 26), // 设置标题颜色为深灰色
m_theme(Theme::Light) // 初始化主题为浅色
{
}
// 重写paint函数用于自定义绘制项
void TagListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
painter->setRenderHint(QPainter::Antialiasing);
auto name = index.data(TagListModel::NameRole).toString();
auto color = index.data(TagListModel::ColorRole).toString();
painter->setRenderHint(QPainter::Antialiasing); // 设置抗锯齿,使绘制更平滑
auto name = index.data(TagListModel::NameRole).toString(); // 获取模型中的名称数据
auto color = index.data(TagListModel::ColorRole).toString(); // 获取模型中的颜色数据
auto rect = option.rect;
rect.setHeight(20);
QPainterPath path;
path.addRoundedRect(rect, 10, 10);
if (m_theme == Theme::Dark) {
painter->fillPath(path, QColor(76, 85, 97));
} else {
painter->fillPath(path, QColor(218, 235, 248));
auto rect = option.rect; // 获取绘制区域
rect.setHeight(20); // 设置绘制区域的高度
QPainterPath path; // 创建路径对象
path.addRoundedRect(rect, 10, 10); // 添加圆角矩形路径
if (m_theme == Theme::Dark) { // 如果主题是深色
painter->fillPath(path, QColor(76, 85, 97)); // 填充深灰色背景
} else { // 否则
painter->fillPath(path, QColor(218, 235, 248)); // 填充浅灰色背景
}
auto iconRect = QRect(rect.x() + 5, rect.y() + (rect.height() - 12) / 2, 12, 12);
painter->setPen(QColor(color));
#ifdef __APPLE__
int iconPointSizeOffset = 0;
#else
int iconPointSizeOffset = -4;
auto iconRect =
QRect(rect.x() + 5, rect.y() + (rect.height() - 12) / 2, 12, 12); // 设置图标区域
painter->setPen(QColor(color)); // 设置画笔颜色为模型中的颜色
#ifdef __APPLE__ // 如果是苹果系统
int iconPointSizeOffset = 0; // 图标点大小偏移量为0
#else // 其他系统
int iconPointSizeOffset = -4; // 图标点大小偏移量为-4
#endif
painter->setFont(FontLoader::getInstance().loadFont("Font Awesome 6 Free Solid", "",
painter->setFont(FontLoader::getInstance().loadFont("Font Awesome 6 Free Solid", "", // 加载字体
12 + iconPointSizeOffset));
painter->drawText(iconRect, u8"\uf111"); // fa-circle
painter->setBrush(m_titleColor);
painter->setPen(m_titleColor);
painter->drawText(iconRect, u8"\uf111"); // 绘制图标(一个圆圈)
painter->setBrush(m_titleColor); // 设置画刷颜色为标题颜色
painter->setPen(m_titleColor); // 设置画笔颜色为标题颜色
QRect nameRect(rect);
nameRect.setLeft(iconRect.x() + iconRect.width() + 5);
painter->setFont(m_titleFont);
painter->drawText(nameRect, Qt::AlignLeft | Qt::AlignVCenter, name);
QRect nameRect(rect); // 创建名称区域
nameRect.setLeft(iconRect.x() + iconRect.width() + 5); // 设置名称区域的左边距
painter->setFont(m_titleFont); // 设置字体为标题字体
painter->drawText(nameRect, Qt::AlignLeft | Qt::AlignVCenter, name); // 绘制名称文本
}
// 重写sizeHint函数用于自定义项的大小
QSize TagListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(option);
QSize size;
size.setHeight(20);
auto name = index.data(TagListModel::NameRole).toString();
QFontMetrics fmName(m_titleFont);
QRect fmRectName = fmName.boundingRect(name);
size.setWidth(5 + 12 + 5 + fmRectName.width() + 7);
return size;
Q_UNUSED(option); // 声明option参数未使用
QSize size; // 创建大小对象
size.setHeight(20); // 设置高度为20
auto name = index.data(TagListModel::NameRole).toString(); // 获取模型中的名称数据
QFontMetrics fmName(m_titleFont); // 创建字体度量对象
QRect fmRectName = fmName.boundingRect(name); // 获取名称文本的边界矩形
size.setWidth(5 + 12 + 5 + fmRectName.width() + 7); // 计算宽度
return size; // 返回大小
}
// 设置主题,并根据主题改变标题颜色
void TagListDelegate::setTheme(Theme::Value theme)
{
m_theme = theme;
switch (m_theme) {
m_theme = theme; // 设置主题
switch (m_theme) { // 根据主题进行条件编译
case Theme::Light: {
m_titleColor = QColor(26, 26, 26);
m_titleColor = QColor(26, 26, 26); // 浅色主题下,标题颜色为深灰色
break;
}
case Theme::Dark: {
m_titleColor = QColor(212, 212, 212);
m_titleColor = QColor(212, 212, 212); // 深色主题下,标题颜色为浅灰色
break;
}
case Theme::Sepia: {
m_titleColor = QColor(26, 26, 26);
m_titleColor = QColor(26, 26, 26); // 棕褐色主题下,标题颜色为深灰色
break;
}
}
}
}

@ -1,30 +1,31 @@
#ifndef TAGLISTDELEGATE_H
#ifndef TAGLISTDELEGATE_H // 头文件保护,防止重复包含
#define TAGLISTDELEGATE_H
#include <QStyledItemDelegate>
#include "editorsettingsoptions.h"
#include <QStyledItemDelegate> // 引入QStyledItemDelegate类
#include "editorsettingsoptions.h" // 自定义的编辑器设置选项头文件
class TagListDelegate : public QStyledItemDelegate
class TagListDelegate
: public QStyledItemDelegate // 声明TagListDelegate类继承自QStyledItemDelegate
{
Q_OBJECT
public:
explicit TagListDelegate(QObject *parent = nullptr);
Q_OBJECT // 宏用于支持Qt的信号和槽机制
public : explicit TagListDelegate(QObject *parent = nullptr); // 构造函数声明
// QAbstractItemDelegate interface
// QAbstractItemDelegate接口
public:
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
virtual QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
void setTheme(Theme::Value theme);
const QModelIndex &index) const override; // 重写paint函数用于绘制项
virtual QSize
sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const override; // 重写sizeHint函数用于获取项的大小
void setTheme(Theme::Value theme); // 设置主题的函数声明
private:
QString m_displayFont;
QFont m_titleFont;
QFont m_titleSelectedFont;
QFont m_dateFont;
QColor m_titleColor;
Theme::Value m_theme;
QString m_displayFont; // 显示字体的字符串
QFont m_titleFont; // 标题字体
QFont m_titleSelectedFont; // 选中状态下的标题字体(在提供的代码中未使用)
QFont m_dateFont; // 日期字体(在提供的代码中未使用)
QColor m_titleColor; // 标题颜色
Theme::Value m_theme; // 主题枚举值
};
#endif // TAGLISTDELEGATE_H
#endif // TAGLISTDELEGATE_H
Loading…
Cancel
Save