Kate
autobookmarker.cpp
Go to the documentation of this file.
00001 /* 00002 This library is free software you can redistribute it and/or 00003 modify it under the terms of the GNU Library General Public 00004 License. 00005 00006 This library is distributed in the hope that it will be useful, 00007 but WITHOUT ANY WARRANTY; without even the implied warranty of 00008 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00009 Library General Public License for more details. 00010 00011 You should have received a copy of the GNU Library General Public License 00012 along with this library; see the file COPYING.LIB. If not, write to 00013 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00014 Boston, MA 02110-1301, USA. 00015 00016 --- 00017 file: autobookmarker.cpp 00018 00019 KTextEditor plugin to add bookmarks to documents. 00020 Copyright Anders Lund <anders.lund@lund.tdcadsl.dk>, 2003 00021 */ 00022 00023 //BEGIN includes 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 //Added by qt3to4: 00053 #include <QtGui/QPixmap> 00054 #include <QtGui/QGridLayout> 00055 #include <QtGui/QBoxLayout> 00056 00057 //#include <kdebug.h> 00058 //END includes 00059 00060 //BEGIN AutoBookmarker 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& /*args*/ ) 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 */*view*/) 00075 { 00076 } 00077 00078 void AutoBookmarker::removeView(KTextEditor::View */*view*/) 00079 { 00080 } 00081 00082 KTextEditor::ConfigPage * AutoBookmarker::configPage( uint /*number*/, QWidget *parent, const char *name ) 00083 { 00084 return new AutoBookmarkerConfigPage( parent, name ); 00085 } 00086 00087 QString AutoBookmarker::configPageName( uint /*p*/ ) const 00088 { 00089 // switch (p) 00090 // { 00091 // case 0: 00092 return i18n("AutoBookmarks"); 00093 // default: 00094 // return ""; 00095 // } 00096 } 00097 00098 QString AutoBookmarker::configPageFullName( uint /*p*/ ) const 00099 { 00100 // switch (p) 00101 // { 00102 // case 0: 00103 return i18n("Configure AutoBookmarks"); 00104 // default: 00105 // return ""; 00106 // } 00107 } 00108 00109 QPixmap AutoBookmarker::configPagePixmap( uint /*p*/, int size ) const 00110 { 00111 return UserIcon("kte_bookmark", size); 00112 } 00113 00114 void AutoBookmarker::slotCompleted() 00115 { 00116 // get the document info 00117 KTextEditor::DocumentInfoInterface *di = 00118 static_cast<KTextEditor::DocumentInfoInterface*>(document()-> 00119 qt_cast("KTextEditor::DocumentInfoInterface")); 00120 QString mt; 00121 if ( di ) // we can still try match the URL otherwise 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 // for each item, if either mask matches 00130 // * apply if onLoad is true 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() ); // no preferences 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 //END 00174 00175 //BEGIN ABGlobal 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 // clean the config object 00228 QStringList l = config->groupList(); 00229 for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) 00230 config->deleteGroup( *it ); 00231 00232 // fill in the current list 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(); // explicit -- this is supposedly handled by the d'tor 00244 delete config; 00245 } 00246 //END ABGlobal 00247 00248 //BEGIN AutoBookmarkEntItem 00249 // A QListviewItem which can hold a AutoBookmarkEnt pointer 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 //END 00269 00270 //BEGIN AutoBookmarkerEntEditor 00271 // Dialog for editing a single autobookmark entity 00272 // * edit the pattern 00273 // * set the file/mime type masks 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 00288 QLabel *l = new QLabel( i18n("&Pattern:"), w ); 00289 lePattern = new KLineEdit( e->pattern, w ); 00290 l->setBuddy( lePattern ); 00291 lo->addWidget( l, 0, 0 ); 00292 lo->addMultiCellWidget( lePattern, 0, 0, 1, 2 ); 00293 lePattern->setWhatsThis(i18n( 00294 "<p>A regular expression. Matching lines will be bookmarked.</p>" ) ); 00295 00296 connect( lePattern, SIGNAL(textChanged ( const QString & ) ),this, SLOT( slotPatternChanged( const QString& ) ) ); 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 cbCS->setWhatsThis(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 cbMM->setWhatsThis(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 KLineEdit( e->filemask.join( "; " ), w ); 00315 l->setBuddy( leFileMask ); 00316 lo->addWidget( l, 3, 0 ); 00317 lo->addMultiCellWidget( leFileMask, 3, 3, 1, 2 ); 00318 leFileMask->setWhatsThis(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 KLineEdit( e->mimemask.join( "; " ), w ); 00326 l->setBuddy( leMimeTypes ); 00327 lo->addWidget( l, 4, 0 ); 00328 lo->addWidget( leMimeTypes, 4, 1 ); 00329 leMimeTypes->setWhatsThis(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->setIcon(KIcon("tools-wizard")); 00338 connect(btnMTW, SIGNAL(clicked()), this, SLOT(showMTDlg())); 00339 btnMTW->setWhatsThis(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 slotPatternChanged( lePattern->text() ); 00344 } 00345 00346 void AutoBookmarkerEntEditor::slotPatternChanged( const QString&_pattern ) 00347 { 00348 enableButtonOk( !_pattern.isEmpty() ); 00349 } 00350 00351 void AutoBookmarkerEntEditor::apply() 00352 { 00353 if ( lePattern->text().isEmpty() ) return; 00354 00355 e->pattern = lePattern->text(); 00356 e->filemask = leFileMask->text().split( QRegExp("\\s*;\\s*"), QString::SkipEmptyParts ); 00357 e->mimemask = leMimeTypes->text().split( QRegExp("\\s*;\\s*"), QString::SkipEmptyParts ); 00358 e->flags = 0; 00359 if ( cbCS->isOn() ) e->flags |= AutoBookmarkEnt::CaseSensitive; 00360 if ( cbMM->isOn() ) e->flags |= AutoBookmarkEnt::MinimalMatching; 00361 } 00362 00363 void AutoBookmarkerEntEditor::showMTDlg() 00364 { 00365 QString text = i18n("Select the MimeTypes for this pattern.\nPlease note that this will automatically edit the associated file extensions as well."); 00366 QStringList list = leMimeTypes->text().split( QRegExp("\\s*;\\s*"), QString::SkipEmptyParts ); 00367 KMimeTypeChooserDialog d( i18n("Select Mime Types"), text, list, "text", this ); 00368 if ( d.exec() == KDialog::Accepted ) { 00369 // do some checking, warn user if mime types or patterns are removed. 00370 // if the lists are empty, and the fields not, warn. 00371 leFileMask->setText(d.chooser()->patterns().join("; ")); 00372 leMimeTypes->setText(d.chooser()->mimeTypes().join("; ")); 00373 } 00374 } 00375 //END 00376 00377 //BEGIN AutoBookmarkerConfigPage 00378 // TODO allow custom mark types with icons 00379 AutoBookmarkerConfigPage::AutoBookmarkerConfigPage( QWidget *parent, const char *name ) 00380 : KTextEditor::ConfigPage( parent, name ) 00381 { 00382 QVBoxLayout *lo = new QVBoxLayout( this ); 00383 00384 QLabel *l = new QLabel( i18n("&Patterns"), this ); 00385 lo->addWidget( l ); 00386 lvPatterns = new K3ListView( this ); 00387 lvPatterns->addColumn( i18n("Pattern") ); 00388 lvPatterns->addColumn( i18n("Mime Types") ); 00389 lvPatterns->addColumn( i18n("File Masks") ); 00390 lo->addWidget( lvPatterns ); 00391 l->setBuddy( lvPatterns ); 00392 lvPatterns->setWhatsThis(i18n( 00393 "<p>This list shows your configured autobookmark entities. When a document " 00394 "is opened, each entity is used in the following way:<p>" 00395 "<ol>" 00396 "<li>The entity is dismissed, if a mime and/or filename mask is defined, " 00397 "and neither matches the document.</li>" 00398 "<li>Otherwise each line of the document is tried against the pattern, " 00399 "and a bookmark is set on matching lines.</li></ol>" 00400 "<p>Use the buttons below to manage your collection of entities.</p>") ); 00401 00402 QHBoxLayout *lo1 = new QHBoxLayout ( lo ); 00403 00404 btnNew = new QPushButton( i18n("&New..."), this ); 00405 lo1->addWidget( btnNew ); 00406 btnNew->setWhatsThis(i18n( 00407 "Press this button to create a new autobookmark entity.") ); 00408 00409 btnDel = new QPushButton( i18n("&Delete"), this ); 00410 lo1->addWidget( btnDel ); 00411 btnDel->setWhatsThis(i18n( 00412 "Press this button to delete the currently selected entity.") ); 00413 00414 btnEdit = new QPushButton( i18n("&Edit..."), this ); 00415 lo1->addWidget( btnEdit ); 00416 btnEdit->setWhatsThis(i18n( 00417 "Press this button to edit the currently selected entity.") ); 00418 00419 lo1->addStretch( 1 ); 00420 00421 connect( btnNew, SIGNAL(clicked()), this, SLOT(slotNew()) ); 00422 connect( btnDel, SIGNAL(clicked()), this, SLOT(slotDel()) ); 00423 connect( btnEdit, SIGNAL(clicked()), this, SLOT(slotEdit()) ); 00424 connect( lvPatterns, SIGNAL(doubleClicked(Q3ListViewItem *)), this, SLOT(slotEdit()) ); 00425 00426 m_ents = new ABEntityList(); 00427 m_ents->setAutoDelete( true ); 00428 reset(); 00429 } 00430 00431 // replace the global list with the new one 00432 void AutoBookmarkerConfigPage::apply() 00433 { 00434 ABGlobal::self()->entities()->clear(); 00435 00436 ABEntityListIterator it ( *m_ents ); 00437 AutoBookmarkEnt *e; 00438 00439 while ( (e = it.current()) != 0 ) 00440 { 00441 ABGlobal::self()->entities()->append( e ); 00442 ++it; 00443 } 00444 00445 ABGlobal::self()->writeConfig(); 00446 00447 // TODO -- how do i refresh all the view menus 00448 } 00449 00450 // renew our copy of the global list 00451 void AutoBookmarkerConfigPage::reset() 00452 { 00453 m_ents->clear(); // unused - no reset button currently 00454 00455 ABEntityListIterator it ( *ABGlobal::self()->entities() ); 00456 AutoBookmarkEnt *e; 00457 while ( (e = it.current()) != 0 ) 00458 { 00459 AutoBookmarkEnt *me = new AutoBookmarkEnt( *e ); 00460 m_ents->append( me ); 00461 new AutoBookmarkEntItem( lvPatterns, me ); 00462 ++it; 00463 } 00464 } 00465 00466 // TODO (so far not used) we have no defaults (except deleting all items??) 00467 void AutoBookmarkerConfigPage::defaults() 00468 { 00469 // if KMessageBox::warningYesNo() 00470 // clear all 00471 } 00472 00473 // open the edit dialog with a new entity, 00474 // and add it if the dialog is accepted 00475 void AutoBookmarkerConfigPage::slotNew() 00476 { 00477 AutoBookmarkEnt *e = new AutoBookmarkEnt(); 00478 AutoBookmarkerEntEditor dlg( this, e ); 00479 if ( dlg.exec() ) 00480 { 00481 dlg.apply(); 00482 new AutoBookmarkEntItem( lvPatterns, e ); 00483 m_ents->append( e ); 00484 } 00485 } 00486 00487 // delete the selected item and remove it from the list view and internal list 00488 void AutoBookmarkerConfigPage::slotDel() 00489 { 00490 AutoBookmarkEntItem *i = (AutoBookmarkEntItem*)lvPatterns->currentItem(); 00491 int idx = m_ents->findRef( i->ent ); 00492 m_ents->remove( idx ); 00493 delete i; 00494 } 00495 00496 // open the edit dialog with the selected item 00497 void AutoBookmarkerConfigPage::slotEdit() 00498 { 00499 AutoBookmarkEnt *e = ((AutoBookmarkEntItem*)lvPatterns->currentItem())->ent; 00500 AutoBookmarkerEntEditor dlg( this, e ); 00501 if ( dlg.exec() ) 00502 { 00503 dlg.apply(); 00504 ((AutoBookmarkEntItem*)lvPatterns->currentItem())->redo(); 00505 } 00506 } 00507 //END AutoBookmarkerConfigPage 00508 00509 //BEGIN AutoBookmarkEnt 00510 AutoBookmarkEnt::AutoBookmarkEnt( const QString &p, const QStringList &f, const QStringList &m, int fl ) 00511 : pattern( p ), 00512 filemask( f ), 00513 mimemask( m ), 00514 flags( fl ) 00515 {; 00516 } 00517 //END 00518 // 00519 #include "autobookmarker.moc"
KDE 4.6 API Reference