- function tips done

This commit is contained in:
royqh1979@gmail.com 2021-09-25 21:34:10 +08:00
parent 168cb49218
commit dc807f527c
9 changed files with 682 additions and 488 deletions

View File

@ -1,4 +1,5 @@
Version 0.2 Version 0.2
- enhancement: function tips
- enhancement: project support - enhancement: project support
- enhancement: paint color editor use system palette's disabled group color - enhancement: paint color editor use system palette's disabled group color
- fix: add watch not work when there's no editor openned; - fix: add watch not work when there's no editor openned;

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -464,6 +464,7 @@ void Editor::focusOutEvent(QFocusEvent *event)
pMainWindow->updateEditorActions(); pMainWindow->updateEditorActions();
pMainWindow->updateStatusbarForLineCol(); pMainWindow->updateStatusbarForLineCol();
pMainWindow->updateForStatusbarModeInfo(); pMainWindow->updateForStatusbarModeInfo();
pMainWindow->functionTip()->hide();
} }
void Editor::keyPressEvent(QKeyEvent *event) void Editor::keyPressEvent(QKeyEvent *event)
@ -1784,6 +1785,7 @@ void Editor::showCompletion(bool autoComplete)
}); });
mCompletionPopup->setParser(mParser); mCompletionPopup->setParser(mParser);
mCompletionPopup->setUseCppKeyword(mUseCppSyntax); mCompletionPopup->setUseCppKeyword(mUseCppSyntax);
pMainWindow->functionTip()->hide();
mCompletionPopup->show(); mCompletionPopup->show();
// Scan the current function body // Scan the current function body
@ -1842,6 +1844,7 @@ void Editor::showHeaderCompletion(bool autoComplete)
if (word.lastIndexOf('"')>0 || word.lastIndexOf('>')>0) if (word.lastIndexOf('"')>0 || word.lastIndexOf('>')>0)
return; return;
pMainWindow->functionTip()->hide();
mHeaderCompletionPopup->show(); mHeaderCompletionPopup->show();
mHeaderCompletionPopup->setSearchLocal(word.startsWith('"')); mHeaderCompletionPopup->setSearchLocal(word.startsWith('"'));
word.remove(0,1); word.remove(0,1);
@ -2246,6 +2249,10 @@ QString Editor::getHintForFunction(const PStatement &statement, const PStatement
void Editor::updateFunctionTip() void Editor::updateFunctionTip()
{ {
if (pMainWindow->completionPopup()->isVisible()) {
pMainWindow->functionTip()->hide();
return;
}
BufferCoord caretPos = caretXY(); BufferCoord caretPos = caretXY();
ContentsCoord curPos = fromBufferCoord(caretPos); ContentsCoord curPos = fromBufferCoord(caretPos);
ContentsCoord cursorPos = curPos; ContentsCoord cursorPos = curPos;
@ -2257,6 +2264,7 @@ void Editor::updateFunctionTip()
// Stopping characters... // Stopping characters...
QChar ch = *curPos; QChar ch = *curPos;
if (ch == '\0' || ch == ';') { if (ch == '\0' || ch == ';') {
pMainWindow->functionTip()->hide();
return; return;
// Opening brace, increase count // Opening brace, increase count
} }
@ -2299,14 +2307,17 @@ void Editor::updateFunctionTip()
curPos += 1; curPos += 1;
} }
//qDebug()<<"first pass:"<<nBraces<<" "<<curPos.line()<<":"<<curPos.ch()<<" - '"<<*curPos<<"'";
// If we couldn't find the closing brace or reached the FMaxScanLength... // If we couldn't find the closing brace or reached the FMaxScanLength...
if (nBraces!=-1) { if (nBraces!=-1) {
pMainWindow->functionTip()->hide();
return; return;
} }
ContentsCoord FFunctionEnd = curPos; ContentsCoord FFunctionEnd = curPos;
int paramPos = 0; int paramPos = 0;
bool paramPosFounded = false;
// We've stopped at the ending ), start walking backwards )*here* with nBraces = -1 // We've stopped at the ending ), start walking backwards )*here* with nBraces = -1
for (int i=0;i<FMaxScanLength;i++) { for (int i=0;i<FMaxScanLength;i++) {
QChar ch = *curPos; QChar ch = *curPos;
@ -2316,8 +2327,10 @@ void Editor::updateFunctionTip()
curPos -= 1; curPos -= 1;
ch = *(curPos); ch = *(curPos);
prevCh = *(curPos-1); prevCh = *(curPos-1);
if (prevCh == '\0') if (prevCh == '\0') {
pMainWindow->functionTip()->hide();
return; return;
}
if (prevCh == '/' && ch == '*' ) { if (prevCh == '/' && ch == '*' ) {
curPos -= 1; curPos -= 1;
break; break;
@ -2331,8 +2344,9 @@ void Editor::updateFunctionTip()
break;; break;;
} else if (ch == ',') { } else if (ch == ',') {
if (nBraces == 0) { if (nBraces == 0) {
if (curPos <= cursorPos) { if (curPos <= cursorPos && !paramPosFounded) {
paramPos = nCommas; paramPos = nCommas;
paramPosFounded = true;
} }
nCommas++; nCommas++;
} }
@ -2341,10 +2355,13 @@ void Editor::updateFunctionTip()
if (curPos.atStart()) if (curPos.atStart())
break; break;
} }
paramPos = nCommas - paramPos; if (paramPosFounded)
paramPos = nCommas - paramPos;
//qDebug()<<"second pass:"<<nBraces<<","<<nCommas<<","<<paramPos<<" "<<curPos.line()<<":"<<curPos.ch()<<" - '"<<*curPos<<"'";
// If we couldn't find the closing brace or reached the FMaxScanLength... // If we couldn't find the closing brace or reached the FMaxScanLength...
if (nBraces!=-1) { if (nBraces!=-1) {
pMainWindow->functionTip()->hide();
return; return;
} }
@ -2362,22 +2379,31 @@ void Editor::updateFunctionTip()
} }
ContentsCoord prevPos = curPos-1; ContentsCoord prevPos = curPos-1;
if (prevPos.atStart()) if (prevPos.atStart()) {
pMainWindow->functionTip()->hide();
return; return;
}
// Get the name of the function we're about to show // Get the name of the function we're about to show
BufferCoord FuncStartXY = prevPos.toBufferCoord(); BufferCoord FuncStartXY = prevPos.toBufferCoord();
QString token; QString token;
PSynHighlighterAttribute HLAttr; PSynHighlighterAttribute HLAttr;
if (!getHighlighterAttriAtRowCol(FuncStartXY,token,HLAttr)) { if (!getHighlighterAttriAtRowCol(FuncStartXY,token,HLAttr)) {
pMainWindow->functionTip()->hide();
return; return;
} }
if (HLAttr->name()!=SYNS_AttrIdentifier) if (HLAttr->name()!=SYNS_AttrIdentifier) {
pMainWindow->functionTip()->hide();
return; return;
}
BufferCoord pWordBegin, pWordEnd; BufferCoord pWordBegin, pWordEnd;
QString s = getWordAtPosition(this, FuncStartXY, pWordBegin,pWordEnd, WordPurpose::wpInformation); QString s = getWordAtPosition(this, FuncStartXY, pWordBegin,pWordEnd, WordPurpose::wpInformation);
// qDebug()<<QString("find word at %1:%2 - '%3'")
// .arg(FuncStartXY.Line)
// .arg(FuncStartXY.Char)
// .arg(s);
// Don't bother scanning the database when there's no identifier to scan for // Don't bother scanning the database when there's no identifier to scan for
// Only do the cumbersome list filling when showing a new tooltip... // Only do the cumbersome list filling when showing a new tooltip...
@ -2401,8 +2427,13 @@ void Editor::updateFunctionTip()
// If we can't find it in our database, hide // If we can't find it in our database, hide
if (pMainWindow->functionTip()->tipCount()<=0) { if (pMainWindow->functionTip()->tipCount()<=0) {
pMainWindow->functionTip()->hide();
return; return;
} }
// Position it at the top of the next line
QPoint p = rowColumnToPixels(displayXY());
p+=QPoint(0,textHeight()+2);
pMainWindow->functionTip()->move(mapToGlobal(p));
pMainWindow->functionTip()->setFunctioFullName(s); pMainWindow->functionTip()->setFunctioFullName(s);
pMainWindow->functionTip()->guessFunction(nCommas); pMainWindow->functionTip()->guessFunction(nCommas);
@ -2410,32 +2441,6 @@ void Editor::updateFunctionTip()
paramPos paramPos
); );
pMainWindow->functionTip()->show(); pMainWindow->functionTip()->show();
//// // get the current token position in the text
//// // this is where the prototype name usually starts
//// FTokenPos := CurPos - Length(S);
//// Search for the best possible overload match according to comma count
//if (shoFindBestMatchingToolTip in FOptions) then
// // Only do so when the user didn't select his own
// if not FCustomSelIndex then
// S := FindClosestToolTip(S, nCommas);
//// Select the current one
//if (FSelIndex < FToolTips.Count) then
// S := FToolTips.Strings[FSelIndex];
//// set the hint caption
//Caption := Trim(S);
//// we use the LookupEditor to get the highlighter-attributes
//// from. check the DrawAdvanced method!
//FLookupEditor.Text := Caption;
//FLookupEditor.Highlighter := FEditor.Highlighter;
//// get the index of the current argument (where the cursor is)
//FCurParamIndex := GetCommaIndex(P, FFunctionStart + 1, CaretPos - 1);
//RethinkCoordAndActivate;
} }
void Editor::setInProject(bool newInProject) void Editor::setInProject(bool newInProject)

