⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 completion.cpp

📁 qtopia的源程序,一种嵌入式图形操作系统
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************** Copyright (C) 1992-$THISYEAR$ Trolltech AS. All rights reserved.**** This file is part of the $MODULE$ of the Qt Toolkit.**** $LICENSE$**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "completion.h"#include "paragdata.h"#include "editor.h"#include <q3listbox.h>#include <q3vbox.h>#include <qmap.h>#include <qdesktopwidget.h>//Added by qt3to4:#include <QEvent>#include <QKeyEvent>#include <Q3Frame>#include <Q3ValueList>#include "q3richtext_p.h"#include <qapplication.h>#include <qregexp.h>#include "arghintwidget.h"#include <qsizegrip.h>#include <qtimer.h>static QColor getColor( const QString &type ){    if ( type == QString::fromLatin1("function") || type == QString::fromLatin1("slot") || type == QString::fromLatin1("package") )	return Qt::blue;    else if ( type == QString::fromLatin1("variable") || type == QString::fromLatin1("widget") || type == QString::fromLatin1("dir") )	return Qt::darkRed;    else if ( type == QString::fromLatin1("object") || type == QString::fromLatin1("class") )	return Qt::darkBlue;    else if ( type == QString::fromLatin1("property") )	return Qt::darkGreen;    else if ( type == QString::fromLatin1("enum") )	return Qt::darkYellow;    return Qt::black;}class CompletionItem : public Q3ListBoxItem{public:    CompletionItem( Q3ListBox *lb, const QString &txt, const QString &t, const QString &p,		    const QString &pre, const QString &p2 )	: Q3ListBoxItem( lb ), type( t ), postfix( p ), prefix( pre ), postfix2( p2 ),	  parag( 0 ), lastState( false ) { setText( txt ); }    ~CompletionItem() { delete parag; }    void paint( QPainter *painter ) {	if ( lastState != isSelected() ) {	    delete parag;	    parag = 0;	}	lastState = isSelected();	if ( !parag )	    setupParagraph();	parag->paint( *painter, listBox()->colorGroup() );    }    int height( const Q3ListBox * ) const {	if ( !parag )	    ( (CompletionItem*)this )->setupParagraph();	return parag->rect().height();    }    int width( const Q3ListBox * ) const {	if ( !parag )	    ( (CompletionItem*)this )->setupParagraph();	return parag->rect().width() - 2;    }    QString text() const { return Q3ListBoxItem::text() + postfix; }private:    void setupParagraph();    QString type, postfix, prefix, postfix2;    Q3TextParagraph *parag;    bool lastState;};void CompletionItem::setupParagraph() {    if ( !parag ) {	Q3TextFormatter *formatter;	formatter = new Q3TextFormatterBreakWords;	formatter->setWrapEnabled( false );	parag = new Q3TextParagraph( 0 );	parag->setTabStops( listBox()->fontMetrics().width( QString::fromLatin1("propertyXXXX") ) );	parag->pseudoDocument()->pFormatter = formatter;	parag->insert( 0, " " + type + ( type.isEmpty() ? " " : "\t" ) + prefix +		       Q3ListBoxItem::text() + postfix + postfix2 );	bool selCol = isSelected() && listBox()->colorGroup().highlightedText() != listBox()->colorGroup().text();	QColor sc = selCol ? listBox()->colorGroup().highlightedText() : getColor( type );	Q3TextFormat *f1 = parag->formatCollection()->format( listBox()->font(), sc );	Q3TextFormat *f3 = parag->formatCollection()->format( listBox()->font(), isSelected() ?							     listBox()->colorGroup().highlightedText() :							     listBox()->colorGroup().text() );	QFont f( listBox()->font() );	f.setBold( true );	Q3TextFormat *f2 =	    parag->formatCollection()->format( f, isSelected() ? listBox()->colorGroup().highlightedText() :					       listBox()->colorGroup().text() );	parag->setFormat( 1, type.length() + 1, f1 );	parag->setFormat( type.length() + 2, prefix.length() + Q3ListBoxItem::text().length(), f2 );	if ( !postfix.isEmpty() )	    parag->setFormat( type.length() + 2 + prefix.length() + Q3ListBoxItem::text().length(),			      postfix.length(), f3 );	parag->setFormat( type.length() + 2 + prefix.length() + Q3ListBoxItem::text().length() + postfix.length(),			  postfix2.length(), f3 );	f1->removeRef();	f2->removeRef();	f3->removeRef();	parag->format();    }}EditorCompletion::EditorCompletion( Editor *e ){    enabled = true;    lastDoc = 0;    completionPopup = new Q3VBox( e->topLevelWidget(), 0, Qt::WType_Popup );    completionPopup->setFrameStyle( Q3Frame::Box | Q3Frame::Plain );    completionPopup->setLineWidth( 1 );    functionLabel = new ArgHintWidget( e->topLevelWidget(), "editor_function_lbl" );    functionLabel->hide();    completionListBox = new Q3ListBox( completionPopup, "editor_completion_lb" );    completionListBox->setFrameStyle( Q3Frame::NoFrame );    completionListBox->installEventFilter( this );    completionListBox->setHScrollBarMode( Q3ScrollView::AlwaysOn );    completionListBox->setVScrollBarMode( Q3ScrollView::AlwaysOn );    completionListBox->setCornerWidget( new QSizeGrip( completionListBox ) );    completionPopup->installEventFilter( this );    functionLabel->installEventFilter( this );    completionOffset = 0;    curEditor = e;    curEditor->installEventFilter( this );}EditorCompletion::~EditorCompletion(){    delete functionLabel;}void EditorCompletion::addCompletionEntry( const QString &s, Q3TextDocument *, bool strict ){    if (s.isEmpty())        return;    QChar key( s[ 0 ] );    QMap<QChar, QStringList>::Iterator it = completionMap.find( key );    if ( it == completionMap.end() ) {	completionMap.insert( key, QStringList( s ) );    } else {	if ( strict ) {	    QStringList::Iterator sit;	    for ( sit = (*it).begin(); sit != (*it).end(); ) {		if ( (*sit).length() > s.length() && (*sit).left( s.length() ) == s ) {		    if ( (*sit)[ (int)s.length() ].isLetter() && (*sit)[ (int)s.length() ].upper() != (*sit)[ (int)s.length() ] )			return;		} else if ( s.length() > (*sit).length() && s.left( (*sit).length() ) == *sit ) {		    if ( s[ (int)(*sit).length() ].isLetter() && s[ (int)(*sit).length() ].upper() != s[ (int)(*sit).length() ] ) {			sit = (*it).remove( sit );                        continue;                    }		}                ++sit;	    }	}	(*it).append( s );    }}Q3ValueList<CompletionEntry> EditorCompletion::completionList( const QString &s, Q3TextDocument *doc ) const{    if ( doc )	( (EditorCompletion*)this )->updateCompletionMap( doc );    QChar key( s[ 0 ] );    QMap<QChar, QStringList>::ConstIterator it = completionMap.find( key );    if ( it == completionMap.end() )	return Q3ValueList<CompletionEntry>();    QStringList::ConstIterator it2 = (*it).begin();    Q3ValueList<CompletionEntry> lst;    int len = s.length();    for ( ; it2 != (*it).end(); ++it2 ) {	CompletionEntry c;	c.type = "";	c.text = *it2;	c.postfix = "";	c.prefix = "";	c.postfix2 = "";	if ( (int)(*it2).length() > len && (*it2).left( len ) == s && lst.find( c ) == lst.end() )	    lst << c;    }    return lst;}void EditorCompletion::updateCompletionMap( Q3TextDocument *doc ){    bool strict = true;    if ( doc != lastDoc )	strict = false;    lastDoc = doc;    Q3TextParagraph *s = doc->firstParagraph();    if ( !s->extraData() )	s->setExtraData( new ParagData );    while ( s ) {	if ( s->length() == ( (ParagData*)s->extraData() )->lastLengthForCompletion ) {	    s = s->next();	    continue;	}	QChar c;	QString buffer;	for ( int i = 0; i < s->length(); ++i ) {	    c = s->at( i )->c;	    if ( c.isLetter() || c.isNumber() || c == '_' || c == '#' ) {		buffer += c;	    } else {		addCompletionEntry( buffer, doc, strict );		buffer = QString::null;	    }	}	if ( !buffer.isEmpty() )	    addCompletionEntry( buffer, doc, strict );	( (ParagData*)s->extraData() )->lastLengthForCompletion = s->length();	s = s->next();    }}bool EditorCompletion::doCompletion(){    searchString = "";    if ( !curEditor )	return false;    Q3TextCursor *cursor = curEditor->textCursor();    Q3TextDocument *doc = curEditor->document();    if ( cursor->index() > 0 && cursor->paragraph()->at( cursor->index() - 1 )->c == '.' &&	 ( cursor->index() == 1 || cursor->paragraph()->at( cursor->index() - 2 )->c != '.' ) )	return doObjectCompletion();    int idx = cursor->index();    if ( idx == 0 )	return false;    QChar c = cursor->paragraph()->at( idx - 1 )->c;    if ( !c.isLetter() && !c.isNumber() && c != '_' && c != '#' )	return false;    QString s;    idx--;    completionOffset = 1;    for (;;) {	s.prepend( QString( cursor->paragraph()->at( idx )->c ) );	idx--;	if ( idx < 0 )	    break;	if ( !cursor->paragraph()->at( idx )->c.isLetter() &&	     !cursor->paragraph()->at( idx )->c.isNumber() &&	     cursor->paragraph()->at( idx )->c != '_' &&	     cursor->paragraph()->at( idx )->c != '#' )	    break;	completionOffset++;    }    searchString = s;    Q3ValueList<CompletionEntry> lst( completionList( s, doc ) );    if ( lst.count() > 1 ) {	Q3TextStringChar *chr = cursor->paragraph()->at( cursor->index() );	int h = cursor->paragraph()->lineHeightOfChar( cursor->index() );	int x = cursor->paragraph()->rect().x() + chr->x;	int y, dummy;	cursor->paragraph()->lineHeightOfChar( cursor->index(), &dummy, &y );	y += cursor->paragraph()->rect().y();	completionListBox->clear();	for ( Q3ValueList<CompletionEntry>::ConstIterator it = lst.begin(); it != lst.end(); ++it )	    (void)new CompletionItem( completionListBox, (*it).text, (*it).type, (*it).postfix,				      (*it).prefix, (*it).postfix2 );	cList = lst;	completionPopup->resize( completionListBox->sizeHint() +				 QSize( completionListBox->verticalScrollBar()->width() + 4,					completionListBox->horizontalScrollBar()->height() + 4 ) );	completionListBox->setCurrentItem( 0 );	if ( curEditor->mapToGlobal( QPoint( 0, y ) ).y() + h + completionPopup->height() < QApplication::desktop()->height() )	    completionPopup->move( curEditor->mapToGlobal( curEditor->							   contentsToViewport( QPoint( x, y + h ) ) ) );	else	    completionPopup->move( curEditor->mapToGlobal( curEditor->							   contentsToViewport( QPoint( x, y - completionPopup->height() ) ) ) );	completionPopup->show();    } else if ( lst.count() == 1 ) {	curEditor->insert( lst.first().text.mid( completionOffset, 0xFFFFFF ), 			   (uint) ( Q3TextEdit::RedoIndentation |				    Q3TextEdit::CheckNewLines |				    Q3TextEdit::RemoveSelected ) );    } else {	return false;    }    return true;}bool EditorCompletion::eventFilter( QObject *o, QEvent *e ){    if ( !enabled )	return false;    if ( e->type() == QEvent::KeyPress &&#if (QT_VERSION) < 0x030200	 o->inherits("Editor")#else	 ::qobject_cast<Editor*>(o)#endif	 ) {	curEditor = (Editor*)o;	QKeyEvent *ke = (QKeyEvent*)e;	if ( ke->key() == Qt::Key_Tab ) {	    QString s = curEditor->textCursor()->paragraph()->string()->toString().			left( curEditor->textCursor()->index() );	    if ( curEditor->document()->hasSelection( Q3TextDocument::Standard ) ||		 s.simplifyWhiteSpace().isEmpty() ) {		if ( curEditor->document()->indent() ) {		    curEditor->indent();		    int i = 0;		    for ( ; i < curEditor->textCursor()->paragraph()->length() - 1; ++i ) {			if ( curEditor->textCursor()->paragraph()->at( i )->c != ' ' &&			     curEditor->textCursor()->paragraph()->at( i )->c != '\t' )			    break;		    }		    curEditor->drawCursor( false );		    curEditor->textCursor()->setIndex( i );		    curEditor->drawCursor( true );		} else {		    curEditor->insert( QString::fromLatin1("\t") );		}		return true;	    }	}	if ( functionLabel->isVisible() ) {	    if ( ke->key() == Qt::Key_Up && ( ke->state() & Qt::ControlModifier ) == Qt::ControlModifier ) {		functionLabel->gotoPrev();		return true;	    } else if ( ke->key() == Qt::Key_Down && ( ke->state() & Qt::ControlModifier ) == Qt::ControlModifier ) {		functionLabel->gotoNext();		return true;	    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -