mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
support manual sort
This commit is contained in:
parent
319da24989
commit
aa00164dff
@ -327,3 +327,23 @@ bool Node::canRename(const QString &p_newName) const
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Node::sortChildren(const QVector<int> &p_beforeIdx, const QVector<int> &p_afterIdx)
|
||||
{
|
||||
Q_ASSERT(isContainer());
|
||||
|
||||
Q_ASSERT(p_beforeIdx.size() == p_afterIdx.size());
|
||||
|
||||
if (p_beforeIdx == p_afterIdx) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto ori = m_children;
|
||||
for (int i = 0; i < p_beforeIdx.size(); ++i) {
|
||||
if (p_beforeIdx[i] != p_afterIdx[i]) {
|
||||
m_children[p_beforeIdx[i]] = ori[p_afterIdx[i]];
|
||||
}
|
||||
}
|
||||
|
||||
save();
|
||||
}
|
||||
|
@ -158,6 +158,8 @@ namespace vnotex
|
||||
|
||||
bool canRename(const QString &p_newName) const;
|
||||
|
||||
void sortChildren(const QVector<int> &p_beforeIdx, const QVector<int> &p_afterIdx);
|
||||
|
||||
static bool isAncestor(const Node *p_ancestor, const Node *p_child);
|
||||
|
||||
protected:
|
||||
|
@ -488,11 +488,10 @@ void VXNotebookConfigMgr::loadNode(Node *p_node) const
|
||||
|
||||
void VXNotebookConfigMgr::saveNode(const Node *p_node)
|
||||
{
|
||||
Q_ASSERT(!p_node->isRoot());
|
||||
|
||||
if (p_node->isContainer()) {
|
||||
writeNodeConfig(p_node);
|
||||
} else {
|
||||
Q_ASSERT(!p_node->isRoot());
|
||||
writeNodeConfig(p_node->getParent());
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +75,7 @@
|
||||
<file>icons/outline_editor.svg</file>
|
||||
<file>icons/find_replace_editor.svg</file>
|
||||
<file>icons/section_number_editor.svg</file>
|
||||
<file>icons/sort.svg</file>
|
||||
<file>logo/vnote.svg</file>
|
||||
<file>logo/vnote.png</file>
|
||||
<file>logo/256x256/vnote.png</file>
|
||||
|
8
src/data/core/icons/sort.svg
Normal file
8
src/data/core/icons/sort.svg
Normal file
@ -0,0 +1,8 @@
|
||||
<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
|
||||
<g>
|
||||
<title>Layer 2</title>
|
||||
<text fill="#000000" stroke-width="0" x="50.16984" y="94.53242" id="svg_1" font-size="24" font-family="Sans-serif" text-anchor="middle" xml:space="preserve" transform="matrix(14.638787563577418,0,0,15.425402876908336,-563.6705867690341,-1147.819919301283) " stroke="#000000">A</text>
|
||||
<text id="svg_3" fill="#000000" stroke-width="0" x="42.10906" y="100.56143" font-size="24" font-family="Sans-serif" text-anchor="middle" xml:space="preserve" transform="matrix(14.638787563577418,0,0,15.425402876908336,-251.02721518700292,-1086.2459218037245) " stroke="#000000">Z</text>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 789 B |
@ -58,9 +58,7 @@ void NodeInfoWidget::setupUI(const Node *p_parentNode, Node::Flags p_newNodeFlag
|
||||
if (!createMode) {
|
||||
m_createdDateTimeLabel = new QLabel(this);
|
||||
m_mainLayout->addRow(tr("Created time:"), m_createdDateTimeLabel);
|
||||
}
|
||||
|
||||
if (!createMode && isNote) {
|
||||
m_modifiedDateTimeLabel = new QLabel(this);
|
||||
m_mainLayout->addRow(tr("Modified time:"), m_modifiedDateTimeLabel);
|
||||
}
|
||||
@ -135,10 +133,8 @@ void NodeInfoWidget::setNode(const Node *p_node)
|
||||
auto createdTime = Utils::dateTimeString(m_node->getCreatedTimeUtc().toLocalTime());
|
||||
m_createdDateTimeLabel->setText(createdTime);
|
||||
|
||||
if (m_modifiedDateTimeLabel) {
|
||||
auto modifiedTime = Utils::dateTimeString(m_node->getModifiedTimeUtc().toLocalTime());
|
||||
m_modifiedDateTimeLabel->setText(modifiedTime);
|
||||
}
|
||||
auto modifiedTime = Utils::dateTimeString(m_node->getModifiedTimeUtc().toLocalTime());
|
||||
m_modifiedDateTimeLabel->setText(modifiedTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
257
src/widgets/dialogs/sortdialog.cpp
Normal file
257
src/widgets/dialogs/sortdialog.cpp
Normal file
@ -0,0 +1,257 @@
|
||||
#include "sortdialog.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QHeaderView>
|
||||
|
||||
#include <widgets/treewidget.h>
|
||||
#include <widgets/widgetsfactory.h>
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
SortDialog::SortDialog(const QString &p_title,
|
||||
const QString &p_info,
|
||||
QWidget *p_parent)
|
||||
: ScrollDialog(p_parent)
|
||||
{
|
||||
setupUI(p_title, p_info);
|
||||
}
|
||||
|
||||
void SortDialog::setupUI(const QString &p_title, const QString &p_info)
|
||||
{
|
||||
auto mainWidget = new QWidget(this);
|
||||
setCentralWidget(mainWidget);
|
||||
|
||||
auto mainLayout = new QVBoxLayout(mainWidget);
|
||||
|
||||
if (!p_info.isEmpty()) {
|
||||
auto infoLabel = new QLabel(p_info, mainWidget);
|
||||
infoLabel->setWordWrap(true);
|
||||
mainLayout->addWidget(infoLabel);
|
||||
}
|
||||
|
||||
{
|
||||
auto bodyLayout = new QHBoxLayout();
|
||||
mainLayout->addLayout(bodyLayout);
|
||||
|
||||
// Tree widget.
|
||||
m_treeWidget = new TreeWidget(mainWidget);
|
||||
m_treeWidget->setRootIsDecorated(false);
|
||||
m_treeWidget->setSelectionMode(QAbstractItemView::ContiguousSelection);
|
||||
m_treeWidget->setDragDropMode(QAbstractItemView::InternalMove);
|
||||
connect(static_cast<TreeWidget *>(m_treeWidget), &TreeWidget::rowsMoved,
|
||||
this, [this](int p_first, int p_last, int p_row) {
|
||||
auto item = m_treeWidget->topLevelItem(p_row);
|
||||
if (item) {
|
||||
// Keep all items selected.
|
||||
m_treeWidget->setCurrentItem(item);
|
||||
|
||||
const int cnt = p_last - p_first + 1;
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
auto it = m_treeWidget->topLevelItem(p_row + i);
|
||||
if (it) {
|
||||
it->setSelected(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
bodyLayout->addWidget(m_treeWidget);
|
||||
|
||||
// Buttons for top/up/down/bottom.
|
||||
auto btnLayout = new QVBoxLayout();
|
||||
bodyLayout->addLayout(btnLayout);
|
||||
|
||||
auto topBtn = new QPushButton(tr("&Top"), mainWidget);
|
||||
connect(topBtn, &QPushButton::clicked,
|
||||
this, [this]() {
|
||||
handleMoveOperation(MoveOperation::Top);
|
||||
});
|
||||
btnLayout->addWidget(topBtn);
|
||||
|
||||
auto upBtn = new QPushButton(tr("&Up"), mainWidget);
|
||||
connect(upBtn, &QPushButton::clicked,
|
||||
this, [this]() {
|
||||
handleMoveOperation(MoveOperation::Up);
|
||||
});
|
||||
btnLayout->addWidget(upBtn);
|
||||
|
||||
auto downBtn = new QPushButton(tr("&Down"), mainWidget);
|
||||
connect(downBtn, &QPushButton::clicked,
|
||||
this, [this]() {
|
||||
handleMoveOperation(MoveOperation::Down);
|
||||
});
|
||||
btnLayout->addWidget(downBtn);
|
||||
|
||||
auto bottomBtn = new QPushButton(tr("&Bottom"), mainWidget);
|
||||
connect(bottomBtn, &QPushButton::clicked,
|
||||
this, [this]() {
|
||||
handleMoveOperation(MoveOperation::Bottom);
|
||||
});
|
||||
btnLayout->addWidget(bottomBtn);
|
||||
|
||||
btnLayout->addStretch();
|
||||
}
|
||||
|
||||
setDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
setWindowTitle(p_title);
|
||||
}
|
||||
|
||||
QTreeWidget *SortDialog::getTreeWidget() const
|
||||
{
|
||||
return m_treeWidget;
|
||||
}
|
||||
|
||||
void SortDialog::updateTreeWidget()
|
||||
{
|
||||
int cols = m_treeWidget->columnCount();
|
||||
for (int i = 0; i < cols; ++i) {
|
||||
m_treeWidget->resizeColumnToContents(i);
|
||||
}
|
||||
|
||||
QHeaderView *header = m_treeWidget->header();
|
||||
if (header) {
|
||||
header->setStretchLastSection(true);
|
||||
}
|
||||
|
||||
// We just need single level.
|
||||
int cnt = m_treeWidget->topLevelItemCount();
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
QTreeWidgetItem *item = m_treeWidget->topLevelItem(i);
|
||||
item->setFlags(item->flags() & ~Qt::ItemIsDropEnabled);
|
||||
}
|
||||
|
||||
m_treeWidget->sortByColumn(-1);
|
||||
m_treeWidget->setSortingEnabled(true);
|
||||
}
|
||||
|
||||
QVector<QVariant> SortDialog::getSortedData() const
|
||||
{
|
||||
const int cnt = m_treeWidget->topLevelItemCount();
|
||||
QVector<QVariant> data(cnt);
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
QTreeWidgetItem *item = m_treeWidget->topLevelItem(i);
|
||||
Q_ASSERT(item);
|
||||
data[i] = item->data(0, Qt::UserRole);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void SortDialog::handleMoveOperation(MoveOperation p_op)
|
||||
{
|
||||
const QList<QTreeWidgetItem *> selectedItems = m_treeWidget->selectedItems();
|
||||
if (selectedItems.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int first = m_treeWidget->topLevelItemCount();
|
||||
int last = -1;
|
||||
for (const auto &it : selectedItems) {
|
||||
int idx = m_treeWidget->indexOfTopLevelItem(it);
|
||||
Q_ASSERT(idx > -1);
|
||||
if (idx < first) {
|
||||
first = idx;
|
||||
}
|
||||
|
||||
if (idx > last) {
|
||||
last = idx;
|
||||
}
|
||||
}
|
||||
|
||||
Q_ASSERT(first <= last && (last - first + 1) == selectedItems.size());
|
||||
QTreeWidgetItem *firstItem = nullptr;
|
||||
|
||||
m_treeWidget->sortByColumn(-1);
|
||||
|
||||
switch (p_op) {
|
||||
case MoveOperation::Top:
|
||||
if (first == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
m_treeWidget->clearSelection();
|
||||
|
||||
// Insert item[last] to index 0 repeatedly.
|
||||
for (int i = last - first; i >= 0; --i) {
|
||||
QTreeWidgetItem *item = m_treeWidget->takeTopLevelItem(last);
|
||||
Q_ASSERT(item);
|
||||
m_treeWidget->insertTopLevelItem(0, item);
|
||||
item->setSelected(true);
|
||||
}
|
||||
|
||||
firstItem = m_treeWidget->topLevelItem(0);
|
||||
|
||||
break;
|
||||
|
||||
case MoveOperation::Up:
|
||||
if (first == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
m_treeWidget->clearSelection();
|
||||
|
||||
// Insert item[last] to index (first -1) repeatedly.
|
||||
for (int i = last - first; i >= 0; --i) {
|
||||
QTreeWidgetItem *item = m_treeWidget->takeTopLevelItem(last);
|
||||
Q_ASSERT(item);
|
||||
m_treeWidget->insertTopLevelItem(first - 1, item);
|
||||
item->setSelected(true);
|
||||
}
|
||||
|
||||
firstItem = m_treeWidget->topLevelItem(first - 1);
|
||||
|
||||
break;
|
||||
|
||||
case MoveOperation::Down:
|
||||
if (last == m_treeWidget->topLevelItemCount() - 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
m_treeWidget->clearSelection();
|
||||
|
||||
// Insert item[first] to index (last) repeatedly.
|
||||
for (int i = last - first; i >= 0; --i) {
|
||||
QTreeWidgetItem *item = m_treeWidget->takeTopLevelItem(first);
|
||||
Q_ASSERT(item);
|
||||
m_treeWidget->insertTopLevelItem(last + 1, item);
|
||||
item->setSelected(true);
|
||||
|
||||
if (!firstItem) {
|
||||
firstItem = item;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MoveOperation::Bottom:
|
||||
if (last == m_treeWidget->topLevelItemCount() - 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
m_treeWidget->clearSelection();
|
||||
|
||||
// Insert item[first] to the last of the tree repeatedly.
|
||||
for (int i = last - first; i >= 0; --i) {
|
||||
QTreeWidgetItem *item = m_treeWidget->takeTopLevelItem(first);
|
||||
Q_ASSERT(item);
|
||||
m_treeWidget->addTopLevelItem(item);
|
||||
item->setSelected(true);
|
||||
|
||||
if (!firstItem) {
|
||||
firstItem = item;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (firstItem) {
|
||||
m_treeWidget->setCurrentItem(firstItem);
|
||||
m_treeWidget->scrollToItem(firstItem);
|
||||
}
|
||||
}
|
44
src/widgets/dialogs/sortdialog.h
Normal file
44
src/widgets/dialogs/sortdialog.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef SORTDIALOG_H
|
||||
#define SORTDIALOG_H
|
||||
|
||||
#include "scrolldialog.h"
|
||||
|
||||
class QTreeWidget;
|
||||
class QPushButton;
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
class SortDialog : public ScrollDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SortDialog(const QString &p_title, const QString &p_info, QWidget *p_parent = nullptr);
|
||||
|
||||
QTreeWidget *getTreeWidget() const;
|
||||
|
||||
// Called after updating the QTreeWidget from getTreeWidget().
|
||||
void updateTreeWidget();
|
||||
|
||||
// Get user data of column 0 from sorted items.
|
||||
QVector<QVariant> getSortedData() const;
|
||||
|
||||
private:
|
||||
enum MoveOperation
|
||||
{
|
||||
Top,
|
||||
Up,
|
||||
Down,
|
||||
Bottom
|
||||
};
|
||||
|
||||
private slots:
|
||||
void handleMoveOperation(MoveOperation p_op);
|
||||
|
||||
private:
|
||||
void setupUI(const QString &p_title, const QString &p_info);
|
||||
|
||||
QTreeWidget *m_treeWidget = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SORTDIALOG_H
|
@ -1,6 +1,11 @@
|
||||
#include "notebooknodeexplorer.h"
|
||||
|
||||
#include <QtWidgets>
|
||||
#include <QTreeWidget>
|
||||
#include <QVBoxLayout>
|
||||
#include <QSplitter>
|
||||
#include <QTreeWidget>
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
|
||||
#include <notebook/notebook.h>
|
||||
#include <notebook/node.h>
|
||||
@ -13,6 +18,7 @@
|
||||
#include "dialogs/notepropertiesdialog.h"
|
||||
#include "dialogs/folderpropertiesdialog.h"
|
||||
#include "dialogs/deleteconfirmdialog.h"
|
||||
#include "dialogs/sortdialog.h"
|
||||
#include <utils/widgetutils.h>
|
||||
#include <utils/pathutils.h>
|
||||
#include <utils/clipboardutils.h>
|
||||
@ -742,6 +748,11 @@ void NotebookNodeExplorer::createContextMenuOnNode(QMenu *p_menu, const Node *p_
|
||||
act = createAction(Action::RemoveFromConfig, p_menu);
|
||||
p_menu->addAction(act);
|
||||
|
||||
p_menu->addSeparator();
|
||||
|
||||
act = createAction(Action::Sort, p_menu);
|
||||
p_menu->addAction(act);
|
||||
|
||||
if (selectedSize == 1) {
|
||||
p_menu->addSeparator();
|
||||
|
||||
@ -913,6 +924,7 @@ QAction *NotebookNodeExplorer::createAction(Action p_act, QObject *p_parent)
|
||||
break;
|
||||
|
||||
case Action::DeleteFromRecycleBin:
|
||||
// It is fine to have &D with Action::Delete since they won't be at the same context.
|
||||
act = new QAction(tr("&Delete From Recycle Bin"), p_parent);
|
||||
connect(act, &QAction::triggered,
|
||||
this, [this]() {
|
||||
@ -927,6 +939,14 @@ QAction *NotebookNodeExplorer::createAction(Action p_act, QObject *p_parent)
|
||||
removeSelectedNodesFromConfig();
|
||||
});
|
||||
break;
|
||||
|
||||
case Action::Sort:
|
||||
act = new QAction(generateMenuActionIcon("sort.svg"), tr("&Sort"), p_parent);
|
||||
connect(act, &QAction::triggered,
|
||||
this, [this]() {
|
||||
manualSort();
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
return act;
|
||||
@ -1416,3 +1436,65 @@ void NotebookNodeExplorer::setRecycleBinNodeVisible(bool p_visible)
|
||||
m_recycleBinNodeVisible = p_visible;
|
||||
reload();
|
||||
}
|
||||
|
||||
void NotebookNodeExplorer::manualSort()
|
||||
{
|
||||
auto node = getCurrentNode();
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto parentNode = node->getParent();
|
||||
bool isNotebook = parentNode->isRoot();
|
||||
|
||||
// Check whether sort files or folders based on current node type.
|
||||
bool sortFolders = node->isContainer();
|
||||
|
||||
SortDialog sortDlg(sortFolders ? tr("Sort Folders") : tr("Sort Notes"),
|
||||
tr("Sort nodes under %1 (%2) in the configuration file.").arg(
|
||||
isNotebook ? tr("notebook") : tr("folder"),
|
||||
isNotebook ? m_notebook->getName() : parentNode->getName()),
|
||||
VNoteX::getInst().getMainWindow());
|
||||
|
||||
QVector<int> selectedIdx;
|
||||
|
||||
// Update the tree.
|
||||
{
|
||||
auto treeWidget = sortDlg.getTreeWidget();
|
||||
treeWidget->clear();
|
||||
treeWidget->setColumnCount(2);
|
||||
treeWidget->setHeaderLabels({tr("Name"), tr("Created Time"), tr("Modified Time")});
|
||||
|
||||
const auto &children = parentNode->getChildren();
|
||||
for (int i = 0; i < children.size(); ++i) {
|
||||
const auto &child = children[i];
|
||||
if (m_notebook->isRecycleBinNode(child.data())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool selected = sortFolders ? child->isContainer() : !child->isContainer();
|
||||
if (selected) {
|
||||
selectedIdx.push_back(i);
|
||||
|
||||
QStringList cols {child->getName(),
|
||||
Utils::dateTimeString(child->getCreatedTimeUtc().toLocalTime()),
|
||||
Utils::dateTimeString(child->getModifiedTimeUtc().toLocalTime())};
|
||||
auto item = new QTreeWidgetItem(treeWidget, cols);
|
||||
item->setData(0, Qt::UserRole, i);
|
||||
}
|
||||
}
|
||||
|
||||
sortDlg.updateTreeWidget();
|
||||
}
|
||||
|
||||
if (sortDlg.exec() == QDialog::Accepted) {
|
||||
const auto data = sortDlg.getSortedData();
|
||||
Q_ASSERT(data.size() == selectedIdx.size());
|
||||
QVector<int> sortedIdx(data.size(), -1);
|
||||
for (int i = 0; i < data.size(); ++i) {
|
||||
sortedIdx[i] = data[i].toInt();
|
||||
}
|
||||
parentNode->sortChildren(selectedIdx, sortedIdx);
|
||||
updateNode(parentNode);
|
||||
}
|
||||
}
|
||||
|
@ -118,9 +118,22 @@ namespace vnotex
|
||||
private:
|
||||
enum Column { Name = 0 };
|
||||
|
||||
enum Action { NewNote, NewFolder, Properties, OpenLocation, CopyPath,
|
||||
Copy, Cut, Paste, EmptyRecycleBin, Delete,
|
||||
DeleteFromRecycleBin, RemoveFromConfig };
|
||||
enum class Action
|
||||
{
|
||||
NewNote,
|
||||
NewFolder,
|
||||
Properties,
|
||||
OpenLocation,
|
||||
CopyPath,
|
||||
Copy,
|
||||
Cut,
|
||||
Paste,
|
||||
EmptyRecycleBin,
|
||||
Delete,
|
||||
DeleteFromRecycleBin,
|
||||
RemoveFromConfig,
|
||||
Sort
|
||||
};
|
||||
|
||||
void setupUI();
|
||||
|
||||
@ -210,6 +223,9 @@ namespace vnotex
|
||||
// [p_start, p_end).
|
||||
void sortNodes(QVector<QSharedPointer<Node>> &p_nodes, int p_start, int p_end, int p_viewOrder) const;
|
||||
|
||||
// Sort nodes in config file.
|
||||
void manualSort();
|
||||
|
||||
static NotebookNodeExplorer::NodeData getItemNodeData(const QTreeWidgetItem *p_item);
|
||||
|
||||
static void setItemNodeData(QTreeWidgetItem *p_item, const NodeData &p_data);
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <QMouseEvent>
|
||||
#include <QHeaderView>
|
||||
#include <QKeyEvent>
|
||||
#include <QDropEvent>
|
||||
|
||||
#include <utils/widgetutils.h>
|
||||
|
||||
@ -212,3 +213,29 @@ QVector<QTreeWidgetItem *> TreeWidget::getVisibleItems(const QTreeWidget *p_widg
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
void TreeWidget::dropEvent(QDropEvent *p_event)
|
||||
{
|
||||
auto dragItems = selectedItems();
|
||||
|
||||
int first = -1, last = -1;
|
||||
QTreeWidgetItem *firstItem = NULL;
|
||||
for (int i = 0; i < dragItems.size(); ++i) {
|
||||
int row = indexFromItem(dragItems[i]).row();
|
||||
if (row > last) {
|
||||
last = row;
|
||||
}
|
||||
|
||||
if (first == -1 || row < first) {
|
||||
first = row;
|
||||
firstItem = dragItems[i];
|
||||
}
|
||||
}
|
||||
|
||||
Q_ASSERT(firstItem);
|
||||
|
||||
QTreeWidget::dropEvent(p_event);
|
||||
|
||||
int target = indexFromItem(firstItem).row();
|
||||
emit rowsMoved(first, last, target);
|
||||
}
|
||||
|
@ -34,11 +34,17 @@ namespace vnotex
|
||||
|
||||
static QVector<QTreeWidgetItem *> getVisibleItems(const QTreeWidget *p_widget);
|
||||
|
||||
signals:
|
||||
// Rows [@p_first, @p_last] were moved to @p_row.
|
||||
void rowsMoved(int p_first, int p_last, int p_row);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE;
|
||||
|
||||
void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE;
|
||||
|
||||
void dropEvent(QDropEvent *p_event) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
static QTreeWidgetItem *findItemHelper(QTreeWidgetItem *p_item, const QVariant &p_data);
|
||||
|
||||
|
@ -23,6 +23,7 @@ SOURCES += \
|
||||
$$PWD/dialogs/settings/settingsdialog.cpp \
|
||||
$$PWD/dialogs/settings/texteditorpage.cpp \
|
||||
$$PWD/dialogs/settings/themepage.cpp \
|
||||
$$PWD/dialogs/sortdialog.cpp \
|
||||
$$PWD/dialogs/tableinsertdialog.cpp \
|
||||
$$PWD/dragdropareaindicator.cpp \
|
||||
$$PWD/editors/editormarkdownvieweradapter.cpp \
|
||||
@ -109,6 +110,7 @@ HEADERS += \
|
||||
$$PWD/dialogs/settings/settingsdialog.h \
|
||||
$$PWD/dialogs/settings/texteditorpage.h \
|
||||
$$PWD/dialogs/settings/themepage.h \
|
||||
$$PWD/dialogs/sortdialog.h \
|
||||
$$PWD/dialogs/tableinsertdialog.h \
|
||||
$$PWD/dragdropareaindicator.h \
|
||||
$$PWD/editors/editormarkdownvieweradapter.h \
|
||||
|
Loading…
x
Reference in New Issue
Block a user