Преглед на файлове

Implement argument hint popups.

git-svn-id: file:///var/svn/tigccpp/trunk@855 9552661e-59e3-4036-b4f2-dbe53926924f
kevinkofler преди 18 години
родител
ревизия
508470b581
променени са 4 файла, в които са добавени 144 реда и са изтрити 38 реда
  1. 72 0
      ktigcc/completion.cpp
  2. 16 0
      ktigcc/completion.h
  3. 33 20
      ktigcc/mainform.ui.h
  4. 23 18
      ktigcc/srcfilewin.ui.h

+ 72 - 0
ktigcc/completion.cpp

@@ -216,6 +216,21 @@ static QValueList<KTextEditor::CompletionEntry> sortCompletionEntries(
   return result;
 }
 
+static QStringList prototypesForIdentifier(const QString &identifier,
+  const QValueList<KTextEditor::CompletionEntry> &entries)
+{
+  QStringList result;
+  for (QValueList<KTextEditor::CompletionEntry>::ConstIterator it=entries.begin();
+       it!=entries.end(); ++it) {
+    const KTextEditor::CompletionEntry &entry=*it;
+    if (entry.text==identifier) {
+      QString prototype=entry.prefix+' '+entry.text+entry.postfix;
+      if (result.find(prototype)==result.end()) result.append(prototype);
+    }
+  }
+  return result;
+}
+
 bool parseHelpSources(QWidget *parent, const QString &directory,
                       QMap<QString,CompletionInfo> &sysHdrCompletion)
 {
@@ -562,3 +577,60 @@ bool CompletionPopup::eventFilter(QObject *o, QEvent *e)
   }
   return false;
 }
+
+ArgHintPopup::ArgHintPopup(Kate::View *parent, const QString &fileName,
+                           MainForm *mainForm)
+  : QObject(parent), done(false), argHintPopup(0)
+{
+  QValueList<KTextEditor::CompletionEntry> entries;
+  if (!completionEntriesForFile(parent->getDoc()->text(),fileName,mainForm,
+                                entries)) {
+    nothingFound:
+    deleteLater();
+    return;
+  }
+  unsigned column=parent->cursorColumnReal();
+  if (!column || !--column) goto nothingFound;
+  QString textLine=parent->currentTextLine();
+  if (column>textLine.length() || textLine[column]!='(') goto nothingFound;
+  unsigned startColumn=column, endColumn=column;
+  while (column && (textLine[--column].isLetterOrNumber()
+                    || textLine[column]=='_' || textLine[column]=='$'))
+    startColumn--;
+  QString identifier=textLine.mid(startColumn,endColumn-startColumn);
+  QStringList prototypes=prototypesForIdentifier(identifier,entries);
+  if (prototypes.isEmpty()) goto nothingFound;  
+  connect(parent,SIGNAL(argHintHidden()),this,SLOT(slotDone()));
+  parent->showArgHint(prototypes,"()",",");
+  // Unfortunately, Kate doesn't always send the argHintHidden event when it
+  // closes its popup. Work around that.
+  QWidgetList *list=QApplication::topLevelWidgets();
+  QWidgetListIt it(*list);
+  while (QWidget *w=it.current()) {
+    ++it;
+    if (w->isVisible() && w->testWFlags(Qt::WType_Popup)) {
+      argHintPopup=w;
+      break;      
+    }
+  }
+  delete list;
+  if (argHintPopup)
+    argHintPopup->installEventFilter(this);
+}
+
+void ArgHintPopup::slotDone()
+{
+  if (!done) {
+    done=true;
+    deleteLater();
+  }
+}
+
+bool ArgHintPopup::eventFilter(QObject *o, QEvent *e)
+{
+  if (!done && o==argHintPopup && e->type()==QEvent::Hide) {
+    done=true;
+    deleteLater();
+  }
+  return false;
+}

+ 16 - 0
ktigcc/completion.h

@@ -94,3 +94,19 @@ class CompletionPopup : public QObject {
     bool done;
     QWidget *completionPopup;
 };
+
+class ArgHintPopup : public QObject {
+  Q_OBJECT
+
+  public:
+    ArgHintPopup(Kate::View *parent, const QString &fileName,
+                 MainForm *mainForm);
+    virtual ~ArgHintPopup() {}
+  private slots:
+    void slotDone();
+  protected:
+    bool eventFilter(QObject *o, QEvent *e);
+  private:
+    bool done;
+    QWidget *argHintPopup;
+};

+ 33 - 20
ktigcc/mainform.ui.h

