| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- #include <QVector>
- #include <QString>
- #include <QKeyEvent>
- #include <QLabel>
- #include <QCoreApplication>
- #include "voutline.h"
- #include "utils/vutils.h"
- #include "vnote.h"
- #include "vfile.h"
- extern VNote *g_vnote;
- VOutline::VOutline(QWidget *parent)
- : VTreeWidget(parent),
- VNavigationMode(),
- m_muted(false)
- {
- setColumnCount(1);
- setHeaderHidden(true);
- setSelectionMode(QAbstractItemView::SingleSelection);
- // TODO: jump to the header when user click the same item twice.
- connect(this, &VOutline::currentItemChanged,
- this, &VOutline::handleCurrentItemChanged);
- }
- void VOutline::updateOutline(const VTableOfContent &p_outline)
- {
- if (p_outline == m_outline) {
- return;
- }
- // Clear current header
- m_currentHeader.clear();
- m_outline = p_outline;
- updateTreeFromOutline();
- expandTree();
- }
- void VOutline::updateTreeFromOutline()
- {
- clear();
- if (m_outline.isEmpty()) {
- return;
- }
- const QVector<VTableOfContentItem> &headers = m_outline.getTable();
- int idx = 0;
- updateTreeByLevel(headers, idx, NULL, NULL, 1);
- }
- void VOutline::updateTreeByLevel(const QVector<VTableOfContentItem> &headers,
- int &index,
- QTreeWidgetItem *parent,
- QTreeWidgetItem *last,
- int level)
- {
- while (index < headers.size()) {
- const VTableOfContentItem &header = headers[index];
- QTreeWidgetItem *item;
- if (header.m_level == level) {
- if (parent) {
- item = new QTreeWidgetItem(parent);
- } else {
- item = new QTreeWidgetItem(this);
- }
- fillItem(item, header);
- last = item;
- ++index;
- } else if (header.m_level < level) {
- return;
- } else {
- updateTreeByLevel(headers, index, last, NULL, level + 1);
- }
- }
- }
- void VOutline::fillItem(QTreeWidgetItem *p_item, const VTableOfContentItem &p_header)
- {
- p_item->setData(0, Qt::UserRole, p_header.m_index);
- p_item->setText(0, p_header.m_name);
- p_item->setToolTip(0, p_header.m_name);
- if (p_header.isEmpty()) {
- p_item->setForeground(0, QColor("grey"));
- }
- }
- void VOutline::expandTree()
- {
- if (topLevelItemCount() == 0) {
- return;
- }
- expandAll();
- }
- void VOutline::handleCurrentItemChanged(QTreeWidgetItem *p_curItem,
- QTreeWidgetItem * p_preItem)
- {
- Q_UNUSED(p_preItem);
- if (!p_curItem) {
- return;
- }
- const VTableOfContentItem *header = getHeaderFromItem(p_curItem);
- Q_ASSERT(header);
- m_currentHeader.update(m_outline.getFile(), header->m_index);
- if (!header->isEmpty() && !m_muted) {
- emit outlineItemActivated(m_currentHeader);
- }
- }
- void VOutline::updateCurrentHeader(const VHeaderPointer &p_header)
- {
- if (p_header == m_currentHeader
- || !m_outline.isMatched(p_header)) {
- return;
- }
- // Item change should not emit the signal.
- m_muted = true;
- m_currentHeader = p_header;
- selectHeader(m_currentHeader);
- m_muted = false;
- }
- void VOutline::selectHeader(const VHeaderPointer &p_header)
- {
- setCurrentItem(NULL);
- if (!m_outline.getItem(p_header)) {
- return;
- }
- int nrTop = topLevelItemCount();
- for (int i = 0; i < nrTop; ++i) {
- if (selectHeaderOne(topLevelItem(i), p_header)) {
- return;
- }
- }
- }
- bool VOutline::selectHeaderOne(QTreeWidgetItem *p_item, const VHeaderPointer &p_header)
- {
- if (!p_item) {
- return false;
- }
- const VTableOfContentItem *header = getHeaderFromItem(p_item);
- if (!header) {
- return false;
- }
- if (header->isMatched(p_header)) {
- setCurrentItem(p_item);
- return true;
- }
- int nrChild = p_item->childCount();
- for (int i = 0; i < nrChild; ++i) {
- if (selectHeaderOne(p_item->child(i), p_header)) {
- return true;
- }
- }
- return false;
- }
- void VOutline::keyPressEvent(QKeyEvent *event)
- {
- int key = event->key();
- int modifiers = event->modifiers();
- switch (key) {
- case Qt::Key_Return:
- {
- QTreeWidgetItem *item = currentItem();
- if (item) {
- item->setExpanded(!item->isExpanded());
- }
- break;
- }
- case Qt::Key_J:
- {
- if (modifiers == Qt::ControlModifier) {
- event->accept();
- QKeyEvent *downEvent = new QKeyEvent(QEvent::KeyPress, Qt::Key_Down,
- Qt::NoModifier);
- QCoreApplication::postEvent(this, downEvent);
- return;
- }
- break;
- }
- case Qt::Key_K:
- {
- if (modifiers == Qt::ControlModifier) {
- event->accept();
- QKeyEvent *upEvent = new QKeyEvent(QEvent::KeyPress, Qt::Key_Up,
- Qt::NoModifier);
- QCoreApplication::postEvent(this, upEvent);
- return;
- }
- break;
- }
- default:
- break;
- }
- VTreeWidget::keyPressEvent(event);
- }
- void VOutline::showNavigation()
- {
- VNavigationMode::showNavigation(this);
- }
- bool VOutline::handleKeyNavigation(int p_key, bool &p_succeed)
- {
- static bool secondKey = false;
- return VNavigationMode::handleKeyNavigation(this,
- secondKey,
- p_key,
- p_succeed);
- }
- const VTableOfContentItem *VOutline::getHeaderFromItem(QTreeWidgetItem *p_item) const
- {
- int index = p_item->data(0, Qt::UserRole).toInt();
- return m_outline.getItem(index);
- }
|