| # kate Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# 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 //BEGIN Includes
    00020 #include "katefiletype.h"
    00021 #include "katefiletype.moc"
    00022
    00023 #include "katedocument.h"
    00024 #include "kateconfig.h"
    00025 #include "kateview.h"
    00026 #include "katefactory.h"
    00027
    00028 #include <kconfig.h>
    00029 #include <kmimemagic.h>
    00030 #include <kmimetype.h>
    00031 #include <kmimetypechooser.h>
    00032 #include <kdebug.h>
    00033 #include <kiconloader.h>
    00034 #include <knuminput.h>
    00035 #include <klocale.h>
    00036 #include <kpopupmenu.h>
    00037
    00038 #include <qregexp.h>
    00039 #include <qcheckbox.h>
    00040 #include <qcombobox.h>
    00041 #include <qgroupbox.h>
    00042 #include <qhbox.h>
    00043 #include <qheader.h>
    00044 #include <qhgroupbox.h>
    00045 #include <qlabel.h>
    00046 #include <qlayout.h>
    00047 #include <qlineedit.h>
    00048 #include <qpushbutton.h>
    00049 #include <qtoolbutton.h>
    00050 #include <qvbox.h>
    00051 #include <qvgroupbox.h>
    00052 #include <qwhatsthis.h>
    00053 #include <qwidgetstack.h>
    00054
    00055 #define KATE_FT_HOWMANY 1024
    00056 //END Includes
    00057
    00058 //BEGIN KateFileTypeManager
    00059 KateFileTypeManager::KateFileTypeManager ()
    00060 {
    00061   m_types.setAutoDelete (true);
    00062
    00063   update ();
    00064 }
    00065
    00066 KateFileTypeManager::~KateFileTypeManager ()
    00067 {
    00068 }
    00069
    00070 //
    00071 // read the types from config file and update the internal list
    00072 //
    00073 void KateFileTypeManager::update ()
    00074 {
    00075   KConfig config ("katefiletyperc", false, false);
    00076
    00077   QStringList g (config.groupList());
    00078   g.sort ();
    00079
    00080   m_types.clear ();
    00081   for (uint z=0; z < g.count(); z++)
    00082   {
    00083     config.setGroup (g[z]);
    00084
    00085     KateFileType *type = new KateFileType ();
    00086
    00087     type->number = z;
    00088     type->name = g[z];
    00089     type->section = config.readEntry ("Section");
    00090     type->wildcards = config.readListEntry ("Wildcards", ';');
    00091     type->mimetypes = config.readListEntry ("Mimetypes", ';');
    00092     type->priority = config.readNumEntry ("Priority");
    00093     type->varLine = config.readEntry ("Variables");
    00094
    00095     m_types.append (type);
    00096   }
    00097 }
    00098
    00099 //
    00100 // save the given list to config file + update
    00101 //
    00102 void KateFileTypeManager::save (QPtrList<KateFileType> *v)
    00103 {
    00104   KConfig config ("katefiletyperc", false, false);
    00105
    00106   QStringList newg;
    00107   for (uint z=0; z < v->count(); z++)
    00108   {
    00109     config.setGroup (v->at(z)->name);
    00110
    00111     config.writeEntry ("Section", v->at(z)->section);
    00112     config.writeEntry ("Wildcards", v->at(z)->wildcards, ';');
    00113     config.writeEntry ("Mimetypes", v->at(z)->mimetypes, ';');
    00114     config.writeEntry ("Priority", v->at(z)->priority);
    00115
    00116     QString varLine = v->at(z)->varLine;
    00117     if (QRegExp("kate:(.*)").search(varLine) < 0)
    00118       varLine.prepend ("kate: ");
    00119
    00120     config.writeEntry ("Variables", varLine);
    00121
    00122     newg << v->at(z)->name;
    00123   }
    00124
    00125   QStringList g (config.groupList());
    00126
    00127   for (uint z=0; z < g.count(); z++)
    00128   {
    00129     if (newg.findIndex (g[z]) == -1)
    00130       config.deleteGroup (g[z]);
    00131   }
    00132
    00133   config.sync ();
    00134
    00135   update ();
    00136 }
    00137
    00138 int KateFileTypeManager::fileType (KateDocument *doc)
    00139 {
    00140   kdDebug(13020)<<k_funcinfo<<endl;
    00141   if (!doc)
    00142     return -1;
    00143
    00144   if (m_types.isEmpty())
    00145     return -1;
    00146
    00147   QString fileName = doc->url().prettyURL();
    00148   int length = doc->url().prettyURL().length();
    00149
    00150   int result;
    00151
    00152   // Try wildcards
    00153   if ( ! fileName.isEmpty() )
    00154   {
    00155     static QStringList commonSuffixes = QStringList::split (";", ".orig;.new;~;.bak;.BAK");
    00156
    00157     if ((result = wildcardsFind(fileName)) != -1)
    00158       return result;
    00159
    00160     QString backupSuffix = KateDocumentConfig::global()->backupSuffix();
    00161     if (fileName.endsWith(backupSuffix)) {
    00162       if ((result = wildcardsFind(fileName.left(length - backupSuffix.length()))) != -1)
    00163         return result;
    00164     }
    00165
    00166     for (QStringList::Iterator it = commonSuffixes.begin(); it != commonSuffixes.end(); ++it) {
    00167       if (*it != backupSuffix && fileName.endsWith(*it)) {
    00168         if ((result = wildcardsFind(fileName.left(length - (*it).length()))) != -1)
    00169           return result;
    00170       }
    00171     }
    00172   }
    00173
    00174   // Even try the document name, if the URL is empty
    00175   // This is usefull if the document name is set for example by a plugin which
    00176   // created the document
    00177   else if ( (result = wildcardsFind(doc->docName())) != -1)
    00178   {
    00179     kdDebug(13020)<<"KateFiletype::filetype(): got type "<<result<<" using docName '"<<doc->docName()<<"'"<<endl;
    00180     return result;
    00181   }
    00182
    00183   // Try content-based mimetype
    00184   KMimeType::Ptr mt = doc->mimeTypeForContent();
    00185
    00186   QPtrList<KateFileType> types;
    00187
    00188   for (uint z=0; z < m_types.count(); z++)
    00189   {
    00190     if (m_types.at(z)->mimetypes.findIndex (mt->name()) > -1)
    00191       types.append (m_types.at(z));
    00192   }
    00193
    00194   if ( !types.isEmpty() )
    00195   {
    00196     int pri = -1;
    00197     int hl = -1;
    00198
    00199     for (KateFileType *type = types.first(); type != 0L; type = types.next())
    00200     {
    00201       if (type->priority > pri)
    00202       {
    00203         pri = type->priority;
    00204         hl = type->number;
    00205       }
    00206     }
    00207
    00208     return hl;
    00209   }
    00210
    00211
    00212   return -1;
    00213 }
    00214
    00215 int KateFileTypeManager::wildcardsFind (const QString &fileName)
    00216 {
    00217   QPtrList<KateFileType> types;
    00218
    00219   for (uint z=0; z < m_types.count(); z++)
    00220   {
    00221     for( QStringList::Iterator it = m_types.at(z)->wildcards.begin(); it != m_types.at(z)->wildcards.end(); ++it )
    00222     {
    00223       // anders: we need to be sure to match the end of string, as eg a css file
    00224       // would otherwise end up with the c hl
    00225       QRegExp re(*it, true, true);
    00226       if ( ( re.search( fileName ) > -1 ) && ( re.matchedLength() == (int)fileName.length() ) )
    00227         types.append (m_types.at(z));
    00228     }
    00229   }
    00230
    00231   if ( !types.isEmpty() )
    00232   {
    00233     int pri = -1;
    00234     int hl = -1;
    00235
    00236     for (KateFileType *type = types.first(); type != 0L; type = types.next())
    00237     {
    00238       if (type->priority > pri)
    00239       {
    00240         pri = type->priority;
    00241         hl = type->number;
    00242       }
    00243     }
    00244
    00245     return hl;
    00246   }
    00247
    00248   return -1;
    00249 }
    00250
    00251 const KateFileType *KateFileTypeManager::fileType (uint number)
    00252 {
    00253   if (number < m_types.count())
    00254     return m_types.at(number);
    00255
    00256   return 0;
    00257 }
    00258 //END KateFileTypeManager
    00259
    00260 //BEGIN KateFileTypeConfigTab
    00261 KateFileTypeConfigTab::KateFileTypeConfigTab( QWidget *parent )
    00262   : KateConfigPage( parent )
    00263 {
    00264   m_types.setAutoDelete (true);
    00265   m_lastType = 0;
    00266
    00267   QVBoxLayout *layout = new QVBoxLayout(this, 0, KDialog::spacingHint() );
    00268
    00269   // hl chooser
    00270   QHBox *hbHl = new QHBox( this );
    00271   layout->add (hbHl);
    00272   hbHl->setSpacing( KDialog::spacingHint() );
    00273   QLabel *lHl = new QLabel( i18n("&Filetype:"), hbHl );
    00274   typeCombo = new QComboBox( false, hbHl );
    00275   lHl->setBuddy( typeCombo );
    00276   connect( typeCombo, SIGNAL(activated(int)),
    00277            this, SLOT(typeChanged(int)) );
    00278
    00279   QPushButton *btnnew = new QPushButton( i18n("&New"), hbHl );
    00280   connect( btnnew, SIGNAL(clicked()), this, SLOT(newType()) );
    00281
    00282   btndel = new QPushButton( i18n("&Delete"), hbHl );
    00283   connect( btndel, SIGNAL(clicked()), this, SLOT(deleteType()) );
    00284
    00285   gbProps = new QGroupBox( 2, Qt::Horizontal, i18n("Properties"), this );
    00286   layout->add (gbProps);
    00287
    00288   // file & mime types
    00289   QLabel *lname = new QLabel( i18n("N&ame:"), gbProps );
    00290   name  = new QLineEdit( gbProps );
    00291   lname->setBuddy( name );
    00292
    00293   // file & mime types
    00294   QLabel *lsec = new QLabel( i18n("&Section:"), gbProps );
    00295   section  = new QLineEdit( gbProps );
    00296   lsec->setBuddy( section );
    00297
    00298   // file & mime types
    00299   QLabel *lvar = new QLabel( i18n("&Variables:"), gbProps );
    00300   varLine  = new QLineEdit( gbProps );
    00301   lvar->setBuddy( varLine );
    00302
    00303   // file & mime types
    00304   QLabel *lFileExts = new QLabel( i18n("File e&xtensions:"), gbProps );
    00305   wildcards  = new QLineEdit( gbProps );
    00306   lFileExts->setBuddy( wildcards );
    00307
    00308   QLabel *lMimeTypes = new QLabel( i18n("MIME &types:"), gbProps);
    00309   QHBox *hbMT = new QHBox (gbProps);
    00310   mimetypes = new QLineEdit( hbMT );
    00311   lMimeTypes->setBuddy( mimetypes );
    00312
    00313   QToolButton *btnMTW = new QToolButton(hbMT);
    00314   btnMTW->setIconSet(QIconSet(SmallIcon("wizard")));
    00315   connect(btnMTW, SIGNAL(clicked()), this, SLOT(showMTDlg()));
    00316
    00317   QLabel *lprio = new QLabel( i18n("Prio&rity:"), gbProps);
    00318   priority = new KIntNumInput( gbProps );
    00319   lprio->setBuddy( priority );
    00320
    00321   layout->addStretch();
    00322
    00323   reload();
    00324
    00325   connect( name, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotChanged() ) );
    00326   connect( section, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotChanged() ) );
    00327   connect( varLine, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotChanged() ) );
    00328   connect( wildcards, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotChanged() ) );
    00329   connect( mimetypes, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotChanged() ) );
    00330   connect( priority, SIGNAL( valueChanged ( int ) ), this, SLOT( slotChanged() ) );
    00331
    00332   QWhatsThis::add( btnnew, i18n("Create a new file type.") );
    00333   QWhatsThis::add( btndel, i18n("Delete the current file type.") );
    00334   QWhatsThis::add( name, i18n(
    00335       "The name of the filetype will be the text of the corresponding menu item.") );
    00336   QWhatsThis::add( section, i18n(
    00337       "The section name is used to organize the file types in menus.") );
    00338   QWhatsThis::add( varLine, i18n(
    00339       "<p>This string allows you to configure Kate's settings for the files "
    00340       "selected by this mimetype using Kate variables. You can set almost any "
    00341       "configuration option, such as highlight, indent-mode, encoding, etc.</p>"
    00342       "<p>For a full list of known variables, see the manual.</p>") );
    00343   QWhatsThis::add( wildcards, i18n(
    00344       "The wildcards mask allows you to select files by filename. A typical "
    00345       "mask uses an asterisk and the file extension, for example "
    00346       "<code>*.txt; *.text</code>. The string is a semicolon-separated list "
    00347       "of masks.") );
    00348   QWhatsThis::add( mimetypes, i18n(
    00349       "The mime type mask allows you to select files by mimetype. The string is "
    00350       "a semicolon-separated list of mimetypes, for example "
    00351       "<code>text/plain; text/english</code>.") );
    00352   QWhatsThis::add( btnMTW, i18n(
    00353       "Displays a wizard that helps you easily select mimetypes.") );
    00354   QWhatsThis::add( priority, i18n(
    00355       "Sets a priority for this file type. If more than one file type selects the same "
    00356       "file, the one with the highest priority will be used." ) );
    00357 }
    00358
    00359 void KateFileTypeConfigTab::apply()
    00360 {
    00361   if (!changed())
    00362     return;
    00363
    00364   save ();
    00365
    00366   KateFactory::self()->fileTypeManager()->save(&m_types);
    00367 }
    00368
    00369 void KateFileTypeConfigTab::reload()
    00370 {
    00371   m_types.clear();
    00372   for (uint z=0; z < KateFactory::self()->fileTypeManager()->list()->count(); z++)
    00373   {
    00374     KateFileType *type = new KateFileType ();
    00375
    00376     *type = *KateFactory::self()->fileTypeManager()->list()->at(z);
    00377
    00378     m_types.append (type);
    00379   }
    00380
    00381   update ();
    00382 }
    00383
    00384 void KateFileTypeConfigTab::reset()
    00385 {
    00386   reload ();
    00387 }
    00388
    00389 void KateFileTypeConfigTab::defaults()
    00390 {
    00391   reload ();
    00392 }
    00393
    00394 void KateFileTypeConfigTab::update ()
    00395 {
    00396   m_lastType = 0;
    00397
    00398   typeCombo->clear ();
    00399
    00400   for( uint i = 0; i < m_types.count(); i++) {
    00401     if (m_types.at(i)->section.length() > 0)
    00402       typeCombo->insertItem(m_types.at(i)->section + QString ("/") + m_types.at(i)->name);
    00403     else
    00404       typeCombo->insertItem(m_types.at(i)->name);
    00405   }
    00406
    00407   typeCombo->setCurrentItem (0);
    00408
    00409   typeChanged (0);
    00410
    00411   typeCombo->setEnabled (typeCombo->count() > 0);
    00412 }
    00413
    00414 void KateFileTypeConfigTab::deleteType ()
    00415 {
    00416   int type = typeCombo->currentItem ();
    00417
    00418   if ((type > -1) && ((uint)type < m_types.count()))
    00419   {
    00420     m_types.remove (type);
    00421     update ();
    00422   }
    00423 }
    00424
    00425 void KateFileTypeConfigTab::newType ()
    00426 {
    00427   QString newN = i18n("New Filetype");
    00428
    00429   for( uint i = 0; i < m_types.count(); i++) {
    00430     if (m_types.at(i)->name == newN)
    00431     {
    00432       typeCombo->setCurrentItem (i);
    00433       typeChanged (i);
    00434       return;
    00435     }
    00436   }
    00437
    00438   KateFileType *newT = new KateFileType ();
    00439   newT->priority = 0;
    00440   newT->name = newN;
    00441
    00442   m_types.prepend (newT);
    00443
    00444   update ();
    00445 }
    00446
    00447 void KateFileTypeConfigTab::save ()
    00448 {
    00449   if (m_lastType)
    00450   {
    00451     m_lastType->name = name->text ();
    00452     m_lastType->section = section->text ();
    00453     m_lastType->varLine = varLine->text ();
    00454     m_lastType->wildcards = QStringList::split (";", wildcards->text ());
    00455     m_lastType->mimetypes = QStringList::split (";", mimetypes->text ());
    00456     m_lastType->priority = priority->value();
    00457   }
    00458 }
    00459
    00460 void KateFileTypeConfigTab::typeChanged (int type)
    00461 {
    00462   save ();
    00463
    00464   KateFileType *t = 0;
    00465
    00466   if ((type > -1) && ((uint)type < m_types.count()))
    00467     t = m_types.at(type);
    00468
    00469   if (t)
    00470   {
    00471     gbProps->setTitle (i18n("Properties of %1").arg (typeCombo->currentText()));
    00472
    00473     gbProps->setEnabled (true);
    00474     btndel->setEnabled (true);
    00475
    00476     name->setText(t->name);
    00477     section->setText(t->section);
    00478     varLine->setText(t->varLine);
    00479     wildcards->setText(t->wildcards.join (";"));
    00480     mimetypes->setText(t->mimetypes.join (";"));
    00481     priority->setValue(t->priority);
    00482   }
    00483   else
    00484   {
    00485     gbProps->setTitle (i18n("Properties"));
    00486
    00487     gbProps->setEnabled (false);
    00488     btndel->setEnabled (false);
    00489
    00490     name->clear();
    00491     section->clear();
    00492     varLine->clear();
    00493     wildcards->clear();
    00494     mimetypes->clear();
    00495     priority->setValue(0);
    00496   }
    00497
    00498   m_lastType = t;
    00499 }
    00500
    00501 void KateFileTypeConfigTab::showMTDlg()
    00502 {
    00503
    00504   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.");
    00505   QStringList list = QStringList::split( QRegExp("\\s*;\\s*"), mimetypes->text() );
    00506   KMimeTypeChooserDialog *d = new KMimeTypeChooserDialog( i18n("Select Mime Types"), text, list, "text", this );
    00507   if ( d->exec() == KDialogBase::Accepted ) {
    00508     // do some checking, warn user if mime types or patterns are removed.
    00509     // if the lists are empty, and the fields not, warn.
    00510     wildcards->setText( d->chooser()->patterns().join(";") );
    00511     mimetypes->setText( d->chooser()->mimeTypes().join(";") );
    00512   }
    00513 }
    00514 //END KateFileTypeConfigTab
    00515
    00516 //BEGIN KateViewFileTypeAction
    00517 void KateViewFileTypeAction::init()
    00518 {
    00519   m_doc = 0;
    00520   subMenus.setAutoDelete( true );
    00521
    00522   popupMenu()->insertItem ( i18n("None"), this, SLOT(setType(int)), 0,  0);
    00523
    00524   connect(popupMenu(),SIGNAL(aboutToShow()),this,SLOT(slotAboutToShow()));
    00525 }
    00526
    00527 void KateViewFileTypeAction::updateMenu (Kate::Document *doc)
    00528 {
    00529   m_doc = (KateDocument *)doc;
    00530 }
    00531
    00532 void KateViewFileTypeAction::slotAboutToShow()
    00533 {
    00534   KateDocument *doc=m_doc;
    00535   int count = KateFactory::self()->fileTypeManager()->list()->count();
    00536
    00537   for (int z=0; z<count; z++)
    00538   {
    00539     QString hlName = KateFactory::self()->fileTypeManager()->list()->at(z)->name;
    00540     QString hlSection = KateFactory::self()->fileTypeManager()->list()->at(z)->section;
    00541
    00542     if ( !hlSection.isEmpty() && (names.contains(hlName) < 1) )
    00543     {
    00544       if (subMenusName.contains(hlSection) < 1)
    00545       {
    00546         subMenusName << hlSection;
    00547         QPopupMenu *menu = new QPopupMenu ();
    00548         subMenus.append(menu);
    00549         popupMenu()->insertItem (hlSection, menu);
    00550       }
    00551
    00552       int m = subMenusName.findIndex (hlSection);
    00553       names << hlName;
    00554       subMenus.at(m)->insertItem ( hlName, this, SLOT(setType(int)), 0,  z+1);
    00555     }
    00556     else if (names.contains(hlName) < 1)
    00557     {
    00558       names << hlName;
    00559       popupMenu()->insertItem ( hlName, this, SLOT(setType(int)), 0,  z+1);
    00560     }
    00561   }
    00562
    00563   if (!doc) return;
    00564
    00565   for (uint i=0;i<subMenus.count();i++)
    00566   {
    00567     for (uint i2=0;i2<subMenus.at(i)->count();i2++)
    00568       subMenus.at(i)->setItemChecked(subMenus.at(i)->idAt(i2),false);
    00569   }
    00570   popupMenu()->setItemChecked (0, false);
    00571
    00572   if (doc->fileType() == -1)
    00573     popupMenu()->setItemChecked (0, true);
    00574   else
    00575   {
    00576     const KateFileType *t = 0;
    00577     if ((t = KateFactory::self()->fileTypeManager()->fileType (doc->fileType())))
    00578     {
    00579       int i = subMenusName.findIndex (t->section);
    00580       if (i >= 0 && subMenus.at(i))
    00581         subMenus.at(i)->setItemChecked (doc->fileType()+1, true);
    00582       else
    00583         popupMenu()->setItemChecked (0, true);
    00584     }
    00585   }
    00586 }
    00587
    00588 void KateViewFileTypeAction::setType (int mode)
    00589 {
    00590   KateDocument *doc=m_doc;
    00591
    00592   if (doc)
    00593     doc->updateFileType(mode-1, true);
    00594 }
    00595 //END KateViewFileTypeAction
    00596 // kate: space-indent on; indent-width 2; replace-tabs on;

This file is part of the documentation for kate Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:36:36 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003