diff options
author | Slávek Banko <slavek.banko@axis.cz> | 2013-10-07 23:28:24 +0200 |
---|---|---|
committer | Slávek Banko <slavek.banko@axis.cz> | 2013-10-08 05:14:51 +0200 |
commit | 3af5832abe7c802a384cd58d34f7cc4433595ced (patch) | |
tree | cc300d6fae4cb5798f0cf5db3ece63026f34379a /src/queryview.cpp | |
download | kscope-3af5832abe7c802a384cd58d34f7cc4433595ced.tar.gz kscope-3af5832abe7c802a384cd58d34f7cc4433595ced.zip |
Initial import of kscope 1.6.2
Diffstat (limited to 'src/queryview.cpp')
-rw-r--r-- | src/queryview.cpp | 444 |
1 files changed, 444 insertions, 0 deletions
diff --git a/src/queryview.cpp b/src/queryview.cpp new file mode 100644 index 0000000..c56a2b0 --- /dev/null +++ b/src/queryview.cpp @@ -0,0 +1,444 @@ +/*************************************************************************** + * + * 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 <qapplication.h> +#include <qclipboard.h> +#include <klocale.h> +#include "queryview.h" +#include "queryresultsmenu.h" +#include "queryviewdlg.h" +#include "cscopefrontend.h" +#include "searchresultsdlg.h" + +/** + * Class constructor. + * @param pParent The parent widget + * @param szName The name of the widget + */ +QueryView::QueryView(QWidget* pParent, const char* szName) : + QListView(pParent, szName), + m_pLastItem(NULL) +{ + // Create the popup-menu + m_pQueryMenu = new QueryResultsMenu(this); + + // Initialise the list's columns + setAllColumnsShowFocus(true); + addColumn(i18n("Function")); + addColumn(i18n("File")); + addColumn(i18n("Line")); + addColumn(i18n("Text")); + setColumnAlignment(2, Qt::AlignRight); + + setShowSortIndicator(true); + + // A record is selected if it is either double-clicked, or the ENTER + // key is pressed while the record is highlighted + connect(this, SIGNAL(doubleClicked(QListViewItem*)), this, + SLOT(slotRecordSelected(QListViewItem*))); + connect(this, SIGNAL(returnPressed(QListViewItem*)), this, + SLOT(slotRecordSelected(QListViewItem*))); + + // Show the popup-menu when requested + connect(this, + SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&, int)), + m_pQueryMenu, SLOT(slotShow(QListViewItem*, const QPoint&, int))); + + // Handle popup-menu commands + connect(m_pQueryMenu, SIGNAL(viewSource(QListViewItem*)), this, + SLOT(slotRecordSelected(QListViewItem*))); + connect(m_pQueryMenu, SIGNAL(findDef(const QString&)), this, + SLOT(slotFindDef(const QString&))); + connect(m_pQueryMenu, SIGNAL(copy(QListViewItem*, int)), this, + SLOT(slotCopy(QListViewItem*, int))); + connect(m_pQueryMenu, SIGNAL(filter(int)), this, SLOT(slotFilter(int))); + connect(m_pQueryMenu, SIGNAL(showAll()), this, + SLOT(slotShowAll())); + connect(m_pQueryMenu, SIGNAL(remove(QListViewItem*)), this, + SLOT(slotRemoveItem(QListViewItem*))); +} + +/** + * Class destructor. + */ +QueryView::~QueryView() +{ +} + +/** + * Creates a new list 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 item (ignored) + */ +void QueryView::addRecord(const QString& sFunc, const QString& sFile, + const QString& sLine, const QString& sText, QListViewItem* /* pParent */) +{ + QListViewItem* pItem; + + pItem = new QueryViewItem(this, m_pLastItem, 2); + pItem->setText(0, sFunc); + pItem->setText(1, sFile); + pItem->setText(2, sLine); + pItem->setText(3, sText); + + m_pLastItem = pItem; +} + +/** + * Selects an item. + * When an item is selected, it is highlighted and made visible. By + * definition, the lineRequested() signal is also emitted. + * This method is used for selecting records programmatically (@see + * selectNext() for example). It has nothing to do with user selection. + * @param pItem The list item to select + */ +void QueryView::select(QListViewItem* pItem) +{ + ensureItemVisible(pItem); + setSelected(pItem, true); + slotRecordSelected(pItem); +} + +/** + * Selects the next record in the list (if one exists). + * The function selects the next item as follows: + * - The first item in the list, if there is no current item + * - The current item, if it is not selected + * - The item immediately below the current item, otherwise + */ +void QueryView::selectNext() +{ + QListViewItem* pItem; + + // Do nothing if the list is empty + if (firstChild() == NULL) + return; + + // Find the next record + pItem = currentItem(); + if (pItem == NULL) { + pItem = firstChild(); + } + else if (pItem->isSelected()) { + pItem = pItem->itemBelow(); + if (pItem == NULL) + return; + } + + // Select the new item + select(pItem); +} + +/** + * Selects the previous record in the list (if one exists). + * The function selects the previous item as follows: + * - The first item in the list, if there is no current item + * - The current item, if it is not selected + * - The item immediately above the current item, otherwise + */ +void QueryView::selectPrev() +{ + QListViewItem* pItem; + + // Do nothing if the list is empty + if (firstChild() == NULL) + return; + + // Find the item immediately above this one + pItem = currentItem(); + if (pItem == NULL) { + pItem = firstChild(); + } + else if (pItem->isSelected()) { + pItem = pItem->itemAbove(); + if (pItem == NULL) + return; + } + + // Select the new item + select(pItem); +} + +/** + * Informs the view that query progress information has been received. + * The view emits the needToShow() signal telling its parent that the widget + * should become visible (if not already so). + */ +void QueryView::queryProgress() +{ + if (!isVisible()) + emit needToShow(); +} + +/** + * Called when a query using this view terminates. + * @param nRecords Number of records generated by the query + */ +void QueryView::queryFinished(uint nRecords, QListViewItem*) +{ + // Auto-select a single record (no need to emit the show() signal in + // that case) + if (nRecords == 1) { + emit select(firstChild()); + return; + } + + // Report a query that has returned an empty record set + if (nRecords == 0) + addRecord(i18n("No results"), "", "", "", NULL); + + // Data is available, instruct the owner object to show the view + emit needToShow(); +} + +/** + * Creates an iterator and initialises it to point to the first _visible_ + * item in the list. + * @return A new iterator initialised to the beginning of the list + */ +QueryView::Iterator QueryView::getIterator() +{ + QListViewItem* pItem; + + for (pItem = firstChild(); pItem != NULL && !pItem->isVisible(); + pItem = pItem->nextSibling()); + + return Iterator(pItem); +} + +/** + * Handles double-click events over the view. + * NOTE: We override this method since the QListView implementation opens + * expandable items. This is undesired for tree-like query views (such as the + * call tree. + * @param pEvent Event description object + */ +void QueryView::contentsMouseDoubleClickEvent(QMouseEvent* pEvent) +{ + QListViewItem* pItem; + + // Handle only left button double-clicks + if (pEvent == NULL || pEvent->button() != LeftButton) + return; + + // Find the clicked item + pItem = itemAt(contentsToViewport(pEvent->pos())); + if (pItem == NULL) + return; + + // Emit the doubleClicked() signal + emit doubleClicked(pItem); +} + +/** + * Emits the lineRequested() signal when a list item is selected. + * This slot is connected to the doubleClicked() and returnPressed() + * signals of the list view. + * @param pItem The selected item + */ +void QueryView::slotRecordSelected(QListViewItem* pItem) +{ + QString sFileName, sLine; + + // Get the file name and line number + sFileName = pItem->text(1); + sLine = pItem->text(2); + + // Do not process the "No results" item + if (!sLine.isEmpty()) + emit lineRequested(sFileName, sLine.toUInt()); +} + +/** + * Looks up the definition of a given function. + * Results are displayed in a popup window. + * This slot is connected to the findDef() signal emitted by the results menu. + * @param sFunc The function to look for + */ +void QueryView::slotFindDef(const QString& sFunc) +{ + QueryViewDlg* pDlg; + + // Create a query view dialogue + pDlg = new QueryViewDlg(QueryViewDlg::DestroyOnSelect, this); + + // Display a line when it is selected in the dialogue + connect(pDlg, SIGNAL(lineRequested(const QString&, uint)), this, + SIGNAL(lineRequested(const QString&, uint))); + + // Start the query + pDlg->query(CscopeFrontend::Definition, sFunc); +} + +/** + * Copies the text of the requested field (item+column) to the clipboard. + * This slot is connected to the copy() signal of the QueryResultsMenu object. + * @param pItem The item from which to copy + * @param nCol The index of the item field to copy + */ +void QueryView::slotCopy(QListViewItem* pItem, int nCol) +{ + QApplication::clipboard()->setText(pItem->text(nCol), + QClipboard::Clipboard); +} + +/** + * Hides all items in the page 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 nCol The list column to search in + */ +void QueryView::slotFilter(int nCol) +{ + SearchResultsDlg dlg(this); + QRegExp re; + QListViewItem* pItem; + bool bNegate; + + // Prepare the dialogue + dlg.setColumn(nCol); + + // Show the dialogue + if (dlg.exec() != QDialog::Accepted) + return; + + // Get the selected regular expression + dlg.getPattern(re); + bNegate = dlg.isNegated(); + + // Disable visual updates while search is in progress + setUpdatesEnabled(false); + + // Iterate over all items in the list + pItem = firstChild(); + while (pItem != NULL) { + // Filter visible items only + if (pItem->isVisible() && + (re.search(pItem->text(nCol)) == -1) != bNegate) { + pItem->setVisible(false); + } + + pItem = pItem->nextSibling(); + } + + // Redraw the list + setUpdatesEnabled(true); + triggerUpdate(); +} + +/** + * Makes all list items visible. + * This slot is connected to the showAll() signal of the QueryResultsMenu + * object. + */ +void QueryView::slotShowAll() +{ + QListViewItem* pItem; + + // Iterate over all items in the list + pItem = firstChild(); + while (pItem != NULL) { + pItem->setVisible(true); + pItem = pItem->nextSibling(); + } +} + +/** + * Deletes the item on which a popup-menu has been invoked. + * This slot is connected to the remove() signal of the QueryResultsMenu + * object. + * @param pItem The item to remove + */ +void QueryView::slotRemoveItem(QListViewItem* pItem) +{ + delete pItem; +} + +/** + * Moves the iterator to the next _visible_ item in the list. + */ +void QueryView::Iterator::next() +{ + if (m_pItem == NULL) + return; + + do { + m_pItem = m_pItem->nextSibling(); + } while (m_pItem != NULL && !m_pItem->isVisible()); +} + +/** + * @return The function associated with the list item the iterator points to + */ +QString QueryView::Iterator::getFunc() +{ + if (m_pItem == NULL) + return ""; + + return m_pItem->text(0); +} + +/** + * @return The file associated with the list item the iterator points to + */ +QString QueryView::Iterator::getFile() +{ + if (m_pItem == NULL) + return ""; + + return m_pItem->text(1); +} + +/** + * @return The line number associated with the list item the iterator points + * to + */ +QString QueryView::Iterator::getLine() +{ + if (m_pItem == NULL) + return ""; + + return m_pItem->text(2); +} + +/** + * @return The text associated with the list item the iterator points to + */ +QString QueryView::Iterator::getText() +{ + if (m_pItem == NULL) + return ""; + + return m_pItem->text(3); +} + +#include "queryview.moc" |