mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
support history navigation
This commit is contained in:
parent
4284d20dea
commit
f6436bfabf
@ -4,7 +4,7 @@
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
|
||||
<g>
|
||||
<path fill="#010101" d="M169.6,377.6c-22.882,0-41.6,18.718-41.6,41.601c0,22.882,18.718,41.6,41.6,41.6s41.601-18.718,41.601-41.6
|
||||
<path fill="#000000" d="M169.6,377.6c-22.882,0-41.6,18.718-41.6,41.601c0,22.882,18.718,41.6,41.6,41.6s41.601-18.718,41.601-41.6
|
||||
C211.2,396.317,192.481,377.6,169.6,377.6z M48,51.2v41.6h41.6l74.883,151.682l-31.308,50.954c-3.118,5.2-5.2,12.482-5.2,19.765
|
||||
c0,27.85,19.025,41.6,44.825,41.6H416v-40H177.893c-3.118,0-5.2-2.082-5.2-5.2c0-1.036,2.207-5.2,2.207-5.2l20.782-32.8h154.954
|
||||
c15.601,0,29.128-8.317,36.4-21.836l74.882-128.8c1.237-2.461,2.082-6.246,2.082-10.399c0-11.446-9.364-19.765-20.8-19.765H135.364
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
10
src/resources/icons/clear_history.svg
Normal file
10
src/resources/icons/clear_history.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
<path style="fill:#C9302C" d="M443.6,387.1L312.4,255.4l131.5-130c5.4-5.4,5.4-14.2,0-19.6l-37.4-37.6c-2.6-2.6-6.1-4-9.8-4c-3.7,0-7.2,1.5-9.8,4
|
||||
L256,197.8L124.9,68.3c-2.6-2.6-6.1-4-9.8-4c-3.7,0-7.2,1.5-9.8,4L68,105.9c-5.4,5.4-5.4,14.2,0,19.6l131.5,130L68.4,387.1
|
||||
c-2.6,2.6-4.1,6.1-4.1,9.8c0,3.7,1.4,7.2,4.1,9.8l37.4,37.6c2.7,2.7,6.2,4.1,9.8,4.1c3.5,0,7.1-1.3,9.8-4.1L256,313.1l130.7,131.1
|
||||
c2.7,2.7,6.2,4.1,9.8,4.1c3.5,0,7.1-1.3,9.8-4.1l37.4-37.6c2.6-2.6,4.1-6.1,4.1-9.8C447.7,393.2,446.2,389.7,443.6,387.1z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 995 B |
9
src/resources/icons/history.svg
Normal file
9
src/resources/icons/history.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
|
||||
<g fill-opacity=".9">
|
||||
<path style="fill:#000000" d="M255.8 48C141 48 48 141.2 48 256s93 208 207.8 208c115 0 208.2-93.2 208.2-208S370.8 48 255.8 48zm.2 374.4c-91.9 0-166.4-74.5-166.4-166.4S164.1 89.6 256 89.6 422.4 164.1 422.4 256 347.9 422.4 256 422.4z"/>
|
||||
<path style="fill:#000000" d="M266.4 152h-31.2v124.8l109.2 65.5 15.6-25.6-93.6-55.5V152z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 836 B |
11
src/resources/icons/pin.svg
Normal file
11
src/resources/icons/pin.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
<path fill="#000000" d="M331.8,228C331.8,228,331.8,228,331.8,228c-1.2-0.5-2.4-1-3.5-1.7c-7-4-12.2-10.9-13.9-19.2L295.9,89.4l-0.2-5.8
|
||||
c0-7.1,4.1-10.2,10-13l0,0c0.7-0.3,1.4-0.6,2.1-0.9c7.2-3.4,12.1-7.8,12.1-16.3c0-20.1-6.5-21.4-18.2-21.4h-91.3
|
||||
c-11.7,0-18.2,1.2-18.2,21.4c0,8.5,4.9,12.9,12.1,16.3c0.7,0.3,1.4,0.5,2.1,0.9c0,0,0,0,0,0c5.9,2.9,10,6,10,13l-0.2,5.8
|
||||
l-18.5,117.7c-1.7,8.3-6.9,15.2-13.9,19.2c-1.1,0.7-2.3,1.2-3.5,1.7c0,0,0,0,0,0c-19.7,10.2-36.2,30.8-36.2,54.7
|
||||
c0,15.9,3.5,21.3,15.2,21.3H240l12,176h8l12-176h80.8c11.7,0,15.2-4.7,15.2-21.3C368,258.8,351.5,238.2,331.8,228z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
@ -119,6 +119,10 @@ search_hit_item_bg=@master_dark_bg
|
||||
ue_cmd_busy_border=#3F51B5
|
||||
ue_cmd_fail_border=@danger_bg
|
||||
|
||||
; VListWidget/VTreeWidget separator.
|
||||
item_separator_fg=@master_light_bg
|
||||
item_separator_bg=@separator_bg
|
||||
|
||||
[widgets]
|
||||
; Widget color attributes.
|
||||
|
||||
@ -138,6 +142,7 @@ menubar_item_selected_bg=@selected_bg
|
||||
; Menu.
|
||||
menu_bg=@base_bg
|
||||
menu_fg=@base_fg
|
||||
menu_border_bg=@border_bg
|
||||
menu_item_disabled_fg=@disabled_fg
|
||||
menu_item_selected_fg=@selected_fg
|
||||
menu_item_selected_bg=@selected_bg
|
||||
|
@ -40,7 +40,7 @@ QMenuBar::item:selected {
|
||||
QMenu {
|
||||
background: @menu_bg;
|
||||
color: @menu_fg;
|
||||
margin: 2px;
|
||||
border: 2px solid @menu_border_bg;
|
||||
}
|
||||
|
||||
QMenu::icon {
|
||||
@ -402,10 +402,10 @@ VButtonMenuItem:disabled {
|
||||
/* QComboBox */
|
||||
QComboBox#NotebookSelector {
|
||||
border: none;
|
||||
font-size: 13pt;
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
icon-size: $30px;
|
||||
font-size: 12pt;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
icon-size: $24px;
|
||||
font-weight: bold;
|
||||
color: @combobox_notebookselector_fg;
|
||||
background: @combobox_notebookselector_bg;
|
||||
@ -424,14 +424,14 @@ QComboBox#NotebookSelector:hover {
|
||||
QComboBox#NotebookSelector QListWidget {
|
||||
border: 1px solid @combobox_view_border;
|
||||
background-color: @combobox_bg;
|
||||
font-size: 13pt;
|
||||
font-size: 12pt;
|
||||
font-weight: normal;
|
||||
icon-size: $30px;
|
||||
icon-size: $24px;
|
||||
}
|
||||
|
||||
QComboBox#NotebookSelector QListWidget::item {
|
||||
padding-top: $10px;
|
||||
padding-bottom: $10px;
|
||||
padding-top: $5px;
|
||||
padding-bottom: $5px;
|
||||
}
|
||||
|
||||
QComboBox#NotebookSelector QListWidget::item:hover {
|
||||
@ -851,6 +851,10 @@ QListView::item:selected:!active {
|
||||
color: @listview_item_selected_inactive_fg;
|
||||
background: @listview_item_selected_inactive_bg;
|
||||
}
|
||||
|
||||
QListView::item:disabled {
|
||||
background: transparent;
|
||||
}
|
||||
/* End QListView */
|
||||
|
||||
/* QSplitter */
|
||||
@ -1250,6 +1254,10 @@ QWidget[ToolBoxTitle="true"] {
|
||||
border-bottom: 2px solid @toolbox_title_border;
|
||||
}
|
||||
|
||||
QWidget[ToolBoxTitle="true"] QPushButton[ToolBoxTitleBtn="true"] {
|
||||
height: $20px;
|
||||
}
|
||||
|
||||
QWidget[MainEditor="true"] {
|
||||
border: none;
|
||||
}
|
||||
|
@ -87,6 +87,10 @@ search_hit_item_bg=#80CBC4
|
||||
ue_cmd_busy_border=#3F51B5
|
||||
ue_cmd_fail_border=@danger_bg
|
||||
|
||||
; VListWidget/VTreeWidget separator.
|
||||
item_separator_fg=@content_fg
|
||||
item_separator_bg=@separator_bg
|
||||
|
||||
[widgets]
|
||||
; Widget color attributes.
|
||||
|
||||
|
@ -294,10 +294,10 @@ VButtonMenuItem:disabled {
|
||||
/* QComboBox */
|
||||
QComboBox#NotebookSelector {
|
||||
border: none;
|
||||
font-size: 13pt;
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
icon-size: $30px;
|
||||
font-size: 12pt;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
icon-size: $24px;
|
||||
background: @combobox_bg;
|
||||
}
|
||||
|
||||
@ -328,13 +328,13 @@ QComboBox#NotebookSelector::down-arrow:disabled {
|
||||
QComboBox#NotebookSelector QListWidget {
|
||||
border: 1px solid @combobox_view_border;
|
||||
background-color: @combobox_bg;
|
||||
font-size: 13pt;
|
||||
icon-size: $30px;
|
||||
font-size: 12pt;
|
||||
icon-size: $24px;
|
||||
}
|
||||
|
||||
QComboBox#NotebookSelector QListWidget::item {
|
||||
padding-top: $10px;
|
||||
padding-bottom: $10px;
|
||||
padding-top: $5px;
|
||||
padding-bottom: $5px;
|
||||
}
|
||||
|
||||
QComboBox#NotebookSelector QListWidget::item:hover {
|
||||
|
@ -113,6 +113,10 @@ search_hit_item_bg=#CCE7E4
|
||||
ue_cmd_busy_border=#3F51B5
|
||||
ue_cmd_fail_border=@danger_bg
|
||||
|
||||
; VListWidget/VTreeWidget separator.
|
||||
item_separator_fg=@master_dark_bg
|
||||
item_separator_bg=@separator_bg
|
||||
|
||||
[widgets]
|
||||
; Widget color attributes.
|
||||
|
||||
@ -120,7 +124,7 @@ ue_cmd_fail_border=@danger_bg
|
||||
widget_fg=@base_fg
|
||||
|
||||
; Separator of dock widgets.
|
||||
dock_separator_bg=@border_bg
|
||||
dock_separator_bg=@separator_bg
|
||||
dock_separator_hover_bg=@hover_bg
|
||||
dock_separator_pressed_bg=@pressed_bg
|
||||
|
||||
@ -132,6 +136,7 @@ menubar_item_selected_bg=@selected_bg
|
||||
; Menu.
|
||||
menu_bg=@base_bg
|
||||
menu_fg=@base_fg
|
||||
menu_border_bg=@border_bg
|
||||
menu_item_disabled_fg=@disabled_fg
|
||||
menu_item_selected_fg=@selected_fg
|
||||
menu_item_selected_bg=@selected_bg
|
||||
|
@ -40,7 +40,7 @@ QMenuBar::item:selected {
|
||||
QMenu {
|
||||
background: @menu_bg;
|
||||
color: @menu_fg;
|
||||
margin: 2px;
|
||||
border: 2px solid @menu_border_bg;
|
||||
}
|
||||
|
||||
QMenu::icon {
|
||||
@ -402,10 +402,10 @@ VButtonMenuItem:disabled {
|
||||
/* QComboBox */
|
||||
QComboBox#NotebookSelector {
|
||||
border: none;
|
||||
font-size: 13pt;
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
icon-size: $30px;
|
||||
font-size: 12pt;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
icon-size: $24px;
|
||||
font-weight: bold;
|
||||
color: @combobox_notebookselector_fg;
|
||||
background: @combobox_notebookselector_bg;
|
||||
@ -424,14 +424,14 @@ QComboBox#NotebookSelector:hover {
|
||||
QComboBox#NotebookSelector QListWidget {
|
||||
border: 1px solid @combobox_view_border;
|
||||
background-color: @combobox_bg;
|
||||
font-size: 13pt;
|
||||
font-size: 12pt;
|
||||
font-weight: normal;
|
||||
icon-size: $30px;
|
||||
icon-size: $24px;
|
||||
}
|
||||
|
||||
QComboBox#NotebookSelector QListWidget::item {
|
||||
padding-top: $10px;
|
||||
padding-bottom: $10px;
|
||||
padding-top: $5px;
|
||||
padding-bottom: $5px;
|
||||
}
|
||||
|
||||
QComboBox#NotebookSelector QListWidget::item:hover {
|
||||
@ -851,6 +851,10 @@ QListView::item:selected:!active {
|
||||
color: @listview_item_selected_inactive_fg;
|
||||
background: @listview_item_selected_inactive_bg;
|
||||
}
|
||||
|
||||
QListView::item:disabled {
|
||||
background: transparent;
|
||||
}
|
||||
/* End QListView */
|
||||
|
||||
/* QSplitter */
|
||||
@ -1249,6 +1253,10 @@ QWidget[ToolBoxTitle="true"] {
|
||||
border-bottom: $2px solid @toolbox_title_border;
|
||||
}
|
||||
|
||||
QWidget[ToolBoxTitle="true"] QPushButton[ToolBoxTitleBtn="true"] {
|
||||
height: $20px;
|
||||
}
|
||||
|
||||
QWidget[MainEditor="true"] {
|
||||
border: none;
|
||||
}
|
||||
|
@ -209,6 +209,10 @@ enable_wildcard_in_simple_search=true
|
||||
; scope,object,target,engine,option,pattern
|
||||
search_options=4,2,7,0,0,""
|
||||
|
||||
; Number of items in history
|
||||
; 0 to disable history
|
||||
history_size=50
|
||||
|
||||
[export]
|
||||
; Path of the wkhtmltopdf tool
|
||||
wkhtmltopdf=wkhtmltopdf
|
||||
|
@ -131,7 +131,8 @@ SOURCES += main.cpp\
|
||||
vlivepreviewhelper.cpp \
|
||||
vmathjaxpreviewhelper.cpp \
|
||||
vmathjaxwebdocument.cpp \
|
||||
vmathjaxinplacepreviewhelper.cpp
|
||||
vmathjaxinplacepreviewhelper.cpp \
|
||||
vhistorylist.cpp
|
||||
|
||||
HEADERS += vmainwindow.h \
|
||||
vdirectorytree.h \
|
||||
@ -254,7 +255,9 @@ HEADERS += vmainwindow.h \
|
||||
vmathjaxpreviewhelper.h \
|
||||
vmathjaxwebdocument.h \
|
||||
vmathjaxinplacepreviewhelper.h \
|
||||
markdownitoption.h
|
||||
markdownitoption.h \
|
||||
vhistorylist.h \
|
||||
vhistoryentry.h
|
||||
|
||||
RESOURCES += \
|
||||
vnote.qrc \
|
||||
|
@ -41,7 +41,7 @@ void VCart::setupUI()
|
||||
g_mainWin,
|
||||
MessageBoxType::Danger);
|
||||
if (ret == QMessageBox::Ok) {
|
||||
m_itemList->clear();
|
||||
m_itemList->clearAll();
|
||||
updateNumberLabel();
|
||||
}
|
||||
}
|
||||
@ -55,7 +55,7 @@ void VCart::setupUI()
|
||||
btnLayout->addWidget(m_numLabel);
|
||||
btnLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
m_itemList = new QListWidget();
|
||||
m_itemList = new VListWidget();
|
||||
m_itemList->setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||
m_itemList->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
m_itemList->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
@ -109,9 +109,9 @@ void VCart::handleContextMenuRequested(QPoint p_pos)
|
||||
menu.setToolTipsVisible(true);
|
||||
|
||||
if (item) {
|
||||
int itemCount = m_itemList->selectedItems().size();
|
||||
if (itemCount == 1) {
|
||||
menu.addAction(m_openAct);
|
||||
|
||||
if (m_itemList->selectedItems().size() == 1) {
|
||||
menu.addAction(m_locateAct);
|
||||
}
|
||||
|
||||
@ -174,7 +174,15 @@ void VCart::deleteSelectedItems()
|
||||
|
||||
void VCart::openSelectedItems() const
|
||||
{
|
||||
openItem(m_itemList->currentItem());
|
||||
QStringList files;
|
||||
QList<QListWidgetItem *> selectedItems = m_itemList->selectedItems();
|
||||
for (auto it : selectedItems) {
|
||||
files << getFilePath(it);
|
||||
}
|
||||
|
||||
if (!files.isEmpty()) {
|
||||
g_mainWin->openFiles(files);
|
||||
}
|
||||
}
|
||||
|
||||
void VCart::locateCurrentItem()
|
||||
@ -266,3 +274,22 @@ void VCart::updateNumberLabel() const
|
||||
m_numLabel->setText(tr("%1 %2").arg(cnt)
|
||||
.arg(cnt > 1 ? tr("Items") : tr("Item")));
|
||||
}
|
||||
|
||||
void VCart::showNavigation()
|
||||
{
|
||||
VNavigationMode::showNavigation(m_itemList);
|
||||
}
|
||||
|
||||
bool VCart::handleKeyNavigation(int p_key, bool &p_succeed)
|
||||
{
|
||||
static bool secondKey = false;
|
||||
return VNavigationMode::handleKeyNavigation(m_itemList,
|
||||
secondKey,
|
||||
p_key,
|
||||
p_succeed);
|
||||
}
|
||||
|
||||
QWidget *VCart::getContentWidget() const
|
||||
{
|
||||
return m_itemList;
|
||||
}
|
||||
|
14
src/vcart.h
14
src/vcart.h
@ -7,14 +7,12 @@
|
||||
#include "vnavigationmode.h"
|
||||
|
||||
class QPushButton;
|
||||
class QListWidget;
|
||||
class VListWidget;
|
||||
class QListWidgetItem;
|
||||
class QLabel;
|
||||
class QAction;
|
||||
class QKeyEvent;
|
||||
class QFocusEvent;
|
||||
|
||||
class VCart : public QWidget
|
||||
class VCart : public QWidget, public VNavigationMode
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@ -26,6 +24,12 @@ public:
|
||||
|
||||
QVector<QString> getFiles() const;
|
||||
|
||||
QWidget *getContentWidget() const;
|
||||
|
||||
// Implementations for VNavigationMode.
|
||||
void showNavigation() Q_DECL_OVERRIDE;
|
||||
bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE;
|
||||
|
||||
private slots:
|
||||
void handleContextMenuRequested(QPoint p_pos);
|
||||
|
||||
@ -55,7 +59,7 @@ private:
|
||||
|
||||
QPushButton *m_clearBtn;
|
||||
QLabel *m_numLabel;
|
||||
QListWidget *m_itemList;
|
||||
VListWidget *m_itemList;
|
||||
|
||||
QAction *m_openAct;
|
||||
QAction *m_locateAct;
|
||||
|
@ -293,6 +293,11 @@ void VConfigManager::initialize()
|
||||
|
||||
m_enableGraphviz = getConfigFromSettings("global", "enable_graphviz").toBool();
|
||||
m_graphvizDot = getConfigFromSettings("web", "graphviz_dot").toString();
|
||||
|
||||
m_historySize = getConfigFromSettings("global", "history_size").toInt();
|
||||
if (m_historySize < 0) {
|
||||
m_historySize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void VConfigManager::initSettings()
|
||||
@ -1210,9 +1215,42 @@ void VConfigManager::setLastOpenedFiles(const QVector<VFileSessionInfo> &p_files
|
||||
}
|
||||
|
||||
m_sessionSettings->endArray();
|
||||
qDebug() << "write" << p_files.size()
|
||||
<< "items in [last_opened_files] section";
|
||||
}
|
||||
|
||||
void VConfigManager::getHistory(QLinkedList<VHistoryEntry> &p_history)
|
||||
{
|
||||
p_history.clear();
|
||||
|
||||
int size = m_sessionSettings->beginReadArray("history");
|
||||
for (int i = 0; i < size; ++i) {
|
||||
m_sessionSettings->setArrayIndex(i);
|
||||
p_history.append(VHistoryEntry::fromSettings(m_sessionSettings));
|
||||
}
|
||||
|
||||
m_sessionSettings->endArray();
|
||||
}
|
||||
|
||||
void VConfigManager::setHistory(const QLinkedList<VHistoryEntry> &p_history)
|
||||
{
|
||||
if (m_hasReset) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QString section("history");
|
||||
|
||||
// Clear it first
|
||||
m_sessionSettings->beginGroup(section);
|
||||
m_sessionSettings->remove("");
|
||||
m_sessionSettings->endGroup();
|
||||
|
||||
m_sessionSettings->beginWriteArray(section);
|
||||
int i = 0;
|
||||
for (auto it = p_history.begin(); it != p_history.end(); ++it, ++i) {
|
||||
m_sessionSettings->setArrayIndex(i);
|
||||
it->toSettings(m_sessionSettings);
|
||||
}
|
||||
|
||||
m_sessionSettings->endArray();
|
||||
}
|
||||
|
||||
QVector<VMagicWord> VConfigManager::getCustomMagicWords()
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <QVector>
|
||||
#include <QSettings>
|
||||
#include <QHash>
|
||||
#include <QLinkedList>
|
||||
|
||||
#include "vnotebook.h"
|
||||
#include "hgmarkdownhighlighter.h"
|
||||
@ -15,6 +16,7 @@
|
||||
#include "vfilesessioninfo.h"
|
||||
#include "utils/vmetawordmanager.h"
|
||||
#include "markdownitoption.h"
|
||||
#include "vhistoryentry.h"
|
||||
|
||||
class QJsonObject;
|
||||
class QString;
|
||||
@ -356,6 +358,13 @@ public:
|
||||
// Write last opened files to [last_opened_files] of session.ini.
|
||||
void setLastOpenedFiles(const QVector<VFileSessionInfo> &p_files);
|
||||
|
||||
// Read history from [history] of session.ini.
|
||||
void getHistory(QLinkedList<VHistoryEntry> &p_history);
|
||||
|
||||
void setHistory(const QLinkedList<VHistoryEntry> &p_history);
|
||||
|
||||
int getHistorySize() const;
|
||||
|
||||
// Read custom magic words from [magic_words] section.
|
||||
QVector<VMagicWord> getCustomMagicWords();
|
||||
|
||||
@ -884,6 +893,9 @@ private:
|
||||
|
||||
QString m_plantUMLCmd;
|
||||
|
||||
// Size of history.
|
||||
int m_historySize;
|
||||
|
||||
// The name of the config file in each directory, obsolete.
|
||||
// Use c_dirConfigFile instead.
|
||||
static const QString c_obsoleteDirConfigFile;
|
||||
@ -2284,4 +2296,9 @@ inline void VConfigManager::setGraphvizDot(const QString &p_dotPath)
|
||||
m_graphvizDot = p_dotPath;
|
||||
setConfigToSettings("web", "graphviz_dot", p_dotPath);
|
||||
}
|
||||
|
||||
inline int VConfigManager::getHistorySize() const
|
||||
{
|
||||
return m_historySize;
|
||||
}
|
||||
#endif // VCONFIGMANAGER_H
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "utils/vimnavigationforwidget.h"
|
||||
#include "utils/viconutils.h"
|
||||
#include "vfilelist.h"
|
||||
#include "vhistorylist.h"
|
||||
|
||||
extern VMainWindow *g_mainWin;
|
||||
|
||||
@ -146,6 +147,13 @@ void VDirectoryTree::initActions()
|
||||
connect(m_openLocationAct, &QAction::triggered,
|
||||
this, &VDirectoryTree::openDirectoryLocation);
|
||||
|
||||
m_pinToHistoryAct = new QAction(VIconUtils::menuIcon(":/resources/icons/pin.svg"),
|
||||
tr("Pin To History"),
|
||||
this);
|
||||
m_pinToHistoryAct->setToolTip(tr("Pin selected folder to History"));
|
||||
connect(m_pinToHistoryAct, &QAction::triggered,
|
||||
this, &VDirectoryTree::pinDirectoryToHistory);
|
||||
|
||||
m_reloadAct = new QAction(tr("&Reload From Disk"), this);
|
||||
m_reloadAct->setToolTip(tr("Reload the content of this folder (or notebook) from disk"));
|
||||
connect(m_reloadAct, &QAction::triggered,
|
||||
@ -435,6 +443,7 @@ void VDirectoryTree::contextMenuRequested(QPoint pos)
|
||||
|
||||
if (item) {
|
||||
menu.addAction(m_openLocationAct);
|
||||
menu.addAction(m_pinToHistoryAct);
|
||||
menu.addAction(dirInfoAct);
|
||||
}
|
||||
|
||||
@ -1211,3 +1220,11 @@ VDirectory *VDirectoryTree::currentDirectory() const
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void VDirectoryTree::pinDirectoryToHistory()
|
||||
{
|
||||
QTreeWidgetItem *curItem = currentItem();
|
||||
V_ASSERT(curItem);
|
||||
g_mainWin->getHistoryList()->pinFolder(getVDirectory(curItem)->fetchPath());
|
||||
g_mainWin->showStatusMessage(tr("1 folder pinned to History"));
|
||||
}
|
||||
|
@ -93,6 +93,9 @@ private slots:
|
||||
// Sort sub-folders of current item's folder.
|
||||
void sortItems();
|
||||
|
||||
// Pin selected directory to History.
|
||||
void pinDirectoryToHistory();
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
@ -176,6 +179,7 @@ private:
|
||||
QAction *cutAct;
|
||||
QAction *pasteAct;
|
||||
QAction *m_openLocationAct;
|
||||
QAction *m_pinToHistoryAct;
|
||||
QAction *m_sortAct;
|
||||
|
||||
// Reload content from disk.
|
||||
|
@ -1131,7 +1131,8 @@ void VEditArea::recordClosedFile(const VFileSessionInfo &p_file)
|
||||
}
|
||||
|
||||
m_lastClosedFiles.push(p_file);
|
||||
qDebug() << "pushed closed file" << p_file.m_file;
|
||||
|
||||
emit fileClosed(p_file.m_file);
|
||||
}
|
||||
|
||||
void VEditArea::handleFileTimerTimeout()
|
||||
|
@ -105,6 +105,9 @@ signals:
|
||||
// Emit when Vim status updated.
|
||||
void vimStatusUpdated(const VVim *p_vim);
|
||||
|
||||
// Emit when @p_file is closed.
|
||||
void fileClosed(const QString &p_file);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "vconfigmanager.h"
|
||||
#include "utils/viconutils.h"
|
||||
#include "vcart.h"
|
||||
#include "vhistorylist.h"
|
||||
|
||||
extern VConfigManager *g_config;
|
||||
extern VMainWindow *g_mainWin;
|
||||
@ -167,7 +168,9 @@ void VEditWindow::initTabActions()
|
||||
}
|
||||
});
|
||||
|
||||
m_addToCartAct = new QAction(tr("Add To Cart"), this);
|
||||
m_addToCartAct = new QAction(VIconUtils::menuIcon(":/resources/icons/cart.svg"),
|
||||
tr("Add To Cart"),
|
||||
this);
|
||||
m_addToCartAct->setToolTip(tr("Add this note to Cart for further processing"));
|
||||
connect(m_addToCartAct, &QAction::triggered,
|
||||
this, [this](){
|
||||
@ -181,6 +184,24 @@ void VEditWindow::initTabActions()
|
||||
g_mainWin->showStatusMessage(tr("1 note added to Cart"));
|
||||
});
|
||||
|
||||
m_pinToHistoryAct = new QAction(VIconUtils::menuIcon(":/resources/icons/pin.svg"),
|
||||
tr("Pin To History"),
|
||||
this);
|
||||
m_pinToHistoryAct->setToolTip(tr("Pin this note to History"));
|
||||
connect(m_pinToHistoryAct, &QAction::triggered,
|
||||
this, [this](){
|
||||
int tab = this->m_pinToHistoryAct->data().toInt();
|
||||
Q_ASSERT(tab != -1);
|
||||
|
||||
VEditTab *editor = getTab(tab);
|
||||
QPointer<VFile> file = editor->getFile();
|
||||
Q_ASSERT(file);
|
||||
QStringList files;
|
||||
files << file->fetchPath();
|
||||
g_mainWin->getHistoryList()->pinFiles(files);
|
||||
g_mainWin->showStatusMessage(tr("1 note pinned to History"));
|
||||
});
|
||||
|
||||
m_openLocationAct = new QAction(tr("Open Note Location"), this);
|
||||
m_openLocationAct->setToolTip(tr("Open the folder containing this note in operating system"));
|
||||
connect(m_openLocationAct, &QAction::triggered,
|
||||
@ -692,6 +713,9 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos)
|
||||
m_addToCartAct->setData(tab);
|
||||
menu.addAction(m_addToCartAct);
|
||||
|
||||
m_pinToHistoryAct->setData(tab);
|
||||
menu.addAction(m_pinToHistoryAct);
|
||||
|
||||
m_noteInfoAct->setData(tab);
|
||||
menu.addAction(m_noteInfoAct);
|
||||
} else if (file->getType() == FileType::Orphan
|
||||
@ -708,6 +732,9 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos)
|
||||
m_addToCartAct->setData(tab);
|
||||
menu.addAction(m_addToCartAct);
|
||||
|
||||
m_pinToHistoryAct->setData(tab);
|
||||
menu.addAction(m_pinToHistoryAct);
|
||||
|
||||
m_noteInfoAct->setData(tab);
|
||||
menu.addAction(m_noteInfoAct);
|
||||
}
|
||||
|
@ -231,6 +231,9 @@ private:
|
||||
// Add this note to Cart.
|
||||
QAction *m_addToCartAct;
|
||||
|
||||
// Pin this note to History.
|
||||
QAction *m_pinToHistoryAct;
|
||||
|
||||
// Open the location (the folder containing this file) of this note.
|
||||
QAction *m_openLocationAct;
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "utils/viconutils.h"
|
||||
#include "dialog/vtipsdialog.h"
|
||||
#include "vcart.h"
|
||||
#include "vhistorylist.h"
|
||||
|
||||
extern VConfigManager *g_config;
|
||||
extern VNote *g_vnote;
|
||||
@ -190,11 +191,20 @@ void VFileList::initActions()
|
||||
connect(m_openLocationAct, &QAction::triggered,
|
||||
this, &VFileList::openFileLocation);
|
||||
|
||||
m_addToCartAct = new QAction(tr("Add To Cart"), this);
|
||||
m_addToCartAct = new QAction(VIconUtils::menuIcon(":/resources/icons/cart.svg"),
|
||||
tr("Add To Cart"),
|
||||
this);
|
||||
m_addToCartAct->setToolTip(tr("Add selected notes to Cart for further processing"));
|
||||
connect(m_addToCartAct, &QAction::triggered,
|
||||
this, &VFileList::addFileToCart);
|
||||
|
||||
m_pinToHistoryAct = new QAction(VIconUtils::menuIcon(":/resources/icons/pin.svg"),
|
||||
tr("Pin To History"),
|
||||
this);
|
||||
m_pinToHistoryAct->setToolTip(tr("Pin selected notes to History"));
|
||||
connect(m_pinToHistoryAct, &QAction::triggered,
|
||||
this, &VFileList::pinFileToHistory);
|
||||
|
||||
m_sortAct = new QAction(VIconUtils::menuIcon(":/resources/icons/sort.svg"),
|
||||
tr("&Sort"),
|
||||
this);
|
||||
@ -276,6 +286,22 @@ void VFileList::addFileToCart() const
|
||||
.arg(items.size() > 1 ? tr("notes") : tr("note")));
|
||||
}
|
||||
|
||||
void VFileList::pinFileToHistory() const
|
||||
{
|
||||
QList<QListWidgetItem *> items = fileList->selectedItems();
|
||||
|
||||
QStringList files;
|
||||
for (int i = 0; i < items.size(); ++i) {
|
||||
files << getVFile(items[i])->fetchPath();
|
||||
}
|
||||
|
||||
g_mainWin->getHistoryList()->pinFiles(files);
|
||||
|
||||
g_mainWin->showStatusMessage(tr("%1 %2 pinned to History")
|
||||
.arg(items.size())
|
||||
.arg(items.size() > 1 ? tr("notes") : tr("note")));
|
||||
}
|
||||
|
||||
void VFileList::fileInfo(VNoteFile *p_file)
|
||||
{
|
||||
if (!p_file) {
|
||||
@ -621,6 +647,7 @@ void VFileList::contextMenuRequested(QPoint pos)
|
||||
}
|
||||
|
||||
menu.addAction(m_addToCartAct);
|
||||
menu.addAction(m_pinToHistoryAct);
|
||||
|
||||
if (selectedSize == 1) {
|
||||
menu.addAction(fileInfoAct);
|
||||
|
@ -89,6 +89,9 @@ private slots:
|
||||
// Add selected files to Cart.
|
||||
void addFileToCart() const;
|
||||
|
||||
// Add selected files to History and pin them.
|
||||
void pinFileToHistory() const;
|
||||
|
||||
// Copy selected files to clipboard.
|
||||
// Will put a Json string into the clipboard which contains the information
|
||||
// about copied files.
|
||||
@ -195,6 +198,8 @@ private:
|
||||
|
||||
QAction *m_addToCartAct;
|
||||
|
||||
QAction *m_pinToHistoryAct;
|
||||
|
||||
// Context sub-menu of Open With.
|
||||
QMenu *m_openWithMenu;
|
||||
|
||||
|
64
src/vhistoryentry.h
Normal file
64
src/vhistoryentry.h
Normal file
@ -0,0 +1,64 @@
|
||||
#ifndef VHISTORYENTRY_H
|
||||
#define VHISTORYENTRY_H
|
||||
|
||||
#include <QDate>
|
||||
#include <QSettings>
|
||||
|
||||
namespace HistoryConfig
|
||||
{
|
||||
static const QString c_file = "file";
|
||||
static const QString c_date = "date";
|
||||
static const QString c_pinned = "pinned";
|
||||
static const QString c_isFolder = "is_folder";
|
||||
}
|
||||
|
||||
class VHistoryEntry
|
||||
{
|
||||
public:
|
||||
VHistoryEntry()
|
||||
: m_isPinned(false),
|
||||
m_isFolder(false)
|
||||
{
|
||||
}
|
||||
|
||||
VHistoryEntry(const QString &p_file,
|
||||
const QDate &p_date,
|
||||
bool p_isPinned = false,
|
||||
bool p_isFolder = false)
|
||||
: m_file(p_file), m_isPinned(p_isPinned), m_isFolder(p_isFolder)
|
||||
{
|
||||
m_date = p_date.toString(Qt::ISODate);
|
||||
}
|
||||
|
||||
// Fetch VHistoryEntry from @p_settings.
|
||||
static VHistoryEntry fromSettings(const QSettings *p_settings)
|
||||
{
|
||||
VHistoryEntry entry;
|
||||
entry.m_file = p_settings->value(HistoryConfig::c_file).toString();
|
||||
entry.m_date = p_settings->value(HistoryConfig::c_date).toString();
|
||||
entry.m_isPinned = p_settings->value(HistoryConfig::c_pinned).toBool();
|
||||
entry.m_isFolder = p_settings->value(HistoryConfig::c_isFolder).toBool();
|
||||
return entry;
|
||||
}
|
||||
|
||||
void toSettings(QSettings *p_settings) const
|
||||
{
|
||||
p_settings->setValue(HistoryConfig::c_file, m_file);
|
||||
p_settings->setValue(HistoryConfig::c_date, m_date);
|
||||
p_settings->setValue(HistoryConfig::c_pinned, m_isPinned);
|
||||
p_settings->setValue(HistoryConfig::c_isFolder, m_isFolder);
|
||||
}
|
||||
|
||||
// File path.
|
||||
QString m_file;
|
||||
|
||||
// Accessed date.
|
||||
// UTC in Qt::ISODate format.
|
||||
QString m_date;
|
||||
|
||||
bool m_isPinned;
|
||||
|
||||
bool m_isFolder;
|
||||
};
|
||||
|
||||
#endif // VHISTORYENTRY_H
|
507
src/vhistorylist.cpp
Normal file
507
src/vhistorylist.cpp
Normal file
@ -0,0 +1,507 @@
|
||||
#include "vhistorylist.h"
|
||||
|
||||
#include <QtWidgets>
|
||||
#include <QDebug>
|
||||
|
||||
#include "utils/viconutils.h"
|
||||
#include "utils/vutils.h"
|
||||
#include "vlistwidget.h"
|
||||
#include "vconfigmanager.h"
|
||||
#include "vmainwindow.h"
|
||||
#include "vcart.h"
|
||||
#include "vnote.h"
|
||||
#include "vnotefile.h"
|
||||
#include "vdirectory.h"
|
||||
|
||||
extern VMainWindow *g_mainWin;
|
||||
|
||||
extern VConfigManager *g_config;
|
||||
|
||||
extern VNote *g_vnote;
|
||||
|
||||
VHistoryList::VHistoryList(QWidget *p_parent)
|
||||
: QWidget(p_parent),
|
||||
m_initialized(false),
|
||||
m_updatePending(true),
|
||||
m_currentDate(QDate::currentDate())
|
||||
{
|
||||
setupUI();
|
||||
}
|
||||
|
||||
void VHistoryList::setupUI()
|
||||
{
|
||||
m_clearBtn = new QPushButton(VIconUtils::buttonDangerIcon(":/resources/icons/clear_history.svg"), "");
|
||||
m_clearBtn->setToolTip(tr("Clear"));
|
||||
m_clearBtn->setProperty("FlatBtn", true);
|
||||
connect(m_clearBtn, &QPushButton::clicked,
|
||||
this, [this]() {
|
||||
init();
|
||||
|
||||
if (m_histories.size() > 0) {
|
||||
int ret = VUtils::showMessage(QMessageBox::Warning,
|
||||
tr("Warning"),
|
||||
tr("Are you sure to clear History?"),
|
||||
"",
|
||||
QMessageBox::Ok | QMessageBox::Cancel,
|
||||
QMessageBox::Ok,
|
||||
g_mainWin,
|
||||
MessageBoxType::Danger);
|
||||
if (ret == QMessageBox::Ok) {
|
||||
m_histories.clear();
|
||||
g_config->setHistory(m_histories);
|
||||
m_updatePending = true;
|
||||
updateList();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
QHBoxLayout *btnLayout = new QHBoxLayout;
|
||||
btnLayout->addWidget(m_clearBtn);
|
||||
btnLayout->addStretch();
|
||||
btnLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
m_itemList = new VListWidget();
|
||||
m_itemList->setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||
m_itemList->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
m_itemList->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
connect(m_itemList, &QListWidget::customContextMenuRequested,
|
||||
this, &VHistoryList::handleContextMenuRequested);
|
||||
connect(m_itemList, &QListWidget::itemActivated,
|
||||
this, &VHistoryList::openItem);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout();
|
||||
mainLayout->addLayout(btnLayout);
|
||||
mainLayout->addWidget(m_itemList);
|
||||
mainLayout->setContentsMargins(3, 0, 3, 0);
|
||||
|
||||
setLayout(mainLayout);
|
||||
}
|
||||
|
||||
void VHistoryList::initActions()
|
||||
{
|
||||
m_openAct = new QAction(tr("&Open"), this);
|
||||
m_openAct->setToolTip(tr("Open selected notes"));
|
||||
connect(m_openAct, &QAction::triggered,
|
||||
this, &VHistoryList::openSelectedItems);
|
||||
|
||||
m_locateAct = new QAction(VIconUtils::menuIcon(":/resources/icons/locate_note.svg"),
|
||||
tr("&Locate To Folder"),
|
||||
this);
|
||||
m_locateAct->setToolTip(tr("Locate the folder of current note"));
|
||||
connect(m_locateAct, &QAction::triggered,
|
||||
this, &VHistoryList::locateCurrentItem);
|
||||
|
||||
m_pinAct = new QAction(VIconUtils::menuIcon(":/resources/icons/pin.svg"),
|
||||
tr("Pin"),
|
||||
this);
|
||||
m_pinAct->setToolTip(tr("Pin selected notes in History"));
|
||||
connect(m_pinAct, &QAction::triggered,
|
||||
this, &VHistoryList::pinSelectedItems);
|
||||
|
||||
m_unpinAct = new QAction(tr("Unpin"), this);
|
||||
m_unpinAct->setToolTip(tr("Unpin selected notes in History"));
|
||||
connect(m_unpinAct, &QAction::triggered,
|
||||
this, &VHistoryList::unpinSelectedItems);
|
||||
|
||||
m_addToCartAct = new QAction(VIconUtils::menuIcon(":/resources/icons/cart.svg"),
|
||||
tr("Add To Cart"),
|
||||
this);
|
||||
m_addToCartAct->setToolTip(tr("Add selected notes to Cart for further processing"));
|
||||
connect(m_addToCartAct, &QAction::triggered,
|
||||
this, &VHistoryList::addFileToCart);
|
||||
}
|
||||
|
||||
void VHistoryList::addFile(const QString &p_filePath)
|
||||
{
|
||||
init();
|
||||
|
||||
QStringList files;
|
||||
files << p_filePath;
|
||||
addFilesInternal(files, false);
|
||||
|
||||
if (isVisible()) {
|
||||
updateList();
|
||||
}
|
||||
}
|
||||
|
||||
void VHistoryList::pinFiles(const QStringList &p_files)
|
||||
{
|
||||
init();
|
||||
|
||||
addFilesInternal(p_files, true);
|
||||
if (isVisible()) {
|
||||
updateList();
|
||||
}
|
||||
}
|
||||
|
||||
void VHistoryList::unpinFiles(const QStringList &p_files)
|
||||
{
|
||||
init();
|
||||
|
||||
for (auto const & file : p_files) {
|
||||
auto it = findFileInHistory(file);
|
||||
if (it != m_histories.end()) {
|
||||
it->m_isPinned = false;
|
||||
}
|
||||
}
|
||||
|
||||
g_config->setHistory(m_histories);
|
||||
m_updatePending = true;
|
||||
}
|
||||
|
||||
void VHistoryList::pinFolder(const QString &p_folder)
|
||||
{
|
||||
init();
|
||||
|
||||
auto it = findFileInHistory(p_folder);
|
||||
if (it != m_histories.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_histories.append(VHistoryEntry(p_folder, QDate::currentDate(), true, true));
|
||||
|
||||
checkHistorySize();
|
||||
|
||||
g_config->setHistory(m_histories);
|
||||
m_updatePending = true;
|
||||
|
||||
if (isVisible()) {
|
||||
updateList();
|
||||
}
|
||||
}
|
||||
|
||||
void VHistoryList::addFilesInternal(const QStringList &p_files, bool p_isPinned)
|
||||
{
|
||||
for (auto const & file : p_files) {
|
||||
// Find it in existing enries.
|
||||
bool pinnedBefore = false;
|
||||
auto it = findFileInHistory(file);
|
||||
if (it != m_histories.end()) {
|
||||
pinnedBefore = it->m_isPinned;
|
||||
m_histories.erase(it);
|
||||
}
|
||||
|
||||
// Append an entry at the end.
|
||||
bool pin = p_isPinned ? true : (pinnedBefore ? true : false);
|
||||
m_histories.append(VHistoryEntry(file, QDate::currentDate(), pin));
|
||||
}
|
||||
|
||||
checkHistorySize();
|
||||
|
||||
g_config->setHistory(m_histories);
|
||||
m_updatePending = true;
|
||||
}
|
||||
|
||||
void VHistoryList::checkHistorySize()
|
||||
{
|
||||
int numToRemove = m_histories.size() - g_config->getHistorySize();
|
||||
for (auto rit = m_histories.begin(); numToRemove > 0 && rit != m_histories.end();) {
|
||||
if (rit->m_isPinned) {
|
||||
++rit;
|
||||
continue;
|
||||
}
|
||||
|
||||
rit = m_histories.erase(rit);
|
||||
--numToRemove;
|
||||
}
|
||||
}
|
||||
|
||||
void VHistoryList::init()
|
||||
{
|
||||
if (m_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_folderIcon = VIconUtils::treeViewIcon(":/resources/icons/dir_item.svg");
|
||||
|
||||
initActions();
|
||||
|
||||
g_config->getHistory(m_histories);
|
||||
|
||||
m_initialized = true;
|
||||
m_updatePending = true;
|
||||
}
|
||||
|
||||
void VHistoryList::showEvent(QShowEvent *p_event)
|
||||
{
|
||||
init();
|
||||
|
||||
if (m_currentDate != QDate::currentDate()) {
|
||||
m_currentDate = QDate::currentDate();
|
||||
m_updatePending = true;
|
||||
}
|
||||
|
||||
updateList();
|
||||
|
||||
QWidget::showEvent(p_event);
|
||||
}
|
||||
|
||||
QLinkedList<VHistoryEntry>::iterator VHistoryList::findFileInHistory(const QString &p_file)
|
||||
{
|
||||
for (QLinkedList<VHistoryEntry>::iterator it = m_histories.begin();
|
||||
it != m_histories.end();
|
||||
++it) {
|
||||
if (VUtils::equalPath(p_file, it->m_file)) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
|
||||
return m_histories.end();
|
||||
}
|
||||
|
||||
struct SeparatorItem
|
||||
{
|
||||
SeparatorItem()
|
||||
: m_valid(false)
|
||||
{
|
||||
}
|
||||
|
||||
QString m_date;
|
||||
QListWidgetItem *m_item;
|
||||
bool m_valid;
|
||||
};
|
||||
|
||||
void VHistoryList::updateList()
|
||||
{
|
||||
if (!m_updatePending) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_updatePending = false;
|
||||
|
||||
m_itemList->clearAll();
|
||||
|
||||
if (m_histories.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add separators.
|
||||
// Pinned separator.
|
||||
SeparatorItem pinItem;
|
||||
pinItem.m_item = VListWidget::createSeparatorItem(tr("Pinned"));
|
||||
m_itemList->addItem(pinItem.m_item);
|
||||
|
||||
const int sepSize = 4;
|
||||
QString sepText[4] = {tr("Today"), tr("Yesterday"), tr("Last 7 Days"), tr("Older")};
|
||||
QVector<SeparatorItem> seps(sepSize);
|
||||
|
||||
seps[0].m_date = m_currentDate.toString(Qt::ISODate);
|
||||
seps[1].m_date = m_currentDate.addDays(-1).toString(Qt::ISODate);
|
||||
seps[2].m_date = m_currentDate.addDays(-7).toString(Qt::ISODate);
|
||||
// Leave the last string empty.
|
||||
|
||||
for (int i = 0; i < sepSize; ++i) {
|
||||
seps[i].m_item = VListWidget::createSeparatorItem(sepText[i]);
|
||||
m_itemList->addItem(seps[i].m_item);
|
||||
}
|
||||
|
||||
for (auto it = m_histories.cbegin(); it != m_histories.cend(); ++it) {
|
||||
QListWidgetItem *item = new QListWidgetItem(VUtils::fileNameFromPath(it->m_file));
|
||||
item->setToolTip(it->m_file);
|
||||
item->setData(Qt::UserRole, (qulonglong)&(*it));
|
||||
|
||||
if (it->m_isFolder) {
|
||||
item->setIcon(m_folderIcon);
|
||||
}
|
||||
|
||||
if (it->m_isPinned) {
|
||||
m_itemList->insertItem(m_itemList->row(pinItem.m_item) + 1, item);
|
||||
pinItem.m_valid = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sepSize; ++i) {
|
||||
if (it->m_date >= seps[i].m_date) {
|
||||
m_itemList->insertItem(m_itemList->row(seps[i].m_item) + 1, item);
|
||||
seps[i].m_valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We always display pinned separator.
|
||||
|
||||
for (int i = 0; i < sepSize; ++i) {
|
||||
if (!seps[i].m_valid) {
|
||||
delete seps[i].m_item;
|
||||
}
|
||||
}
|
||||
|
||||
seps.clear();
|
||||
}
|
||||
|
||||
QWidget *VHistoryList::getContentWidget() const
|
||||
{
|
||||
return m_itemList;
|
||||
}
|
||||
|
||||
void VHistoryList::handleContextMenuRequested(QPoint p_pos)
|
||||
{
|
||||
QListWidgetItem *item = m_itemList->itemAt(p_pos);
|
||||
if (!item || VListWidget::isSeparatorItem(item)) {
|
||||
return;
|
||||
}
|
||||
|
||||
QMenu menu(this);
|
||||
menu.setToolTipsVisible(true);
|
||||
|
||||
menu.addAction(m_openAct);
|
||||
|
||||
QList<QListWidgetItem *> selectedItems = m_itemList->selectedItems();
|
||||
if (selectedItems.size() == 1) {
|
||||
menu.addAction(m_locateAct);
|
||||
}
|
||||
|
||||
bool allPinned = true, allUnpinned = true;
|
||||
for (auto const & it : selectedItems) {
|
||||
if (getHistoryEntry(it)->m_isPinned) {
|
||||
allUnpinned = false;
|
||||
} else {
|
||||
allPinned = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (allUnpinned) {
|
||||
menu.addAction(m_pinAct);
|
||||
} else if (allPinned) {
|
||||
menu.addAction(m_unpinAct);
|
||||
}
|
||||
|
||||
menu.addSeparator();
|
||||
|
||||
menu.addAction(m_addToCartAct);
|
||||
|
||||
menu.exec(m_itemList->mapToGlobal(p_pos));
|
||||
}
|
||||
|
||||
bool VHistoryList::isFolder(const QListWidgetItem *p_item) const
|
||||
{
|
||||
return getHistoryEntry(p_item)->m_isFolder;
|
||||
}
|
||||
|
||||
VHistoryEntry *VHistoryList::getHistoryEntry(const QListWidgetItem *p_item) const
|
||||
{
|
||||
return (VHistoryEntry *)p_item->data(Qt::UserRole).toULongLong();
|
||||
}
|
||||
|
||||
QString VHistoryList::getFilePath(const QListWidgetItem *p_item) const
|
||||
{
|
||||
return getHistoryEntry(p_item)->m_file;
|
||||
}
|
||||
|
||||
void VHistoryList::pinSelectedItems()
|
||||
{
|
||||
QStringList files;
|
||||
QList<QListWidgetItem *> selectedItems = m_itemList->selectedItems();
|
||||
for (auto it : selectedItems) {
|
||||
files << getFilePath(it);
|
||||
}
|
||||
|
||||
pinFiles(files);
|
||||
}
|
||||
|
||||
void VHistoryList::unpinSelectedItems()
|
||||
{
|
||||
QStringList files;
|
||||
QList<QListWidgetItem *> selectedItems = m_itemList->selectedItems();
|
||||
for (auto it : selectedItems) {
|
||||
files << getFilePath(it);
|
||||
}
|
||||
|
||||
unpinFiles(files);
|
||||
|
||||
if (isVisible()) {
|
||||
updateList();
|
||||
}
|
||||
}
|
||||
|
||||
void VHistoryList::openSelectedItems() const
|
||||
{
|
||||
QStringList files;
|
||||
QList<QListWidgetItem *> selectedItems = m_itemList->selectedItems();
|
||||
|
||||
if (selectedItems.size() == 1 && isFolder(selectedItems.first())) {
|
||||
// Locate to the folder.
|
||||
VDirectory *dir = g_vnote->getInternalDirectory(getFilePath(selectedItems.first()));
|
||||
if (dir) {
|
||||
g_mainWin->locateDirectory(dir);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto it : selectedItems) {
|
||||
if (isFolder(it)) {
|
||||
// Skip folders.
|
||||
continue;
|
||||
}
|
||||
|
||||
files << getFilePath(it);
|
||||
}
|
||||
|
||||
if (!files.isEmpty()) {
|
||||
g_mainWin->openFiles(files);
|
||||
}
|
||||
}
|
||||
|
||||
void VHistoryList::openItem(const QListWidgetItem *p_item) const
|
||||
{
|
||||
if (!p_item) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isFolder(p_item)) {
|
||||
// Locate to the folder.
|
||||
VDirectory *dir = g_vnote->getInternalDirectory(getFilePath(p_item));
|
||||
if (dir) {
|
||||
g_mainWin->locateDirectory(dir);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList files;
|
||||
files << getFilePath(p_item);
|
||||
g_mainWin->openFiles(files);
|
||||
}
|
||||
|
||||
void VHistoryList::locateCurrentItem()
|
||||
{
|
||||
auto item = m_itemList->currentItem();
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
VFile *file = g_vnote->getInternalFile(getFilePath(item));
|
||||
if (file) {
|
||||
g_mainWin->locateFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
void VHistoryList::showNavigation()
|
||||
{
|
||||
VNavigationMode::showNavigation(m_itemList);
|
||||
}
|
||||
|
||||
bool VHistoryList::handleKeyNavigation(int p_key, bool &p_succeed)
|
||||
{
|
||||
static bool secondKey = false;
|
||||
return VNavigationMode::handleKeyNavigation(m_itemList,
|
||||
secondKey,
|
||||
p_key,
|
||||
p_succeed);
|
||||
}
|
||||
|
||||
void VHistoryList::addFileToCart() const
|
||||
{
|
||||
QList<QListWidgetItem *> items = m_itemList->selectedItems();
|
||||
VCart *cart = g_mainWin->getCart();
|
||||
|
||||
for (int i = 0; i < items.size(); ++i) {
|
||||
cart->addFile(getFilePath(items[i]));
|
||||
}
|
||||
|
||||
g_mainWin->showStatusMessage(tr("%1 %2 added to Cart")
|
||||
.arg(items.size())
|
||||
.arg(items.size() > 1 ? tr("notes") : tr("note")));
|
||||
}
|
104
src/vhistorylist.h
Normal file
104
src/vhistorylist.h
Normal file
@ -0,0 +1,104 @@
|
||||
#ifndef VHISTORYLIST_H
|
||||
#define VHISTORYLIST_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLinkedList>
|
||||
#include <QIcon>
|
||||
|
||||
#include "vhistoryentry.h"
|
||||
#include "vnavigationmode.h"
|
||||
|
||||
class QPushButton;
|
||||
class VListWidget;
|
||||
class QListWidgetItem;
|
||||
class QLabel;
|
||||
class QAction;
|
||||
class QShowEvent;
|
||||
|
||||
class VHistoryList : public QWidget, public VNavigationMode
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VHistoryList(QWidget *p_parent = nullptr);
|
||||
|
||||
QWidget *getContentWidget() const;
|
||||
|
||||
void pinFiles(const QStringList &p_files);
|
||||
|
||||
void pinFolder(const QString &p_folder);
|
||||
|
||||
// Implementations for VNavigationMode.
|
||||
void showNavigation() Q_DECL_OVERRIDE;
|
||||
bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE;
|
||||
|
||||
public slots:
|
||||
void addFile(const QString &p_filePath);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE;
|
||||
|
||||
private slots:
|
||||
void handleContextMenuRequested(QPoint p_pos);
|
||||
|
||||
void openSelectedItems() const;
|
||||
|
||||
void openItem(const QListWidgetItem *p_item) const;
|
||||
|
||||
void pinSelectedItems();
|
||||
|
||||
void unpinSelectedItems();
|
||||
|
||||
void locateCurrentItem();
|
||||
|
||||
// Add selected files to Cart.
|
||||
void addFileToCart() const;
|
||||
|
||||
private:
|
||||
void setupUI();
|
||||
|
||||
void initActions();
|
||||
|
||||
// Read data from config file.
|
||||
void init();
|
||||
|
||||
void updateList();
|
||||
|
||||
QLinkedList<VHistoryEntry>::iterator findFileInHistory(const QString &p_file);
|
||||
|
||||
QString getFilePath(const QListWidgetItem *p_item) const;
|
||||
|
||||
VHistoryEntry *getHistoryEntry(const QListWidgetItem *p_item) const;
|
||||
|
||||
bool isFolder(const QListWidgetItem *p_item) const;
|
||||
|
||||
// @p_isPinned won't change it if an item is pinned already.
|
||||
void addFilesInternal(const QStringList &p_files, bool p_isPinned);
|
||||
|
||||
void unpinFiles(const QStringList &p_files);
|
||||
|
||||
void checkHistorySize();
|
||||
|
||||
QPushButton *m_clearBtn;
|
||||
VListWidget *m_itemList;
|
||||
|
||||
QAction *m_openAct;
|
||||
QAction *m_locateAct;
|
||||
QAction *m_pinAct;
|
||||
QAction *m_unpinAct;
|
||||
QAction *m_addToCartAct;
|
||||
|
||||
// Whether data is loaded.
|
||||
bool m_initialized;
|
||||
|
||||
// New files are appended to the end.
|
||||
QLinkedList<VHistoryEntry> m_histories;
|
||||
|
||||
// Whether we need to update the list.
|
||||
bool m_updatePending;
|
||||
|
||||
QDate m_currentDate;
|
||||
|
||||
QIcon m_folderIcon;
|
||||
};
|
||||
|
||||
#endif // VHISTORYLIST_H
|
@ -8,6 +8,9 @@
|
||||
#include "utils/vutils.h"
|
||||
#include "utils/vimnavigationforwidget.h"
|
||||
#include "vstyleditemdelegate.h"
|
||||
#include "vpalette.h"
|
||||
|
||||
extern VPalette *g_palette;
|
||||
|
||||
VListWidget::VListWidget(QWidget *p_parent)
|
||||
: QListWidget(p_parent),
|
||||
@ -20,7 +23,7 @@ VListWidget::VListWidget(QWidget *p_parent)
|
||||
|
||||
m_searchInput->hide();
|
||||
|
||||
m_delegate = new VStyledItemDelegate(this);
|
||||
m_delegate = new VStyledItemDelegate(this, NULL);
|
||||
setItemDelegate(m_delegate);
|
||||
}
|
||||
|
||||
@ -108,6 +111,10 @@ QList<void *> VListWidget::searchItems(const QString &p_text,
|
||||
QList<void *> res;
|
||||
res.reserve(items.size());
|
||||
for (int i = 0; i < items.size(); ++i) {
|
||||
if (items[i]->type() == ItemTypeSeparator) {
|
||||
continue;
|
||||
}
|
||||
|
||||
res.append(items[i]);
|
||||
}
|
||||
|
||||
@ -212,3 +219,14 @@ QSize VListWidget::sizeHint() const
|
||||
}
|
||||
}
|
||||
|
||||
QListWidgetItem *VListWidget::createSeparatorItem(const QString &p_text)
|
||||
{
|
||||
QListWidgetItem *item = new QListWidgetItem(p_text, NULL, ItemTypeSeparator);
|
||||
item->setFlags(Qt::NoItemFlags);
|
||||
return item;
|
||||
}
|
||||
|
||||
bool VListWidget::isSeparatorItem(const QListWidgetItem *p_item)
|
||||
{
|
||||
return p_item->type() == ItemTypeSeparator;
|
||||
}
|
||||
|
@ -34,10 +34,14 @@ public:
|
||||
|
||||
virtual QSize sizeHint() const Q_DECL_OVERRIDE;
|
||||
|
||||
void setFitContent(bool p_enabled);
|
||||
|
||||
// Sort @p_list according to @p_sortedIdx.
|
||||
static void sortListWidget(QListWidget *p_list, const QVector<int> &p_sortedIdx);
|
||||
|
||||
void setFitContent(bool p_enabled);
|
||||
static QListWidgetItem *createSeparatorItem(const QString &p_text);
|
||||
|
||||
static bool isSeparatorItem(const QListWidgetItem *p_item);
|
||||
|
||||
private slots:
|
||||
void handleSearchModeTriggered(bool p_inSearchMode, bool p_focus);
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "vhelpue.h"
|
||||
#include "vlistfolderue.h"
|
||||
#include "dialog/vfixnotebookdialog.h"
|
||||
#include "vhistorylist.h"
|
||||
|
||||
extern VConfigManager *g_config;
|
||||
|
||||
@ -64,6 +65,8 @@ extern QFile g_logFile;
|
||||
|
||||
#define COLOR_PIXMAP_ICON_SIZE 64
|
||||
|
||||
#define NAVI_BOX_NOTEBOOKS_IDX 0
|
||||
|
||||
|
||||
VMainWindow::VMainWindow(VSingleInstanceGuard *p_guard, QWidget *p_parent)
|
||||
: QMainWindow(p_parent),
|
||||
@ -145,10 +148,12 @@ void VMainWindow::registerCaptainAndNavigationTargets()
|
||||
m_captain->registerNavigationTarget(m_notebookSelector);
|
||||
m_captain->registerNavigationTarget(m_dirTree);
|
||||
m_captain->registerNavigationTarget(m_fileList);
|
||||
m_captain->registerNavigationTarget(m_historyList);
|
||||
m_captain->registerNavigationTarget(m_editArea);
|
||||
m_captain->registerNavigationTarget(m_toolBox);
|
||||
m_captain->registerNavigationTarget(outline);
|
||||
m_captain->registerNavigationTarget(m_snippetList);
|
||||
m_captain->registerNavigationTarget(m_cart);
|
||||
m_captain->registerNavigationTarget(m_searcher);
|
||||
|
||||
// Register Captain mode targets.
|
||||
@ -196,14 +201,7 @@ void VMainWindow::registerCaptainAndNavigationTargets()
|
||||
|
||||
void VMainWindow::setupUI()
|
||||
{
|
||||
m_naviBox = new VToolBox();
|
||||
|
||||
setupNotebookPanel();
|
||||
|
||||
m_naviBox->addItem(m_nbSplitter,
|
||||
":/resources/icons/notebook.svg",
|
||||
tr("Notebooks"),
|
||||
m_dirTree);
|
||||
setupNaviBox();
|
||||
|
||||
m_editArea = new VEditArea();
|
||||
m_editArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
@ -211,6 +209,9 @@ void VMainWindow::setupUI()
|
||||
m_fileList->setEditArea(m_editArea);
|
||||
m_dirTree->setEditArea(m_editArea);
|
||||
|
||||
connect(m_editArea, &VEditArea::fileClosed,
|
||||
m_historyList, &VHistoryList::addFile);
|
||||
|
||||
// Main Splitter
|
||||
m_mainSplitter = new QSplitter();
|
||||
m_mainSplitter->setObjectName("MainSplitter");
|
||||
@ -265,6 +266,23 @@ void VMainWindow::setupUI()
|
||||
initTrayIcon();
|
||||
}
|
||||
|
||||
void VMainWindow::setupNaviBox()
|
||||
{
|
||||
m_naviBox = new VToolBox();
|
||||
|
||||
setupNotebookPanel();
|
||||
m_naviBox->addItem(m_nbSplitter,
|
||||
":/resources/icons/notebook.svg",
|
||||
tr("Notebooks"),
|
||||
m_dirTree);
|
||||
|
||||
m_historyList = new VHistoryList();
|
||||
m_naviBox->addItem(m_historyList,
|
||||
":/resources/icons/history.svg",
|
||||
tr("History"),
|
||||
m_historyList->getContentWidget());
|
||||
}
|
||||
|
||||
void VMainWindow::setupNotebookPanel()
|
||||
{
|
||||
m_notebookSelector = new VNotebookSelector();
|
||||
@ -1265,7 +1283,8 @@ void VMainWindow::initToolsDock()
|
||||
tr("Snippets"));
|
||||
m_toolBox->addItem(m_cart,
|
||||
":/resources/icons/cart.svg",
|
||||
tr("Cart"));
|
||||
tr("Cart"),
|
||||
m_cart->getContentWidget());
|
||||
|
||||
m_toolDock->setWidget(m_toolBox);
|
||||
addDockWidget(Qt::RightDockWidgetArea, m_toolDock);
|
||||
@ -3134,5 +3153,5 @@ void VMainWindow::kickOffStartUpTimer(const QStringList &p_files)
|
||||
void VMainWindow::showNotebookPanel()
|
||||
{
|
||||
changePanelView(PanelViewState::VerticalMode);
|
||||
m_naviBox->setCurrentIndex(0, false);
|
||||
m_naviBox->setCurrentIndex(NAVI_BOX_NOTEBOOKS_IDX, false);
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ class VCart;
|
||||
class VSearcher;
|
||||
class QPrinter;
|
||||
class VUniversalEntry;
|
||||
class VHistoryList;
|
||||
|
||||
enum class PanelViewState
|
||||
{
|
||||
@ -79,6 +80,8 @@ public:
|
||||
|
||||
VNotebookSelector *getNotebookSelector() const;
|
||||
|
||||
VHistoryList *getHistoryList() const;
|
||||
|
||||
// View and edit the information of @p_file, which is an orphan file.
|
||||
void editOrphanFileInfo(VFile *p_file);
|
||||
|
||||
@ -199,6 +202,8 @@ protected:
|
||||
private:
|
||||
void setupUI();
|
||||
|
||||
void setupNaviBox();
|
||||
|
||||
void setupNotebookPanel();
|
||||
|
||||
void initToolBar();
|
||||
@ -442,6 +447,8 @@ private:
|
||||
|
||||
VUniversalEntry *m_ue;
|
||||
|
||||
VHistoryList *m_historyList;
|
||||
|
||||
// Interval of the shared memory timer in ms.
|
||||
static const int c_sharedMemTimerInterval;
|
||||
};
|
||||
@ -481,6 +488,11 @@ inline VCart *VMainWindow::getCart() const
|
||||
return m_cart;
|
||||
}
|
||||
|
||||
inline VHistoryList *VMainWindow::getHistoryList() const
|
||||
{
|
||||
return m_historyList;
|
||||
}
|
||||
|
||||
inline VDirectoryTree *VMainWindow::getDirectoryTree() const
|
||||
{
|
||||
return m_dirTree;
|
||||
|
@ -70,7 +70,7 @@ QList<QListWidgetItem *> VNavigationMode::getVisibleItems(const QListWidget *p_w
|
||||
QList<QListWidgetItem *> items;
|
||||
for (int i = 0; i < p_widget->count(); ++i) {
|
||||
QListWidgetItem *item = p_widget->item(i);
|
||||
if (!item->isHidden()) {
|
||||
if (!item->isHidden() && item->flags() != Qt::NoItemFlags) {
|
||||
items.append(item);
|
||||
}
|
||||
}
|
||||
|
@ -214,5 +214,8 @@
|
||||
<file>utils/markdown-it/markdown-it-imsize.min.js</file>
|
||||
<file>utils/markdown-it/markdown-it-emoji.min.js</file>
|
||||
<file>resources/icons/notebook.svg</file>
|
||||
<file>resources/icons/history.svg</file>
|
||||
<file>resources/icons/clear_history.svg</file>
|
||||
<file>resources/icons/pin.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "vmainwindow.h"
|
||||
#include "vnotefile.h"
|
||||
#include "vcart.h"
|
||||
#include "vhistorylist.h"
|
||||
|
||||
extern VNote *g_vnote;
|
||||
|
||||
@ -53,10 +54,19 @@ void VSearchResultTree::initActions()
|
||||
connect(m_locateAct, &QAction::triggered,
|
||||
this, &VSearchResultTree::locateCurrentItem);
|
||||
|
||||
m_addToCartAct = new QAction(tr("Add To Cart"), this);
|
||||
m_addToCartAct = new QAction(VIconUtils::menuIcon(":/resources/icons/cart.svg"),
|
||||
tr("Add To Cart"),
|
||||
this);
|
||||
m_addToCartAct->setToolTip(tr("Add selected notes to Cart for further processing"));
|
||||
connect(m_addToCartAct, &QAction::triggered,
|
||||
this, &VSearchResultTree::addSelectedItemsToCart);
|
||||
|
||||
m_pinToHistoryAct = new QAction(VIconUtils::menuIcon(":/resources/icons/pin.svg"),
|
||||
tr("Pin To History"),
|
||||
this);
|
||||
m_pinToHistoryAct->setToolTip(tr("Pin selected notes to History"));
|
||||
connect(m_pinToHistoryAct, &QAction::triggered,
|
||||
this, &VSearchResultTree::pinSelectedItemsToHistory);
|
||||
}
|
||||
|
||||
void VSearchResultTree::updateResults(const QList<QSharedPointer<VSearchResultItem> > &p_items)
|
||||
@ -165,6 +175,7 @@ void VSearchResultTree::handleContextMenuRequested(QPoint p_pos)
|
||||
|
||||
if (hasNote) {
|
||||
menu.addAction(m_addToCartAct);
|
||||
menu.addAction(m_pinToHistoryAct);
|
||||
}
|
||||
|
||||
menu.exec(mapToGlobal(p_pos));
|
||||
@ -207,6 +218,25 @@ void VSearchResultTree::addSelectedItemsToCart()
|
||||
}
|
||||
}
|
||||
|
||||
void VSearchResultTree::pinSelectedItemsToHistory()
|
||||
{
|
||||
QList<QTreeWidgetItem *> items = selectedItems();
|
||||
QStringList files;
|
||||
for (int i = 0; i < items.size(); ++i) {
|
||||
const QSharedPointer<VSearchResultItem> &resItem = itemResultData(items[i]);
|
||||
if (resItem->m_type == VSearchResultItem::Note) {
|
||||
files << resItem->m_path;
|
||||
}
|
||||
}
|
||||
|
||||
if (!files.isEmpty()) {
|
||||
g_mainWin->getHistoryList()->pinFiles(files);
|
||||
g_mainWin->showStatusMessage(tr("%1 %2 pinned to History")
|
||||
.arg(files.size())
|
||||
.arg(files.size() > 1 ? tr("notes") : tr("note")));
|
||||
}
|
||||
}
|
||||
|
||||
VSearchResultItem::ItemType VSearchResultTree::itemResultType(const QTreeWidgetItem *p_item) const
|
||||
{
|
||||
Q_ASSERT(p_item);
|
||||
|
@ -34,6 +34,8 @@ private slots:
|
||||
|
||||
void addSelectedItemsToCart();
|
||||
|
||||
void pinSelectedItemsToHistory();
|
||||
|
||||
private:
|
||||
void appendItem(const QSharedPointer<VSearchResultItem> &p_item);
|
||||
|
||||
@ -56,6 +58,8 @@ private:
|
||||
QAction *m_locateAct;
|
||||
|
||||
QAction *m_addToCartAct;
|
||||
|
||||
QAction *m_pinToHistoryAct;
|
||||
};
|
||||
|
||||
#endif // VSEARCHRESULTTREE_H
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "dialog/vconfirmdeletiondialog.h"
|
||||
#include "vmainwindow.h"
|
||||
#include "utils/viconutils.h"
|
||||
#include "vlistwidget.h"
|
||||
|
||||
extern VConfigManager *g_config;
|
||||
|
||||
@ -70,7 +71,7 @@ void VSnippetList::setupUI()
|
||||
btnLayout->addWidget(m_numLabel);
|
||||
btnLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
m_snippetList = new QListWidget();
|
||||
m_snippetList = new VListWidget();
|
||||
m_snippetList->setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||
m_snippetList->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
m_snippetList->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
@ -380,7 +381,7 @@ void VSnippetList::makeSureFolderExist() const
|
||||
|
||||
void VSnippetList::updateContent()
|
||||
{
|
||||
m_snippetList->clear();
|
||||
m_snippetList->clearAll();
|
||||
|
||||
for (int i = 0; i < m_snippets.size(); ++i) {
|
||||
const VSnippet &snip = m_snippets[i];
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "vnavigationmode.h"
|
||||
|
||||
class QPushButton;
|
||||
class QListWidget;
|
||||
class VListWidget;
|
||||
class QListWidgetItem;
|
||||
class QLabel;
|
||||
class QAction;
|
||||
@ -92,7 +92,7 @@ private:
|
||||
QPushButton *m_addBtn;
|
||||
QPushButton *m_locateBtn;
|
||||
QLabel *m_numLabel;
|
||||
QListWidget *m_snippetList;
|
||||
VListWidget *m_snippetList;
|
||||
|
||||
QAction *m_applyAct;
|
||||
QAction *m_infoAct;
|
||||
|
@ -1,17 +1,25 @@
|
||||
#include "vstyleditemdelegate.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QDebug>
|
||||
#include <QListWidget>
|
||||
#include <QListWidgetItem>
|
||||
#include <QTreeWidgetItem>
|
||||
|
||||
#include "vpalette.h"
|
||||
#include "vtreewidget.h"
|
||||
|
||||
extern VPalette *g_palette;
|
||||
|
||||
VStyledItemDelegate::VStyledItemDelegate(QObject *p_parent)
|
||||
: QStyledItemDelegate(p_parent)
|
||||
VStyledItemDelegate::VStyledItemDelegate(QListWidget *p_list, VTreeWidget *p_tree)
|
||||
: QStyledItemDelegate(p_list ? (QObject *)p_list : (QObject *)p_tree),
|
||||
m_list(p_list),
|
||||
m_tree(p_tree)
|
||||
{
|
||||
Q_ASSERT(!(m_list && m_tree));
|
||||
m_itemHitBg = QBrush(QColor(g_palette->color("search_hit_item_bg")));
|
||||
m_itemHitFg = QBrush(QColor(g_palette->color("search_hit_item_fg")));
|
||||
m_itemSeparatorBg = QBrush(QColor(g_palette->color("item_separator_bg")));
|
||||
m_itemSeparatorFg = QBrush(QColor(g_palette->color("item_separator_fg")));
|
||||
}
|
||||
|
||||
void VStyledItemDelegate::paint(QPainter *p_painter,
|
||||
@ -25,7 +33,30 @@ void VStyledItemDelegate::paint(QPainter *p_painter,
|
||||
// option.palette.setBrush(QPalette::Base, m_itemHitBg);
|
||||
option.palette.setBrush(QPalette::Text, m_itemHitFg);
|
||||
QStyledItemDelegate::paint(p_painter, option, p_index);
|
||||
} else if (itemType(p_index) == ItemTypeSeparator) {
|
||||
QStyleOptionViewItem option(p_option);
|
||||
p_painter->fillRect(option.rect, m_itemSeparatorBg);
|
||||
option.palette.setBrush(QPalette::Text, m_itemSeparatorFg);
|
||||
QStyledItemDelegate::paint(p_painter, option, p_index);
|
||||
} else {
|
||||
QStyledItemDelegate::paint(p_painter, p_option, p_index);
|
||||
}
|
||||
}
|
||||
|
||||
int VStyledItemDelegate::itemType(const QModelIndex &p_index) const
|
||||
{
|
||||
int type = 0;
|
||||
if (m_list) {
|
||||
QListWidgetItem *item = m_list->item(p_index.row());
|
||||
if (item) {
|
||||
type = item->type();
|
||||
}
|
||||
} else if (m_tree) {
|
||||
QTreeWidgetItem *item = m_tree->getItemFromIndex(p_index);
|
||||
if (item) {
|
||||
type = item->type();
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
@ -5,11 +5,16 @@
|
||||
#include <QBrush>
|
||||
#include <QSet>
|
||||
|
||||
class QListWidget;
|
||||
class VTreeWidget;
|
||||
|
||||
// Should be larger then QListWidgetItem::UserType and QTreeWidgetItem::UserType.
|
||||
#define ItemTypeSeparator 2000
|
||||
|
||||
class VStyledItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
explicit VStyledItemDelegate(QObject *p_parent = Q_NULLPTR);
|
||||
explicit VStyledItemDelegate(QListWidget *p_list = nullptr, VTreeWidget *p_tree = nullptr);
|
||||
|
||||
virtual void paint(QPainter *p_painter,
|
||||
const QStyleOptionViewItem &p_option,
|
||||
@ -22,11 +27,19 @@ public:
|
||||
private:
|
||||
bool isHit(const QModelIndex &p_index) const;
|
||||
|
||||
QBrush m_itemHitBg;
|
||||
int itemType(const QModelIndex &p_index) const;
|
||||
|
||||
QBrush m_itemHitBg;
|
||||
QBrush m_itemHitFg;
|
||||
|
||||
QBrush m_itemSeparatorBg;
|
||||
QBrush m_itemSeparatorFg;
|
||||
|
||||
QSet<QModelIndex> m_hitItems;
|
||||
|
||||
// m_list OR m_tree (but not both) could be not NULL.
|
||||
const QListWidget *m_list;
|
||||
const VTreeWidget *m_tree;
|
||||
};
|
||||
|
||||
inline void VStyledItemDelegate::setHitItems(const QSet<QModelIndex> &p_hitItems)
|
||||
|
@ -52,6 +52,7 @@ int VToolBox::addItem(QWidget *p_widget,
|
||||
QPushButton *btn = new QPushButton(icon, "");
|
||||
btn->setToolTip(p_text);
|
||||
btn->setProperty("FlatBtn", true);
|
||||
btn->setProperty("ToolBoxTitleBtn", true);
|
||||
connect(btn, &QPushButton::clicked,
|
||||
this, [this]() {
|
||||
QObject *btn = sender();
|
||||
|
@ -44,7 +44,7 @@ VTreeWidget::VTreeWidget(QWidget *p_parent)
|
||||
effect->setOpacity(SEARCH_INPUT_IDLE_OPACITY);
|
||||
});
|
||||
|
||||
m_delegate = new VStyledItemDelegate(this);
|
||||
m_delegate = new VStyledItemDelegate(NULL, this);
|
||||
setItemDelegate(m_delegate);
|
||||
|
||||
connect(this, &VTreeWidget::itemExpanded,
|
||||
@ -155,6 +155,10 @@ QList<void *> VTreeWidget::searchItems(const QString &p_text,
|
||||
QList<void *> res;
|
||||
res.reserve(items.size());
|
||||
for (int i = 0; i < items.size(); ++i) {
|
||||
if (items[i]->type() == ItemTypeSeparator) {
|
||||
continue;
|
||||
}
|
||||
|
||||
res.append(items[i]);
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,8 @@ public:
|
||||
|
||||
void setFitContent(bool p_enabled);
|
||||
|
||||
QTreeWidgetItem *getItemFromIndex(const QModelIndex &p_index) const;
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE;
|
||||
|
||||
@ -95,4 +97,9 @@ inline void VTreeWidget::setFitContent(bool p_enabled)
|
||||
setSizeAdjustPolicy(m_fitContent ? QAbstractScrollArea::AdjustToContents
|
||||
: QAbstractScrollArea::AdjustIgnored);
|
||||
}
|
||||
|
||||
inline QTreeWidgetItem *VTreeWidget::getItemFromIndex(const QModelIndex &p_index) const
|
||||
{
|
||||
return itemFromIndex(p_index);
|
||||
}
|
||||
#endif // VTREEWIDGET_H
|
||||
|
@ -16,8 +16,6 @@
|
||||
|
||||
extern VConfigManager *g_config;
|
||||
|
||||
extern VPalette *g_palette;
|
||||
|
||||
VVimIndicator::VVimIndicator(QWidget *p_parent)
|
||||
: QWidget(p_parent), m_vim(NULL)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user