diff options
Diffstat (limited to 'src/treewidget.cpp')
-rw-r--r-- | src/treewidget.cpp | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/src/treewidget.cpp b/src/treewidget.cpp new file mode 100644 index 0000000..b303194 --- /dev/null +++ b/src/treewidget.cpp @@ -0,0 +1,260 @@ +/*************************************************************************** + * + * Copyright (C) 2005 Elad Lahav (elad_lahav@users.sourceforge.net) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ + +#include "treewidget.h" +#include "queryviewdriver.h" + +/** + * Class constructor. + * @param pParent Parent widget + * @param szName The name of the widget + */ +TreeWidget::TreeWidget(QWidget* pParent, const char* szName) : + QueryView(pParent, szName), + m_nQueryType(CscopeFrontend::Called) +{ + setRootIsDecorated(true); + + // Create a driver object + m_pDriver = new QueryViewDriver(this, this); + + // Query a tree item when it is expanded for the first time + connect(this, SIGNAL(expanded(QListViewItem*)), this, + SLOT(slotQueryItem(QListViewItem*))); +} + +/** + * Class destructor. + */ +TreeWidget::~TreeWidget() +{ +} + +/** + * Determines the mode of the tree. + * @param mode The new mode (@see Mode) + */ +void TreeWidget::setMode(Mode mode) +{ + m_nQueryType = (mode == Called) ? CscopeFrontend::Called : + CscopeFrontend::Calling; +} + +/** + * Sets a new root item for the tree. + * @param sFunc The name of the function to serve as root + */ +void TreeWidget::setRoot(const QString& sFunc) +{ + QListViewItem* pRoot; + + // Remove the current root, if any + if ((pRoot = firstChild()) != NULL) + delete pRoot; + + // Create a new root item + pRoot = new QListViewItem(this, sFunc); + pRoot->setExpandable(true); +} + +/** + * Runs a query on the root item. + */ +void TreeWidget::queryRoot() +{ + QListViewItem* pRoot; + + if ((pRoot = firstChild()) != NULL) + slotQueryItem(pRoot); +} + +/** + * Stores the tree contents in the given file. + * @param pFile An open file to write to + */ +void TreeWidget::save(FILE* pFile) +{ + QTextStream str(pFile, IO_WriteOnly); + QListViewItem* pRoot; + Encoder enc; + + if (m_nQueryType == CscopeFrontend::Called) + str << "calltree {" << endl; + else + str << "callingtree {" << endl; + + // Write the tree to the file + pRoot = firstChild(); + str << pRoot->text(0) << endl; + str << '{' << endl; + saveItems(pRoot->firstChild(), str, enc); + str << '}' << endl; + str << '}' << endl; +} + +/** + * Recursively writes tree items to a file. + * Given an item, the method writes this item and all of its siblings. + * Child items are written recursively. + * @param pItem The first item to write + * @param str An initialised text stream to use for writing + * @param enc An encoder for free-text strings + */ +void TreeWidget::saveItems(QListViewItem* pItem, QTextStream& str, Encoder& enc) +{ + // Iterate over all items in this level + for (; pItem != NULL; pItem = pItem->nextSibling()) { + // Write function parameters + str << pItem->text(0) << " [ " + << "kscope_file=\"" << pItem->text(1) << "\", " + << "kscope_line=" << pItem->text(2) << ", " + << "kscope_text=\"" << enc.encode(pItem->text(3)) << "\"" + << "]" << endl; + + // Write child items + str << "{" << endl; + saveItems(pItem->firstChild(), str, enc); + str << "}" << endl; + } +} + +/** + * Creates a new tree item showing a query result record. + * @param sFunc The name of the function + * @param sFile The file path + * @param sLine The line number in the above file + * @param sText The line's text + * @param pParent The parent for the new item + */ +void TreeWidget::addRecord(const QString& sFunc, const QString& sFile, + const QString& sLine, const QString& sText, QListViewItem* pParent) +{ + QListViewItem* pItem; + + pItem = new QueryViewItem(pParent, m_pLastItem, 2); + pItem->setText(0, sFunc); + pItem->setText(1, sFile); + pItem->setText(2, sLine); + pItem->setText(3, sText); + + pItem->setExpandable(true); + m_pLastItem = pItem; +} + +/** + * Called when a query running on the tree terminates. + * If there were no results, the item becomes non-expandable. + * NOTE: On top of its current behaviour, this function is required in order to + * override the default behaviour, as specified by QueryView. + * @param nResults Number of results + * @param pParent The item for which the query was executed + */ +void TreeWidget::queryFinished(uint nResults, QListViewItem* pParent) +{ + if (nResults == 0) + pParent->setExpandable(false); + else + pParent->setOpen(true); +} + +/** + * Runs a query on the given item, unless it was queried before. + * This slot is connected to the expanded() signal of the list view. + * @param pItem The item to query + */ +void TreeWidget::slotQueryItem(QListViewItem* pItem) +{ + // Do nothing if the item was already queried + // An item has been queried if it has children or marked as non-expandable + if (pItem->firstChild() != NULL || !pItem->isExpandable()) + return; + + // Run the query + m_pDriver->query(m_nQueryType, pItem->text(0), true, pItem); +} + +/** + * Hides all descendant that do not meet the given search criteria. + * This slot is connected to the search() signal of the QueryResultsMenu + * object. + * The search is incremental: only visible items are checked, so that a new + * search goes over the results of the previous one. + * @param pParent The parent item whose child are searched + * @param re The pattern to search + * @param nCol The list column to search in + */ +void TreeWidget::slotSearch(QListViewItem* pParent, const QRegExp& re, + int nCol) +{ + QListViewItem* pItem; + + // Get the first child + if (pParent != NULL) + pItem = pParent->firstChild(); + else + pItem = firstChild(); + + // Iterate over all child items + while (pItem != NULL) { + // Filter visible items only + if (pItem->isVisible() && re.search(pItem->text(nCol)) == -1) + pItem->setVisible(false); + + // Search child items recursively + slotSearch(pItem, re, nCol); + + pItem = pItem->nextSibling(); + } +} + +/** + * Makes all descendants of the given item visible. + * This slot is connected to the showAll() signal of the QueryResultsMenu + * object. + */ +void TreeWidget::slotShowAll(QListViewItem* pParent) +{ + QListViewItem* pItem; + + // Get the first child + if (pParent != NULL) + pItem = pParent->firstChild(); + else + pItem = firstChild(); + + // Iterate over all child items + while (pItem != NULL) { + pItem->setVisible(true); + + // Show child items recursively + slotShowAll(pItem); + + pItem = pItem->nextSibling(); + } +} + +#include "treewidget.moc" |