kate Library API Documentation

autobookmarker.cpp

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., 59 Temple Place - Suite 330,
00014     Boston, MA 02111-1307, 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 <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 //#include <kdebug.h>
00057 //END includes
00058 
00059 //BEGIN AutoBookmarker
00060 K_EXPORT_COMPONENT_FACTORY( ktexteditor_autobookmarker, KGenericFactory<AutoBookmarker>( "ktexteditor_autobookmarker" ) )
00061 
00062 AutoBookmarker::AutoBookmarker( QObject *parent,
00063                             const char* name,
00064                             const QStringList& /*args*/ )
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 */*view*/)
00073 {
00074 }
00075 
00076 void AutoBookmarker::removeView(KTextEditor::View */*view*/)
00077 {
00078 }
00079 
00080 KTextEditor::ConfigPage * AutoBookmarker::configPage( uint /*number*/, QWidget *parent, const char *name )
00081 {
00082   return new AutoBookmarkerConfigPage( parent, name );
00083 }
00084 
00085 QString AutoBookmarker::configPageName( uint /*p*/ ) const
00086 {
00087 //   switch (p)
00088 //   {
00089 //     case 0:
00090       return i18n("AutoBookmarks");
00091 //     default:
00092 //       return "";
00093 //   }
00094 }
00095 
00096 QString AutoBookmarker::configPageFullName( uint /*p*/ ) const
00097 {
00098 //   switch (p)
00099 //   {
00100 //     case 0:
00101       return i18n("Configure AutoBookmarks");
00102 //     default:
00103 //       return "";
00104 //   }
00105 }
00106 
00107 QPixmap AutoBookmarker::configPagePixmap( uint /*p*/, int size ) const
00108 {
00109   return UserIcon("kte_bookmark", size);
00110 }
00111 
00112 void AutoBookmarker::slotCompleted()
00113 {
00114   // get the document info
00115   KTextEditor::DocumentInfoInterface *di =
00116       static_cast<KTextEditor::DocumentInfoInterface*>(document()->
00117           qt_cast("KTextEditor::DocumentInfoInterface"));
00118   QString mt;
00119   if ( di ) // we can still try match the URL otherwise
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   // 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::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   // clean the config object
00234   QStringList l = config->groupList();
00235   for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it )
00236     config->deleteGroup( *it );
00237 
00238   // fill in the current list
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(); // explicit -- this is supposedly handled by the d'tor
00250   delete config;
00251 }
00252 //END ABGlobal
00253 
00254 //BEGIN AutoBookmarkEntItem
00255 // A QListviewItem which can hold a AutoBookmarkEnt pointer
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 //END
00275 
00276 //BEGIN AutoBookmarkerEntEditor
00277 // Dialog for editing a single autobookmark entity
00278 // * edit the pattern
00279 // * set the file/mime type masks
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     // do some checking, warn user if mime types or patterns are removed.
00364     // if the lists are empty, and the fields not, warn.
00365     leFileMask->setText(d->chooser()->patterns().join("; "));
00366     leMimeTypes->setText(d->chooser()->mimeTypes().join("; "));
00367   }
00368 }
00369 //END
00370 
00371 //BEGIN AutoBookmarkerConfigPage
00372 // TODO allow custom mark types with icons
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 // replace the global list with the new one
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   // TODO -- how do i refresh all the view menus
00444 }
00445 
00446 // renew our copy of the global list
00447 void AutoBookmarkerConfigPage::reset()
00448 {
00449   m_ents->clear(); // unused - no reset button currently
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 // TODO (so far not used) we have no defaults (except deleting all items??)
00463 void AutoBookmarkerConfigPage::defaults()
00464 {
00465   // if KMessageBox::warningYesNo()
00466   // clear all
00467 }
00468 
00469 // open the edit dialog with a new entity,
00470 // and add it if the dialog is accepted
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 // delete the selected item and remove it from the list view and internal list
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 // open the edit dialog with the selected item
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 //END AutoBookmarkerConfigPage
00504 
00505 //BEGIN AutoBookmarkEnt
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 //END
00514 //
00515 #include "autobookmarker.moc"
KDE Logo
This file is part of the documentation for kate Library Version 3.3.90.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 30 10:24:41 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003