parenmatcher.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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 }
This file is part of the documentation for KDevelop Version 3.1.2.