/*************************************************************************** * * 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 #include #include #include #include #include #include #include #include "symboldlg.h" #include "cscopefrontend.h" #include "kscopeconfig.h" TQStringList SymbolDlg::s_slHistory; /** * Class constructor. * @param pParent Parent widget * @param szName This widget's name */ SymbolDlg::SymbolDlg(TQWidget* 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(); ((TQWidget*)m_pHintGroup)->hide(); m_pBeginWithRadio->toggle(); adjustSize(); // Close the dialogue when either the "OK" or "Cancel" button are clicked connect(m_pOKButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(accept())); connect(m_pCancelButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(reject())); // Run a symbol completion query when the "Hint" button is clicked connect(m_pHintButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotHintClicked())); // Add results to the hint list connect(m_pCscope, TQ_SIGNAL(dataReady(FrontendToken*)), this, TQ_SLOT(slotHintDataReady(FrontendToken*))); // Set hint button availability based on the type of query connect(m_pTypeCombo, TQ_SIGNAL(activated(int)), this, TQ_SLOT(slotTypeChanged(int))); // Selecting an item in the hint list sets it as the current text connect(m_pHintList, TQ_SIGNAL(selectionChanged(TQListViewItem*)), this, TQ_SLOT(slotHintItemSelected(TQListViewItem*))); // 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, TQ_SIGNAL(doubleClicked(TQListViewItem*)), this, TQ_SLOT(accept())); // Refresh the hint list when the hint options change connect(m_pBeginWithRadio, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(slotHintOptionChanged(bool))); connect(m_pContainRadio, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(slotHintOptionChanged(bool))); // Show hint query progress information connect(m_pCscope, TQ_SIGNAL(progress(int, int)), this, TQ_SLOT(slotHintProgress(int, int))); connect(m_pCscope, TQ_SIGNAL(finished(uint)), this, TQ_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 TQString& sSymbol) { m_pSymbolHC->setCurrentText(sSymbol); } /** * @param slSymHistory A list of previously queried symbols */ void SymbolDlg::setHistory(TQStringList& slSymHistory) { m_pSymbolHC->setHistoryItems(slSymHistory); } /** * @return The current text of the symbol combo-box */ TQString SymbolDlg::getSymbol() const { TQString 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 */ TQString SymbolDlg::promptSymbol(TQWidget* pParent, uint& nType, const TQString& 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() != TQDialog::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() { TQString sText, sRegExp; // Show the hint list if necessary if (!m_pHintList->isVisible()) { m_pHintList->show(); ((TQWidget*)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) { TQString 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 TQListViewItem(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(TQListViewItem* 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"