kate Library API Documentation

katefiletype.cpp

00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2001-2003 Christoph Cullmann <cullmann@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License version 2 as published by the Free Software Foundation. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00016 Boston, MA 02111-1307, USA. 00017 */ 00018 00019 #include "katefiletype.h" 00020 #include "katefiletype.moc" 00021 00022 #include "katedocument.h" 00023 #include "kateconfig.h" 00024 #include "katedialogs.h" 00025 #include "kateview.h" 00026 #include "katefactory.h" 00027 00028 #include <kconfig.h> 00029 #include <kmimemagic.h> 00030 #include <kmimetype.h> 00031 #include <kdebug.h> 00032 #include <kiconloader.h> 00033 #include <knuminput.h> 00034 #include <klocale.h> 00035 #include <kpopupmenu.h> 00036 00037 #include <qregexp.h> 00038 #include <qcheckbox.h> 00039 #include <qcombobox.h> 00040 #include <qgroupbox.h> 00041 #include <qhbox.h> 00042 #include <qheader.h> 00043 #include <qhgroupbox.h> 00044 #include <qlabel.h> 00045 #include <qlayout.h> 00046 #include <qlineedit.h> 00047 #include <qpushbutton.h> 00048 #include <qtoolbutton.h> 00049 #include <qvbox.h> 00050 #include <qvgroupbox.h> 00051 #include <qwhatsthis.h> 00052 #include <qwidgetstack.h> 00053 00054 #define KATE_FT_HOWMANY 1024 00055 00056 KateFileTypeManager::KateFileTypeManager () 00057 { 00058 m_types.setAutoDelete (true); 00059 00060 update (); 00061 } 00062 00063 KateFileTypeManager::~KateFileTypeManager () 00064 { 00065 } 00066 00067 // 00068 // read the types from config file and update the internal list 00069 // 00070 void KateFileTypeManager::update () 00071 { 00072 KConfig config ("katefiletyperc", false, false); 00073 00074 QStringList g (config.groupList()); 00075 g.sort (); 00076 00077 m_types.clear (); 00078 for (uint z=0; z < g.count(); z++) 00079 { 00080 config.setGroup (g[z]); 00081 00082 KateFileType *type = new KateFileType (); 00083 00084 type->number = z; 00085 type->name = g[z]; 00086 type->section = config.readEntry ("Section"); 00087 type->wildcards = config.readListEntry ("Wildcards", ';'); 00088 type->mimetypes = config.readListEntry ("Mimetypes", ';'); 00089 type->priority = config.readNumEntry ("Priority"); 00090 type->varLine = config.readEntry ("Variables"); 00091 00092 m_types.append (type); 00093 00094 kdDebug(13020) << "INIT LIST: " << type->name << endl; 00095 } 00096 } 00097 00098 // 00099 // save the given list to config file + update 00100 // 00101 void KateFileTypeManager::save (QPtrList<KateFileType> *v) 00102 { 00103 KConfig config ("katefiletyperc", false, false); 00104 00105 QStringList newg; 00106 for (uint z=0; z < v->count(); z++) 00107 { 00108 config.setGroup (v->at(z)->name); 00109 00110 config.writeEntry ("Section", v->at(z)->section); 00111 config.writeEntry ("Wildcards", v->at(z)->wildcards, ';'); 00112 config.writeEntry ("Mimetypes", v->at(z)->mimetypes, ';'); 00113 config.writeEntry ("Priority", v->at(z)->priority); 00114 00115 QString varLine = v->at(z)->varLine; 00116 if (QRegExp("kate:(.*)").search(varLine) < 0) 00117 varLine.prepend ("kate: "); 00118 00119 config.writeEntry ("Variables", varLine); 00120 00121 newg << v->at(z)->name; 00122 } 00123 00124 QStringList g (config.groupList()); 00125 00126 for (uint z=0; z < g.count(); z++) 00127 { 00128 if (newg.findIndex (g[z]) == -1) 00129 config.deleteGroup (g[z]); 00130 } 00131 00132 config.sync (); 00133 00134 update (); 00135 } 00136 00137 int KateFileTypeManager::fileType (KateDocument *doc) 00138 { 00139 if (!doc) 00140 return -1; 00141 00142 if (m_types.isEmpty()) 00143 return -1; 00144 00145 QString fileName = doc->url().prettyURL(); 00146 int length = doc->url().prettyURL().length(); 00147 00148 // 00149 // first use the wildcards 00150 // 00151 static QStringList commonSuffixes = QStringList::split (";", ".orig;.new;~;.bak;.BAK"); 00152 00153 int result; 00154 if ((result = wildcardsFind(fileName)) != -1) 00155 return result; 00156 00157 QString backupSuffix = KateDocumentConfig::global()->backupSuffix(); 00158 if (fileName.endsWith(backupSuffix)) { 00159 if ((result = wildcardsFind(fileName.left(length - backupSuffix.length()))) != -1) 00160 return result; 00161 } 00162 00163 for (QStringList::Iterator it = commonSuffixes.begin(); it != commonSuffixes.end(); ++it) { 00164 if (*it != backupSuffix && fileName.endsWith(*it)) { 00165 if ((result = wildcardsFind(fileName.left(length - (*it).length()))) != -1) 00166 return result; 00167 } 00168 } 00169 00170 // 00171 // now use the KMimeType POWER ;) 00172 // 00173 QByteArray buf (KATE_FT_HOWMANY); 00174 uint bufpos = 0; 00175 for (uint i=0; i < doc->numLines(); i++) 00176 { 00177 QString line = doc->textLine( i ); 00178 uint len = line.length() + 1; 00179 00180 if (bufpos + len > KATE_FT_HOWMANY) 00181 len = KATE_FT_HOWMANY - bufpos; 00182 00183 memcpy(&buf[bufpos], (line + "\n").latin1(), len); 00184 00185 bufpos += len; 00186 00187 if (bufpos >= KATE_FT_HOWMANY) 00188 break; 00189 } 00190 buf.resize( bufpos ); 00191 00192 int accuracy; 00193 KMimeType::Ptr mt = KMimeType::findByContent( buf, &accuracy ); 00194 00195 QPtrList<KateFileType> types; 00196 00197 for (uint z=0; z < m_types.count(); z++) 00198 { 00199 if (m_types.at(z)->mimetypes.findIndex (mt->name()) > -1) 00200 types.append (m_types.at(z)); 00201 } 00202 00203 if ( !types.isEmpty() ) 00204 { 00205 int pri = -1; 00206 int hl = -1; 00207 00208 for (KateFileType *type = types.first(); type != 0L; type = types.next()) 00209 { 00210 if (type->priority > pri) 00211 { 00212 pri = type->priority; 00213 hl = type->number; 00214 } 00215 } 00216 00217 return hl; 00218 } 00219 00220 return -1; 00221 } 00222 00223 int KateFileTypeManager::wildcardsFind (const QString &fileName) 00224 { 00225 QPtrList<KateFileType> types; 00226 00227 for (uint z=0; z < m_types.count(); z++) 00228 { 00229 for( QStringList::Iterator it = m_types.at(z)->wildcards.begin(); it != m_types.at(z)->wildcards.end(); ++it ) 00230 { 00231 // anders: we need to be sure to match the end of string, as eg a css file 00232 // would otherwise end up with the c hl 00233 QRegExp re(*it, true, true); 00234 if ( ( re.search( fileName ) > -1 ) && ( re.matchedLength() == (int)fileName.length() ) ) 00235 types.append (m_types.at(z)); 00236 } 00237 } 00238 00239 if ( !types.isEmpty() ) 00240 { 00241 int pri = -1; 00242 int hl = -1; 00243 00244 for (KateFileType *type = types.first(); type != 0L; type = types.next()) 00245 { 00246 if (type->priority > pri) 00247 { 00248 pri = type->priority; 00249 hl = type->number; 00250 } 00251 } 00252 00253 return hl; 00254 } 00255 00256 return -1; 00257 } 00258 00259 const KateFileType *KateFileTypeManager::fileType (uint number) 00260 { 00261 if (number < m_types.count()) 00262 return m_types.at(number); 00263 00264 return 0; 00265 } 00266 00267 KateFileTypeConfigTab::KateFileTypeConfigTab( QWidget *parent ) 00268 : KateConfigPage( parent ) 00269 { 00270 m_types.setAutoDelete (true); 00271 m_lastType = 0; 00272 00273 QVBoxLayout *layout = new QVBoxLayout(this, 0, KDialog::spacingHint() ); 00274 00275 // hl chooser 00276 QHBox *hbHl = new QHBox( this ); 00277 layout->add (hbHl); 00278 hbHl->setSpacing( KDialog::spacingHint() ); 00279 QLabel *lHl = new QLabel( i18n("&Filetype:"), hbHl ); 00280 typeCombo = new QComboBox( false, hbHl ); 00281 lHl->setBuddy( typeCombo ); 00282 connect( typeCombo, SIGNAL(activated(int)), 00283 this, SLOT(typeChanged(int)) ); 00284 00285 btndel = new QPushButton( i18n("&Delete"), hbHl ); 00286 connect( btndel, SIGNAL(clicked()), this, SLOT(deleteType()) ); 00287 00288 QPushButton *btnnew = new QPushButton( i18n("&New"), hbHl ); 00289 connect( btnnew, SIGNAL(clicked()), this, SLOT(newType()) ); 00290 00291 gbProps = new QGroupBox( 2, Qt::Horizontal, i18n("Properties"), this ); 00292 layout->add (gbProps); 00293 00294 // file & mime types 00295 QLabel *lname = new QLabel( i18n("N&ame:"), gbProps ); 00296 name = new QLineEdit( gbProps ); 00297 lname->setBuddy( name ); 00298 00299 // file & mime types 00300 QLabel *lsec = new QLabel( i18n("&Section:"), gbProps ); 00301 section = new QLineEdit( gbProps ); 00302 lsec->setBuddy( section ); 00303 00304 // file & mime types 00305 QLabel *lvar = new QLabel( i18n("&Variables:"), gbProps ); 00306 varLine = new QLineEdit( gbProps ); 00307 lvar->setBuddy( varLine ); 00308 00309 // file & mime types 00310 QLabel *lFileExts = new QLabel( i18n("File e&xtensions:"), gbProps ); 00311 wildcards = new QLineEdit( gbProps ); 00312 lFileExts->setBuddy( wildcards ); 00313 00314 QLabel *lMimeTypes = new QLabel( i18n("MIME &types:"), gbProps); 00315 QHBox *hbMT = new QHBox (gbProps); 00316 mimetypes = new QLineEdit( hbMT ); 00317 lMimeTypes->setBuddy( mimetypes ); 00318 00319 QToolButton *btnMTW = new QToolButton(hbMT); 00320 btnMTW->setIconSet(QIconSet(SmallIcon("wizard"))); 00321 connect(btnMTW, SIGNAL(clicked()), this, SLOT(showMTDlg())); 00322 00323 QLabel *lprio = new QLabel( i18n("Prio&rity:"), gbProps); 00324 priority = new KIntNumInput( gbProps ); 00325 lprio->setBuddy( priority ); 00326 00327 layout->addStretch(); 00328 00329 reload(); 00330 00331 connect( name, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotChanged() ) ); 00332 connect( section, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotChanged() ) ); 00333 connect( varLine, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotChanged() ) ); 00334 connect( wildcards, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotChanged() ) ); 00335 connect( mimetypes, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotChanged() ) ); 00336 connect( priority, SIGNAL( valueChanged ( int ) ), this, SLOT( slotChanged() ) ); 00337 } 00338 00339 void KateFileTypeConfigTab::apply() 00340 { 00341 if (!changed()) 00342 return; 00343 00344 save (); 00345 00346 KateFactory::self()->fileTypeManager()->save(&m_types); 00347 } 00348 00349 void KateFileTypeConfigTab::reload() 00350 { 00351 m_types.clear(); 00352 for (uint z=0; z < KateFactory::self()->fileTypeManager()->list()->count(); z++) 00353 { 00354 KateFileType *type = new KateFileType (); 00355 00356 *type = *KateFactory::self()->fileTypeManager()->list()->at(z); 00357 00358 m_types.append (type); 00359 } 00360 00361 update (); 00362 } 00363 00364 void KateFileTypeConfigTab::reset() 00365 { 00366 reload (); 00367 } 00368 00369 void KateFileTypeConfigTab::defaults() 00370 { 00371 reload (); 00372 } 00373 00374 void KateFileTypeConfigTab::update () 00375 { 00376 m_lastType = 0; 00377 00378 typeCombo->clear (); 00379 00380 for( uint i = 0; i < m_types.count(); i++) { 00381 if (m_types.at(i)->section.length() > 0) 00382 typeCombo->insertItem(m_types.at(i)->section + QString ("/") + m_types.at(i)->name); 00383 else 00384 typeCombo->insertItem(m_types.at(i)->name); 00385 } 00386 00387 typeCombo->setCurrentItem (0); 00388 00389 typeChanged (0); 00390 00391 typeCombo->setEnabled (typeCombo->count() > 0); 00392 } 00393 00394 void KateFileTypeConfigTab::deleteType () 00395 { 00396 int type = typeCombo->currentItem (); 00397 00398 if ((type > -1) && ((uint)type < m_types.count())) 00399 { 00400 m_types.remove (type); 00401 update (); 00402 } 00403 } 00404 00405 void KateFileTypeConfigTab::newType () 00406 { 00407 QString newN = i18n("New Filetype"); 00408 00409 for( uint i = 0; i < m_types.count(); i++) { 00410 if (m_types.at(i)->name == newN) 00411 { 00412 typeCombo->setCurrentItem (i); 00413 typeChanged (i); 00414 return; 00415 } 00416 } 00417 00418 KateFileType *newT = new KateFileType (); 00419 newT->priority = 0; 00420 newT->name = newN; 00421 00422 m_types.prepend (newT); 00423 00424 update (); 00425 } 00426 00427 void KateFileTypeConfigTab::save () 00428 { 00429 if (m_lastType) 00430 { 00431 m_lastType->name = name->text (); 00432 m_lastType->section = section->text (); 00433 m_lastType->varLine = varLine->text (); 00434 m_lastType->wildcards = QStringList::split (";", wildcards->text ()); 00435 m_lastType->mimetypes = QStringList::split (";", mimetypes->text ()); 00436 m_lastType->priority = priority->value(); 00437 } 00438 } 00439 00440 void KateFileTypeConfigTab::typeChanged (int type) 00441 { 00442 save (); 00443 00444 KateFileType *t = 0; 00445 00446 if ((type > -1) && ((uint)type < m_types.count())) 00447 t = m_types.at(type); 00448 00449 if (t) 00450 { 00451 gbProps->setTitle (i18n("Properties of %1").arg (typeCombo->currentText())); 00452 00453 gbProps->setEnabled (true); 00454 btndel->setEnabled (true); 00455 00456 name->setText(t->name); 00457 section->setText(t->section); 00458 varLine->setText(t->varLine); 00459 wildcards->setText(t->wildcards.join (";")); 00460 mimetypes->setText(t->mimetypes.join (";")); 00461 priority->setValue(t->priority); 00462 } 00463 else 00464 { 00465 gbProps->setTitle (i18n("Properties")); 00466 00467 gbProps->setEnabled (false); 00468 btndel->setEnabled (false); 00469 00470 name->clear(); 00471 section->clear(); 00472 varLine->clear(); 00473 wildcards->clear(); 00474 mimetypes->clear(); 00475 priority->setValue(0); 00476 } 00477 00478 m_lastType = t; 00479 } 00480 00481 void KateFileTypeConfigTab::showMTDlg() 00482 { 00483 00484 QString text = i18n("Select the MimeTypes you want for this file type.\nPlease note that this will automatically edit the associated file extensions as well."); 00485 QStringList list = QStringList::split( QRegExp("\\s*;\\s*"), mimetypes->text() ); 00486 KMimeTypeChooserDlg *d = new KMimeTypeChooserDlg( this, i18n("Select Mime Types"), text, list ); 00487 if ( d->exec() == KDialogBase::Accepted ) { 00488 // do some checking, warn user if mime types or patterns are removed. 00489 // if the lists are empty, and the fields not, warn. 00490 wildcards->setText(d->patterns().join(";")); 00491 mimetypes->setText(d->mimeTypes().join(";")); 00492 } 00493 } 00494 00495 void KateViewFileTypeAction::init() 00496 { 00497 m_doc = 0; 00498 subMenus.setAutoDelete( true ); 00499 00500 popupMenu()->insertItem ( i18n("None"), this, SLOT(setType(int)), 0, 0); 00501 00502 connect(popupMenu(),SIGNAL(aboutToShow()),this,SLOT(slotAboutToShow())); 00503 } 00504 00505 void KateViewFileTypeAction::updateMenu (Kate::Document *doc) 00506 { 00507 m_doc = (KateDocument *)doc; 00508 } 00509 00510 void KateViewFileTypeAction::slotAboutToShow() 00511 { 00512 KateDocument *doc=m_doc; 00513 int count = KateFactory::self()->fileTypeManager()->list()->count(); 00514 00515 for (int z=0; z<count; z++) 00516 { 00517 QString hlName = KateFactory::self()->fileTypeManager()->list()->at(z)->name; 00518 QString hlSection = KateFactory::self()->fileTypeManager()->list()->at(z)->section; 00519 00520 if ( !hlSection.isEmpty() && (names.contains(hlName) < 1) ) 00521 { 00522 if (subMenusName.contains(hlSection) < 1) 00523 { 00524 subMenusName << hlSection; 00525 QPopupMenu *menu = new QPopupMenu (); 00526 subMenus.append(menu); 00527 popupMenu()->insertItem (hlSection, menu); 00528 } 00529 00530 int m = subMenusName.findIndex (hlSection); 00531 names << hlName; 00532 subMenus.at(m)->insertItem ( hlName, this, SLOT(setType(int)), 0, z+1); 00533 } 00534 else if (names.contains(hlName) < 1) 00535 { 00536 names << hlName; 00537 popupMenu()->insertItem ( hlName, this, SLOT(setType(int)), 0, z+1); 00538 } 00539 } 00540 00541 if (!doc) return; 00542 00543 for (uint i=0;i<subMenus.count();i++) 00544 { 00545 for (uint i2=0;i2<subMenus.at(i)->count();i2++) 00546 subMenus.at(i)->setItemChecked(subMenus.at(i)->idAt(i2),false); 00547 } 00548 popupMenu()->setItemChecked (0, false); 00549 00550 if (doc->fileType() == -1) 00551 popupMenu()->setItemChecked (0, true); 00552 else 00553 { 00554 const KateFileType *t = 0; 00555 if ((t = KateFactory::self()->fileTypeManager()->fileType (doc->fileType()))) 00556 { 00557 int i = subMenusName.findIndex (t->section); 00558 if (i >= 0 && subMenus.at(i)) 00559 subMenus.at(i)->setItemChecked (doc->fileType()+1, true); 00560 else 00561 popupMenu()->setItemChecked (0, true); 00562 } 00563 } 00564 } 00565 00566 void KateViewFileTypeAction::setType (int mode) 00567 { 00568 KateDocument *doc=m_doc; 00569 00570 if (doc) 00571 doc->updateFileType(mode-1, true); 00572 } 00573 00574 // kate: space-indent on; indent-width 2; replace-tabs on;
KDE Logo
This file is part of the documentation for kate Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 16 17:24:01 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003