Browse Source

UniversalEntry

1. Use VListWidget in VListFolderUE;
2. Add j to list history;
Le Tan 7 years ago
parent
commit
6212bb48bc

+ 6 - 2
src/src.pro

@@ -133,7 +133,9 @@ SOURCES += main.cpp\
     vmathjaxwebdocument.cpp \
     vmathjaxinplacepreviewhelper.cpp \
     vhistorylist.cpp \
-    vexplorer.cpp
+    vexplorer.cpp \
+    vlistue.cpp \
+    vuetitlecontentpanel.cpp
 
 HEADERS  += vmainwindow.h \
     vdirectorytree.h \
@@ -260,7 +262,9 @@ HEADERS  += vmainwindow.h \
     vhistorylist.h \
     vhistoryentry.h \
     vexplorer.h \
-    vexplorerentry.h
+    vexplorerentry.h \
+    vlistue.h \
+    vuetitlecontentpanel.h
 
 RESOURCES += \
     vnote.qrc \

+ 1 - 1
src/vhistorylist.cpp

@@ -144,7 +144,7 @@ void VHistoryList::pinFolder(const QString &p_folder)
 void VHistoryList::addFilesInternal(const QStringList &p_files, bool p_isPinned)
 {
     for (auto const & file : p_files) {
-        // Find it in existing enries.
+        // Find it in existing entries.
         bool pinnedBefore = false;
         auto it = findFileInHistory(file);
         if (it != m_histories.end()) {

+ 8 - 0
src/vhistorylist.h

@@ -23,6 +23,8 @@ public:
 
     void pinFolder(const QString &p_folder);
 
+    const QLinkedList<VHistoryEntry> &getHistoryEntries() const;
+
     // Implementations for VNavigationMode.
     void showNavigation() Q_DECL_OVERRIDE;
     bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE;
@@ -91,4 +93,10 @@ private:
     QDate m_currentDate;
 };
 
+inline const QLinkedList<VHistoryEntry> &VHistoryList::getHistoryEntries() const
+{
+    const_cast<VHistoryList *>(this)->init();
+
+    return m_histories;
+}
 #endif // VHISTORYLIST_H

+ 11 - 38
src/vlistfolderue.cpp

@@ -4,7 +4,7 @@
 #include <QLabel>
 #include <QVBoxLayout>
 
-#include "vlistwidgetdoublerows.h"
+#include "vlistwidget.h"
 #include "vdirectory.h"
 #include "vdirectorytree.h"
 #include "vmainwindow.h"
@@ -14,40 +14,12 @@
 #include "vsearchue.h"
 #include "utils/vutils.h"
 #include "vnotebook.h"
+#include "vuetitlecontentpanel.h"
 
 extern VMainWindow *g_mainWin;
 
 extern VNote *g_vnote;
 
-VListFolderPanel::VListFolderPanel(QWidget *p_contentWidget,
-                                QWidget *p_parent)
-    : QWidget(p_parent)
-{
-    m_titleLabel = new QLabel(this);
-    m_titleLabel->setProperty("TitleLabel", true);
-
-    p_contentWidget->setParent(this);
-
-    QVBoxLayout *layout = new QVBoxLayout();
-    layout->addWidget(m_titleLabel);
-    layout->addWidget(p_contentWidget);
-
-    layout->setContentsMargins(0, 0, 0, 0);
-
-    setLayout(layout);
-}
-
-void VListFolderPanel::setTitleLabel(const QString &p_title)
-{
-    m_titleLabel->setText(p_title);
-}
-
-void VListFolderPanel::clearTitle()
-{
-    m_titleLabel->clear();
-}
-
-
 VListFolderUE::VListFolderUE(QObject *p_parent)
     : IUniversalEntry(p_parent),
       m_listWidget(NULL)
@@ -72,12 +44,12 @@ void VListFolderUE::init()
     m_noteIcon = VIconUtils::treeViewIcon(":/resources/icons/note_item.svg");
     m_folderIcon = VIconUtils::treeViewIcon(":/resources/icons/dir_item.svg");
 
-    m_listWidget = new VListWidgetDoubleRows(m_widgetParent);
+    m_listWidget = new VListWidget(m_widgetParent);
     m_listWidget->setFitContent(true);
     connect(m_listWidget, SIGNAL(itemActivated(QListWidgetItem *)),
             this, SLOT(activateItem(QListWidgetItem *)));
 
-    m_panel = new VListFolderPanel(m_listWidget, m_widgetParent);
+    m_panel = new VUETitleContentPanel(m_listWidget, m_widgetParent);
     m_panel->hide();
 }
 
@@ -208,12 +180,11 @@ void VListFolderUE::addResultItem(const QSharedPointer<VSearchResultItem> &p_ite
 {
     m_data.append(p_item);
 
-    QString first, second;
+    QString text;
     if (p_item->m_text.isEmpty()) {
-        first = p_item->m_path;
+        text = p_item->m_path;
     } else {
-        first = p_item->m_text;
-        second = p_item->m_path;
+        text = p_item->m_text;
     }
 
     QIcon *icon = NULL;
@@ -230,10 +201,12 @@ void VListFolderUE::addResultItem(const QSharedPointer<VSearchResultItem> &p_ite
         break;
     }
 
-    QListWidgetItem *item = m_listWidget->addDoubleRowsItem(*icon, first, second);
+    QListWidgetItem *item = new QListWidgetItem(*icon, text);
     item->setData(Qt::UserRole, m_data.size() - 1);
     item->setToolTip(p_item->m_path);
 
+    m_listWidget->addItem(item);
+
     if (m_listWidget->count() == 1) {
         m_listWidget->setCurrentRow(0);
     }
@@ -282,7 +255,7 @@ bool VListFolderUE::listFolder(const QString &p_path, const QString &p_cmd)
     m_data.clear();
 
     m_currentFolderPath = dir->fetchPath();
-    m_panel->setTitleLabel(m_currentFolderPath);
+    m_panel->setTitle(m_currentFolderPath);
 
     if (!dir->open()) {
         return true;

+ 4 - 19
src/vlistfolderue.h

@@ -7,25 +7,10 @@
 
 #include "vsearchconfig.h"
 
-class VListWidgetDoubleRows;
+class VListWidget;
 class QListWidgetItem;
 class QLabel;
-
-class VListFolderPanel : public QWidget
-{
-    Q_OBJECT
-public:
-    explicit VListFolderPanel(QWidget *p_contentWidget,
-                              QWidget *p_parent = nullptr);
-
-    void setTitleLabel(const QString &p_title);
-
-    void clearTitle();
-
-private:
-    QLabel *m_titleLabel;
-};
-
+class VUETitleContentPanel;
 
 // Universal Entry to list contents of folder.
 class VListFolderUE : public IUniversalEntry
@@ -81,9 +66,9 @@ private:
     // Current folder path.
     QString m_currentFolderPath;
 
-    VListWidgetDoubleRows *m_listWidget;
+    VListWidget *m_listWidget;
 
-    VListFolderPanel *m_panel;
+    VUETitleContentPanel *m_panel;
 };
 
 #endif // VLISTFOLDERUE_H

+ 242 - 0
src/vlistue.cpp

@@ -0,0 +1,242 @@
+#include "vlistue.h"
+
+#include <QListWidgetItem>
+#include <QLabel>
+#include <QVBoxLayout>
+
+#include "vlistwidgetdoublerows.h"
+#include "vdirectory.h"
+#include "vdirectorytree.h"
+#include "vmainwindow.h"
+#include "vnote.h"
+#include "utils/viconutils.h"
+#include "vnotefile.h"
+#include "vsearchue.h"
+#include "utils/vutils.h"
+#include "vnotebook.h"
+#include "vuetitlecontentpanel.h"
+#include "vhistorylist.h"
+
+extern VMainWindow *g_mainWin;
+
+extern VNote *g_vnote;
+
+VListUE::VListUE(QObject *p_parent)
+    : IUniversalEntry(p_parent),
+      m_listWidget(NULL)
+{
+}
+
+QString VListUE::description(int p_id) const
+{
+    switch (p_id) {
+    case ID::History:
+        return tr("List and search history");
+
+    default:
+        Q_ASSERT(false);
+        return tr("Invalid ID %1").arg(p_id);
+    }
+}
+
+void VListUE::init()
+{
+    if (m_initialized) {
+        return;
+    }
+
+    m_initialized = true;
+
+    m_noteIcon = VIconUtils::treeViewIcon(":/resources/icons/note_item.svg");
+    m_folderIcon = VIconUtils::treeViewIcon(":/resources/icons/dir_item.svg");
+
+    m_listWidget = new VListWidgetDoubleRows(m_widgetParent);
+    m_listWidget->setFitContent(true);
+    connect(m_listWidget, SIGNAL(itemActivated(QListWidgetItem *)),
+            this, SLOT(activateItem(QListWidgetItem *)));
+
+    m_panel = new VUETitleContentPanel(m_listWidget, m_widgetParent);
+    m_panel->hide();
+}
+
+QWidget *VListUE::widget(int p_id)
+{
+    Q_UNUSED(p_id);
+
+    init();
+
+    return m_panel;
+}
+
+void VListUE::processCommand(int p_id, const QString &p_cmd)
+{
+    Q_UNUSED(p_id);
+
+    init();
+
+    clear(-1);
+
+    switch (p_id) {
+    case ID::History:
+        listHistory(p_cmd);
+        break;
+
+    default:
+        break;
+    }
+
+    m_listWidget->updateGeometry();
+    emit widgetUpdated();
+    emit stateUpdated(State::Success);
+}
+
+void VListUE::clear(int p_id)
+{
+    Q_UNUSED(p_id);
+
+    m_panel->clearTitle();
+    m_listWidget->clearAll();
+    m_data.clear();
+}
+
+void VListUE::selectNextItem(int p_id, bool p_forward)
+{
+    Q_UNUSED(p_id);
+
+    m_listWidget->selectNextItem(p_forward);
+}
+
+void VListUE::activate(int p_id)
+{
+    Q_UNUSED(p_id);
+    activateItem(m_listWidget->currentItem());
+}
+
+const QSharedPointer<VSearchResultItem> &VListUE::itemResultData(const QListWidgetItem *p_item) const
+{
+    Q_ASSERT(p_item);
+    int idx = p_item->data(Qt::UserRole).toInt();
+    Q_ASSERT(idx >= 0 && idx < m_data.size());
+    return m_data[idx];
+}
+
+void VListUE::activateItem(QListWidgetItem *p_item)
+{
+    if (!p_item) {
+        return;
+    }
+
+    emit requestHideUniversalEntry();
+
+    VSearchUE::activateItem(itemResultData(p_item));
+}
+
+void VListUE::sort(int p_id)
+{
+    Q_UNUSED(p_id);
+    static bool noteFirst = false;
+
+    int cnt = m_listWidget->count();
+    if (noteFirst) {
+        int idx = cnt - 1;
+        while (true) {
+            if (itemResultData(m_listWidget->item(idx))->m_type != VSearchResultItem::Note) {
+                // Move it to the first row.
+                m_listWidget->moveItem(idx, 0);
+            } else {
+                break;
+            }
+        }
+    } else {
+        int idx = 0;
+        while (true) {
+            if (itemResultData(m_listWidget->item(idx))->m_type != VSearchResultItem::Note) {
+                // Move it to the last row.
+                m_listWidget->moveItem(idx, cnt - 1);
+            } else {
+                break;
+            }
+        }
+    }
+
+    if (cnt) {
+        m_listWidget->setCurrentRow(0);
+    }
+
+    noteFirst = !noteFirst;
+}
+
+void VListUE::addResultItem(const QSharedPointer<VSearchResultItem> &p_item)
+{
+    m_data.append(p_item);
+
+    QString first, second;
+    if (p_item->m_text.isEmpty()) {
+        first = p_item->m_path;
+    } else {
+        first = p_item->m_text;
+        second = p_item->m_path;
+    }
+
+    QIcon *icon = NULL;
+    switch (p_item->m_type) {
+    case VSearchResultItem::Note:
+        icon = &m_noteIcon;
+        break;
+
+    case VSearchResultItem::Folder:
+        icon = &m_folderIcon;
+        break;
+
+    default:
+        break;
+    }
+
+    QListWidgetItem *item = m_listWidget->addDoubleRowsItem(*icon, first, second);
+    item->setData(Qt::UserRole, m_data.size() - 1);
+    item->setToolTip(p_item->m_path);
+
+    if (m_listWidget->count() == 1) {
+        m_listWidget->setCurrentRow(0);
+    }
+}
+
+void VListUE::listHistory(const QString &p_cmd)
+{
+    m_panel->setTitle(tr("History"));
+
+    VHistoryList *history = g_mainWin->getHistoryList();
+    const QLinkedList<VHistoryEntry> &entries = history->getHistoryEntries();
+    if (p_cmd.isEmpty()) {
+        // List the content.
+        for (auto it = entries.rbegin(); it != entries.rend(); ++it) {
+            QSharedPointer<VSearchResultItem> item(new VSearchResultItem(it->m_isFolder ? VSearchResultItem::Folder : VSearchResultItem::Note,
+                                                                         VSearchResultItem::LineNumber,
+                                                                         VUtils::fileNameFromPath(it->m_file),
+                                                                         it->m_file));
+            addResultItem(item);
+        }
+    } else {
+        // Search the content.
+        VSearchConfig config(VSearchConfig::CurrentFolder,
+                             VSearchConfig::Name,
+                             VSearchConfig::Note | VSearchConfig::Folder,
+                             VSearchConfig::Internal,
+                             VSearchConfig::NoneOption,
+                             p_cmd,
+                             QString());
+
+        for (auto it = entries.rbegin(); it != entries.rend(); ++it) {
+            QString name = VUtils::fileNameFromPath(it->m_file);
+            if (!config.m_token.matched(name)) {
+                continue;
+            }
+
+            QSharedPointer<VSearchResultItem> item(new VSearchResultItem(it->m_isFolder ? VSearchResultItem::Folder : VSearchResultItem::Note,
+                                                                         VSearchResultItem::LineNumber,
+                                                                         name,
+                                                                         it->m_file));
+            addResultItem(item);
+        }
+    }
+}

+ 67 - 0
src/vlistue.h

@@ -0,0 +1,67 @@
+#ifndef VLISTUE_H
+#define VLISTUE_H
+
+#include "iuniversalentry.h"
+
+#include <QWidget>
+#include <QIcon>
+#include <functional>
+#include <QSharedPointer>
+
+#include "vsearchconfig.h"
+
+class VListWidgetDoubleRows;
+class QListWidgetItem;
+class QLabel;
+class VUETitleContentPanel;
+
+class VListUE : public IUniversalEntry
+{
+    Q_OBJECT
+public:
+    enum ID
+    {
+        // List and search the history.
+        History = 0
+    };
+
+    explicit VListUE(QObject *p_parent = nullptr);
+
+    QString description(int p_id) const Q_DECL_OVERRIDE;
+
+    QWidget *widget(int p_id) Q_DECL_OVERRIDE;
+
+    void processCommand(int p_id, const QString &p_cmd) Q_DECL_OVERRIDE;
+
+    void clear(int p_id) Q_DECL_OVERRIDE;
+
+    void selectNextItem(int p_id, bool p_forward) Q_DECL_OVERRIDE;
+
+    void activate(int p_id) Q_DECL_OVERRIDE;
+
+    void sort(int p_id) Q_DECL_OVERRIDE;
+
+protected:
+    void init() Q_DECL_OVERRIDE;
+
+private slots:
+    void activateItem(QListWidgetItem *p_item);
+
+private:
+    void addResultItem(const QSharedPointer<VSearchResultItem> &p_item);
+
+    const QSharedPointer<VSearchResultItem> &itemResultData(const QListWidgetItem *p_item) const;
+
+    void listHistory(const QString &p_cmd);
+
+    QVector<QSharedPointer<VSearchResultItem> > m_data;
+
+    QIcon m_noteIcon;
+    QIcon m_folderIcon;
+
+    VListWidgetDoubleRows *m_listWidget;
+
+    VUETitleContentPanel *m_panel;
+};
+
+#endif // VLISTUE_H

+ 8 - 0
src/vlistwidget.cpp

@@ -230,3 +230,11 @@ bool VListWidget::isSeparatorItem(const QListWidgetItem *p_item)
 {
     return p_item->type() == ItemTypeSeparator;
 }
+
+void VListWidget::moveItem(int p_srcRow, int p_destRow)
+{
+    QListWidgetItem *it = takeItem(p_srcRow);
+    if (it) {
+        insertItem(p_destRow, it);
+    }
+}

+ 2 - 0
src/vlistwidget.h

@@ -34,6 +34,8 @@ public:
 
     virtual QSize sizeHint() const Q_DECL_OVERRIDE;
 
+    virtual void moveItem(int p_srcRow, int p_destRow);
+
     void setFitContent(bool p_enabled);
 
     // Sort @p_list according to @p_sortedIdx.

+ 1 - 1
src/vlistwidgetdoublerows.h

@@ -23,7 +23,7 @@ public:
                                           const QString &p_firstRow,
                                           const QString &p_secondRow);
 
-    void moveItem(int p_srcRow, int p_destRow);
+    void moveItem(int p_srcRow, int p_destRow) Q_DECL_OVERRIDE;
 
     void clearAll() Q_DECL_OVERRIDE;
 };

+ 7 - 0
src/vmainwindow.cpp

@@ -47,6 +47,7 @@
 #include "dialog/vfixnotebookdialog.h"
 #include "vhistorylist.h"
 #include "vexplorer.h"
+#include "vlistue.h"
 
 extern VConfigManager *g_config;
 
@@ -2489,6 +2490,11 @@ QVector<VFile *> VMainWindow::openFiles(const QStringList &p_files,
     vfiles.reserve(p_files.size());
 
     for (int i = 0; i < p_files.size(); ++i) {
+        if (!QFileInfo::exists(p_files[i])) {
+            qWarning() << "file" << p_files[i] << "does not exist";
+            continue;
+        }
+
         VFile *file = NULL;
         if (!p_forceOrphan) {
             file = vnote->getInternalFile(p_files[i]);
@@ -3135,6 +3141,7 @@ void VMainWindow::initUniversalEntry()
     m_ue->registerEntry('h', searchUE, VSearchUE::Path_FolderNote_AllNotebook);
     m_ue->registerEntry('n', searchUE, VSearchUE::Path_FolderNote_CurrentNotebook);
     m_ue->registerEntry('m', new VListFolderUE(this), 0);
+    m_ue->registerEntry('j', new VListUE(this), VListUE::History);
     m_ue->registerEntry('?', new VHelpUE(this), 0);
 }
 

+ 34 - 0
src/vuetitlecontentpanel.cpp

@@ -0,0 +1,34 @@
+#include "vuetitlecontentpanel.h"
+
+#include <QLabel>
+#include <QVBoxLayout>
+#include <QVariant>
+#include <QString>
+
+VUETitleContentPanel::VUETitleContentPanel(QWidget *p_contentWidget,
+                                           QWidget *p_parent)
+    : QWidget(p_parent)
+{
+    m_titleLabel = new QLabel(this);
+    m_titleLabel->setProperty("TitleLabel", true);
+
+    p_contentWidget->setParent(this);
+
+    QVBoxLayout *layout = new QVBoxLayout();
+    layout->addWidget(m_titleLabel);
+    layout->addWidget(p_contentWidget);
+
+    layout->setContentsMargins(0, 0, 0, 0);
+
+    setLayout(layout);
+}
+
+void VUETitleContentPanel::setTitle(const QString &p_title)
+{
+    m_titleLabel->setText(p_title);
+}
+
+void VUETitleContentPanel::clearTitle()
+{
+    m_titleLabel->clear();
+}

+ 23 - 0
src/vuetitlecontentpanel.h

@@ -0,0 +1,23 @@
+#ifndef VUETITLECONTENTPANEL_H
+#define VUETITLECONTENTPANEL_H
+
+#include <QWidget>
+
+class QLabel;
+
+class VUETitleContentPanel : public QWidget
+{
+    Q_OBJECT
+public:
+    explicit VUETitleContentPanel(QWidget *p_contentWidget,
+                                  QWidget *p_parent = nullptr);
+
+    void setTitle(const QString &p_title);
+
+    void clearTitle();
+
+private:
+    QLabel *m_titleLabel;
+};
+
+#endif // VUETITLECONTENTPANEL_H