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

Kate

  • sources
  • kde-4.12
  • applications
  • kate
  • part
  • completion
katecompletionwidget.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE libraries and the Kate part.
2  *
3  * Copyright (C) 2005-2006 Hamish Rodda <rodda@kde.org>
4  * Copyright (C) 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 
22 #include "katecompletionwidget.h"
23 
24 #include <QtGui/QBoxLayout>
25 #include <QtGui/QApplication>
26 #include <QtGui/QDesktopWidget>
27 #include <QtGui/QHeaderView>
28 #include <QtCore/QTimer>
29 #include <QtGui/QLabel>
30 #include <QtGui/QToolButton>
31 #include <QtGui/QSizeGrip>
32 #include <QtGui/QPushButton>
33 #include <QtGui/QAbstractScrollArea>
34 #include <QtGui/QScrollBar>
35 #include <QtCore/QScopedPointer>
36 
37 #include <kicon.h>
38 #include <kdialog.h>
39 
40 #include <ktexteditor/codecompletionmodelcontrollerinterface.h>
41 
42 #include "kateview.h"
43 #include "katerenderer.h"
44 #include "kateconfig.h"
45 #include "katedocument.h"
46 #include "katebuffer.h"
47 
48 #include "katecompletionmodel.h"
49 #include "katecompletiontree.h"
50 #include "katecompletionconfig.h"
51 #include "kateargumenthinttree.h"
52 #include "kateargumenthintmodel.h"
53 
54 //#include "modeltest.h"
55 
56 const bool hideAutomaticCompletionOnExactMatch = true;
57 
58 //If this is true, the completion-list is navigated up/down when 'tab' is pressed, instead of doing partial completion
59 const bool shellLikeTabCompletion = false;
60 
61 #define CALLCI(WHAT,WHATELSE,WHAT2,model,FUNC) \
62 {\
63  static KTextEditor::CodeCompletionModelControllerInterface3 defaultIf;\
64  KTextEditor::CodeCompletionModelControllerInterface3* ret =\
65  dynamic_cast<KTextEditor::CodeCompletionModelControllerInterface3*>(model);\
66  if (!ret) {\
67  WHAT2 defaultIf.FUNC;\
68  }else \
69  WHAT2 ret->FUNC;\
70 }
71 
72 
73 static KTextEditor::Range _completionRange(KTextEditor::CodeCompletionModel *model, KTextEditor::View *view, const KTextEditor::Cursor& cursor){
74  CALLCI(return,,return, model,completionRange(view, cursor));
75 }
76 
77 static KTextEditor::Range _updateRange(KTextEditor::CodeCompletionModel *model,KTextEditor::View *view, KTextEditor::Range& range) {
78  CALLCI(, return range,return, model,updateCompletionRange(view, range));
79 }
80 
81 static QString _filterString(KTextEditor::CodeCompletionModel *model,KTextEditor::View *view, const KTextEditor::Range& range, const KTextEditor::Cursor& cursor) {
82  CALLCI(return,,return, model,filterString(view, range, cursor));
83 }
84 
85 static bool _shouldAbortCompletion(KTextEditor::CodeCompletionModel *model,KTextEditor::View *view, const KTextEditor::Range& range, const QString& currentCompletion) {
86  CALLCI(return,,return, model,shouldAbortCompletion(view, range, currentCompletion));
87 }
88 
89 static void _aborted(KTextEditor::CodeCompletionModel *model,KTextEditor::View *view) {
90  CALLCI(return,,return, model,aborted(view));
91 }
92 
93 static bool _shouldStartCompletion(KTextEditor::CodeCompletionModel *model,KTextEditor::View *view, QString m_automaticInvocationLine,bool m_lastInsertionByUser, const KTextEditor::Cursor& cursor) {
94  CALLCI(return,,return,model,shouldStartCompletion(view, m_automaticInvocationLine, m_lastInsertionByUser, cursor));
95 }
96 
97 KateCompletionWidget::KateCompletionWidget(KateView* parent)
98  : QFrame(parent, Qt::ToolTip)
99  , m_presentationModel(new KateCompletionModel(this))
100  , m_entryList(new KateCompletionTree(this))
101  , m_argumentHintModel(new KateArgumentHintModel(this))
102  , m_argumentHintTree(new KateArgumentHintTree(this))
103  , m_automaticInvocationDelay(100)
104  , m_filterInstalled(false)
105  , m_configWidget(new KateCompletionConfig(m_presentationModel, view()))
106  , m_lastInsertionByUser(false)
107  , m_inCompletionList(false)
108  , m_isSuspended(false)
109  , m_dontShowArgumentHints(false)
110  , m_needShow(false)
111  , m_hadCompletionNavigation(false)
112  , m_noAutoHide(false)
113  , m_completionEditRunning (false)
114  , m_expandedAddedHeightBase(0)
115  , m_lastInvocationType(KTextEditor::CodeCompletionModel::AutomaticInvocation)
116 {
117  connect(parent, SIGNAL(navigateAccept()), SLOT(navigateAccept()));
118  connect(parent, SIGNAL(navigateBack()), SLOT(navigateBack()));
119  connect(parent, SIGNAL(navigateDown()), SLOT(navigateDown()));
120  connect(parent, SIGNAL(navigateLeft()), SLOT(navigateLeft()));
121  connect(parent, SIGNAL(navigateRight()), SLOT(navigateRight()));
122  connect(parent, SIGNAL(navigateUp()), SLOT(navigateUp()));
123 
124  qRegisterMetaType<KTextEditor::Cursor>("KTextEditor::Cursor");
125 
126  setFrameStyle( QFrame::Box | QFrame::Plain );
127  setLineWidth( 1 );
128  //setWindowOpacity(0.8);
129 
130  m_entryList->setModel(m_presentationModel);
131  m_entryList->setColumnWidth(0, 0); //These will be determined automatically in KateCompletionTree::resizeColumns
132  m_entryList->setColumnWidth(1, 0);
133  m_entryList->setColumnWidth(2, 0);
134 
135  m_entryList->setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
136 
137  m_argumentHintTree->setParent(0, Qt::ToolTip);
138  m_argumentHintTree->setModel(m_argumentHintModel);
139 
140  // trigger completion on double click on completion list
141  connect(m_entryList, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(execute()));
142 
143  connect(m_entryList->verticalScrollBar(), SIGNAL(valueChanged(int)), m_presentationModel, SLOT(placeExpandingWidgets()));
144  connect(m_argumentHintTree->verticalScrollBar(), SIGNAL(valueChanged(int)), m_argumentHintModel, SLOT(placeExpandingWidgets()));
145  connect(view(), SIGNAL(focusOut(KTextEditor::View*)), this, SLOT(viewFocusOut()));
146 
147  m_automaticInvocationTimer = new QTimer(this);
148  m_automaticInvocationTimer->setSingleShot(true);
149  connect(m_automaticInvocationTimer, SIGNAL(timeout()), this, SLOT(automaticInvocation()));
150 
151  // Keep branches expanded
152  connect(m_presentationModel, SIGNAL(modelReset()), this, SLOT(modelReset()));
153  connect(m_presentationModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(rowsInserted(QModelIndex,int,int)));
154  connect(m_argumentHintModel, SIGNAL(contentStateChanged(bool)), this, SLOT(argumentHintsChanged(bool)));
155 
156  // No smart lock, no queued connects
157  connect(view(), SIGNAL(cursorPositionChanged(KTextEditor::View*,KTextEditor::Cursor)), this, SLOT(cursorPositionChanged()));
158  connect(view(), SIGNAL(verticalScrollPositionChanged(KTextEditor::View*,KTextEditor::Cursor)), this, SLOT(updatePositionSlot()));
159 
163  connect(&view()->doc()->buffer(), SIGNAL(lineWrapped(KTextEditor::Cursor)), this, SLOT(wrapLine(KTextEditor::Cursor)));
164  connect(&view()->doc()->buffer(), SIGNAL(lineUnwrapped(int)), this, SLOT(unwrapLine(int)));
165  connect(&view()->doc()->buffer(), SIGNAL(textInserted(KTextEditor::Cursor,QString)), this, SLOT(insertText(KTextEditor::Cursor,QString)));
166  connect(&view()->doc()->buffer(), SIGNAL(textRemoved(KTextEditor::Range,QString)), this, SLOT(removeText(KTextEditor::Range)));
167 
168  // This is a non-focus widget, it is passed keyboard input from the view
169 
170  //We need to do this, because else the focus goes to nirvana without any control when the completion-widget is clicked.
171  setFocusPolicy(Qt::ClickFocus);
172  m_argumentHintTree->setFocusPolicy(Qt::ClickFocus);
173 
174  foreach (QWidget* childWidget, findChildren<QWidget*>())
175  childWidget->setFocusPolicy(Qt::NoFocus);
176 
177  //Position the entry-list so a frame can be drawn around it
178  m_entryList->move(frameWidth(), frameWidth());
179 }
180 
181 KateCompletionWidget::~KateCompletionWidget() {
182 }
183 
184 void KateCompletionWidget::viewFocusOut() {
185  abortCompletion();
186 }
187 
188 void KateCompletionWidget::modelContentChanged() {
190  if(m_completionRanges.isEmpty()) {
191  //kDebug( 13035 ) << "content changed, but no completion active";
192  abortCompletion();
193  return;
194  }
195 
196  if(!view()->hasFocus()) {
197  //kDebug( 13035 ) << "view does not have focus";
198  return;
199  }
200 
201  if(!m_waitingForReset.isEmpty()) {
202  //kDebug( 13035 ) << "waiting for" << m_waitingForReset.size() << "completion-models to reset";
203  return;
204  }
205 
206  int realItemCount = 0;
207  foreach (KTextEditor::CodeCompletionModel* model, m_presentationModel->completionModels())
208  realItemCount += model->rowCount();
209  if( !m_isSuspended && ((isHidden() && m_argumentHintTree->isHidden()) || m_needShow) && realItemCount != 0 ) {
210  m_needShow = false;
211  updateAndShow();
212  }
213 
214  if(m_argumentHintModel->rowCount(QModelIndex()) == 0)
215  m_argumentHintTree->hide();
216 
217  if(m_presentationModel->rowCount(QModelIndex()) == 0)
218  hide();
219 
220 
221  //With each filtering items can be added or removed, so we have to reset the current index here so we always have a selected item
222  m_entryList->setCurrentIndex(model()->index(0,0));
223  if(!model()->indexIsItem(m_entryList->currentIndex())) {
224  QModelIndex firstIndex = model()->index(0,0, m_entryList->currentIndex());
225  m_entryList->setCurrentIndex(firstIndex);
226  //m_entryList->scrollTo(firstIndex, QAbstractItemView::PositionAtTop);
227  }
228 
229  updateHeight();
230 
231  //New items for the argument-hint tree may have arrived, so check whether it needs to be shown
232  if( m_argumentHintTree->isHidden() && !m_dontShowArgumentHints && m_argumentHintModel->rowCount(QModelIndex()) != 0 )
233  m_argumentHintTree->show();
234 
235  if(!m_noAutoHide && hideAutomaticCompletionOnExactMatch && !isHidden() &&
236  m_lastInvocationType == KTextEditor::CodeCompletionModel::AutomaticInvocation &&
237  m_presentationModel->shouldMatchHideCompletionList())
238  hide();
239  else if(isHidden() && !m_presentationModel->shouldMatchHideCompletionList() &&
240  m_presentationModel->rowCount(QModelIndex()))
241  show();
242 }
243 
244 KateArgumentHintTree* KateCompletionWidget::argumentHintTree() const {
245  return m_argumentHintTree;
246 }
247 
248 KateArgumentHintModel* KateCompletionWidget::argumentHintModel() const {
249  return m_argumentHintModel;
250 }
251 
252 const KateCompletionModel* KateCompletionWidget::model() const {
253  return m_presentationModel;
254 }
255 
256 KateCompletionModel* KateCompletionWidget::model() {
257  return m_presentationModel;
258 }
259 
260 void KateCompletionWidget::rowsInserted(const QModelIndex& parent, int rowFrom, int rowEnd)
261 {
262  m_entryList->setAnimated(false);
263  if(!model()->isGroupingEnabled())
264  return;
265 
266  if (!parent.isValid())
267  for (int i = rowFrom; i <= rowEnd; ++i)
268  m_entryList->expand(m_presentationModel->index(i, 0, parent));
269 }
270 
271 KateView * KateCompletionWidget::view( ) const
272 {
273  return static_cast<KateView*>(const_cast<QObject*>(parent()));
274 }
275 
276 void KateCompletionWidget::argumentHintsChanged(bool hasContent)
277 {
278  m_dontShowArgumentHints = !hasContent;
279 
280  if( m_dontShowArgumentHints )
281  m_argumentHintTree->hide();
282  else
283  updateArgumentHintGeometry();
284 }
285 
286 void KateCompletionWidget::startCompletion(KTextEditor::CodeCompletionModel::InvocationType invocationType, const QList<KTextEditor::CodeCompletionModel*>& models)
287 {
288  if(invocationType == KTextEditor::CodeCompletionModel::UserInvocation)
289  {
290  abortCompletion();
291  }
292  startCompletion(KTextEditor::Range(KTextEditor::Cursor(-1, -1), KTextEditor::Cursor(-1, -1)), models, invocationType);
293 }
294 
295 void KateCompletionWidget::deleteCompletionRanges()
296 {
298  foreach(const CompletionRange &r, m_completionRanges)
299  delete r.range;
300  m_completionRanges.clear();
301 }
302 
303 void KateCompletionWidget::startCompletion(const KTextEditor::Range& word, KTextEditor::CodeCompletionModel* model, KTextEditor::CodeCompletionModel::InvocationType invocationType)
304 {
305  QList<KTextEditor::CodeCompletionModel*> models;
306  if (model) {
307  models << model;
308  } else {
309  models = m_sourceModels;
310  }
311  startCompletion(word, models, invocationType);
312 }
313 
314 void KateCompletionWidget::startCompletion(const KTextEditor::Range& word, const QList<KTextEditor::CodeCompletionModel*>& modelsToStart, KTextEditor::CodeCompletionModel::InvocationType invocationType)
315 {
316 
318 
319  m_isSuspended = false;
320  m_inCompletionList = true; //Always start at the top of the completion-list
321  m_needShow = true;
322 
323  if(m_completionRanges.isEmpty())
324  m_noAutoHide = false; //Re-enable auto-hide on every clean restart of the completion
325 
326  m_lastInvocationType = invocationType;
327 
328  disconnect(this->model(), SIGNAL(contentGeometryChanged()), this, SLOT(modelContentChanged()));
329 
330  m_dontShowArgumentHints = true;
331 
332  QList<KTextEditor::CodeCompletionModel*> models = (modelsToStart.isEmpty() ? m_sourceModels : modelsToStart);
333 
334  foreach(KTextEditor::CodeCompletionModel* model, m_completionRanges.keys())
335  if(!models.contains(model))
336  models << model;
337 
338  if (!m_filterInstalled) {
339  if (!QApplication::activeWindow()) {
340  kWarning(13035) << "No active window to install event filter on!!";
341  return;
342  }
343  // Enable the cc box to move when the editor window is moved
344  QApplication::activeWindow()->installEventFilter(this);
345  m_filterInstalled = true;
346  }
347 
348  m_presentationModel->clearCompletionModels();
349 
350  if(invocationType == KTextEditor::CodeCompletionModel::UserInvocation) {
351  deleteCompletionRanges();
352  }
353 
354  foreach (KTextEditor::CodeCompletionModel* model, models) {
355  KTextEditor::Range range;
356  if (word.isValid()) {
357  range = word;
358  //kDebug()<<"word is used";
359  } else {
360  range=_completionRange(model,view(), view()->cursorPosition());
361  //kDebug()<<"completionRange has been called, cursor pos is"<<view()->cursorPosition();
362  }
363  //kDebug()<<"range is"<<range;
364  if(!range.isValid()) {
365  if(m_completionRanges.contains(model)) {
366  KTextEditor::MovingRange *oldRange = m_completionRanges[model].range;
367  //kDebug()<<"removing completion range 1";
368  m_completionRanges.remove(model);
369  delete oldRange;
370  }
371  models.removeAll(model);
372  continue;
373  }
374  if(m_completionRanges.contains(model)) {
375  if(*m_completionRanges[model].range == range) {
376  continue; //Leave it running as it is
377  }
378  else { // delete the range that was used previously
379  KTextEditor::MovingRange *oldRange = m_completionRanges[model].range;
380  //kDebug()<<"removing completion range 2";
381  m_completionRanges.remove(model);
382  delete oldRange;
383  }
384  }
385 
386  connect(model, SIGNAL(waitForReset()), this, SLOT(waitForModelReset()));
387 
388  //kDebug()<<"Before completin invoke: range:"<<range;
389  model->completionInvoked(view(), range, invocationType);
390 
391  disconnect(model, SIGNAL(waitForReset()), this, SLOT(waitForModelReset()));
392 
393  m_completionRanges[model] = view()->doc()->newMovingRange(range, KTextEditor::MovingRange::ExpandRight | KTextEditor::MovingRange::ExpandLeft);
394 
395  //In automatic invocation mode, hide the completion widget as soon as the position where the completion was started is passed to the left
396  m_completionRanges[model].leftBoundary = view()->cursorPosition();
397 
398  //In manual invocation mode, bound the activity either the the point from where completion was invoked, or to the start of the range
399  if(invocationType != KTextEditor::CodeCompletionModel::AutomaticInvocation)
400  if(range.start() < m_completionRanges[model].leftBoundary)
401  m_completionRanges[model].leftBoundary = range.start();
402 
403  if(!m_completionRanges[model].range->toRange().isValid()) {
404  kWarning(13035) << "Could not construct valid smart-range from" << range << "instead got" << *m_completionRanges[model].range;
405  abortCompletion();
406  return;
407  }
408  }
409 
410  m_presentationModel->setCompletionModels(models);
411 
412  cursorPositionChanged();
413 
414  if (!m_completionRanges.isEmpty()) {
415  connect(this->model(), SIGNAL(contentGeometryChanged()), this, SLOT(modelContentChanged()));
416  //Now that all models have been notified, check whether the widget should be displayed instantly
417  modelContentChanged();
418  }
419  else {
420  abortCompletion();
421  }
422 }
423 
424 void KateCompletionWidget::waitForModelReset()
425 {
426  KTextEditor::CodeCompletionModel* senderModel = qobject_cast<KTextEditor::CodeCompletionModel*>(sender());
427  if(!senderModel) {
428  kWarning() << "waitForReset signal from bad model";
429  return;
430  }
431  m_waitingForReset.insert(senderModel);
432 }
433 
434 void KateCompletionWidget::updateAndShow()
435 {
436  //kDebug()<<"*******************************************";
437  if(!view()->hasFocus()) {
438  kDebug( 13035 ) << "view does not have focus";
439  return;
440  }
441 
442  setUpdatesEnabled(false);
443 
444  modelReset();
445 
446  m_argumentHintModel->buildRows();
447  if( m_argumentHintModel->rowCount(QModelIndex()) != 0 )
448  argumentHintsChanged(true);
449 // }
450 
451  //We do both actions twice here so they are stable, because they influence each other:
452  //updatePosition updates the height, resizeColumns needs the correct height to decide over
453  //how many rows it computs the column-width
454  updatePosition(true);
455  m_entryList->resizeColumns(true, true);
456  updatePosition(true);
457  m_entryList->resizeColumns(true, true);
458 
459  setUpdatesEnabled(true);
460 
461  if(m_argumentHintModel->rowCount(QModelIndex())) {
462  updateArgumentHintGeometry();
463  m_argumentHintTree->show();
464  } else
465  m_argumentHintTree->hide();
466 
467  if (m_presentationModel->rowCount() && (!m_presentationModel->shouldMatchHideCompletionList() ||
468  !hideAutomaticCompletionOnExactMatch ||
469  m_lastInvocationType != KTextEditor::CodeCompletionModel::AutomaticInvocation) )
470  show();
471  else
472  hide();
473 }
474 
475 void KateCompletionWidget::updatePositionSlot()
476 {
477  updatePosition();
478 }
479 
480 bool KateCompletionWidget::updatePosition(bool force)
481 {
482  if (!force && !isCompletionActive())
483  return false;
484 
485  if (!completionRange()) {
486  return false;
487  }
488  QPoint cursorPosition = view()->cursorToCoordinate(completionRange()->start());
489  if (cursorPosition == QPoint(-1,-1)) {
490  // Start of completion range is now off-screen -> abort
491  abortCompletion();
492  return false;
493  }
494 
495  QPoint p = view()->mapToGlobal( cursorPosition );
496  int x = p.x() - m_entryList->columnTextViewportPosition(m_presentationModel->translateColumn(KTextEditor::CodeCompletionModel::Name)) - 4 - (m_entryList->viewport()->pos().x());
497  int y = p.y();
498 
499  y += view()->renderer()->config()->fontMetrics().height() + 4;
500 
501  bool borderHit = false;
502 
503  if (x + width() > QApplication::desktop()->screenGeometry(view()).right()) {
504  x = QApplication::desktop()->screenGeometry(view()).right() - width();
505  borderHit = true;
506  }
507 
508  if( x < QApplication::desktop()->screenGeometry(view()).left() ) {
509  x = QApplication::desktop()->screenGeometry(view()).left();
510  borderHit = true;
511  }
512 
513  move( QPoint(x,y) );
514 
515  updateHeight();
516 
517  updateArgumentHintGeometry();
518 
519 // //kDebug() << "updated to" << geometry() << m_entryList->geometry() << borderHit;
520 
521  return borderHit;
522 }
523 
524 void KateCompletionWidget::updateArgumentHintGeometry()
525 {
526  if( !m_dontShowArgumentHints ) {
527  //Now place the argument-hint widget
528  QRect geom = m_argumentHintTree->geometry();
529  geom.moveTo(pos());
530  geom.setWidth(width());
531  geom.moveBottom(pos().y() - view()->renderer()->config()->fontMetrics().height()*2);
532  m_argumentHintTree->updateGeometry(geom);
533  }
534 }
535 
536 //Checks whether the given model has at least "rows" rows, also searching the second level of the tree.
537 bool hasAtLeastNRows(int rows, QAbstractItemModel* model) {
538  int count = 0;
539  for(int row = 0; row < model->rowCount(); ++row) {
540  ++count;
541 
542  QModelIndex index(model->index(row, 0));
543  if(index.isValid())
544  count += model->rowCount(index);
545 
546  if(count > rows)
547  return true;
548  }
549  return false;
550 }
551 
552 void KateCompletionWidget::updateHeight()
553 {
554  QRect geom = geometry();
555 
556  int minBaseHeight = 10;
557  int maxBaseHeight = 300;
558 
559  int baseHeight = 0;
560  int calculatedCustomHeight = 0;
561 
562  if(hasAtLeastNRows(15, m_presentationModel)) {
563  //If we know there is enough rows, always use max-height, we don't need to calculate size-hints
564  baseHeight = maxBaseHeight;
565  }else{
566  //Calculate size-hints to determine the best height
567  for(int row = 0; row < m_presentationModel->rowCount(); ++row) {
568  baseHeight += treeView()->sizeHintForRow(row);
569 
570  QModelIndex index(m_presentationModel->index(row, 0));
571  if(index.isValid()) {
572  for(int row2 = 0; row2 < m_presentationModel->rowCount(index); ++row2) {
573  int h = 0;
574  for(int a = 0; a < m_presentationModel->columnCount(index); ++a) {
575  int localHeight = treeView()->sizeHintForIndex(index.child(row2, a)).height();
576  if(localHeight > h)
577  h = localHeight;
578  }
579  baseHeight += h;
580  if(baseHeight > maxBaseHeight)
581  break;
582  }
583 
584  if(baseHeight > maxBaseHeight)
585  break;
586  }
587  }
588 
589  calculatedCustomHeight = baseHeight;
590  }
591 
592  baseHeight += 2*frameWidth();
593 
594  if(m_entryList->horizontalScrollBar()->isVisible())
595  baseHeight += m_entryList->horizontalScrollBar()->height();
596 
597 
598  if(baseHeight < minBaseHeight)
599  baseHeight = minBaseHeight;
600  if(baseHeight > maxBaseHeight) {
601  baseHeight = maxBaseHeight;
602  m_entryList->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
603  }else{
604  //Somewhere there seems to be a bug that makes QTreeView add a scroll-bar
605  //even if the content exactly fits in. So forcefully disable the scroll-bar in that case
606  m_entryList->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
607 }
608 
609  int newExpandingAddedHeight = 0;
610 
611  if(baseHeight == maxBaseHeight && model()->expandingWidgetsHeight()) {
612  //Eventually add some more height
613  if(calculatedCustomHeight && calculatedCustomHeight > baseHeight && calculatedCustomHeight < (maxBaseHeight + model()->expandingWidgetsHeight()))
614  newExpandingAddedHeight = calculatedCustomHeight - baseHeight;
615  else
616  newExpandingAddedHeight = model()->expandingWidgetsHeight();
617  }
618 
619  if( m_expandedAddedHeightBase != baseHeight && m_expandedAddedHeightBase - baseHeight > -2 && m_expandedAddedHeightBase - baseHeight < 2 )
620  {
621  //Re-use the stored base-height if it only slightly differs from the current one.
622  //Reason: Qt seems to apply slightly wrong sizes when the completion-widget is moved out of the screen at the bottom,
623  // which completely breaks this algorithm. Solution: re-use the old base-size if it only slightly differs from the computed one.
624  baseHeight = m_expandedAddedHeightBase;
625  }
626 
627  int screenBottom = QApplication::desktop()->screenGeometry(view()).bottom();
628 
629  //Limit the height to the bottom of the screen
630  int bottomPosition = baseHeight + newExpandingAddedHeight + geometry().top();
631 
632  if( bottomPosition > screenBottom ) {
633  newExpandingAddedHeight -= bottomPosition - (screenBottom);
634  }
635 
636  int finalHeight = baseHeight+newExpandingAddedHeight;
637 
638  if( finalHeight < 10 ) {
639  m_entryList->resize(m_entryList->width(), height() - 2*frameWidth());
640  return;
641  }
642 
643  m_expandedAddedHeightBase = geometry().height();
644 
645  geom.setHeight(finalHeight);
646 
647  //Work around a crash deep within the Qt 4.5 raster engine
648  m_entryList->setScrollingEnabled(false);
649 
650  if(geometry() != geom)
651  setGeometry(geom);
652 
653  QSize entryListSize = QSize(m_entryList->width(), finalHeight - 2*frameWidth());
654  if(m_entryList->size() != entryListSize)
655  m_entryList->resize(entryListSize);
656 
657 
658  m_entryList->setScrollingEnabled(true);
659 }
660 
661 void KateCompletionWidget::cursorPositionChanged( )
662 {
664  if (m_completionRanges.isEmpty())
665  return;
666 
667  QModelIndex oldCurrentSourceIndex;
668  if(m_inCompletionList && m_entryList->currentIndex().isValid())
669  oldCurrentSourceIndex = m_presentationModel->mapToSource(m_entryList->currentIndex());
670 
671  KTextEditor::Cursor cursor = view()->cursorPosition();
672 
673  QList<KTextEditor::CodeCompletionModel*> checkCompletionRanges = m_completionRanges.keys();
674 
675  //Check the models and eventuall abort some
676  for(QList<KTextEditor::CodeCompletionModel*>::iterator it = checkCompletionRanges.begin(); it != checkCompletionRanges.end(); ++it) {
677  KTextEditor::CodeCompletionModel *model = *it;
678  if(!m_completionRanges.contains(model))
679  continue;
680 
681  //kDebug()<<"range before _updateRange:"<< *range;
682 
683  // this might invalidate the range, therefore re-check afterwards
684  KTextEditor::Range rangeTE = m_completionRanges[model].range->toRange();
685  KTextEditor::Range newRange = _updateRange(model, view(), rangeTE);
686  if(!m_completionRanges.contains(model))
687  continue;
688 
689  // update value
690  m_completionRanges[model].range->setRange (newRange);
691 
692  //kDebug()<<"range after _updateRange:"<< *range;
693  QString currentCompletion = _filterString(model,view(), *m_completionRanges[model].range, view()->cursorPosition());
694  if(!m_completionRanges.contains(model))
695  continue;
696 
697  //kDebug()<<"after _filterString, currentCompletion="<< currentCompletion;
698  bool abort = _shouldAbortCompletion(model,view(), *m_completionRanges[model].range, currentCompletion);
699  if(!m_completionRanges.contains(model))
700  continue;
701 
702  //kDebug()<<"after _shouldAbortCompletion:abort="<<abort;
703  if(view()->cursorPosition() < m_completionRanges[model].leftBoundary) {
704  //kDebug() << "aborting because of boundary: cursor:"<<view()->cursorPosition()<<"completion_Range_left_boundary:"<<m_completionRanges[*it].leftBoundary;
705  abort = true;
706  }
707 
708  if(!m_completionRanges.contains(model))
709  continue;
710 
711  if (abort) {
712  if (m_completionRanges.count() == 1) {
713  //last model - abort whole completion
714  abortCompletion();
715  return;
716  } else {
717  {
718  delete m_completionRanges[model].range;
719  //kDebug()<<"removing completion range 3";
720  m_completionRanges.remove(model);
721  }
722 
723  _aborted(model,view());
724  m_presentationModel->removeCompletionModel(model);
725  }
726  } else {
727  m_presentationModel->setCurrentCompletion(model, currentCompletion);
728  }
729  }
730 
731  if(oldCurrentSourceIndex.isValid()) {
732  QModelIndex idx = m_presentationModel->mapFromSource(oldCurrentSourceIndex);
733  if(idx.isValid()) {
734  //kDebug() << "setting" << idx;
735  m_entryList->setCurrentIndex(idx.sibling(idx.row(), 0));
736 // m_entryList->nextCompletion();
737 // m_entryList->previousCompletion();
738  }else{
739  //kDebug() << "failed to map from source";
740  }
741  }
742 
743  m_entryList->scheduleUpdate();
744 }
745 
746 bool KateCompletionWidget::isCompletionActive( ) const
747 {
748  return !m_completionRanges.isEmpty() && ((!isHidden() && isVisible()) || (!m_argumentHintTree->isHidden() && m_argumentHintTree->isVisible()));
749 }
750 
751 void KateCompletionWidget::abortCompletion( )
752 {
753  //kDebug(13035) ;
754 
755  m_isSuspended = false;
756 
757  bool wasActive = isCompletionActive();
758 
759  clear();
760 
761  if(!isHidden())
762  hide();
763  if(!m_argumentHintTree->isHidden())
764  m_argumentHintTree->hide();
765 
766  if (wasActive)
767  view()->sendCompletionAborted();
768 }
769 
770 void KateCompletionWidget::clear() {
771  m_presentationModel->clearCompletionModels();
772  m_argumentHintTree->clearCompletion();
773  m_argumentHintModel->clear();
774 
775  foreach(KTextEditor::CodeCompletionModel* model, m_completionRanges.keys())
776  _aborted(model,view());
777 
778  deleteCompletionRanges();
779 }
780 
781 bool KateCompletionWidget::navigateAccept() {
782  m_hadCompletionNavigation = true;
783 
784  if(currentEmbeddedWidget())
785  QMetaObject::invokeMethod(currentEmbeddedWidget(), "embeddedWidgetAccept");
786 
787  QModelIndex index = selectedIndex();
788  if( index.isValid() ) {
789  index.data(KTextEditor::CodeCompletionModel::AccessibilityAccept);
790  return true;
791  }
792  return false;
793 }
794 
795 void KateCompletionWidget::execute()
796 {
797  //kDebug(13035) ;
798 
799  if (!isCompletionActive())
800  return;
801 
802  QModelIndex index = selectedIndex();
803 
804  if (!index.isValid())
805  return abortCompletion();
806 
807  QModelIndex toExecute;
808 
809  if(index.model() == m_presentationModel)
810  toExecute = m_presentationModel->mapToSource(index);
811  else
812  toExecute = m_argumentHintModel->mapToSource(index);
813 
814  if (!toExecute.isValid()) {
815  kWarning() << k_funcinfo << "Could not map index" << m_entryList->selectionModel()->currentIndex() << "to source index.";
816  return abortCompletion();
817  }
818 
819  // encapsulate all editing as being from the code completion, and undo-able in one step.
820  view()->doc()->editStart();
821  m_completionEditRunning = true;
822 
823  // create scoped pointer, to ensure deletion of cursor
824  QScopedPointer<KTextEditor::MovingCursor> oldPos (view()->doc()->newMovingCursor(view()->cursorPosition(), KTextEditor::MovingCursor::StayOnInsert));
825 
826  KTextEditor::CodeCompletionModel* model = static_cast<KTextEditor::CodeCompletionModel*>(const_cast<QAbstractItemModel*>(toExecute.model()));
827  Q_ASSERT(model);
828 
829  KTextEditor::CodeCompletionModel2* model2 = qobject_cast<KTextEditor::CodeCompletionModel2*>(model);
830 
831  Q_ASSERT(m_completionRanges.contains(model));
832  KTextEditor::Cursor start = m_completionRanges[model].range->start();
833 
834  if(model2)
835  model2->executeCompletionItem2(view()->document(), *m_completionRanges[model].range, toExecute);
836  else if(toExecute.parent().isValid())
837  //The normale CodeCompletionInterface cannot handle feedback for hierarchical models, so just do the replacement
838  view()->document()->replaceText(*m_completionRanges[model].range, model->data(toExecute.sibling(toExecute.row(), KTextEditor::CodeCompletionModel::Name)).toString());
839  else
840  model->executeCompletionItem(view()->document(), *m_completionRanges[model].range, toExecute.row());
841 
842  view()->doc()->editEnd();
843  m_completionEditRunning = false;
844 
845  abortCompletion();
846 
847  view()->sendCompletionExecuted(start, model, toExecute);
848 
849  KTextEditor::Cursor newPos = view()->cursorPosition();
850 
851  if(newPos > *oldPos) {
852  m_automaticInvocationAt = newPos;
853  m_automaticInvocationLine = view()->doc()->text(KTextEditor::Range(*oldPos, newPos));
854  //kDebug() << "executed, starting automatic invocation with line" << m_automaticInvocationLine;
855  m_lastInsertionByUser = false;
856  m_automaticInvocationTimer->start();
857  }
858 }
859 
860 void KateCompletionWidget::resizeEvent( QResizeEvent * event )
861 {
862  QFrame::resizeEvent(event);
863 }
864 
865 void KateCompletionWidget::showEvent ( QShowEvent * event )
866 {
867  m_isSuspended = false;
868 
869  QFrame::showEvent(event);
870 
871  if( !m_dontShowArgumentHints && m_argumentHintModel->rowCount(QModelIndex()) != 0 )
872  m_argumentHintTree->show();
873 }
874 
875 KTextEditor::MovingRange * KateCompletionWidget::completionRange(KTextEditor::CodeCompletionModel* model) const
876 {
877  if (!model) {
878  if (m_completionRanges.isEmpty()) return 0;
879 
880  KTextEditor::MovingRange* ret = m_completionRanges.begin()->range;
881 
882  foreach(const CompletionRange &range, m_completionRanges)
883  if(range.range->start() > ret->start())
884  ret = range.range;
885  return ret;
886  }
887  if(m_completionRanges.contains(model))
888  return m_completionRanges[model].range;
889  else
890  return 0;
891 }
892 
893 QMap<KTextEditor::CodeCompletionModel*, KateCompletionWidget::CompletionRange> KateCompletionWidget::completionRanges( ) const
894 {
895  return m_completionRanges;
896 }
897 
898 void KateCompletionWidget::modelReset( )
899 {
900  setUpdatesEnabled(false);
901  m_entryList->setAnimated(false);
902  m_argumentHintTree->setAnimated(false);
905  for(int row = 0; row < m_argumentHintModel->rowCount(QModelIndex()); ++row) {
906  QModelIndex index(m_argumentHintModel->index(row, 0, QModelIndex()));
907  if(!m_argumentHintTree->isExpanded(index)) {
908  m_argumentHintTree->expand(index);
909  }
910  }
911 
912  for(int row = 0; row < m_entryList->model()->rowCount(QModelIndex()); ++row) {
913  QModelIndex index(m_entryList->model()->index(row, 0, QModelIndex()));
914  if(!m_entryList->isExpanded(index)) {
915  m_entryList->expand(index);
916  }
917  }
918  setUpdatesEnabled(true);
919 }
920 
921 KateCompletionTree* KateCompletionWidget::treeView() const {
922  return m_entryList;
923 }
924 
925 QModelIndex KateCompletionWidget::selectedIndex() const {
926  if(!isCompletionActive())
927  return QModelIndex();
928 
929  if( m_inCompletionList )
930  return m_entryList->currentIndex();
931  else
932  return m_argumentHintTree->currentIndex();
933 }
934 
935 bool KateCompletionWidget::navigateLeft() {
936  m_hadCompletionNavigation = true;
937  if(currentEmbeddedWidget())
938  QMetaObject::invokeMethod(currentEmbeddedWidget(), "embeddedWidgetLeft");
939 
940  QModelIndex index = selectedIndex();
941 
942  if( index.isValid() ) {
943  index.data(KTextEditor::CodeCompletionModel::AccessibilityPrevious);
944 
945  return true;
946  }
947  return false;
948 }
949 
950 bool KateCompletionWidget::navigateRight() {
951  m_hadCompletionNavigation = true;
952  if(currentEmbeddedWidget())
953  QMetaObject::invokeMethod(currentEmbeddedWidget(), "embeddedWidgetRight");
954 
955  QModelIndex index = selectedIndex();
956 
957  if( index.isValid() ) {
958  index.data(KTextEditor::CodeCompletionModel::AccessibilityNext);
959  return true;
960  }
961 
962  return false;
963 }
964 
965 bool KateCompletionWidget::hadNavigation() const {
966  return m_hadCompletionNavigation;
967 }
968 
969 void KateCompletionWidget::resetHadNavigation() {
970  m_hadCompletionNavigation = false;
971 }
972 
973 
974 bool KateCompletionWidget::navigateBack() {
975  m_hadCompletionNavigation = true;
976  if(currentEmbeddedWidget())
977  QMetaObject::invokeMethod(currentEmbeddedWidget(), "embeddedWidgetBack");
978  return false;
979 }
980 
981 bool KateCompletionWidget::toggleExpanded(bool forceExpand, bool forceUnExpand) {
982  if ( (canExpandCurrentItem() || forceExpand ) && !forceUnExpand) {
983  bool ret = canExpandCurrentItem();
984  setCurrentItemExpanded(true);
985  return ret;
986  } else if (canCollapseCurrentItem() || forceUnExpand) {
987  bool ret = canCollapseCurrentItem();
988  setCurrentItemExpanded(false);
989  return ret;
990  }
991  return false;
992 }
993 
994 bool KateCompletionWidget::canExpandCurrentItem() const {
995  if( m_inCompletionList ) {
996  if( !m_entryList->currentIndex().isValid() ) return false;
997  return model()->isExpandable( m_entryList->currentIndex() ) && !model()->isExpanded( m_entryList->currentIndex() );
998  } else {
999  if( !m_argumentHintTree->currentIndex().isValid() ) return false;
1000  return argumentHintModel()->isExpandable( m_argumentHintTree->currentIndex() ) && !argumentHintModel()->isExpanded( m_argumentHintTree->currentIndex() );
1001  }
1002 }
1003 
1004 bool KateCompletionWidget::canCollapseCurrentItem() const {
1005  if( m_inCompletionList ) {
1006  if( !m_entryList->currentIndex().isValid() ) return false;
1007  return model()->isExpandable( m_entryList->currentIndex() ) && model()->isExpanded( m_entryList->currentIndex() );
1008  }else{
1009  if( !m_argumentHintTree->currentIndex().isValid() ) return false;
1010  return m_argumentHintModel->isExpandable( m_argumentHintTree->currentIndex() ) && m_argumentHintModel->isExpanded( m_argumentHintTree->currentIndex() );
1011  }
1012 }
1013 
1014 void KateCompletionWidget::setCurrentItemExpanded( bool expanded ) {
1015  if( m_inCompletionList ) {
1016  if( !m_entryList->currentIndex().isValid() ) return;
1017  model()->setExpanded(m_entryList->currentIndex(), expanded);
1018  updateHeight();
1019  }else{
1020  if( !m_argumentHintTree->currentIndex().isValid() ) return;
1021  m_argumentHintModel->setExpanded(m_argumentHintTree->currentIndex(), expanded);
1022  }
1023 }
1024 
1025 bool KateCompletionWidget::eventFilter( QObject * watched, QEvent * event )
1026 {
1027  bool ret = QFrame::eventFilter(watched, event);
1028 
1029  if (watched != this)
1030  if (event->type() == QEvent::Move)
1031  updatePosition();
1032 
1033  return ret;
1034 }
1035 
1036 bool KateCompletionWidget::navigateDown() {
1037  m_hadCompletionNavigation = true;
1038  if(currentEmbeddedWidget()) {
1039  QMetaObject::invokeMethod(currentEmbeddedWidget(), "embeddedWidgetDown");
1040  }
1041  return false;
1042 }
1043 
1044 bool KateCompletionWidget::navigateUp() {
1045  m_hadCompletionNavigation = true;
1046  if(currentEmbeddedWidget())
1047  QMetaObject::invokeMethod(currentEmbeddedWidget(), "embeddedWidgetUp");
1048  return false;
1049 }
1050 
1051 QWidget* KateCompletionWidget::currentEmbeddedWidget() {
1052  QModelIndex index = selectedIndex();
1053  if(!index.isValid())
1054  return 0;
1055  if( qobject_cast<const ExpandingWidgetModel*>(index.model()) ) {
1056  const ExpandingWidgetModel* model = static_cast<const ExpandingWidgetModel*>(index.model());
1057  if( model->isExpanded(index) )
1058  return model->expandingWidget(index);
1059  }
1060  return 0;
1061 }
1062 
1063 void KateCompletionWidget::cursorDown()
1064 {
1065  bool wasPartiallyExpanded = model()->partiallyExpandedRow().isValid();
1066 
1067  if( m_inCompletionList )
1068  m_entryList->nextCompletion();
1069  else {
1070  if( !m_argumentHintTree->nextCompletion() )
1071  switchList();
1072  }
1073 
1074  if(wasPartiallyExpanded != model()->partiallyExpandedRow().isValid())
1075  updateHeight();
1076 }
1077 
1078 void KateCompletionWidget::cursorUp()
1079 {
1080  bool wasPartiallyExpanded = model()->partiallyExpandedRow().isValid();
1081 
1082  if( m_inCompletionList ) {
1083  if( !m_entryList->previousCompletion() )
1084  switchList();
1085  }else{
1086  m_argumentHintTree->previousCompletion();
1087  }
1088 
1089  if(wasPartiallyExpanded != model()->partiallyExpandedRow().isValid())
1090  updateHeight();
1091 }
1092 
1093 void KateCompletionWidget::pageDown( )
1094 {
1095  bool wasPartiallyExpanded = model()->partiallyExpandedRow().isValid();
1096 
1097  if( m_inCompletionList )
1098  m_entryList->pageDown();
1099  else {
1100  if( !m_argumentHintTree->pageDown() )
1101  switchList();
1102  }
1103 
1104  if(wasPartiallyExpanded != model()->partiallyExpandedRow().isValid())
1105  updateHeight();
1106 }
1107 
1108 void KateCompletionWidget::pageUp( )
1109 {
1110  bool wasPartiallyExpanded = model()->partiallyExpandedRow().isValid();
1111 
1112  if( m_inCompletionList ) {
1113  if( !m_entryList->pageUp() )
1114  switchList();
1115  }else{
1116  m_argumentHintTree->pageUp();
1117  }
1118 
1119  if(wasPartiallyExpanded != model()->partiallyExpandedRow().isValid())
1120  updateHeight();
1121 }
1122 
1123 void KateCompletionWidget::top( )
1124 {
1125  bool wasPartiallyExpanded = model()->partiallyExpandedRow().isValid();
1126 
1127  if( m_inCompletionList )
1128  m_entryList->top();
1129  else
1130  m_argumentHintTree->top();
1131 
1132  if(wasPartiallyExpanded != model()->partiallyExpandedRow().isValid())
1133  updateHeight();
1134 }
1135 
1136 void KateCompletionWidget::bottom( )
1137 {
1138  bool wasPartiallyExpanded = model()->partiallyExpandedRow().isValid();
1139 
1140  if( m_inCompletionList )
1141  m_entryList->bottom();
1142  else
1143  m_argumentHintTree->bottom();
1144 
1145  if(wasPartiallyExpanded != model()->partiallyExpandedRow().isValid())
1146  updateHeight();
1147 }
1148 
1149 void KateCompletionWidget::switchList() {
1150  if( m_inCompletionList ) {
1151  if( m_argumentHintModel->rowCount(QModelIndex()) != 0 ) {
1152  m_entryList->setCurrentIndex(QModelIndex());
1153  m_argumentHintTree->setCurrentIndex(m_argumentHintModel->index(m_argumentHintModel->rowCount(QModelIndex())-1, 0));
1154  m_inCompletionList = false;
1155  }
1156  } else {
1157  if( m_presentationModel->rowCount(QModelIndex()) != 0 ) {
1158  m_argumentHintTree->setCurrentIndex(QModelIndex());
1159  m_entryList->setCurrentIndex(m_presentationModel->index(0, 0));
1160  if(model()->hasGroups()) //If we have groups we have to move on, because the first item is a label
1161  m_entryList->nextCompletion();
1162  m_inCompletionList = true;
1163  }
1164  }
1165 }
1166 
1167 void KateCompletionWidget::showConfig( )
1168 {
1169  abortCompletion();
1170 
1171  m_configWidget->exec();
1172 }
1173 
1174 void KateCompletionWidget::completionModelReset()
1175 {
1176  KTextEditor::CodeCompletionModel* model = qobject_cast<KTextEditor::CodeCompletionModel*>(sender());
1177  if(!model) {
1178  kWarning() << "bad sender";
1179  return;
1180  }
1181 
1182  if(!m_waitingForReset.contains(model))
1183  return;
1184 
1185  m_waitingForReset.remove(model);
1186 
1187  if(m_waitingForReset.isEmpty()) {
1188  if(!isCompletionActive()) {
1189  //kDebug() << "all completion-models we waited for are ready. Last one: " << model->objectName();
1190  //Eventually show the completion-list if this was the last model we were waiting for
1191  //Use a queued connection once again to make sure that KateCompletionModel is notified before we are
1192  QMetaObject::invokeMethod(this, "modelContentChanged", Qt::QueuedConnection);
1193  }
1194  }
1195 }
1196 
1197 void KateCompletionWidget::modelDestroyed(QObject* model) {
1198  unregisterCompletionModel(static_cast<KTextEditor::CodeCompletionModel*>(model));
1199 }
1200 
1201 void KateCompletionWidget::registerCompletionModel(KTextEditor::CodeCompletionModel* model)
1202 {
1203  if (m_sourceModels.contains(model)) {
1204  return;
1205  }
1206 
1207  connect(model, SIGNAL(destroyed(QObject*)), SLOT(modelDestroyed(QObject*)));
1208  //This connection must not be queued
1209  connect(model, SIGNAL(modelReset()), SLOT(completionModelReset()));
1210 
1211  m_sourceModels.append(model);
1212 
1213  if (isCompletionActive()) {
1214  m_presentationModel->addCompletionModel(model);
1215  }
1216 }
1217 
1218 void KateCompletionWidget::unregisterCompletionModel(KTextEditor::CodeCompletionModel* model)
1219 {
1220  disconnect(model, SIGNAL(destroyed(QObject*)), this, SLOT(modelDestroyed(QObject*)));
1221  disconnect(model, SIGNAL(modelReset()), this, SLOT(completionModelReset()));
1222 
1223  m_sourceModels.removeAll(model);
1224  abortCompletion();
1225 }
1226 
1227 int KateCompletionWidget::automaticInvocationDelay() const {
1228  return m_automaticInvocationDelay;
1229 }
1230 
1231 void KateCompletionWidget::setAutomaticInvocationDelay(int delay) {
1232  m_automaticInvocationDelay = delay;
1233 }
1234 
1235 void KateCompletionWidget::wrapLine (const KTextEditor::Cursor &)
1236 {
1237  m_lastInsertionByUser = !m_completionEditRunning;
1238 
1239  // wrap line, be done
1240  m_automaticInvocationLine.clear();
1241  m_automaticInvocationTimer->stop();
1242 }
1243 
1244 void KateCompletionWidget::unwrapLine (int)
1245 {
1246  m_lastInsertionByUser = !m_completionEditRunning;
1247 
1248  // just removal
1249  m_automaticInvocationLine.clear();
1250  m_automaticInvocationTimer->stop();
1251 }
1252 
1253 void KateCompletionWidget::insertText (const KTextEditor::Cursor &position, const QString &text)
1254 {
1255  m_lastInsertionByUser = !m_completionEditRunning;
1256 
1257  // no invoke?
1258  if (!view()->config()->automaticCompletionInvocation()) {
1259  m_automaticInvocationLine.clear();
1260  m_automaticInvocationTimer->stop();
1261  return;
1262  }
1263 
1264  if(m_automaticInvocationAt != position) {
1265  m_automaticInvocationLine.clear();
1266  m_lastInsertionByUser = !m_completionEditRunning;
1267  }
1268 
1269  m_automaticInvocationLine += text;
1270  m_automaticInvocationAt = position;
1271  m_automaticInvocationAt.setColumn (position.column() + text.length());
1272 
1273  if (m_automaticInvocationLine.isEmpty()) {
1274  m_automaticInvocationTimer->stop();
1275  return;
1276  }
1277 
1278  m_automaticInvocationTimer->start(m_automaticInvocationDelay);
1279 }
1280 
1281 void KateCompletionWidget::removeText (const KTextEditor::Range &)
1282 {
1283  m_lastInsertionByUser = !m_completionEditRunning;
1284 
1285  // just removal
1286  m_automaticInvocationLine.clear();
1287  m_automaticInvocationTimer->stop();
1288 }
1289 
1290 void KateCompletionWidget::automaticInvocation()
1291 {
1292  //kDebug()<<"m_automaticInvocationAt:"<<m_automaticInvocationAt;
1293  //kDebug()<<view()->cursorPosition();
1294  if(m_automaticInvocationAt != view()->cursorPosition())
1295  return;
1296 
1297  bool start = false;
1298  QList<KTextEditor::CodeCompletionModel*> models;
1299 
1300  //kDebug()<<"checking models";
1301  foreach (KTextEditor::CodeCompletionModel *model, m_sourceModels) {
1302  //kDebug()<<"m_completionRanges contains model?:"<<m_completionRanges.contains(model);
1303  if(m_completionRanges.contains(model))
1304  continue;
1305 
1306  start=_shouldStartCompletion(model,view(), m_automaticInvocationLine, m_lastInsertionByUser, view()->cursorPosition());
1307  //kDebug()<<"start="<<start;
1308  if (start)
1309  {
1310  models << model;
1311  }
1312  }
1313  //kDebug()<<"models found:"<<!models.isEmpty();
1314  if (!models.isEmpty()) {
1315  // Start automatic code completion
1316  startCompletion(KTextEditor::CodeCompletionModel::AutomaticInvocation, models);
1317  }
1318 }
1319 
1320 void KateCompletionWidget::userInvokedCompletion()
1321 {
1322  startCompletion(KTextEditor::CodeCompletionModel::UserInvocation);
1323 }
1324 
1325 void KateCompletionWidget::tab(bool shift)
1326 {
1327  m_noAutoHide = true;
1328  if(!shift) {
1329  QString prefix = m_presentationModel->commonPrefix((m_inCompletionList && !shellLikeTabCompletion) ? m_entryList->currentIndex() : QModelIndex());
1330  if(!prefix.isEmpty()) {
1331  view()->insertText(prefix);
1332  }else if(shellLikeTabCompletion) {
1333  cursorDown();
1334  return;
1335  }
1336  }else{
1337  if(shellLikeTabCompletion) {
1338  cursorUp();
1339  return;
1340  }
1341 
1342  //Reset left boundaries, so completion isn't stopped
1343  typedef QMap<KTextEditor::CodeCompletionModel*, CompletionRange> CompletionRangeMap;
1344  for(CompletionRangeMap::iterator it = m_completionRanges.begin(); it != m_completionRanges.end(); ++it)
1345  (*it).leftBoundary = (*it).range->start();
1346 
1347  //Remove suffix until the completion-list filter is widened again
1348  uint itemCount = m_presentationModel->filteredItemCount();
1349 
1350  while(view()->cursorPosition().column() > 0 && m_presentationModel->filteredItemCount() == itemCount) {
1351  KTextEditor::Range lastcharRange = KTextEditor::Range(view()->cursorPosition()-KTextEditor::Cursor(0,1), view()->cursorPosition());
1352  QString cursorText = view()->document()->text(lastcharRange);
1353  if(!cursorText[0].isSpace())
1354  {
1355  view()->document()->removeText(lastcharRange);
1356  QApplication::sendPostedEvents();
1357  }else{
1358  break;
1359  }
1360  }
1361  }
1362 }
1363 
1364 #include "katecompletionwidget.moc"
1365 
1366 // kate: space-indent on; indent-width 2; replace-tabs on;
KateCompletionModel::clearCompletionModels
void clearCompletionModels()
Definition: katecompletionmodel.cpp:2253
_shouldAbortCompletion
static bool _shouldAbortCompletion(KTextEditor::CodeCompletionModel *model, KTextEditor::View *view, const KTextEditor::Range &range, const QString &currentCompletion)
Definition: katecompletionwidget.cpp:85
kdialog.h
KateCompletionWidget::currentEmbeddedWidget
QWidget * currentEmbeddedWidget()
Definition: katecompletionwidget.cpp:1051
KTextEditor::Range::start
Cursor & start()
KateCompletionModel::mapFromSource
virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const
Maps from an index in a source-model to the index of the item in this display-model.
Definition: katecompletionmodel.cpp:892
CALLCI
#define CALLCI(WHAT, WHATELSE, WHAT2, model, FUNC)
Definition: katecompletionwidget.cpp:61
KTextEditor::CodeCompletionModel::Name
kateview.h
KateCompletionModel::completionModels
QList< KTextEditor::CodeCompletionModel * > completionModels() const
Definition: katecompletionmodel.cpp:2041
KateArgumentHintTree::pageDown
bool pageDown()
Definition: kateargumenthinttree.cpp:242
KateDocument::newMovingRange
virtual KTextEditor::MovingRange * newMovingRange(const KTextEditor::Range &range, KTextEditor::MovingRange::InsertBehaviors insertBehaviors=KTextEditor::MovingRange::DoNotExpand, KTextEditor::MovingRange::EmptyBehavior emptyBehavior=KTextEditor::MovingRange::AllowEmpty)
Create a new moving range for this document.
Definition: katedocument.cpp:4742
KateCompletionModel::setCompletionModels
void setCompletionModels(const QList< KTextEditor::CodeCompletionModel * > &models)
Definition: katecompletionmodel.cpp:2022
KateCompletionTree::setScrollingEnabled
void setScrollingEnabled(bool)
Definition: katecompletiontree.cpp:73
KateView::sendCompletionExecuted
void sendCompletionExecuted(const KTextEditor::Cursor &position, KTextEditor::CodeCompletionModel *model, const QModelIndex &index)
Definition: kateview.cpp:2364
KateCompletionModel::commonPrefix
QString commonPrefix(QModelIndex selectedIndex) const
Returns a common prefix for all current visible completion entries If there is no common prefix...
Definition: katecompletionmodel.cpp:1006
ExpandingWidgetModel::partiallyExpandedRow
QModelIndex partiallyExpandedRow() const
Returns the first row that is currently partially expanded.
Definition: expandingwidgetmodel.cpp:116
KateArgumentHintModel
Definition: kateargumenthintmodel.h:30
KateView::renderer
KateRenderer * renderer()
Definition: kateview.cpp:1653
KateView::document
KTextEditor::Document * document() const
Definition: kateview.cpp:2769
katerenderer.h
KTextEditor::CodeCompletionModel::UserInvocation
KateArgumentHintModel::mapToSource
QModelIndex mapToSource(const QModelIndex &proxyIndex) const
Definition: kateargumenthintmodel.cpp:39
KateCompletionWidget::pageDown
void pageDown()
Definition: katecompletionwidget.cpp:1093
KateCompletionWidget::showEvent
virtual void showEvent(QShowEvent *event)
Definition: katecompletionwidget.cpp:865
KTextEditor::Range::isValid
virtual bool isValid() const
KTextEditor::CodeCompletionModel::InvocationType
InvocationType
KateCompletionModel::mapToSource
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const
Maps from this display-model into the appropriate source code-completion model.
Definition: katecompletionmodel.cpp:875
timeout
int timeout
KTextEditor::CodeCompletionModel::AutomaticInvocation
katecompletiontree.h
KateCompletionWidget::cursorDown
void cursorDown()
Definition: katecompletionwidget.cpp:1063
KateCompletionWidget::waitForModelReset
void waitForModelReset()
Definition: katecompletionwidget.cpp:424
QWidget
KTextEditor::CodeCompletionModel::completionInvoked
virtual void completionInvoked(KTextEditor::View *view, const KTextEditor::Range &range, InvocationType invocationType)
KateCompletionWidget::navigateRight
bool navigateRight()
Definition: katecompletionwidget.cpp:950
katedocument.h
KateCompletionWidget::navigateBack
bool navigateBack()
Definition: katecompletionwidget.cpp:974
KateCompletionModel::filteredItemCount
uint filteredItemCount() const
Definition: katecompletionmodel.cpp:1712
KateCompletionWidget::KateCompletionWidget
KateCompletionWidget(KateView *parent)
Definition: katecompletionwidget.cpp:97
KateCompletionWidget::argumentHintsChanged
void argumentHintsChanged(bool hasContent)
Definition: katecompletionwidget.cpp:276
KateArgumentHintTree::pageUp
bool pageUp()
Definition: kateargumenthinttree.cpp:257
kateargumenthintmodel.h
KateCompletionWidget::automaticInvocation
void automaticInvocation()
Definition: katecompletionwidget.cpp:1290
KateCompletionModel
This class has the responsibility for filtering, sorting, and manipulating code completion data provi...
Definition: katecompletionmodel.h:48
KTextEditor::MovingRange
KateArgumentHintTree::clearCompletion
void clearCompletion()
Definition: kateargumenthinttree.cpp:56
QString
KateCompletionWidget::resetHadNavigation
void resetHadNavigation()
Definition: katecompletionwidget.cpp:969
KTextEditor::CodeCompletionModel2::executeCompletionItem2
virtual void executeCompletionItem2(Document *document, const Range &word, const QModelIndex &index) const
QObject
kDebug
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KTextEditor::Cursor
KateCompletionModel::setCurrentCompletion
void setCurrentCompletion(KTextEditor::CodeCompletionModel *model, const QString &completion)
Definition: katecompletionmodel.cpp:916
k_funcinfo
#define k_funcinfo
KateCompletionWidget::model
const KateCompletionModel * model() const
Definition: katecompletionwidget.cpp:252
ExpandingWidgetModel::isExpandable
bool isExpandable(const QModelIndex &index) const
Definition: expandingwidgetmodel.cpp:290
KateCompletionWidget::~KateCompletionWidget
~KateCompletionWidget()
Definition: katecompletionwidget.cpp:181
_aborted
static void _aborted(KTextEditor::CodeCompletionModel *model, KTextEditor::View *view)
Definition: katecompletionwidget.cpp:89
KateCompletionWidget::setCurrentItemExpanded
void setCurrentItemExpanded(bool)
Definition: katecompletionwidget.cpp:1014
KateCompletionTree::top
void top()
Definition: katecompletiontree.cpp:374
KateArgumentHintTree
Definition: kateargumenthinttree.h:30
prefix
QString prefix()
config
KSharedConfigPtr config()
katebuffer.h
KateCompletionWidget::setAutomaticInvocationDelay
void setAutomaticInvocationDelay(int delay)
Definition: katecompletionwidget.cpp:1231
KateCompletionWidget::unregisterCompletionModel
void unregisterCompletionModel(KTextEditor::CodeCompletionModel *model)
Definition: katecompletionwidget.cpp:1218
KateCompletionWidget::completionRanges
QMap< KTextEditor::CodeCompletionModel *, CompletionRange > completionRanges() const
Definition: katecompletionwidget.cpp:893
KateCompletionModel::removeCompletionModel
void removeCompletionModel(KTextEditor::CodeCompletionModel *model)
Definition: katecompletionmodel.cpp:2046
_shouldStartCompletion
static bool _shouldStartCompletion(KTextEditor::CodeCompletionModel *model, KTextEditor::View *view, QString m_automaticInvocationLine, bool m_lastInsertionByUser, const KTextEditor::Cursor &cursor)
Definition: katecompletionwidget.cpp:93
_completionRange
static KTextEditor::Range _completionRange(KTextEditor::CodeCompletionModel *model, KTextEditor::View *view, const KTextEditor::Cursor &cursor)
Definition: katecompletionwidget.cpp:73
shellLikeTabCompletion
const bool shellLikeTabCompletion
Definition: katecompletionwidget.cpp:59
KateCompletionWidget::toggleExpanded
bool toggleExpanded(bool forceExpand=false, bool forceUnExpand=false)
Returns whether the current item was expanded/unexpanded.
Definition: katecompletionwidget.cpp:981
KTextEditor::MovingRange::ExpandLeft
KateCompletionWidget::argumentHintTree
KateArgumentHintTree * argumentHintTree() const
Definition: katecompletionwidget.cpp:244
KTextEditor::CodeCompletionModel::rowCount
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
kateargumenthinttree.h
KateArgumentHintModel::buildRows
void buildRows()
Definition: kateargumenthintmodel.cpp:62
KateRenderer::config
KateRendererConfig * config() const
Configuration.
Definition: katerenderer.h:362
KTextEditor::Document::removeText
virtual bool removeText(const Range &range, bool block=false)=0
KateArgumentHintModel::rowCount
virtual int rowCount(const QModelIndex &parent) const
Definition: kateargumenthintmodel.cpp:226
KateArgumentHintTree::updateGeometry
void updateGeometry()
Definition: kateargumenthinttree.cpp:190
KateArgumentHintTree::bottom
void bottom()
Definition: kateargumenthinttree.cpp:283
KateCompletionWidget::view
KateView * view() const
Definition: katecompletionwidget.cpp:271
KateCompletionWidget::navigateUp
bool navigateUp()
Definition: katecompletionwidget.cpp:1044
KateCompletionWidget::bottom
void bottom()
Definition: katecompletionwidget.cpp:1136
KateView::cursorToCoordinate
QPoint cursorToCoordinate(const KTextEditor::Cursor &cursor) const
Definition: kateview.cpp:2408
hasAtLeastNRows
bool hasAtLeastNRows(int rows, QAbstractItemModel *model)
Definition: katecompletionwidget.cpp:537
ExpandingWidgetModel::expandingWidget
QWidget * expandingWidget(const QModelIndex &row) const
Definition: expandingwidgetmodel.cpp:431
KateCompletionModel::rowCount
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
Definition: katecompletionmodel.cpp:847
KateCompletionModel::columnCount
virtual int columnCount(const QModelIndex &parent=QModelIndex()) const
Definition: katecompletionmodel.cpp:373
KTextEditor::CodeCompletionModel::AccessibilityAccept
katecompletionmodel.h
KateCompletionWidget::top
void top()
Definition: katecompletionwidget.cpp:1123
KateCompletionWidget::cursorUp
void cursorUp()
Definition: katecompletionwidget.cpp:1078
KateArgumentHintTree::previousCompletion
bool previousCompletion()
Definition: kateargumenthinttree.cpp:218
katecompletionwidget.h
KateCompletionWidget::registerCompletionModel
void registerCompletionModel(KTextEditor::CodeCompletionModel *model)
Definition: katecompletionwidget.cpp:1201
KateArgumentHintModel::clear
void clear()
Definition: kateargumenthintmodel.cpp:34
KateCompletionWidget::updatePosition
bool updatePosition(bool force=false)
Definition: katecompletionwidget.cpp:480
KateCompletionTree::bottom
void bottom()
Definition: katecompletiontree.cpp:391
KateCompletionWidget::canCollapseCurrentItem
bool canCollapseCurrentItem() const
Definition: katecompletionwidget.cpp:1004
ExpandingWidgetModel::isExpanded
bool isExpanded(const QModelIndex &row) const
Definition: expandingwidgetmodel.cpp:305
KateView
Definition: kateview.h:78
QAbstractItemModel
KTextEditor::Range
KTextEditor::Document::text
virtual QString text() const =0
KateCompletionTree::pageUp
bool pageUp()
Definition: katecompletiontree.cpp:360
move
CopyJob * move(const KUrl &src, const KUrl &dest, JobFlags flags=DefaultFlags)
hideAutomaticCompletionOnExactMatch
const bool hideAutomaticCompletionOnExactMatch
Definition: katecompletionwidget.cpp:56
KateCompletionWidget::updateHeight
void updateHeight()
Called by KateViewInternal, because we need the specific information from the event.
Definition: katecompletionwidget.cpp:552
KateCompletionModel::index
virtual QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
Definition: katecompletionmodel.cpp:407
KateCompletionWidget::navigateAccept
bool navigateAccept()
Definition: katecompletionwidget.cpp:781
KateCompletionWidget::userInvokedCompletion
void userInvokedCompletion()
Definition: katecompletionwidget.cpp:1320
KateCompletionModel::translateColumn
int translateColumn(int sourceColumn) const
Definition: katecompletionmodel.cpp:1263
KateCompletionTree::resizeColumns
void resizeColumns(bool firstShow=false, bool forceResize=false)
Definition: katecompletiontree.cpp:114
KateArgumentHintTree::top
void top()
Definition: kateargumenthinttree.cpp:271
katecompletionconfig.h
_filterString
static QString _filterString(KTextEditor::CodeCompletionModel *model, KTextEditor::View *view, const KTextEditor::Range &range, const KTextEditor::Cursor &cursor)
Definition: katecompletionwidget.cpp:81
KTextEditor::MovingRange::ExpandRight
KateCompletionModel::addCompletionModel
void addCompletionModel(KTextEditor::CodeCompletionModel *model)
Definition: katecompletionmodel.cpp:2001
KateView::cursorPosition
KTextEditor::Cursor cursorPosition() const
Definition: kateview.cpp:2398
KateCompletionWidget::argumentHintModel
KateArgumentHintModel * argumentHintModel() const
Definition: katecompletionwidget.cpp:248
codecompletionmodelcontrollerinterface.h
KateCompletionWidget::isCompletionActive
bool isCompletionActive() const
Definition: katecompletionwidget.cpp:746
KTextEditor::MovingRange::start
virtual const MovingCursor & start() const =0
KTextEditor::View::insertText
virtual bool insertText(const QString &text)
KateCompletionWidget::resizeEvent
virtual void resizeEvent(QResizeEvent *event)
Definition: katecompletionwidget.cpp:860
ExpandingWidgetModel::setExpanded
void setExpanded(QModelIndex index, bool expanded)
Change the expand-state of the row given through index. The display will be updated.
Definition: expandingwidgetmodel.cpp:311
KateCompletionModel::shouldMatchHideCompletionList
bool shouldMatchHideCompletionList() const
Returns whether one of the filtered items exactly matches its completion string.
Definition: katecompletionmodel.cpp:1721
KateCompletionWidget::updatePositionSlot
void updatePositionSlot()
Definition: katecompletionwidget.cpp:475
QPoint
KTextEditor::CodeCompletionModel2
KateCompletionWidget::eventFilter
virtual bool eventFilter(QObject *watched, QEvent *event)
Definition: katecompletionwidget.cpp:1025
KateDocument::editEnd
void editEnd()
End a editor operation.
Definition: katedocument.cpp:796
QRect
KateCompletionWidget::navigateDown
bool navigateDown()
Definition: katecompletionwidget.cpp:1036
KateCompletionWidget::navigateLeft
bool navigateLeft()
Definition: katecompletionwidget.cpp:935
KateCompletionWidget::tab
void tab(bool shift)
Definition: katecompletionwidget.cpp:1325
KateCompletionTree::scheduleUpdate
void scheduleUpdate()
Definition: katecompletiontree.cpp:386
KateCompletionTree::nextCompletion
bool nextCompletion()
Definition: katecompletiontree.cpp:297
KateCompletionWidget::hadNavigation
bool hadNavigation() const
Definition: katecompletionwidget.cpp:965
KateCompletionWidget::startCompletion
void startCompletion(KTextEditor::CodeCompletionModel::InvocationType invocationType, const QList< KTextEditor::CodeCompletionModel * > &models=QList< KTextEditor::CodeCompletionModel * >())
Definition: katecompletionwidget.cpp:286
KTextEditor::CodeCompletionModel::executeCompletionItem
virtual void executeCompletionItem(Document *document, const Range &word, int row) const
KateCompletionWidget::CompletionRange::range
KTextEditor::MovingRange * range
Definition: katecompletionwidget.h:103
KateCompletionModel::hasGroups
bool hasGroups() const
Definition: katecompletionmodel.cpp:783
KateView::sendCompletionAborted
void sendCompletionAborted()
Definition: kateview.cpp:2369
KateCompletionWidget::pageUp
void pageUp()
Definition: katecompletionwidget.cpp:1108
_updateRange
static KTextEditor::Range _updateRange(KTextEditor::CodeCompletionModel *model, KTextEditor::View *view, KTextEditor::Range &range)
Definition: katecompletionwidget.cpp:77
KateDocument::text
virtual QString text(const KTextEditor::Range &range, bool blockwise=false) const
Definition: katedocument.cpp:337
KTextEditor::CodeCompletionModel::AccessibilityNext
kWarning
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KateCompletionTree::columnTextViewportPosition
int columnTextViewportPosition(int column) const
Returns the approximated viewport position of the text in the given column, skipping an eventual icon...
Definition: katecompletiontree.cpp:86
QSize
KateView::doc
KateDocument * doc()
accessor to katedocument pointer
Definition: kateview.h:552
KateCompletionTree::previousCompletion
bool previousCompletion()
Definition: katecompletiontree.cpp:320
KateCompletionConfig
Definition: katecompletionconfig.h:36
KateRendererConfig::fontMetrics
const QFontMetricsF & fontMetrics() const
Definition: kateconfig.cpp:2135
KTextEditor::MovingCursor::StayOnInsert
KateDocument::editStart
void editStart()
Enclose editor actions with editStart() and editEnd() to group them.
Definition: katedocument.cpp:776
KTextEditor::View
kicon.h
KateArgumentHintTree::nextCompletion
bool nextCompletion()
Definition: kateargumenthinttree.cpp:194
KateCompletionWidget::canExpandCurrentItem
bool canExpandCurrentItem() const
Definition: katecompletionwidget.cpp:994
KateCompletionTree
Definition: katecompletiontree.h:32
KateCompletionWidget::abortCompletion
void abortCompletion()
Definition: katecompletionwidget.cpp:751
KateCompletionWidget::treeView
KateCompletionTree * treeView() const
Definition: katecompletionwidget.cpp:921
QEvent
QFrame
KateCompletionTree::pageDown
bool pageDown()
Definition: katecompletiontree.cpp:344
kateconfig.h
KTextEditor::Cursor::setColumn
virtual void setColumn(int column)
KTextEditor::Cursor::column
int column() const
KTextEditor::Document::replaceText
virtual bool replaceText(const Range &range, const QString &text, bool block=false)
KateCompletionWidget::automaticInvocationDelay
int automaticInvocationDelay() const
Definition: katecompletionwidget.cpp:1227
ExpandingWidgetModel::expandingWidgetsHeight
int expandingWidgetsHeight() const
Returns the total height added through all open expanding-widgets.
Definition: expandingwidgetmodel.cpp:420
KateCompletionWidget::execute
void execute()
Definition: katecompletionwidget.cpp:795
QMap< KTextEditor::CodeCompletionModel *, KateCompletionWidget::CompletionRange >
KateCompletionWidget::completionRange
KTextEditor::MovingRange * completionRange(KTextEditor::CodeCompletionModel *model=0) const
Definition: katecompletionwidget.cpp:875
KateCompletionWidget::CompletionRange
Definition: katecompletionwidget.h:93
KTextEditor::CodeCompletionModel::AccessibilityPrevious
QList< KTextEditor::CodeCompletionModel * >
ExpandingWidgetModel
Cares about expanding/un-expanding items in a tree-view together with ExpandingDelegate.
Definition: expandingwidgetmodel.h:36
KTextEditor::CodeCompletionModel
KateCompletionWidget::showConfig
void showConfig()
Definition: katecompletionwidget.cpp:1167
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:31:51 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Kate

Skip menu "Kate"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

applications API Reference

Skip menu "applications API Reference"
  •   kate
  •       kate
  •   KTextEditor
  •   Kate
  • Applications
  •   Libraries
  •     libkonq
  • Konsole

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