kmail

snippetwidget.cpp
1 /***************************************************************************
2  * snippet feature from tdevelop/plugins/snippet/ *
3  * *
4  * Copyright (C) 2007 by Robert Gruber *
5  * rgruber@users.sourceforge.net *
6  * *
7  * This program is free software; you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or *
10  * (at your option) any later version. *
11  * *
12  ***************************************************************************/
13 
14 #include <kurl.h>
15 #include <kdebug.h>
16 #include <tdelocale.h>
17 #include <tqlayout.h>
18 #include <kpushbutton.h>
19 #include <tdelistview.h>
20 #include <tqheader.h>
21 #include <klineedit.h>
22 #include <ktextedit.h>
23 #include <tdemessagebox.h>
24 #include <tdeconfig.h>
25 #include <tqtooltip.h>
26 #include <tdepopupmenu.h>
27 #include <tqregexp.h>
28 #include <tqinputdialog.h>
29 #include <tqlabel.h>
30 #include <tqcheckbox.h>
31 #include <tqwhatsthis.h>
32 #include <tqdragobject.h>
33 #include <tqtimer.h>
34 #include <kcombobox.h>
35 #include <kmedit.h>
36 #include <kiconloader.h>
37 #include <tdeshortcut.h>
38 #include <tdeaction.h>
39 #include <kkeybutton.h>
40 
41 #include "snippetdlg.h"
42 #include "snippetitem.h"
43 #include "snippetwidget.h"
44 
45 #include <cassert>
46 
47 SnippetWidget::SnippetWidget(KMEdit* editor, TDEActionCollection* actionCollection, TQWidget* parent)
48  : TDEListView(parent, "snippet widget"), TQToolTip( viewport() ),
49  mEditor( editor ), mActionCollection( actionCollection )
50 {
51  // init the TQPtrList
52  _list.setAutoDelete(TRUE);
53 
54  // init the TDEListView
55  setSorting( -1 );
56  addColumn( "" );
57  setFullWidth(true);
58  header()->hide();
59  setAcceptDrops(true);
60  setDragEnabled(true);
61  setDropVisualizer(false);
62  setRootIsDecorated(true);
63 
64  //connect the signals
65  connect( this, TQ_SIGNAL( contextMenuRequested ( TQListViewItem *, const TQPoint & , int ) ),
66  this, TQ_SLOT( showPopupMenu(TQListViewItem *, const TQPoint & , int ) ) );
67 
68  connect( this, TQ_SIGNAL( doubleClicked (TQListViewItem *) ),
69  this, TQ_SLOT( slotEdit( TQListViewItem *) ) );
70  connect( this, TQ_SIGNAL( returnPressed (TQListViewItem *) ),
71  this, TQ_SLOT( slotExecuted( TQListViewItem *) ) );
72 
73  connect( this, TQ_SIGNAL( dropped(TQDropEvent *, TQListViewItem *) ),
74  this, TQ_SLOT( slotDropped(TQDropEvent *, TQListViewItem *) ) );
75 
76  connect( editor, TQ_SIGNAL( insertSnippet() ), this, TQ_SLOT( slotExecute() ));
77 
78  _cfg = 0;
79 
80  TQTimer::singleShot(0, this, TQ_SLOT(initConfig()));
81 }
82 
83 SnippetWidget::~SnippetWidget()
84 {
85  writeConfig();
86  delete _cfg;
87 
88  /* We need to delete the child items before the parent items
89  otherwise KDevelop would crash on exiting */
90  SnippetItem * item;
91  while (_list.count() > 0) {
92  for (item=_list.first(); item; item=_list.next()) {
93  if (item->childCount() == 0)
94  _list.remove(item);
95  }
96  }
97 }
98 
99 
105 {
106  //kdDebug(5006) << "Ender slotAdd()" << endl;
107  SnippetDlg dlg( mActionCollection, this, "SnippetDlg");
108 
109  /*check if the user clicked a SnippetGroup
110  If not, we set the group variable to the SnippetGroup
111  which the selected item is a child of*/
112  SnippetGroup * group = dynamic_cast<SnippetGroup*>(selectedItem());
113  if ( !group && selectedItem() )
114  group = dynamic_cast<SnippetGroup*>(selectedItem()->parent());
115 
116  /* still no group, let's make a default one */
117  if (!group ) {
118  if ( _list.isEmpty() ) {
119  group = new SnippetGroup(this, i18n("General"), SnippetGroup::getMaxId() );
120  _list.append( group );
121  } else {
122  group = dynamic_cast<SnippetGroup*>( _list.first() );
123  }
124  }
125  assert( group );
126 
127  /*fill the combobox with the names of all SnippetGroup entries*/
128  for (SnippetItem *it=_list.first(); it; it=_list.next()) {
129  if (dynamic_cast<SnippetGroup*>(it)) {
130  dlg.cbGroup->insertItem(it->getName());
131  }
132  }
133  dlg.cbGroup->setCurrentText(group->getName());
134 
135  if (dlg.exec() == TQDialog::Accepted) {
136  group = dynamic_cast<SnippetGroup*>(SnippetItem::findItemByName(dlg.cbGroup->currentText(), _list));
137  _list.append( makeItem( group, dlg.snippetName->text(), dlg.snippetText->text(), dlg.keyButton->shortcut() ) );
138  }
139 }
140 
145 SnippetItem* SnippetWidget::makeItem( SnippetItem* parent, const TQString& name, const TQString& text, const TDEShortcut& shortcut )
146 {
147  SnippetItem * item = new SnippetItem(parent, name, text);
148  const TQString actionName = i18n("Snippet %1").arg(name);
149  const TQString normalizedName = TQString(actionName).replace(" ", "_");
150  if ( !mActionCollection->action(normalizedName.utf8().data() ) ) {
151  TDEAction * action = new TDEAction( actionName, shortcut, item,
152  TQ_SLOT( slotExecute() ), mActionCollection,
153  normalizedName.utf8() );
154  item->setAction(action);
155  connect( item, TQ_SIGNAL( execute( TQListViewItem* ) ),
156  this, TQ_SLOT( slotExecuted( TQListViewItem* ) ) );
157  }
158  return item;
159 }
160 
166 {
167  //kdDebug(5006) << "Ender slotAddGroup()" << endl;
168  SnippetDlg dlg( mActionCollection, this, "SnippetDlg");
169  dlg.setShowShortcut( false );
170  dlg.snippetText->setEnabled(false);
171  dlg.snippetText->setText(i18n("GROUP"));
172  dlg.setCaption(i18n("Add Group"));
173  dlg.cbGroup->insertItem(i18n("All"));
174  dlg.cbGroup->setCurrentText(i18n("All"));
175 
176  if (dlg.exec() == TQDialog::Accepted) {
177  _list.append( new SnippetGroup(this, dlg.snippetName->text(), SnippetGroup::getMaxId() ) );
178  }
179 }
180 
181 
187 {
188  //get current data
189  TQListViewItem * item = currentItem();
190  SnippetItem *snip = dynamic_cast<SnippetItem*>( item );
191  SnippetGroup *group = dynamic_cast<SnippetGroup*>( item );
192  if (!snip)
193  return;
194 
195  if (group) {
196  if (group->childCount() > 0 &&
197  KMessageBox::warningContinueCancel(this, i18n("Do you really want to remove this group and all its snippets?"),TQString(),KStdGuiItem::del())
198  == KMessageBox::Cancel)
199  return;
200 
201  SnippetItem *it=_list.first();
202  while ( it ) {
203  if (it->getParent() == group->getId()) {
204  SnippetItem *doomed = it;
205  it = _list.next();
206  //kdDebug(5006) << "remove " << doomed->getName() << endl;
207  _list.remove(doomed);
208  } else {
209  it = _list.next();
210  }
211  }
212  }
213 
214  //kdDebug(5006) << "remove " << snip->getName() << endl;
215  _list.remove(snip);
216 }
217 
218 
219 
224 void SnippetWidget::slotEdit( TQListViewItem* item )
225 {
226  if( item == 0 ) {
227  item = currentItem();
228  }
229 
230  SnippetGroup *pGroup = dynamic_cast<SnippetGroup*>(item);
231  SnippetItem *pSnippet = dynamic_cast<SnippetItem*>( item );
232  if (!pSnippet || pGroup) /*selected item must be a SnippetItem but MUST not be a SnippetGroup*/
233  return;
234 
235  //init the dialog
236  SnippetDlg dlg( mActionCollection, this, "SnippetDlg");
237  dlg.snippetName->setText(pSnippet->getName());
238  dlg.snippetText->setText(pSnippet->getText());
239  dlg.keyButton->setShortcut( pSnippet->getAction()->shortcut(), false );
240  dlg.btnAdd->setText(i18n("&Apply"));
241 
242  dlg.setCaption(i18n("Edit Snippet"));
243  /*fill the combobox with the names of all SnippetGroup entries*/
244  for (SnippetItem *it=_list.first(); it; it=_list.next()) {
245  if (dynamic_cast<SnippetGroup*>(it)) {
246  dlg.cbGroup->insertItem(it->getName());
247  }
248  }
249  dlg.cbGroup->setCurrentText(SnippetItem::findGroupById(pSnippet->getParent(), _list)->getName());
250 
251  if (dlg.exec() == TQDialog::Accepted) {
252  //update the TDEListView and the SnippetItem
253  item->setText( 0, dlg.snippetName->text() );
254  pSnippet->setName( dlg.snippetName->text() );
255  pSnippet->setText( dlg.snippetText->text() );
256  pSnippet->getAction()->setShortcut( dlg.keyButton->shortcut());
257 
258  /* if the user changed the parent we need to move the snippet */
259  if ( SnippetItem::findGroupById(pSnippet->getParent(), _list)->getName() != dlg.cbGroup->currentText() ) {
260  SnippetGroup * newGroup = dynamic_cast<SnippetGroup*>(SnippetItem::findItemByName(dlg.cbGroup->currentText(), _list));
261  pSnippet->parent()->takeItem(pSnippet);
262  newGroup->insertItem(pSnippet);
263  pSnippet->resetParent();
264  }
265 
266  setSelected(item, TRUE);
267  }
268 }
269 
275 {
276  //get current data
277  TQListViewItem * item = currentItem();
278 
279  SnippetGroup *pGroup = dynamic_cast<SnippetGroup*>( item );
280  if (!pGroup) /*selected item MUST be a SnippetGroup*/
281  return;
282 
283  //init the dialog
284  SnippetDlg dlg( mActionCollection, this, "SnippetDlg" );
285  dlg.setShowShortcut( false );
286  dlg.snippetName->setText(pGroup->getName());
287  dlg.snippetText->setText(pGroup->getText());
288  dlg.btnAdd->setText(i18n("&Apply"));
289  dlg.snippetText->setEnabled(FALSE);
290  dlg.setCaption(i18n("Edit Group"));
291  dlg.cbGroup->insertItem(i18n("All"));
292 
293  if (dlg.exec() == TQDialog::Accepted) {
294  //update the TDEListView and the SnippetGroup
295  item->setText( 0, dlg.snippetName->text() );
296  pGroup->setName( dlg.snippetName->text() );
297 
298  setSelected(item, TRUE);
299  }
300 }
301 
302 void SnippetWidget::slotExecuted(TQListViewItem * item)
303 {
304  if( item == 0 )
305  {
306  item = currentItem();
307  }
308 
309  SnippetItem *pSnippet = dynamic_cast<SnippetItem*>( item );
310  if (!pSnippet || dynamic_cast<SnippetGroup*>(item))
311  return;
312 
313  //process variables if any, then insert into the active view
314  insertIntoActiveView( parseText(pSnippet->getText(), _SnippetConfig.getDelimiter()) );
315 }
316 
317 
322 void SnippetWidget::insertIntoActiveView( const TQString &text )
323 {
324  mEditor->insert( text );
325 }
326 
327 
333 {
334  if( !_cfg )
335  return;
336  _cfg->deleteGroup("SnippetPart"); //this is neccessary otherwise delete entries will stay in list until
337  //they get overwritten by a more recent entry
338  _cfg->setGroup("SnippetPart");
339 
340  TQString strKeyName="";
341  TQString strKeyText="";
342  TQString strKeyId="";
343 
344  int iSnipCount = 0;
345  int iGroupCount = 0;
346 
347  SnippetItem* item=_list.first();
348  while ( item != 0) {
349 
350  //kdDebug(5006) << "-->ERROR " << item->getName() << endl;
351  //kdDebug(5006) << "SnippetWidget::writeConfig() " << item->getName() << endl;
352  SnippetGroup * group = dynamic_cast<SnippetGroup*>(item);
353  if (group) {
354  //kdDebug(5006) << "-->GROUP " << item->getName() << group->getId() << " " << iGroupCount<< endl;
355  strKeyName=TQString("snippetGroupName_%1").arg(iGroupCount);
356  strKeyId=TQString("snippetGroupId_%1").arg(iGroupCount);
357 
358  _cfg->writeEntry(strKeyName, group->getName());
359  _cfg->writeEntry(strKeyId, group->getId());
360 
361  iGroupCount++;
362  } else if (dynamic_cast<SnippetItem*>(item)) {
363  //kdDebug(5006) << "-->ITEM " << item->getName() << item->getParent() << " " << iSnipCount << endl;
364  strKeyName=TQString("snippetName_%1").arg(iSnipCount);
365  strKeyText=TQString("snippetText_%1").arg(iSnipCount);
366  strKeyId=TQString("snippetParent_%1").arg(iSnipCount);
367 
368  _cfg->writeEntry(strKeyName, item->getName());
369  _cfg->writeEntry(strKeyText, item->getText());
370  _cfg->writeEntry(strKeyId, item->getParent());
371 
372  TDEAction * action = item->getAction();
373  assert( action );
374  const TDEShortcut& sc = action->shortcut();
375  if (!sc.isNull() ) {
376  _cfg->writeEntry( TQString("snippetShortcut_%1").arg(iSnipCount), sc.toString() );
377  }
378  iSnipCount++;
379  } else {
380  //kdDebug(5006) << "-->ERROR " << item->getName() << endl;
381  }
382  item = _list.next();
383  }
384  _cfg->writeEntry("snippetCount", iSnipCount);
385  _cfg->writeEntry("snippetGroupCount", iGroupCount);
386 
387  int iCount = 1;
388  TQMap<TQString, TQString>::Iterator it;
389  for ( it = _mapSaved.begin(); it != _mapSaved.end(); ++it ) { //write the saved variable values
390  if (it.data().length()<=0) continue; //is the saved value has no length -> no need to save it
391 
392  strKeyName=TQString("snippetSavedName_%1").arg(iCount);
393  strKeyText=TQString("snippetSavedVal_%1").arg(iCount);
394 
395  _cfg->writeEntry(strKeyName, it.key());
396  _cfg->writeEntry(strKeyText, it.data());
397 
398  iCount++;
399  }
400  _cfg->writeEntry("snippetSavedCount", iCount-1);
401 
402 
403  _cfg->writeEntry( "snippetDelimiter", _SnippetConfig.getDelimiter() );
404  _cfg->writeEntry( "snippetVarInput", _SnippetConfig.getInputMethod() );
405  _cfg->writeEntry( "snippetToolTips", _SnippetConfig.useToolTips() );
406  _cfg->writeEntry( "snippetGroupAutoOpen", _SnippetConfig.getAutoOpenGroups() );
407 
408  _cfg->writeEntry("snippetSingleRect", _SnippetConfig.getSingleRect() );
409  _cfg->writeEntry("snippetMultiRect", _SnippetConfig.getMultiRect() );
410 
411  _cfg->sync();
412 }
413 
418 void SnippetWidget::initConfig()
419 {
420  if (_cfg == NULL)
421  _cfg = new TDEConfig("kmailsnippetrc", false, false);
422 
423  _cfg->setGroup("SnippetPart");
424 
425  TQString strKeyName="";
426  TQString strKeyText="";
427  TQString strKeyId="";
428  SnippetItem *item;
429  SnippetGroup *group;
430 
431  //kdDebug(5006) << "SnippetWidget::initConfig() " << endl;
432 
433  //if entry doesn't get found, this will return -1 which we will need a bit later
434  int iCount = _cfg->readNumEntry("snippetGroupCount", -1);
435 
436  for ( int i=0; i<iCount; i++) { //read the group-list
437  strKeyName=TQString("snippetGroupName_%1").arg(i);
438  strKeyId=TQString("snippetGroupId_%1").arg(i);
439 
440  TQString strNameVal="";
441  int iIdVal=-1;
442 
443  strNameVal = _cfg->readEntry(strKeyName, "");
444  iIdVal = _cfg->readNumEntry(strKeyId, -1);
445  //kdDebug(5006) << "Read group " << " " << iIdVal << endl;
446 
447  if (strNameVal != "" && iIdVal != -1) {
448  group = new SnippetGroup(this, strNameVal, iIdVal);
449  //kdDebug(5006) << "Created group " << group->getName() << " " << group->getId() << endl;
450  _list.append(group);
451  }
452  }
453 
454  /* Check if the snippetGroupCount property has been found
455  if iCount is -1 this means, that the user has his snippets
456  stored without groups. Therefore we will call the
457  initConfigOldVersion() function below */
458  // should not happen since this function has been removed
459 
460  if (iCount != -1) {
461  iCount = _cfg->readNumEntry("snippetCount", 0);
462  for ( int i=0; i<iCount; i++) { //read the snippet-list
463  strKeyName=TQString("snippetName_%1").arg(i);
464  strKeyText=TQString("snippetText_%1").arg(i);
465  strKeyId=TQString("snippetParent_%1").arg(i);
466 
467  TQString strNameVal="";
468  TQString strTextVal="";
469  int iParentVal = -1;
470 
471  strNameVal = _cfg->readEntry(strKeyName, "");
472  strTextVal = _cfg->readEntry(strKeyText, "");
473  iParentVal = _cfg->readNumEntry(strKeyId, -1);
474  //kdDebug(5006) << "Read item " << strNameVal << " " << iParentVal << endl;
475 
476  if (strNameVal != "" && strTextVal != "" && iParentVal != -1) {
477  TDEShortcut shortcut( _cfg->readEntry( TQString("snippetShortcut_%1").arg(i), TQString() ) );
478  item = makeItem( SnippetItem::findGroupById(iParentVal, _list), strNameVal, strTextVal, shortcut );
479  //kdDebug(5006) << "Created item " << item->getName() << " " << item->getParent() << endl;
480  _list.append(item);
481  }
482  }
483  } else {
484  //kdDebug() << "iCount is not -1";
485  }
486 
487  iCount = _cfg->readNumEntry("snippetSavedCount", 0);
488 
489  for ( int i=1; i<=iCount; i++) { //read the saved-values and store in TQMap
490  strKeyName=TQString("snippetSavedName_%1").arg(i);
491  strKeyText=TQString("snippetSavedVal_%1").arg(i);
492 
493  TQString strNameVal="";
494  TQString strTextVal="";
495 
496  strNameVal = _cfg->readEntry(strKeyName, "");
497  strTextVal = _cfg->readEntry(strKeyText, "");
498 
499  if (strNameVal != "" && strTextVal != "") {
500  _mapSaved[strNameVal] = strTextVal;
501  }
502  }
503 
504 
505  _SnippetConfig.setDelimiter( _cfg->readEntry("snippetDelimiter", "$") );
506  _SnippetConfig.setInputMethod( _cfg->readNumEntry("snippetVarInput", 0) );
507  _SnippetConfig.setToolTips( _cfg->readBoolEntry("snippetToolTips", true) );
508  _SnippetConfig.setAutoOpenGroups( _cfg->readNumEntry("snippetGroupAutoOpen", 1) );
509 
510  _SnippetConfig.setSingleRect( _cfg->readRectEntry("snippetSingleRect", 0L) );
511  _SnippetConfig.setMultiRect( _cfg->readRectEntry("snippetMultiRect", 0L) );
512 }
513 
518 void SnippetWidget::maybeTip( const TQPoint & p )
519 {
520  SnippetItem * item = dynamic_cast<SnippetItem*>( itemAt( p ) );
521  if (!item)
522  return;
523 
524  TQRect r = itemRect( item );
525 
526  if (r.isValid() &&
527  _SnippetConfig.useToolTips() )
528  {
529  tip( r, item->getText() ); //show the snippet's text
530  }
531 }
532 
537 void SnippetWidget::showPopupMenu( TQListViewItem * item, const TQPoint & p, int )
538 {
539  TDEPopupMenu popup;
540 
541  SnippetItem * selectedItem = static_cast<SnippetItem *>(item);
542  if ( item ) {
543  popup.insertTitle( selectedItem->getName() );
544  if (dynamic_cast<SnippetGroup*>(item)) {
545  popup.insertItem( i18n("Edit &group..."), this, TQ_SLOT( slotEditGroup() ) );
546  } else {
547  popup.insertItem( SmallIconSet("edit-paste"), i18n("&Paste"), this, TQ_SLOT( slotExecuted() ) );
548  popup.insertItem( SmallIconSet("edit"), i18n("&Edit..."), this, TQ_SLOT( slotEdit() ) );
549  }
550  popup.insertItem( SmallIconSet("edit-delete"), i18n("&Remove"), this, TQ_SLOT( slotRemove() ) );
551  popup.insertSeparator();
552  } else {
553  popup.insertTitle(i18n("Text Snippets"));
554  }
555  popup.insertItem( i18n("&Add Snippet..."), this, TQ_SLOT( slotAdd() ) );
556  popup.insertItem( i18n("Add G&roup..."), this, TQ_SLOT( slotAddGroup() ) );
557 
558  popup.exec(p);
559 }
560 
561 
562 // fn SnippetWidget::parseText(TQString text, TQString del)
567 TQString SnippetWidget::parseText(TQString text, TQString del)
568 {
569  TQString str = text;
570  TQString strName = "";
571  TQString strNew = "";
572  TQString strMsg="";
573  int iFound = -1;
574  int iEnd = -1;
575  TQMap<TQString, TQString> mapVar;
576  int iInMeth = _SnippetConfig.getInputMethod();
577  TQRect rSingle = _SnippetConfig.getSingleRect();
578  TQRect rMulti = _SnippetConfig.getMultiRect();
579 
580  do {
581  iFound = text.find(TQRegExp("\\"+del+"[A-Za-z-_0-9\\s]*\\"+del), iEnd+1); //find the next variable by this TQRegExp
582  if (iFound >= 0) {
583  iEnd = text.find(del, iFound+1)+1;
584  strName = text.mid(iFound, iEnd-iFound);
585 
586  if ( strName != del+del ) { //if not doubel-delimiter
587  if (iInMeth == 0) { //if input-method "single" is selected
588  if ( mapVar[strName].length() <= 0 ) { // and not already in map
589  strMsg=i18n("Please enter the value for <b>%1</b>:").arg(strName);
590  strNew = showSingleVarDialog( strName, &_mapSaved, rSingle );
591  if (strNew=="")
592  return ""; //user clicked Cancle
593  } else {
594  continue; //we have already handled this variable
595  }
596  } else {
597  strNew = ""; //for inputmode "multi" just reset new valaue
598  }
599  } else {
600  strNew = del; //if double-delimiter -> replace by single character
601  }
602 
603  if (iInMeth == 0) { //if input-method "single" is selected
604  str.replace(strName, strNew);
605  }
606 
607  mapVar[strName] = strNew;
608  }
609  } while (iFound != -1);
610 
611  if (iInMeth == 1) { //check config, if input-method "multi" is selected
612  int w, bh, oh;
613  w = rMulti.width();
614  bh = rMulti.height();
615  oh = rMulti.top();
616  if (showMultiVarDialog( &mapVar, &_mapSaved, w, bh, oh )) { //generate and show the dialog
617  TQMap<TQString, TQString>::Iterator it;
618  for ( it = mapVar.begin(); it != mapVar.end(); ++it ) { //walk through the map and do the replacement
619  str.replace(it.key(), it.data());
620  }
621  } else {
622  return "";
623  }
624 
625  rMulti.setWidth(w); //this is a hack to save the dialog's dimensions in only one TQRect
626  rMulti.setHeight(bh);
627  rMulti.setTop(oh);
628  rMulti.setLeft(0);
629  _SnippetConfig.setMultiRect(rMulti);
630  }
631 
632  _SnippetConfig.setSingleRect(rSingle);
633 
634  return str;
635 }
636 
637 
638 // fn SnippetWidget::showMultiVarDialog()
644 bool SnippetWidget::showMultiVarDialog(TQMap<TQString, TQString> * map, TQMap<TQString, TQString> * mapSave,
645  int & iWidth, int & iBasicHeight, int & iOneHeight)
646 {
647  //if no var -> no need to show
648  if (map->count() == 0)
649  return true;
650 
651  //if only var is the double-delimiter -> no need to show
652  TQMap<TQString, TQString>::Iterator it = map->begin();
653  if ( map->count() == 1 && it.data()==_SnippetConfig.getDelimiter()+_SnippetConfig.getDelimiter() )
654  return true;
655 
656  TQMap<TQString, KTextEdit *> mapVar2Te; //this map will help keeping track which TEXTEDIT goes with which variable
657  TQMap<TQString, TQCheckBox *> mapVar2Cb; //this map will help keeping track which CHECKBOX goes with which variable
658 
659  // --BEGIN-- building a dynamic dialog
660  TQDialog dlg(this);
661  dlg.setCaption(i18n("Enter Values for Variables"));
662 
663  TQGridLayout * layout = new TQGridLayout( &dlg, 1, 1, 11, 6, "layout");
664  TQGridLayout * layoutTop = new TQGridLayout( 0, 1, 1, 0, 6, "layoutTop");
665  TQGridLayout * layoutVar = new TQGridLayout( 0, 1, 1, 0, 6, "layoutVar");
666  TQGridLayout * layoutBtn = new TQGridLayout( 0, 1, 1, 0, 6, "layoutBtn");
667 
668  KTextEdit *te = NULL;
669  TQLabel * labTop = NULL;
670  TQCheckBox * cb = NULL;
671 
672  labTop = new TQLabel( &dlg, "label" );
673  labTop->setSizePolicy( TQSizePolicy( (TQSizePolicy::SizeType)1, (TQSizePolicy::SizeType)0, 0, 0,
674  labTop->sizePolicy().hasHeightForWidth() ) );
675  labTop->setText(i18n("Enter the replacement values for these variables:"));
676  layoutTop->addWidget(labTop, 0, 0);
677  layout->addMultiCellLayout( layoutTop, 0, 0, 0, 1 );
678 
679 
680  int i = 0; //walk through the variable map and add
681  for ( it = map->begin(); it != map->end(); ++it ) { //a checkbox, a lable and a lineedit to the main layout
682  if (it.key() == _SnippetConfig.getDelimiter() + _SnippetConfig.getDelimiter())
683  continue;
684 
685  cb = new TQCheckBox( &dlg, "cbVar" );
686  cb->setChecked( FALSE );
687  cb->setText(it.key());
688  layoutVar->addWidget( cb, i ,0, TQt::AlignTop );
689 
690  te = new KTextEdit( &dlg, "teVar" );
691  layoutVar->addWidget( te, i, 1, TQt::AlignTop );
692 
693  if ((*mapSave)[it.key()].length() > 0) {
694  cb->setChecked( TRUE );
695  te->setText((*mapSave)[it.key()]);
696  }
697 
698  mapVar2Te[it.key()] = te;
699  mapVar2Cb[it.key()] = cb;
700 
701  TQToolTip::add( cb, i18n("Enable this to save the value entered to the right as the default value for this variable") );
702  TQWhatsThis::add( cb, i18n("If you enable this option, the value entered to the right will be saved. "
703  "If you use the same variable later, even in another snippet, the value entered to the right "
704  "will be the default value for that variable.") );
705 
706  i++;
707  }
708  layout->addMultiCellLayout( layoutVar, 1, 1, 0, 1 );
709 
710  KPushButton * btn1 = new KPushButton( KStdGuiItem::cancel(), &dlg, "pushButton1" );
711  btn1->setSizePolicy( TQSizePolicy( (TQSizePolicy::SizeType)1, (TQSizePolicy::SizeType)0, 0, 0,
712  btn1->sizePolicy().hasHeightForWidth() ) );
713  layoutBtn->addWidget( btn1, 0, 0 );
714 
715  KPushButton * btn2 = new KPushButton( KStdGuiItem::apply(), &dlg, "pushButton2" );
716  btn2->setDefault( TRUE );
717  btn2->setSizePolicy( TQSizePolicy( (TQSizePolicy::SizeType)1, (TQSizePolicy::SizeType)0, 0, 0,
718  btn2->sizePolicy().hasHeightForWidth() ) );
719  layoutBtn->addWidget( btn2, 0, 1 );
720 
721  layout->addMultiCellLayout( layoutBtn, 2, 2, 0, 1 );
722  // --END-- building a dynamic dialog
723 
724  //connect the buttons to the TQDialog default slots
725  connect(btn1, TQ_SIGNAL(clicked()), &dlg, TQ_SLOT(reject()) );
726  connect(btn2, TQ_SIGNAL(clicked()), &dlg, TQ_SLOT(accept()) );
727 
728  //prepare to execute the dialog
729  bool bReturn = false;
730  //resize the textedits
731  if (iWidth > 1) {
732  TQRect r = dlg.geometry();
733  r.setHeight(iBasicHeight + iOneHeight*mapVar2Te.count());
734  r.setWidth(iWidth);
735  dlg.setGeometry(r);
736  }
737  if ( i > 0 && // only if there are any variables
738  dlg.exec() == TQDialog::Accepted ) {
739 
740  TQMap<TQString, KTextEdit *>::Iterator it2;
741  for ( it2 = mapVar2Te.begin(); it2 != mapVar2Te.end(); ++it2 ) {
742  if (it2.key() == _SnippetConfig.getDelimiter() + _SnippetConfig.getDelimiter())
743  continue;
744  (*map)[it2.key()] = it2.data()->text(); //copy the entered values back to the given map
745 
746  if (mapVar2Cb[it2.key()]->isChecked()) //if the checkbox is on; save the values for later
747  (*mapSave)[it2.key()] = it2.data()->text();
748  else
749  (*mapSave).erase(it2.key());
750  }
751  bReturn = true;
752 
753  iBasicHeight = dlg.geometry().height() - layoutVar->geometry().height();
754  iOneHeight = layoutVar->geometry().height() / mapVar2Te.count();
755  iWidth = dlg.geometry().width();
756  }
757 
758  //do some cleanup
759  TQMap<TQString, KTextEdit *>::Iterator it1;
760  for (it1 = mapVar2Te.begin(); it1 != mapVar2Te.end(); ++it1)
761  delete it1.data();
762  mapVar2Te.clear();
763  TQMap<TQString, TQCheckBox *>::Iterator it2;
764  for (it2 = mapVar2Cb.begin(); it2 != mapVar2Cb.end(); ++it2)
765  delete it2.data();
766  mapVar2Cb.clear();
767  delete layoutTop;
768  delete layoutVar;
769  delete layoutBtn;
770  delete layout;
771 
772  if (i==0) //if nothing happened this means, that there are no variables to translate
773  return true; //.. so just return OK
774 
775  return bReturn;
776 // return true;
777 }
778 
779 
780 // fn SnippetWidget::showSingleVarDialog(TQString var, TQMap<TQString, TQString> * mapSave)
785 TQString SnippetWidget::showSingleVarDialog(TQString var, TQMap<TQString, TQString> * mapSave, TQRect & dlgSize)
786 {
787  // --BEGIN-- building a dynamic dialog
788  TQDialog dlg(this);
789  dlg.setCaption(i18n("Enter Values for Variables"));
790 
791  TQGridLayout * layout = new TQGridLayout( &dlg, 1, 1, 11, 6, "layout");
792  TQGridLayout * layoutTop = new TQGridLayout( 0, 1, 1, 0, 6, "layoutTop");
793  TQGridLayout * layoutVar = new TQGridLayout( 0, 1, 1, 0, 6, "layoutVar");
794  TQGridLayout * layoutBtn = new TQGridLayout( 0, 2, 1, 0, 6, "layoutBtn");
795 
796  KTextEdit *te = NULL;
797  TQLabel * labTop = NULL;
798  TQCheckBox * cb = NULL;
799 
800  labTop = new TQLabel( &dlg, "label" );
801  layoutTop->addWidget(labTop, 0, 0);
802  labTop->setText(i18n("Enter the replacement values for %1:").arg( var ));
803  layout->addMultiCellLayout( layoutTop, 0, 0, 0, 1 );
804 
805 
806  cb = new TQCheckBox( &dlg, "cbVar" );
807  cb->setChecked( FALSE );
808  cb->setText(i18n( "Make value &default" ));
809 
810  te = new KTextEdit( &dlg, "teVar" );
811  layoutVar->addWidget( te, 0, 1, TQt::AlignTop);
812  layoutVar->addWidget( cb, 1, 1, TQt::AlignTop);
813  if ((*mapSave)[var].length() > 0) {
814  cb->setChecked( TRUE );
815  te->setText((*mapSave)[var]);
816  }
817 
818  TQToolTip::add( cb, i18n("Enable this to save the value entered to the right as the default value for this variable") );
819  TQWhatsThis::add( cb, i18n("If you enable this option, the value entered to the right will be saved. "
820  "If you use the same variable later, even in another snippet, the value entered to the right "
821  "will be the default value for that variable.") );
822 
823  layout->addMultiCellLayout( layoutVar, 1, 1, 0, 1 );
824 
825  KPushButton * btn1 = new KPushButton( KStdGuiItem::cancel(), &dlg, "pushButton1" );
826  layoutBtn->addWidget( btn1, 0, 0 );
827 
828  KPushButton * btn2 = new KPushButton( KStdGuiItem::apply(), &dlg, "pushButton2" );
829  btn2->setDefault( TRUE );
830  layoutBtn->addWidget( btn2, 0, 1 );
831 
832  layout->addMultiCellLayout( layoutBtn, 2, 2, 0, 1 );
833  te->setFocus();
834  // --END-- building a dynamic dialog
835 
836  //connect the buttons to the TQDialog default slots
837  connect(btn1, TQ_SIGNAL(clicked()), &dlg, TQ_SLOT(reject()) );
838  connect(btn2, TQ_SIGNAL(clicked()), &dlg, TQ_SLOT(accept()) );
839 
840  //execute the dialog
841  TQString strReturn = "";
842  if (dlgSize.isValid())
843  dlg.setGeometry(dlgSize);
844  if ( dlg.exec() == TQDialog::Accepted ) {
845  if (cb->isChecked()) //if the checkbox is on; save the values for later
846  (*mapSave)[var] = te->text();
847  else
848  (*mapSave).erase(var);
849 
850  strReturn = te->text(); //copy the entered values back the the given map
851 
852  dlgSize = dlg.geometry();
853  }
854 
855  //do some cleanup
856  delete cb;
857  delete te;
858  delete labTop;
859  delete btn1;
860  delete btn2;
861  delete layoutTop;
862  delete layoutVar;
863  delete layoutBtn;
864  delete layout;
865 
866  return strReturn;
867 }
868 
869 // fn SnippetWidget::acceptDrag (TQDropEvent *event) const
876 bool SnippetWidget::acceptDrag (TQDropEvent *event) const
877 {
878  //kdDebug(5006) << "Format: " << event->format() << "" << event->pos() << endl;
879 
880  TQListViewItem * item = itemAt(event->pos());
881 
882  if (item &&
883  TQString(event->format()).startsWith("text/plain") &&
884  static_cast<SnippetWidget *>(event->source()) != this) {
886  return TRUE;
887  } else if(item &&
888  TQString(event->format()).startsWith("x-kmailsnippet") &&
889  static_cast<SnippetWidget *>(event->source()) != this)
890  {
891  //kdDebug(5006) << "returning TRUE " << endl;
892  return TRUE;
893  } else {
894  //kdDebug(5006) << "returning FALSE" << endl;
895  event->acceptAction(FALSE);
896  return FALSE;
897  }
898 }
899 
900 // fn SnippetWidget::slotDropped(TQDropEvent *e, TQListViewItem *after)
906 void SnippetWidget::slotDropped(TQDropEvent *e, TQListViewItem *)
907 {
908  TQListViewItem * item2 = itemAt(e->pos());
909 
910  SnippetGroup *group = dynamic_cast<SnippetGroup *>(item2);
911  if (!group)
912  group = dynamic_cast<SnippetGroup *>(item2->parent());
913 
914  TQCString dropped;
915  TQByteArray data = e->encodedData("text/plain");
916  if ( e->provides("text/plain") && data.size()>0 ) {
917  //get the data from the event...
918  TQString encData(data.data());
919  //kdDebug(5006) << "encData: " << encData << endl;
920 
921  //... then fill the dialog with the given data
922  SnippetDlg dlg( mActionCollection, this, "SnippetDlg" );
923  dlg.snippetName->clear();
924  dlg.snippetText->setText(encData);
925 
926  /*fill the combobox with the names of all SnippetGroup entries*/
927  for (SnippetItem *it=_list.first(); it; it=_list.next()) {
928  if (dynamic_cast<SnippetGroup*>(it)) {
929  dlg.cbGroup->insertItem(it->getName());
930  }
931  }
932  dlg.cbGroup->setCurrentText(group->getName());
933 
934  if (dlg.exec() == TQDialog::Accepted) {
935  /* get the group that the user selected with the combobox */
936  group = dynamic_cast<SnippetGroup*>(SnippetItem::findItemByName(dlg.cbGroup->currentText(), _list));
937  _list.append( makeItem(group, dlg.snippetName->text(), dlg.snippetText->text(), dlg.keyButton->shortcut() ) );
938  }
939  }
940 }
941 
942 void SnippetWidget::startDrag()
943 {
944  TQString text = dynamic_cast<SnippetItem*>( currentItem() )->getText();
945  TQTextDrag *drag = new TQTextDrag(text, this);
946  drag->setSubtype("x-textsnippet");
947  drag->drag();
948 }
949 
950 void SnippetWidget::slotExecute()
951 {
952  slotExecuted(currentItem());
953 }
954 
955 
956 #include "snippetwidget.moc"
957 
This class represents one group in the listview.
Definition: snippetitem.h:71
This class represents one CodeSnippet-Item in the listview.
Definition: snippetitem.h:32
This is the widget which gets added to the right TreeToolView.
Definition: snippetwidget.h:46
void slotDropped(TQDropEvent *e, TQListViewItem *after)
void showPopupMenu(TQListViewItem *item, const TQPoint &p, int)
void maybeTip(const TQPoint &)
bool acceptDrag(TQDropEvent *event) const
void slotEdit(TQListViewItem *item_=0)