@@ -5945,26 +5945,39 @@ void MainForm::current_view_selectionChanged()
 
 void MainForm::current_view_charactersInteractivelyInserted(int line, int col, const QString &characters)
 {
-  if (CURRENT_VIEW && preferences.autoBlocks && !characters.compare("{")
-      && col==CURRENT_VIEW->getDoc()->lineLength(line)-1) {
-    Kate::Document *doc=CURRENT_VIEW->getDoc();
-    CATEGORY_OF(category,currentListItem);
-    QString fileText=doc->text();
-    // Only for C files.
-    if (category==cFilesListItem||category==qllFilesListItem
-        ||(category==hFilesListItem&&(fileText.isNull()||fileText.isEmpty()||(fileText[0]!='|'&&fileText[0]!=';')))) {
-      QString indent=doc->textLine(line);
-      // Only if the line was all whitespace, otherwise wait for Enter to be
-      // pressed (prevents annoying the user while typing a string or something).
-      if (indent.contains(QRegExp("^\\s*\\{$"))) {
-        indent=indent.remove('{');
-        QString cursorLine=indent+"\t";
-        KTextEditor::EditInterfaceExt *editExt=KTextEditor::editInterfaceExt(doc);
-        editExt->editBegin();
-        doc->insertLine(line+1,cursorLine);
-        doc->insertLine(line+2,indent+"}");
-        editExt->editEnd();
-        CURRENT_VIEW->setCursorPositionReal(line+1,cursorLine.length());
+  if (CURRENT_VIEW) {
+    if (preferences.autoBlocks && characters=="{"
+        && col==CURRENT_VIEW->getDoc()->lineLength(line)-1) {
+      Kate::Document *doc=CURRENT_VIEW->getDoc();
+      CATEGORY_OF(category,currentListItem);
+      QString fileText=doc->text();
+      // Only for C files.
+      if (category==cFilesListItem||category==qllFilesListItem
+          ||(category==hFilesListItem&&(fileText.isNull()||fileText.isEmpty()||(fileText[0]!='|'&&fileText[0]!=';')))) {
+        QString indent=doc->textLine(line);
+        // Only if the line was all whitespace, otherwise wait for Enter to be
+        // pressed (prevents annoying the user while typing a string or something).
+        if (indent.contains(QRegExp("^\\s*\\{$"))) {
+          indent=indent.remove('{');
+          QString cursorLine=indent+"\t";
+          KTextEditor::EditInterfaceExt *editExt=KTextEditor::editInterfaceExt(doc);
+          editExt->editBegin();
+          doc->insertLine(line+1,cursorLine);
+          doc->insertLine(line+2,indent+"}");
+          editExt->editEnd();
+          CURRENT_VIEW->setCursorPositionReal(line+1,cursorLine.length());
+        }
+      }
+    }
+    if (IS_FILE(currentListItem)
+        && CURRENT_VIEW==static_cast<ListViewFile *>(currentListItem)->kateView
+        && characters=="(") {
+      QString fileText=CURRENT_VIEW->getDoc()->text();
+      CATEGORY_OF(category,currentListItem);
+      // Completion only operates on C files.
+      if (category==cFilesListItem || category==qllFilesListItem
+          || (category==hFilesListItem && fileText[0]!='|' && fileText[0]!=';')) {
+        new ArgHintPopup(CURRENT_VIEW,pathInProject(currentListItem),this);
       }
     }
   }

+ 23 - 18
ktigcc/srcfilewin.ui.h

@@ -1198,26 +1198,31 @@ void SourceFileWindow::current_view_selectionChanged()
 
 void SourceFileWindow::current_view_charactersInteractivelyInserted(int line, int col, const QString &characters)
 {
-  if (CURRENT_VIEW && preferences.autoBlocks && !characters.compare("{")
-      && col==CURRENT_VIEW->getDoc()->lineLength(line)-1) {
-    Kate::Document *doc=CURRENT_VIEW->getDoc();
-    QString fileText=doc->text();
-    // Only for C files.
-    if (THIS->isCFile) {
-      QString indent=doc->textLine(line);
-      // Only if the line was all whitespace, otherwise wait for Enter to be
-      // pressed (prevents annoying the user while typing a string or something).
-      if (indent.contains(QRegExp("^\\s*\\{$"))) {
-        indent=indent.remove('{');
-        QString cursorLine=indent+"\t";
-        KTextEditor::EditInterfaceExt *editExt=KTextEditor::editInterfaceExt(doc);
-        editExt->editBegin();
-        doc->insertLine(line+1,cursorLine);
-        doc->insertLine(line+2,indent+"}");
-        editExt->editEnd();
-        CURRENT_VIEW->setCursorPositionReal(line+1,cursorLine.length());
+  if (CURRENT_VIEW) {
+    if (preferences.autoBlocks && characters=="{"
+        && col==CURRENT_VIEW->getDoc()->lineLength(line)-1) {
+      Kate::Document *doc=CURRENT_VIEW->getDoc();
+      QString fileText=doc->text();
+      // Only for C files.
+      if (THIS->isCFile) {
+        QString indent=doc->textLine(line);
+        // Only if the line was all whitespace, otherwise wait for Enter to be
+        // pressed (prevents annoying the user while typing a string or something).
+        if (indent.contains(QRegExp("^\\s*\\{$"))) {
+          indent=indent.remove('{');
+          QString cursorLine=indent+"\t";
+          KTextEditor::EditInterfaceExt *editExt=KTextEditor::editInterfaceExt(doc);
+          editExt->editBegin();
+          doc->insertLine(line+1,cursorLine);
+          doc->insertLine(line+2,indent+"}");
+          editExt->editEnd();
+          CURRENT_VIEW->setCursorPositionReal(line+1,cursorLine.length());
+        }
       }
     }
+    // Completion only operates on C files.
+    if (characters=="(" && THIS->isCFile)
+      new ArgHintPopup(CURRENT_VIEW,THIS->fileName,THIS->mainForm);
   }
 }