00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "autobookmarker.h"
00025
00026 #include <ktexteditor/markinterfaceextension.h>
00027 #include <ktexteditor/editinterface.h>
00028 #include <ktexteditor/documentinfo.h>
00029 #include <ktexteditor/document.h>
00030
00031 #include <kaction.h>
00032 #include <kapplication.h>
00033 #include <kconfig.h>
00034 #include <kpluginfactory.h>
00035 #include <kpluginloader.h>
00036 #include <kicon.h>
00037 #include <k3listview.h>
00038 #include <klineedit.h>
00039 #include <klocale.h>
00040 #include <kmimetype.h>
00041 #include <kmimetypechooser.h>
00042 #include <krun.h>
00043 #include <kurl.h>
00044
00045 #include <QtGui/QCheckBox>
00046 #include <QtGui/QLabel>
00047 #include <QtGui/QLayout>
00048 #include <Qt3Support/Q3ListView>
00049 #include <QtGui/QPushButton>
00050 #include <QtGui/QToolButton>
00051 #include <QtCore/QRegExp>
00052
00053 #include <QtGui/QPixmap>
00054 #include <QtGui/QGridLayout>
00055 #include <QtGui/QBoxLayout>
00056
00057
00058
00059
00060
00061 K_PLUGIN_FACTORY( AutoBookmarkerFactory, registerPlugin<AutoBookmarker>(); )
00062 K_EXPORT_PLUGIN( AutoBookmarkerFactory( "ktexteditor_autobookmarker", "ktexteditor_plugins" ) )
00063
00064 AutoBookmarker::AutoBookmarker( QObject *parent,
00065 const char* name,
00066 const QVariantList& )
00067 : KTextEditor::Plugin ( (KTextEditor::Document*) parent, name ),
00068 KTextEditor::ConfigInterfaceExtension()
00069 {
00070 if ( parent )
00071 connect( parent, SIGNAL( completed() ), this, SLOT( slotCompleted() ) );
00072 }
00073
00074 void AutoBookmarker::addView(KTextEditor::View *)
00075 {
00076 }
00077
00078 void AutoBookmarker::removeView(KTextEditor::View *)
00079 {
00080 }
00081
00082 KTextEditor::ConfigPage * AutoBookmarker::configPage( uint , QWidget *parent, const char *name )
00083 {
00084 return new AutoBookmarkerConfigPage( parent, name );
00085 }
00086
00087 QString AutoBookmarker::configPageName( uint ) const
00088 {
00089
00090
00091
00092 return i18n("AutoBookmarks");
00093
00094
00095
00096 }
00097
00098 QString AutoBookmarker::configPageFullName( uint ) const
00099 {
00100
00101
00102
00103 return i18n("Configure AutoBookmarks");
00104
00105
00106
00107 }
00108
00109 QPixmap AutoBookmarker::configPagePixmap( uint , int size ) const
00110 {
00111 return UserIcon("kte_bookmark", size);
00112 }
00113
00114 void AutoBookmarker::slotCompleted()
00115 {
00116
00117 KTextEditor::DocumentInfoInterface *di =
00118 static_cast<KTextEditor::DocumentInfoInterface*>(document()->
00119 qt_cast("KTextEditor::DocumentInfoInterface"));
00120 QString mt;
00121 if ( di )
00122 mt = di->mimeType();
00123
00124 QString fileName;
00125 if ( document()->url().isValid() )
00126 fileName = document()->url().fileName();
00127
00128 ABEntityList *l = ABGlobal::self()->entities();
00129
00130
00131 ABEntityListIterator it( *l );
00132 int n( 0 );
00133 bool found;
00134 AutoBookmarkEnt *e;
00135 while ( ( e = it.current() ) != 0 )
00136 {
00137 found = ( !e->mimemask.count() && !e->filemask.count() );
00138 if ( ! found )
00139 found = ( ! mt.isEmpty() && e->mimemask.contains( mt ) );
00140 if ( ! found )
00141 for( QStringList::Iterator it1 = e->filemask.begin(); it1 != e->filemask.end(); ++it1 )
00142 {
00143 QRegExp re(*it1, true, true);
00144 if ( ( found = ( ( re.search( fileName ) > -1 ) && ( re.matchedLength() == (int)fileName.length() ) ) ) )
00145 break;
00146 }
00147
00148 if ( found )
00149 applyEntity( e );
00150
00151 n++;
00152 ++it;
00153 }
00154
00155 }
00156
00157 void AutoBookmarker::applyEntity( AutoBookmarkEnt *e )
00158 {
00159 KTextEditor::Document *doc = document();
00160 KTextEditor::EditInterface *ei = KTextEditor::editInterface( doc );
00161 KTextEditor::MarkInterface *mi = KTextEditor::markInterface( doc );
00162
00163 if ( ! ( ei && mi ) ) return;
00164
00165 QRegExp re( e->pattern, e->flags & AutoBookmarkEnt::CaseSensitive );
00166 re.setMinimal( e->flags & AutoBookmarkEnt::MinimalMatching );
00167
00168 for ( uint l( 0 ); l < ei->numLines(); l++ )
00169 if ( re.search( ei->textLine( l ) ) > -1 )
00170 mi->setMark( l, KTextEditor::MarkInterface::Bookmark );
00171 }
00172
00173
00174
00175
00176 ABGlobal::ABGlobal()
00177 {
00178 m_ents = new ABEntityList;
00179 readConfig();
00180 }
00181
00182 ABGlobal::~ABGlobal()
00183 {
00184 delete m_ents;
00185 }
00186
00187 ABGlobal *ABGlobal::self()
00188 {
00189 K_STATIC_DELETER(ABGlobal, s_self)
00190 return s_self;
00191 }
00192
00193 void ABGlobal::readConfig()
00194 {
00195 if ( ! m_ents )
00196 m_ents = new ABEntityList;
00197 else
00198 m_ents->clear();
00199 KConfig *config = new KConfig("ktexteditor_autobookmarkerrc");
00200
00201 uint n( 0 );
00202 while ( config->hasGroup( QString("autobookmark%1").arg( n ) ) )
00203 {
00204 KConfigGroup cg( config, QString("autobookmark%1").arg( n ) );
00205 QStringList filemask = cg.readXdgListEntry( "filemask" );
00206 QStringList mimemask = cg.readXdgListEntry( "mimemask" );
00207 int flags = cg.readEntry( "flags", 1 );
00208 AutoBookmarkEnt *e = new AutoBookmarkEnt(
00209 cg.readEntry( "pattern", "" ),
00210 filemask,
00211 mimemask,
00212 flags
00213 );
00214
00215 m_ents->append( e );
00216
00217 ++n;
00218 }
00219
00220 delete config;
00221 }
00222
00223 void ABGlobal::writeConfig()
00224 {
00225 KConfig *config = new KConfig("ktexteditor_autobookmarkerrc");
00226
00227
00228 QStringList l = config->groupList();
00229 for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it )
00230 config->deleteGroup( *it );
00231
00232
00233 for ( uint i = 0; i < m_ents->count(); i++ )
00234 {
00235 AutoBookmarkEnt *e = m_ents->at( i );
00236 KConfigGroup cg( config, QString("autobookmark%1").arg( i ) );
00237 cg.writeEntry( "pattern", e->pattern );
00238 cg.writeXdgListEntry( "filemask", e->filemask );
00239 cg.writeXdgListEntry( "mimemask", e->mimemask );
00240 cg.writeEntry( "flags", e->flags );
00241 }
00242
00243 config->sync();
00244 delete config;
00245 }
00246
00247
00248
00249
00250 class AutoBookmarkEntItem : public Q3ListViewItem
00251 {
00252 public:
00253 AutoBookmarkEntItem( K3ListView *lv, AutoBookmarkEnt *e )
00254 : Q3ListViewItem( lv ),
00255 ent( e )
00256 {
00257 redo();
00258 };
00259 ~AutoBookmarkEntItem(){};
00260 void redo()
00261 {
00262 setText( 0, ent->pattern );
00263 setText( 1, ent->mimemask.join("; ") );
00264 setText( 2, ent->filemask.join("; ") );
00265 }
00266 AutoBookmarkEnt *ent;
00267 };
00268
00269
00270
00271
00272
00273
00274 AutoBookmarkerEntEditor::AutoBookmarkerEntEditor( QWidget *parent, AutoBookmarkEnt *e )
00275 : KDialog( parent ),
00276 e( e )
00277 {
00278 setObjectName( "autobookmark_ent_editor" );
00279 setModal( true );
00280 setCaption( i18n("Edit Entry") );
00281 setButtons( KDialog::Ok | KDialog::Cancel );
00282
00283 QFrame *w = new QFrame( this );
00284 setMainWidget( w );
00285
00286 QGridLayout * lo = new QGridLayout( w, 5, 3 );
00287 lo->setSpacing( KDialog::spacingHint() );
00288
00289 QLabel *l = new QLabel( i18n("&Pattern:"), w );
00290 lePattern = new KLineEdit( e->pattern, w );
00291 l->setBuddy( lePattern );
00292 lo->addWidget( l, 0, 0 );
00293 lo->addMultiCellWidget( lePattern, 0, 0, 1, 2 );
00294 lePattern->setWhatsThis(i18n(
00295 "<p>A regular expression. Matching lines will be bookmarked.</p>" ) );
00296
00297 connect( lePattern, SIGNAL(textChanged ( const QString & ) ),this, SLOT( slotPatternChanged( const QString& ) ) );
00298
00299 cbCS = new QCheckBox( i18n("Case &sensitive"), w );
00300 lo->addMultiCellWidget( cbCS, 1, 1, 0, 2 );
00301 cbCS->setChecked( e->flags & AutoBookmarkEnt::CaseSensitive );
00302 cbCS->setWhatsThis(i18n(
00303 "<p>If enabled, the pattern matching will be case sensitive, otherwise "
00304 "not.</p>") );
00305
00306 cbMM = new QCheckBox( i18n("&Minimal matching"), w );
00307 lo->addMultiCellWidget( cbMM, 2, 2, 0 ,2 );
00308 cbMM->setChecked( e->flags & AutoBookmarkEnt::MinimalMatching );
00309 cbMM->setWhatsThis(i18n(
00310 "<p>If enabled, the pattern matching will use minimal matching; if you "
00311 "do not know what that is, please read the appendix on regular expressions "
00312 "in the kate manual.</p>") );
00313
00314 l = new QLabel( i18n("&File mask:"), w );
00315 leFileMask = new KLineEdit( e->filemask.join( "; " ), w );
00316 l->setBuddy( leFileMask );
00317 lo->addWidget( l, 3, 0 );
00318 lo->addMultiCellWidget( leFileMask, 3, 3, 1, 2 );
00319 leFileMask->setWhatsThis(i18n(
00320 "<p>A list of filename masks, separated by semicolons. This can be used "
00321 "to limit the usage of this entity to files with matching names.</p>"
00322 "<p>Use the wizard button to the right of the mimetype entry below to "
00323 "easily fill out both lists.</p>" ) );
00324
00325 l = new QLabel( i18n("MIME &types:"), w );
00326 leMimeTypes = new KLineEdit( e->mimemask.join( "; " ), w );
00327 l->setBuddy( leMimeTypes );
00328 lo->addWidget( l, 4, 0 );
00329 lo->addWidget( leMimeTypes, 4, 1 );
00330 leMimeTypes->setWhatsThis(i18n(
00331 "<p>A list of mime types, separated by semicolon. This can be used to "
00332 "limit the usage of this entity to files with matching mime types.</p>"
00333 "<p>Use the wizard button on the right to get a list of existing file "
00334 "types to choose from, using it will fill in the file masks as well.</p>" ) );
00335
00336 QToolButton *btnMTW = new QToolButton(w);
00337 lo->addWidget( btnMTW, 4, 2 );
00338 btnMTW->setIcon(KIcon("tools-wizard"));
00339 connect(btnMTW, SIGNAL(clicked()), this, SLOT(showMTDlg()));
00340 btnMTW->setWhatsThis(i18n(
00341 "<p>Click this button to display a checkable list of mimetypes available "
00342 "on your system. When used, the file masks entry above will be filled in "
00343 "with the corresponding masks.</p>") );
00344 slotPatternChanged( lePattern->text() );
00345 }
00346
00347 void AutoBookmarkerEntEditor::slotPatternChanged( const QString&_pattern )
00348 {
00349 enableButtonOk( !_pattern.isEmpty() );
00350 }
00351
00352 void AutoBookmarkerEntEditor::apply()
00353 {
00354 if ( lePattern->text().isEmpty() ) return;
00355
00356 e->pattern = lePattern->text();
00357 e->filemask = leFileMask->text().split( QRegExp("\\s*;\\s*"), QString::SkipEmptyParts );
00358 e->mimemask = leMimeTypes->text().split( QRegExp("\\s*;\\s*"), QString::SkipEmptyParts );
00359 e->flags = 0;
00360 if ( cbCS->isOn() ) e->flags |= AutoBookmarkEnt::CaseSensitive;
00361 if ( cbMM->isOn() ) e->flags |= AutoBookmarkEnt::MinimalMatching;
00362 }
00363
00364 void AutoBookmarkerEntEditor::showMTDlg()
00365 {
00366 QString text = i18n("Select the MimeTypes for this pattern.\nPlease note that this will automatically edit the associated file extensions as well.");
00367 QStringList list = leMimeTypes->text().split( QRegExp("\\s*;\\s*"), QString::SkipEmptyParts );
00368 KMimeTypeChooserDialog d( i18n("Select Mime Types"), text, list, "text", this );
00369 if ( d.exec() == KDialog::Accepted ) {
00370
00371
00372 leFileMask->setText(d.chooser()->patterns().join("; "));
00373 leMimeTypes->setText(d.chooser()->mimeTypes().join("; "));
00374 }
00375 }
00376
00377
00378
00379
00380 AutoBookmarkerConfigPage::AutoBookmarkerConfigPage( QWidget *parent, const char *name )
00381 : KTextEditor::ConfigPage( parent, name )
00382 {
00383 QVBoxLayout *lo = new QVBoxLayout( this );
00384 lo->setSpacing( KDialog::spacingHint() );
00385
00386 QLabel *l = new QLabel( i18n("&Patterns"), this );
00387 lo->addWidget( l );
00388 lvPatterns = new K3ListView( this );
00389 lvPatterns->addColumn( i18n("Pattern") );
00390 lvPatterns->addColumn( i18n("Mime Types") );
00391 lvPatterns->addColumn( i18n("File Masks") );
00392 lo->addWidget( lvPatterns );
00393 l->setBuddy( lvPatterns );
00394 lvPatterns->setWhatsThis(i18n(
00395 "<p>This list shows your configured autobookmark entities. When a document "
00396 "is opened, each entity is used in the following way:<p>"
00397 "<ol>"
00398 "<li>The entity is dismissed, if a mime and/or filename mask is defined, "
00399 "and neither matches the document.</li>"
00400 "<li>Otherwise each line of the document is tried against the pattern, "
00401 "and a bookmark is set on matching lines.</li></ol>"
00402 "<p>Use the buttons below to manage your collection of entities.</p>") );
00403
00404 QHBoxLayout *lo1 = new QHBoxLayout ( lo );
00405 lo1->setSpacing( KDialog::spacingHint() );
00406
00407 btnNew = new QPushButton( i18n("&New..."), this );
00408 lo1->addWidget( btnNew );
00409 btnNew->setWhatsThis(i18n(
00410 "Press this button to create a new autobookmark entity.") );
00411
00412 btnDel = new QPushButton( i18n("&Delete"), this );
00413 lo1->addWidget( btnDel );
00414 btnDel->setWhatsThis(i18n(
00415 "Press this button to delete the currently selected entity.") );
00416
00417 btnEdit = new QPushButton( i18n("&Edit..."), this );
00418 lo1->addWidget( btnEdit );
00419 btnEdit->setWhatsThis(i18n(
00420 "Press this button to edit the currently selected entity.") );
00421
00422 lo1->addStretch( 1 );
00423
00424 connect( btnNew, SIGNAL(clicked()), this, SLOT(slotNew()) );
00425 connect( btnDel, SIGNAL(clicked()), this, SLOT(slotDel()) );
00426 connect( btnEdit, SIGNAL(clicked()), this, SLOT(slotEdit()) );
00427 connect( lvPatterns, SIGNAL(doubleClicked(Q3ListViewItem *)), this, SLOT(slotEdit()) );
00428
00429 m_ents = new ABEntityList();
00430 m_ents->setAutoDelete( true );
00431 reset();
00432 }
00433
00434
00435 void AutoBookmarkerConfigPage::apply()
00436 {
00437 ABGlobal::self()->entities()->clear();
00438
00439 ABEntityListIterator it ( *m_ents );
00440 AutoBookmarkEnt *e;
00441
00442 while ( (e = it.current()) != 0 )
00443 {
00444 ABGlobal::self()->entities()->append( e );
00445 ++it;
00446 }
00447
00448 ABGlobal::self()->writeConfig();
00449
00450
00451 }
00452
00453
00454 void AutoBookmarkerConfigPage::reset()
00455 {
00456 m_ents->clear();
00457
00458 ABEntityListIterator it ( *ABGlobal::self()->entities() );
00459 AutoBookmarkEnt *e;
00460 while ( (e = it.current()) != 0 )
00461 {
00462 AutoBookmarkEnt *me = new AutoBookmarkEnt( *e );
00463 m_ents->append( me );
00464 new AutoBookmarkEntItem( lvPatterns, me );
00465 ++it;
00466 }
00467 }
00468
00469
00470 void AutoBookmarkerConfigPage::defaults()
00471 {
00472
00473
00474 }
00475
00476
00477
00478 void AutoBookmarkerConfigPage::slotNew()
00479 {
00480 AutoBookmarkEnt *e = new AutoBookmarkEnt();
00481 AutoBookmarkerEntEditor dlg( this, e );
00482 if ( dlg.exec() )
00483 {
00484 dlg.apply();
00485 new AutoBookmarkEntItem( lvPatterns, e );
00486 m_ents->append( e );
00487 }
00488 }
00489
00490
00491 void AutoBookmarkerConfigPage::slotDel()
00492 {
00493 AutoBookmarkEntItem *i = (AutoBookmarkEntItem*)lvPatterns->currentItem();
00494 int idx = m_ents->findRef( i->ent );
00495 m_ents->remove( idx );
00496 delete i;
00497 }
00498
00499
00500 void AutoBookmarkerConfigPage::slotEdit()
00501 {
00502 AutoBookmarkEnt *e = ((AutoBookmarkEntItem*)lvPatterns->currentItem())->ent;
00503 AutoBookmarkerEntEditor dlg( this, e );
00504 if ( dlg.exec() )
00505 {
00506 dlg.apply();
00507 ((AutoBookmarkEntItem*)lvPatterns->currentItem())->redo();
00508 }
00509 }
00510
00511
00512
00513 AutoBookmarkEnt::AutoBookmarkEnt( const QString &p, const QStringList &f, const QStringList &m, int fl )
00514 : pattern( p ),
00515 filemask( f ),
00516 mimemask( m ),
00517 flags( fl )
00518 {;
00519 }
00520
00521
00522 #include "autobookmarker.moc"