00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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
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
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
00232
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
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
00295
QLabel *lname =
new QLabel( i18n(
"N&ame:"), gbProps );
00296
name =
new QLineEdit( gbProps );
00297 lname->
setBuddy( name );
00298
00299
00300
QLabel *lsec =
new QLabel( i18n(
"&Section:"), gbProps );
00301 section =
new QLineEdit( gbProps );
00302 lsec->
setBuddy( section );
00303
00304
00305
QLabel *lvar =
new QLabel( i18n(
"&Variables:"), gbProps );
00306 varLine =
new QLineEdit( gbProps );
00307 lvar->
setBuddy( varLine );
00308
00309
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
00489
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