diff --git a/src/src.pro b/src/src.pro index db15b44e..1b54ac8a 100644 --- a/src/src.pro +++ b/src/src.pro @@ -68,7 +68,8 @@ SOURCES += main.cpp\ utils/vvim.cpp \ utils/veditutils.cpp \ vvimindicator.cpp \ - vbuttonwithwidget.cpp + vbuttonwithwidget.cpp \ + vtabindicator.cpp HEADERS += vmainwindow.h \ vdirectorytree.h \ @@ -123,7 +124,9 @@ HEADERS += vmainwindow.h \ utils/vvim.h \ utils/veditutils.h \ vvimindicator.h \ - vbuttonwithwidget.h + vbuttonwithwidget.h \ + vedittabinfo.h \ + vtabindicator.h RESOURCES += \ vnote.qrc \ diff --git a/src/veditarea.cpp b/src/veditarea.cpp index ec4518b5..98754eb2 100644 --- a/src/veditarea.cpp +++ b/src/veditarea.cpp @@ -67,8 +67,8 @@ void VEditArea::insertSplitWindow(int idx) { VEditWindow *win = new VEditWindow(vnote, this); splitter->insertWidget(idx, win); - connect(win, &VEditWindow::tabStatusChanged, - this, &VEditArea::handleEditWindowStatusChanged); + connect(win, &VEditWindow::tabStatusUpdated, + this, &VEditArea::handleWindowTabStatusUpdated); connect(win, &VEditWindow::requestSplitWindow, this, &VEditArea::handleSplitWindowRequest); connect(win, &VEditWindow::requestRemoveSplit, @@ -85,12 +85,10 @@ void VEditArea::insertSplitWindow(int idx) this, &VEditArea::handleWindowVimStatusUpdated); } -void VEditArea::handleEditWindowStatusChanged(const VFile *p_file, - const VEditTab *p_editTab, - bool p_editMode) +void VEditArea::handleWindowTabStatusUpdated(const VEditTabInfo &p_info) { if (splitter->widget(curWindowIndex) == sender()) { - emit curTabStatusChanged(p_file, p_editTab, p_editMode); + emit tabStatusUpdated(p_info); } } @@ -216,14 +214,15 @@ void VEditArea::updateWindowStatus() { if (curWindowIndex == -1) { Q_ASSERT(splitter->count() == 0); - emit curTabStatusChanged(NULL, NULL, false); + + emit tabStatusUpdated(VEditTabInfo()); emit outlineChanged(VToc()); emit curHeaderChanged(VAnchor()); return; } VEditWindow *win = getWindow(curWindowIndex); - win->requestUpdateTabStatus(); + win->updateTabStatus(); win->requestUpdateOutline(); win->requestUpdateCurHeader(); } diff --git a/src/veditarea.h b/src/veditarea.h index 4a94f581..d58e57f7 100644 --- a/src/veditarea.h +++ b/src/veditarea.h @@ -60,7 +60,9 @@ public: bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; signals: - void curTabStatusChanged(const VFile *p_file, const VEditTab *p_editTab, bool p_editMode); + // Emit when current window's tab status updated. + void tabStatusUpdated(const VEditTabInfo &p_info); + void outlineChanged(const VToc &toc); void curHeaderChanged(const VAnchor &anchor); @@ -98,9 +100,9 @@ private slots: void handleReplaceAll(const QString &p_text, uint p_options, const QString &p_replaceText); void handleFindDialogClosed(); - void handleEditWindowStatusChanged(const VFile *p_file, - const VEditTab *p_editTab, - bool p_editMode); + + // Hanle the status update of current tab within a VEditWindow. + void handleWindowTabStatusUpdated(const VEditTabInfo &p_info); // Handle the statusMessage signal of VEditWindow. void handleWindowStatusMessage(const QString &p_msg); @@ -117,6 +119,8 @@ private: inline VEditWindow *getWindow(int windowIndex) const; void insertSplitWindow(int idx); void removeSplitWindow(VEditWindow *win); + + // Update status of current window. void updateWindowStatus(); VNote *vnote; diff --git a/src/vedittab.cpp b/src/vedittab.cpp index b34396d6..0f34297c 100644 --- a/src/vedittab.cpp +++ b/src/vedittab.cpp @@ -77,3 +77,18 @@ void VEditTab::wheelEvent(QWheelEvent *p_event) p_event->ignore(); } + +void VEditTab::updateStatus() +{ + m_modified = m_file->isModified(); + + emit statusUpdated(createEditTabInfo()); +} + +VEditTabInfo VEditTab::createEditTabInfo() +{ + VEditTabInfo info; + info.m_editTab = this; + + return info; +} diff --git a/src/vedittab.h b/src/vedittab.h index 98af3a1e..73d66021 100644 --- a/src/vedittab.h +++ b/src/vedittab.h @@ -7,6 +7,7 @@ #include "vtoc.h" #include "vfile.h" #include "utils/vvim.h" +#include "vedittabinfo.h" class VEditArea; @@ -71,6 +72,9 @@ public slots: // Enter edit mode virtual void editFile() = 0; + // Update status of current tab. Emit statusUpdated(). + virtual void updateStatus(); + protected: void wheelEvent(QWheelEvent *p_event) Q_DECL_OVERRIDE; @@ -80,6 +84,9 @@ protected: // Called to zoom in/out content. virtual void zoom(bool p_zoomIn, qreal p_step = 0.25) = 0; + // Create a filled VEditTabInfo. + virtual VEditTabInfo createEditTabInfo(); + // File related to this tab. QPointer m_file; bool m_isEditMode; @@ -95,7 +102,8 @@ signals: void curHeaderChanged(const VAnchor &p_anchor); - void statusChanged(); + // The status of current tab has updates. + void statusUpdated(const VEditTabInfo &p_info); // Emit when want to show message in status bar. void statusMessage(const QString &p_msg); diff --git a/src/vedittabinfo.h b/src/vedittabinfo.h new file mode 100644 index 00000000..5fc4003b --- /dev/null +++ b/src/vedittabinfo.h @@ -0,0 +1,20 @@ +#ifndef VEDITTABINFO_H +#define VEDITTABINFO_H + +class VEditTab; + +struct VEditTabInfo +{ + VEditTabInfo() + : m_editTab(NULL), m_cursorBlockNumber(-1), m_cursorPositionInBlock(-1), + m_blockCount(-1) {} + + VEditTab *m_editTab; + + // Cursor information. -1 for invalid info. + int m_cursorBlockNumber; + int m_cursorPositionInBlock; + int m_blockCount; +}; + +#endif // VEDITTABINFO_H diff --git a/src/veditwindow.cpp b/src/veditwindow.cpp index cad6a545..86c4ef10 100644 --- a/src/veditwindow.cpp +++ b/src/veditwindow.cpp @@ -166,7 +166,7 @@ bool VEditWindow::closeFile(const VFile *p_file, bool p_forced) Q_ASSERT(editor); if (!p_forced) { setCurrentIndex(idx); - noticeStatus(idx); + updateTabStatus(idx); } // Even p_forced is true we need to delete unused images. bool ok = editor->closeFile(p_forced); @@ -226,7 +226,7 @@ bool VEditWindow::closeAllFiles(bool p_forced) if (!p_forced) { setCurrentIndex(0); - noticeStatus(0); + updateTabStatus(0); } // Even p_forced is true we need to delete unused images. bool ok = editor->closeFile(p_forced); @@ -266,8 +266,8 @@ int VEditWindow::openFileInTab(VFile *p_file, OpenFileMode p_mode) this, &VEditWindow::handleOutlineChanged); connect(editor, &VEditTab::curHeaderChanged, this, &VEditWindow::handleCurHeaderChanged); - connect(editor, &VEditTab::statusChanged, - this, &VEditWindow::handleTabStatusChanged); + connect(editor, &VEditTab::statusUpdated, + this, &VEditWindow::handleTabStatusUpdated); connect(editor, &VEditTab::statusMessage, this, &VEditWindow::handleTabStatusMessage); connect(editor, &VEditTab::vimStatusUpdated, @@ -333,20 +333,23 @@ void VEditWindow::saveFile() editor->saveFile(); } -void VEditWindow::noticeTabStatus(int p_index) +void VEditWindow::updateTabStatus(int p_index) { if (p_index == -1) { - emit tabStatusChanged(NULL, NULL, false); + p_index = currentIndex(); + } + + if (p_index == -1) { + emit tabStatusUpdated(VEditTabInfo()); + emit outlineChanged(VToc()); + emit curHeaderChanged(VAnchor()); return; } - updateTabInfo(p_index); - updateAllTabsSequence(); - - VEditTab *editor = getTab(p_index); - const VFile *file = editor->getFile(); - bool editMode = editor->isEditMode(); - emit tabStatusChanged(file, editor, editMode); + VEditTab *tab = getTab(p_index); + tab->updateStatus(); + tab->requestUpdateOutline(); + tab->requestUpdateCurHeader(); } void VEditWindow::updateTabInfo(int p_index) @@ -372,12 +375,6 @@ void VEditWindow::updateAllTabsSequence() } } -// Be requested to report current status -void VEditWindow::requestUpdateTabStatus() -{ - noticeTabStatus(currentIndex()); -} - // Be requested to report current outline void VEditWindow::requestUpdateOutline() { @@ -492,7 +489,7 @@ void VEditWindow::tabListJump(VFile *p_file) int idx = findTabByFile(p_file); Q_ASSERT(idx >= 0); setCurrentIndex(idx); - noticeStatus(idx); + updateTabStatus(idx); } void VEditWindow::updateSplitMenu() @@ -552,31 +549,16 @@ void VEditWindow::scrollCurTab(const VAnchor &p_anchor) } } -// Update tab status, outline and current header. -void VEditWindow::noticeStatus(int index) -{ - qDebug() << "tab" << index; - noticeTabStatus(index); - - if (index == -1) { - emit outlineChanged(VToc()); - emit curHeaderChanged(VAnchor()); - } else { - VEditTab *tab = getTab(index); - tab->requestUpdateOutline(); - tab->requestUpdateCurHeader(); - } -} - -void VEditWindow::handleTabStatusChanged() +void VEditWindow::handleTabStatusUpdated(const VEditTabInfo &p_info) { int idx = indexOf(dynamic_cast(sender())); + + updateTabInfo(idx); + updateAllTabsSequence(); + if (idx == currentIndex()) { - noticeTabStatus(idx); - } else { - // Only update the tab status. Do no propagate upwards. - updateTabInfo(idx); - updateAllTabsSequence(); + // Current tab. Propogate its status. + emit tabStatusUpdated(p_info); } } @@ -603,7 +585,7 @@ void VEditWindow::updateFileInfo(const VFile *p_file) } int idx = findTabByFile(p_file); if (idx > -1) { - noticeStatus(idx); + updateTabStatus(idx); } } @@ -618,7 +600,7 @@ void VEditWindow::updateDirectoryInfo(const VDirectory *p_dir) VEditTab *editor = getTab(i); QPointer file = editor->getFile(); if (p_dir->containsFile(file)) { - noticeStatus(i); + updateTabStatus(i); } } } @@ -634,7 +616,7 @@ void VEditWindow::updateNotebookInfo(const VNotebook *p_notebook) VEditTab *editor = getTab(i); QPointer file = editor->getFile(); if (p_notebook->containsFile(file)) { - noticeStatus(i); + updateTabStatus(i); } } } @@ -727,11 +709,11 @@ bool VEditWindow::addEditTab(QWidget *p_widget) this, &VEditWindow::handleOutlineChanged); connect(editor, &VEditTab::curHeaderChanged, this, &VEditWindow::handleCurHeaderChanged); - connect(editor, &VEditTab::statusChanged, - this, &VEditWindow::handleTabStatusChanged); + connect(editor, &VEditTab::statusUpdated, + this, &VEditWindow::handleTabStatusUpdated); int idx = appendEditTab(editor->getFile(), editor); setCurrentIndex(idx); - noticeTabStatus(idx); + updateTabStatus(idx); return true; } diff --git a/src/veditwindow.h b/src/veditwindow.h index 91cb7b8f..82f529dd 100644 --- a/src/veditwindow.h +++ b/src/veditwindow.h @@ -32,7 +32,6 @@ public: void readFile(); void saveAndReadFile(); bool closeAllFiles(bool p_forced); - void requestUpdateTabStatus(); void requestUpdateOutline(); void requestUpdateCurHeader(); // Focus to current tab's editor @@ -56,11 +55,18 @@ public: bool alternateTab(); VEditTab *getTab(int tabIndex) const; + // Ask tab @p_index to update its status and propogate. + // The status here means tab status, outline, current header. + // If @p_index is -1, it is current tab. + void updateTabStatus(int p_index = -1); + protected: void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; signals: - void tabStatusChanged(const VFile *p_file, const VEditTab *p_editTab, bool p_editMode); + // Status of current VEditTab has update. + void tabStatusUpdated(const VEditTabInfo &p_info); + void requestSplitWindow(VEditWindow *curWindow); void requestRemoveSplit(VEditWindow *curWindow); // This widget or its children get the focus @@ -84,7 +90,6 @@ private slots: void tabListJump(VFile *p_file); void handleOutlineChanged(const VToc &p_toc); void handleCurHeaderChanged(const VAnchor &p_anchor); - void handleTabStatusChanged(); void updateSplitMenu(); void tabbarContextMenuRequested(QPoint p_pos); void handleLocateAct(); @@ -97,6 +102,9 @@ private slots: // Handle the vimStatusUpdated() signal of VEditTab. void handleTabVimStatusUpdated(const VVim *p_vim); + // Handle the statusUpdated signal of VEditTab. + void handleTabStatusUpdated(const VEditTabInfo &p_info); + private: void initTabActions(); void setupCornerWidget(); @@ -104,8 +112,6 @@ private: int insertEditTab(int p_index, VFile *p_file, QWidget *p_page); int appendEditTab(VFile *p_file, QWidget *p_page); int openFileInTab(VFile *p_file, OpenFileMode p_mode); - void noticeTabStatus(int p_index); - void noticeStatus(int index); inline QString generateTooltip(const VFile *p_file) const; inline QString generateTabText(int p_index, const QString &p_name, bool p_modified, bool p_modifiable) const; diff --git a/src/vhtmltab.cpp b/src/vhtmltab.cpp index c8396adf..4fd90950 100644 --- a/src/vhtmltab.cpp +++ b/src/vhtmltab.cpp @@ -48,6 +48,7 @@ void VHtmlTab::setupUI() QVBoxLayout *mainLayout = new QVBoxLayout(); mainLayout->addWidget(m_editor); + mainLayout->setContentsMargins(0, 0, 0, 0); setLayout(mainLayout); } @@ -59,14 +60,7 @@ void VHtmlTab::handleTextChanged() return; } - noticeStatusChanged(); -} - -void VHtmlTab::noticeStatusChanged() -{ - m_modified = m_file->isModified(); - - emit statusChanged(); + updateStatus(); } void VHtmlTab::showFileReadMode() @@ -75,7 +69,7 @@ void VHtmlTab::showFileReadMode() m_editor->setReadOnly(true); - noticeStatusChanged(); + updateStatus(); } void VHtmlTab::showFileEditMode() @@ -89,7 +83,7 @@ void VHtmlTab::showFileEditMode() m_editor->beginEdit(); m_editor->setFocus(); - noticeStatusChanged(); + updateStatus(); } bool VHtmlTab::closeFile(bool p_forced) @@ -184,7 +178,7 @@ bool VHtmlTab::saveFile() m_editor->setModified(true); } - noticeStatusChanged(); + updateStatus(); return ret; } diff --git a/src/vhtmltab.h b/src/vhtmltab.h index ea0a237f..9024dfd6 100644 --- a/src/vhtmltab.h +++ b/src/vhtmltab.h @@ -56,9 +56,6 @@ private slots: // Handle text changed in m_editor. void handleTextChanged(); - // Emit statusChanged() signal to notify that status of this tab has changed. - void noticeStatusChanged(); - // m_editor requests to save changes and enter read mode. void saveAndRead(); diff --git a/src/vmainwindow.cpp b/src/vmainwindow.cpp index b8f36eef..9289e740 100644 --- a/src/vmainwindow.cpp +++ b/src/vmainwindow.cpp @@ -21,6 +21,7 @@ #include "vexporter.h" #include "vmdtab.h" #include "vvimindicator.h" +#include "vtabindicator.h" extern VConfigManager vconfig; @@ -108,8 +109,8 @@ void VMainWindow::setupUI() editArea, &VEditArea::openFile); connect(fileList, &VFileList::fileUpdated, editArea, &VEditArea::handleFileUpdated); - connect(editArea, &VEditArea::curTabStatusChanged, - this, &VMainWindow::handleCurTabStatusChanged); + connect(editArea, &VEditArea::tabStatusUpdated, + this, &VMainWindow::handleAreaTabStatusUpdated); connect(editArea, &VEditArea::statusMessage, this, &VMainWindow::showStatusMessage); connect(editArea, &VEditArea::vimStatusUpdated, @@ -119,10 +120,15 @@ void VMainWindow::setupUI() setCentralWidget(mainSplitter); - // Create and show the status bar m_vimIndicator = new VVimIndicator(this); m_vimIndicator->hide(); + + m_tabIndicator = new VTabIndicator(this); + m_tabIndicator->hide(); + + // Create and show the status bar statusBar()->addPermanentWidget(m_vimIndicator); + statusBar()->addPermanentWidget(m_tabIndicator); } QWidget *VMainWindow::setupDirectoryPanel() @@ -1108,18 +1114,26 @@ void VMainWindow::updateActionStateFromTabStatusChange(const VFile *p_file, } } -void VMainWindow::handleCurTabStatusChanged(const VFile *p_file, const VEditTab *p_editTab, bool p_editMode) +void VMainWindow::handleAreaTabStatusUpdated(const VEditTabInfo &p_info) { - updateActionStateFromTabStatusChange(p_file, p_editMode); - if (p_file) { - m_findReplaceDialog->updateState(p_file->getDocType(), p_editMode); + bool editMode = false; + m_curTab = p_info.m_editTab; + if (m_curTab) { + m_curFile = m_curTab->getFile(); + editMode = m_curTab->isEditMode(); + } else { + m_curFile = NULL; } + updateActionStateFromTabStatusChange(m_curFile, editMode); + QString title; - if (p_file) { - title = QString("[%1] %2").arg(p_file->getNotebookName()).arg(p_file->retrivePath()); - if (p_file->isModifiable()) { - if (p_file->isModified()) { + if (m_curFile) { + m_findReplaceDialog->updateState(m_curFile->getDocType(), editMode); + + title = QString("[%1] %2").arg(m_curFile->getNotebookName()).arg(m_curFile->retrivePath()); + if (m_curFile->isModifiable()) { + if (m_curFile->isModified()) { title.append('*'); } } else { @@ -1128,10 +1142,7 @@ void VMainWindow::handleCurTabStatusChanged(const VFile *p_file, const VEditTab } updateWindowTitle(title); - m_curFile = const_cast(p_file); - m_curTab = const_cast(p_editTab); - - updateStatusInfo(p_editMode); + updateStatusInfo(p_info); } void VMainWindow::onePanelView() @@ -1505,12 +1516,20 @@ void VMainWindow::showStatusMessage(const QString &p_msg) statusBar()->showMessage(p_msg, timeout); } -void VMainWindow::updateStatusInfo(bool p_editMode) +void VMainWindow::updateStatusInfo(const VEditTabInfo &p_info) { - if (!p_editMode || !m_curTab) { - m_vimIndicator->hide(); + if (m_curTab) { + m_tabIndicator->update(p_info); + m_tabIndicator->show(); + + if (m_curTab->isEditMode()) { + m_curTab->requestUpdateVimStatus(); + } else { + m_vimIndicator->hide(); + } } else { - m_curTab->requestUpdateVimStatus(); + m_tabIndicator->hide(); + m_vimIndicator->hide(); } } diff --git a/src/vmainwindow.h b/src/vmainwindow.h index 332a0b51..7f63bb9f 100644 --- a/src/vmainwindow.h +++ b/src/vmainwindow.h @@ -30,6 +30,7 @@ class VAvatar; class VFindReplaceDialog; class VCaptain; class VVimIndicator; +class VTabIndicator; class VMainWindow : public QMainWindow { @@ -61,7 +62,6 @@ private slots: void changeHighlightSelectedWord(bool p_checked); void changeHighlightSearchedWord(bool p_checked); void changeHighlightTrailingSapce(bool p_checked); - void handleCurTabStatusChanged(const VFile *p_file, const VEditTab *p_editTab, bool p_editMode); void onePanelView(); void twoPanelView(); void expandPanelView(bool p_checked); @@ -92,6 +92,9 @@ private slots: // Handle Vim status updated. void handleVimStatusUpdated(const VVim *p_vim); + // Handle the status update of the current tab of VEditArea. + void handleAreaTabStatusUpdated(const VEditTabInfo &p_info); + protected: void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; @@ -131,8 +134,8 @@ private: void toggleOnePanelView(); void closeCurrentFile(); - // Update status bar information according to m_curTab and m_curFile. - void updateStatusInfo(bool p_editMode); + // Update status bar information. + void updateStatusInfo(const VEditTabInfo &p_info); // Wrapper to create a QAction. QAction *newAction(const QIcon &p_icon, @@ -158,6 +161,7 @@ private: VAvatar *m_avatar; VFindReplaceDialog *m_findReplaceDialog; VVimIndicator *m_vimIndicator; + VTabIndicator *m_tabIndicator; // Whether it is one panel or two panles. bool m_onePanel; diff --git a/src/vmdedit.h b/src/vmdedit.h index 22a02dad..6ed62ddd 100644 --- a/src/vmdedit.h +++ b/src/vmdedit.h @@ -45,6 +45,8 @@ signals: // Signal when current header change. void curHeaderChanged(VAnchor p_anchor); + // Signal when the status of VMdEdit changed. + // Will be emitted by VImagePreviewer for now. void statusChanged(); private slots: diff --git a/src/vmdtab.cpp b/src/vmdtab.cpp index 09ffcd1e..2dcc397d 100644 --- a/src/vmdtab.cpp +++ b/src/vmdtab.cpp @@ -49,11 +49,13 @@ void VMdTab::setupUI() connect(dynamic_cast(m_editor), &VMdEdit::headersChanged, this, &VMdTab::updateTocFromHeaders); connect(dynamic_cast(m_editor), &VMdEdit::statusChanged, - this, &VMdTab::noticeStatusChanged); + this, &VMdTab::updateStatus); connect(m_editor, SIGNAL(curHeaderChanged(VAnchor)), this, SLOT(updateCurHeader(VAnchor))); connect(m_editor, &VEdit::textChanged, this, &VMdTab::handleTextChanged); + connect(m_editor, &VEdit::cursorPositionChanged, + this, &VMdTab::updateStatus); connect(m_editor, &VEdit::saveAndRead, this, &VMdTab::saveAndRead); connect(m_editor, &VEdit::discardAndRead, @@ -82,14 +84,7 @@ void VMdTab::handleTextChanged() return; } - noticeStatusChanged(); -} - -void VMdTab::noticeStatusChanged() -{ - m_modified = m_file->isModified(); - - emit statusChanged(); + updateStatus(); } void VMdTab::showFileReadMode() @@ -110,7 +105,7 @@ void VMdTab::showFileReadMode() scrollWebViewToHeader(outlineIndex); - noticeStatusChanged(); + updateStatus(); } void VMdTab::scrollWebViewToHeader(int p_outlineIndex) @@ -173,7 +168,7 @@ void VMdTab::showFileEditMode() mdEdit->setFocus(); - noticeStatusChanged(); + updateStatus(); } bool VMdTab::closeFile(bool p_forced) @@ -268,7 +263,7 @@ bool VMdTab::saveFile() m_editor->setModified(true); } - noticeStatusChanged(); + updateStatus(); return ret; } @@ -656,3 +651,17 @@ void VMdTab::requestUpdateVimStatus() emit vimStatusUpdated(NULL); } } + +VEditTabInfo VMdTab::createEditTabInfo() +{ + VEditTabInfo info = VEditTab::createEditTabInfo(); + + if (m_editor) { + QTextCursor cursor = m_editor->textCursor(); + info.m_cursorBlockNumber = cursor.block().blockNumber(); + info.m_cursorPositionInBlock = cursor.positionInBlock(); + info.m_blockCount = m_editor->document()->blockCount(); + } + + return info; +} diff --git a/src/vmdtab.h b/src/vmdtab.h index b750f338..31c00f86 100644 --- a/src/vmdtab.h +++ b/src/vmdtab.h @@ -65,9 +65,6 @@ private slots: // Handle text changed in m_editor. void handleTextChanged(); - // Emit statusChanged() signal to notify that status of this tab has changed. - void noticeStatusChanged(); - // Update m_toc according to @p_tocHtml for read mode. void updateTocFromHtml(const QString &p_tocHtml); @@ -122,6 +119,9 @@ private: // Focus the proper child widget. void focusChild() Q_DECL_OVERRIDE; + // Create a filled VEditTabInfo. + VEditTabInfo createEditTabInfo() Q_DECL_OVERRIDE; + VEdit *m_editor; VWebView *m_webViewer; VDocument *m_document; diff --git a/src/vtabindicator.cpp b/src/vtabindicator.cpp new file mode 100644 index 00000000..2f42a1a0 --- /dev/null +++ b/src/vtabindicator.cpp @@ -0,0 +1,97 @@ +#include "vtabindicator.h" + +#include +#include + +#include "vedittab.h" + +VTabIndicator::VTabIndicator(QWidget *p_parent) + : QWidget(p_parent) +{ + setupUI(); +} + +void VTabIndicator::setupUI() +{ + m_docTypeLabel = new QLabel(this); + m_readonlyLabel = new QLabel(tr("ReadOnly"), + this); + m_cursorLabel = new QLabel(this); + + QHBoxLayout *mainLayout = new QHBoxLayout(this); + mainLayout->addWidget(m_cursorLabel); + mainLayout->addWidget(m_readonlyLabel); + mainLayout->addWidget(m_docTypeLabel); + mainLayout->setContentsMargins(0, 0, 0, 0); + + setLayout(mainLayout); +} + +static QString docTypeToString(DocType p_type) +{ + QString str; + + switch (p_type) { + case DocType::Html: + str = "HTML"; + break; + + case DocType::Markdown: + str = "Markdown"; + break; + + case DocType::List: + str = "List"; + break; + + case DocType::Container: + str = "Container"; + break; + + default: + str = "Unknown"; + break; + } + + return str; +} + +void VTabIndicator::update(const VEditTabInfo &p_info) +{ + const VEditTab *editTab = NULL; + const VFile *file = NULL; + DocType docType = DocType::Html; + bool readonly = true; + QString cursorStr; + + if (p_info.m_editTab) + { + editTab = p_info.m_editTab; + file = editTab->getFile(); + docType = file->getDocType(); + readonly = !file->isModifiable(); + + if (editTab->isEditMode()) { + int line = p_info.m_cursorBlockNumber + 1; + int col = p_info.m_cursorPositionInBlock; + if (col < 0) { + col = 0; + } + + int lineCount = p_info.m_blockCount < 1 ? 1 : p_info.m_blockCount; + + QString cursorText = tr("Line: %1 - %2(%3%) " + "Col: %4") + .arg(line).arg(lineCount) + .arg((int)(line * 1.0 / lineCount * 100), 2) + .arg(col, 3); + m_cursorLabel->setText(cursorText); + m_cursorLabel->show(); + } else { + m_cursorLabel->hide(); + } + } + + m_docTypeLabel->setText(docTypeToString(docType)); + m_readonlyLabel->setVisible(readonly); +} diff --git a/src/vtabindicator.h b/src/vtabindicator.h new file mode 100644 index 00000000..8c8f1e7f --- /dev/null +++ b/src/vtabindicator.h @@ -0,0 +1,32 @@ +#ifndef VTABINDICATOR_H +#define VTABINDICATOR_H + +#include +#include "vedittabinfo.h" + +class QLabel; + +class VTabIndicator : public QWidget +{ + Q_OBJECT + +public: + explicit VTabIndicator(QWidget *p_parent = 0); + + // Update indicator. + void update(const VEditTabInfo &p_info); + +private: + void setupUI(); + + // Indicate the doc type. + QLabel *m_docTypeLabel; + + // Indicate the readonly property. + QLabel *m_readonlyLabel; + + // Indicate the position of current cursor. + QLabel *m_cursorLabel; +}; + +#endif // VTABINDICATOR_H diff --git a/src/vvimindicator.cpp b/src/vvimindicator.cpp index 6ed0c8be..62620fa7 100644 --- a/src/vvimindicator.cpp +++ b/src/vvimindicator.cpp @@ -13,8 +13,8 @@ extern VConfigManager vconfig; -VVimIndicator::VVimIndicator(QWidget *parent) - : QWidget(parent), m_vim(NULL) +VVimIndicator::VVimIndicator(QWidget *p_parent) + : QWidget(p_parent), m_vim(NULL) { setupUI(); } @@ -26,6 +26,7 @@ void VVimIndicator::setupUI() m_regBtn = new VButtonWithWidget(QIcon(":/resources/icons/arrow_dropup.svg"), "\"", this); + m_regBtn->setToolTip(tr("Registers")); m_regBtn->setProperty("StatusBtn", true); m_regBtn->setFocusPolicy(Qt::NoFocus); QTreeWidget *regTree = new QTreeWidget(this); @@ -41,6 +42,7 @@ void VVimIndicator::setupUI() m_markBtn = new VButtonWithWidget(QIcon(":/resources/icons/arrow_dropup.svg"), "[]", this); + m_markBtn->setToolTip(tr("Marks")); m_markBtn->setProperty("StatusBtn", true); m_markBtn->setFocusPolicy(Qt::NoFocus); QTreeWidget *markTree = new QTreeWidget(this); @@ -154,16 +156,18 @@ static void fillTreeItemsWithRegisters(QTreeWidget *p_tree, void VVimIndicator::update(const VVim *p_vim) { - if (!p_vim) { - m_vim = p_vim; - return; - } - m_vim = p_vim; - VimMode mode = p_vim->getMode(); - QChar curRegName = p_vim->getCurrentRegisterName(); - QChar lastUsedMark = p_vim->getMarks().getLastUsedMark(); + VimMode mode = VimMode::Normal; + QChar curRegName(' '); + QChar lastUsedMark; + QString pendingKeys; + if (p_vim) { + mode = p_vim->getMode(); + curRegName = p_vim->getCurrentRegisterName(); + lastUsedMark = p_vim->getMarks().getLastUsedMark(); + pendingKeys = p_vim->getPendingKeys(); + } QString style = QString("QLabel { padding: 0px 2px 0px 2px; font: bold; background-color: %1; }") .arg(modeBackgroundColor(mode)); @@ -176,8 +180,8 @@ void VVimIndicator::update(const VVim *p_vim) .arg(lastUsedMark.isNull() ? QChar(' ') : lastUsedMark); m_markBtn->setText(markText); - QString keyText = QString("%1") - .arg(p_vim->getPendingKeys()); + QString keyText = QString("%2") + .arg("#15AE67").arg(pendingKeys); m_keyLabel->setText(keyText); } diff --git a/src/vvimindicator.h b/src/vvimindicator.h index 6353a51c..2d17316d 100644 --- a/src/vvimindicator.h +++ b/src/vvimindicator.h @@ -12,9 +12,9 @@ class VVimIndicator : public QWidget Q_OBJECT public: - explicit VVimIndicator(QWidget *parent = 0); + explicit VVimIndicator(QWidget *p_parent = 0); -public slots: + // Update indicator according to @p_vim. void update(const VVim *p_vim); private slots: