diff --git a/src/resources/icons/view.svg b/src/resources/icons/view.svg
new file mode 100644
index 00000000..176f2647
--- /dev/null
+++ b/src/resources/icons/view.svg
@@ -0,0 +1,15 @@
+
+
+
+
diff --git a/src/resources/vnote.ini b/src/resources/vnote.ini
index dee9bf79..2f3fdc24 100644
--- a/src/resources/vnote.ini
+++ b/src/resources/vnote.ini
@@ -213,6 +213,16 @@ search_options=4,2,7,0,0,""
; 0 to disable history
history_size=50
+; View order of note list
+; 0 - configuration file
+; 1 - name
+; 2 - name reverse
+; 3 - created time
+; 4 - created time reverse
+; 5 - modified time
+; 6 - modified time reverse
+note_list_view_order=0
+
[export]
; Path of the wkhtmltopdf tool
wkhtmltopdf=wkhtmltopdf
diff --git a/src/vconfigmanager.cpp b/src/vconfigmanager.cpp
index 7a5f12b5..55f19556 100644
--- a/src/vconfigmanager.cpp
+++ b/src/vconfigmanager.cpp
@@ -51,6 +51,7 @@ const QString VConfigManager::c_exportFolderName = QString("vnote_exports");
VConfigManager::VConfigManager(QObject *p_parent)
: QObject(p_parent),
+ m_noteListViewOrder(-1),
m_hasReset(false),
userSettings(NULL),
defaultSettings(NULL),
diff --git a/src/vconfigmanager.h b/src/vconfigmanager.h
index 6787c983..9dc016a1 100644
--- a/src/vconfigmanager.h
+++ b/src/vconfigmanager.h
@@ -490,6 +490,9 @@ public:
const QString &getGraphvizDot() const;
void setGraphvizDot(const QString &p_dotPath);
+ int getNoteListViewOrder() const;
+ void setNoteListViewOrder(int p_order);
+
private:
// Look up a config from user and default settings.
QVariant getConfigFromSettings(const QString §ion, const QString &key) const;
@@ -870,9 +873,6 @@ private:
// Whether close note before open it via external editor.
bool m_closeBeforeExternalEditor;
- // Whether user has reset the configurations.
- bool m_hasReset;
-
// The string containing styles to inline when copied in edit mode.
QString m_stylesToInlineWhenCopied;
@@ -896,6 +896,12 @@ private:
// Size of history.
int m_historySize;
+ // View order of note list.
+ int m_noteListViewOrder;
+
+ // Whether user has reset the configurations.
+ bool m_hasReset;
+
// The name of the config file in each directory, obsolete.
// Use c_dirConfigFile instead.
static const QString c_obsoleteDirConfigFile;
@@ -2301,4 +2307,23 @@ inline int VConfigManager::getHistorySize() const
{
return m_historySize;
}
+
+inline int VConfigManager::getNoteListViewOrder() const
+{
+ if (m_noteListViewOrder == -1) {
+ const_cast(this)->m_noteListViewOrder = getConfigFromSettings("global", "note_list_view_order").toInt();
+ }
+
+ return m_noteListViewOrder;
+}
+
+inline void VConfigManager::setNoteListViewOrder(int p_order)
+{
+ if (m_noteListViewOrder == p_order) {
+ return;
+ }
+
+ m_noteListViewOrder = p_order;
+ setConfigToSettings("global", "note_list_view_order", m_noteListViewOrder);
+}
#endif // VCONFIGMANAGER_H
diff --git a/src/vfilelist.cpp b/src/vfilelist.cpp
index ab2a63b6..2ef94e00 100644
--- a/src/vfilelist.cpp
+++ b/src/vfilelist.cpp
@@ -66,10 +66,22 @@ void VFileList::setupUI()
QLabel *titleLabel = new QLabel(tr("Notes"), this);
titleLabel->setProperty("TitleLabel", true);
+ QPushButton *viewBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/view.svg"), "", this);
+ viewBtn->setToolTip(tr("View"));
+ viewBtn->setProperty("CornerBtn", true);
+
+ QMenu *viewMenu = new QMenu(this);
+ connect(viewMenu, &QMenu::aboutToShow,
+ this, [this, viewMenu]() {
+ updateViewMenu(viewMenu);
+ });
+ viewBtn->setMenu(viewMenu);
+
m_numLabel = new QLabel(this);
QHBoxLayout *titleLayout = new QHBoxLayout();
titleLayout->addWidget(titleLabel);
+ titleLayout->addWidget(viewBtn);
titleLayout->addStretch();
titleLayout->addWidget(m_numLabel);
@@ -156,7 +168,9 @@ void VFileList::updateFileList()
return;
}
- const QVector &files = m_directory->getFiles();
+ QVector files = m_directory->getFiles();
+ sortFiles(files, (ViewOrder)g_config->getNoteListViewOrder());
+
for (int i = 0; i < files.size(); ++i) {
VNoteFile *file = files[i];
insertFileListItem(file);
@@ -359,11 +373,9 @@ void VFileList::newFile()
}
}
- QVector items = updateFileListAdded();
- Q_ASSERT(items.size() == 1);
- fileList->setCurrentItem(items[0], QItemSelectionModel::ClearAndSelect);
- // Qt seems not to update the QListWidget correctly. Manually force it to repaint.
- fileList->update();
+ updateFileList();
+
+ locateFile(file);
// Open it in edit mode
emit fileCreated(file, OpenFileMode::Edit, true);
@@ -383,27 +395,6 @@ void VFileList::newFile()
}
}
-QVector VFileList::updateFileListAdded()
-{
- QVector ret;
- const QVector &files = m_directory->getFiles();
- for (int i = 0; i < files.size(); ++i) {
- VNoteFile *file = files[i];
- if (i >= fileList->count()) {
- QListWidgetItem *item = insertFileListItem(file, false);
- ret.append(item);
- } else {
- VNoteFile *itemFile = getVFile(fileList->item(i));
- if (itemFile != file) {
- QListWidgetItem *item = insertFileListItem(file, false);
- ret.append(item);
- }
- }
- }
-
- return ret;
-}
-
void VFileList::deleteSelectedFiles()
{
QList items = fileList->selectedItems();
@@ -500,6 +491,7 @@ void VFileList::deleteFiles(const QVector &p_files)
g_mainWin->showStatusMessage(tr("%1 %2 deleted")
.arg(nrDeleted)
.arg(nrDeleted > 1 ? tr("notes") : tr("note")));
+ updateNumberLabel();
}
}
}
@@ -760,7 +752,7 @@ bool VFileList::importFiles(const QStringList &p_files, QString *p_errMsg)
QString dirPath = m_directory->fetchPath();
QDir dir(dirPath);
- int nrImported = 0;
+ QVector importedFiles;
for (int i = 0; i < p_files.size(); ++i) {
const QString &file = p_files[i];
@@ -799,7 +791,7 @@ bool VFileList::importFiles(const QStringList &p_files, QString *p_errMsg)
VNoteFile *destFile = m_directory->addFile(name, -1);
if (destFile) {
- ++nrImported;
+ importedFiles.append(destFile);
qDebug() << "imported" << file << "as" << targetFilePath;
} else {
VUtils::addErrMsg(p_errMsg, tr("Fail to add the note %1 to target folder's configuration.")
@@ -809,10 +801,12 @@ bool VFileList::importFiles(const QStringList &p_files, QString *p_errMsg)
}
}
- qDebug() << "imported" << nrImported << "files";
+ qDebug() << "imported" << importedFiles.size() << "files";
updateFileList();
+ selectFiles(importedFiles);
+
return ret;
}
@@ -1273,3 +1267,152 @@ void VFileList::updateNumberLabel() const
m_numLabel->setText(tr("%1 %2").arg(cnt)
.arg(cnt > 1 ? tr("Items") : tr("Item")));
}
+
+void VFileList::updateViewMenu(QMenu *p_menu)
+{
+ if (p_menu->isEmpty()) {
+ QActionGroup *ag = new QActionGroup(p_menu);
+
+ QAction *act = new QAction(tr("View By Configuration File"), ag);
+ act->setCheckable(true);
+ act->setData(ViewOrder::Config);
+ act->setChecked(true);
+ p_menu->addAction(act);
+
+ act = new QAction(tr("View By Name"), ag);
+ act->setCheckable(true);
+ act->setData(ViewOrder::Name);
+ p_menu->addAction(act);
+
+ act = new QAction(tr("View By Name (Reverse)"), ag);
+ act->setCheckable(true);
+ act->setData(ViewOrder::NameReverse);
+ p_menu->addAction(act);
+
+ act = new QAction(tr("View By Created Time"), ag);
+ act->setCheckable(true);
+ act->setData(ViewOrder::CreatedTime);
+ p_menu->addAction(act);
+
+ act = new QAction(tr("View By Created Time (Reverse)"), ag);
+ act->setCheckable(true);
+ act->setData(ViewOrder::CreatedTimeReverse);
+ p_menu->addAction(act);
+
+ act = new QAction(tr("View By Modified Time"), ag);
+ act->setCheckable(true);
+ act->setData(ViewOrder::ModifiedTime);
+ p_menu->addAction(act);
+
+ act = new QAction(tr("View By Modified Time (Reverse)"), ag);
+ act->setCheckable(true);
+ act->setData(ViewOrder::ModifiedTimeReverse);
+ p_menu->addAction(act);
+
+ int config = g_config->getNoteListViewOrder();
+ for (auto act : ag->actions()) {
+ if (act->data().toInt() == config) {
+ act->setChecked(true);
+ }
+ }
+
+ connect(ag, &QActionGroup::triggered,
+ this, [this](QAction *p_action) {
+ int order = p_action->data().toInt();
+ g_config->setNoteListViewOrder(order);
+
+ sortFileList((ViewOrder)order);
+ });
+ }
+}
+
+void VFileList::sortFileList(ViewOrder p_order)
+{
+ QVector files = m_directory->getFiles();
+ sortFiles(files, p_order);
+
+ Q_ASSERT(files.size() == fileList->count());
+ int cnt = files.size();
+ for (int i = 0; i < cnt; ++i) {
+ int row = -1;
+ for (int j = i; j < cnt; ++j) {
+ QListWidgetItem *item = fileList->item(j);
+ if (files[i] == getVFile(item)) {
+ row = j;
+ break;
+ }
+ }
+
+ Q_ASSERT(row > -1);
+ QListWidgetItem *item = fileList->takeItem(row);
+ fileList->insertItem(i, item);
+ }
+}
+
+void VFileList::sortFiles(QVector &p_files, ViewOrder p_order)
+{
+ bool reverse = false;
+
+ switch (p_order) {
+ case ViewOrder::Config:
+ break;
+
+ case ViewOrder::NameReverse:
+ reverse = true;
+ V_FALLTHROUGH
+ case ViewOrder::Name:
+ std::sort(p_files.begin(), p_files.end(), [reverse](const VNoteFile *p_a, const VNoteFile *p_b) {
+ if (reverse) {
+ return p_b->getName() < p_a->getName();
+ } else {
+ return p_a->getName() < p_b->getName();
+ }
+ });
+ break;
+
+ case ViewOrder::CreatedTimeReverse:
+ reverse = true;
+ V_FALLTHROUGH
+ case ViewOrder::CreatedTime:
+ std::sort(p_files.begin(), p_files.end(), [reverse](const VNoteFile *p_a, const VNoteFile *p_b) {
+ if (reverse) {
+ return p_b->getCreatedTimeUtc() < p_a->getCreatedTimeUtc();
+ } else {
+ return p_a->getCreatedTimeUtc() < p_b->getCreatedTimeUtc();
+ }
+ });
+ break;
+
+ case ViewOrder::ModifiedTimeReverse:
+ reverse = true;
+ V_FALLTHROUGH
+ case ViewOrder::ModifiedTime:
+ std::sort(p_files.begin(), p_files.end(), [reverse](const VNoteFile *p_a, const VNoteFile *p_b) {
+ if (reverse) {
+ return p_b->getModifiedTimeUtc() < p_a->getModifiedTimeUtc();
+ } else {
+ return p_a->getModifiedTimeUtc() < p_b->getModifiedTimeUtc();
+ }
+ });
+ break;
+
+ default:
+ break;
+ }
+}
+
+void VFileList::selectFiles(const QVector &p_files)
+{
+ bool first = true;
+ for (auto const & file : p_files) {
+ QListWidgetItem *item = findItem(file);
+ if (item) {
+ if (first) {
+ first = false;
+ fileList->setCurrentItem(item, QItemSelectionModel::ClearAndSelect);
+ } else {
+ item->setSelected(true);
+ }
+ }
+ }
+}
diff --git a/src/vfilelist.h b/src/vfilelist.h
index c4cce227..ac702343 100644
--- a/src/vfilelist.h
+++ b/src/vfilelist.h
@@ -119,6 +119,19 @@ protected:
void focusInEvent(QFocusEvent *p_event) Q_DECL_OVERRIDE;
private:
+ // Should be aligned with note_list_view_order in vnote.ini.
+ enum ViewOrder
+ {
+ Config = 0,
+ Name,
+ NameReverse,
+ CreatedTime,
+ CreatedTimeReverse,
+ ModifiedTime,
+ ModifiedTimeReverse,
+ Max
+ };
+
void setupUI();
// Init shortcuts.
@@ -143,9 +156,6 @@ private:
const QVector &p_files,
bool p_isCut);
- // New items have been added to direcotry. Update file list accordingly.
- QVector updateFileListAdded();
-
inline QPointer getVFile(QListWidgetItem *p_item) const;
// Fill the info of @p_item according to @p_file.
@@ -166,6 +176,16 @@ private:
void updateNumberLabel() const;
+ // Update the View menu.
+ void updateViewMenu(QMenu *p_menu);
+
+ // Sort file list.
+ void sortFileList(ViewOrder p_order);
+
+ void sortFiles(QVector &p_files, ViewOrder p_order);
+
+ void selectFiles(const QVector &p_files);
+
VEditArea *editArea;
VListWidget *fileList;
diff --git a/src/vnote.qrc b/src/vnote.qrc
index b0470a78..32ba666f 100644
--- a/src/vnote.qrc
+++ b/src/vnote.qrc
@@ -217,5 +217,6 @@
resources/icons/history.svg
resources/icons/clear_history.svg
resources/icons/pin.svg
+ resources/icons/view.svg