File indexing completed on 2024-05-05 04:40:52

0001 /*
0002     SPDX-FileCopyrightText: 2007 David Nolden <david.nolden.kdevelop@art-master.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include "projectitemquickopen.h"
0008 
0009 #include <QIcon>
0010 
0011 #include <KLocalizedString>
0012 
0013 #include <interfaces/iprojectcontroller.h>
0014 #include <interfaces/idocumentcontroller.h>
0015 #include <interfaces/icore.h>
0016 
0017 #include <language/interfaces/iquickopen.h>
0018 
0019 #include <language/duchain/duchain.h>
0020 #include <language/duchain/duchainlock.h>
0021 #include <language/duchain/declaration.h>
0022 #include <language/duchain/types/functiontype.h>
0023 #include <language/duchain/functiondefinition.h>
0024 
0025 using namespace KDevelop;
0026 
0027 DUChainItemData::DUChainItemData(const DUChainItem& file, bool openDefinition)
0028     : m_item(file)
0029     , m_openDefinition(openDefinition)
0030 {
0031 }
0032 
0033 QString DUChainItemData::text() const
0034 {
0035     DUChainReadLocker lock;
0036     Declaration* decl = m_item.m_item.data();
0037     if (!decl) {
0038         return i18n("Not available any more: %1", m_item.m_text);
0039     }
0040 
0041     if (auto* def = dynamic_cast<FunctionDefinition*>(decl)) {
0042         if (def->declaration()) {
0043             decl = def->declaration();
0044         }
0045     }
0046 
0047     QString text = decl->qualifiedIdentifier().toString();
0048 
0049     if (!decl->abstractType()) {
0050         //With simplified representation, still mark functions as such by adding parens
0051         if (dynamic_cast<AbstractFunctionDeclaration*>(decl)) {
0052             text += QLatin1String("(...)");
0053         }
0054     } else if (TypePtr<FunctionType> function = decl->type<FunctionType>()) {
0055         text += function->partToString(FunctionType::SignatureArguments);
0056     }
0057 
0058     return text;
0059 }
0060 
0061 QList<QVariant> DUChainItemData::highlighting() const
0062 {
0063     DUChainReadLocker lock;
0064 
0065     Declaration* decl = m_item.m_item.data();
0066     if (!decl) {
0067         return QList<QVariant>();
0068     }
0069 
0070     if (auto* def = dynamic_cast<FunctionDefinition*>(decl)) {
0071         if (def->declaration()) {
0072             decl = def->declaration();
0073         }
0074     }
0075 
0076     QTextCharFormat boldFormat;
0077     boldFormat.setFontWeight(QFont::Bold);
0078     QTextCharFormat normalFormat;
0079 
0080     int prefixLength = 0;
0081 
0082     QString signature;
0083     TypePtr<FunctionType> function = decl->type<FunctionType>();
0084     if (function) {
0085         signature = function->partToString(FunctionType::SignatureArguments);
0086     }
0087 
0088     //Only highlight the last part of the qualified identifier, so the scope doesn't distract too much
0089     QualifiedIdentifier id = decl->qualifiedIdentifier();
0090     QString fullId = id.toString();
0091     QString lastId;
0092     if (!id.isEmpty()) {
0093         lastId = id.last().toString();
0094     }
0095 
0096     prefixLength += fullId.length() - lastId.length();
0097 
0098     QList<QVariant> ret{
0099         0,
0100         prefixLength,
0101         QVariant(normalFormat),
0102         prefixLength,
0103         lastId.length(),
0104         QVariant(boldFormat),
0105     };
0106     if (!signature.isEmpty()) {
0107         ret << prefixLength + lastId.length();
0108         ret << signature.length();
0109         ret << QVariant(normalFormat);
0110     }
0111 
0112     return ret;
0113 }
0114 
0115 QString DUChainItemData::htmlDescription() const
0116 {
0117     if (m_item.m_noHtmlDestription) {
0118         return QString();
0119     }
0120 
0121     DUChainReadLocker lock;
0122     Declaration* decl = m_item.m_item.data();
0123     if (!decl) {
0124         return i18n("Not available any more");
0125     }
0126 
0127     TypePtr<FunctionType> function = decl->type<FunctionType>();
0128 
0129     QString text;
0130 
0131     if (function && function->returnType()) {
0132         text = i18nc("%1: function signature", "Return: %1",
0133                      function->partToString(FunctionType::SignatureReturn)) + QLatin1Char(' ');
0134     }
0135 
0136     text += i18nc("%1: file path", "File: %1", ICore::self()->projectController()->prettyFileName(decl->url().toUrl()));
0137 
0138     QString ret = QLatin1String("<small><small>") + text + QLatin1String("</small></small>");
0139 
0140     return ret;
0141 }
0142 
0143 bool DUChainItemData::execute(QString& /*filterText*/)
0144 {
0145     DUChainReadLocker lock;
0146     Declaration* decl = m_item.m_item.data();
0147     if (!decl) {
0148         return false;
0149     }
0150 
0151     if (m_openDefinition && FunctionDefinition::definition(decl)) {
0152         decl = FunctionDefinition::definition(decl);
0153     }
0154 
0155     QUrl url = decl->url().toUrl();
0156     KTextEditor::Cursor cursor = decl->rangeInCurrentRevision().start();
0157 
0158     DUContext* internal = decl->internalContext();
0159 
0160     if (internal && (internal->type() == DUContext::Other || internal->type() == DUContext::Class)) {
0161         //Move into the body
0162         if (internal->range().end.line > internal->range().start.line) {
0163             cursor = KTextEditor::Cursor(internal->range().start.line + 1, 0); //Move into the body
0164         }
0165     }
0166 
0167     lock.unlock();
0168     ICore::self()->documentController()->openDocument(url, cursor);
0169     return true;
0170 }
0171 
0172 bool DUChainItemData::isExpandable() const
0173 {
0174     return true;
0175 }
0176 
0177 QWidget* DUChainItemData::expandingWidget() const
0178 {
0179     DUChainReadLocker lock;
0180 
0181     auto* decl = dynamic_cast<KDevelop::Declaration*>(m_item.m_item.data());
0182     if (!decl || !decl->context()) {
0183         return nullptr;
0184     }
0185 
0186     return decl->context()->createNavigationWidget(decl, decl->topContext(),
0187                                                    AbstractNavigationWidget::EmbeddableWidget);
0188 }
0189 
0190 QIcon DUChainItemData::icon() const
0191 {
0192     return QIcon();
0193 }
0194 
0195 Path DUChainItemData::projectPath() const
0196 {
0197     return m_item.m_projectPath;
0198 }
0199 
0200 DUChainItemDataProvider::DUChainItemDataProvider(IQuickOpen* quickopen, bool openDefinitions)
0201     : m_quickopen(quickopen)
0202     , m_openDefinitions(openDefinitions)
0203 {
0204     reset();
0205 }
0206 
0207 void DUChainItemDataProvider::setFilterText(const QString& text)
0208 {
0209     Base::setFilter(text);
0210 }
0211 
0212 uint DUChainItemDataProvider::itemCount() const
0213 {
0214     return Base::filteredItems().count();
0215 }
0216 
0217 uint DUChainItemDataProvider::unfilteredItemCount() const
0218 {
0219     return Base::items().count();
0220 }
0221 
0222 QuickOpenDataPointer DUChainItemDataProvider::data(uint row) const
0223 {
0224     return KDevelop::QuickOpenDataPointer(createData(Base::filteredItems()[row]));
0225 }
0226 
0227 DUChainItemData* DUChainItemDataProvider::createData(const DUChainItem& item) const
0228 {
0229     return new DUChainItemData(item, m_openDefinitions);
0230 }
0231 
0232 QString DUChainItemDataProvider::itemText(const DUChainItem& data) const
0233 {
0234     return data.m_text;
0235 }
0236 
0237 void DUChainItemDataProvider::reset()
0238 {
0239 }
0240 
0241 #include "moc_duchainitemquickopen.cpp"