00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "abbrevpart.h"
00017
00018 #include <qfile.h>
00019 #include <qfileinfo.h>
00020 #include <qregexp.h>
00021 #include <qvbox.h>
00022 #include <kdebug.h>
00023 #include <kdialogbase.h>
00024 #include <klocale.h>
00025 #include <kparts/part.h>
00026 #include <kstandarddirs.h>
00027 #include <kdevgenericfactory.h>
00028 #include <kaction.h>
00029 #include <kconfig.h>
00030 #include <kio/netaccess.h>
00031 #include <kiconloader.h>
00032
00033 #include <ktexteditor/document.h>
00034 #include <ktexteditor/editinterface.h>
00035 #include <ktexteditor/viewcursorinterface.h>
00036 #include <ktexteditor/codecompletioninterface.h>
00037
00038 #include "kdevcore.h"
00039 #include "kdevpartcontroller.h"
00040 #include "abbrevconfigwidget.h"
00041
00042 static const KAboutData data("kdevabbrev", I18N_NOOP("Abbreviations"), "1.0");
00043
00044 class AbbrevFactory : public KDevGenericFactory<AbbrevPart>
00045 {
00046 public:
00047 AbbrevFactory()
00048 : KDevGenericFactory<AbbrevPart>( &data )
00049 { }
00050
00051 virtual KInstance *createInstance()
00052 {
00053 KInstance *instance = KDevGenericFactory<AbbrevPart>::createInstance();
00054 KStandardDirs *dirs = instance->dirs();
00055 dirs->addResourceType( "codetemplates",
00056 KStandardDirs::kde_default( "data" ) + "kdevabbrev/templates/" );
00057 dirs->addResourceType( "sources",
00058 KStandardDirs::kde_default( "data" ) + "kdevabbrev/sources" );
00059
00060 return instance;
00061 }
00062 };
00063
00064 K_EXPORT_COMPONENT_FACTORY( libkdevabbrev, AbbrevFactory )
00065
00066 AbbrevPart::AbbrevPart(QObject *parent, const char *name, const QStringList &)
00067 : KDevPlugin("Abbrev", "fontsizeup", parent, name ? name : "AbbrevPart")
00068 {
00069 setInstance(AbbrevFactory::instance());
00070 setXMLFile("kdevabbrev.rc");
00071
00072 connect(partController(), SIGNAL(activePartChanged(KParts::Part*)),
00073 this, SLOT(slotActivePartChanged(KParts::Part*)) );
00074
00075 connect(core(), SIGNAL(configWidget(KDialogBase*)), this, SLOT(configWidget(KDialogBase*)));
00076
00077 KAction *action;
00078 action = new KAction( i18n("Expand Text"), CTRL + Key_J,
00079 this, SLOT(slotExpandText()),
00080 actionCollection(), "edit_expandtext" );
00081 action->setToolTip( i18n("Expand current word") );
00082 action->setWhatsThis( i18n("<b>Expand current word</b><p>Current word can be completed using the list of similar words in source files.") );
00083
00084 action = new KAction( i18n("Expand Abbreviation"), CTRL + Key_L,
00085 this, SLOT(slotExpandAbbrev()),
00086 actionCollection(), "edit_expandabbrev" );
00087 action->setToolTip( i18n("Expand abbreviation") );
00088 action->setWhatsThis( i18n("<b>Expand abbreviation</b><p>Enable and configure abbreviations in <b>KDevelop Settings</b>, <b>Abbreviations</b> tab.") );
00089
00090 load();
00091
00092 m_inCompletion = false;
00093 docIface = 0;
00094 editIface = 0;
00095 viewCursorIface = 0;
00096 completionIface = 0;
00097
00098 m_prevLine = -1;
00099 m_prevColumn = -1;
00100 m_sequenceLength = 0;
00101
00102 KConfig* config = AbbrevFactory::instance()->config();
00103 KConfigGroupSaver group( config, "General" );
00104 m_autoWordCompletionEnabled = config->readBoolEntry( "AutoWordCompletion", false );
00105
00106 updateActions();
00107
00108 slotActivePartChanged( partController()->activePart() );
00109 }
00110
00111
00112 AbbrevPart::~AbbrevPart()
00113 {
00114 save();
00115 }
00116
00117 bool AbbrevPart::autoWordCompletionEnabled() const
00118 {
00119 return m_autoWordCompletionEnabled;
00120 }
00121
00122 void AbbrevPart::setAutoWordCompletionEnabled( bool enabled )
00123 {
00124 if( enabled == m_autoWordCompletionEnabled )
00125 return;
00126
00127 KConfig* config = AbbrevFactory::instance()->config();
00128 KConfigGroupSaver group( config, "General" );
00129
00130 m_autoWordCompletionEnabled = enabled;
00131 config->writeEntry( "AutoWordCompletion", m_autoWordCompletionEnabled );
00132 config->sync();
00133
00134 if( !docIface || !docIface->widget() )
00135 return;
00136
00137 disconnect( docIface, 0, this, 0 );
00138 disconnect( docIface->widget(), 0, this, 0 );
00139
00140 if( m_autoWordCompletionEnabled ){
00141 connect( docIface->widget(), SIGNAL(completionAborted()),
00142 this, SLOT(slotCompletionAborted()) );
00143 connect( docIface->widget(), SIGNAL(completionDone()),
00144 this, SLOT(slotCompletionDone()) );
00145 connect( docIface->widget(), SIGNAL(aboutToShowCompletionBox()),
00146 this, SLOT(slotAboutToShowCompletionBox()) );
00147
00148 connect( docIface, SIGNAL(textChanged()), this, SLOT(slotTextChanged()) );
00149 }
00150 }
00151 void AbbrevPart::load()
00152 {
00153 KStandardDirs *dirs = AbbrevFactory::instance()->dirs();
00154 QString localTemplatesFile = locateLocal("codetemplates", "templates", AbbrevFactory::instance());
00155 QStringList files;
00156 if (QFileInfo(localTemplatesFile).exists())
00157 files << localTemplatesFile;
00158 else
00159 files = dirs->findAllResources("codetemplates", QString::null, false, true);
00160
00161 QString localSourcesFile = locateLocal("sources", "sources", AbbrevFactory::instance());
00162 QStringList sourceFiles;
00163 if (QFileInfo(localSourcesFile).exists())
00164 sourceFiles << localSourcesFile;
00165 else
00166 sourceFiles = dirs->findAllResources("sources", QString::null, false, true);
00167 kdDebug(9028) << "=========> sourceFiles: " << sourceFiles.join(" ") << endl;
00168
00169 this->m_completionFile = QString::null;
00170 for( QStringList::Iterator it=sourceFiles.begin(); it!=sourceFiles.end(); ++it ) {
00171 QString fn = *it;
00172 kdDebug(9028) << "===> load file: " << fn << endl;
00173 QFile f( fn );
00174 if ( f.open(IO_ReadOnly) ) {
00175 QTextStream stream( &f );
00176 m_completionFile += ( stream.read() + QString("\n") );
00177 f.close();
00178 }
00179 }
00180
00181 QStringList::ConstIterator it;
00182 for (it = files.begin(); it != files.end(); ++it) {
00183 QString fn = *it;
00184 kdDebug(9028) << "fn = " << fn << endl;
00185 QFile f( fn );
00186 if ( f.open(IO_ReadOnly) ) {
00187 QDomDocument doc;
00188 doc.setContent( &f );
00189 QDomElement root = doc.firstChild().toElement();
00190 QDomElement e = root.firstChild().toElement();
00191 while ( !e.isNull() ){
00192 addTemplate( e.attribute("name"),
00193 e.attribute("description"),
00194 e.attribute("suffixes"),
00195 e.attribute("code") );
00196 e = e.nextSibling().toElement();
00197 }
00198 f.close();
00199 }
00200 }
00201 }
00202
00203
00204 void AbbrevPart::save()
00205 {
00206 QString fn = AbbrevFactory::instance()->dirs()->saveLocation("codetemplates", "", true);
00207 kdDebug(9028) << "fn = " << fn << endl;
00208
00209 QDomDocument doc( "Templates" );
00210 QDomElement root = doc.createElement( "Templates" );
00211 doc.appendChild( root );
00212
00213 QPtrList<CodeTemplate> templates = m_templates.allTemplates();
00214 CodeTemplate *templ;
00215 for (templ = templates.first(); templ; templ = templates.next())
00216 {
00217 QDomElement e = doc.createElement( "Template" );
00218 e.setAttribute( "name", templ->name );
00219 e.setAttribute( "description", templ->description );
00220 e.setAttribute( "suffixes", templ->suffixes );
00221 e.setAttribute( "code", templ->code );
00222 root.appendChild( e );
00223 }
00224
00225 QFile f( fn + "templates" );
00226 if( f.open(IO_WriteOnly) ){
00227 QTextStream stream( &f );
00228 stream << doc.toString();
00229 f.close();
00230 }
00231 }
00232
00233
00234 QString AbbrevPart::currentWord() const
00235 {
00236 uint line, col;
00237 viewCursorIface->cursorPositionReal(&line, &col);
00238 QString str = editIface->textLine(line);
00239 int i;
00240 for (i = col-1; i >= 0; --i)
00241 if( ! (str[i].isLetter() || str[i] == '_') )
00242 break;
00243
00244 return str.mid(i+1, col-i-1);
00245 }
00246
00247
00248 void AbbrevPart::configWidget(KDialogBase *dlg)
00249 {
00250 QVBox *vbox = dlg->addVBoxPage(i18n("Abbreviations"), i18n("Abbreviations"), BarIcon( icon(), KIcon::SizeMedium) );
00251 AbbrevConfigWidget *w = new AbbrevConfigWidget(this, vbox, "abbrev config widget");
00252 connect(dlg, SIGNAL(okClicked()), w, SLOT(accept()));
00253 }
00254
00255
00256 void AbbrevPart::slotExpandText()
00257 {
00258 if( !editIface || !completionIface || !viewCursorIface )
00259 return;
00260
00261 QString word = currentWord();
00262 if (word.isEmpty())
00263 return;
00264
00265 QValueList<KTextEditor::CompletionEntry> entries = findAllWords(editIface->text(), word);
00266 if (entries.count() == 0) {
00267 ;
00268
00269
00270
00271
00272
00273
00274 } else {
00275 m_inCompletion = true;
00276 completionIface->showCompletionBox(entries, word.length());
00277 }
00278 }
00279
00280
00281 QValueList<KTextEditor::CompletionEntry> AbbrevPart::findAllWords(const QString &text, const QString &prefix)
00282 {
00283 QValueList<KTextEditor::CompletionEntry> entries;
00284
00285 KParts::ReadWritePart *part = dynamic_cast<KParts::ReadWritePart*>(partController()->activePart());
00286 QWidget *view = partController()->activeWidget();
00287 if (!part || !view) {
00288 kdDebug(9028) << "no rw part" << endl;
00289 return entries;
00290 }
00291
00292 QString suffix = part->url().url();
00293 int pos = suffix.findRev('.');
00294 if (pos != -1)
00295 suffix.remove(0, pos+1);
00296 kdDebug(9028) << "AbbrevPart::findAllWords with suffix " << suffix << endl;
00297
00298 QMap<QString, bool> map;
00299 QRegExp rx( QString("\\b") + prefix + "[a-zA-Z0-9_]+\\b" );
00300
00301 int idx = 0;
00302 pos = 0;
00303 int len = 0;
00304 while ( (pos = rx.search(text, idx)) != -1 ) {
00305 len = rx.matchedLength();
00306 QString word = text.mid(pos, len);
00307 if (map.find(word) == map.end()) {
00308 KTextEditor::CompletionEntry e;
00309 e.text = word;
00310 entries << e;
00311 map[ word ] = TRUE;
00312 }
00313 idx = pos + len + 1;
00314 }
00315
00316 idx = 0;
00317 pos = 0;
00318 len = 0;
00319 while ( (pos = rx.search(m_completionFile, idx)) != -1 ) {
00320 len = rx.matchedLength();
00321 QString word = m_completionFile.mid(pos, len);
00322 if (map.find(word) == map.end()) {
00323 KTextEditor::CompletionEntry e;
00324 e.text = word;
00325 entries << e;
00326 map[ word ] = TRUE;
00327 }
00328 idx = pos + len + 1;
00329 }
00330
00331
00332 QMap<QString, CodeTemplate*> m = m_templates[suffix];
00333 for (QMap<QString, CodeTemplate*>::const_iterator it = m.begin(); it != m.end() ; ++it) {
00334 KTextEditor::CompletionEntry e;
00335 e.text = it.data()->description + " <abbrev>";
00336 e.userdata = it.key();
00337 entries << e;
00338 }
00339
00340 return entries;
00341 }
00342
00343
00344 void AbbrevPart::slotExpandAbbrev()
00345 {
00346 KParts::ReadWritePart *part = dynamic_cast<KParts::ReadWritePart*>(partController()->activePart());
00347 QWidget *view = partController()->activeWidget();
00348 if (!part || !view) {
00349 kdDebug(9028) << "no rw part" << endl;
00350 return;
00351 }
00352
00353 QString suffix = part->url().url();
00354 int pos = suffix.findRev('.');
00355 if (pos != -1)
00356 suffix.remove(0, pos+1);
00357
00358 KTextEditor::EditInterface *editiface
00359 = dynamic_cast<KTextEditor::EditInterface*>(part);
00360 if (!editiface) {
00361 kdDebug(9028) << "no editiface" << endl;
00362 return;
00363 }
00364 KTextEditor::ViewCursorInterface *cursoriface
00365 = dynamic_cast<KTextEditor::ViewCursorInterface*>(view);
00366 if (!cursoriface) {
00367 kdDebug(9028) << "no viewcursoriface" << endl;
00368 return;
00369 }
00370
00371 QString word = currentWord();
00372 kdDebug(9028) << "Expanding word " << word << " with suffix " << suffix << "." << endl;
00373
00374 QMap<QString, CodeTemplate*> m = m_templates[suffix];
00375 for (QMap<QString, CodeTemplate*>::const_iterator it = m.begin(); it != m.end() ; ++it) {
00376 if (it.key() != word)
00377 continue;
00378
00379 uint line, col;
00380 cursoriface->cursorPositionReal(&line, &col);
00381 editiface->removeText( line, col-word.length(), line, col );
00382 insertChars(it.data()->code );
00383 }
00384 }
00385
00386
00387 void AbbrevPart::insertChars( const QString &chars )
00388 {
00389 unsigned line=0, col=0;
00390 viewCursorIface->cursorPositionReal( &line, &col );
00391
00392 unsigned int currentLine=line, currentCol=col;
00393
00394 QString spaces;
00395 QString s = editIface->textLine( currentLine );
00396 uint i=0;
00397 while( i<s.length() && s[ i ].isSpace() ){
00398 spaces += s[ i ];
00399 ++i;
00400 }
00401
00402 bool foundPipe = false;
00403 QString str;
00404 QTextStream stream( &str, IO_WriteOnly );
00405 QStringList lines = QStringList::split( "\n", chars );
00406 QStringList::Iterator it = lines.begin();
00407 line = currentLine;
00408 while( it != lines.end() ){
00409 QString lineText = *it;
00410 if( it != lines.begin() ){
00411 stream << spaces;
00412 if( !foundPipe )
00413 currentCol += spaces.length();
00414 }
00415
00416 int idx = lineText.find( '|' );
00417 if( idx != -1 ){
00418 stream << lineText.left( idx ) << lineText.mid( idx+1 );
00419 if( !foundPipe ){
00420 foundPipe = true;
00421 currentCol += lineText.left( idx ).length();
00422 kdDebug(9007) << "found pipe at " << currentLine << ", " << currentCol << endl;
00423 }
00424 } else {
00425 stream << lineText;
00426 }
00427
00428 ++it;
00429
00430 if( it != lines.end() ){
00431 stream << "\n";
00432 if( !foundPipe ){
00433 ++currentLine;
00434 currentCol = 0;
00435 }
00436 }
00437 }
00438 editIface->insertText( line, col, str );
00439 kdDebug(9007) << "go to " << currentLine << ", " << currentCol << endl;
00440 viewCursorIface->setCursorPositionReal( currentLine, currentCol );
00441 }
00442
00443 void AbbrevPart::addTemplate( const QString& templ,
00444 const QString& descr,
00445 const QString& suffixes,
00446 const QString& code)
00447 {
00448 m_templates.insert(templ, descr, code, suffixes);
00449 }
00450
00451
00452 void AbbrevPart::removeTemplate( const QString &suffixes, const QString &name )
00453 {
00454 m_templates.remove( suffixes, name );
00455 }
00456
00457
00458 void AbbrevPart::clearTemplates()
00459 {
00460 m_templates.clear();
00461 }
00462
00463 CodeTemplateList AbbrevPart::templates() const
00464 {
00465 return m_templates;
00466 }
00467
00468 void AbbrevPart::slotActivePartChanged( KParts::Part* part )
00469 {
00470 kdDebug(9028) << "AbbrevPart::slotActivePartChanged()" << endl;
00471 KTextEditor::Document* doc = dynamic_cast<KTextEditor::Document*>( part );
00472
00473 if( !doc || !part->widget() || doc == docIface )
00474 {
00475 actionCollection()->action( "edit_expandtext" )->setEnabled( false );
00476 actionCollection()->action( "edit_expandabbrev" )->setEnabled( false );
00477 return;
00478 }
00479
00480 docIface = doc;
00481
00482 if( !docIface ){
00483 docIface = 0;
00484 editIface = 0;
00485 viewCursorIface = 0;
00486 completionIface = 0;
00487 }
00488
00489 editIface = dynamic_cast<KTextEditor::EditInterface*>( part );
00490 viewCursorIface = dynamic_cast<KTextEditor::ViewCursorInterface*>( part->widget() );
00491 completionIface = dynamic_cast<KTextEditor::CodeCompletionInterface*>( part->widget() );
00492
00493 updateActions();
00494
00495 if( !editIface || !viewCursorIface || !completionIface )
00496 return;
00497
00498 disconnect( part->widget(), 0, this, 0 );
00499 disconnect( doc, 0, this, 0 );
00500
00501 connect( part->widget(), SIGNAL(filterInsertString(KTextEditor::CompletionEntry*, QString*)),
00502 this, SLOT(slotFilterInsertString(KTextEditor::CompletionEntry*, QString*)) );
00503
00504 if( autoWordCompletionEnabled() ){
00505 connect( part->widget(), SIGNAL(completionAborted()), this, SLOT(slotCompletionAborted()) );
00506 connect( part->widget(), SIGNAL(completionDone()), this, SLOT(slotCompletionDone()) );
00507 connect( part->widget(), SIGNAL(aboutToShowCompletionBox()), this, SLOT(slotAboutToShowCompletionBox()) );
00508 connect( doc, SIGNAL(textChanged()), this, SLOT(slotTextChanged()) );
00509 }
00510
00511 m_prevLine = -1;
00512 m_prevColumn = -1;
00513 m_sequenceLength = 0;
00514 kdDebug(9028) << "AbbrevPart::slotActivePartChanged() -- OK" << endl;
00515 }
00516
00517 void AbbrevPart::slotTextChanged()
00518 {
00519 if( m_inCompletion )
00520 return;
00521
00522 unsigned int line, col;
00523 viewCursorIface->cursorPositionReal( &line, &col );
00524
00525 if( m_prevLine != int(line) || m_prevColumn+1 != int(col) || col == 0 ){
00526 m_prevLine = line;
00527 m_prevColumn = col;
00528 m_sequenceLength = 1;
00529 return;
00530 }
00531
00532 QString textLine = editIface->textLine( line );
00533 QChar ch = textLine[ col-1 ];
00534 QChar currentChar = textLine[ col ];
00535
00536 if( currentChar.isLetterOrNumber() || currentChar == QChar('_') || !(ch.isLetterOrNumber() || ch == QChar('_')) ){
00537
00538 m_prevLine = -1;
00539 return;
00540 }
00541
00542 if( m_sequenceLength >= 3 )
00543 slotExpandText();
00544
00545 ++m_sequenceLength;
00546 m_prevLine = line;
00547 m_prevColumn = col;
00548 }
00549
00550 void AbbrevPart::slotFilterInsertString( KTextEditor::CompletionEntry* entry, QString* text )
00551 {
00552 kdDebug(9028) << "AbbrevPart::slotFilterInsertString()" << endl;
00553 KParts::ReadWritePart *part = dynamic_cast<KParts::ReadWritePart*>(partController()->activePart());
00554 QWidget *view = partController()->activeWidget();
00555 if (!part || !view) {
00556 kdDebug(9028) << "no rw part" << endl;
00557 return;
00558 }
00559
00560 QString suffix = part->url().url();
00561 int pos = suffix.findRev('.');
00562 if (pos != -1)
00563 suffix.remove(0, pos+1);
00564 kdDebug(9028) << "AbbrevPart::slotFilterInsertString with suffix " << suffix << endl;
00565
00566 if( !entry || !text || !viewCursorIface || !editIface )
00567 return;
00568
00569 QString expand( " <abbrev>" );
00570 if( !entry->userdata.isNull() && entry->text.endsWith(expand) ){
00571 QString macro = entry->text.left( entry->text.length() - expand.length() );
00572 *text = "";
00573 uint line, col;
00574 viewCursorIface->cursorPositionReal( &line, &col );
00575 editIface->removeText( line, col-currentWord().length(), line, col );
00576 insertChars( m_templates[suffix][entry->userdata]->code );
00577 }
00578 }
00579
00580 void AbbrevPart::updateActions()
00581 {
00582 actionCollection()->action( "edit_expandtext" )->setEnabled( docIface != 0 );
00583 actionCollection()->action( "edit_expandabbrev" )->setEnabled( docIface != 0 );
00584 }
00585
00586 void AbbrevPart::slotCompletionAborted()
00587 {
00588 kdDebug(9028) << "AbbrevPart::slotCompletionAborted()" << endl;
00589 m_inCompletion = false;
00590 }
00591
00592 void AbbrevPart::slotCompletionDone()
00593 {
00594 kdDebug(9028) << "AbbrevPart::slotCompletionDone()" << endl;
00595 m_inCompletion = false;
00596 }
00597
00598 void AbbrevPart::slotAboutToShowCompletionBox()
00599 {
00600 kdDebug(9028) << "AbbrevPart::slotAboutToShowCompletionBox()" << endl;
00601 m_inCompletion = true;
00602 }
00603
00604 CodeTemplateList::CodeTemplateList( )
00605 {
00606 allCodeTemplates.setAutoDelete(true);
00607 }
00608
00609 CodeTemplateList::~ CodeTemplateList( )
00610 {
00611 }
00612
00613 QMap< QString, CodeTemplate * > CodeTemplateList::operator [ ]( QString suffix )
00614 {
00615 kdDebug(9028) << "CodeTemplateList::operator []" << endl;
00616 QMap< QString, CodeTemplate * > selectedTemplates;
00617 for (QMap<QString, QMap<QString, CodeTemplate* > >::const_iterator it = templates.begin(); it != templates.end(); ++it)
00618 {
00619 kdDebug(9028) << "CodeTemplateList::operator [] - suffixes " << it.key() << endl;
00620 if (QStringList::split(",", it.key()).contains(suffix))
00621 {
00622 kdDebug(9028) << "CodeTemplateList::operator [] - suffixes " << it.key() << " contains " << suffix << endl;
00623
00624 QMap<QString, CodeTemplate* > m = it.data();
00625 for (QMap<QString, CodeTemplate* >::const_iterator itt = m.begin(); itt != m.end(); ++itt)
00626 {
00627 kdDebug(9028) << "x" << endl;
00628 selectedTemplates[itt.key()] = itt.data();
00629 }
00630 }
00631 }
00632 return selectedTemplates;
00633 }
00634
00635 void CodeTemplateList::insert( QString name, QString description, QString code, QString suffixes )
00636 {
00637 QString origSuffixes = suffixes;
00638
00639 int pos = suffixes.find('(');
00640 if (pos == -1)
00641 return;
00642 suffixes.remove(0, pos+1);
00643 pos = suffixes.find(')');
00644 if (pos == -1)
00645 return;
00646 suffixes.remove(pos, suffixes.length()-pos);
00647
00648
00649 CodeTemplate *t;
00650 if (templates.contains(suffixes) && templates[suffixes].contains(name))
00651 {
00652 kdDebug(9028) << "found template for suffixes " << suffixes << " and name " << name << endl;
00653 t = templates[suffixes][name];
00654 }
00655 else
00656 {
00657 kdDebug(9028) << "creating template for suffixes " << suffixes << " and name " << name << endl;
00658 t = new CodeTemplate();
00659 allCodeTemplates.append(t);
00660 templates[suffixes][name] = t;
00661 }
00662 t->name = name;
00663 t->description = description;
00664 t->code = code;
00665 t->suffixes = origSuffixes;
00666 if (!m_suffixes.contains(origSuffixes))
00667 m_suffixes.append(origSuffixes);
00668 }
00669
00670 QPtrList< CodeTemplate > CodeTemplateList::allTemplates( ) const
00671 {
00672 return allCodeTemplates;
00673 }
00674
00675 void CodeTemplateList::remove( const QString & suffixes, const QString & name )
00676 {
00677 allCodeTemplates.remove(templates[suffixes][name]);
00678 templates[suffixes].remove(name);
00679 }
00680
00681 void CodeTemplateList::clear( )
00682 {
00683 templates.clear();
00684 allCodeTemplates.clear();
00685 }
00686
00687 QStringList CodeTemplateList::suffixes( )
00688 {
00689 return m_suffixes;
00690 }
00691
00692 #include "abbrevpart.moc"