• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdevelop API Reference
  • KDE Home
  • Contact Us
 

kdevplatform/language/duchain

  • sources
  • kfour-appscomplete
  • kdevelop
  • kdevplatform
  • language
  • duchain
  • navigation
problemnavigationcontext.cpp
Go to the documentation of this file.
1 /*
2  Copyright 2009 David Nolden <[email protected]>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License version 2 as published by the Free Software Foundation.
7 
8  This library is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  Library General Public License for more details.
12 
13  You should have received a copy of the GNU Library General Public License
14  along with this library; see the file COPYING.LIB. If not, write to
15  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  Boston, MA 02110-1301, USA.
17  */
18 
19 #include "problemnavigationcontext.h"
20 
21 #include <debug.h>
22 
23 #include <QBuffer>
24 #include <QStyle>
25 #include <QApplication>
26 
27 #include <KLocalizedString>
28 
29 #include <language/duchain/declaration.h>
30 #include <language/duchain/duchainlock.h>
31 #include <language/duchain/duchainutils.h>
32 #include <language/duchain/problem.h>
33 
34 #include <language/duchain/duchain.h>
35 #include <language/editor/documentrange.h>
36 
37 using namespace KDevelop;
38 
39 namespace {
40 QString KEY_INVOKE_ACTION(int num) { return QStringLiteral("invoke_action_%1").arg(num); }
41 
42 QString htmlImg(const QIcon& icon, QStyle::PixelMetric metric)
43 {
44  const int size = qApp->style()->pixelMetric(metric, nullptr, nullptr);
45  const QPixmap pixmap = icon.pixmap(size, size);
46  QByteArray pngBytes;
47  QBuffer buffer(&pngBytes);
48  buffer.open(QIODevice::WriteOnly);
49  pixmap.save(&buffer, "PNG", 100);
50 
51  const QString imgTag = QStringLiteral("<img width='%1' height='%1' src='data:image/png;base64, %2'/>")
52  .arg(size)
53  .arg(QString::fromLatin1(pngBytes.toBase64()));
54  return imgTag;
55 }
56 }
57 
58 ProblemNavigationContext::ProblemNavigationContext(const QVector<IProblem::Ptr>& problems, const Flags flags)
59  : m_problems(problems)
60  , m_flags(flags)
61  , m_widget(nullptr)
62 {
63  // Sort problems vector:
64  // 1) By severity
65  // 2) By sourceString, if severities are equals
66  std::sort(m_problems.begin(), m_problems.end(), [](const IProblem::Ptr& a, const IProblem::Ptr& b) {
67  if (a->severity() < b->severity())
68  return true;
69 
70  if (a->severity() > b->severity())
71  return false;
72 
73  if (a->sourceString() < b->sourceString())
74  return true;
75 
76  return false;
77  });
78 }
79 
80 ProblemNavigationContext::~ProblemNavigationContext()
81 {
82  delete m_widget;
83 }
84 
85 QWidget* ProblemNavigationContext::widget() const
86 {
87  return m_widget;
88 }
89 
90 bool ProblemNavigationContext::isWidgetMaximized() const
91 {
92  return false;
93 }
94 
95 QString ProblemNavigationContext::name() const
96 {
97  return i18n("Problem");
98 }
99 
100 QString ProblemNavigationContext::escapedHtml(const QString& text) const
101 {
102  const QString htmlStart = QStringLiteral("<html>");
103  const QString htmlEnd = QStringLiteral("</html>");
104 
105  QString result = text.trimmed();
106 
107  if (!result.startsWith(htmlStart))
108  return result.toHtmlEscaped();
109 
110  result.remove(htmlStart);
111  result.remove(htmlEnd);
112 
113  return result;
114 }
115 
116 void ProblemNavigationContext::html(IProblem::Ptr problem)
117 {
118  modifyHtml() += QStringLiteral("<table><tr>");
119 
120  modifyHtml() += QStringLiteral("<td valign=\"middle\">%1</td>")
121  .arg(htmlImg(IProblem::iconForSeverity(problem->severity()), QStyle::PM_LargeIconSize));
122 
123  // BEGIN: right column
124  modifyHtml() += QStringLiteral("<td>");
125 
126  modifyHtml() += i18n("Problem in <i>%1</i>", problem->sourceString());
127  modifyHtml() += QStringLiteral("<br/>");
128 
129  if (m_flags & ShowLocation) {
130  modifyHtml() += labelHighlight(i18n("Location: "));
131  makeLink(QStringLiteral("%1 :%2")
132  .arg(problem->finalLocation().document.toUrl().fileName())
133  .arg(problem->finalLocation().start().line() + 1),
134  QString(),
135  NavigationAction(problem->finalLocation().document.toUrl(), problem->finalLocation().start())
136  );
137 
138  modifyHtml() += QStringLiteral("<br/>");
139  }
140 
141  QString description = escapedHtml(problem->description());
142  QString explanation = escapedHtml(problem->explanation());
143 
144  modifyHtml() += description;
145 
146  // Add only non-empty explanation which differs from the problem description.
147  // Skip this if we have more than one problem.
148  if (m_problems.size() == 1 && !explanation.isEmpty() && explanation != description)
149  modifyHtml() += QLatin1String("<p><i style=\"white-space:pre-wrap\">") + explanation +
150  QLatin1String("</i></p>");
151 
152  modifyHtml() += QStringLiteral("</td>");
153  // END: right column
154 
155  modifyHtml() += QStringLiteral("</tr></table>");
156 
157  const auto diagnostics = problem->diagnostics();
158  if (!diagnostics.isEmpty()) {
159  DUChainReadLocker lock;
160  for (auto diagnostic : diagnostics) {
161  modifyHtml() += QStringLiteral("<p>");
162  modifyHtml() += labelHighlight(QStringLiteral("%1: ").arg(diagnostic->severityString()));
163  modifyHtml() += escapedHtml(diagnostic->description());
164 
165  const DocumentRange range = diagnostic->finalLocation();
166  Declaration* declaration = DUChainUtils::itemUnderCursor(range.document.toUrl(), range.start()).declaration;
167  if (declaration) {
168  modifyHtml() += i18n("<br>See: ");
169  makeLink(declaration->toString(), DeclarationPointer(declaration),
170  NavigationAction::NavigateDeclaration);
171  modifyHtml() += i18n(" in ");
172  const auto url = declaration->url().toUrl();
173  makeLink(QStringLiteral("%1 :%2")
174  .arg(url.fileName())
175  .arg(declaration->rangeInCurrentRevision().start().line() + 1),
176  url.toDisplayString(QUrl::PreferLocalFile), NavigationAction(url, declaration->rangeInCurrentRevision().start()));
177  } else if (range.start().isValid()) {
178  modifyHtml() += i18n("<br>See: ");
179  const auto url = range.document.toUrl();
180  makeLink(QStringLiteral("%1 :%2")
181  .arg(url.fileName())
182  .arg(range.start().line() + 1),
183  url.toDisplayString(QUrl::PreferLocalFile), NavigationAction(url, range.start()));
184  }
185 
186  modifyHtml() += QStringLiteral("</p>");
187  }
188  }
189 
190  auto assistant = problem->solutionAssistant();
191  if (assistant && !assistant->actions().isEmpty()) {
192  modifyHtml() +=
193  QStringLiteral("<table width='100%' style='border: 1px solid black; background-color: %1;'>").arg(QStringLiteral(
194  "#b3d4ff"));
195  modifyHtml() +=
196  QStringLiteral("<tr><td valign='middle'>%1</td><td width='100%'>")
197  .arg(htmlImg(QIcon::fromTheme(QStringLiteral("dialog-ok-apply")), QStyle::PM_LargeIconSize));
198 
199  const int startIndex = m_assistantsActions.size();
200  int currentIndex = startIndex;
201  const auto assistantActions = assistant->actions();
202  for (auto& assistantAction : assistantActions) {
203  m_assistantsActions.append(assistantAction);
204 
205  if (currentIndex != startIndex)
206  modifyHtml() += QStringLiteral("<br/>");
207 
208  makeLink(i18n("Solution (%1)", currentIndex + 1), KEY_INVOKE_ACTION(currentIndex),
209  NavigationAction(KEY_INVOKE_ACTION(currentIndex)));
210  modifyHtml() += QLatin1String(": ") + assistantAction->description().toHtmlEscaped();
211 
212  ++currentIndex;
213  }
214 
215  modifyHtml() += QStringLiteral("</td></tr>");
216  modifyHtml() += QStringLiteral("</table>");
217  }
218 }
219 
220 QString ProblemNavigationContext::html(bool shorten)
221 {
222  AbstractNavigationContext::html(shorten);
223 
224  clear();
225  m_assistantsActions.clear();
226 
227  int problemIndex = 0;
228  for (auto& problem : qAsConst(m_problems)) {
229  html(problem);
230 
231  if (++problemIndex != m_problems.size())
232  modifyHtml() += QStringLiteral("<hr>");
233  }
234 
235  return currentHtml();
236 }
237 
238 NavigationContextPointer ProblemNavigationContext::executeKeyAction(const QString& key)
239 {
240  const QLatin1String invokeActionPrefix("invoke_action_");
241  if (key.startsWith(invokeActionPrefix)) {
242  const int index = key.midRef(invokeActionPrefix.size()).toInt();
243  executeAction(index);
244  }
245 
246  return {};
247 }
248 
249 void ProblemNavigationContext::executeAction(int index)
250 {
251  if (index < 0 || index >= m_assistantsActions.size())
252  return;
253 
254  auto action = m_assistantsActions.at(index);
255  Q_ASSERT(action);
256 
257  if (action) {
258  action->execute();
259  if (topContext())
260  DUChain::self()->updateContextForUrl(topContext()->url(), TopDUContext::ForceUpdate);
261  } else {
262  qCWarning(LANGUAGE()) << "No such action";
263  return;
264  }
265 }
KDevelop::DUChainUtils::itemUnderCursor
KDEVPLATFORMLANGUAGE_EXPORT ItemUnderCursor itemUnderCursor(const QUrl &url, const KTextEditor::Cursor &cursor)
Returns 1.
Definition: duchainutils.cpp:332
duchainlock.h
KDevelop::ProblemNavigationContext::isWidgetMaximized
bool isWidgetMaximized() const override
Whether the widget returned by widget() should take the maximum possible spsace.
Definition: problemnavigationcontext.cpp:90
KDevelop::DUChainReadLocker
Customized read locker for the definition-use chain.
Definition: duchainlock.h:114
KDevelop::AbstractNavigationContext::currentHtml
QString currentHtml() const
Returns the html text being built in its current state.
Definition: abstractnavigationcontext.cpp:587
duchainutils.h
QVector::begin
iterator begin()
KDevelop::AbstractNavigationContext::labelHighlight
static const Colorizer labelHighlight
Definition: abstractnavigationcontext.h:164
problemnavigationcontext.h
QString::midRef
QStringRef midRef(int position, int n) const
KDevelop::DUChain::updateContextForUrl
void updateContextForUrl(const IndexedString &document, TopDUContext::Features minFeatures, QObject *notifyReady=nullptr, int priority=1) const
Makes sure the standard-context for the given url is up-to-date.
Definition: duchain.cpp:1839
QString::trimmed
QString trimmed() const
QVector::append
void append(const T &value)
QWidget
QIcon::fromTheme
QIcon fromTheme(const QString &name, const QIcon &fallback)
KDevelop::m_problems
KDEVPLATFORMLANGUAGE_EXPORT m_problems
Definition: topducontextdata.h:49
m_flags
DUContext::SearchFlags m_flags
Definition: ducontext.cpp:615
KDevelop::Declaration::toString
virtual QString toString() const
Determine this declaration as a string.
Definition: declaration.cpp:466
KDevelop::ProblemNavigationContext::widget
QWidget * widget() const override
Here the context can return a widget to be displayed.
Definition: problemnavigationcontext.cpp:85
KDevelop::Declaration
Represents a single declaration in a definition-use chain.
Definition: declaration.h:51
problem.h
QExplicitlySharedDataPointer< AbstractNavigationContext >
KDevelop::ProblemNavigationContext::html
QString html(bool shorten=false) override
Here the context can return html to be displayed.
Definition: problemnavigationcontext.cpp:220
KDevelop::ProblemNavigationContext::ProblemNavigationContext
ProblemNavigationContext(const QVector< IProblem::Ptr > &problems, const Flags flags={})
Definition: problemnavigationcontext.cpp:58
QPixmap
QBuffer
KDevelop::AbstractNavigationContext::makeLink
virtual void makeLink(const QString &name, const DeclarationPointer &declaration, NavigationAction::Type actionType)
Creates and registers a link to the given declaration, labeled by the given name.
Definition: abstractnavigationcontext.cpp:93
QVector::clear
void clear()
declaration.h
KDevelop::NavigationAction
Definition: navigationaction.h:31
KDevelop::DUChainBase::url
virtual IndexedString url() const
Definition: duchainbase.cpp:68
QString
QVector::at
const T & at(int i) const
QPixmap::save
bool save(const QString &fileName, const char *format, int quality) const
KDevelop::AbstractNavigationContext::clear
void clear()
Definition: abstractnavigationcontext.cpp:146
KDevelop::AbstractNavigationContext::modifyHtml
TextHandler modifyHtml()
Returns a convenience object that allows writing "modifyHtml() += "Hallo";".
Definition: abstractnavigationcontext.h:139
KDevelop::ProblemNavigationContext::executeKeyAction
NavigationContextPointer executeKeyAction(const QString &key) override
Override this to execute own key-actions using NavigationAction.
Definition: problemnavigationcontext.cpp:238
QIcon
QLatin1String
KDevelop::ProblemNavigationContext::ShowLocation
Definition: problemnavigationcontext.h:39
KDevelop::DUChainBase::rangeInCurrentRevision
KTextEditor::Range rangeInCurrentRevision() const
Returns the range assigned to this object, transformed into the current revision of the document.
Definition: duchainbase.cpp:157
QString::remove
QString & remove(int position, int n)
KDevelop::AbstractNavigationContext::html
virtual QString html(bool shorten=false)
Here the context can return html to be displayed.
Definition: abstractnavigationcontext.cpp:530
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
KDevelop::NavigationAction::NavigateDeclaration
Definition: navigationaction.h:35
KDevelop::AbstractNavigationContext::topContext
TopDUContextPointer topContext() const
Definition: abstractnavigationcontext.cpp:69
QVector::end
iterator end()
KDevelop::ProblemNavigationContext::~ProblemNavigationContext
~ProblemNavigationContext() override
Definition: problemnavigationcontext.cpp:80
QIcon::pixmap
QPixmap pixmap(const QSize &size, Mode mode, State state) const
QString::fromLatin1
QString fromLatin1(const char *str, int size)
duchain.h
QByteArray::toBase64
QByteArray toBase64() const
KDevelop
Definition: abstractfunctiondeclaration.cpp:27
QVector::size
int size() const
KDevelop::TopDUContext::ForceUpdate
Definition: topducontext.h:204
KDevelop::ProblemNavigationContext::executeAction
void executeAction(int index)
Definition: problemnavigationcontext.cpp:249
KDevelop::ProblemNavigationContext::name
QString name() const override
Definition: problemnavigationcontext.cpp:95
QVector< IProblem::Ptr >
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
KDevelop::DeclarationPointer
DUChainPointer< Declaration > DeclarationPointer
Definition: duchainpointer.h:200
QByteArray
KDevelop::DUChain::self
static DUChain * self()
Returns the global static instance.
Definition: duchain.cpp:1230
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Mar 8 2021 23:29:50 by doxygen 1.8.16 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kdevplatform/language/duchain

Skip menu "kdevplatform/language/duchain"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdevelop API Reference

Skip menu "kdevelop API Reference"
  • kdevplatform
  •   debugger
  •   documentation
  •   interfaces
  •   language
  •     assistant
  •     backgroundparser
  •     checks
  •     classmodel
  •     codecompletion
  •     codegen
  •     duchain
  •     editor
  •     highlighting
  •     interfaces
  •     util
  •   outputview
  •   project
  •   serialization
  •   shell
  •   sublime
  •   tests
  •   util
  •   vcs

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal