TDE core libraries
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

autobookmarker.cpp 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. /*
  2. This library is free software you can redistribute it and/or
  3. modify it under the terms of the GNU Library General Public
  4. License.
  5. This library is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  8. Library General Public License for more details.
  9. You should have received a copy of the GNU Library General Public License
  10. along with this library; see the file COPYING.LIB. If not, write to
  11. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  12. Boston, MA 02110-1301, USA.
  13. ---
  14. file: autobookmarker.cpp
  15. KTextEditor plugin to add bookmarks to documents.
  16. Copyright Anders Lund <anders.lund@lund.tdcadsl.dk>, 2003
  17. */
  18. //BEGIN includes
  19. #include "autobookmarker.h"
  20. #include <tdetexteditor/markinterfaceextension.h>
  21. #include <tdetexteditor/editinterface.h>
  22. #include <tdetexteditor/documentinfo.h>
  23. #include <tdetexteditor/document.h>
  24. #include <tdeaction.h>
  25. #include <tdeapplication.h>
  26. #include <tdeconfig.h>
  27. #include <kgenericfactory.h>
  28. #include <kiconloader.h>
  29. #include <tdelistview.h>
  30. #include <tdelocale.h>
  31. #include <kmimetype.h>
  32. #include <kmimetypechooser.h>
  33. #include <kprocess.h>
  34. #include <krun.h>
  35. #include <kstaticdeleter.h>
  36. #include <kurl.h>
  37. #include <tqcheckbox.h>
  38. #include <tqlabel.h>
  39. #include <tqlayout.h>
  40. #include <tqlineedit.h>
  41. #include <tqlistview.h>
  42. #include <tqpopupmenu.h>
  43. #include <tqpushbutton.h>
  44. #include <tqtoolbutton.h>
  45. #include <tqwhatsthis.h>
  46. #include <tqregexp.h>
  47. //#include <kdebug.h>
  48. //END includes
  49. //BEGIN AutoBookmarker
  50. K_EXPORT_COMPONENT_FACTORY( tdetexteditor_autobookmarker, KGenericFactory<AutoBookmarker>( "tdetexteditor_autobookmarker" ) )
  51. AutoBookmarker::AutoBookmarker( TQObject *parent,
  52. const char* name,
  53. const TQStringList& /*args*/ )
  54. : KTextEditor::Plugin ( (KTextEditor::Document*) parent, name ),
  55. KTextEditor::ConfigInterfaceExtension()
  56. {
  57. if ( parent )
  58. connect( parent, TQT_SIGNAL( completed() ), this, TQT_SLOT( slotCompleted() ) );
  59. }
  60. void AutoBookmarker::addView(KTextEditor::View */*view*/)
  61. {
  62. }
  63. void AutoBookmarker::removeView(KTextEditor::View */*view*/)
  64. {
  65. }
  66. KTextEditor::ConfigPage * AutoBookmarker::configPage( uint /*number*/, TQWidget *parent, const char *name )
  67. {
  68. return new AutoBookmarkerConfigPage( parent, name );
  69. }
  70. TQString AutoBookmarker::configPageName( uint /*p*/ ) const
  71. {
  72. // switch (p)
  73. // {
  74. // case 0:
  75. return i18n("AutoBookmarks");
  76. // default:
  77. // return "";
  78. // }
  79. }
  80. TQString AutoBookmarker::configPageFullName( uint /*p*/ ) const
  81. {
  82. // switch (p)
  83. // {
  84. // case 0:
  85. return i18n("Configure AutoBookmarks");
  86. // default:
  87. // return "";
  88. // }
  89. }
  90. TQPixmap AutoBookmarker::configPagePixmap( uint /*p*/, int size ) const
  91. {
  92. return UserIcon("kte_bookmark", size);
  93. }
  94. void AutoBookmarker::slotCompleted()
  95. {
  96. // get the document info
  97. KTextEditor::DocumentInfoInterface *di =
  98. ::tqqt_cast<KTextEditor::DocumentInfoInterface*>(document());
  99. TQString mt;
  100. if ( di ) // we can still try match the URL otherwise
  101. mt = di->mimeType();
  102. TQString fileName;
  103. if ( document()->url().isValid() )
  104. fileName = document()->url().fileName();
  105. ABEntityList *l = ABGlobal::self()->entities();
  106. // for each item, if either mask matches
  107. // * apply if onLoad is true
  108. ABEntityListIterator it( *l );
  109. int n( 0 );
  110. bool found;
  111. AutoBookmarkEnt *e;
  112. while ( ( e = it.current() ) != 0 )
  113. {
  114. found = ( !e->mimemask.count() && !e->filemask.count() ); // no preferences
  115. if ( ! found )
  116. found = ( ! mt.isEmpty() && e->mimemask.contains( mt ) );
  117. if ( ! found )
  118. for( TQStringList::Iterator it1 = e->filemask.begin(); it1 != e->filemask.end(); ++it1 )
  119. {
  120. TQRegExp re(*it1, true, true);
  121. if ( ( found = ( ( re.search( fileName ) > -1 ) && ( re.matchedLength() == (int)fileName.length() ) ) ) )
  122. break;
  123. }
  124. if ( found )
  125. applyEntity( e );
  126. n++;
  127. ++it;
  128. }
  129. }
  130. void AutoBookmarker::applyEntity( AutoBookmarkEnt *e )
  131. {
  132. KTextEditor::Document *doc = document();
  133. KTextEditor::EditInterface *ei = KTextEditor::editInterface( doc );
  134. KTextEditor::MarkInterface *mi = KTextEditor::markInterface( doc );
  135. if ( ! ( ei && mi ) ) return;
  136. TQRegExp re( e->pattern, e->flags & AutoBookmarkEnt::CaseSensitive );
  137. re.setMinimal( e->flags & AutoBookmarkEnt::MinimalMatching );
  138. for ( uint l( 0 ); l < ei->numLines(); l++ )
  139. if ( re.search( ei->textLine( l ) ) > -1 )
  140. mi->setMark( l, KTextEditor::MarkInterface::Bookmark );
  141. }
  142. //END
  143. //BEGIN ABGlobal
  144. ABGlobal *ABGlobal::s_self = 0;
  145. ABGlobal::ABGlobal()
  146. {
  147. m_ents = new ABEntityList;
  148. readConfig();
  149. }
  150. ABGlobal::~ABGlobal()
  151. {
  152. delete m_ents;
  153. }
  154. static KStaticDeleter<ABGlobal> sdSelf;
  155. ABGlobal *ABGlobal::self()
  156. {
  157. if ( ! s_self )
  158. sdSelf.setObject(s_self, new ABGlobal());
  159. return s_self;
  160. }
  161. void ABGlobal::readConfig()
  162. {
  163. if ( ! m_ents )
  164. m_ents = new ABEntityList;
  165. else
  166. m_ents->clear();
  167. TDEConfig *config = new TDEConfig("tdetexteditor_autobookmarkerrc");
  168. uint n( 0 );
  169. while ( config->hasGroup( TQString("autobookmark%1").arg( n ) ) )
  170. {
  171. config->setGroup( TQString("autobookmark%1").arg( n ) );
  172. TQStringList filemask = config->readListEntry( "filemask", ';' );
  173. TQStringList mimemask = config->readListEntry( "mimemask", ';' );
  174. int flags = config->readNumEntry( "flags", 1 );
  175. AutoBookmarkEnt *e = new AutoBookmarkEnt(
  176. config->readEntry( "pattern", "" ),
  177. filemask,
  178. mimemask,
  179. flags
  180. );
  181. m_ents->append( e );
  182. ++n;
  183. }
  184. delete config;
  185. }
  186. void ABGlobal::writeConfig()
  187. {
  188. TDEConfig *config = new TDEConfig("tdetexteditor_autobookmarkerrc");
  189. // clean the config object
  190. TQStringList l = config->groupList();
  191. for ( TQStringList::Iterator it = l.begin(); it != l.end(); ++it )
  192. config->deleteGroup( *it );
  193. // fill in the current list
  194. for ( uint i = 0; i < m_ents->count(); i++ )
  195. {
  196. AutoBookmarkEnt *e = m_ents->at( i );
  197. config->setGroup( TQString("autobookmark%1").arg( i ) );
  198. config->writeEntry( "pattern", e->pattern );
  199. config->writeEntry( "filemask", e->filemask, ';' );
  200. config->writeEntry( "mimemask", e->mimemask, ';' );
  201. config->writeEntry( "flags", e->flags );
  202. }
  203. config->sync(); // explicit -- this is supposedly handled by the d'tor
  204. delete config;
  205. }
  206. //END ABGlobal
  207. //BEGIN AutoBookmarkEntItem
  208. // A QListviewItem which can hold a AutoBookmarkEnt pointer
  209. class AutoBookmarkEntItem : public QListViewItem
  210. {
  211. public:
  212. AutoBookmarkEntItem( TDEListView *lv, AutoBookmarkEnt *e )
  213. : TQListViewItem( lv ),
  214. ent( e )
  215. {
  216. redo();
  217. };
  218. ~AutoBookmarkEntItem(){};
  219. void redo()
  220. {
  221. setText( 0, ent->pattern );
  222. setText( 1, ent->mimemask.join("; ") );
  223. setText( 2, ent->filemask.join("; ") );
  224. }
  225. AutoBookmarkEnt *ent;
  226. };
  227. //END
  228. //BEGIN AutoBookmarkerEntEditor
  229. // Dialog for editing a single autobookmark entity
  230. // * edit the pattern
  231. // * set the file/mime type masks
  232. AutoBookmarkerEntEditor::AutoBookmarkerEntEditor( TQWidget *parent, AutoBookmarkEnt *e )
  233. : KDialogBase( parent, "autobookmark_ent_editor",
  234. true, i18n("Edit Entry"),
  235. KDialogBase::Ok|KDialogBase::Cancel ),
  236. e( e )
  237. {
  238. TQFrame *w = makeMainWidget();
  239. TQGridLayout * lo = new TQGridLayout( w, 5, 3 );
  240. lo->setSpacing( KDialogBase::spacingHint() );
  241. TQLabel *l = new TQLabel( i18n("&Pattern:"), w );
  242. lePattern = new TQLineEdit( e->pattern, w );
  243. l->setBuddy( lePattern );
  244. lo->addWidget( l, 0, 0 );
  245. lo->addMultiCellWidget( lePattern, 0, 0, 1, 2 );
  246. TQWhatsThis::add( lePattern, i18n(
  247. "<p>A regular expression. Matching lines will be bookmarked.</p>" ) );
  248. connect( lePattern, TQT_SIGNAL(textChanged ( const TQString & ) ),this, TQT_SLOT( slotPatternChanged( const TQString& ) ) );
  249. cbCS = new TQCheckBox( i18n("Case &sensitive"), w );
  250. lo->addMultiCellWidget( cbCS, 1, 1, 0, 2 );
  251. cbCS->setChecked( e->flags & AutoBookmarkEnt::CaseSensitive );
  252. TQWhatsThis::add( cbCS, i18n(
  253. "<p>If enabled, the pattern matching will be case sensitive, otherwise "
  254. "not.</p>") );
  255. cbMM = new TQCheckBox( i18n("&Minimal matching"), w );
  256. lo->addMultiCellWidget( cbMM, 2, 2, 0 ,2 );
  257. cbMM->setChecked( e->flags & AutoBookmarkEnt::MinimalMatching );
  258. TQWhatsThis::add( cbMM, i18n(
  259. "<p>If enabled, the pattern matching will use minimal matching; if you "
  260. "do not know what that is, please read the appendix on regular expressions "
  261. "in the kate manual.</p>") );
  262. l = new TQLabel( i18n("&File mask:"), w );
  263. leFileMask = new TQLineEdit( e->filemask.join( "; " ), w );
  264. l->setBuddy( leFileMask );
  265. lo->addWidget( l, 3, 0 );
  266. lo->addMultiCellWidget( leFileMask, 3, 3, 1, 2 );
  267. TQWhatsThis::add( leFileMask, i18n(
  268. "<p>A list of filename masks, separated by semicolons. This can be used "
  269. "to limit the usage of this entity to files with matching names.</p>"
  270. "<p>Use the wizard button to the right of the mimetype entry below to "
  271. "easily fill out both lists.</p>" ) );
  272. l = new TQLabel( i18n("MIME &types:"), w );
  273. leMimeTypes = new TQLineEdit( e->mimemask.join( "; " ), w );
  274. l->setBuddy( leMimeTypes );
  275. lo->addWidget( l, 4, 0 );
  276. lo->addWidget( leMimeTypes, 4, 1 );
  277. TQWhatsThis::add( leMimeTypes, i18n(
  278. "<p>A list of mime types, separated by semicolon. This can be used to "
  279. "limit the usage of this entity to files with matching mime types.</p>"
  280. "<p>Use the wizard button on the right to get a list of existing file "
  281. "types to choose from, using it will fill in the file masks as well.</p>" ) );
  282. TQToolButton *btnMTW = new TQToolButton(w);
  283. lo->addWidget( btnMTW, 4, 2 );
  284. btnMTW->setIconSet(TQIconSet(SmallIcon("wizard")));
  285. connect(btnMTW, TQT_SIGNAL(clicked()), this, TQT_SLOT(showMTDlg()));
  286. TQWhatsThis::add( btnMTW, i18n(
  287. "<p>Click this button to display a checkable list of mimetypes available "
  288. "on your system. When used, the file masks entry above will be filled in "
  289. "with the corresponding masks.</p>") );
  290. slotPatternChanged( lePattern->text() );
  291. }
  292. void AutoBookmarkerEntEditor::slotPatternChanged( const TQString&_pattern )
  293. {
  294. enableButtonOK( !_pattern.isEmpty() );
  295. }
  296. void AutoBookmarkerEntEditor::apply()
  297. {
  298. if ( lePattern->text().isEmpty() ) return;
  299. e->pattern = lePattern->text();
  300. e->filemask = TQStringList::split( TQRegExp("\\s*;\\s*"), leFileMask->text() );
  301. e->mimemask = TQStringList::split( TQRegExp("\\s*;\\s*"), leMimeTypes->text() );
  302. e->flags = 0;
  303. if ( cbCS->isOn() ) e->flags |= AutoBookmarkEnt::CaseSensitive;
  304. if ( cbMM->isOn() ) e->flags |= AutoBookmarkEnt::MinimalMatching;
  305. }
  306. void AutoBookmarkerEntEditor::showMTDlg()
  307. {
  308. TQString text = i18n("Select the MimeTypes for this pattern.\nPlease note that this will automatically edit the associated file extensions as well.");
  309. TQStringList list = TQStringList::split( TQRegExp("\\s*;\\s*"), leMimeTypes->text() );
  310. KMimeTypeChooserDialog d( i18n("Select Mime Types"), text, list, "text", this );
  311. if ( d.exec() == KDialogBase::Accepted ) {
  312. // do some checking, warn user if mime types or patterns are removed.
  313. // if the lists are empty, and the fields not, warn.
  314. leFileMask->setText(d.chooser()->patterns().join("; "));
  315. leMimeTypes->setText(d.chooser()->mimeTypes().join("; "));
  316. }
  317. }
  318. //END
  319. //BEGIN AutoBookmarkerConfigPage
  320. // TODO allow custom mark types with icons
  321. AutoBookmarkerConfigPage::AutoBookmarkerConfigPage( TQWidget *parent, const char *name )
  322. : KTextEditor::ConfigPage( parent, name )
  323. {
  324. TQVBoxLayout *lo = new TQVBoxLayout( this );
  325. lo->setSpacing( KDialogBase::spacingHint() );
  326. TQLabel *l = new TQLabel( i18n("&Patterns"), this );
  327. lo->addWidget( l );
  328. lvPatterns = new TDEListView( this );
  329. lvPatterns->addColumn( i18n("Pattern") );
  330. lvPatterns->addColumn( i18n("Mime Types") );
  331. lvPatterns->addColumn( i18n("File Masks") );
  332. lo->addWidget( lvPatterns );
  333. l->setBuddy( lvPatterns );
  334. TQWhatsThis::add( lvPatterns, i18n(
  335. "<p>This list shows your configured autobookmark entities. When a document "
  336. "is opened, each entity is used in the following way: "
  337. "<ol>"
  338. "<li>The entity is dismissed, if a mime and/or filename mask is defined, "
  339. "and neither matches the document.</li>"
  340. "<li>Otherwise each line of the document is tried against the pattern, "
  341. "and a bookmark is set on matching lines.</li></ul>"
  342. "<p>Use the buttons below to manage your collection of entities.</p>") );
  343. TQHBoxLayout *lo1 = new TQHBoxLayout ( lo );
  344. lo1->setSpacing( KDialogBase::spacingHint() );
  345. btnNew = new TQPushButton( i18n("&New..."), this );
  346. lo1->addWidget( btnNew );
  347. TQWhatsThis::add( btnNew, i18n(
  348. "Press this button to create a new autobookmark entity.") );
  349. btnDel = new TQPushButton( i18n("&Delete"), this );
  350. lo1->addWidget( btnDel );
  351. TQWhatsThis::add( btnDel, i18n(
  352. "Press this button to delete the currently selected entity.") );
  353. btnEdit = new TQPushButton( i18n("&Edit..."), this );
  354. lo1->addWidget( btnEdit );
  355. TQWhatsThis::add( btnEdit, i18n(
  356. "Press this button to edit the currently selected entity.") );
  357. lo1->addStretch( 1 );
  358. connect( btnNew, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotNew()) );
  359. connect( btnDel, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotDel()) );
  360. connect( btnEdit, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotEdit()) );
  361. connect( lvPatterns, TQT_SIGNAL(doubleClicked(TQListViewItem *)), this, TQT_SLOT(slotEdit()) );
  362. m_ents = new ABEntityList();
  363. m_ents->setAutoDelete( true );
  364. reset();
  365. }
  366. // replace the global list with the new one
  367. void AutoBookmarkerConfigPage::apply()
  368. {
  369. ABGlobal::self()->entities()->clear();
  370. ABEntityListIterator it ( *m_ents );
  371. AutoBookmarkEnt *e;
  372. while ( (e = it.current()) != 0 )
  373. {
  374. ABGlobal::self()->entities()->append( e );
  375. ++it;
  376. }
  377. ABGlobal::self()->writeConfig();
  378. // TODO -- how do i refresh all the view menus
  379. }
  380. // renew our copy of the global list
  381. void AutoBookmarkerConfigPage::reset()
  382. {
  383. m_ents->clear(); // unused - no reset button currently
  384. ABEntityListIterator it ( *ABGlobal::self()->entities() );
  385. AutoBookmarkEnt *e;
  386. while ( (e = it.current()) != 0 )
  387. {
  388. AutoBookmarkEnt *me = new AutoBookmarkEnt( *e );
  389. m_ents->append( me );
  390. new AutoBookmarkEntItem( lvPatterns, me );
  391. ++it;
  392. }
  393. }
  394. // TODO (so far not used) we have no defaults (except deleting all items??)
  395. void AutoBookmarkerConfigPage::defaults()
  396. {
  397. // if KMessageBox::warningYesNo()
  398. // clear all
  399. }
  400. // open the edit dialog with a new entity,
  401. // and add it if the dialog is accepted
  402. void AutoBookmarkerConfigPage::slotNew()
  403. {
  404. AutoBookmarkEnt *e = new AutoBookmarkEnt();
  405. AutoBookmarkerEntEditor dlg( this, e );
  406. if ( dlg.exec() )
  407. {
  408. dlg.apply();
  409. new AutoBookmarkEntItem( lvPatterns, e );
  410. m_ents->append( e );
  411. }
  412. }
  413. // delete the selected item and remove it from the list view and internal list
  414. void AutoBookmarkerConfigPage::slotDel()
  415. {
  416. AutoBookmarkEntItem *i = (AutoBookmarkEntItem*)lvPatterns->currentItem();
  417. int idx = m_ents->findRef( i->ent );
  418. m_ents->remove( idx );
  419. delete i;
  420. }
  421. // open the edit dialog with the selected item
  422. void AutoBookmarkerConfigPage::slotEdit()
  423. {
  424. AutoBookmarkEnt *e = ((AutoBookmarkEntItem*)lvPatterns->currentItem())->ent;
  425. AutoBookmarkerEntEditor dlg( this, e );
  426. if ( dlg.exec() )
  427. {
  428. dlg.apply();
  429. ((AutoBookmarkEntItem*)lvPatterns->currentItem())->redo();
  430. }
  431. }
  432. //END AutoBookmarkerConfigPage
  433. //BEGIN AutoBookmarkEnt
  434. AutoBookmarkEnt::AutoBookmarkEnt( const TQString &p, const TQStringList &f, const TQStringList &m, int fl )
  435. : pattern( p ),
  436. filemask( f ),
  437. mimemask( m ),
  438. flags( fl )
  439. {;
  440. }
  441. //END
  442. //
  443. #include "autobookmarker.moc"