• 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
useswidget.cpp
Go to the documentation of this file.
1 /*
2  Copyright 2008 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 "useswidget.h"
20 #include <debug.h>
21 
22 #include <QIcon>
23 #include <QLabel>
24 #include <QProgressBar>
25 #include <QResizeEvent>
26 #include <QToolButton>
27 #include <QVBoxLayout>
28 
29 #include <KLocalizedString>
30 
31 #include <language/duchain/duchainlock.h>
32 #include <language/duchain/duchain.h>
33 #include <language/duchain/uses.h>
34 #include <language/duchain/declaration.h>
35 #include <language/duchain/use.h>
36 #include <interfaces/icore.h>
37 #include <interfaces/idocumentcontroller.h>
38 #include <interfaces/iprojectcontroller.h>
39 
40 #include <language/duchain/duchainutils.h>
41 #include <language/codegen/coderepresentation.h>
42 #include <interfaces/iproject.h>
43 #include <util/foregroundlock.h>
44 
45 using namespace KDevelop;
46 
47 namespace {
48 QString backgroundColor(bool isHighlighted)
49 {
50  if (isHighlighted) {
51  return QColor(251, 150, 242).name();
52  } else {
53  return QColor(251, 250, 150).name();
54  }
55 }
56 }
57 
58 const int tooltipContextSize = 2; //How many lines around the use are shown in the tooltip
59 
63 QString highlightAndEscapeUseText(QString line, int cutOff, KTextEditor::Range range)
64 {
65  int leftCutRoom = range.start().column();
66  int rightCutRoom = line.length() - range.end().column();
67 
68  if (range.start().column() < 0 || range.end().column() > line.length() || cutOff > leftCutRoom + rightCutRoom)
69  return QString(); //Not enough room for cutting off on sides
70 
71  int leftCut = 0;
72  int rightCut = 0;
73 
74  if (leftCutRoom < rightCutRoom) {
75  if (leftCutRoom * 2 >= cutOff) {
76  //Enough room on both sides. Just cut.
77  leftCut = cutOff / 2;
78  rightCut = cutOff - leftCut;
79  } else {
80  //Not enough room in left side, but enough room all together
81  leftCut = leftCutRoom;
82  rightCut = cutOff - leftCut;
83  }
84  } else {
85  if (rightCutRoom * 2 >= cutOff) {
86  //Enough room on both sides. Just cut.
87  rightCut = cutOff / 2;
88  leftCut = cutOff - rightCut;
89  } else {
90  //Not enough room in right side, but enough room all together
91  rightCut = rightCutRoom;
92  leftCut = cutOff - rightCut;
93  }
94  }
95  Q_ASSERT(leftCut + rightCut <= cutOff);
96 
97  line.chop(rightCut);
98  line.remove(0, leftCut);
99  range += KTextEditor::Range(0, -leftCut, 0, -leftCut);
100 
101  Q_ASSERT(range.start().column() >= 0 && range.end().column() <= line.length());
102 
103  //TODO: share code with context browser
104  // mixing (255, 255, 0, 100) with white yields this:
105  const QColor foreground(0, 0, 0);
106 
107  return QLatin1String("<code>") + line.left(range.start().column()).toHtmlEscaped()
108  + QLatin1String("<span style=\"background-color:") + backgroundColor(false) + QLatin1String(";color:") +
109  foreground.name() + QLatin1String(";\">")
110  + line.mid(range.start().column(), range.end().column() - range.start().column()).toHtmlEscaped()
111  + QLatin1String("</span>") +
112  line.mid(range.end().column(), line.length() - range.end().column()).toHtmlEscaped() + QLatin1String(
113  "</code>");
114 }
115 
120 OneUseWidget::OneUseWidget(IndexedDeclaration declaration, const IndexedString& document, KTextEditor::Range range,
121  const CodeRepresentation& code) : m_range(new PersistentMovingRange(range, document))
122  , m_declaration(declaration)
123  , m_document(document)
124 {
125  //Make the sizing of this widget independent of the content, because we will adapt the content to the size
126  setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
127 
128  m_sourceLine = code.line(m_range->range().start().line());
129 
130  m_layout = new QHBoxLayout(this);
131  m_layout->setContentsMargins(0, 0, 0, 0);
132  setLayout(m_layout);
133 
134  setCursor(Qt::PointingHandCursor);
135 
136  m_label = new QLabel(this);
137  m_icon = new QLabel(this);
138  m_icon->setPixmap(QIcon::fromTheme(QStringLiteral("code-function")).pixmap(16));
139 
140  DUChainReadLocker lock(DUChain::lock());
141  QString text = QLatin1String("<a>") + i18nc("refers to a line in source code", "Line <b>%1</b>:",
142  range.start().line()) + QLatin1String("</a>");
143  if (!m_sourceLine.isEmpty() && m_sourceLine.length() > m_range->range().end().column()) {
144  text += QLatin1String("&nbsp;&nbsp;") + highlightAndEscapeUseText(m_sourceLine, 0, m_range->range());
145 
146  //Useful tooltip:
147  int start = m_range->range().start().line() - tooltipContextSize;
148  int end = m_range->range().end().line() + tooltipContextSize + 1;
149 
150  QStringList toolTipLines;
151  for (int a = start; a < end; ++a) {
152  QString lineText = code.line(a).toHtmlEscaped();
153  if (m_range->range().start().line() <= a && m_range->range().end().line() >= a) {
154  lineText = QLatin1String("<b>") + lineText + QLatin1String("</b>");
155  }
156  if (!lineText.trimmed().isEmpty()) {
157  toolTipLines.append(lineText);
158  }
159  }
160 
161  setToolTip(QLatin1String("<html><body><pre>") + toolTipLines.join(QLatin1String("<br>")) +
162  QLatin1String("</pre></body></html>"));
163  }
164  m_label->setText(text);
165 
166  m_layout->addWidget(m_icon);
167  m_layout->addWidget(m_label);
168  m_layout->setAlignment(Qt::AlignLeft);
169 }
170 
171 void OneUseWidget::setHighlighted(bool highlight)
172 {
173  if (highlight == m_isHighlighted) {
174  return;
175  }
176 
177  if (highlight) {
178  m_label->setText(m_label->text().replace(QLatin1String("background-color:") + backgroundColor(false),
179  QLatin1String("background-color:") + backgroundColor(true)));
180  m_isHighlighted = true;
181  } else {
182  m_label->setText(m_label->text().replace(QLatin1String("background-color:") + backgroundColor(true),
183  QLatin1String("background-color:") + backgroundColor(false)));
184  m_isHighlighted = false;
185  }
186 }
187 
188 bool KDevelop::OneUseWidget::isHighlighted() const
189 {
190  return m_isHighlighted;
191 }
192 
193 void OneUseWidget::activateLink()
194 {
195  ICore::self()->documentController()->openDocument(m_document.toUrl(), m_range->range().start());
196 }
197 
198 void OneUseWidget::mousePressEvent(QMouseEvent* event)
199 {
200  if (event->button() == Qt::LeftButton && !event->modifiers()) {
201  activateLink();
202  event->accept();
203  }
204 }
205 
206 OneUseWidget::~OneUseWidget()
207 {
208 }
209 
210 void OneUseWidget::resizeEvent(QResizeEvent* event)
211 {
213  QSize size = event->size();
214 
215  KTextEditor::Range range = m_range->range();
216 
217  int cutOff = 0;
218  int maxCutOff = m_sourceLine.length() - (range.end().column() - range.start().column());
219 
220  //Reset so we also get more context while up-sizing
221  m_label->setText(QLatin1String("<a>") +
222  i18nc("Refers to a line in source code", "Line <b>%1</b>:", range.start().line() + 1)
223  + QLatin1String("</a> ") + highlightAndEscapeUseText(m_sourceLine, cutOff, range));
224 
226  while (sizeHint().width() > size.width() && cutOff < maxCutOff) {
227  //We've got to save space
228  m_label->setText(QLatin1String("<a>") +
229  i18nc("Refers to a line in source code", "Line <b>%1</b>:", range.start().line() + 1)
230  + QLatin1String("</a> ") + highlightAndEscapeUseText(m_sourceLine, cutOff, range));
231  cutOff += 5;
232  }
233 
234  event->accept();
235 
236  QWidget::resizeEvent(event);
237 }
238 
239 void NavigatableWidgetList::setShowHeader(bool show)
240 {
241  if (show && !m_headerLayout->parent())
242  m_layout->insertLayout(0, m_headerLayout);
243  else
244  m_headerLayout->setParent(nullptr);
245 }
246 
247 NavigatableWidgetList::~NavigatableWidgetList()
248 {
249  delete m_headerLayout;
250 }
251 
252 NavigatableWidgetList::NavigatableWidgetList(bool allowScrolling, uint maxHeight, bool vertical)
253  : m_allowScrolling(allowScrolling)
254 {
255  m_layout = new QVBoxLayout;
256  m_layout->setContentsMargins(0, 0, 0, 0);
257  m_layout->setSizeConstraint(QLayout::SetMinAndMaxSize);
258  m_layout->setSpacing(0);
259  setBackgroundRole(QPalette::Base);
260  m_useArrows = false;
261 
262  if (vertical)
263  m_itemLayout = new QVBoxLayout;
264  else
265  m_itemLayout = new QHBoxLayout;
266  m_itemLayout->setContentsMargins(0, 0, 0, 0);
267 
268  m_itemLayout->setContentsMargins(0, 0, 0, 0);
269  m_itemLayout->setSpacing(0);
270 // m_layout->setSizeConstraint(QLayout::SetMinAndMaxSize);
271 // setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Maximum);
272  setWidgetResizable(true);
273 
274  m_headerLayout = new QHBoxLayout;
275  m_headerLayout->setContentsMargins(0, 0, 0, 0);
276  m_headerLayout->setSpacing(0);
277 
278  if (m_useArrows) {
279  auto previousButton = new QToolButton();
280  previousButton->setIcon(QIcon::fromTheme(QStringLiteral("go-previous")));
281 
282  auto nextButton = new QToolButton();
283  nextButton->setIcon(QIcon::fromTheme(QStringLiteral("go-next")));
284 
285  m_headerLayout->addWidget(previousButton);
286  m_headerLayout->addWidget(nextButton);
287  }
288 
289  //hide these buttons for now, they're senseless
290 
291  m_layout->addLayout(m_headerLayout);
292 
293  auto* spaceLayout = new QHBoxLayout;
294  spaceLayout->addSpacing(10);
295  spaceLayout->addLayout(m_itemLayout);
296 
297  m_layout->addLayout(spaceLayout);
298 
299  if (maxHeight)
300  setMaximumHeight(maxHeight);
301 
302  if (m_allowScrolling) {
303  auto* contentsWidget = new QWidget;
304  contentsWidget->setLayout(m_layout);
305  setWidget(contentsWidget);
306  } else {
307  setLayout(m_layout);
308  }
309 }
310 
311 void NavigatableWidgetList::deleteItems()
312 {
313  const auto items = this->items();
314  qDeleteAll(items);
315 }
316 
317 void NavigatableWidgetList::addItem(QWidget* widget, int pos)
318 {
319  if (pos == -1)
320  m_itemLayout->addWidget(widget);
321  else
322  m_itemLayout->insertWidget(pos, widget);
323 }
324 
325 QList<QWidget*> NavigatableWidgetList::items() const
326 {
327  QList<QWidget*> ret;
328  for (int a = 0; a < m_itemLayout->count(); ++a) {
329  auto* widgetItem = dynamic_cast<QWidgetItem*>(m_itemLayout->itemAt(a));
330  if (widgetItem) {
331  ret << widgetItem->widget();
332  }
333  }
334 
335  return ret;
336 }
337 
338 bool NavigatableWidgetList::hasItems() const
339 {
340  return ( bool )m_itemLayout->count();
341 }
342 
343 void NavigatableWidgetList::addHeaderItem(QWidget* widget, Qt::Alignment alignment)
344 {
345  if (m_useArrows) {
346  Q_ASSERT(m_headerLayout->count() >= 2); //At least the 2 back/next buttons
347  m_headerLayout->insertWidget(m_headerLayout->count() - 1, widget, alignment);
348  } else {
349  //We need to do this so the header doesn't get stretched
350  widget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
351  m_headerLayout->insertWidget(m_headerLayout->count(), widget, alignment);
352 // widget->setMaximumHeight(20);
353  }
354 }
355 
357 bool isNewGroup(DUContext* parent, DUContext* child)
358 {
359  if (parent->type() == DUContext::Other && child->type() == DUContext::Other)
360  return false;
361  else
362  return true;
363 }
364 
365 uint countUses(int usedDeclarationIndex, DUContext* context)
366 {
367  uint ret = 0;
368 
369  for (int useIndex = 0; useIndex < context->usesCount(); ++useIndex)
370  if (context->uses()[useIndex].m_declarationIndex == usedDeclarationIndex)
371  ++ret;
372 
373  const auto childContexts = context->childContexts();
374  for (DUContext* child : childContexts) {
375  if (!isNewGroup(context, child))
376  ret += countUses(usedDeclarationIndex, child);
377  }
378 
379  return ret;
380 }
381 
382 QList<OneUseWidget*> createUseWidgets(const CodeRepresentation& code, int usedDeclarationIndex, IndexedDeclaration decl,
383  DUContext* context)
384 {
385  QList<OneUseWidget*> ret;
386  VERIFY_FOREGROUND_LOCKED
387 
388  for (int useIndex = 0; useIndex < context->usesCount(); ++useIndex)
389  if (context->uses()[useIndex].m_declarationIndex == usedDeclarationIndex)
390  ret <<
391  new OneUseWidget(decl, context->url(), context->transformFromLocalRevision(
392  context->uses()[useIndex].m_range), code);
393 
394  const auto childContexts = context->childContexts();
395  for (DUContext* child : childContexts) {
396  if (!isNewGroup(context, child))
397  ret += createUseWidgets(code, usedDeclarationIndex, decl, child);
398  }
399 
400  return ret;
401 }
402 
403 ContextUsesWidget::ContextUsesWidget(const CodeRepresentation& code, const QList<IndexedDeclaration>& usedDeclarations,
404  IndexedDUContext context) : m_context(context)
405 {
406  setFrameShape(NoFrame);
407 
408  DUChainReadLocker lock(DUChain::lock());
409  QString headerText = i18n("Unknown context");
410  setUpdatesEnabled(false);
411 
412  if (context.data()) {
413  DUContext* ctx = context.data();
414 
415  if (ctx->scopeIdentifier(true).isEmpty())
416  headerText = i18n("Global");
417  else {
418  headerText = ctx->scopeIdentifier(true).toString();
419  if (ctx->type() == DUContext::Function || (ctx->owner() && ctx->owner()->isFunctionDeclaration()))
420  headerText += QLatin1String("(...)");
421  }
422 
423  QSet<int> hadIndices;
424 
425  for (const IndexedDeclaration usedDeclaration : usedDeclarations) {
426  int usedDeclarationIndex = ctx->topContext()->indexForUsedDeclaration(usedDeclaration.data(), false);
427  if (hadIndices.contains(usedDeclarationIndex))
428  continue;
429 
430  hadIndices.insert(usedDeclarationIndex);
431 
432  if (usedDeclarationIndex != std::numeric_limits<int>::max()) {
433  const auto useWidgets = createUseWidgets(code, usedDeclarationIndex, usedDeclaration, ctx);
434  for (OneUseWidget* widget : useWidgets) {
435  addItem(widget);
436  }
437  }
438  }
439  }
440 
441  auto* headerLabel = new QLabel(i18nc("%1: source file", "In %1", QLatin1String("<a href='navigateToFunction'>")
442  + headerText.toHtmlEscaped() + QLatin1String("</a>: ")));
443  addHeaderItem(headerLabel);
444  setUpdatesEnabled(true);
445  connect(headerLabel, &QLabel::linkActivated, this, &ContextUsesWidget::linkWasActivated);
446 }
447 
448 void ContextUsesWidget::linkWasActivated(const QString& link)
449 {
450  if (link == QLatin1String("navigateToFunction")) {
451  DUChainReadLocker lock(DUChain::lock());
452  DUContext* context = m_context.context();
453  if (context) {
454  CursorInRevision contextStart = context->range().start;
455  KTextEditor::Cursor cursor(contextStart.line, contextStart.column);
456  QUrl url = context->url().toUrl();
457  lock.unlock();
458  ForegroundLock fgLock;
459  ICore::self()->documentController()->openDocument(url, cursor);
460  }
461  }
462 }
463 
464 DeclarationWidget::DeclarationWidget(const CodeRepresentation& code, const IndexedDeclaration& decl)
465 {
466  setFrameShape(NoFrame);
467  DUChainReadLocker lock(DUChain::lock());
468 
469  setUpdatesEnabled(false);
470  if (Declaration* dec = decl.data()) {
471  auto* headerLabel = new QLabel(dec->isDefinition() ? i18n("Definition") : i18n("Declaration"));
472  addHeaderItem(headerLabel);
473  addItem(new OneUseWidget(decl, dec->url(), dec->rangeInCurrentRevision(), code));
474  }
475 
476  setUpdatesEnabled(true);
477 }
478 
479 TopContextUsesWidget::TopContextUsesWidget(IndexedDeclaration declaration,
480  const QList<IndexedDeclaration>& allDeclarations,
481  IndexedTopDUContext topContext)
482  : m_topContext(topContext)
483  , m_declaration(declaration)
484  , m_allDeclarations(allDeclarations)
485  , m_usesCount(0)
486 {
487  m_itemLayout->setContentsMargins(10, 0, 0, 5);
488  setFrameShape(NoFrame);
489  setUpdatesEnabled(false);
490  DUChainReadLocker lock(DUChain::lock());
491  auto* labelLayout = new QHBoxLayout;
492  labelLayout->setContentsMargins(0, -1, 0, 0); // let's keep the spacing *above* the line
493  auto* headerWidget = new QWidget;
494  headerWidget->setLayout(labelLayout);
495  headerWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
496 
497  auto* label = new QLabel(this);
498  m_icon = new QLabel(this);
499  m_toggleButton = new QLabel(this);
500  m_icon->setPixmap(QIcon::fromTheme(QStringLiteral("code-class")).pixmap(16));
501  labelLayout->addWidget(m_icon);
502  labelLayout->addWidget(label);
503  labelLayout->addWidget(m_toggleButton);
504  labelLayout->setAlignment(Qt::AlignLeft);
505 
506  if (topContext.isLoaded())
507  m_usesCount = DUChainUtils::contextCountUses(topContext.data(), declaration.data());
508 
509  QString labelText = i18ncp("%1: number of uses, %2: filename with uses", "%2: 1 use", "%2: %1 uses",
510  m_usesCount,
511  ICore::self()->projectController()->prettyFileName(topContext.url().toUrl()));
512  label->setText(labelText);
513 
514  m_toggleButton->setText(QLatin1String("&nbsp;&nbsp; <a href='toggleCollapsed'>[") +
515  i18nc("Refers to closing a UI element", "Collapse") + QLatin1String("]</a>"));
516 
517  connect(m_toggleButton, &QLabel::linkActivated, this, &TopContextUsesWidget::labelClicked);
518  addHeaderItem(headerWidget);
519  setUpdatesEnabled(true);
520 }
521 
522 int TopContextUsesWidget::usesCount() const
523 {
524  return m_usesCount;
525 }
526 
527 QList<ContextUsesWidget*> buildContextUses(const CodeRepresentation& code,
528  const QList<IndexedDeclaration>& declarations, DUContext* context)
529 {
530  QList<ContextUsesWidget*> ret;
531 
532  if (!context->parentContext() || isNewGroup(context->parentContext(), context)) {
533  auto* created = new ContextUsesWidget(code, declarations, context);
534  if (created->hasItems())
535  ret << created;
536  else
537  delete created;
538  }
539 
540  const auto childContexts = context->childContexts();
541  for (DUContext* child : childContexts) {
542  ret += buildContextUses(code, declarations, child);
543  }
544 
545  return ret;
546 }
547 
548 void TopContextUsesWidget::setExpanded(bool expanded)
549 {
550  if (!expanded) {
551  m_toggleButton->setText(QLatin1String("&nbsp;&nbsp; <a href='toggleCollapsed'>[") +
552  i18nc("Refers to opening a UI element", "Expand") + QLatin1String("]</a>"));
553  deleteItems();
554  } else {
555  m_toggleButton->setText(QLatin1String("&nbsp;&nbsp; <a href='toggleCollapsed'>[") +
556  i18nc("Refers to closing a UI element", "Collapse") + QLatin1String("]</a>"));
557  if (hasItems())
558  return;
559  DUChainReadLocker lock(DUChain::lock());
560  TopDUContext* topContext = m_topContext.data();
561 
562  if (topContext && m_declaration.data()) {
563  CodeRepresentation::Ptr code = createCodeRepresentation(topContext->url());
564  setUpdatesEnabled(false);
565 
566  IndexedTopDUContext localTopContext(topContext);
567  for (const IndexedDeclaration& decl : qAsConst(m_allDeclarations)) {
568  if (decl.indexedTopContext() == localTopContext) {
569  addItem(new DeclarationWidget(*code, decl));
570  }
571  }
572 
573  const auto contextUseWidgets = buildContextUses(*code, m_allDeclarations, topContext);
574  for (ContextUsesWidget* usesWidget : contextUseWidgets) {
575  addItem(usesWidget);
576  }
577 
578  setUpdatesEnabled(true);
579  }
580  }
581 }
582 
583 void TopContextUsesWidget::labelClicked()
584 {
585  if (hasItems()) {
586  setExpanded(false);
587  } else {
588  setExpanded(true);
589  }
590 }
591 
592 UsesWidget::~UsesWidget()
593 {
594  if (m_collector) {
595  m_collector->setWidget(nullptr);
596  }
597 }
598 
599 UsesWidget::UsesWidget(const IndexedDeclaration& declaration,
600  const QSharedPointer<UsesWidgetCollector>& customCollector)
601  : NavigatableWidgetList(true)
602 {
603  DUChainReadLocker lock(DUChain::lock());
604  setUpdatesEnabled(false);
605 
606  m_headerLine = new QLabel;
607  redrawHeaderLine();
608  connect(m_headerLine, &QLabel::linkActivated, this, &UsesWidget::headerLinkActivated);
609  m_layout->insertWidget(0, m_headerLine, 0, Qt::AlignTop);
610 
611  m_layout->setAlignment(Qt::AlignTop);
612  m_itemLayout->setAlignment(Qt::AlignTop);
613 
614  m_progressBar = new QProgressBar;
615  addHeaderItem(m_progressBar);
616 
617  if (!customCollector) {
618  m_collector = QSharedPointer<UsesWidgetCollector>(new UsesWidget::UsesWidgetCollector(declaration));
619  } else {
620  m_collector = customCollector;
621  }
622 
623  m_collector->setProcessDeclarations(true);
624  m_collector->setWidget(this);
625  m_collector->startCollecting();
626 
627  setUpdatesEnabled(true);
628 }
629 
630 void UsesWidget::redrawHeaderLine()
631 {
632  m_headerLine->setText(headerLineText());
633 }
634 
635 const QString UsesWidget::headerLineText() const
636 {
637  return i18np("1 use found", "%1 uses found", countAllUses()) + QLatin1String(" &bull; "
638  "<a href='expandAll'>[") + i18n(
639  "Expand all") + QLatin1String("]</a> &bull; "
640  "<a href='collapseAll'>[")
641  + i18n("Collapse all") + QLatin1String("]</a>");
642 }
643 
644 unsigned int UsesWidget::countAllUses() const
645 {
646  unsigned int totalUses = 0;
647  const auto items = this->items();
648  for (QWidget* w : items) {
649  if (auto* useWidget = qobject_cast<TopContextUsesWidget*>(w)) {
650  totalUses += useWidget->usesCount();
651  }
652  }
653 
654  return totalUses;
655 }
656 
657 void UsesWidget::setAllExpanded(bool expanded)
658 {
659  const auto items = this->items();
660  for (QWidget* w : items) {
661  if (auto* useWidget = qobject_cast<TopContextUsesWidget*>(w)) {
662  useWidget->setExpanded(expanded);
663  }
664  }
665 }
666 
667 void UsesWidget::headerLinkActivated(const QString& linkName)
668 {
669  if (linkName == QLatin1String("expandAll")) {
670  setAllExpanded(true);
671  } else if (linkName == QLatin1String("collapseAll")) {
672  setAllExpanded(false);
673  }
674 }
675 
676 UsesWidget::UsesWidgetCollector::UsesWidgetCollector(IndexedDeclaration decl) : UsesCollector(decl)
677  , m_widget(nullptr)
678 {
679 }
680 
681 void UsesWidget::UsesWidgetCollector::setWidget(UsesWidget* widget)
682 {
683  m_widget = widget;
684 }
685 
686 void UsesWidget::UsesWidgetCollector::maximumProgress(uint max)
687 {
688  if (!m_widget) {
689  return;
690  }
691 
692  if (m_widget->m_progressBar) {
693  m_widget->m_progressBar->setMaximum(max);
694  m_widget->m_progressBar->setMinimum(0);
695  m_widget->m_progressBar->setValue(0);
696  } else {
697  qCWarning(LANGUAGE) << "maximumProgress called twice";
698  }
699 }
700 
701 void UsesWidget::UsesWidgetCollector::progress(uint processed, uint total)
702 {
703  if (!m_widget) {
704  return;
705  }
706 
707  m_widget->redrawHeaderLine();
708 
709  if (m_widget->m_progressBar) {
710  m_widget->m_progressBar->setValue(processed);
711 
712  if (processed == total) {
713  m_widget->setUpdatesEnabled(false);
714  delete m_widget->m_progressBar;
715  m_widget->m_progressBar = nullptr;
716  m_widget->setShowHeader(false);
717  m_widget->setUpdatesEnabled(true);
718  }
719  } else {
720  qCWarning(LANGUAGE) << "progress() called too often";
721  }
722 }
723 
724 void UsesWidget::UsesWidgetCollector::processUses(KDevelop::ReferencedTopDUContext topContext)
725 {
726  if (!m_widget) {
727  return;
728  }
729 
730  DUChainReadLocker lock;
731 
732  qCDebug(LANGUAGE) << "processing" << topContext->url().str();
733  auto* widget = new TopContextUsesWidget(declaration(), declarations(), topContext.data());
734 
735  // move to back if it's just the declaration/definition
736  bool toBack = widget->usesCount() == 0;
737  // move to front the item belonging to the current open document
738  IDocument* doc = ICore::self()->documentController()->activeDocument();
739  bool toFront = doc && (doc->url() == topContext->url().toUrl());
740 
741  widget->setExpanded(true);
742 
743  m_widget->addItem(widget, toFront ? 0 : toBack ? widget->items().size() : -1);
744  m_widget->redrawHeaderLine();
745 }
746 
747 QSize KDevelop::UsesWidget::sizeHint() const
748 {
749  QSize ret = QWidget::sizeHint();
750  if (ret.height() < 300)
751  ret.setHeight(300);
752  return ret;
753 }
duchainlock.h
KDevelop::DeclarationWidget::DeclarationWidget
DeclarationWidget(const KDevelop::CodeRepresentation &code, const KDevelop::IndexedDeclaration &declaration)
Definition: useswidget.cpp:464
QList::append
void append(const T &value)
KDevelop::IndexedTopDUContext
Allows simple indirect access to top-contexts with on-demand loading.
Definition: indexedtopducontext.h:35
isNewGroup
bool isNewGroup(DUContext *parent, DUContext *child)
Returns whether the uses in the child should be a new uses-group.
Definition: useswidget.cpp:357
KDevelop::UsesWidget::UsesWidget
UsesWidget(const IndexedDeclaration &declaration, const QSharedPointer< UsesWidgetCollector > &customCollector={})
Definition: useswidget.cpp:599
KDevelop::UsesWidget::redrawHeaderLine
void redrawHeaderLine()
Definition: useswidget.cpp:630
QSet
QColor
QBoxLayout::itemAt
virtual QLayoutItem * itemAt(int index) const
QVBoxLayout
KDevelop::DUChainReadLocker
Customized read locker for the definition-use chain.
Definition: duchainlock.h:114
QLabel::setText
void setText(const QString &)
QWidget::QWidget
QWidget(QWidget *parent, QFlags< Qt::WindowType > f)
KDevelop::IndexedDUContext::data
DUContext * data() const
Duchain must be read locked.
Definition: indexedducontext.h:45
KDevelop::DUChain::lock
static DUChainLock * lock()
Retrieve the read write lock for the entire definition-use chain.
Definition: duchain.cpp:1283
QWidget::pos
QPoint pos() const
KDevelop::UsesWidget::sizeHint
QSize sizeHint() const override
Definition: useswidget.cpp:747
KDevelop::NavigatableWidgetList::setShowHeader
void setShowHeader(bool show)
Definition: useswidget.cpp:239
QUrl
duchainutils.h
QWidget::setSizePolicy
void setSizePolicy(QSizePolicy)
KDevelop::TopDUContext::indexForUsedDeclaration
int indexForUsedDeclaration(Declaration *declaration, bool create=true)
Retrieves or creates a local index that is to be used for referencing the given.
Definition: topducontext.cpp:1159
KDevelop::UsesWidget::UsesWidgetCollector
This class can be overridden to do additional processing while the uses-widget shows the uses.
Definition: useswidget.h:161
KDevelop::ReferencedTopDUContext
KDevelop can unload unused top-context at any time.
Definition: topducontext.h:59
KDevelop::OneUseWidget::isHighlighted
bool isHighlighted() const
Definition: useswidget.cpp:188
KDevelop::NavigatableWidgetList::NavigatableWidgetList
NavigatableWidgetList(bool allowScrolling=false, uint maxHeight=0, bool vertical=true)
Definition: useswidget.cpp:252
QWidget::resizeEvent
virtual void resizeEvent(QResizeEvent *event)
KDevelop::UsesWidget::UsesWidgetCollector::UsesWidgetCollector
UsesWidgetCollector(IndexedDeclaration decl)
Definition: useswidget.cpp:676
QString::trimmed
QString trimmed() const
QColor::name
QString name() const
QWidget::event
virtual bool event(QEvent *event)
QBoxLayout::count
virtual int count() const
QWidget
QIcon::fromTheme
QIcon fromTheme(const QString &name, const QIcon &fallback)
QString::chop
void chop(int n)
KDevelop::UsesWidget
A widget that allows browsing through all the uses of a declaration, and also through all declaration...
Definition: useswidget.h:154
QSize
KDevelop::Use::m_declarationIndex
int m_declarationIndex
Definition: use.h:61
KDevelop::Declaration::isFunctionDeclaration
virtual bool isFunctionDeclaration() const
Determine whether this declaration is a function declaration.
Definition: declaration.cpp:655
KDevelop::OneUseWidget::activateLink
void activateLink()
Definition: useswidget.cpp:193
KDevelop::NavigatableWidgetList::~NavigatableWidgetList
~NavigatableWidgetList() override
Definition: useswidget.cpp:247
QWidget::setUpdatesEnabled
void setUpdatesEnabled(bool enable)
QSize::width
int width() const
KDevelop::DUChainBase::transformFromLocalRevision
KTextEditor::Cursor transformFromLocalRevision(const CursorInRevision &cursor) const
QSharedPointer
QFrame::setFrameShape
void setFrameShape(Shape)
KDevelop::UsesWidget::headerLinkActivated
void headerLinkActivated(const QString &linkName)
Definition: useswidget.cpp:667
KDevelop::DUChainUtils::contextCountUses
KDEVPLATFORMLANGUAGE_EXPORT uint contextCountUses(DUContext *context, Declaration *declaration)
Returns the total count of uses of the given declaration under the given context.
Definition: duchainutils.cpp:583
tooltipContextSize
const int tooltipContextSize
Definition: useswidget.cpp:58
QList
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
KDevelop::IndexedDUContext::context
DUContext * context() const
Duchain must be read locked.
Definition: indexedducontext.cpp:56
QMouseEvent
KDevelop::UsesCollector
A helper base-class for collecting the top-contexts that contain all uses of a declaration The most i...
Definition: usescollector.h:33
QLabel::linkActivated
void linkActivated(const QString &link)
KDevelop::NavigatableWidgetList::m_layout
QVBoxLayout * m_layout
Definition: useswidget.h:91
KDevelop::Declaration
Represents a single declaration in a definition-use chain.
Definition: declaration.h:51
QBoxLayout::addWidget
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
KDevelop::UsesWidget::~UsesWidget
~UsesWidget() override
Definition: useswidget.cpp:592
KDevelop::OneUseWidget::~OneUseWidget
~OneUseWidget() override
Definition: useswidget.cpp:206
KDevelop::IndexedTopDUContext::url
IndexedString url() const
Definition: indexedtopducontext.cpp:41
QLabel
KDevelop::IndexedTopDUContext::isLoaded
bool isLoaded() const
Returns whether the top-context is currently loaded.
Definition: indexedtopducontext.cpp:33
KDevelop::DUContext::topContext
TopDUContext * topContext() const override
Find the top context.
Definition: ducontext.cpp:1499
KDevelop::TopDUContext::url
IndexedString url() const override
Definition: topducontext.cpp:1228
KDevelop::NavigatableWidgetList::items
QList< QWidget * > items() const
Definition: useswidget.cpp:325
KDevelop::Use::m_range
RangeInRevision m_range
Definition: use.h:60
KDevelop::IndexedDeclaration
Represents a declaration only by its global indices.
Definition: indexeddeclaration.h:33
KDevelop::NavigatableWidgetList::addItem
void addItem(QWidget *widget, int pos=-1)
Definition: useswidget.cpp:317
KDevelop::UsesWidget::UsesWidgetCollector::processUses
void processUses(KDevelop::ReferencedTopDUContext topContext) override
Called with every top-context that can contain uses of the declaration, or if setProcessDeclarations(...
Definition: useswidget.cpp:724
useswidget.h
QSize::height
int height() const
declaration.h
QScrollArea::widget
QWidget * widget() const
Qt::Alignment
typedef Alignment
KDevelop::DUChainBase::url
virtual IndexedString url() const
Definition: duchainbase.cpp:68
QString
QScrollArea::alignment
Qt::Alignment alignment() const
QToolButton
KDevelop::DUChainBase::range
RangeInRevision range() const
Returns the range assigned to this object, in the document revision when this document was last parse...
Definition: duchainbase.cpp:152
QString::isEmpty
bool isEmpty() const
QString::length
int length() const
KDevelop::OneUseWidget
A widget representing one use of a Declaration in a specific context.
Definition: useswidget.h:43
KDevelop::TopDUContext
The top context in a definition-use chain for one source file.
Definition: topducontext.h:113
QWidget::setBackgroundRole
void setBackgroundRole(QPalette::ColorRole role)
QBoxLayout::insertWidget
void insertWidget(int index, QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
KDevelop::TopContextUsesWidget
Represents the uses of a declaration within one top-context.
Definition: useswidget.h:128
use.h
createUseWidgets
QList< OneUseWidget * > createUseWidgets(const CodeRepresentation &code, int usedDeclarationIndex, IndexedDeclaration decl, DUContext *context)
Definition: useswidget.cpp:382
KDevelop::DUContext::Other
Represents executable code, like for example within a compound-statement.
Definition: ducontext.h:113
KDevelop::NavigatableWidgetList::hasItems
bool hasItems() const
Whether items were added to this list using addItem(..)
Definition: useswidget.cpp:338
highlightAndEscapeUseText
QString highlightAndEscapeUseText(QString line, int cutOff, KTextEditor::Range range)
The returned text is fully escaped.
Definition: useswidget.cpp:63
QStringList::join
QString join(const QString &separator) const
QWidget::setMaximumHeight
void setMaximumHeight(int maxh)
QLatin1String
KDevelop::ContextUsesWidget::ContextUsesWidget
ContextUsesWidget(const CodeRepresentation &code, const QList< IndexedDeclaration > &usedDeclaration, IndexedDUContext context)
Definition: useswidget.cpp:403
KDevelop::TopContextUsesWidget::usesCount
int usesCount() const
Definition: useswidget.cpp:522
QSet::contains
bool contains(const T &value) const
KDevelop::NavigatableWidgetList::deleteItems
void deleteItems()
Deletes all items that were added using addItem.
Definition: useswidget.cpp:311
KDevelop::QualifiedIdentifier::toString
QString toString(IdentifierStringFormattingOptions options=NoOptions) const
Definition: identifier.cpp:798
QString::remove
QString & remove(int position, int n)
QWidget::show
void show()
KDevelop::DUContext::childContexts
QVector< DUContext * > childContexts() const
Returns the list of immediate child contexts for this context.
Definition: ducontext.cpp:479
KDevelop::NavigatableWidgetList::m_itemLayout
QBoxLayout * m_itemLayout
Definition: useswidget.h:90
QLayout::setSizeConstraint
void setSizeConstraint(SizeConstraint)
QScrollArea::setWidgetResizable
void setWidgetResizable(bool resizable)
KDevelop::IndexedDeclaration::data
Declaration * data() const
Definition: indexeddeclaration.h:47
KDevelop::NavigatableWidgetList::addHeaderItem
void addHeaderItem(QWidget *widget, Qt::Alignment alignment={})
Definition: useswidget.cpp:343
countUses
uint countUses(int usedDeclarationIndex, DUContext *context)
Definition: useswidget.cpp:365
KDevelop::IndexedTopDUContext::data
TopDUContext * data() const
Returns the top-context represented by this indexed top-context.
Definition: indexedtopducontext.cpp:49
KDevelop::NavigatableWidgetList
Definition: useswidget.h:72
KDevelop::TopContextUsesWidget::setExpanded
void setExpanded(bool)
Definition: useswidget.cpp:548
QWidget::setToolTip
void setToolTip(const QString &)
buildContextUses
QList< ContextUsesWidget * > buildContextUses(const CodeRepresentation &code, const QList< IndexedDeclaration > &declarations, DUContext *context)
Definition: useswidget.cpp:527
QBoxLayout::setSpacing
void setSpacing(int spacing)
KDevelop::UsesWidget::countAllUses
unsigned int countAllUses() const
Definition: useswidget.cpp:644
QString::left
QString left(int n) const
KDevelop::TopContextUsesWidget::TopContextUsesWidget
TopContextUsesWidget(IndexedDeclaration declaration, const QList< IndexedDeclaration > &localDeclarations, IndexedTopDUContext topContext)
Definition: useswidget.cpp:479
QBoxLayout::insertLayout
void insertLayout(int index, QLayout *layout, int stretch)
duchain.h
KDevelop::ReferencedTopDUContext::data
TopDUContext * data() const
Definition: topducontext.h:68
QResizeEvent
QHBoxLayout
QObject::setParent
void setParent(QObject *parent)
KDevelop::OneUseWidget::OneUseWidget
OneUseWidget(IndexedDeclaration declaration, const IndexedString &document, KTextEditor::Range range, const CodeRepresentation &code)
Note: the links in the HTML here are only used for styling the navigation is implemented in the mouse...
Definition: useswidget.cpp:120
QWidget::sizeHint
virtual QSize sizeHint() const
QLayout::setContentsMargins
void setContentsMargins(int left, int top, int right, int bottom)
uses.h
KDevelop
Definition: abstractfunctiondeclaration.cpp:27
QSet::insert
const_iterator insert(const T &value)
KDevelop::UsesWidget::UsesWidgetCollector::progress
void progress(uint processed, uint total) override
Called whenever progress has been made. max equals the value given initially by maximumProgress.
Definition: useswidget.cpp:701
KDevelop::DUContext
A single context in source code, represented as a node in a directed acyclic graph.
Definition: ducontext.h:72
QLayout::setAlignment
bool setAlignment(QWidget *w, QFlags< Qt::AlignmentFlag > alignment)
KDevelop::DUContext::usesCount
int usesCount() const
Returns the count of uses that can be accessed through uses()
Definition: ducontext.cpp:1333
QBoxLayout::addLayout
void addLayout(QLayout *layout, int stretch)
QBoxLayout::addSpacing
void addSpacing(int size)
KDevelop::DUContext::owner
Declaration * owner() const
If this context was opened by a declaration or definition, this returns that item.
Definition: ducontext.cpp:486
KDevelop::DUContext::uses
const Use * uses() const
Uses: A "Use" represents any position in a document where a Declaration is used literally.
Definition: ducontext.cpp:1321
KDevelop::ContextUsesWidget
Definition: useswidget.h:98
QWidget::setLayout
void setLayout(QLayout *layout)
KDevelop::DUContext::type
ContextType type() const
Definition: ducontext.cpp:1134
QLabel::setPixmap
void setPixmap(const QPixmap &)
QString::mid
QString mid(int position, int n) const
QWidget::size
QSize size() const
KDevelop::DUContext::Function
A context that declares function-arguments.
Definition: ducontext.h:106
QObject::parent
QObject * parent() const
QSize::setHeight
void setHeight(int height)
QProgressBar
QScrollArea::setWidget
void setWidget(QWidget *widget)
KDevelop::UsesWidget::UsesWidgetCollector::setWidget
void setWidget(UsesWidget *widget)
Definition: useswidget.cpp:681
KDevelop::DeclarationWidget
Definition: useswidget.h:116
KDevelop::DUContext::parentContext
DUContext * parentContext() const
Returns the immediate parent context of this context.
Definition: ducontext.cpp:512
KDevelop::DUContext::scopeIdentifier
QualifiedIdentifier scopeIdentifier(bool includeClasses=false) const
Calculate the fully qualified scope identifier.
Definition: ducontext.cpp:1082
KDevelop::QualifiedIdentifier::isEmpty
bool isEmpty() const
Definition: identifier.cpp:1041
KDevelop::UsesWidget::UsesWidgetCollector::maximumProgress
void maximumProgress(uint max) override
Indicates the maximum progress this collector can make.
Definition: useswidget.cpp:686
QWidget::setCursor
void setCursor(const QCursor &)
QStringList
KDevelop::UsesWidget::setAllExpanded
void setAllExpanded(bool expanded)
Definition: useswidget.cpp:657
KDevelop::IndexedDUContext
Represents a context only by its global indices.
Definition: indexedducontext.h:35
KDevelop::OneUseWidget::setHighlighted
void setHighlighted(bool highlight)
Definition: useswidget.cpp:171
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Thu Mar 4 2021 23:31:17 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