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 <kapp.h>
00033 #include <kconfig.h>
00034 #include <kgenericfactory.h>
00035 #include <kiconloader.h>
00036 #include <klistview.h>
00037 #include <klocale.h>
00038 #include <kmimetype.h>
00039 #include <kmimetypechooser.h>
00040 #include <kprocess.h>
00041 #include <krun.h>
00042 #include <kstaticdeleter.h>
00043 #include <kurl.h>
00044
00045 #include <qcheckbox.h>
00046 #include <qlabel.h>
00047 #include <qlayout.h>
00048 #include <qlineedit.h>
00049 #include <qlistview.h>
00050 #include <qpopupmenu.h>
00051 #include <qpushbutton.h>
00052 #include <qtoolbutton.h>
00053 #include <qwhatsthis.h>
00054 #include <qregexp.h>
00055
00056
00057
00058
00059
00060 K_EXPORT_COMPONENT_FACTORY( ktexteditor_autobookmarker, KGenericFactory<AutoBookmarker>( "ktexteditor_autobookmarker" ) )
00061
00062 AutoBookmarker::AutoBookmarker( QObject *parent,
00063 const char* name,
00064 const QStringList& )
00065 : KTextEditor::Plugin ( (KTextEditor::Document*) parent, name ),
00066 KTextEditor::ConfigInterfaceExtension()
00067 {
00068 if ( parent )
00069 connect( parent, SIGNAL( completed() ), this, SLOT( slotCompleted() ) );
00070 }
00071
00072 void AutoBookmarker::addView(KTextEditor::View *)
00073 {
00074 }
00075
00076 void AutoBookmarker::removeView(KTextEditor::View *)
00077 {
00078 }
00079
00080 KTextEditor::ConfigPage * AutoBookmarker::configPage( uint , QWidget *parent, const char *name )
00081 {
00082 return new AutoBookmarkerConfigPage( parent, name );
00083 }
00084
00085 QString AutoBookmarker::configPageName( uint ) const
00086 {
00087
00088
00089
00090 return i18n("AutoBookmarks");
00091
00092
00093
00094 }
00095
00096 QString AutoBookmarker::configPageFullName( uint ) const
00097 {
00098
00099
00100
00101 return i18n("Configure AutoBookmarks");
00102
00103
00104
00105 }
00106
00107 QPixmap AutoBookmarker::configPagePixmap( uint , int size ) const
00108 {
00109 return UserIcon("kte_bookmark", size);
00110 }
00111
00112 void AutoBookmarker::slotCompleted()
00113 {
00114
00115 KTextEditor::DocumentInfoInterface *di =
00116 static_cast<KTextEditor::DocumentInfoInterface*>(document()->
00117 qt_cast("KTextEditor::DocumentInfoInterface"));
00118 QString mt;
00119 if ( di )
00120 {
00121 mt = di->mimeType();
00122 }
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::s_self = 0;
00177
00178 ABGlobal::ABGlobal()
00179 {
00180 m_ents = new ABEntityList;
00181 readConfig();
00182 }
00183
00184 ABGlobal::~ABGlobal()
00185 {
00186 delete m_ents;
00187 }
00188
00189 static KStaticDeleter<ABGlobal> sdSelf;
00190
00191 ABGlobal *ABGlobal::self()
00192 {
00193 if ( ! s_self )
00194 sdSelf.setObject(s_self, new ABGlobal());
00195
00196 return s_self;
00197 }
00198
00199 void ABGlobal::readConfig()
00200 {
00201 if ( ! m_ents )
00202 m_ents = new ABEntityList;
00203 else
00204 m_ents->clear();
00205 KConfig *config = new KConfig("ktexteditor_autobookmarkerrc");
00206
00207 uint n( 0 );
00208 while ( config->hasGroup( QString("autobookmark%1").arg( n ) ) )
00209 {
00210 config->setGroup( QString("autobookmark%1").arg( n ) );
00211 QStringList filemask = config->readListEntry( "filemask", ';' );
00212 QStringList mimemask = config->readListEntry( "mimemask", ';' );
00213 int flags = config->readNumEntry( "flags", 1 );
00214 AutoBookmarkEnt *e = new AutoBookmarkEnt(
00215 config->readEntry( "pattern", "" ),
00216 filemask,
00217 mimemask,
00218 flags
00219 );
00220
00221 m_ents->append( e );
00222
00223 ++n;
00224 }
00225
00226 delete config;
00227 }
00228
00229 void ABGlobal::writeConfig()
00230 {
00231 KConfig *config = new KConfig("ktexteditor_autobookmarkerrc");
00232
00233
00234 QStringList l = config->groupList();
00235 for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it )
00236 config->deleteGroup( *it );
00237
00238
00239 for ( uint i = 0; i < m_ents->count(); i++ )
00240 {
00241 AutoBookmarkEnt *e = m_ents->at( i );
00242 config->setGroup( QString("autobookmark%1").arg( i ) );
00243 config->writeEntry( "pattern", e->pattern );
00244 config->writeEntry( "filemask", e->filemask, ';' );
00245 config->writeEntry( "mimemask", e->mimemask, ';' );
00246 config->writeEntry( "flags", e->flags );
00247 }
00248
00249 config->sync();
00250 delete config;
00251 }
00252
00253
00254
00255
00256 class AutoBookmarkEntItem : public QListViewItem
00257 {
00258 public:
00259 AutoBookmarkEntItem( KListView *lv, AutoBookmarkEnt *e )
00260 : QListViewItem( lv ),
00261 ent( e )
00262 {
00263 redo();
00264 };
00265 ~AutoBookmarkEntItem(){};
00266 void redo()
00267 {
00268 setText( 0, ent->pattern );
00269 setText( 1, ent->mimemask.join("; ") );
00270 setText( 2, ent->filemask.join("; ") );
00271 }
00272 AutoBookmarkEnt *ent;
00273 };
00274
00275
00276
00277
00278
00279
00280 AutoBookmarkerEntEditor::AutoBookmarkerEntEditor( QWidget *parent, AutoBookmarkEnt *e )
00281 : KDialogBase( parent, "autobookmark_ent_editor",
00282 true, i18n("Edit Entry"),
00283 KDialogBase::Ok|KDialogBase::Cancel ),
00284 e( e )
00285 {
00286 QFrame *w = makeMainWidget();
00287 QGridLayout * lo = new QGridLayout( w, 5, 3 );
00288 lo->setSpacing( KDialogBase::spacingHint() );
00289
00290 QLabel *l = new QLabel( i18n("&Pattern:"), w );
00291 lePattern = new QLineEdit( e->pattern, w );
00292 l->setBuddy( lePattern );
00293 lo->addWidget( l, 0, 0 );
00294 lo->addMultiCellWidget( lePattern, 0, 0, 1, 2 );
00295 QWhatsThis::add( lePattern, i18n(
00296 "<p>A regular expression. Matching lines will be bookmarked.</p>" ) );
00297
00298 cbCS = new QCheckBox( i18n("Case &sensitive"), w );
00299 lo->addMultiCellWidget( cbCS, 1, 1, 0, 2 );
00300 cbCS->setChecked( e->flags & AutoBookmarkEnt::CaseSensitive );
00301 QWhatsThis::add( cbCS, i18n(
00302 "<p>If enabled, the pattern matching will be case sensitive, otherwise "
00303 "not.</p>") );
00304
00305 cbMM = new QCheckBox( i18n("&Minimal matching"), w );
00306 lo->addMultiCellWidget( cbMM, 2, 2, 0 ,2 );
00307 cbMM->setChecked( e->flags & AutoBookmarkEnt::MinimalMatching );
00308 QWhatsThis::add( cbMM, i18n(
00309 "<p>If enabled, the pattern matching will use minimal matching; if you "
00310 "do not know what that is, please read the appendix on regular expressions "
00311 "in the kate manual.</p>") );
00312
00313 l = new QLabel( i18n("&File mask:"), w );
00314 leFileMask = new QLineEdit( e->filemask.join( "; " ), w );
00315 l->setBuddy( leFileMask );
00316 lo->addWidget( l, 3, 0 );
00317 lo->addMultiCellWidget( leFileMask, 3, 3, 1, 2 );
00318 QWhatsThis::add( leFileMask, i18n(
00319 "<p>A list of filename masks, separated by semicolons. This can be used "
00320 "to limit the usage of this entity to files with matching names.</p>"
00321 "<p>Use the wizard button to the right of the mimetype entry below to "
00322 "easily fill out both lists.</p>" ) );
00323
00324 l = new QLabel( i18n("MIME &types:"), w );
00325 leMimeTypes = new QLineEdit( e->mimemask.join( "; " ), w );
00326 l->setBuddy( leMimeTypes );
00327 lo->addWidget( l, 4, 0 );
00328 lo->addWidget( leMimeTypes, 4, 1 );
00329 QWhatsThis::add( leMimeTypes, i18n(
00330 "<p>A list of mime types, separated by semicolon. This can be used to "
00331 "limit the usage of this entity to files with matching mime types.</p>"
00332 "<p>Use the wizard button on the right to get a list of existing file "
00333 "types to choose from, using it will fill in the file masks as well.</p>" ) );
00334
00335 QToolButton *btnMTW = new QToolButton(w);
00336 lo->addWidget( btnMTW, 4, 2 );
00337 btnMTW->setIconSet(QIconSet(SmallIcon("wizard")));
00338 connect(btnMTW, SIGNAL(clicked()), this, SLOT(showMTDlg()));
00339 QWhatsThis::add( btnMTW, i18n(
00340 "<p>Click this button to display a checkable list of mimetypes available "
00341 "on your system. When used, the file masks entry above will be filled in "
00342 "with the corresponding masks.</p>") );
00343 }
00344
00345 void AutoBookmarkerEntEditor::apply()
00346 {
00347 if ( lePattern->text().isEmpty() ) return;
00348
00349 e->pattern = lePattern->text();
00350 e->filemask = QStringList::split( QRegExp("\\s*;\\s*"), leFileMask->text() );
00351 e->mimemask = QStringList::split( QRegExp("\\s*;\\s*"), leMimeTypes->text() );
00352 e->flags = 0;
00353 if ( cbCS->isOn() ) e->flags |= AutoBookmarkEnt::CaseSensitive;
00354 if ( cbMM->isOn() ) e->flags |= AutoBookmarkEnt::MinimalMatching;
00355 }
00356
00357 void AutoBookmarkerEntEditor::showMTDlg()
00358 {
00359 QString text = i18n("Select the MimeTypes for this pattern.\nPlease note that this will automatically edit the associated file extensions as well.");
00360 QStringList list = QStringList::split( QRegExp("\\s*;\\s*"), leMimeTypes->text() );
00361 KMimeTypeChooserDialog *d = new KMimeTypeChooserDialog( i18n("Select Mime Types"), text, list, "text", this );
00362 if ( d->exec() == KDialogBase::Accepted ) {
00363
00364
00365 leFileMask->setText(d->chooser()->patterns().join("; "));
00366 leMimeTypes->setText(d->chooser()->mimeTypes().join("; "));
00367 }
00368 }
00369
00370
00371
00372
00373 AutoBookmarkerConfigPage::AutoBookmarkerConfigPage( QWidget *parent, const char *name )
00374 : KTextEditor::ConfigPage( parent, name )
00375 {
00376 QVBoxLayout *lo = new QVBoxLayout( this );
00377 lo->setSpacing( KDialogBase::spacingHint() );
00378
00379 QLabel *l = new QLabel( i18n("&Patterns"), this );
00380 lo->addWidget( l );
00381 lvPatterns = new KListView( this );
00382 lvPatterns->addColumn( i18n("Pattern") );
00383 lvPatterns->addColumn( i18n("Mime Types") );
00384 lvPatterns->addColumn( i18n("File Masks") );
00385 lo->addWidget( lvPatterns );
00386 l->setBuddy( lvPatterns );
00387 QWhatsThis::add( lvPatterns, i18n(
00388 "<p>This list shows your configured autobookmark entities. When a document "
00389 "is opened, each entity is used in the following way: "
00390 "<ol>"
00391 "<li>The entity is dismissed, if a mime and/or filename mask is defined, "
00392 "and neither matches the document.</li>"
00393 "<li>Otherwise each line of the document is tried against the pattern, "
00394 "and a bookmark is set on matching lines.</li></ul>"
00395 "<p>Use the buttons below to manage your collection of entities.</p>") );
00396
00397 QHBoxLayout *lo1 = new QHBoxLayout ( lo );
00398 lo1->setSpacing( KDialogBase::spacingHint() );
00399
00400 btnNew = new QPushButton( i18n("&New..."), this );
00401 lo1->addWidget( btnNew );
00402 QWhatsThis::add( btnNew, i18n(
00403 "Press this button to create a new autobookmark entity.") );
00404
00405 btnDel = new QPushButton( i18n("&Delete"), this );
00406 lo1->addWidget( btnDel );
00407 QWhatsThis::add( btnDel, i18n(
00408 "Press this button to delete the currently selected entity.") );
00409
00410 btnEdit = new QPushButton( i18n("&Edit..."), this );
00411 lo1->addWidget( btnEdit );
00412 QWhatsThis::add( btnEdit, i18n(
00413 "Press this button to edit the currently selected entity.") );
00414
00415 lo1->addStretch( 1 );
00416
00417 connect( btnNew, SIGNAL(clicked()), this, SLOT(slotNew()) );
00418 connect( btnDel, SIGNAL(clicked()), this, SLOT(slotDel()) );
00419 connect( btnEdit, SIGNAL(clicked()), this, SLOT(slotEdit()) );
00420 connect( lvPatterns, SIGNAL(doubleClicked(QListViewItem *)), this, SLOT(slotEdit()) );
00421
00422 m_ents = new ABEntityList();
00423 m_ents->setAutoDelete( true );
00424 reset();
00425 }
00426
00427
00428 void AutoBookmarkerConfigPage::apply()
00429 {
00430 ABGlobal::self()->entities()->clear();
00431
00432 ABEntityListIterator it ( *m_ents );
00433 AutoBookmarkEnt *e;
00434
00435 while ( (e = it.current()) != 0 )
00436 {
00437 ABGlobal::self()->entities()->append( e );
00438 ++it;
00439 }
00440
00441 ABGlobal::self()->writeConfig();
00442
00443
00444 }
00445
00446
00447 void AutoBookmarkerConfigPage::reset()
00448 {
00449 m_ents->clear();
00450
00451 ABEntityListIterator it ( *ABGlobal::self()->entities() );
00452 AutoBookmarkEnt *e;
00453 while ( (e = it.current()) != 0 )
00454 {
00455 AutoBookmarkEnt *me = new AutoBookmarkEnt( *e );
00456 m_ents->append( me );
00457 new AutoBookmarkEntItem( lvPatterns, me );
00458 ++it;
00459 }
00460 }
00461
00462
00463 void AutoBookmarkerConfigPage::defaults()
00464 {
00465
00466
00467 }
00468
00469
00470
00471 void AutoBookmarkerConfigPage::slotNew()
00472 {
00473 AutoBookmarkEnt *e = new AutoBookmarkEnt();
00474 AutoBookmarkerEntEditor dlg( this, e );
00475 if ( dlg.exec() )
00476 {
00477 dlg.apply();
00478 new AutoBookmarkEntItem( lvPatterns, e );
00479 m_ents->append( e );
00480 }
00481 }
00482
00483
00484 void AutoBookmarkerConfigPage::slotDel()
00485 {
00486 AutoBookmarkEntItem *i = (AutoBookmarkEntItem*)lvPatterns->currentItem();
00487 int idx = m_ents->findRef( i->ent );
00488 m_ents->remove( idx );
00489 delete i;
00490 }
00491
00492
00493 void AutoBookmarkerConfigPage::slotEdit()
00494 {
00495 AutoBookmarkEnt *e = ((AutoBookmarkEntItem*)lvPatterns->currentItem())->ent;
00496 AutoBookmarkerEntEditor dlg( this, e );
00497 if ( dlg.exec() )
00498 {
00499 dlg.apply();
00500 ((AutoBookmarkEntItem*)lvPatterns->currentItem())->redo();
00501 }
00502 }
00503
00504
00505
00506 AutoBookmarkEnt::AutoBookmarkEnt( const QString &p, const QStringList &f, const QStringList &m, int fl )
00507 : pattern( p ),
00508 filemask( f ),
00509 mimemask( m ),
00510 flags( fl )
00511 {;
00512 }
00513
00514
00515 #include "autobookmarker.moc"