From: <da...@us...> - 2006-03-01 16:55:42
|
Revision: 1908 Author: dandfra Date: 2006-03-01 08:55:26 -0800 (Wed, 01 Mar 2006) ViewCVS: http://svn.sourceforge.net/tora/?rev=1908&view=rev Log Message: ----------- Autocompletion prima parte Modified Paths: -------------- trunk/tora/toeditextensions.cpp trunk/tora/toeditextensions.h trunk/tora/tohighlightedtext.cpp trunk/tora/tohighlightedtext.h trunk/tora/utils.h Modified: trunk/tora/toeditextensions.cpp =================================================================== --- trunk/tora/toeditextensions.cpp 2006-03-01 02:34:46 UTC (rev 1907) +++ trunk/tora/toeditextensions.cpp 2006-03-01 16:55:26 UTC (rev 1908) @@ -73,6 +73,7 @@ static int UpperCase; static int LowerCase; static int GotoLine; +static int AutoComplete; #define CONF_EXPAND_SPACES "ExpandSpaces" #define CONF_COMMA_BEFORE "CommaBefore" @@ -114,8 +115,19 @@ IndentButton->setEnabled(enable); if (DeindentButton) DeindentButton->setEnabled(enable); + toHighlightedText * cur=dynamic_cast<toHighlightedText *>(widget); + toMainWidget()->editMenu()->setItemEnabled(AutoComplete, cur); } +void toEditExtensions::autoComplete(){ + toHighlightedText *cur=dynamic_cast<toHighlightedText *>(Current); + if(cur) + cur->autoCompleteFromAPIs(); + else{ + TO_DEBUGOUT("cur null"); + } +} + void toEditExtensions::lostFocus(toEditWidget *widget) { if (widget) @@ -528,6 +540,8 @@ GotoLine = toMainWidget()->editMenu()->insertItem(qApp->translate("toEditExtensionTool", "Goto Line"), &EditExtensions, SLOT(gotoLine())); + AutoComplete=toMainWidget()->editMenu()->insertItem(qApp->translate("toEditExtensionTool", "Complete"),&EditExtensions,SLOT(autoComplete()),toKeySequence(qApp->translate("toEditExtensionTool", "Ctrl+Space","Edit|Complete"))); + IndentButton = new QToolButton(QPixmap(const_cast<const char**>(indent_xpm)), qApp->translate("toEditExtensionTool", "Indent block in editor"), qApp->translate("toEditExtensionTool", "Indent block in editor"), Modified: trunk/tora/toeditextensions.h =================================================================== --- trunk/tora/toeditextensions.h 2006-03-01 02:34:46 UTC (rev 1907) +++ trunk/tora/toeditextensions.h 2006-03-01 16:55:26 UTC (rev 1908) @@ -77,6 +77,8 @@ void lowerCase(void); void gotoLine(void); + + void autoComplete(void); }; class toEditExtensionGoto : public toEditExtensionGotoUI Modified: trunk/tora/tohighlightedtext.cpp =================================================================== --- trunk/tora/tohighlightedtext.cpp 2006-03-01 02:34:46 UTC (rev 1907) +++ trunk/tora/tohighlightedtext.cpp 2006-03-01 16:55:26 UTC (rev 1908) @@ -57,6 +57,7 @@ #include <qnamespace.h> #include <qextscintillalexersql.h> +#include <qpoint.h> #include "todefaultkeywords.h" @@ -290,25 +291,35 @@ setMarkerBackgroundColor(Qt::red,errorMarker); debugMarker=markerDefine(Rectangle,8); setMarkerBackgroundColor(Qt::darkGreen,debugMarker); - setMarkerBackgroundColor(Qt::red,errorMarker); setMarginMarkerMask(1,0); + setAutoCompletionReplaceWord(true); setAutoIndent(true); connect(this,SIGNAL(cursorPositionChanged(int,int)),this,SLOT(setStatusMessage(void ))); complAPI=new QextScintillaAPIs(); connect (this,SIGNAL(cursorPositionChanged(int,int)),this,SLOT(positionChanged(int,int))); - this->SendScintilla(QextScintillaBase::SCI_AUTOCSETSEPARATOR,'!'); + timer=new QTimer(this); + connect( timer, SIGNAL(timeout()), this, SLOT(autoCompleteFromAPIs()) ); + popup=new QListBox(0,"popup",Qt::WType_Popup|Qt::WStyle_NoBorder|Qt::WStyle_Customize); + popup->hide(); + connect(popup,SIGNAL(clicked(QListBoxItem*)),this,SLOT(completeFromAPI(QListBoxItem*))); + connect(popup,SIGNAL(returnPressed(QListBoxItem*)),this,SLOT(completeFromAPI(QListBoxItem*))); } toHighlightedText::~toHighlightedText() { if(complAPI) delete complAPI; + if(popup) + delete popup; } void toHighlightedText::positionChanged(int row, int col){ - /*if (col>0 && this->text(row)[col-1]=='.'){ - this->autoCompleteFromAPIs(); - }*/ + if (col>0 && this->text(row)[col-1]=='.'){ + timer->start(500,true); + }else{ + if(timer->isActive()) + timer->stop(); + } } static QString UpperIdent(const QString &str){ @@ -319,84 +330,23 @@ } void toHighlightedText::autoCompleteFromAPIs(){ - complAPI->clear(); - int curline, curcol; - getCursorPosition (&curline, &curcol); - - QString line = text(curline); - - if (!isReadOnly() && curcol >= 0 && line[curcol-1] == '.'){ - //if (!hasSelectedText()) - // return ; - if (toTool::globalConfig(CONF_CODE_COMPLETION, "Yes").isEmpty()) - return ; - - toSQLParse::editorTokenizer tokens(this, curcol, curline); - QString name = tokens.getToken(false); - QString owner; - if (name == ".") - name = tokens.getToken(false); - - QString token = tokens.getToken(false); - if (token == ".") - owner = tokens.getToken(false); - else{ - QString cmp = UpperIdent(name); - QString lastToken; - while ((invalidToken(tokens.line(), tokens.offset() + token.length()) || UpperIdent(token) != cmp || lastToken == ".") && token != ";" && !token.isEmpty()){ - lastToken = token; - token = tokens.getToken(false); - } - - if(token == ";" || token.isEmpty()){ - tokens.setLine(curline); - tokens.setOffset(curcol); - token = tokens.getToken(); - while ((invalidToken(tokens.line(), tokens.offset()) || UpperIdent(token) != cmp && lastToken != ".") && token != ";" && !token.isEmpty()) - token = tokens.getToken(); - lastToken = token; - tokens.getToken(false); - } - if(token != ";" && !token.isEmpty()){ - token = tokens.getToken(false); - if (token != "TABLE" && token != "UPDATE" && token != "FROM" && token != "INTO" && (toIsIdent(token[0]) || token[0] == '\"')){ - name = token; - token = tokens.getToken(false); - if (token == ".") - owner = tokens.getToken(false); - }else if (token == ")"){ - return ; - } - } - } - if (!owner.isEmpty()){ - name = owner + QString::fromLatin1(".") + name; - } - if (!name.isEmpty()){ - try{ - toConnection &conn = toCurrentConnection(this); - toQDescList &desc = conn.columns(conn.realName(name, false)); - for (toQDescList::iterator i = desc.begin();i != desc.end();i++){ - QString t; - int ind = (*i).Name.find("("); - if (ind < 0) - ind = (*i).Name.find("RETURNING") - 1; //it could be a function or procedure without parameters. -1 to remove the space - if (ind >= 0) - t = conn.quote((*i).Name.mid(0, ind)) + (*i).Name.mid(ind); - else - t = conn.quote((*i).Name); - /*if (!(*i).Comment.isEmpty()){ - t += QString::fromLatin1(" - "); - t += (*i).Comment; - } - t+="!";*/ - complAPI->add(t); - } - this->setAutoCompletionAPIs(complAPI); - this->setCallTipsAPIs(complAPI); - QextScintilla::autoCompleteFromAPIs(); - }catch (...){} - } + QStringList compleList=this->getCompletionList(); + if(!compleList.isEmpty()){ + long position, posx, posy; + int curCol, curRow; + this->getCursorPosition(&curRow,&curCol); + position=this->SendScintilla(SCI_GETCURRENTPOS); + posx=this->SendScintilla(SCI_POINTXFROMPOSITION,0,position); + posy=this->SendScintilla(SCI_POINTYFROMPOSITION,0,position)+ + this->SendScintilla(SCI_TEXTHEIGHT,curRow); + QPoint p(posx,posy); + p=this->mapToGlobal(p); + popup->move(p); + popup->clear(); + popup->insertStringList(compleList); + popup->show(); + }else{ + popup->hide(); } } @@ -580,3 +530,110 @@ else toStatusMessage((*err).second, true); } + +QStringList toHighlightedText::getCompletionList(){ + int curline, curcol; + QStringList toReturn; + getCursorPosition (&curline, &curcol); + + QString line = text(curline); + + if (!isReadOnly() && curcol >= 0){ + if (toTool::globalConfig(CONF_CODE_COMPLETION, "Yes").isEmpty()) + return toReturn; + + toSQLParse::editorTokenizer tokens(this, curcol, curline); + QString partial; + if (line[curcol-1]!='.'){ + partial=tokens.getToken(false); + }else{ + partial=""; + } + + QString name = tokens.getToken(false); + QString owner; + if (name == "."){ + name = tokens.getToken(false); + } + + QString token = tokens.getToken(false); + if (token == ".") + owner = tokens.getToken(false); + else{ + QString cmp = UpperIdent(name); + QString lastToken; + while ((invalidToken(tokens.line(), tokens.offset() + token.length()) || UpperIdent(token) != cmp || lastToken == ".") && token != ";" && !token.isEmpty()){ + lastToken = token; + token = tokens.getToken(false); + } + + if(token == ";" || token.isEmpty()){ + tokens.setLine(curline); + tokens.setOffset(curcol); + token = tokens.getToken(); + while ((invalidToken(tokens.line(), tokens.offset()) || UpperIdent(token) != cmp && lastToken != ".") && token != ";" && !token.isEmpty()) + token = tokens.getToken(); + lastToken = token; + tokens.getToken(false); + } + if(token != ";" && !token.isEmpty()){ + token = tokens.getToken(false); + if (token != "TABLE" && token != "UPDATE" && token != "FROM" && token != "INTO" && (toIsIdent(token[0]) || token[0] == '\"')){ + name = token; + token = tokens.getToken(false); + if (token == ".") + owner = tokens.getToken(false); + }else if (token == ")"){ + return toReturn; + } + } + } + if (!owner.isEmpty()){ + name = owner + QString::fromLatin1(".") + name; + } + if (!name.isEmpty()){ + try{ + toConnection &conn = toCurrentConnection(this); + toQDescList &desc = conn.columns(conn.realName(name, false)); + for (toQDescList::iterator i = desc.begin();i != desc.end();i++){ + QString t; + int ind = (*i).Name.find("("); + if (ind < 0) + ind = (*i).Name.find("RETURNING") - 1; //it could be a function or procedure without parameters. -1 to remove the space + if (ind >= 0) + t = conn.quote((*i).Name.mid(0, ind)) + (*i).Name.mid(ind); + else + t = conn.quote((*i).Name); + if (t.find(partial)==0) + toReturn.append(t); + } + }catch (...){} + } + } + toReturn.sort(); + return toReturn; +} + +void toHighlightedText::completeFromAPI(QListBoxItem* item){ + if(item){ + int curline, curcol, start,end; + getCursorPosition (&curline, &curcol); + QString line = text(curline); + toSQLParse::editorTokenizer tokens(this, curcol, curline); + if (line[curcol-1]!='.'){ + tokens.getToken(false); + start=tokens.offset(); + }else{ + start=curcol; + } + tokens.getToken(true); + end=tokens.offset(); + disconnect(this,SIGNAL(cursorPositionChanged(int,int)),this,SLOT(positionChanged(int,int))); + setSelection(curline,start,curline,end); + this->removeSelectedText(); + this->insert(item->text()); + this->setCursorPosition(curline,start+item->text().length()); + connect (this,SIGNAL(cursorPositionChanged(int,int)),this,SLOT(positionChanged(int,int))); + } + popup->hide(); +} Modified: trunk/tora/tohighlightedtext.h =================================================================== --- trunk/tora/tohighlightedtext.h 2006-03-01 02:34:46 UTC (rev 1907) +++ trunk/tora/tohighlightedtext.h 2006-03-01 16:55:26 UTC (rev 1908) @@ -47,8 +47,11 @@ #include <list> #include <map> +#include <qtimer.h> +#include <qstringlist.h> class QListBox; +class QListBoxItem; class QPainter; class toSyntaxSetup; @@ -231,9 +234,11 @@ */ std::map<int, QString> Errors; QextScintillaAPIs* complAPI; + QTimer* timer; protected: int debugMarker; int errorMarker; + QListBox* popup; public: @@ -344,6 +349,10 @@ */ void tableAtCursor(QString &owner, QString &table, bool highlight = false); +protected: + QStringList getCompletionList(); + + private: bool invalidToken(int line, int col); @@ -362,6 +371,8 @@ void positionChanged(int row, int col); + virtual void completeFromAPI(QListBoxItem * item); + private slots: void setStatusMessage(void); }; Modified: trunk/tora/utils.h =================================================================== --- trunk/tora/utils.h 2006-03-01 02:34:46 UTC (rev 1907) +++ trunk/tora/utils.h 2006-03-01 16:55:26 UTC (rev 1908) @@ -69,6 +69,15 @@ # endif #endif +#define TO_DEBUG +#ifdef TO_DEBUG +#include <stdio.h> +static FILE* toraLog=NULL; +#define TO_DEBUGOUT(x) if(!toraLog) toraLog=fopen("C:\\Temp\\tora.log","a"); fprintf(toraLog,"%s\n",(const char *)x);fflush(toraLog); +#else +#define TO_DEBUGOUT(x) +#endif + #if 0 /** * The class to use for a printer object. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |