explorer: support exploring system's files
@ -922,7 +922,7 @@ VMarkdownTab::VMarkdownTab(QWidget *p_parent)
|
|||||||
{
|
{
|
||||||
// Default note open mode.
|
// Default note open mode.
|
||||||
m_openModeCombo = VUtils::getComboBox();
|
m_openModeCombo = VUtils::getComboBox();
|
||||||
m_openModeCombo->setToolTip(tr("Default mode to open an internal note"));
|
m_openModeCombo->setToolTip(tr("Default mode to open a file"));
|
||||||
m_openModeCombo->addItem(tr("Read Mode"), (int)OpenFileMode::Read);
|
m_openModeCombo->addItem(tr("Read Mode"), (int)OpenFileMode::Read);
|
||||||
m_openModeCombo->addItem(tr("Edit Mode"), (int)OpenFileMode::Edit);
|
m_openModeCombo->addItem(tr("Edit Mode"), (int)OpenFileMode::Edit);
|
||||||
|
|
||||||
@ -992,7 +992,7 @@ VMarkdownTab::VMarkdownTab(QWidget *p_parent)
|
|||||||
m_graphvizDotEdit->setToolTip(tr("Location to the GraphViz dot executable"));
|
m_graphvizDotEdit->setToolTip(tr("Location to the GraphViz dot executable"));
|
||||||
|
|
||||||
QFormLayout *mainLayout = new QFormLayout();
|
QFormLayout *mainLayout = new QFormLayout();
|
||||||
mainLayout->addRow(tr("Note open mode:"), m_openModeCombo);
|
mainLayout->addRow(tr("Open mode:"), m_openModeCombo);
|
||||||
mainLayout->addRow(tr("Heading sequence:"), headingSequenceLayout);
|
mainLayout->addRow(tr("Heading sequence:"), headingSequenceLayout);
|
||||||
mainLayout->addRow(colorColumnLabel, m_colorColumnEdit);
|
mainLayout->addRow(colorColumnLabel, m_colorColumnEdit);
|
||||||
mainLayout->addRow(tr("MathJax configuration:"), m_mathjaxConfigEdit);
|
mainLayout->addRow(tr("MathJax configuration:"), m_mathjaxConfigEdit);
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 19.0.0, 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="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
<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"
|
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||||
width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
<g>
|
||||||
<path style="fill:#000000" d="M399.3,168.9c-0.7-2.9-2-5-3.5-6.8l-83.7-91.7c-1.9-2.1-4.1-3.1-6.6-4.4c-2.9-1.5-6.1-1.6-9.4-1.6H136.2
|
<path fill="#000000" d="M269.534,399.201c-9.616,0-17.483,7.867-17.483,17.483s7.867,17.483,17.483,17.483h160.263
|
||||||
c-12.4,0-23.7,9.6-23.7,22.9v335.2c0,13.4,11.3,25.9,23.7,25.9h243.1c12.4,0,21.2-12.5,21.2-25.9V178.4
|
c9.616,0,17.483-7.867,17.483-17.483V138.409c0-4.954-2.04-9.616-5.536-12.821L310.62,4.662C307.414,1.748,303.043,0,298.673,0
|
||||||
C400.5,174.8,400.1,172.2,399.3,168.9z M305.5,111l58,63.5h-58V111z M144.5,416.5v-320h129v81.7c0,14.8,13.4,28.3,28.1,28.3h66.9
|
h-195.23c-9.616,0-17.483,7.867-17.483,17.483v189.402c0,9.616,7.867,17.483,17.483,17.483s17.483-7.867,17.483-17.483V34.967
|
||||||
v210H144.5z"/>
|
h139.866v151.522c0,9.616,7.867,17.483,17.483,17.483H409.4c0.874,0,2.04,0,2.914-0.291v195.521H269.534z M409.4,169.005H295.759
|
||||||
|
V38.463l116.555,107.522v23.311C411.44,169.005,410.274,169.005,409.4,169.005z M16.026,372.977
|
||||||
|
c0-9.616,7.867-17.483,17.483-17.483h52.45V300.13c0-9.616,7.867-17.483,17.483-17.483s17.483,7.867,17.483,17.483v55.364h58.278
|
||||||
|
c9.616,0,17.483,7.867,17.483,17.483s-7.867,17.483-17.483,17.483h-58.278v55.364c0,9.616-7.867,17.483-17.483,17.483
|
||||||
|
s-17.483-7.867-17.483-17.483V390.46H33.51C23.894,390.46,16.026,382.592,16.026,372.977z"/>
|
||||||
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 868 B After Width: | Height: | Size: 1.3 KiB |
@ -1,10 +1,16 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 19.0.0, 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="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
<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"
|
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||||
width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
|
<g>
|
||||||
<path style="fill:#000000" d="M437.334,144H256.006l-42.668-48H74.666C51.197,96,32,115.198,32,138.667v234.666C32,396.802,51.197,416,74.666,416h362.668
|
<path fill="#000000" d="M444.955,31.782H333.208c-17.576,0-37.758,8.931-47.165,31.782c0,0-4.132,29.145-31.782,31.782
|
||||||
C460.803,416,480,396.802,480,373.333V186.667C480,163.198,460.803,144,437.334,144z M448,373.333
|
H31.782C14.239,95.347,0,109.077,0,126.621v286.551c0,17.544,14.239,31.783,31.782,31.783h413.172
|
||||||
c0,5.782-4.885,10.667-10.666,10.667H74.666C68.884,384,64,379.115,64,373.333V176h373.334c5.781,0,10.666,4.885,10.666,10.667
|
c17.544,0,31.782-14.239,31.782-31.783V63.565C476.737,46.021,462.499,31.782,444.955,31.782z M444.955,126.621v286.551H31.782
|
||||||
V373.333z"/>
|
V127.13H254.26l3.051-0.159c29.812-2.829,48.246-23.71,56.732-45.163c8.263-20.722,22.661-18.243,22.661-18.243h108.251V126.621
|
||||||
|
z"/>
|
||||||
|
<path fill="#000000" d="M317.825,254.26H254.26v-63.565c0-8.772-7.151-15.891-15.891-15.891
|
||||||
|
c-8.772,0-15.891,7.119-15.891,15.891v63.565h-63.565c-8.772,0-15.891,7.151-15.891,15.891s7.119,15.891,15.891,15.891h63.565
|
||||||
|
v63.565c0,8.74,7.119,15.891,15.891,15.891c8.74,0,15.891-7.151,15.891-15.891v-63.565h63.565
|
||||||
|
c8.74,0,15.891-7.151,15.891-15.891S326.565,254.26,317.825,254.26z"/>
|
||||||
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 871 B After Width: | Height: | Size: 1.3 KiB |
17
src/resources/icons/explore_root.svg
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M177.3,76.95v111c0,6.8,5.5,12.3,12.3,12.3h43.2v33.4h-165c-6.8,0-12.3,5.5-12.3,12.3v43.9H12.3
|
||||||
|
c-6.8,0-12.3,5.5-12.3,12.3v111c0,6.8,5.5,12.3,12.3,12.3h111c6.8,0,12.3-5.5,12.3-12.3v-111c0-6.8-5.5-12.3-12.3-12.3H80v-31.7
|
||||||
|
h152.7v31.7h-43.2c-6.8,0-12.3,5.5-12.3,12.3v111c0,6.8,5.5,12.3,12.3,12.3h111c6.8,0,12.3-5.5,12.3-12.3v-111
|
||||||
|
c0-6.8-5.5-12.3-12.3-12.3h-43.2v-31.7H410v31.7h-43.2c-6.8,0-12.3,5.5-12.3,12.3v111c0,6.8,5.5,12.3,12.3,12.3h111
|
||||||
|
c6.8,0,12.3-5.5,12.3-12.3v-111c0-6.8-5.5-12.3-12.3-12.3h-43.2v-43.9c0-6.8-5.5-12.3-12.3-12.3h-165v-33.4h43.2
|
||||||
|
c6.8,0,12.3-5.5,12.3-12.3v-111c0-6.8-5.5-12.3-12.3-12.3h-111C182.8,64.65,177.3,70.15,177.3,76.95z M111,400.75H24.6v-86.5H111
|
||||||
|
V400.75z M288.2,400.75h-86.5v-86.5h86.5V400.75z M465.4,400.75H379v-86.5h86.5v86.5H465.4z M201.8,89.15h86.5v86.5h-86.5
|
||||||
|
L201.8,89.15L201.8,89.15z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
14
src/resources/icons/explorer.svg
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="folder" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 60 60" style="enable-background:new 0 0 60 60;" xml:space="preserve">
|
||||||
|
<path fill="#000000" d="M57.49,21.5H55v-7h-2v-4H25.086l-3.571-5H2.732C1.226,5.5,0,6.726,0,8.232v43.687l0.006,0
|
||||||
|
c-0.005,0.563,0.17,1.114,0.522,1.575C1.018,54.134,1.76,54.5,2.565,54.5h44.759c1.156,0,2.174-0.779,2.45-1.813L60,24.649v-0.177
|
||||||
|
C60,22.75,58.944,21.5,57.49,21.5z M53,21.5h-8v-1c0-0.553-0.448-1-1-1s-1,0.447-1,1v1h-5v-1c0-0.553-0.448-1-1-1s-1,0.447-1,1v1h-5
|
||||||
|
v-1c0-0.553-0.448-1-1-1s-1,0.447-1,1v1h-5v-1c0-0.553-0.448-1-1-1s-1,0.447-1,1v1h-5v-1c0-0.553-0.448-1-1-1s-1,0.447-1,1v1h-2.269
|
||||||
|
c-0.143,0-0.284,0.012-0.422,0.035c-0.499,0.083-0.95,0.315-1.309,0.639V16.5h42V21.5z M5,37.793V22.5h5.695
|
||||||
|
c-0.188,0.243-0.335,0.516-0.414,0.813l-0.317,0.87L5,37.793z M9,20.5H6.414L7,19.914l2-2V20.5z M51,12.5v2H9.586L7,17.086V12.5
|
||||||
|
h19.515H51z M2,8.232C2,7.828,2.329,7.5,2.732,7.5h17.753l2.143,3H5v8.586l-2,2v22.085l-1,2.728V8.232z M47.869,52.083
|
||||||
|
c-0.066,0.245-0.291,0.417-0.545,0.417H2.565c-0.243,0-0.385-0.139-0.448-0.222c-0.063-0.082-0.16-0.256-0.123-0.408L3,49.112v0.001
|
||||||
|
l9.16-25.114l0.026-0.082c0.066-0.245,0.291-0.417,0.545-0.417H55h2.49c0.38,0,0.477,0.546,0.502,0.819L47.869,52.083z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
12
src/resources/icons/open_location.svg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?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">
|
||||||
|
<g>
|
||||||
|
<path fill="#000000" d="M468.7,64H43.3c-6,0-11.3,5-11.3,11.1v265.7c0,6.2,5.2,11.1,11.3,11.1h425.4c6,0,11.3-5,11.3-11.1V75.1
|
||||||
|
C480,69,474.8,64,468.7,64z M448,320H64V96h384V320z"/>
|
||||||
|
<path fill="#000000" d="M302.5,448c28-0.5,41.5-3.9,29-12.5c-12.5-8.7-28.5-15.3-29-22.5c-0.3-3.7-1.7-45-1.7-45H256h-44.8c0,0-1.5,41.3-1.7,45
|
||||||
|
c-0.5,7.1-16.5,13.8-29,22.5c-12.5,8.7,1,12,29,12.5H302.5z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 878 B |
@ -2,9 +2,9 @@
|
|||||||
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- 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">
|
<!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"
|
<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">
|
width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||||
<path style="fill:#000000" d="M458,210.409l-145.267-12.476L256,64l-56.743,133.934L54,210.409l110.192,95.524L131.161,448L256,372.686L380.83,448
|
<path style="fill:#000000" 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
|
||||||
l-33.021-142.066L458,210.409z M272.531,345.286L256,335.312l-16.53,9.973l-59.988,36.191l15.879-68.296l4.369-18.79l-14.577-12.637
|
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
|
||||||
l-52.994-45.939l69.836-5.998l19.206-1.65l7.521-17.75l27.276-64.381l27.27,64.379l7.52,17.751l19.208,1.65l69.846,5.998
|
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
|
||||||
l-52.993,45.939l-14.576,12.636l4.367,18.788l15.875,68.299L272.531,345.286z"/>
|
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>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 956 B After Width: | Height: | Size: 1005 B |
@ -3,10 +3,5 @@
|
|||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
<!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"
|
<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">
|
width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||||
<g>
|
<path fill="#000000" d="M496,384V96H16v288h175v16h-64v16h257v-16h-64v-16H496z M32,112h448v256H32V112z"/>
|
||||||
<path style="fill:#000000" d="M468.7,64H43.3c-6,0-11.3,5-11.3,11.1v265.7c0,6.2,5.2,11.1,11.3,11.1h425.4c6,0,11.3-5,11.3-11.1V75.1
|
|
||||||
C480,69,474.8,64,468.7,64z M448,320H64V96h384V320z"/>
|
|
||||||
<path style="fill:#000000" d="M302.5,448c28-0.5,41.5-3.9,29-12.5c-12.5-8.7-28.5-15.3-29-22.5c-0.3-3.7-1.7-45-1.7-45H256h-44.8c0,0-1.5,41.3-1.7,45
|
|
||||||
c-0.5,7.1-16.5,13.8-29,22.5c-12.5,8.7,1,12,29,12.5H302.5z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 890 B After Width: | Height: | Size: 589 B |
@ -1,9 +1,15 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 16.0.0, 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">
|
<!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"
|
<svg version="1.1" id="Capa_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">
|
width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;"
|
||||||
<path style="fill:#000000" d="M458,210.409l-145.267-12.476L256,64l-56.743,133.934L54,210.409l110.192,95.524L131.161,448L256,372.686L380.83,448
|
xml:space="preserve">
|
||||||
l-33.021-142.066L458,210.409z M272.531,345.287L256,335.313l-0.002-189.277l27.27,64.379l7.52,17.751l19.208,1.65l69.846,5.998
|
<g>
|
||||||
l-52.993,45.939l-14.576,12.636l4.367,18.788l15.875,68.299L272.531,345.287z"/>
|
<path fill="#000000" d="M431.379,0.222h-394.7C16.456,0.222,0,16.671,0,36.895v394.268c0,20.221,16.456,36.677,36.679,36.677h394.7
|
||||||
|
c20.228,0,36.683-16.456,36.683-36.677V36.895C468.062,16.665,451.606,0.222,431.379,0.222z M406.519,41.966
|
||||||
|
c8.689,0,15.723,7.04,15.723,15.72c0,8.683-7.033,15.717-15.723,15.717c-8.688,0-15.723-7.04-15.723-15.717
|
||||||
|
C390.796,49.006,397.83,41.966,406.519,41.966z M350.189,41.966c8.688,0,15.723,7.04,15.723,15.72
|
||||||
|
c0,8.683-7.034,15.717-15.723,15.717c-8.684,0-15.711-7.04-15.711-15.717C334.479,49.006,341.506,41.966,350.189,41.966z
|
||||||
|
M41.913,112.426h184.055v313.495H41.913V112.426z M426.148,425.921H242.104V112.426h184.044V425.921z"/>
|
||||||
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 834 B After Width: | Height: | Size: 1.1 KiB |
10
src/resources/icons/star.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" enable-background="new 0 0 512 512" xml:space="preserve">
|
||||||
|
<path style="fill:#000000" d="M458,210.409l-145.267-12.476L256,64l-56.743,133.934L54,210.409l110.192,95.524L131.161,448L256,372.686L380.83,448
|
||||||
|
l-33.021-142.066L458,210.409z M272.531,345.286L256,335.312l-16.53,9.973l-59.988,36.191l15.879-68.296l4.369-18.79l-14.577-12.637
|
||||||
|
l-52.994-45.939l69.836-5.998l19.206-1.65l7.521-17.75l27.276-64.381l27.27,64.379l7.52,17.751l19.208,1.65l69.846,5.998
|
||||||
|
l-52.993,45.939l-14.576,12.636l4.367,18.788l15.875,68.299L272.531,345.286z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 946 B |
10
src/resources/icons/unstar.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" enable-background="new 0 0 512 512" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<polygon fill="#000000" points="256,372.686 380.83,448 347.809,305.934 458,210.409 312.733,197.934 256,64 199.257,197.934 54,210.409
|
||||||
|
164.192,305.934 131.161,448 "/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 656 B |
@ -7,7 +7,7 @@ mdhl_file=v_moonlight.mdhl
|
|||||||
css_file=v_moonlight.css
|
css_file=v_moonlight.css
|
||||||
codeblock_css_file=v_moonlight_codeblock.css
|
codeblock_css_file=v_moonlight_codeblock.css
|
||||||
mermaid_css_file=v_moonlight_mermaid.css
|
mermaid_css_file=v_moonlight_mermaid.css
|
||||||
version=10
|
version=11
|
||||||
|
|
||||||
; This mapping will be used to translate colors when the content of HTML is copied
|
; This mapping will be used to translate colors when the content of HTML is copied
|
||||||
; without background. You could just specify the foreground colors mapping here.
|
; without background. You could just specify the foreground colors mapping here.
|
||||||
|
@ -630,6 +630,24 @@ QLineEdit[VimCommandLine="true"]:hover {
|
|||||||
background: @lineedit_hover_bg;
|
background: @lineedit_hover_bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QLineEdit[EmbeddedEdit="true"] {
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
border: none;
|
||||||
|
color: @lineedit_fg;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLineEdit[EmbeddedEdit="true"]:focus {
|
||||||
|
background: @lineedit_focus_bg;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLineEdit[EmbeddedEdit="true"]:hover {
|
||||||
|
background: @lineedit_hover_bg;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
QLineEdit {
|
QLineEdit {
|
||||||
border: 1px solid @lineedit_border;
|
border: 1px solid @lineedit_border;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
|
@ -7,7 +7,7 @@ mdhl_file=v_native.mdhl
|
|||||||
css_file=v_native.css
|
css_file=v_native.css
|
||||||
codeblock_css_file=v_native_codeblock.css
|
codeblock_css_file=v_native_codeblock.css
|
||||||
mermaid_css_file=v_native_mermaid.css
|
mermaid_css_file=v_native_mermaid.css
|
||||||
version=10
|
version=11
|
||||||
|
|
||||||
[phony]
|
[phony]
|
||||||
; Abstract color attributes.
|
; Abstract color attributes.
|
||||||
|
@ -452,6 +452,14 @@ QLineEdit[VimCommandLine="true"] {
|
|||||||
background: @lineedit_bg;
|
background: @lineedit_bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QLineEdit[EmbeddedEdit="true"] {
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
border: none;
|
||||||
|
color: @lineedit_fg;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
VUniversalEntry VMetaWordLineEdit {
|
VUniversalEntry VMetaWordLineEdit {
|
||||||
border: 1px solid @lineedit_border;
|
border: 1px solid @lineedit_border;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ mdhl_file=v_pure.mdhl
|
|||||||
css_file=v_pure.css
|
css_file=v_pure.css
|
||||||
codeblock_css_file=v_pure_codeblock.css
|
codeblock_css_file=v_pure_codeblock.css
|
||||||
mermaid_css_file=v_pure_mermaid.css
|
mermaid_css_file=v_pure_mermaid.css
|
||||||
version=10
|
version=11
|
||||||
|
|
||||||
[phony]
|
[phony]
|
||||||
; Abstract color attributes.
|
; Abstract color attributes.
|
||||||
|
@ -630,6 +630,24 @@ QLineEdit[VimCommandLine="true"]:hover {
|
|||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QLineEdit[EmbeddedEdit="true"] {
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
border: none;
|
||||||
|
color: @lineedit_fg;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLineEdit[EmbeddedEdit="true"]:focus {
|
||||||
|
background: @lineedit_focus_bg;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLineEdit[EmbeddedEdit="true"]:hover {
|
||||||
|
background: @lineedit_hover_bg;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
QLineEdit {
|
QLineEdit {
|
||||||
border: 1px solid @lineedit_border;
|
border: 1px solid @lineedit_border;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
|
@ -132,7 +132,8 @@ SOURCES += main.cpp\
|
|||||||
vmathjaxpreviewhelper.cpp \
|
vmathjaxpreviewhelper.cpp \
|
||||||
vmathjaxwebdocument.cpp \
|
vmathjaxwebdocument.cpp \
|
||||||
vmathjaxinplacepreviewhelper.cpp \
|
vmathjaxinplacepreviewhelper.cpp \
|
||||||
vhistorylist.cpp
|
vhistorylist.cpp \
|
||||||
|
vexplorer.cpp
|
||||||
|
|
||||||
HEADERS += vmainwindow.h \
|
HEADERS += vmainwindow.h \
|
||||||
vdirectorytree.h \
|
vdirectorytree.h \
|
||||||
@ -257,7 +258,9 @@ HEADERS += vmainwindow.h \
|
|||||||
vmathjaxinplacepreviewhelper.h \
|
vmathjaxinplacepreviewhelper.h \
|
||||||
markdownitoption.h \
|
markdownitoption.h \
|
||||||
vhistorylist.h \
|
vhistorylist.h \
|
||||||
vhistoryentry.h
|
vhistoryentry.h \
|
||||||
|
vexplorer.h \
|
||||||
|
vexplorerentry.h
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
vnote.qrc \
|
vnote.qrc \
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QTreeWidgetItem>
|
#include <QTreeWidgetItem>
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
|
#include <QInputDialog>
|
||||||
|
|
||||||
#include "vorphanfile.h"
|
#include "vorphanfile.h"
|
||||||
#include "vnote.h"
|
#include "vnote.h"
|
||||||
@ -1542,3 +1543,40 @@ bool VUtils::inSameDrive(const QString &p_a, const QString &p_b)
|
|||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString VUtils::promptForFileName(const QString &p_title,
|
||||||
|
const QString &p_label,
|
||||||
|
const QString &p_default,
|
||||||
|
const QString &p_dir,
|
||||||
|
QWidget *p_parent)
|
||||||
|
{
|
||||||
|
QString name = p_default;
|
||||||
|
QString text = p_label;
|
||||||
|
QDir paDir(p_dir);
|
||||||
|
while (true) {
|
||||||
|
bool ok;
|
||||||
|
name = QInputDialog::getText(p_parent,
|
||||||
|
p_title,
|
||||||
|
text,
|
||||||
|
QLineEdit::Normal,
|
||||||
|
name,
|
||||||
|
&ok);
|
||||||
|
if (!ok || name.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!VUtils::checkFileNameLegal(name)) {
|
||||||
|
text = QObject::tr("Illegal name. Please try again:");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (paDir.exists(name)) {
|
||||||
|
text = QObject::tr("Name already exists. Please try again:");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
@ -333,6 +333,12 @@ public:
|
|||||||
|
|
||||||
static bool inSameDrive(const QString &p_a, const QString &p_b);
|
static bool inSameDrive(const QString &p_a, const QString &p_b);
|
||||||
|
|
||||||
|
static QString promptForFileName(const QString &p_title,
|
||||||
|
const QString &p_label,
|
||||||
|
const QString &p_default,
|
||||||
|
const QString &p_dir,
|
||||||
|
QWidget *p_parent = nullptr);
|
||||||
|
|
||||||
// Regular expression for image link.
|
// Regular expression for image link.
|
||||||
// 
|
// 
|
||||||
// Captured texts (need to be trimmed):
|
// Captured texts (need to be trimmed):
|
||||||
|
@ -52,6 +52,7 @@ const QString VConfigManager::c_exportFolderName = QString("vnote_exports");
|
|||||||
VConfigManager::VConfigManager(QObject *p_parent)
|
VConfigManager::VConfigManager(QObject *p_parent)
|
||||||
: QObject(p_parent),
|
: QObject(p_parent),
|
||||||
m_noteListViewOrder(-1),
|
m_noteListViewOrder(-1),
|
||||||
|
m_explorerCurrentIndex(-1),
|
||||||
m_hasReset(false),
|
m_hasReset(false),
|
||||||
userSettings(NULL),
|
userSettings(NULL),
|
||||||
defaultSettings(NULL),
|
defaultSettings(NULL),
|
||||||
@ -1218,7 +1219,7 @@ void VConfigManager::setLastOpenedFiles(const QVector<VFileSessionInfo> &p_files
|
|||||||
m_sessionSettings->endArray();
|
m_sessionSettings->endArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VConfigManager::getHistory(QLinkedList<VHistoryEntry> &p_history)
|
void VConfigManager::getHistory(QLinkedList<VHistoryEntry> &p_history) const
|
||||||
{
|
{
|
||||||
p_history.clear();
|
p_history.clear();
|
||||||
|
|
||||||
@ -1254,6 +1255,45 @@ void VConfigManager::setHistory(const QLinkedList<VHistoryEntry> &p_history)
|
|||||||
m_sessionSettings->endArray();
|
m_sessionSettings->endArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VConfigManager::getExplorerEntries(QVector<VExplorerEntry> &p_entries) const
|
||||||
|
{
|
||||||
|
p_entries.clear();
|
||||||
|
|
||||||
|
int size = m_sessionSettings->beginReadArray("explorer_starred");
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
m_sessionSettings->setArrayIndex(i);
|
||||||
|
p_entries.append(VExplorerEntry::fromSettings(m_sessionSettings));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_sessionSettings->endArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VConfigManager::setExplorerEntries(const QVector<VExplorerEntry> &p_entries)
|
||||||
|
{
|
||||||
|
if (m_hasReset) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString section("explorer_starred");
|
||||||
|
|
||||||
|
// Clear it first
|
||||||
|
m_sessionSettings->beginGroup(section);
|
||||||
|
m_sessionSettings->remove("");
|
||||||
|
m_sessionSettings->endGroup();
|
||||||
|
|
||||||
|
m_sessionSettings->beginWriteArray(section);
|
||||||
|
int idx = 0;
|
||||||
|
for (auto const & entry : p_entries) {
|
||||||
|
if (entry.m_isStarred) {
|
||||||
|
m_sessionSettings->setArrayIndex(idx);
|
||||||
|
entry.toSettings(m_sessionSettings);
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_sessionSettings->endArray();
|
||||||
|
}
|
||||||
|
|
||||||
QVector<VMagicWord> VConfigManager::getCustomMagicWords()
|
QVector<VMagicWord> VConfigManager::getCustomMagicWords()
|
||||||
{
|
{
|
||||||
QVector<VMagicWord> words;
|
QVector<VMagicWord> words;
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "utils/vmetawordmanager.h"
|
#include "utils/vmetawordmanager.h"
|
||||||
#include "markdownitoption.h"
|
#include "markdownitoption.h"
|
||||||
#include "vhistoryentry.h"
|
#include "vhistoryentry.h"
|
||||||
|
#include "vexplorerentry.h"
|
||||||
|
|
||||||
class QJsonObject;
|
class QJsonObject;
|
||||||
class QString;
|
class QString;
|
||||||
@ -131,6 +132,9 @@ public:
|
|||||||
int getCurNotebookIndex() const;
|
int getCurNotebookIndex() const;
|
||||||
void setCurNotebookIndex(int index);
|
void setCurNotebookIndex(int index);
|
||||||
|
|
||||||
|
int getNaviBoxCurrentIndex() const;
|
||||||
|
void setNaviBoxCurrentIndex(int p_index);
|
||||||
|
|
||||||
// Read [notebooks] section from settings into @p_notebooks.
|
// Read [notebooks] section from settings into @p_notebooks.
|
||||||
void getNotebooks(QVector<VNotebook *> &p_notebooks, QObject *p_parent);
|
void getNotebooks(QVector<VNotebook *> &p_notebooks, QObject *p_parent);
|
||||||
|
|
||||||
@ -359,12 +363,22 @@ public:
|
|||||||
void setLastOpenedFiles(const QVector<VFileSessionInfo> &p_files);
|
void setLastOpenedFiles(const QVector<VFileSessionInfo> &p_files);
|
||||||
|
|
||||||
// Read history from [history] of session.ini.
|
// Read history from [history] of session.ini.
|
||||||
void getHistory(QLinkedList<VHistoryEntry> &p_history);
|
void getHistory(QLinkedList<VHistoryEntry> &p_history) const;
|
||||||
|
|
||||||
void setHistory(const QLinkedList<VHistoryEntry> &p_history);
|
void setHistory(const QLinkedList<VHistoryEntry> &p_history);
|
||||||
|
|
||||||
int getHistorySize() const;
|
int getHistorySize() const;
|
||||||
|
|
||||||
|
// Read explorer's starred entries from [explorer_starred] of session.ini.
|
||||||
|
void getExplorerEntries(QVector<VExplorerEntry> &p_entries) const;
|
||||||
|
|
||||||
|
// Output starred entries to [explorer_starred] of session.ini.
|
||||||
|
void setExplorerEntries(const QVector<VExplorerEntry> &p_entries);
|
||||||
|
|
||||||
|
int getExplorerCurrentIndex() const;
|
||||||
|
|
||||||
|
void setExplorerCurrentIndex(int p_idx);
|
||||||
|
|
||||||
// Read custom magic words from [magic_words] section.
|
// Read custom magic words from [magic_words] section.
|
||||||
QVector<VMagicWord> getCustomMagicWords();
|
QVector<VMagicWord> getCustomMagicWords();
|
||||||
|
|
||||||
@ -899,6 +913,9 @@ private:
|
|||||||
// View order of note list.
|
// View order of note list.
|
||||||
int m_noteListViewOrder;
|
int m_noteListViewOrder;
|
||||||
|
|
||||||
|
// Current entry index of explorer entries.
|
||||||
|
int m_explorerCurrentIndex;
|
||||||
|
|
||||||
// Whether user has reset the configurations.
|
// Whether user has reset the configurations.
|
||||||
bool m_hasReset;
|
bool m_hasReset;
|
||||||
|
|
||||||
@ -1004,6 +1021,16 @@ inline void VConfigManager::setCurNotebookIndex(int index)
|
|||||||
setConfigToSessionSettings("global", "current_notebook", index);
|
setConfigToSessionSettings("global", "current_notebook", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int VConfigManager::getNaviBoxCurrentIndex() const
|
||||||
|
{
|
||||||
|
return getConfigFromSessionSettings("global", "navibox_current_index").toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void VConfigManager::setNaviBoxCurrentIndex(int p_index)
|
||||||
|
{
|
||||||
|
setConfigToSessionSettings("global", "navibox_current_index", p_index);
|
||||||
|
}
|
||||||
|
|
||||||
inline void VConfigManager::getNotebooks(QVector<VNotebook *> &p_notebooks,
|
inline void VConfigManager::getNotebooks(QVector<VNotebook *> &p_notebooks,
|
||||||
QObject *p_parent)
|
QObject *p_parent)
|
||||||
{
|
{
|
||||||
@ -2326,4 +2353,23 @@ inline void VConfigManager::setNoteListViewOrder(int p_order)
|
|||||||
m_noteListViewOrder = p_order;
|
m_noteListViewOrder = p_order;
|
||||||
setConfigToSettings("global", "note_list_view_order", m_noteListViewOrder);
|
setConfigToSettings("global", "note_list_view_order", m_noteListViewOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int VConfigManager::getExplorerCurrentIndex() const
|
||||||
|
{
|
||||||
|
if (m_explorerCurrentIndex == -1) {
|
||||||
|
const_cast<VConfigManager *>(this)->m_explorerCurrentIndex = getConfigFromSessionSettings("global", "explorer_current_entry").toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_explorerCurrentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void VConfigManager::setExplorerCurrentIndex(int p_idx)
|
||||||
|
{
|
||||||
|
if (p_idx == m_explorerCurrentIndex) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_explorerCurrentIndex = p_idx;
|
||||||
|
setConfigToSessionSettings("global", "explorer_current_entry", m_explorerCurrentIndex);
|
||||||
|
}
|
||||||
#endif // VCONFIGMANAGER_H
|
#endif // VCONFIGMANAGER_H
|
||||||
|
@ -33,6 +33,7 @@ VDirectoryTree::VDirectoryTree(QWidget *parent)
|
|||||||
setColumnCount(1);
|
setColumnCount(1);
|
||||||
setHeaderHidden(true);
|
setHeaderHidden(true);
|
||||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
setFitContent(true);
|
||||||
|
|
||||||
initShortcuts();
|
initShortcuts();
|
||||||
|
|
||||||
@ -147,6 +148,8 @@ void VDirectoryTree::updateDirectoryTree()
|
|||||||
if (!restoreCurrentItem() && topLevelItemCount() > 0) {
|
if (!restoreCurrentItem() && topLevelItemCount() > 0) {
|
||||||
setCurrentItem(topLevelItem(0));
|
setCurrentItem(topLevelItem(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resizeColumnToContents(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VDirectoryTree::restoreCurrentItem()
|
bool VDirectoryTree::restoreCurrentItem()
|
||||||
@ -425,8 +428,10 @@ void VDirectoryTree::contextMenuRequested(QPoint pos)
|
|||||||
menu.addAction(reloadAct);
|
menu.addAction(reloadAct);
|
||||||
|
|
||||||
if (item) {
|
if (item) {
|
||||||
QAction *openLocationAct = new QAction(tr("&Open Folder Location"), &menu);
|
QAction *openLocationAct = new QAction(VIconUtils::menuIcon(":/resources/icons/open_location.svg"),
|
||||||
openLocationAct->setToolTip(tr("Open the folder containing this folder in operating system"));
|
tr("&Open Folder Location"),
|
||||||
|
&menu);
|
||||||
|
openLocationAct->setToolTip(tr("Explore this folder in operating system"));
|
||||||
connect(openLocationAct, &QAction::triggered,
|
connect(openLocationAct, &QAction::triggered,
|
||||||
this, &VDirectoryTree::openDirectoryLocation);
|
this, &VDirectoryTree::openDirectoryLocation);
|
||||||
menu.addAction(openLocationAct);
|
menu.addAction(openLocationAct);
|
||||||
@ -645,7 +650,7 @@ void VDirectoryTree::openDirectoryLocation() const
|
|||||||
{
|
{
|
||||||
QTreeWidgetItem *curItem = currentItem();
|
QTreeWidgetItem *curItem = currentItem();
|
||||||
V_ASSERT(curItem);
|
V_ASSERT(curItem);
|
||||||
QUrl url = QUrl::fromLocalFile(getVDirectory(curItem)->fetchBasePath());
|
QUrl url = QUrl::fromLocalFile(getVDirectory(curItem)->fetchPath());
|
||||||
QDesktopServices::openUrl(url);
|
QDesktopServices::openUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,8 +524,10 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos)
|
|||||||
QDesktopServices::openUrl(url);
|
QDesktopServices::openUrl(url);
|
||||||
});
|
});
|
||||||
|
|
||||||
QAction *openLocationAct = new QAction(tr("Open Note Location"), &menu);
|
QAction *openLocationAct = new QAction(VIconUtils::menuIcon(":/resources/icons/open_location.svg"),
|
||||||
openLocationAct->setToolTip(tr("Open the folder containing this note in operating system"));
|
tr("Open Note Location"),
|
||||||
|
&menu);
|
||||||
|
openLocationAct->setToolTip(tr("Explore the folder containing this note in operating system"));
|
||||||
connect(openLocationAct, &QAction::triggered,
|
connect(openLocationAct, &QAction::triggered,
|
||||||
this, [this](){
|
this, [this](){
|
||||||
int tab = GET_TAB_FROM_SENDER();
|
int tab = GET_TAB_FROM_SENDER();
|
||||||
|
737
src/vexplorer.cpp
Normal file
@ -0,0 +1,737 @@
|
|||||||
|
#include "vexplorer.h"
|
||||||
|
|
||||||
|
#include <QtWidgets>
|
||||||
|
#include <QFileSystemModel>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
|
||||||
|
#include "utils/viconutils.h"
|
||||||
|
#include "utils/vutils.h"
|
||||||
|
#include "vconfigmanager.h"
|
||||||
|
#include "vmainwindow.h"
|
||||||
|
#include "vcart.h"
|
||||||
|
#include "vlineedit.h"
|
||||||
|
#include "vhistorylist.h"
|
||||||
|
#include "vorphanfile.h"
|
||||||
|
|
||||||
|
extern VMainWindow *g_mainWin;
|
||||||
|
|
||||||
|
extern VConfigManager *g_config;
|
||||||
|
|
||||||
|
const QString VExplorer::c_infoShortcutSequence = "F2";
|
||||||
|
|
||||||
|
VExplorer::VExplorer(QWidget *p_parent)
|
||||||
|
: QWidget(p_parent),
|
||||||
|
m_initialized(false),
|
||||||
|
m_uiInitialized(false),
|
||||||
|
m_index(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void VExplorer::setupUI()
|
||||||
|
{
|
||||||
|
if (m_uiInitialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_uiInitialized = true;
|
||||||
|
|
||||||
|
QLabel *dirLabel = new QLabel(tr("Directory"), this);
|
||||||
|
|
||||||
|
m_openBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/dir_item.svg"),
|
||||||
|
"",
|
||||||
|
this);
|
||||||
|
m_openBtn->setToolTip(tr("Open"));
|
||||||
|
m_openBtn->setProperty("FlatBtn", true);
|
||||||
|
connect(m_openBtn, &QPushButton::clicked,
|
||||||
|
this, [this]() {
|
||||||
|
static QString defaultPath = g_config->getDocumentPathOrHomePath();
|
||||||
|
QString dirPath = QFileDialog::getExistingDirectory(this,
|
||||||
|
tr("Select Root Directory To Explore"),
|
||||||
|
defaultPath,
|
||||||
|
QFileDialog::ShowDirsOnly
|
||||||
|
| QFileDialog::DontResolveSymlinks);
|
||||||
|
if (!dirPath.isEmpty()) {
|
||||||
|
defaultPath = VUtils::basePathFromPath(dirPath);
|
||||||
|
|
||||||
|
int idx = addEntry(dirPath);
|
||||||
|
updateDirectoryComboBox();
|
||||||
|
if (idx != -1) {
|
||||||
|
setCurrentEntry(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_openLocationBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/open_location.svg"),
|
||||||
|
"",
|
||||||
|
this);
|
||||||
|
m_openLocationBtn->setToolTip(tr("Open Directory Location"));
|
||||||
|
m_openLocationBtn->setProperty("FlatBtn", true);
|
||||||
|
connect(m_openLocationBtn, &QPushButton::clicked,
|
||||||
|
this, [this]() {
|
||||||
|
if (checkIndex()) {
|
||||||
|
QUrl url = QUrl::fromLocalFile(m_entries[m_index].m_directory);
|
||||||
|
QDesktopServices::openUrl(url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_starBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/star.svg"),
|
||||||
|
"",
|
||||||
|
this);
|
||||||
|
m_starBtn->setToolTip(tr("Star"));
|
||||||
|
m_starBtn->setProperty("FlatBtn", true);
|
||||||
|
connect(m_starBtn, &QPushButton::clicked,
|
||||||
|
this, [this]() {
|
||||||
|
if (checkIndex()) {
|
||||||
|
m_entries[m_index].m_isStarred = !m_entries[m_index].m_isStarred;
|
||||||
|
|
||||||
|
g_config->setExplorerEntries(m_entries);
|
||||||
|
|
||||||
|
updateExplorerEntryIndexInConfig();
|
||||||
|
|
||||||
|
updateStarButton();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
QHBoxLayout *dirLayout = new QHBoxLayout();
|
||||||
|
dirLayout->addWidget(dirLabel);
|
||||||
|
dirLayout->addStretch();
|
||||||
|
dirLayout->addWidget(m_openBtn);
|
||||||
|
dirLayout->addWidget(m_openLocationBtn);
|
||||||
|
dirLayout->addWidget(m_starBtn);
|
||||||
|
dirLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
|
m_dirCB = VUtils::getComboBox(this);
|
||||||
|
m_dirCB->setEditable(true);
|
||||||
|
m_dirCB->setLineEdit(new VLineEdit(this));
|
||||||
|
m_dirCB->setToolTip(tr("Path of the root directory to explore"));
|
||||||
|
m_dirCB->lineEdit()->setPlaceholderText(tr("Root path to explore"));
|
||||||
|
m_dirCB->lineEdit()->setProperty("EmbeddedEdit", true);
|
||||||
|
connect(m_dirCB->lineEdit(), &QLineEdit::editingFinished,
|
||||||
|
this, [this]() {
|
||||||
|
QString text = m_dirCB->currentText();
|
||||||
|
int idx = addEntry(text);
|
||||||
|
updateDirectoryComboBox();
|
||||||
|
if (idx != -1) {
|
||||||
|
setCurrentEntry(idx);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
QCompleter *completer = new QCompleter(this);
|
||||||
|
QFileSystemModel *fsModel = new QFileSystemModel(completer);
|
||||||
|
fsModel->setRootPath("");
|
||||||
|
completer->setModel(fsModel);
|
||||||
|
// Enable styling the popup list via QListView::item.
|
||||||
|
completer->popup()->setItemDelegate(new QStyledItemDelegate(this));
|
||||||
|
completer->setCompletionMode(QCompleter::PopupCompletion);
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
#else
|
||||||
|
completer->setCaseSensitivity(Qt::CaseSensitive);
|
||||||
|
#endif
|
||||||
|
m_dirCB->lineEdit()->setCompleter(completer);
|
||||||
|
connect(m_dirCB, SIGNAL(activated(int)),
|
||||||
|
this, SLOT(handleEntryActivated(int)));
|
||||||
|
m_dirCB->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
|
||||||
|
|
||||||
|
QLabel *imgLabel = new QLabel(tr("Image Folder"), this);
|
||||||
|
|
||||||
|
m_imgFolderEdit = new VLineEdit(this);
|
||||||
|
m_imgFolderEdit->setPlaceholderText(tr("Use global configuration (%1)")
|
||||||
|
.arg(g_config->getImageFolderExt()));
|
||||||
|
QString imgFolderTip = tr("Set the path of the image folder to store images "
|
||||||
|
"of files within the root directory.\nIf absolute path is used, "
|
||||||
|
"VNote will not manage those images."
|
||||||
|
"(empty to use global configuration)");
|
||||||
|
m_imgFolderEdit->setToolTip(imgFolderTip);
|
||||||
|
connect(m_imgFolderEdit, &QLineEdit::editingFinished,
|
||||||
|
this, [this]() {
|
||||||
|
if (checkIndex()) {
|
||||||
|
QString folder = m_imgFolderEdit->text();
|
||||||
|
if (folder.isEmpty() || VUtils::checkPathLegal(folder)) {
|
||||||
|
m_entries[m_index].m_imageFolder = folder;
|
||||||
|
if (m_entries[m_index].m_isStarred) {
|
||||||
|
g_config->setExplorerEntries(m_entries);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_imgFolderEdit->setText(m_entries[m_index].m_imageFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// New file/dir.
|
||||||
|
m_newFileBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/create_note_tb.svg"),
|
||||||
|
"",
|
||||||
|
this);
|
||||||
|
m_newFileBtn->setToolTip(tr("New File"));
|
||||||
|
m_newFileBtn->setProperty("FlatBtn", true);
|
||||||
|
connect(m_newFileBtn, &QPushButton::clicked,
|
||||||
|
this, &VExplorer::newFile);
|
||||||
|
|
||||||
|
m_newDirBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/create_rootdir_tb.svg"),
|
||||||
|
"",
|
||||||
|
this);
|
||||||
|
m_newDirBtn->setToolTip(tr("New Folder"));
|
||||||
|
m_newDirBtn->setProperty("FlatBtn", true);
|
||||||
|
connect(m_newDirBtn, &QPushButton::clicked,
|
||||||
|
this, &VExplorer::newFolder);
|
||||||
|
|
||||||
|
QHBoxLayout *btnLayout = new QHBoxLayout();
|
||||||
|
btnLayout->addStretch();
|
||||||
|
btnLayout->addWidget(m_newFileBtn);
|
||||||
|
btnLayout->addWidget(m_newDirBtn);
|
||||||
|
btnLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
|
QFileSystemModel *dirModel = new QFileSystemModel(this);
|
||||||
|
dirModel->setRootPath("");
|
||||||
|
m_tree = new QTreeView(this);
|
||||||
|
m_tree->setModel(dirModel);
|
||||||
|
m_tree->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
|
m_tree->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
connect(m_tree, &QTreeView::customContextMenuRequested,
|
||||||
|
this, &VExplorer::handleContextMenuRequested);
|
||||||
|
connect(m_tree, &QTreeView::activated,
|
||||||
|
this, [this](const QModelIndex &p_index) {
|
||||||
|
QFileSystemModel *model = static_cast<QFileSystemModel *>(m_tree->model());
|
||||||
|
if (!model->isDir(p_index)) {
|
||||||
|
QStringList files;
|
||||||
|
files << model->filePath(p_index);
|
||||||
|
openFiles(files, g_config->getNoteOpenMode());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(m_tree, &QTreeView::expanded,
|
||||||
|
this, &VExplorer::resizeTreeToContents);
|
||||||
|
connect(m_tree, &QTreeView::collapsed,
|
||||||
|
this, &VExplorer::resizeTreeToContents);
|
||||||
|
connect(dirModel, &QFileSystemModel::directoryLoaded,
|
||||||
|
this, &VExplorer::resizeTreeToContents);
|
||||||
|
|
||||||
|
m_tree->setHeaderHidden(true);
|
||||||
|
// Show only the Name column.
|
||||||
|
for (int i = 1; i < dirModel->columnCount(); ++i) {
|
||||||
|
m_tree->hideColumn(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVBoxLayout *mainLayout = new QVBoxLayout();
|
||||||
|
mainLayout->addLayout(dirLayout);
|
||||||
|
mainLayout->addWidget(m_dirCB);
|
||||||
|
mainLayout->addWidget(imgLabel);
|
||||||
|
mainLayout->addWidget(m_imgFolderEdit);
|
||||||
|
mainLayout->addLayout(btnLayout);
|
||||||
|
mainLayout->addWidget(m_tree);
|
||||||
|
mainLayout->setContentsMargins(3, 0, 3, 0);
|
||||||
|
|
||||||
|
setLayout(mainLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VExplorer::init()
|
||||||
|
{
|
||||||
|
if (m_initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_initialized = true;
|
||||||
|
|
||||||
|
setupUI();
|
||||||
|
|
||||||
|
QShortcut *infoShortcut = new QShortcut(QKeySequence(c_infoShortcutSequence), this);
|
||||||
|
infoShortcut->setContext(Qt::WidgetWithChildrenShortcut);
|
||||||
|
connect(infoShortcut, &QShortcut::activated,
|
||||||
|
this, [this]() {
|
||||||
|
});
|
||||||
|
|
||||||
|
g_config->getExplorerEntries(m_entries);
|
||||||
|
m_index = g_config->getExplorerCurrentIndex();
|
||||||
|
if (m_entries.isEmpty()) {
|
||||||
|
m_index = -1;
|
||||||
|
g_config->setExplorerCurrentIndex(m_index);
|
||||||
|
} else if (m_index < 0 || m_index >= m_entries.size()) {
|
||||||
|
m_index = 0;
|
||||||
|
g_config->setExplorerCurrentIndex(m_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateDirectoryComboBox();
|
||||||
|
|
||||||
|
setCurrentEntry(m_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VExplorer::showEvent(QShowEvent *p_event)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
|
||||||
|
QWidget::showEvent(p_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VExplorer::focusInEvent(QFocusEvent *p_event)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
|
||||||
|
QWidget::focusInEvent(p_event);
|
||||||
|
|
||||||
|
if (m_index < 0) {
|
||||||
|
m_openBtn->setFocus();
|
||||||
|
} else {
|
||||||
|
m_tree->setFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VExplorer::updateUI()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void VExplorer::updateDirectoryComboBox()
|
||||||
|
{
|
||||||
|
m_dirCB->clear();
|
||||||
|
|
||||||
|
for (int i = 0; i < m_entries.size(); ++i) {
|
||||||
|
m_dirCB->addItem(QDir::toNativeSeparators(m_entries[i].m_directory));
|
||||||
|
m_dirCB->setItemData(i, m_entries[i].m_directory, Qt::ToolTipRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dirCB->setCurrentIndex(m_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
int VExplorer::addEntry(const QString &p_dir)
|
||||||
|
{
|
||||||
|
if (p_dir.isEmpty() || !QFileInfo::exists(p_dir) || !QDir::isAbsolutePath(p_dir)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString dir(QDir::cleanPath(p_dir));
|
||||||
|
int idx = -1;
|
||||||
|
for (idx = 0; idx < m_entries.size(); ++idx) {
|
||||||
|
if (VUtils::equalPath(dir, m_entries[idx].m_directory)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < m_entries.size()) {
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_entries.append(VExplorerEntry(QFileInfo(dir).absoluteFilePath(), ""));
|
||||||
|
return m_entries.size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VExplorer::handleEntryActivated(int p_idx)
|
||||||
|
{
|
||||||
|
bool valid = false;
|
||||||
|
QString imgFolder;
|
||||||
|
|
||||||
|
if (p_idx >= 0 && p_idx < m_entries.size()) {
|
||||||
|
valid = true;
|
||||||
|
imgFolder = m_entries[p_idx].m_imageFolder;
|
||||||
|
} else {
|
||||||
|
p_idx = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_index = p_idx;
|
||||||
|
|
||||||
|
updateExplorerEntryIndexInConfig();
|
||||||
|
|
||||||
|
m_imgFolderEdit->setText(imgFolder);
|
||||||
|
m_imgFolderEdit->setEnabled(valid);
|
||||||
|
|
||||||
|
m_openLocationBtn->setEnabled(valid);
|
||||||
|
m_newFileBtn->setEnabled(valid);
|
||||||
|
m_newDirBtn->setEnabled(valid);
|
||||||
|
|
||||||
|
updateStarButton();
|
||||||
|
|
||||||
|
updateTree();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VExplorer::updateStarButton()
|
||||||
|
{
|
||||||
|
// -1 for disabled, 0 for star, 1 for unstar.
|
||||||
|
int star = -1;
|
||||||
|
|
||||||
|
if (checkIndex()) {
|
||||||
|
star = m_entries[m_index].m_isStarred ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool enabled = true;
|
||||||
|
switch (star) {
|
||||||
|
default:
|
||||||
|
enabled = false;
|
||||||
|
V_FALLTHROUGH;
|
||||||
|
case 0:
|
||||||
|
m_starBtn->setEnabled(enabled);
|
||||||
|
m_starBtn->setIcon(VIconUtils::buttonIcon(":/resources/icons/star.svg"));
|
||||||
|
m_starBtn->setToolTip(tr("Star"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
m_starBtn->setEnabled(enabled);
|
||||||
|
m_starBtn->setIcon(VIconUtils::buttonIcon(":/resources/icons/unstar.svg"));
|
||||||
|
m_starBtn->setToolTip(tr("Unstar"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VExplorer::setCurrentEntry(int p_index)
|
||||||
|
{
|
||||||
|
m_dirCB->setCurrentIndex(p_index);
|
||||||
|
|
||||||
|
handleEntryActivated(p_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VExplorer::updateExplorerEntryIndexInConfig()
|
||||||
|
{
|
||||||
|
int idx = -1;
|
||||||
|
if (m_index >= 0 && m_index < m_entries.size()) {
|
||||||
|
int starIdx = -1;
|
||||||
|
for (int j = 0; j <= m_index; ++j) {
|
||||||
|
if (m_entries[j].m_isStarred) {
|
||||||
|
++starIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (starIdx > -1) {
|
||||||
|
idx = starIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_config->setExplorerCurrentIndex(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VExplorer::updateTree()
|
||||||
|
{
|
||||||
|
if (checkIndex()) {
|
||||||
|
QString pa = QDir::cleanPath(m_entries[m_index].m_directory);
|
||||||
|
QFileSystemModel *model = static_cast<QFileSystemModel *>(m_tree->model());
|
||||||
|
model->setRootPath(pa);
|
||||||
|
const QModelIndex rootIndex = model->index(pa);
|
||||||
|
if (rootIndex.isValid()) {
|
||||||
|
m_tree->setRootIndex(rootIndex);
|
||||||
|
resizeTreeToContents();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
model->setRootPath("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_tree->reset();
|
||||||
|
resizeTreeToContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VExplorer::handleContextMenuRequested(QPoint p_pos)
|
||||||
|
{
|
||||||
|
QModelIndex index = m_tree->indexAt(p_pos);
|
||||||
|
if (!index.isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenu menu(this);
|
||||||
|
menu.setToolTipsVisible(true);
|
||||||
|
|
||||||
|
QFileSystemModel *model = static_cast<QFileSystemModel *>(m_tree->model());
|
||||||
|
QModelIndexList selectedIdx = m_tree->selectionModel()->selectedRows();
|
||||||
|
if (selectedIdx.size() == 1 && model->isDir(selectedIdx[0])) {
|
||||||
|
QString filePath = model->filePath(selectedIdx[0]);
|
||||||
|
|
||||||
|
QAction *setRootAct = new QAction(VIconUtils::menuIcon(":/resources/icons/explore_root.svg"),
|
||||||
|
tr("Set As Root"),
|
||||||
|
&menu);
|
||||||
|
setRootAct->setToolTip(tr("Set current folder as the root directory to explore"));
|
||||||
|
connect(setRootAct, &QAction::triggered,
|
||||||
|
this, [this, filePath]() {
|
||||||
|
int idx = addEntry(filePath);
|
||||||
|
updateDirectoryComboBox();
|
||||||
|
if (idx != -1) {
|
||||||
|
setCurrentEntry(idx);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.addAction(setRootAct);
|
||||||
|
|
||||||
|
QAction *openLocationAct = new QAction(VIconUtils::menuIcon(":/resources/icons/open_location.svg"),
|
||||||
|
tr("Open Folder Location"),
|
||||||
|
&menu);
|
||||||
|
openLocationAct->setToolTip(tr("Explore this folder in operating system"));
|
||||||
|
connect(openLocationAct, &QAction::triggered,
|
||||||
|
this, [this, filePath]() {
|
||||||
|
QDesktopServices::openUrl(QUrl::fromLocalFile(filePath));
|
||||||
|
});
|
||||||
|
menu.addAction(openLocationAct);
|
||||||
|
|
||||||
|
menu.addSeparator();
|
||||||
|
|
||||||
|
QAction *fileInfoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/note_info.svg"),
|
||||||
|
tr("&Info\t%1").arg(VUtils::getShortcutText(c_infoShortcutSequence)),
|
||||||
|
&menu);
|
||||||
|
fileInfoAct->setToolTip(tr("View and edit current folder's information"));
|
||||||
|
connect(fileInfoAct, &QAction::triggered,
|
||||||
|
this, [this, filePath]() {
|
||||||
|
renameFile(filePath);
|
||||||
|
});
|
||||||
|
menu.addAction(fileInfoAct);
|
||||||
|
|
||||||
|
menu.exec(m_tree->mapToGlobal(p_pos));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool allFiles = true;
|
||||||
|
QStringList selectedFiles;
|
||||||
|
for (auto const & it : selectedIdx) {
|
||||||
|
if (model->isDir(it)) {
|
||||||
|
allFiles = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedFiles << model->filePath(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!allFiles) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only files are selected.
|
||||||
|
// We do not support copy/cut/deletion of files.
|
||||||
|
QAction *openInReadAct = new QAction(VIconUtils::menuIcon(":/resources/icons/reading.svg"),
|
||||||
|
tr("Open In Read Mode"),
|
||||||
|
&menu);
|
||||||
|
openInReadAct->setToolTip(tr("Open selected files in read mode"));
|
||||||
|
connect(openInReadAct, &QAction::triggered,
|
||||||
|
this, [this, selectedFiles]() {
|
||||||
|
openFiles(selectedFiles, OpenFileMode::Read, true);
|
||||||
|
});
|
||||||
|
menu.addAction(openInReadAct);
|
||||||
|
|
||||||
|
QAction *openInEditAct = new QAction(VIconUtils::menuIcon(":/resources/icons/editing.svg"),
|
||||||
|
tr("Open In Edit Mode"),
|
||||||
|
&menu);
|
||||||
|
openInEditAct->setToolTip(tr("Open selected files in edit mode"));
|
||||||
|
connect(openInEditAct, &QAction::triggered,
|
||||||
|
this, [this, selectedFiles]() {
|
||||||
|
openFiles(selectedFiles, OpenFileMode::Edit, true);
|
||||||
|
});
|
||||||
|
menu.addAction(openInEditAct);
|
||||||
|
|
||||||
|
menu.addSeparator();
|
||||||
|
|
||||||
|
if (selectedFiles.size() == 1) {
|
||||||
|
QAction *openLocationAct = new QAction(VIconUtils::menuIcon(":/resources/icons/open_location.svg"),
|
||||||
|
tr("Open File Location"),
|
||||||
|
&menu);
|
||||||
|
openLocationAct->setToolTip(tr("Explore the folder containing this file in operating system"));
|
||||||
|
connect(openLocationAct, &QAction::triggered,
|
||||||
|
this, [this, filePath = selectedFiles[0]] () {
|
||||||
|
QDesktopServices::openUrl(QUrl::fromLocalFile(VUtils::basePathFromPath(filePath)));
|
||||||
|
});
|
||||||
|
menu.addAction(openLocationAct);
|
||||||
|
|
||||||
|
menu.addSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
QAction *addToCartAct = new QAction(VIconUtils::menuIcon(":/resources/icons/cart.svg"),
|
||||||
|
tr("Add To Cart"),
|
||||||
|
&menu);
|
||||||
|
addToCartAct->setToolTip(tr("Add selected files to Cart for further processing"));
|
||||||
|
connect(addToCartAct, &QAction::triggered,
|
||||||
|
this, [this, selectedFiles]() {
|
||||||
|
VCart *cart = g_mainWin->getCart();
|
||||||
|
for (int i = 0; i < selectedFiles.size(); ++i) {
|
||||||
|
cart->addFile(selectedFiles[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_mainWin->showStatusMessage(tr("%1 %2 added to Cart")
|
||||||
|
.arg(selectedFiles.size())
|
||||||
|
.arg(selectedFiles.size() > 1 ? tr("files") : tr("file")));
|
||||||
|
});
|
||||||
|
menu.addAction(addToCartAct);
|
||||||
|
|
||||||
|
QAction *pinToHistoryAct = new QAction(VIconUtils::menuIcon(":/resources/icons/pin.svg"),
|
||||||
|
tr("Pin To History"),
|
||||||
|
&menu);
|
||||||
|
pinToHistoryAct->setToolTip(tr("Pin selected files to History"));
|
||||||
|
connect(pinToHistoryAct, &QAction::triggered,
|
||||||
|
this, [this, selectedFiles]() {
|
||||||
|
g_mainWin->getHistoryList()->pinFiles(selectedFiles);
|
||||||
|
g_mainWin->showStatusMessage(tr("%1 %2 pinned to History")
|
||||||
|
.arg(selectedFiles.size())
|
||||||
|
.arg(selectedFiles.size() > 1 ? tr("files") : tr("file")));
|
||||||
|
});
|
||||||
|
menu.addAction(pinToHistoryAct);
|
||||||
|
|
||||||
|
if (selectedFiles.size() == 1) {
|
||||||
|
QAction *fileInfoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/note_info.svg"),
|
||||||
|
tr("&Info\t%1").arg(VUtils::getShortcutText(c_infoShortcutSequence)),
|
||||||
|
&menu);
|
||||||
|
fileInfoAct->setToolTip(tr("View and edit current file's information"));
|
||||||
|
connect(fileInfoAct, &QAction::triggered,
|
||||||
|
this, [this, filePath = selectedFiles[0]]() {
|
||||||
|
renameFile(filePath);
|
||||||
|
});
|
||||||
|
menu.addAction(fileInfoAct);
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.exec(m_tree->mapToGlobal(p_pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
void VExplorer::openFiles(const QStringList &p_files,
|
||||||
|
OpenFileMode p_mode,
|
||||||
|
bool p_forceMode)
|
||||||
|
{
|
||||||
|
if (!p_files.isEmpty()) {
|
||||||
|
Q_ASSERT(checkIndex());
|
||||||
|
QString imgFolder = m_entries[m_index].m_imageFolder;
|
||||||
|
|
||||||
|
QVector<VFile *> vfiles = g_mainWin->openFiles(p_files, false, p_mode, p_forceMode, false);
|
||||||
|
|
||||||
|
// Set image folder.
|
||||||
|
for (auto it : vfiles) {
|
||||||
|
if (it->getType() == FileType::Orphan) {
|
||||||
|
static_cast<VOrphanFile *>(it)->setImageFolder(imgFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VExplorer::resizeTreeToContents()
|
||||||
|
{
|
||||||
|
m_tree->resizeColumnToContents(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. When only one folder is selected, create a file in that folder.
|
||||||
|
// 2. Otherwise, create a file in the root directory.
|
||||||
|
void VExplorer::newFile()
|
||||||
|
{
|
||||||
|
Q_ASSERT(checkIndex());
|
||||||
|
|
||||||
|
QString parentDir;
|
||||||
|
|
||||||
|
QFileSystemModel *model = static_cast<QFileSystemModel *>(m_tree->model());
|
||||||
|
QModelIndexList selectedIdx = m_tree->selectionModel()->selectedRows();
|
||||||
|
if (selectedIdx.size() == 1 && model->isDir(selectedIdx[0])) {
|
||||||
|
parentDir = model->filePath(selectedIdx[0]);
|
||||||
|
} else {
|
||||||
|
parentDir = m_entries[m_index].m_directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "new file in" << parentDir;
|
||||||
|
|
||||||
|
QString name = VUtils::promptForFileName(tr("New File"),
|
||||||
|
tr("File name (%1):").arg(parentDir),
|
||||||
|
"",
|
||||||
|
parentDir,
|
||||||
|
g_mainWin);
|
||||||
|
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDir paDir(parentDir);
|
||||||
|
QString filePath = paDir.filePath(name);
|
||||||
|
QFile file(filePath);
|
||||||
|
if (!file.open(QIODevice::WriteOnly)) {
|
||||||
|
qWarning() << "Fail to create file" << filePath;
|
||||||
|
VUtils::showMessage(QMessageBox::Warning,
|
||||||
|
tr("New File"),
|
||||||
|
tr("Fail to create file <span style=\"%1\">%2</span>.")
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(filePath),
|
||||||
|
"",
|
||||||
|
QMessageBox::Ok,
|
||||||
|
QMessageBox::Ok,
|
||||||
|
g_mainWin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
m_tree->setFocus();
|
||||||
|
|
||||||
|
// Select the file.
|
||||||
|
const QModelIndex fileIndex = model->index(filePath);
|
||||||
|
Q_ASSERT(fileIndex.isValid());
|
||||||
|
m_tree->scrollTo(fileIndex);
|
||||||
|
m_tree->clearSelection();
|
||||||
|
m_tree->setCurrentIndex(fileIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. When only one folder is selected, create a folder in that folder.
|
||||||
|
// 2. Otherwise, create a folder in the root directory.
|
||||||
|
void VExplorer::newFolder()
|
||||||
|
{
|
||||||
|
Q_ASSERT(checkIndex());
|
||||||
|
|
||||||
|
QString parentDir;
|
||||||
|
|
||||||
|
QFileSystemModel *model = static_cast<QFileSystemModel *>(m_tree->model());
|
||||||
|
QModelIndexList selectedIdx = m_tree->selectionModel()->selectedRows();
|
||||||
|
if (selectedIdx.size() == 1 && model->isDir(selectedIdx[0])) {
|
||||||
|
parentDir = model->filePath(selectedIdx[0]);
|
||||||
|
} else {
|
||||||
|
parentDir = m_entries[m_index].m_directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "new folder in" << parentDir;
|
||||||
|
|
||||||
|
QString name = VUtils::promptForFileName(tr("New Folder"),
|
||||||
|
tr("Folder name (%1):").arg(parentDir),
|
||||||
|
"",
|
||||||
|
parentDir,
|
||||||
|
g_mainWin);
|
||||||
|
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDir paDir(parentDir);
|
||||||
|
QString folderPath = paDir.filePath(name);
|
||||||
|
if (!paDir.mkdir(name)) {
|
||||||
|
qWarning() << "Fail to create folder" << folderPath;
|
||||||
|
VUtils::showMessage(QMessageBox::Warning,
|
||||||
|
tr("New Folder"),
|
||||||
|
tr("Fail to create folder <span style=\"%1\">%2</span>.")
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(folderPath),
|
||||||
|
"",
|
||||||
|
QMessageBox::Ok,
|
||||||
|
QMessageBox::Ok,
|
||||||
|
g_mainWin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_tree->setFocus();
|
||||||
|
|
||||||
|
// Select the folder.
|
||||||
|
const QModelIndex folderIndex = model->index(folderPath);
|
||||||
|
Q_ASSERT(folderIndex.isValid());
|
||||||
|
m_tree->scrollTo(folderIndex);
|
||||||
|
m_tree->clearSelection();
|
||||||
|
m_tree->setCurrentIndex(folderIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VExplorer::renameFile(const QString &p_filePath)
|
||||||
|
{
|
||||||
|
Q_ASSERT(checkIndex());
|
||||||
|
|
||||||
|
QFileInfo fi(p_filePath);
|
||||||
|
QString parentDir = fi.path();
|
||||||
|
QString oldName = fi.fileName();
|
||||||
|
|
||||||
|
QString name = VUtils::promptForFileName(tr("File Information"),
|
||||||
|
tr("Rename file (%1):").arg(p_filePath),
|
||||||
|
oldName,
|
||||||
|
parentDir,
|
||||||
|
g_mainWin);
|
||||||
|
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDir paDir(parentDir);
|
||||||
|
if (!paDir.rename(oldName, name)) {
|
||||||
|
qWarning() << "Fail to rename" << p_filePath;
|
||||||
|
VUtils::showMessage(QMessageBox::Warning,
|
||||||
|
tr("File Information"),
|
||||||
|
tr("Fail to rename file <span style=\"%1\">%2</span>.")
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(p_filePath),
|
||||||
|
"",
|
||||||
|
QMessageBox::Ok,
|
||||||
|
QMessageBox::Ok,
|
||||||
|
g_mainWin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
95
src/vexplorer.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
#ifndef VEXPLORER_H
|
||||||
|
#define VEXPLORER_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
#include "vexplorerentry.h"
|
||||||
|
#include "vconstants.h"
|
||||||
|
|
||||||
|
class QPushButton;
|
||||||
|
class QTreeView;
|
||||||
|
class QTreeWidgetItem;
|
||||||
|
class QShowEvent;
|
||||||
|
class QFocusEvent;
|
||||||
|
class QComboBox;
|
||||||
|
class VLineEdit;
|
||||||
|
|
||||||
|
class VExplorer : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit VExplorer(QWidget *p_parent = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
void focusInEvent(QFocusEvent *p_event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleEntryActivated(int p_idx);
|
||||||
|
|
||||||
|
void handleContextMenuRequested(QPoint p_pos);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupUI();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
void updateUI();
|
||||||
|
|
||||||
|
void updateDirectoryComboBox();
|
||||||
|
|
||||||
|
// Add an entry to m_entries with @p_dir being the path of the entry.
|
||||||
|
// Return the index of the corresponding entry if succeed; otherwise,
|
||||||
|
// return -1.
|
||||||
|
int addEntry(const QString &p_dir);
|
||||||
|
|
||||||
|
void setCurrentEntry(int p_index);
|
||||||
|
|
||||||
|
bool checkIndex() const;
|
||||||
|
|
||||||
|
void updateExplorerEntryIndexInConfig();
|
||||||
|
|
||||||
|
void updateStarButton();
|
||||||
|
|
||||||
|
void updateTree();
|
||||||
|
|
||||||
|
void openFiles(const QStringList &p_files,
|
||||||
|
OpenFileMode p_mode,
|
||||||
|
bool p_forceMode = false);
|
||||||
|
|
||||||
|
void resizeTreeToContents();
|
||||||
|
|
||||||
|
void newFile();
|
||||||
|
|
||||||
|
void newFolder();
|
||||||
|
|
||||||
|
void renameFile(const QString &p_filePath);
|
||||||
|
|
||||||
|
bool m_initialized;
|
||||||
|
|
||||||
|
bool m_uiInitialized;
|
||||||
|
|
||||||
|
QVector<VExplorerEntry> m_entries;
|
||||||
|
|
||||||
|
int m_index;
|
||||||
|
|
||||||
|
QPushButton *m_openBtn;
|
||||||
|
QPushButton *m_openLocationBtn;
|
||||||
|
QPushButton *m_starBtn;
|
||||||
|
QComboBox *m_dirCB;
|
||||||
|
VLineEdit *m_imgFolderEdit;
|
||||||
|
QPushButton *m_newFileBtn;
|
||||||
|
QPushButton *m_newDirBtn;
|
||||||
|
QTreeView *m_tree;
|
||||||
|
|
||||||
|
static const QString c_infoShortcutSequence;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool VExplorer::checkIndex() const
|
||||||
|
{
|
||||||
|
return m_index >= 0 && m_index < m_entries.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // VEXPLORER_H
|
51
src/vexplorerentry.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#ifndef VEXPLORERENTRY_H
|
||||||
|
#define VEXPLORERENTRY_H
|
||||||
|
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
|
namespace ExplorerConfig
|
||||||
|
{
|
||||||
|
static const QString c_directory = "directory";
|
||||||
|
static const QString c_imageFolder = "image_folder";
|
||||||
|
}
|
||||||
|
|
||||||
|
class VExplorerEntry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VExplorerEntry()
|
||||||
|
: m_isStarred(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
VExplorerEntry(const QString &p_directory,
|
||||||
|
const QString &p_imageFolder,
|
||||||
|
bool p_isStarred = false)
|
||||||
|
: m_directory(p_directory),
|
||||||
|
m_imageFolder(p_imageFolder),
|
||||||
|
m_isStarred(p_isStarred)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static VExplorerEntry fromSettings(const QSettings *p_settings)
|
||||||
|
{
|
||||||
|
VExplorerEntry entry;
|
||||||
|
entry.m_directory = p_settings->value(ExplorerConfig::c_directory).toString();
|
||||||
|
entry.m_imageFolder = p_settings->value(ExplorerConfig::c_imageFolder).toString();
|
||||||
|
entry.m_isStarred = true;
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void toSettings(QSettings *p_settings) const
|
||||||
|
{
|
||||||
|
p_settings->setValue(ExplorerConfig::c_directory, m_directory);
|
||||||
|
p_settings->setValue(ExplorerConfig::c_imageFolder, m_imageFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString m_directory;
|
||||||
|
|
||||||
|
QString m_imageFolder;
|
||||||
|
|
||||||
|
bool m_isStarred;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VEXPLORERENTRY_H
|
@ -609,8 +609,10 @@ void VFileList::contextMenuRequested(QPoint pos)
|
|||||||
if (item) {
|
if (item) {
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
if (selectedSize == 1) {
|
if (selectedSize == 1) {
|
||||||
QAction *openLocationAct = new QAction(tr("&Open Note Location"), &menu);
|
QAction *openLocationAct = new QAction(VIconUtils::menuIcon(":/resources/icons/open_location.svg"),
|
||||||
openLocationAct->setToolTip(tr("Open the folder containing this note in operating system"));
|
tr("&Open Note Location"),
|
||||||
|
&menu);
|
||||||
|
openLocationAct->setToolTip(tr("Explore the folder containing this note in operating system"));
|
||||||
connect(openLocationAct, &QAction::triggered,
|
connect(openLocationAct, &QAction::triggered,
|
||||||
this, &VFileList::openFileLocation);
|
this, &VFileList::openFileLocation);
|
||||||
menu.addAction(openLocationAct);
|
menu.addAction(openLocationAct);
|
||||||
@ -1359,7 +1361,7 @@ void VFileList::sortFiles(QVector<VNoteFile *> &p_files, ViewOrder p_order)
|
|||||||
|
|
||||||
case ViewOrder::NameReverse:
|
case ViewOrder::NameReverse:
|
||||||
reverse = true;
|
reverse = true;
|
||||||
V_FALLTHROUGH
|
V_FALLTHROUGH;
|
||||||
case ViewOrder::Name:
|
case ViewOrder::Name:
|
||||||
std::sort(p_files.begin(), p_files.end(), [reverse](const VNoteFile *p_a, const VNoteFile *p_b) {
|
std::sort(p_files.begin(), p_files.end(), [reverse](const VNoteFile *p_a, const VNoteFile *p_b) {
|
||||||
if (reverse) {
|
if (reverse) {
|
||||||
@ -1372,7 +1374,7 @@ void VFileList::sortFiles(QVector<VNoteFile *> &p_files, ViewOrder p_order)
|
|||||||
|
|
||||||
case ViewOrder::CreatedTimeReverse:
|
case ViewOrder::CreatedTimeReverse:
|
||||||
reverse = true;
|
reverse = true;
|
||||||
V_FALLTHROUGH
|
V_FALLTHROUGH;
|
||||||
case ViewOrder::CreatedTime:
|
case ViewOrder::CreatedTime:
|
||||||
std::sort(p_files.begin(), p_files.end(), [reverse](const VNoteFile *p_a, const VNoteFile *p_b) {
|
std::sort(p_files.begin(), p_files.end(), [reverse](const VNoteFile *p_a, const VNoteFile *p_b) {
|
||||||
if (reverse) {
|
if (reverse) {
|
||||||
@ -1385,7 +1387,7 @@ void VFileList::sortFiles(QVector<VNoteFile *> &p_files, ViewOrder p_order)
|
|||||||
|
|
||||||
case ViewOrder::ModifiedTimeReverse:
|
case ViewOrder::ModifiedTimeReverse:
|
||||||
reverse = true;
|
reverse = true;
|
||||||
V_FALLTHROUGH
|
V_FALLTHROUGH;
|
||||||
case ViewOrder::ModifiedTime:
|
case ViewOrder::ModifiedTime:
|
||||||
std::sort(p_files.begin(), p_files.end(), [reverse](const VNoteFile *p_a, const VNoteFile *p_b) {
|
std::sort(p_files.begin(), p_files.end(), [reverse](const VNoteFile *p_a, const VNoteFile *p_b) {
|
||||||
if (reverse) {
|
if (reverse) {
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include "vlistfolderue.h"
|
#include "vlistfolderue.h"
|
||||||
#include "dialog/vfixnotebookdialog.h"
|
#include "dialog/vfixnotebookdialog.h"
|
||||||
#include "vhistorylist.h"
|
#include "vhistorylist.h"
|
||||||
|
#include "vexplorer.h"
|
||||||
|
|
||||||
extern VConfigManager *g_config;
|
extern VConfigManager *g_config;
|
||||||
|
|
||||||
@ -280,6 +281,11 @@ void VMainWindow::setupNaviBox()
|
|||||||
m_naviBox->addItem(m_historyList,
|
m_naviBox->addItem(m_historyList,
|
||||||
":/resources/icons/history.svg",
|
":/resources/icons/history.svg",
|
||||||
tr("History"));
|
tr("History"));
|
||||||
|
|
||||||
|
m_explorer = new VExplorer();
|
||||||
|
m_naviBox->addItem(m_explorer,
|
||||||
|
":/resources/icons/explorer.svg",
|
||||||
|
tr("Explorer"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMainWindow::setupNotebookPanel()
|
void VMainWindow::setupNotebookPanel()
|
||||||
@ -930,7 +936,11 @@ void VMainWindow::initFileMenu()
|
|||||||
// Update lastPath
|
// Update lastPath
|
||||||
lastPath = QFileInfo(files[0]).path();
|
lastPath = QFileInfo(files[0]).path();
|
||||||
|
|
||||||
openFiles(VUtils::filterFilePathsToOpen(files));
|
openFiles(VUtils::filterFilePathsToOpen(files),
|
||||||
|
false,
|
||||||
|
g_config->getNoteOpenMode(),
|
||||||
|
false,
|
||||||
|
false);
|
||||||
});
|
});
|
||||||
|
|
||||||
fileMenu->addAction(openAct);
|
fileMenu->addAction(openAct);
|
||||||
@ -2130,6 +2140,7 @@ void VMainWindow::saveStateAndGeometry()
|
|||||||
g_config->setSearchDockChecked(m_searchDock->isVisible());
|
g_config->setSearchDockChecked(m_searchDock->isVisible());
|
||||||
g_config->setNotebookSplitterState(m_nbSplitter->saveState());
|
g_config->setNotebookSplitterState(m_nbSplitter->saveState());
|
||||||
g_config->setMainSplitterState(m_mainSplitter->saveState());
|
g_config->setMainSplitterState(m_mainSplitter->saveState());
|
||||||
|
g_config->setNaviBoxCurrentIndex(m_naviBox->currentIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMainWindow::restoreStateAndGeometry()
|
void VMainWindow::restoreStateAndGeometry()
|
||||||
@ -2156,6 +2167,8 @@ void VMainWindow::restoreStateAndGeometry()
|
|||||||
if (!nbSplitterState.isEmpty()) {
|
if (!nbSplitterState.isEmpty()) {
|
||||||
m_nbSplitter->restoreState(nbSplitterState);
|
m_nbSplitter->restoreState(nbSplitterState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_naviBox->setCurrentIndex(g_config->getNaviBoxCurrentIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMainWindow::handleCurrentDirectoryChanged(const VDirectory *p_dir)
|
void VMainWindow::handleCurrentDirectoryChanged(const VDirectory *p_dir)
|
||||||
@ -2457,12 +2470,15 @@ bool VMainWindow::tryOpenInternalFile(const QString &p_filePath)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMainWindow::openFiles(const QStringList &p_files,
|
QVector<VFile *> VMainWindow::openFiles(const QStringList &p_files,
|
||||||
bool p_forceOrphan,
|
bool p_forceOrphan,
|
||||||
OpenFileMode p_mode,
|
OpenFileMode p_mode,
|
||||||
bool p_forceMode,
|
bool p_forceMode,
|
||||||
bool p_oneByOne)
|
bool p_oneByOne)
|
||||||
{
|
{
|
||||||
|
QVector<VFile *> vfiles;
|
||||||
|
vfiles.reserve(p_files.size());
|
||||||
|
|
||||||
for (int i = 0; i < p_files.size(); ++i) {
|
for (int i = 0; i < p_files.size(); ++i) {
|
||||||
VFile *file = NULL;
|
VFile *file = NULL;
|
||||||
if (!p_forceOrphan) {
|
if (!p_forceOrphan) {
|
||||||
@ -2474,10 +2490,14 @@ void VMainWindow::openFiles(const QStringList &p_files,
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_editArea->openFile(file, p_mode, p_forceMode);
|
m_editArea->openFile(file, p_mode, p_forceMode);
|
||||||
|
vfiles.append(file);
|
||||||
|
|
||||||
if (p_oneByOne) {
|
if (p_oneByOne) {
|
||||||
QCoreApplication::sendPostedEvents();
|
QCoreApplication::sendPostedEvents();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return vfiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMainWindow::editOrphanFileInfo(VFile *p_file)
|
void VMainWindow::editOrphanFileInfo(VFile *p_file)
|
||||||
@ -2497,7 +2517,7 @@ void VMainWindow::checkSharedMemory()
|
|||||||
QStringList files = m_guard->fetchFilesToOpen();
|
QStringList files = m_guard->fetchFilesToOpen();
|
||||||
if (!files.isEmpty()) {
|
if (!files.isEmpty()) {
|
||||||
qDebug() << "shared memory fetch files" << files;
|
qDebug() << "shared memory fetch files" << files;
|
||||||
openFiles(files);
|
openFiles(files, false, g_config->getNoteOpenMode(), false, false);
|
||||||
|
|
||||||
// Eliminate the signal.
|
// Eliminate the signal.
|
||||||
m_guard->fetchAskedToShow();
|
m_guard->fetchAskedToShow();
|
||||||
@ -2579,7 +2599,7 @@ void VMainWindow::openStartupPages()
|
|||||||
{
|
{
|
||||||
QStringList pagesToOpen = VUtils::filterFilePathsToOpen(g_config->getStartupPages());
|
QStringList pagesToOpen = VUtils::filterFilePathsToOpen(g_config->getStartupPages());
|
||||||
qDebug() << "open startup pages" << pagesToOpen;
|
qDebug() << "open startup pages" << pagesToOpen;
|
||||||
openFiles(pagesToOpen, false, OpenFileMode::Read, false, true);
|
openFiles(pagesToOpen, false, g_config->getNoteOpenMode(), false, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3149,7 +3169,7 @@ void VMainWindow::kickOffStartUpTimer(const QStringList &p_files)
|
|||||||
promptNewNotebookIfEmpty();
|
promptNewNotebookIfEmpty();
|
||||||
QCoreApplication::sendPostedEvents();
|
QCoreApplication::sendPostedEvents();
|
||||||
openStartupPages();
|
openStartupPages();
|
||||||
openFiles(p_files, false, OpenFileMode::Read, false, true);
|
openFiles(p_files, false, g_config->getNoteOpenMode(), false, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ class VSearcher;
|
|||||||
class QPrinter;
|
class QPrinter;
|
||||||
class VUniversalEntry;
|
class VUniversalEntry;
|
||||||
class VHistoryList;
|
class VHistoryList;
|
||||||
|
class VExplorer;
|
||||||
|
|
||||||
enum class PanelViewState
|
enum class PanelViewState
|
||||||
{
|
{
|
||||||
@ -88,11 +89,11 @@ public:
|
|||||||
// Open files @p_files as orphan files or internal note files.
|
// Open files @p_files as orphan files or internal note files.
|
||||||
// If @p_forceOrphan is false, for each file, VNote will try to find out if
|
// If @p_forceOrphan is false, for each file, VNote will try to find out if
|
||||||
// it is a note inside VNote. If yes, VNote will open it as internal file.
|
// it is a note inside VNote. If yes, VNote will open it as internal file.
|
||||||
void openFiles(const QStringList &p_files,
|
QVector<VFile *> openFiles(const QStringList &p_files,
|
||||||
bool p_forceOrphan = false,
|
bool p_forceOrphan = false,
|
||||||
OpenFileMode p_mode = OpenFileMode::Read,
|
OpenFileMode p_mode = OpenFileMode::Read,
|
||||||
bool p_forceMode = false,
|
bool p_forceMode = false,
|
||||||
bool p_oneByOne = false);
|
bool p_oneByOne = false);
|
||||||
|
|
||||||
// Try to open @p_filePath as internal note.
|
// Try to open @p_filePath as internal note.
|
||||||
bool tryOpenInternalFile(const QString &p_filePath);
|
bool tryOpenInternalFile(const QString &p_filePath);
|
||||||
@ -449,6 +450,8 @@ private:
|
|||||||
|
|
||||||
VHistoryList *m_historyList;
|
VHistoryList *m_historyList;
|
||||||
|
|
||||||
|
VExplorer *m_explorer;
|
||||||
|
|
||||||
// Interval of the shared memory timer in ms.
|
// Interval of the shared memory timer in ms.
|
||||||
static const int c_sharedMemTimerInterval;
|
static const int c_sharedMemTimerInterval;
|
||||||
};
|
};
|
||||||
|
@ -218,5 +218,10 @@
|
|||||||
<file>resources/icons/clear_history.svg</file>
|
<file>resources/icons/clear_history.svg</file>
|
||||||
<file>resources/icons/pin.svg</file>
|
<file>resources/icons/pin.svg</file>
|
||||||
<file>resources/icons/view.svg</file>
|
<file>resources/icons/view.svg</file>
|
||||||
|
<file>resources/icons/explorer.svg</file>
|
||||||
|
<file>resources/icons/star.svg</file>
|
||||||
|
<file>resources/icons/open_location.svg</file>
|
||||||
|
<file>resources/icons/unstar.svg</file>
|
||||||
|
<file>resources/icons/explore_root.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@ -50,112 +50,10 @@ VNotebookSelector::VNotebookSelector(QWidget *p_parent)
|
|||||||
m_listWidget->viewport()->installEventFilter(this);
|
m_listWidget->viewport()->installEventFilter(this);
|
||||||
m_listWidget->installEventFilter(this);
|
m_listWidget->installEventFilter(this);
|
||||||
|
|
||||||
initActions();
|
|
||||||
|
|
||||||
connect(this, SIGNAL(currentIndexChanged(int)),
|
connect(this, SIGNAL(currentIndexChanged(int)),
|
||||||
this, SLOT(handleCurIndexChanged(int)));
|
this, SLOT(handleCurIndexChanged(int)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VNotebookSelector::initActions()
|
|
||||||
{
|
|
||||||
m_deleteNotebookAct = new QAction(VIconUtils::menuDangerIcon(":/resources/icons/delete_notebook.svg"),
|
|
||||||
tr("&Delete"), this);
|
|
||||||
m_deleteNotebookAct->setToolTip(tr("Delete current notebook"));
|
|
||||||
connect(m_deleteNotebookAct, SIGNAL(triggered(bool)),
|
|
||||||
this, SLOT(deleteNotebook()));
|
|
||||||
|
|
||||||
m_notebookInfoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/notebook_info.svg"),
|
|
||||||
tr("&Info"), this);
|
|
||||||
m_notebookInfoAct->setToolTip(tr("View and edit current notebook's information"));
|
|
||||||
connect(m_notebookInfoAct, SIGNAL(triggered(bool)),
|
|
||||||
this, SLOT(editNotebookInfo()));
|
|
||||||
|
|
||||||
m_openLocationAct = new QAction(tr("&Open Notebook Location"), this);
|
|
||||||
m_openLocationAct->setToolTip(tr("Open the root folder of this notebook in operating system"));
|
|
||||||
connect(m_openLocationAct, &QAction::triggered,
|
|
||||||
this, [this]() {
|
|
||||||
QList<QListWidgetItem *> items = this->m_listWidget->selectedItems();
|
|
||||||
if (items.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_ASSERT(items.size() == 1);
|
|
||||||
VNotebook *notebook = getNotebook(items[0]);
|
|
||||||
QUrl url = QUrl::fromLocalFile(notebook->getPath());
|
|
||||||
QDesktopServices::openUrl(url);
|
|
||||||
});
|
|
||||||
|
|
||||||
m_recycleBinAct = new QAction(VIconUtils::menuIcon(":/resources/icons/recycle_bin.svg"),
|
|
||||||
tr("&Recycle Bin"), this);
|
|
||||||
m_recycleBinAct->setToolTip(tr("Open the recycle bin of this notebook"));
|
|
||||||
connect(m_recycleBinAct, &QAction::triggered,
|
|
||||||
this, [this]() {
|
|
||||||
QList<QListWidgetItem *> items = this->m_listWidget->selectedItems();
|
|
||||||
if (items.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_ASSERT(items.size() == 1);
|
|
||||||
VNotebook *notebook = getNotebook(items[0]);
|
|
||||||
QUrl url = QUrl::fromLocalFile(notebook->getRecycleBinFolderPath());
|
|
||||||
QDesktopServices::openUrl(url);
|
|
||||||
});
|
|
||||||
|
|
||||||
m_emptyRecycleBinAct = new QAction(VIconUtils::menuDangerIcon(":/resources/icons/empty_recycle_bin.svg"),
|
|
||||||
tr("&Empty Recycle Bin"), this);
|
|
||||||
m_emptyRecycleBinAct->setToolTip(tr("Empty the recycle bin of this notebook"));
|
|
||||||
connect(m_emptyRecycleBinAct, &QAction::triggered,
|
|
||||||
this, [this]() {
|
|
||||||
QList<QListWidgetItem *> items = this->m_listWidget->selectedItems();
|
|
||||||
if (items.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_ASSERT(items.size() == 1);
|
|
||||||
VNotebook *notebook = getNotebook(items[0]);
|
|
||||||
QString binPath = notebook->getRecycleBinFolderPath();
|
|
||||||
|
|
||||||
int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
|
|
||||||
tr("Are you sure to empty recycle bin of notebook "
|
|
||||||
"<span style=\"%1\">%2</span>?")
|
|
||||||
.arg(g_config->c_dataTextStyle)
|
|
||||||
.arg(notebook->getName()),
|
|
||||||
tr("<span style=\"%1\">WARNING</span>: "
|
|
||||||
"VNote will delete all the files in directory "
|
|
||||||
"<span style=\"%2\">%3</span>."
|
|
||||||
"<br>It may be UNRECOVERABLE!")
|
|
||||||
.arg(g_config->c_warningTextStyle)
|
|
||||||
.arg(g_config->c_dataTextStyle)
|
|
||||||
.arg(binPath),
|
|
||||||
QMessageBox::Ok | QMessageBox::Cancel,
|
|
||||||
QMessageBox::Ok,
|
|
||||||
this,
|
|
||||||
MessageBoxType::Danger);
|
|
||||||
if (ret == QMessageBox::Ok) {
|
|
||||||
QString info;
|
|
||||||
if (VUtils::emptyDirectory(notebook, binPath, true)) {
|
|
||||||
info = tr("Successfully emptied recycle bin of notebook "
|
|
||||||
"<span style=\"%1\">%2</span>!")
|
|
||||||
.arg(g_config->c_dataTextStyle)
|
|
||||||
.arg(notebook->getName());
|
|
||||||
} else {
|
|
||||||
info = tr("Fail to empty recycle bin of notebook "
|
|
||||||
"<span style=\"%1\">%2</span>!")
|
|
||||||
.arg(g_config->c_dataTextStyle)
|
|
||||||
.arg(notebook->getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
VUtils::showMessage(QMessageBox::Information,
|
|
||||||
tr("Information"),
|
|
||||||
info,
|
|
||||||
"",
|
|
||||||
QMessageBox::Ok,
|
|
||||||
QMessageBox::Ok,
|
|
||||||
this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void VNotebookSelector::updateComboBox()
|
void VNotebookSelector::updateComboBox()
|
||||||
{
|
{
|
||||||
m_muted = true;
|
m_muted = true;
|
||||||
@ -479,18 +377,122 @@ void VNotebookSelector::popupListContextMenuRequested(QPoint p_pos)
|
|||||||
|
|
||||||
QMenu menu(this);
|
QMenu menu(this);
|
||||||
menu.setToolTipsVisible(true);
|
menu.setToolTipsVisible(true);
|
||||||
menu.addAction(m_deleteNotebookAct);
|
|
||||||
|
QAction *deleteNotebookAct = new QAction(VIconUtils::menuDangerIcon(":/resources/icons/delete_notebook.svg"),
|
||||||
|
tr("&Delete"),
|
||||||
|
&menu);
|
||||||
|
deleteNotebookAct->setToolTip(tr("Delete current notebook"));
|
||||||
|
connect(deleteNotebookAct, SIGNAL(triggered(bool)),
|
||||||
|
this, SLOT(deleteNotebook()));
|
||||||
|
menu.addAction(deleteNotebookAct);
|
||||||
|
|
||||||
if (nb->isValid()) {
|
if (nb->isValid()) {
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
menu.addAction(m_recycleBinAct);
|
|
||||||
menu.addAction(m_emptyRecycleBinAct);
|
QAction *recycleBinAct = new QAction(VIconUtils::menuIcon(":/resources/icons/recycle_bin.svg"),
|
||||||
|
tr("&Recycle Bin"),
|
||||||
|
&menu);
|
||||||
|
recycleBinAct->setToolTip(tr("Open the recycle bin of this notebook"));
|
||||||
|
connect(recycleBinAct, &QAction::triggered,
|
||||||
|
this, [this]() {
|
||||||
|
QList<QListWidgetItem *> items = this->m_listWidget->selectedItems();
|
||||||
|
if (items.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(items.size() == 1);
|
||||||
|
VNotebook *notebook = getNotebook(items[0]);
|
||||||
|
QUrl url = QUrl::fromLocalFile(notebook->getRecycleBinFolderPath());
|
||||||
|
QDesktopServices::openUrl(url);
|
||||||
|
});
|
||||||
|
|
||||||
|
menu.addAction(recycleBinAct);
|
||||||
|
|
||||||
|
QAction *emptyRecycleBinAct = new QAction(VIconUtils::menuDangerIcon(":/resources/icons/empty_recycle_bin.svg"),
|
||||||
|
tr("&Empty Recycle Bin"),
|
||||||
|
&menu);
|
||||||
|
emptyRecycleBinAct->setToolTip(tr("Empty the recycle bin of this notebook"));
|
||||||
|
connect(emptyRecycleBinAct, &QAction::triggered,
|
||||||
|
this, [this]() {
|
||||||
|
QList<QListWidgetItem *> items = this->m_listWidget->selectedItems();
|
||||||
|
if (items.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(items.size() == 1);
|
||||||
|
VNotebook *notebook = getNotebook(items[0]);
|
||||||
|
QString binPath = notebook->getRecycleBinFolderPath();
|
||||||
|
|
||||||
|
int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
|
||||||
|
tr("Are you sure to empty recycle bin of notebook "
|
||||||
|
"<span style=\"%1\">%2</span>?")
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(notebook->getName()),
|
||||||
|
tr("<span style=\"%1\">WARNING</span>: "
|
||||||
|
"VNote will delete all the files in directory "
|
||||||
|
"<span style=\"%2\">%3</span>."
|
||||||
|
"<br>It may be UNRECOVERABLE!")
|
||||||
|
.arg(g_config->c_warningTextStyle)
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(binPath),
|
||||||
|
QMessageBox::Ok | QMessageBox::Cancel,
|
||||||
|
QMessageBox::Ok,
|
||||||
|
this,
|
||||||
|
MessageBoxType::Danger);
|
||||||
|
if (ret == QMessageBox::Ok) {
|
||||||
|
QString info;
|
||||||
|
if (VUtils::emptyDirectory(notebook, binPath, true)) {
|
||||||
|
info = tr("Successfully emptied recycle bin of notebook "
|
||||||
|
"<span style=\"%1\">%2</span>!")
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(notebook->getName());
|
||||||
|
} else {
|
||||||
|
info = tr("Fail to empty recycle bin of notebook "
|
||||||
|
"<span style=\"%1\">%2</span>!")
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(notebook->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
VUtils::showMessage(QMessageBox::Information,
|
||||||
|
tr("Information"),
|
||||||
|
info,
|
||||||
|
"",
|
||||||
|
QMessageBox::Ok,
|
||||||
|
QMessageBox::Ok,
|
||||||
|
this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.addAction(emptyRecycleBinAct);
|
||||||
}
|
}
|
||||||
|
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
menu.addAction(m_openLocationAct);
|
|
||||||
|
QAction *openLocationAct = new QAction(VIconUtils::menuIcon(":/resources/icons/open_location.svg"),
|
||||||
|
tr("&Open Notebook Location"),
|
||||||
|
&menu);
|
||||||
|
openLocationAct->setToolTip(tr("Explore the root folder of this notebook in operating system"));
|
||||||
|
connect(openLocationAct, &QAction::triggered,
|
||||||
|
this, [this]() {
|
||||||
|
QList<QListWidgetItem *> items = this->m_listWidget->selectedItems();
|
||||||
|
if (items.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(items.size() == 1);
|
||||||
|
VNotebook *notebook = getNotebook(items[0]);
|
||||||
|
QUrl url = QUrl::fromLocalFile(notebook->getPath());
|
||||||
|
QDesktopServices::openUrl(url);
|
||||||
|
});
|
||||||
|
menu.addAction(openLocationAct);
|
||||||
|
|
||||||
if (nb->isValid()) {
|
if (nb->isValid()) {
|
||||||
menu.addAction(m_notebookInfoAct);
|
QAction *notebookInfoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/notebook_info.svg"),
|
||||||
|
tr("&Info"),
|
||||||
|
&menu);
|
||||||
|
notebookInfoAct->setToolTip(tr("View and edit current notebook's information"));
|
||||||
|
connect(notebookInfoAct, SIGNAL(triggered(bool)),
|
||||||
|
this, SLOT(editNotebookInfo()));
|
||||||
|
menu.addAction(notebookInfoAct);
|
||||||
}
|
}
|
||||||
|
|
||||||
menu.exec(m_listWidget->mapToGlobal(p_pos));
|
menu.exec(m_listWidget->mapToGlobal(p_pos));
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
class VNotebook;
|
class VNotebook;
|
||||||
class QListWidget;
|
class QListWidget;
|
||||||
class QAction;
|
|
||||||
class QListWidgetItem;
|
class QListWidgetItem;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
|
|
||||||
@ -66,8 +65,6 @@ private slots:
|
|||||||
void editNotebookInfo();
|
void editNotebookInfo();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initActions();
|
|
||||||
|
|
||||||
// Update Combox from m_notebooks.
|
// Update Combox from m_notebooks.
|
||||||
void updateComboBox();
|
void updateComboBox();
|
||||||
|
|
||||||
@ -115,13 +112,6 @@ private:
|
|||||||
// Whether it is muted from currentIndexChanged().
|
// Whether it is muted from currentIndexChanged().
|
||||||
bool m_muted;
|
bool m_muted;
|
||||||
|
|
||||||
// Actions
|
|
||||||
QAction *m_deleteNotebookAct;
|
|
||||||
QAction *m_notebookInfoAct;
|
|
||||||
QAction *m_openLocationAct;
|
|
||||||
QAction *m_recycleBinAct;
|
|
||||||
QAction *m_emptyRecycleBinAct;
|
|
||||||
|
|
||||||
QLabel *m_naviLabel;
|
QLabel *m_naviLabel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,36 +25,23 @@ extern VConfigManager *g_config;
|
|||||||
|
|
||||||
VSearcher::VSearcher(QWidget *p_parent)
|
VSearcher::VSearcher(QWidget *p_parent)
|
||||||
: QWidget(p_parent),
|
: QWidget(p_parent),
|
||||||
|
m_initialized(false),
|
||||||
|
m_uiInitialized(false),
|
||||||
m_inSearch(false),
|
m_inSearch(false),
|
||||||
m_askedToStop(false),
|
m_askedToStop(false),
|
||||||
m_search(this)
|
m_search(this)
|
||||||
{
|
{
|
||||||
qRegisterMetaType<QList<QSharedPointer<VSearchResultItem>>>("QList<QSharedPointer<VSearchResultItem>>");
|
qRegisterMetaType<QList<QSharedPointer<VSearchResultItem>>>("QList<QSharedPointer<VSearchResultItem>>");
|
||||||
|
|
||||||
setupUI();
|
|
||||||
|
|
||||||
initUIFields();
|
|
||||||
|
|
||||||
handleInputChanged();
|
|
||||||
|
|
||||||
connect(&m_search, &VSearch::resultItemAdded,
|
|
||||||
this, [this](const QSharedPointer<VSearchResultItem> &p_item) {
|
|
||||||
// Not sure if it works.
|
|
||||||
QCoreApplication::sendPostedEvents(NULL, QEvent::MouseButtonRelease);
|
|
||||||
m_results->addResultItem(p_item);
|
|
||||||
});
|
|
||||||
connect(&m_search, &VSearch::resultItemsAdded,
|
|
||||||
this, [this](const QList<QSharedPointer<VSearchResultItem> > &p_items) {
|
|
||||||
// Not sure if it works.
|
|
||||||
QCoreApplication::sendPostedEvents(NULL, QEvent::MouseButtonRelease);
|
|
||||||
m_results->addResultItems(p_items);
|
|
||||||
});
|
|
||||||
connect(&m_search, &VSearch::finished,
|
|
||||||
this, &VSearcher::handleSearchFinished);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VSearcher::setupUI()
|
void VSearcher::setupUI()
|
||||||
{
|
{
|
||||||
|
if (m_uiInitialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_uiInitialized = true;
|
||||||
|
|
||||||
// Search button.
|
// Search button.
|
||||||
m_searchBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/search.svg"), "", this);
|
m_searchBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/search.svg"), "", this);
|
||||||
m_searchBtn->setToolTip(tr("Search"));
|
m_searchBtn->setToolTip(tr("Search"));
|
||||||
@ -112,6 +99,7 @@ void VSearcher::setupUI()
|
|||||||
m_keywordCB->setLineEdit(new VLineEdit(this));
|
m_keywordCB->setLineEdit(new VLineEdit(this));
|
||||||
m_keywordCB->setToolTip(tr("Keywords to search for"));
|
m_keywordCB->setToolTip(tr("Keywords to search for"));
|
||||||
m_keywordCB->lineEdit()->setPlaceholderText(tr("Supports space, &&, and ||"));
|
m_keywordCB->lineEdit()->setPlaceholderText(tr("Supports space, &&, and ||"));
|
||||||
|
m_keywordCB->lineEdit()->setProperty("EmbeddedEdit", true);
|
||||||
connect(m_keywordCB, &QComboBox::currentTextChanged,
|
connect(m_keywordCB, &QComboBox::currentTextChanged,
|
||||||
this, &VSearcher::handleInputChanged);
|
this, &VSearcher::handleInputChanged);
|
||||||
connect(m_keywordCB->lineEdit(), &QLineEdit::returnPressed,
|
connect(m_keywordCB->lineEdit(), &QLineEdit::returnPressed,
|
||||||
@ -141,6 +129,7 @@ void VSearcher::setupUI()
|
|||||||
m_filePatternCB->setEditable(true);
|
m_filePatternCB->setEditable(true);
|
||||||
m_filePatternCB->setLineEdit(new VLineEdit(this));
|
m_filePatternCB->setLineEdit(new VLineEdit(this));
|
||||||
m_filePatternCB->setToolTip(tr("Wildcard pattern to filter the files to be searched"));
|
m_filePatternCB->setToolTip(tr("Wildcard pattern to filter the files to be searched"));
|
||||||
|
m_filePatternCB->lineEdit()->setProperty("EmbeddedEdit", true);
|
||||||
m_filePatternCB->completer()->setCaseSensitivity(Qt::CaseSensitive);
|
m_filePatternCB->completer()->setCaseSensitivity(Qt::CaseSensitive);
|
||||||
|
|
||||||
// Engine.
|
// Engine.
|
||||||
@ -544,19 +533,62 @@ void VSearcher::updateNumLabel(int p_count)
|
|||||||
|
|
||||||
void VSearcher::focusToSearch()
|
void VSearcher::focusToSearch()
|
||||||
{
|
{
|
||||||
|
init();
|
||||||
|
|
||||||
m_keywordCB->setFocus(Qt::OtherFocusReason);
|
m_keywordCB->setFocus(Qt::OtherFocusReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VSearcher::showNavigation()
|
void VSearcher::showNavigation()
|
||||||
{
|
{
|
||||||
|
setupUI();
|
||||||
|
|
||||||
VNavigationMode::showNavigation(m_results);
|
VNavigationMode::showNavigation(m_results);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VSearcher::handleKeyNavigation(int p_key, bool &p_succeed)
|
bool VSearcher::handleKeyNavigation(int p_key, bool &p_succeed)
|
||||||
{
|
{
|
||||||
static bool secondKey = false;
|
static bool secondKey = false;
|
||||||
|
setupUI();
|
||||||
|
|
||||||
return VNavigationMode::handleKeyNavigation(m_results,
|
return VNavigationMode::handleKeyNavigation(m_results,
|
||||||
secondKey,
|
secondKey,
|
||||||
p_key,
|
p_key,
|
||||||
p_succeed);
|
p_succeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VSearcher::init()
|
||||||
|
{
|
||||||
|
if (m_initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_initialized = true;
|
||||||
|
|
||||||
|
setupUI();
|
||||||
|
|
||||||
|
initUIFields();
|
||||||
|
|
||||||
|
handleInputChanged();
|
||||||
|
|
||||||
|
connect(&m_search, &VSearch::resultItemAdded,
|
||||||
|
this, [this](const QSharedPointer<VSearchResultItem> &p_item) {
|
||||||
|
// Not sure if it works.
|
||||||
|
QCoreApplication::sendPostedEvents(NULL, QEvent::MouseButtonRelease);
|
||||||
|
m_results->addResultItem(p_item);
|
||||||
|
});
|
||||||
|
connect(&m_search, &VSearch::resultItemsAdded,
|
||||||
|
this, [this](const QList<QSharedPointer<VSearchResultItem> > &p_items) {
|
||||||
|
// Not sure if it works.
|
||||||
|
QCoreApplication::sendPostedEvents(NULL, QEvent::MouseButtonRelease);
|
||||||
|
m_results->addResultItems(p_items);
|
||||||
|
});
|
||||||
|
connect(&m_search, &VSearch::finished,
|
||||||
|
this, &VSearcher::handleSearchFinished);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VSearcher::showEvent(QShowEvent *p_event)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
|
||||||
|
QWidget::showEvent(p_event);
|
||||||
|
}
|
||||||
|
@ -15,6 +15,7 @@ class QLabel;
|
|||||||
class VSearchResultTree;
|
class VSearchResultTree;
|
||||||
class QProgressBar;
|
class QProgressBar;
|
||||||
class QPlainTextEdit;
|
class QPlainTextEdit;
|
||||||
|
class QShowEvent;
|
||||||
|
|
||||||
class VSearcher : public QWidget, public VNavigationMode
|
class VSearcher : public QWidget, public VNavigationMode
|
||||||
{
|
{
|
||||||
@ -28,6 +29,9 @@ public:
|
|||||||
void showNavigation() Q_DECL_OVERRIDE;
|
void showNavigation() Q_DECL_OVERRIDE;
|
||||||
bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE;
|
bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleSearchFinished(const QSharedPointer<VSearchResult> &p_result);
|
void handleSearchFinished(const QSharedPointer<VSearchResult> &p_result);
|
||||||
|
|
||||||
@ -36,6 +40,8 @@ private:
|
|||||||
|
|
||||||
void setupUI();
|
void setupUI();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
void initUIFields();
|
void initUIFields();
|
||||||
|
|
||||||
void setProgressVisible(bool p_visible);
|
void setProgressVisible(bool p_visible);
|
||||||
@ -98,6 +104,10 @@ private:
|
|||||||
|
|
||||||
QPlainTextEdit *m_consoleEdit;
|
QPlainTextEdit *m_consoleEdit;
|
||||||
|
|
||||||
|
bool m_initialized;
|
||||||
|
|
||||||
|
bool m_uiInitialized;
|
||||||
|
|
||||||
bool m_inSearch;
|
bool m_inSearch;
|
||||||
|
|
||||||
bool m_askedToStop;
|
bool m_askedToStop;
|
||||||
|
@ -86,7 +86,11 @@ int VToolBox::addItem(QWidget *p_widget,
|
|||||||
void VToolBox::setCurrentIndex(int p_idx, bool p_focus)
|
void VToolBox::setCurrentIndex(int p_idx, bool p_focus)
|
||||||
{
|
{
|
||||||
if (p_idx < 0 || p_idx >= m_items.size()) {
|
if (p_idx < 0 || p_idx >= m_items.size()) {
|
||||||
m_currentIndex = -1;
|
if (m_items.isEmpty()) {
|
||||||
|
m_currentIndex = -1;
|
||||||
|
} else {
|
||||||
|
m_currentIndex = 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
m_currentIndex = p_idx;
|
m_currentIndex = p_idx;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,8 @@ public:
|
|||||||
|
|
||||||
void setCurrentWidget(QWidget *p_widget, bool p_focus = true);
|
void setCurrentWidget(QWidget *p_widget, bool p_focus = true);
|
||||||
|
|
||||||
|
int currentIndex() const;
|
||||||
|
|
||||||
// Implementations for VNavigationMode.
|
// Implementations for VNavigationMode.
|
||||||
void showNavigation() Q_DECL_OVERRIDE;
|
void showNavigation() Q_DECL_OVERRIDE;
|
||||||
bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE;
|
bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE;
|
||||||
@ -78,4 +80,9 @@ private:
|
|||||||
QVector<ItemInfo> m_items;
|
QVector<ItemInfo> m_items;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline int VToolBox::currentIndex() const
|
||||||
|
{
|
||||||
|
return m_currentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // VTOOLBOX_H
|
#endif // VTOOLBOX_H
|
||||||
|
@ -53,6 +53,12 @@ VTreeWidget::VTreeWidget(QWidget *p_parent)
|
|||||||
resizeColumnToContents(0);
|
resizeColumnToContents(0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
connect(this, &VTreeWidget::itemCollapsed,
|
||||||
|
this, [this]() {
|
||||||
|
if (m_fitContent) {
|
||||||
|
resizeColumnToContents(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void VTreeWidget::keyPressEvent(QKeyEvent *p_event)
|
void VTreeWidget::keyPressEvent(QKeyEvent *p_event)
|
||||||
|