summaryrefslogtreecommitdiffstats
path: root/src/symboldlg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/symboldlg.cpp')
-rw-r--r--src/symboldlg.cpp334
1 files changed, 334 insertions, 0 deletions
diff --git a/src/symboldlg.cpp b/src/symboldlg.cpp
new file mode 100644
index 0000000..3301678
--- /dev/null
+++ b/src/symboldlg.cpp
@@ -0,0 +1,334 @@
+/***************************************************************************
+ *
+ * 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 <qlabel.h>
+#include <qlistview.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qcheckbox.h>
+#include <qgroupbox.h>
+#include <kcombobox.h>
+#include <klocale.h>
+#include "symboldlg.h"
+#include "cscopefrontend.h"
+#include "kscopeconfig.h"
+
+QStringList SymbolDlg::s_slHistory;
+
+/**
+ * Class constructor.
+ * @param pParent Parent widget
+ * @param szName This widget's name
+ */
+SymbolDlg::SymbolDlg(QWidget* pParent, const char* szName) :
+ SymbolLayout(pParent, szName, true, 0),
+ m_progress(m_pHintList)
+{
+ // Create a persistent Cscope process
+ m_pCscope = new CscopeFrontend();
+
+ // Initialise the hint list (hidden by default)
+ m_pHintList->addColumn(i18n("Suggested Symbols"));
+ m_pHintList->hide();
+ ((QWidget*)m_pHintGroup)->hide();
+ m_pBeginWithRadio->toggle();
+ adjustSize();
+
+ // Close the dialogue when either the "OK" or "Cancel" button are clicked
+ connect(m_pOKButton, SIGNAL(clicked()), this, SLOT(accept()));
+ connect(m_pCancelButton, SIGNAL(clicked()), this, SLOT(reject()));
+
+ // Run a symbol completion query when the "Hint" button is clicked
+ connect(m_pHintButton, SIGNAL(clicked()), this, SLOT(slotHintClicked()));
+
+ // Add results to the hint list
+ connect(m_pCscope, SIGNAL(dataReady(FrontendToken*)), this,
+ SLOT(slotHintDataReady(FrontendToken*)));
+
+ // Set hint button availability based on the type of query
+ connect(m_pTypeCombo, SIGNAL(activated(int)), this,
+ SLOT(slotTypeChanged(int)));
+
+ // Selecting an item in the hint list sets it as the current text
+ connect(m_pHintList, SIGNAL(selectionChanged(QListViewItem*)), this,
+ SLOT(slotHintItemSelected(QListViewItem*)));
+
+ // Double-clicking an item in the hint list accepts that item as the
+ // result of the query (i.e., the item is selcted and the dialogue is
+ // closed)
+ connect(m_pHintList, SIGNAL(doubleClicked(QListViewItem*)), this,
+ SLOT(accept()));
+
+ // Refresh the hint list when the hint options change
+ connect(m_pBeginWithRadio, SIGNAL(toggled(bool)), this,
+ SLOT(slotHintOptionChanged(bool)));
+ connect(m_pContainRadio, SIGNAL(toggled(bool)), this,
+ SLOT(slotHintOptionChanged(bool)));
+
+ // Show hint query progress information
+ connect(m_pCscope, SIGNAL(progress(int, int)), this,
+ SLOT(slotHintProgress(int, int)));
+ connect(m_pCscope, SIGNAL(finished(uint)), this,
+ SLOT(slotHintFinished(uint)));
+}
+
+/**
+ * Class destructor.
+ */
+SymbolDlg::~SymbolDlg()
+{
+ delete m_pCscope;
+}
+
+/**
+ * Displays the requested type of query in the type combo-box.
+ * @param nType The requested type
+ */
+void SymbolDlg::setType(uint nType)
+{
+ m_pTypeCombo->setCurrentItem(nType);
+ slotTypeChanged(nType);
+}
+
+/**
+ * @param sSymbol The initial text of the combo-box
+ */
+void SymbolDlg::setSymbol(const QString& sSymbol)
+{
+ m_pSymbolHC->setCurrentText(sSymbol);
+}
+
+/**
+ * @param slSymHistory A list of previously queried symbols
+ */
+void SymbolDlg::setHistory(QStringList& slSymHistory)
+{
+ m_pSymbolHC->setHistoryItems(slSymHistory);
+}
+
+/**
+ * @return The current text of the symbol combo-box
+ */
+QString SymbolDlg::getSymbol() const
+{
+ QString sResult;
+
+ sResult = m_pSymbolHC->currentText().stripWhiteSpace();
+ if (m_pSubStringCheck->isChecked())
+ sResult = ".*" + sResult + ".*";
+
+ return sResult;
+}
+
+/**
+ * @return The type of query requested by the user
+ * @note The returned value does not conform to the type used for running
+ * Cscope queries. Use getQueryType() to translate between these
+ * values.
+ */
+uint SymbolDlg::getType() const
+{
+ return m_pTypeCombo->currentItem();
+}
+
+bool SymbolDlg::getCase() const
+{
+ return !m_pCaseCheck->isChecked();
+}
+
+/**
+ * A convinience static function for creating and showing SymbolDlg dialogue.
+ * @param pParent The parent widget
+ * @param nType The type of query requested by the user (may be
+ * changed in the dialogue)
+ * @param sSymbol The initial text of the combo-box
+ * @return The text entered by the user in the symbol combo-box, or an empty
+ * string if the dialogue was cancelled
+ */
+QString SymbolDlg::promptSymbol(QWidget* pParent, uint& nType,
+ const QString& sSymbol, bool& bCase)
+{
+ SymbolDlg dlg(pParent);
+
+ // Initialise the dialogue
+ dlg.setType(nType);
+ dlg.setHistory(s_slHistory);
+ dlg.setSymbol(sSymbol);
+
+ // Display the dialogue
+ if (dlg.exec() != QDialog::Accepted)
+ return "";
+
+ // Return the text entered by the user
+ nType = dlg.getType();
+ bCase = dlg.getCase();
+ dlg.m_pSymbolHC->addToHistory(dlg.getSymbol());
+ s_slHistory = dlg.m_pSymbolHC->historyItems();
+ return dlg.getSymbol();
+}
+
+/**
+ * Translates a symbol dialogue type into a Cscope query type.
+ * @param nType The type to translate
+ * @return A query type matching the symbol dialogue type
+ */
+uint SymbolDlg::getQueryType(uint nType)
+{
+ if (nType == CallTree)
+ return CscopeFrontend::None;
+
+ if (nType <= Text)
+ return nType;
+
+ return nType + 1;
+}
+
+/**
+ * Runs a symbol definition query, looking for symbols starting with the
+ * currently entered text.
+ * If the hint list is not visible, it is shown first.
+ * This slot is connected to the clicked() signal of the "Hint" button.
+ */
+void SymbolDlg::slotHintClicked()
+{
+ QString sText, sRegExp;
+
+ // Show the hint list if necessary
+ if (!m_pHintList->isVisible()) {
+ m_pHintList->show();
+ ((QWidget*)m_pHintGroup)->show();
+ adjustSize();
+ }
+
+ // Clear the previous contents
+ m_pHintList->clear();
+
+ // Get the currently entered text (must have at least one character)
+ sText = m_pSymbolHC->currentText().stripWhiteSpace();
+ if (sText.isEmpty())
+ return;
+
+ // Create the regular expression
+ if (m_pBeginWithRadio->isOn())
+ sRegExp = sText + "[a-zA-Z0-9_]*";
+ else
+ sRegExp = "[a-zA-Z0-9_]*" + sText + "[a-zA-Z0-9_]*";
+
+ m_reHint.setPattern(sRegExp);
+
+ // Run a Cscope symbol definition query using a regular expression
+ m_pCscope->query(CscopeFrontend::Definition, sRegExp);
+}
+
+/**
+ * Called when a new record is ready to be added to the hint list.
+ * NOTE: Cscope 15.5 has a bug where the "function" field of the record
+ * displays the regular expression instead of the matched symbol name. For
+ * this reason, we need to extract the symbol from the "Text" field.
+ * @param pToken The head of the record's token list
+ */
+void SymbolDlg::slotHintDataReady(FrontendToken* pToken)
+{
+ QString sText;
+
+ // Get the line text
+ pToken = pToken->getNext()->getNext()->getNext();
+ sText = pToken->getData();
+
+ // Find the symbol within the line
+ if (m_reHint.search(sText) == -1)
+ return;
+
+ // Find the symbol within the list, if found - do not add
+ if (m_pHintList->findItem(m_reHint.capturedTexts().first(), 0))
+ return;
+
+ // Add a list item
+ (void)new QListViewItem(m_pHintList, m_reHint.capturedTexts().first());
+
+}
+
+/**
+ * Sets the text of a selected hint list item as the current text of the
+ * symbol combo-box.
+ * This slot is connected to the doubleClicked() signal of the hint list-view.
+ * @param pItem The clicked list item
+ */
+void SymbolDlg::slotHintItemSelected(QListViewItem* pItem)
+{
+ m_pSymbolHC->setCurrentText(pItem->text(0));
+}
+
+/**
+ * Refreshes the hint list based on the newly selected option.
+ * This slot is connected to the toggled() signal of the hint options radio
+ * buttons.
+ * NOTE: The list is only refreshed if the system profile is set to Fast.
+ * @param bOn true if the button was toggled on
+ */
+void SymbolDlg::slotHintOptionChanged(bool bOn)
+{
+ if (bOn && Config().getSysProfile() == KScopeConfig::Fast)
+ slotHintClicked();
+}
+
+/**
+ * Display a progress bar while the hint query is working.
+ * This slot is connected to the progress() signal emitted by the Cscope
+ * frontend object.
+ * @param nProgress Progress value
+ * @param nTotal The final expected value
+ */
+void SymbolDlg::slotHintProgress(int nProgress, int nTotal)
+{
+ m_progress.setProgress(nProgress, nTotal);
+}
+
+/**
+ * Destroys all progress information widget when the query process terminates.
+ * This slot is connected to the finished() signal emitted by the Cscope
+ * process.
+ */
+void SymbolDlg::slotHintFinished(uint /* ignored */)
+{
+ m_progress.finished();
+}
+
+/**
+ * Enables/disables the hint button, based on the newly selected type.
+ * This slot is connected to the activated() signal of the type combo-box.
+ * @param nType The newly selected type
+ */
+void SymbolDlg::slotTypeChanged(int nType)
+{
+ if (nType == FileName || nType == Including)
+ m_pHintButton->setEnabled(false);
+ else
+ m_pHintButton->setEnabled(true);
+}
+
+#include "symboldlg.moc"