KDevelop API Documentation

parenmatcher.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of Qt Designer.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file COPYING included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 **********************************************************************/
00020 
00021 // porting for klint by Roberto Raggi (roberto@kdevelop.org)
00022 
00023 #include "parenmatcher.h"
00024 #include "paragdata.h"
00025 
00026 #include <private/qrichtext_p.h>
00027 #include <qtextedit.h>
00028 #include <qapplication.h>
00029 
00030 ParenMatcher::ParenMatcher()
00031 {
00032     enabled = TRUE;
00033 }
00034 
00035 bool ParenMatcher::match( QTextCursor *cursor )
00036 {
00037     if ( !enabled )
00038     return FALSE;
00039     bool ret = FALSE;
00040 
00041     QChar c( cursor->paragraph()->at( cursor->index() )->c );
00042     bool ok1 = FALSE;
00043     bool ok2 = FALSE;
00044     if ( c == '{' || c == '(' || c == '[' ) {
00045     ok1 = checkOpenParen( cursor );
00046     ret = ok1 || ret;
00047     } else if ( cursor->index() > 0 ) {
00048     c = cursor->paragraph()->at( cursor->index() - 1 )->c;
00049     if ( c == '}' || c == ')' || c == ']' ) {
00050         ok2 = checkClosedParen( cursor );
00051         ret = ok2 || ret;
00052     }
00053     }
00054     return ret;
00055 }
00056 
00057 bool ParenMatcher::checkOpenParen( QTextCursor *cursor )
00058 {
00059     if ( !cursor->paragraph()->extraData() )
00060     return FALSE;
00061     QValueList<Symbol> parenList = ( (ParagData*)cursor->paragraph()->extraData() )->symbolList();
00062 
00063     Symbol openParen, closedParen;
00064     QTextParagraph *closedParenParag = cursor->paragraph();
00065 
00066     int i = 0;
00067     int ignore = 0;
00068     bool foundOpen = FALSE;
00069     QChar c = cursor->paragraph()->at( cursor->index() )->c;
00070     for (;;) {
00071     if ( !foundOpen ) {
00072         if ( i >= (int)parenList.count() )
00073         goto bye;
00074         openParen = parenList[ i ];
00075         if ( openParen.pos() != cursor->index() ) {
00076         ++i;
00077         continue;
00078         } else {
00079         foundOpen = TRUE;
00080         ++i;
00081         }
00082     }
00083 
00084     if ( i >= (int)parenList.count() ) {
00085         for (;;) {
00086         closedParenParag = closedParenParag->next();
00087         if ( !closedParenParag )
00088             goto bye;
00089         if ( closedParenParag->extraData() &&
00090              ( (ParagData*)closedParenParag->extraData() )->symbolList().count() > 0 ) {
00091             parenList = ( (ParagData*)closedParenParag->extraData() )->symbolList();
00092             break;
00093         }
00094         }
00095         i = 0;
00096     }
00097 
00098     closedParen = parenList[ i ];
00099     if ( closedParen.type() == Symbol::Left ) {
00100         ignore++;
00101         ++i;
00102         continue;
00103     } else {
00104         if ( ignore > 0 ) {
00105         ignore--;
00106         ++i;
00107         continue;
00108         }
00109 
00110         int id = Match;
00111         if ( c == '{' && closedParen.ch() != '}' ||
00112          c == '(' && closedParen.ch() != ')' ||
00113          c == '[' && closedParen.ch() != ']' )
00114         id = Mismatch;
00115         cursor->document()->setSelectionStart( id, *cursor );
00116         int tidx = cursor->index();
00117         QTextParagraph *tstring = cursor->paragraph();
00118         cursor->setParagraph( closedParenParag );
00119         cursor->setIndex( closedParen.pos() + 1 );
00120         cursor->document()->setSelectionEnd( id, *cursor );
00121         cursor->setParagraph( tstring );
00122         cursor->setIndex( tidx );
00123         return TRUE;
00124     }
00125     }
00126 
00127  bye:
00128     return FALSE;
00129 }
00130 
00131 bool ParenMatcher::checkClosedParen( QTextCursor *cursor )
00132 {
00133     if ( !cursor->paragraph()->extraData() )
00134     return FALSE;
00135     QValueList<Symbol> parenList = ( (ParagData*)cursor->paragraph()->extraData() )->symbolList();
00136 
00137     Symbol openParen, closedParen;
00138     QTextParagraph *openParenParag = cursor->paragraph();
00139 
00140     int i = parenList.count() - 1;
00141     int ignore = 0;
00142     bool foundClosed = FALSE;
00143     QChar c = cursor->paragraph()->at( cursor->index() - 1 )->c;
00144     for (;;) {
00145     if ( !foundClosed ) {
00146         if ( i < 0 )
00147         goto bye;
00148         closedParen = parenList[ i ];
00149         if ( closedParen.pos() != cursor->index() - 1 ) {
00150         --i;
00151         continue;
00152         } else {
00153         foundClosed = TRUE;
00154         --i;
00155         }
00156     }
00157 
00158     if ( i < 0 ) {
00159         for (;;) {
00160         openParenParag = openParenParag->prev();
00161         if ( !openParenParag )
00162             goto bye;
00163         if ( openParenParag->extraData() &&
00164              ( (ParagData*)openParenParag->extraData() )->symbolList().count() > 0 ) {
00165             parenList = ( (ParagData*)openParenParag->extraData() )->symbolList();
00166             break;
00167         }
00168         }
00169         i = parenList.count() - 1;
00170     }
00171 
00172     openParen = parenList[ i ];
00173     if ( openParen.type() == Symbol::Right ) {
00174         ignore++;
00175         --i;
00176         continue;
00177     } else {
00178         if ( ignore > 0 ) {
00179         ignore--;
00180         --i;
00181         continue;
00182         }
00183 
00184         int id = Match;
00185         if ( c == '}' && openParen.ch() != '{' ||
00186          c == ')' && openParen.ch() != '(' ||
00187          c == ']' && openParen.ch() != '[' )
00188         id = Mismatch;
00189         cursor->document()->setSelectionStart( id, *cursor );
00190         int tidx = cursor->index();
00191         QTextParagraph *tstring = cursor->paragraph();
00192         cursor->setParagraph( openParenParag );
00193         cursor->setIndex( openParen.pos() );
00194         cursor->document()->setSelectionEnd( id, *cursor );
00195         cursor->setParagraph( tstring );
00196         cursor->setIndex( tidx );
00197         return TRUE;
00198     }
00199     }
00200 
00201  bye:
00202     return FALSE;
00203 }
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 23 00:03:42 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003