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

📄 completion.cpp

📁 Linux下的基于X11的图形开发环境。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/************************************************************************ Copyright (C) 2000 Trolltech AS.  All rights reserved.**** This file is part of Qt Designer.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "completion.h"#include "paragdata.h"#include "editor.h"#include <qlistbox.h>#include <qvbox.h>#include <qmap.h>#include <private/qrichtext_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 == "function" || type == "slot" || type == "package" )	return Qt::blue;    else if ( type == "variable" || type == "widget" || type == "dir" )	return Qt::darkRed;    else if ( type == "object" || type == "class" )	return Qt::darkBlue;    else if ( type == "property" )	return Qt::darkGreen;    else if ( type == "enum" )	return Qt::darkYellow;    return Qt::black;}class CompletionItem : public QListBoxItem{public:    CompletionItem( QListBox *lb, const QString &txt, const QString &t, const QString &p,		    const QString &pre, const QString &p2 )	: QListBoxItem( 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 QListBox * ) const {	if ( !parag )	    ( (CompletionItem*)this )->setupParagraph();	return parag->rect().height();    }    int width( const QListBox * ) const {	if ( !parag )	    ( (CompletionItem*)this )->setupParagraph();	return parag->rect().width() - 2;    }    QString text() const { return QListBoxItem::text() + postfix; }private:    void setupParagraph();    QString type, postfix, prefix, postfix2;    QTextParagraph *parag;    bool lastState;};void CompletionItem::setupParagraph() {    if ( !parag ) {	QTextFormatter *formatter;	formatter = new QTextFormatterBreakWords;	formatter->setWrapEnabled( FALSE );	parag = new QTextParagraph( 0 );	parag->setTabStops( listBox()->fontMetrics().width( "propertyXXXX" ) );	parag->pseudoDocument()->pFormatter = formatter;	parag->insert( 0, " " + type + ( type.isEmpty() ? " " : "\t" ) + prefix +		       QListBoxItem::text() + postfix + postfix2 );	bool selCol = isSelected() && listBox()->colorGroup().highlightedText() != listBox()->colorGroup().text();	QColor sc = selCol ? listBox()->colorGroup().highlightedText() : getColor( type );	QTextFormat *f1 = parag->formatCollection()->format( listBox()->font(), sc );	QTextFormat *f3 = parag->formatCollection()->format( listBox()->font(), isSelected() ?							     listBox()->colorGroup().highlightedText() :							     listBox()->colorGroup().text() );	QFont f( listBox()->font() );	f.setBold( TRUE );	QTextFormat *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() + QListBoxItem::text().length(), f2 );	if ( !postfix.isEmpty() )	    parag->setFormat( type.length() + 2 + prefix.length() + QListBoxItem::text().length(),			      postfix.length(), f3 );	parag->setFormat( type.length() + 2 + prefix.length() + QListBoxItem::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 QVBox( e->topLevelWidget(), 0, WType_Popup );    completionPopup->setFrameStyle( QFrame::Box | QFrame::Plain );    completionPopup->setLineWidth( 1 );    functionLabel = new ArgHintWidget( e->topLevelWidget(), "editor_function_lbl" );    functionLabel->hide();    completionListBox = new QListBox( completionPopup, "editor_completion_lb" );    completionListBox->setFrameStyle( QFrame::NoFrame );    completionListBox->installEventFilter( this );    completionListBox->setHScrollBarMode( QScrollView::AlwaysOn );    completionListBox->setVScrollBarMode( QScrollView::AlwaysOn );    completionListBox->setCornerWidget( new QSizeGrip( completionListBox, "editor_cornerwidget" ) );    completionPopup->installEventFilter( this );    functionLabel->installEventFilter( this );    completionPopup->setFocusProxy( completionListBox );    completionOffset = 0;    curEditor = e;    curEditor->installEventFilter( this );}EditorCompletion::~EditorCompletion(){    delete completionPopup;    delete functionLabel;}void EditorCompletion::addCompletionEntry( const QString &s, QTextDocument *, bool strict ){    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(); ) {		QStringList::Iterator it2 = sit;		++sit;		if ( (*it2).length() > s.length() && (*it2).left( s.length() ) == s ) {		    if ( (*it2)[ (int)s.length() ].isLetter() && (*it2)[ (int)s.length() ].upper() != (*it2)[ (int)s.length() ] )			return;		} else if ( s.length() > (*it2).length() && s.left( (*it2).length() ) == *it2 ) {		    if ( s[ (int)(*it2).length() ].isLetter() && s[ (int)(*it2).length() ].upper() != s[ (int)(*it2).length() ] )			(*it).remove( it2 );		}	    }	}	(*it).append( s );    }}QValueList<CompletionEntry> EditorCompletion::completionList( const QString &s, QTextDocument *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 QValueList<CompletionEntry>();    QStringList::ConstIterator it2 = (*it).begin();    QValueList<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( QTextDocument *doc ){    bool strict = TRUE;    if ( doc != lastDoc )	strict = FALSE;    lastDoc = doc;    QTextParagraph *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;    QTextCursor *cursor = curEditor->textCursor();    QTextDocument *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;    QValueList<CompletionEntry> lst( completionList( s, doc ) );    if ( lst.count() > 1 ) {	QTextStringChar *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 ( QValueList<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 );	completionListBox->setFocus();	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) ( QTextEdit::RedoIndentation |				    QTextEdit::CheckNewLines |				    QTextEdit::RemoveSelected ) );    } else {	return FALSE;    }    return TRUE;}bool EditorCompletion::eventFilter( QObject *o, QEvent *e ){    if ( !enabled )	return FALSE;    if ( o->inherits( "Editor" ) && e->type() == QEvent::KeyPress ) {	curEditor = (Editor*)o;	QKeyEvent *ke = (QKeyEvent*)e;	if ( ke->key() == Key_Tab ) {	    QString s = curEditor->textCursor()->paragraph()->string()->toString().			left( curEditor->textCursor()->index() );	    if ( 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( "\t" );		}		return TRUE;	    }	}	if ( functionLabel->isVisible() ) {	    if ( ke->key() == Key_Up && ( ke->state() & ControlButton ) == ControlButton ) {		functionLabel->gotoPrev();		return TRUE;	    } else if ( ke->key() == Key_Down && ( ke->state() & ControlButton ) == ControlButton ) {		functionLabel->gotoNext();		return TRUE;	    }	}

⌨️ 快捷键说明

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