View File

@ -926,7 +926,7 @@
<widget class="QStatusBar" name="statusbar"/> <widget class="QStatusBar" name="statusbar"/>
<widget class="QToolBar" name="toolbarMain"> <widget class="QToolBar" name="toolbarMain">
<property name="windowTitle"> <property name="windowTitle">
<string>toolBar</string> <string>Main</string>
</property> </property>
<property name="iconSize"> <property name="iconSize">
<size> <size>
@ -947,7 +947,7 @@
</widget> </widget>
<widget class="QToolBar" name="toolbarCode"> <widget class="QToolBar" name="toolbarCode">
<property name="windowTitle"> <property name="windowTitle">
<string>toolBar</string> <string>Code</string>
</property> </property>
<attribute name="toolBarArea"> <attribute name="toolBarArea">
<enum>TopToolBarArea</enum> <enum>TopToolBarArea</enum>
@ -962,7 +962,7 @@
</widget> </widget>
<widget class="QToolBar" name="toolbarCompile"> <widget class="QToolBar" name="toolbarCompile">
<property name="windowTitle"> <property name="windowTitle">
<string>toolBar</string> <string>Compile</string>
</property> </property>
<property name="iconSize"> <property name="iconSize">
<size> <size>
@ -983,7 +983,7 @@
</widget> </widget>
<widget class="QToolBar" name="toolbarDebug"> <widget class="QToolBar" name="toolbarDebug">
<property name="windowTitle"> <property name="windowTitle">
<string>toolBar</string> <string>Debug</string>
</property> </property>
<property name="iconSize"> <property name="iconSize">
<size> <size>
@ -1008,7 +1008,7 @@
</widget> </widget>
<widget class="QToolBar" name="toolbarCompilerSet"> <widget class="QToolBar" name="toolbarCompilerSet">
<property name="windowTitle"> <property name="windowTitle">
<string>toolBar_2</string> <string>Compiler Set</string>
</property> </property>
<property name="iconSize"> <property name="iconSize">
<size> <size>

View File

@ -594,7 +594,6 @@ void CppTokenizer::advance()
mCurrent++; mCurrent++;
break; break;
case '\\': case '\\':
if (isLineChar(*(mCurrent + 1))) if (isLineChar(*(mCurrent + 1)))
skipSplitLine(); skipSplitLine();
else else

View File

@ -204,9 +204,10 @@ QChar ContentsCoord::operator*() const
return QChar('\0'); return QChar('\0');
} }
QString s = mEdit->lines()->getString(mLine-1); QString s = mEdit->lines()->getString(mLine-1);
if (mChar > s.length()+1 ) { if (mChar >= s.length()+1 ) {
return QChar('\n'); return QChar('\n');
} }
//qDebug()<<mLine<<":"<<mChar<<" '"<<s<<"'";
return s[mChar-1]; return s[mChar-1];
} }

View File

@ -1,10 +1,11 @@
#include "functiontooltipwidget.h" #include "functiontooltipwidget.h"
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QPushButton>
FunctionTooltipWidget::FunctionTooltipWidget(QWidget *parent) : QWidget(parent) FunctionTooltipWidget::FunctionTooltipWidget(QWidget *parent) :
QFrame(parent, Qt::ToolTip | Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus)
{ {
setWindowFlags(Qt::Popup);
setFocusPolicy(Qt::NoFocus); setFocusPolicy(Qt::NoFocus);
mInfoLabel = new QLabel(this); mInfoLabel = new QLabel(this);
mInfoLabel->setWordWrap(true); mInfoLabel->setWordWrap(true);
@ -21,12 +22,17 @@ FunctionTooltipWidget::FunctionTooltipWidget(QWidget *parent) : QWidget(parent)
mDownButton->setFixedSize(16, 16); mDownButton->setFixedSize(16, 16);
mDownButton->setAutoRaise(true); mDownButton->setAutoRaise(true);
this->setLayout(new QHBoxLayout()); this->setLayout(new QHBoxLayout());
layout()->setContentsMargins(0,0,0,0);
layout()->setSpacing(0);
layout()->addWidget(mUpButton); layout()->addWidget(mUpButton);
layout()->addWidget(mTotalLabel); layout()->addWidget(mTotalLabel);
layout()->addWidget(mDownButton); layout()->addWidget(mDownButton);
layout()->addWidget(mInfoLabel); layout()->addWidget(mInfoLabel);
connect(mUpButton,&QPushButton::clicked,
this,&FunctionTooltipWidget::previousTip);
connect(mDownButton,&QPushButton::clicked,
this,&FunctionTooltipWidget::nextTip);
} }
void FunctionTooltipWidget::addTip(const QString &name, const QString& fullname, void FunctionTooltipWidget::addTip(const QString &name, const QString& fullname,
@ -102,11 +108,23 @@ void FunctionTooltipWidget::updateTip()
} }
text += "( "+displayList.join(", ") + ") "; text += "( "+displayList.join(", ") + ") ";
} }
if (mInfos.length()>1) {
mTotalLabel->setText(QString("%1/%2").arg(mInfoIndex+1).arg(mInfos.length()));
}
int width = mInfoLabel->fontMetrics().horizontalAdvance(text);
if (width > 400) {
mInfoLabel->setMinimumWidth(410);
} else {
mInfoLabel->setMinimumWidth(width);
}
mInfoLabel->setText(text); mInfoLabel->setText(text);
} }
void FunctionTooltipWidget::guessFunction(int commas) void FunctionTooltipWidget::guessFunction(int commas)
{ {
if (mInfoIndex>=0 && mInfoIndex<mInfos.count()
&& mInfos[mInfoIndex]->params.count()>commas)
return;
for (int i=0;i<mInfos.size();i++) { for (int i=0;i<mInfos.size();i++) {
if (mInfos[i]->params.count()>commas) { if (mInfos[i]->params.count()>commas) {
mInfoIndex = i; mInfoIndex = i;
@ -141,6 +159,8 @@ QStringList FunctionTooltipWidget::splitArgs(QString argStr)
QString s = argStr.mid(paramStart,i-paramStart); QString s = argStr.mid(paramStart,i-paramStart);
s=s.trimmed(); s=s.trimmed();
if (!s.isEmpty()) { if (!s.isEmpty()) {
if (s.endsWith(')'))
s.truncate(s.length()-1);
result.append(s); result.append(s);
} }
return result; return result;
@ -164,6 +184,7 @@ int FunctionTooltipWidget::paramIndex() const
void FunctionTooltipWidget::setParamIndex(int newParamIndex) void FunctionTooltipWidget::setParamIndex(int newParamIndex)
{ {
mParamIndex = newParamIndex; mParamIndex = newParamIndex;
updateTip();
} }
void FunctionTooltipWidget::closeEvent(QCloseEvent *) void FunctionTooltipWidget::closeEvent(QCloseEvent *)
@ -179,7 +200,8 @@ void FunctionTooltipWidget::showEvent(QShowEvent *)
updateTip(); updateTip();
} }
void FunctionTooltipWidget::hideEvent(QHideEvent *event) void FunctionTooltipWidget::hideEvent(QHideEvent *)
{ {
mInfos.clear(); mInfos.clear();
mFunctioFullName = "";
} }

View File

@ -14,7 +14,7 @@ struct FunctionInfo {
using PFunctionInfo = std::shared_ptr<FunctionInfo>; using PFunctionInfo = std::shared_ptr<FunctionInfo>;
class FunctionTooltipWidget : public QWidget class FunctionTooltipWidget : public QFrame
{ {
Q_OBJECT Q_OBJECT
public: public: