00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include "qsourcecolorizer.h"
00024
#include "qeditor_part.h"
00025
#include "paragdata.h"
00026
#include "qeditor.h"
00027
00028
#include <qregexp.h>
00029
00030
#include <kapplication.h>
00031
#include <kdebug.h>
00032
#include <kconfig.h>
00033
#include <kglobalsettings.h>
00034
00035
using namespace std;
00036
00037
00038 QSourceColorizer::QSourceColorizer(
QEditor* editor )
00039 :
QTextPreProcessor(), m_editor( editor )
00040 {
00041
m_items.setAutoDelete( TRUE );
00042
00043
QFont defaultFont =
KGlobalSettings::fixedFont();
00044
KConfig* config =
QEditorPartFactory::instance()->
config();
00045 config->
setGroup(
"General" );
00046
00047
m_formats.clear();
00048
00049
DECLARE_FORMAT_ITEM(
Normal,
"Normal", defaultFont, Qt::black );
00050
DECLARE_FORMAT_ITEM(
PreProcessor,
"PreProcessor", defaultFont,
QColor( 0x80, 0x00, 0x80 ) );
00051
DECLARE_FORMAT_ITEM(
Keyword,
"Keyword", defaultFont,
QColor( 0x0e, 0x23, 0xad ) );
00052
DECLARE_FORMAT_ITEM(
BuiltInClass,
"Built-in Class", defaultFont,
QColor( 0xff, 0x77, 0x00 ) );
00053
DECLARE_FORMAT_ITEM(
Operator,
"Operator", defaultFont, Qt::black );
00054
DECLARE_FORMAT_ITEM(
Comment,
"Comment", defaultFont,
QColor( 0x06, 0x78, 0x17) );
00055
DECLARE_FORMAT_ITEM(
Constant,
"Constant", defaultFont,
QColor( 0x00, 0x00, 0xff ) );
00056
DECLARE_FORMAT_ITEM(
String,
"String", defaultFont,
QColor( 0xde, 0x19, 0x07 ) );
00057
00058
setSymbols(
"{[(",
"}])" );
00059 }
00060
00061 QSourceColorizer::~QSourceColorizer()
00062 {
00063
KConfig* config =
QEditorPartFactory::instance()->
config();
00064 config->
setGroup(
"General" );
00065
00066
while( !
m_formats.empty() ){
00067
QMap<int, QPair<QString, QTextFormat*> >::Iterator it =
m_formats.begin();
00068
STORE_FORMAT_ITEM( it.key() );
00069
delete( (*it).second );
00070
m_formats.erase( it );
00071 }
00072
00073 config->
sync();
00074 }
00075
00076
00077 void QSourceColorizer::updateStyles(
QMap<
QString,
QPair<QFont, QColor> >& values )
00078 {
00079
KConfig* config =
QEditorPartFactory::instance()->
config();
00080 config->
setGroup(
"General" );
00081
00082
QMap<QString, QPair<QFont, QColor> >::Iterator it = values.begin();
00083
while( it != values.end() ){
00084 QTextFormat* fmt =
formatFromId( it.key() );
00085
if( fmt ){
00086 fmt->setFont( (*it).first );
00087 fmt->setColor( (*it).second );
00088 }
00089 ++it;
00090 }
00091
00092 {
00093
QMap<int, QPair<QString, QTextFormat*> >::Iterator it =
m_formats.begin();
00094
while( it !=
m_formats.end() ){
00095
STORE_FORMAT_ITEM( it.key() );
00096 ++it;
00097 }
00098 }
00099
00100 config->
sync();
00101 }
00102
00103
00104 void QSourceColorizer::process( QTextDocument* doc, QTextParagraph* parag,
int,
00105
bool invalidate )
00106 {
00107
int state = 0;
00108
int startLevel = 0;
00109
int startState = 0;
00110
00111
if( parag->prev() ){
00112
if( parag->prev()->endState() == -1 )
00113
process( doc, parag->prev(), 0, FALSE );
00114 startState = parag->prev()->endState();
00115 startLevel = ((
ParagData*) parag->prev()->extraData())->level();
00116 }
00117 state = startState;
00118
00119
ParagData* extra = (
ParagData*) parag->extraData();
00120
if( extra ){
00121 extra->
clear();
00122 }
else {
00123 extra =
new ParagData();
00124 parag->setExtraData( extra );
00125 }
00126
00127
HLItemCollection* ctx =
m_items.at( state );
00128
QString s =
m_editor->text( parag->paragId() );
00129
const QChar* buffer = s.unicode();
00130
int length = s.length();
00131
00132
int pos = 0;
00133
while( pos <
length ){
00134
int attr = 0;
00135
int next = state;
00136
00137
int npos = ctx->
checkHL( buffer, pos, s.length(), &attr, &next );
00138
if( npos > pos ){
00139 state = next;
00140 ctx =
m_items.at( state );
00141 parag->setFormat( pos, npos,
format(attr) );
00142 pos = npos;
00143 }
else {
00144
const QChar& ch = buffer[ pos ];
00145
int a = ctx->
attr();
00146
if( !a ){
00147
if(
m_left.find(ch) != -1 ){
00148 extra->
add( Symbol::Left, ch, pos );
00149 }
else if(
m_right.find(ch) != -1 ){
00150 extra->
add( Symbol::Right, ch, pos );
00151 }
00152 }
00153 parag->setFormat( pos, pos+1,
format(a) );
00154 ++pos;
00155 }
00156 }
00157
00158
int oldState = parag->endState();
00159
00160
if( state != oldState ){
00161 parag->setEndState( state );
00162 }
00163
00164
int oldLevel = extra->
level();
00165
int level =
computeLevel( parag, startLevel );
00166
if( level != oldLevel ){
00167 extra->
setLevel( level > 0 ? level : 0 );
00168 }
00169
00170 parag->setFirstPreProcess( FALSE );
00171
00172 QTextParagraph *p = parag->next();
00173
00174
if( (oldLevel != level
00175 || (oldState == -1 && parag->prev() && parag->endState() != parag->prev()->endState())
00176 || (oldState != -1 && oldState != state))
00177 && invalidate && p && !p->firstPreProcess() && p->endState() != -1 )
00178 {
00179
00180
int count = 0;
00181
while ( p ) {
00182
if ( p->endState() == -1 )
00183
return;
00184
00185 ++count;
00186 p->setEndState( -1 );
00187 p = p->next();
00188 }
00189
00190 }
00191 }
00192
00193 void QSourceColorizer::insertHLItem(
int id,
HLItemCollection* item )
00194 {
00195
m_items.insert(
id, item );
00196 }
00197
00198 void QSourceColorizer::setSymbols(
const QString& l,
const QString& r )
00199 {
00200
m_left = l;
00201
m_right = r;
00202 }
00203
00204 QTextFormat*
QSourceColorizer::formatFromId(
const QString&
id )
00205 {
00206
QMap<int, QPair<QString, QTextFormat*> >::Iterator it =
m_formats.begin();
00207
while( it !=
m_formats.end() ){
00208
if( (*it).first ==
id ){
00209
return (*it).second;
00210 }
00211 ++it;
00212 }
00213
return 0;
00214 }
00215
00216 QStringList QSourceColorizer::styleList()
const
00217
{
00218
QStringList lst;
00219
00220
QMap<int, QPair<QString, QTextFormat*> >::ConstIterator it =
m_formats.begin();
00221
while( it !=
m_formats.end() ){
00222 lst << (*it).first;
00223 ++it;
00224 }
00225
00226
return lst;
00227 }
00228