kmail

snippet_widget.cpp

00001 /*
00002  *  File : snippet_widget.cpp
00003  *
00004  *  Author: Robert Gruber <rgruber@users.sourceforge.net>
00005  *
00006  *  Copyright: See COPYING file that comes with this distribution
00007  */
00008 
00009 #include <kurl.h>
00010 #include <kdebug.h>
00011 #include <klocale.h>
00012 #include <qlayout.h>
00013 #include <kpushbutton.h>
00014 #include <klistview.h>
00015 #include <qheader.h>
00016 #include <klineedit.h>
00017 #include <ktextedit.h>
00018 #include <kmessagebox.h>
00019 #include <qsplitter.h>
00020 #include <kconfig.h>
00021 #include <qtooltip.h>
00022 #include <kpopupmenu.h>
00023 #include <qregexp.h>
00024 #include <qinputdialog.h>
00025 #include <qlabel.h>
00026 #include <qcheckbox.h>
00027 #include <qwhatsthis.h>
00028 #include <qdragobject.h>
00029 #include <qtimer.h>
00030 #include <kcombobox.h>
00031 #include <kmedit.h>
00032 #include <kiconloader.h>
00033 
00034 #include "snippetdlg.h"
00035 #include "snippetitem.h"
00036 #include "snippet_widget.h"
00037 
00038 SnippetWidget::SnippetWidget(KMEdit* editor, QWidget* parent)
00039         : KListView(parent, "snippet widget"), QToolTip( viewport() ),
00040         mEditor( editor )
00041 {
00042     // init the QPtrList
00043     _list.setAutoDelete(TRUE);
00044 
00045     // init the KListView
00046     setSorting( -1 );
00047     addColumn( "" );
00048     setFullWidth(true);
00049     header()->hide();
00050     setAcceptDrops(true);
00051     setDragEnabled(true);
00052     setDropVisualizer(false);
00053     setRootIsDecorated(true);
00054 
00055     //connect the signals
00056     connect( this, SIGNAL( contextMenuRequested ( QListViewItem *, const QPoint & , int ) ),
00057              this, SLOT( showPopupMenu(QListViewItem *, const QPoint & , int ) ) );
00058 
00059     connect( this, SIGNAL( doubleClicked (QListViewItem *) ),
00060              this, SLOT( slotEdit( QListViewItem *) ) );
00061     connect( this, SIGNAL( returnPressed (QListViewItem *) ),
00062              this, SLOT( slotExecuted( QListViewItem *) ) );
00063 
00064     connect( this, SIGNAL( dropped(QDropEvent *, QListViewItem *) ),
00065              this, SLOT( slotDropped(QDropEvent *, QListViewItem *) ) );
00066 
00067     connect( editor, SIGNAL( insertSnippet() ), this, SLOT( slotExecute() ));
00068 
00069     _cfg = 0;
00070 
00071     QTimer::singleShot(0, this, SLOT(initConfig()));
00072 }
00073 
00074 SnippetWidget::~SnippetWidget()
00075 {
00076   writeConfig();
00077   delete _cfg;
00078 
00079   /* We need to delete the child items before the parent items
00080      otherwise KDevelop would crash on exiting */
00081   SnippetItem * item;
00082   while (_list.count() > 0) {
00083     for (item=_list.first(); item; item=_list.next()) {
00084       if (item->childCount() == 0)
00085           _list.remove(item);
00086     }
00087   }
00088 }
00089 
00090 
00095 void SnippetWidget::slotAdd()
00096 {
00097   kdDebug(5006) << "Ender slotAdd()" << endl;
00098   SnippetDlg dlg(this, "SnippetDlg", true);
00099 
00100   /*check if the user clicked a SnippetGroup
00101     If not, we set the group variable to the SnippetGroup
00102     which the selected item is a child of*/
00103   SnippetGroup * group = dynamic_cast<SnippetGroup*>(selectedItem());
00104   if (!group)
00105     group = dynamic_cast<SnippetGroup*>(selectedItem()->parent());
00106 
00107   /*fill the combobox with the names of all SnippetGroup entries*/
00108   for (SnippetItem *it=_list.first(); it; it=_list.next()) {
00109     if (dynamic_cast<SnippetGroup*>(it)) {
00110       dlg.cbGroup->insertItem(it->getName());
00111     }
00112   }
00113   dlg.cbGroup->setCurrentText(group->getName());
00114 
00115   if (dlg.exec() == QDialog::Accepted) {
00116       group = dynamic_cast<SnippetGroup*>(SnippetItem::findItemByName(dlg.cbGroup->currentText(), _list));
00117       _list.append( new SnippetItem(group, dlg.snippetName->text(), dlg.snippetText->text()) );
00118   }
00119 }
00120 
00121 
00126 void SnippetWidget::slotAddGroup()
00127 {
00128   kdDebug(5006) << "Ender slotAddGroup()" << endl;
00129   SnippetDlg dlg(this, "SnippetDlg", true);
00130   dlg.snippetText->setEnabled(false);
00131   dlg.snippetText->setText("GROUP");
00132   dlg.setCaption(i18n("Add Group"));
00133   dlg.cbGroup->insertItem(i18n("All"));
00134   dlg.cbGroup->setCurrentText(i18n("All"));
00135 
00136   if (dlg.exec() == QDialog::Accepted) {
00137     _list.append( new SnippetGroup(this, dlg.snippetName->text(), SnippetGroup::getMaxId() ) );
00138   }
00139 }
00140 
00141 
00146 void SnippetWidget::slotRemove()
00147 {
00148   //get current data
00149   QListViewItem * item = currentItem();
00150   SnippetItem *snip = dynamic_cast<SnippetItem*>( item );
00151   SnippetGroup *group = dynamic_cast<SnippetGroup*>( item );
00152   if (!snip)
00153     return;
00154 
00155   if (group) {
00156     if (group->childCount() > 0 &&
00157         KMessageBox::warningContinueCancel(this, i18n("Do you really want to remove this group and all its snippets?"),QString::null,KStdGuiItem::del())
00158         == KMessageBox::Cancel)
00159       return;
00160 
00161     for (SnippetItem *it=_list.first(); it; it=_list.next()) {
00162       if (it->getParent() == group->getId()) {
00163         kdDebug(5006) << "remove " << it->getName() << endl;
00164         _list.remove(it);
00165       }
00166     }
00167   }
00168 
00169   kdDebug(5006) << "remove " << snip->getName() << endl;
00170   _list.remove(snip);
00171 }
00172 
00173 
00174 
00179 void SnippetWidget::slotEdit( QListViewItem* item )
00180 {
00181     if( item == 0 ) {
00182     item = currentItem();
00183     }
00184 
00185   SnippetGroup *pGroup = dynamic_cast<SnippetGroup*>(item);
00186   SnippetItem *pSnippet = dynamic_cast<SnippetItem*>( item );
00187   if (!pSnippet || pGroup) /*selected item must be a SnippetItem but MUST not be a SnippetGroup*/
00188     return;
00189 
00190   //init the dialog
00191   SnippetDlg dlg(this, "SnippetDlg", true);
00192   dlg.snippetName->setText(pSnippet->getName());
00193   dlg.snippetText->setText(pSnippet->getText());
00194   dlg.btnAdd->setText(i18n("&Apply"));
00195 
00196   dlg.setCaption(i18n("Edit Snippet"));
00197   /*fill the combobox with the names of all SnippetGroup entries*/
00198   for (SnippetItem *it=_list.first(); it; it=_list.next()) {
00199     if (dynamic_cast<SnippetGroup*>(it)) {
00200       dlg.cbGroup->insertItem(it->getName());
00201     }
00202   }
00203   dlg.cbGroup->setCurrentText(SnippetItem::findGroupById(pSnippet->getParent(), _list)->getName());
00204 
00205   if (dlg.exec() == QDialog::Accepted) {
00206     //update the KListView and the SnippetItem
00207     item->setText( 0, dlg.snippetName->text() );
00208     pSnippet->setName( dlg.snippetName->text() );
00209     pSnippet->setText( dlg.snippetText->text() );
00210 
00211     /* if the user changed the parent we need to move the snippet */
00212     if ( SnippetItem::findGroupById(pSnippet->getParent(), _list)->getName() != dlg.cbGroup->currentText() ) {
00213       SnippetGroup * newGroup = dynamic_cast<SnippetGroup*>(SnippetItem::findItemByName(dlg.cbGroup->currentText(), _list));
00214       pSnippet->parent()->takeItem(pSnippet);
00215       newGroup->insertItem(pSnippet);
00216       pSnippet->resetParent();
00217     }
00218 
00219     setSelected(item, TRUE);
00220   }
00221 }
00222 
00227 void SnippetWidget::slotEditGroup()
00228 {
00229   //get current data
00230   QListViewItem * item = currentItem();
00231 
00232   SnippetGroup *pGroup = dynamic_cast<SnippetGroup*>( item );
00233   if (!pGroup) /*selected item MUST be a SnippetGroup*/
00234     return;
00235 
00236   //init the dialog
00237   SnippetDlg dlg(this, "SnippetDlg", true);
00238   dlg.snippetName->setText(pGroup->getName());
00239   dlg.snippetText->setText(pGroup->getText());
00240   dlg.btnAdd->setText(i18n("&Apply"));
00241   dlg.snippetText->setEnabled(FALSE);
00242   dlg.setCaption(i18n("Edit Group"));
00243   dlg.cbGroup->insertItem(i18n("All"));
00244 
00245   if (dlg.exec() == QDialog::Accepted) {
00246     //update the KListView and the SnippetGroup
00247     item->setText( 0, dlg.snippetName->text() );
00248     pGroup->setName( dlg.snippetName->text() );
00249 
00250     setSelected(item, TRUE);
00251   }
00252 }
00253 
00254 void SnippetWidget::slotExecuted(QListViewItem * item)
00255 {
00256 
00257     if( item == 0 )
00258     {
00259     item = currentItem();
00260     }
00261 
00262   SnippetItem *pSnippet = dynamic_cast<SnippetItem*>( item );
00263   if (!pSnippet || dynamic_cast<SnippetGroup*>(item))
00264       return;
00265 
00266   //process variables if any, then insert into the active view
00267   insertIntoActiveView( parseText(pSnippet->getText(), _SnippetConfig.getDelimiter()) );
00268 }
00269 
00270 
00275 void SnippetWidget::insertIntoActiveView(QString text)
00276 {
00277     QTextStream *s = new QTextStream(text, IO_ReadWrite);
00278     mEditor->insertText(s);
00279 }
00280 
00281 
00286 void SnippetWidget::writeConfig()
00287 {
00288   if( !_cfg )
00289     return;
00290   _cfg->deleteGroup("SnippetPart");  //this is neccessary otherwise delete entries will stay in list until
00291                                      //they get overwritten by a more recent entry
00292   _cfg->setGroup("SnippetPart");
00293 
00294   SnippetItem *item;
00295   QString strKeyName="";
00296   QString strKeyText="";
00297   QString strKeyId="";
00298 
00299   int iSnipCount = 0;
00300   int iGroupCount = 0;
00301 
00302   for ( item = _list.first(); item; item = _list.next() ) {  //write the snippet-list
00303     kdDebug(5006) << "SnippetWidget::writeConfig() " << item->getName() << endl;
00304     SnippetGroup * group = dynamic_cast<SnippetGroup*>(item);
00305     if (group) {
00306       kdDebug(5006) << "-->GROUP " << item->getName() << group->getId() << " " << iGroupCount<< endl;
00307       strKeyName=QString("snippetGroupName_%1").arg(iGroupCount);
00308       strKeyId=QString("snippetGroupId_%1").arg(iGroupCount);
00309 
00310       _cfg->writeEntry(strKeyName, group->getName());
00311       _cfg->writeEntry(strKeyId, group->getId());
00312 
00313       iGroupCount++;
00314     } else if (dynamic_cast<SnippetItem*>(item)) {
00315       kdDebug(5006) << "-->ITEM " << item->getName() << item->getParent() << " " << iSnipCount << endl;
00316       strKeyName=QString("snippetName_%1").arg(iSnipCount);
00317       strKeyText=QString("snippetText_%1").arg(iSnipCount);
00318       strKeyId=QString("snippetParent_%1").arg(iSnipCount);
00319 
00320       _cfg->writeEntry(strKeyName, item->getName());
00321       _cfg->writeEntry(strKeyText, item->getText());
00322       _cfg->writeEntry(strKeyId, item->getParent());
00323       iSnipCount++;
00324     } else {
00325       kdDebug(5006) << "-->ERROR " << item->getName() << endl;
00326     }
00327   }
00328   _cfg->writeEntry("snippetCount", iSnipCount);
00329   _cfg->writeEntry("snippetGroupCount", iGroupCount);
00330 
00331   int iCount = 1;
00332   QMap<QString, QString>::Iterator it;
00333   for ( it = _mapSaved.begin(); it != _mapSaved.end(); ++it ) {  //write the saved variable values
00334     if (it.data().length()<=0) continue;  //is the saved value has no length -> no need to save it
00335 
00336     strKeyName=QString("snippetSavedName_%1").arg(iCount);
00337     strKeyText=QString("snippetSavedVal_%1").arg(iCount);
00338 
00339     _cfg->writeEntry(strKeyName, it.key());
00340     _cfg->writeEntry(strKeyText, it.data());
00341 
00342     iCount++;
00343   }
00344   _cfg->writeEntry("snippetSavedCount", iCount-1);
00345 
00346 
00347   _cfg->writeEntry( "snippetDelimiter", _SnippetConfig.getDelimiter() );
00348   _cfg->writeEntry( "snippetVarInput", _SnippetConfig.getInputMethod() );
00349   _cfg->writeEntry( "snippetToolTips", _SnippetConfig.useToolTips() );
00350   _cfg->writeEntry( "snippetGroupAutoOpen", _SnippetConfig.getAutoOpenGroups() );
00351 
00352   _cfg->writeEntry("snippetSingleRect", _SnippetConfig.getSingleRect() );
00353   _cfg->writeEntry("snippetMultiRect", _SnippetConfig.getMultiRect() );
00354 
00355   _cfg->sync();
00356 }
00357 
00362 void SnippetWidget::initConfig()
00363 {
00364   if (_cfg == NULL)
00365     _cfg = new KConfig("kmailsnippetrc", false, false);
00366 
00367   _cfg->setGroup("SnippetPart");
00368 
00369   QString strKeyName="";
00370   QString strKeyText="";
00371   QString strKeyId="";
00372   SnippetItem *item;
00373   SnippetGroup *group;
00374 
00375   kdDebug(5006) << "SnippetWidget::initConfig() " << endl;
00376 
00377   //if entry doesn't get found, this will return -1 which we will need a bit later
00378   int iCount = _cfg->readNumEntry("snippetGroupCount", -1);
00379 
00380   for ( int i=0; i<iCount; i++) {  //read the group-list
00381     strKeyName=QString("snippetGroupName_%1").arg(i);
00382     strKeyId=QString("snippetGroupId_%1").arg(i);
00383 
00384     QString strNameVal="";
00385     int iIdVal=-1;
00386 
00387     strNameVal = _cfg->readEntry(strKeyName, "");
00388     iIdVal = _cfg->readNumEntry(strKeyId, -1);
00389     kdDebug(5006) << "Read group "  << " " << iIdVal << endl;
00390 
00391     if (strNameVal != "" && iIdVal != -1) {
00392       group = new SnippetGroup(this, strNameVal, iIdVal);
00393       kdDebug(5006) << "Created group " << group->getName() << " " << group->getId() << endl;
00394       _list.append(group);
00395     }
00396   }
00397 
00398   /* Check if the snippetGroupCount property has been found
00399      if iCount is -1 this means, that the user has his snippets
00400      stored without groups. Therefore we will call the
00401      initConfigOldVersion() function below */
00402   // should not happen since this function has been removed
00403 
00404   if (iCount != -1) {
00405     iCount = _cfg->readNumEntry("snippetCount", 0);
00406     for ( int i=0; i<iCount; i++) {  //read the snippet-list
00407         strKeyName=QString("snippetName_%1").arg(i);
00408         strKeyText=QString("snippetText_%1").arg(i);
00409         strKeyId=QString("snippetParent_%1").arg(i);
00410 
00411         QString strNameVal="";
00412         QString strTextVal="";
00413         int iParentVal = -1;
00414 
00415         strNameVal = _cfg->readEntry(strKeyName, "");
00416         strTextVal = _cfg->readEntry(strKeyText, "");
00417         iParentVal = _cfg->readNumEntry(strKeyId, -1);
00418         kdDebug(5006) << "Read item " << strNameVal << " " << iParentVal << endl;
00419 
00420         if (strNameVal != "" && strTextVal != "" && iParentVal != -1) {
00421         item = new SnippetItem(SnippetItem::findGroupById(iParentVal, _list), strNameVal, strTextVal);
00422         kdDebug(5006) << "Created item " << item->getName() << " " << item->getParent() << endl;
00423         _list.append(item);
00424         }
00425     }
00426   } else {
00427       kdDebug() << "iCount is not -1";
00428   }
00429 
00430   iCount = _cfg->readNumEntry("snippetSavedCount", 0);
00431 
00432   for ( int i=1; i<=iCount; i++) {  //read the saved-values and store in QMap
00433     strKeyName=QString("snippetSavedName_%1").arg(i);
00434     strKeyText=QString("snippetSavedVal_%1").arg(i);
00435 
00436     QString strNameVal="";
00437     QString strTextVal="";
00438 
00439     strNameVal = _cfg->readEntry(strKeyName, "");
00440     strTextVal = _cfg->readEntry(strKeyText, "");
00441 
00442     if (strNameVal != "" && strTextVal != "") {
00443       _mapSaved[strNameVal] = strTextVal;
00444     }
00445   }
00446 
00447 
00448   _SnippetConfig.setDelimiter( _cfg->readEntry("snippetDelimiter", "$") );
00449   _SnippetConfig.setInputMethod( _cfg->readNumEntry("snippetVarInput", 0) );
00450   _SnippetConfig.setToolTips( _cfg->readBoolEntry("snippetToolTips", true) );
00451   _SnippetConfig.setAutoOpenGroups( _cfg->readNumEntry("snippetGroupAutoOpen", 1) );
00452 
00453   _SnippetConfig.setSingleRect( _cfg->readRectEntry("snippetSingleRect", 0L) );
00454   _SnippetConfig.setMultiRect( _cfg->readRectEntry("snippetMultiRect", 0L) );
00455 }
00456 
00461 void SnippetWidget::maybeTip( const QPoint & p )
00462 {
00463     SnippetItem * item = dynamic_cast<SnippetItem*>( itemAt( p ) );
00464     if (!item)
00465       return;
00466 
00467     QRect r = itemRect( item );
00468 
00469     if (r.isValid() &&
00470         _SnippetConfig.useToolTips() )
00471     {
00472         tip( r, item->getText() );  //show the snippet's text
00473     }
00474 }
00475 
00480 void SnippetWidget::showPopupMenu( QListViewItem * item, const QPoint & p, int )
00481 {
00482     KPopupMenu popup;
00483 
00484     SnippetItem * selectedItem = static_cast<SnippetItem *>(item);
00485     if ( item ) {
00486         popup.insertTitle( selectedItem->getName() );
00487         if (dynamic_cast<SnippetGroup*>(item)) {
00488             popup.insertItem( i18n("Edit &group..."), this, SLOT( slotEditGroup() ) );
00489         } else {
00490             popup.insertItem( SmallIconSet("editpaste"), i18n("&Paste"), this, SLOT( slotExecuted() ) );
00491             popup.insertItem( SmallIconSet("edit"), i18n("&Edit..."), this, SLOT( slotEdit() ) );
00492         }
00493         popup.insertItem( SmallIconSet("editdelete"), i18n("&Remove"), this, SLOT( slotRemove() ) );
00494         popup.insertSeparator();
00495         popup.insertItem( i18n("&Add Snippet..."), this, SLOT( slotAdd() ) );
00496         popup.insertItem( i18n("Add G&roup..."), this, SLOT( slotAddGroup() ) );
00497     } else {
00498         popup.insertTitle(i18n("Text Snippets"));
00499 
00500         popup.insertItem( i18n("Add Group..."), this, SLOT( slotAddGroup() ) );
00501     }
00502 
00503     popup.exec(p);
00504 }
00505 
00506 
00507 //  fn SnippetWidget::parseText(QString text, QString del)
00512 QString SnippetWidget::parseText(QString text, QString del)
00513 {
00514   QString str = text;
00515   QString strName = "";
00516   QString strNew = "";
00517   QString strMsg="";
00518   int iFound = -1;
00519   int iEnd = -1;
00520   QMap<QString, QString> mapVar;
00521   int iInMeth = _SnippetConfig.getInputMethod();
00522   QRect rSingle = _SnippetConfig.getSingleRect();
00523   QRect rMulti = _SnippetConfig.getMultiRect();
00524 
00525   do {
00526     iFound = text.find(QRegExp("\\"+del+"[A-Za-z-_0-9\\s]*\\"+del), iEnd+1);  //find the next variable by this QRegExp
00527     if (iFound >= 0) {
00528       iEnd = text.find(del, iFound+1)+1;
00529       strName = text.mid(iFound, iEnd-iFound);
00530 
00531       if ( strName != del+del  ) {  //if not doubel-delimiter
00532         if (iInMeth == 0) { //if input-method "single" is selected
00533           if ( mapVar[strName].length() <= 0 ) {  // and not already in map
00534             strMsg=i18n("Please enter the value for <b>%1</b>:").arg(strName);
00535             strNew = showSingleVarDialog( strName, &_mapSaved, rSingle );
00536             if (strNew=="")
00537               return ""; //user clicked Cancle
00538           } else {
00539             continue; //we have already handled this variable
00540           }
00541         } else {
00542           strNew = ""; //for inputmode "multi" just reset new valaue
00543         }
00544       } else {
00545         strNew = del; //if double-delimiter -> replace by single character
00546       }
00547 
00548       if (iInMeth == 0) {  //if input-method "single" is selected
00549         str.replace(strName, strNew);
00550       }
00551 
00552       mapVar[strName] = strNew;
00553     }
00554   } while (iFound != -1);
00555 
00556   if (iInMeth == 1) {  //check config, if input-method "multi" is selected
00557     int w, bh, oh;
00558     w = rMulti.width();
00559     bh = rMulti.height();
00560     oh = rMulti.top();
00561     if (showMultiVarDialog( &mapVar, &_mapSaved, w, bh, oh )) {  //generate and show the dialog
00562       QMap<QString, QString>::Iterator it;
00563       for ( it = mapVar.begin(); it != mapVar.end(); ++it ) {  //walk through the map and do the replacement
00564         str.replace(it.key(), it.data());
00565       }
00566     } else {
00567       return "";
00568     }
00569 
00570     rMulti.setWidth(w);   //this is a hack to save the dialog's dimensions in only one QRect
00571     rMulti.setHeight(bh);
00572     rMulti.setTop(oh);
00573     rMulti.setLeft(0);
00574      _SnippetConfig.setMultiRect(rMulti);
00575   }
00576 
00577   _SnippetConfig.setSingleRect(rSingle);
00578 
00579   return str;
00580 }
00581 
00582 
00583 //  fn SnippetWidget::showMultiVarDialog()
00589 bool SnippetWidget::showMultiVarDialog(QMap<QString, QString> * map, QMap<QString, QString> * mapSave,
00590                                        int & iWidth, int & iBasicHeight, int & iOneHeight)
00591 {
00592   //if no var -> no need to show
00593   if (map->count() == 0)
00594     return true;
00595 
00596   //if only var is the double-delimiter -> no need to show
00597   QMap<QString, QString>::Iterator it = map->begin();
00598   if ( map->count() == 1 && it.data()==_SnippetConfig.getDelimiter()+_SnippetConfig.getDelimiter() )
00599     return true;
00600 
00601   QMap<QString, KTextEdit *> mapVar2Te;  //this map will help keeping track which TEXTEDIT goes with which variable
00602   QMap<QString, QCheckBox *> mapVar2Cb;  //this map will help keeping track which CHECKBOX goes with which variable
00603 
00604   // --BEGIN-- building a dynamic dialog
00605   QDialog dlg(this);
00606   dlg.setCaption(i18n("Enter Values for Variables"));
00607 
00608   QGridLayout * layout = new QGridLayout( &dlg, 1, 1, 11, 6, "layout");
00609   QGridLayout * layoutTop = new QGridLayout( 0, 1, 1, 0, 6, "layoutTop");
00610   QGridLayout * layoutVar = new QGridLayout( 0, 1, 1, 0, 6, "layoutVar");
00611   QGridLayout * layoutBtn = new QGridLayout( 0, 1, 1, 0, 6, "layoutBtn");
00612 
00613   KTextEdit *te = NULL;
00614   QLabel * labTop = NULL;
00615   QCheckBox * cb = NULL;
00616 
00617   labTop = new QLabel( &dlg, "label" );
00618   labTop->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0,
00619                          labTop->sizePolicy().hasHeightForWidth() ) );
00620   labTop->setText(i18n("Enter the replacement values for these variables:"));
00621   layoutTop->addWidget(labTop, 0, 0);
00622   layout->addMultiCellLayout( layoutTop, 0, 0, 0, 1 );
00623 
00624 
00625   int i = 0;                                           //walk through the variable map and add
00626   for ( it = map->begin(); it != map->end(); ++it ) {  //a checkbox, a lable and a lineedit to the main layout
00627     if (it.key() == _SnippetConfig.getDelimiter() + _SnippetConfig.getDelimiter())
00628       continue;
00629 
00630     cb = new QCheckBox( &dlg, "cbVar" );
00631     cb->setChecked( FALSE );
00632     cb->setText(it.key());
00633     layoutVar->addWidget( cb, i ,0, Qt::AlignTop );
00634 
00635     te = new KTextEdit( &dlg, "teVar" );
00636     layoutVar->addWidget( te, i, 1, Qt::AlignTop );
00637 
00638     if ((*mapSave)[it.key()].length() > 0) {
00639       cb->setChecked( TRUE );
00640       te->setText((*mapSave)[it.key()]);
00641     }
00642 
00643     mapVar2Te[it.key()] = te;
00644     mapVar2Cb[it.key()] = cb;
00645 
00646     QToolTip::add( cb, i18n("Enable this to save the value entered to the right as the default value for this variable") );
00647     QWhatsThis::add( cb, i18n("If you enable this option, the value entered to the right will be saved. "
00648                               "If you use the same variable later, even in another snippet, the value entered to the right "
00649                   "will be the default value for that variable.") );
00650 
00651     i++;
00652   }
00653   layout->addMultiCellLayout( layoutVar, 1, 1, 0, 1 );
00654 
00655   KPushButton * btn1 = new KPushButton( KStdGuiItem::cancel(), &dlg, "pushButton1" );
00656   btn1->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0,
00657                          btn1->sizePolicy().hasHeightForWidth() ) );
00658   layoutBtn->addWidget( btn1, 0, 0 );
00659 
00660   KPushButton * btn2 = new KPushButton( KStdGuiItem::apply(), &dlg, "pushButton2" );
00661   btn2->setDefault( TRUE );
00662   btn2->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0,
00663                          btn2->sizePolicy().hasHeightForWidth() ) );
00664   layoutBtn->addWidget( btn2, 0, 1 );
00665 
00666   layout->addMultiCellLayout( layoutBtn, 2, 2, 0, 1 );
00667   // --END-- building a dynamic dialog
00668 
00669   //connect the buttons to the QDialog default slots
00670   connect(btn1, SIGNAL(clicked()), &dlg, SLOT(reject()) );
00671   connect(btn2, SIGNAL(clicked()), &dlg, SLOT(accept()) );
00672 
00673   //prepare to execute the dialog
00674   bool bReturn = false;
00675   //resize the textedits
00676   if (iWidth > 1) {
00677     QRect r = dlg.geometry();
00678     r.setHeight(iBasicHeight + iOneHeight*mapVar2Te.count());
00679     r.setWidth(iWidth);
00680     dlg.setGeometry(r);
00681   }
00682   if ( i > 0 && // only if there are any variables
00683     dlg.exec() == QDialog::Accepted ) {
00684 
00685     QMap<QString, KTextEdit *>::Iterator it2;
00686     for ( it2 = mapVar2Te.begin(); it2 != mapVar2Te.end(); ++it2 ) {
00687       if (it2.key() == _SnippetConfig.getDelimiter() + _SnippetConfig.getDelimiter())
00688         continue;
00689       (*map)[it2.key()] = it2.data()->text();    //copy the entered values back to the given map
00690 
00691       if (mapVar2Cb[it2.key()]->isChecked())     //if the checkbox is on; save the values for later
00692         (*mapSave)[it2.key()] = it2.data()->text();
00693       else
00694         (*mapSave).erase(it2.key());
00695     }
00696     bReturn = true;
00697 
00698     iBasicHeight = dlg.geometry().height() - layoutVar->geometry().height();
00699     iOneHeight = layoutVar->geometry().height() / mapVar2Te.count();
00700     iWidth = dlg.geometry().width();
00701   }
00702 
00703   //do some cleanup
00704   QMap<QString, KTextEdit *>::Iterator it1;
00705   for (it1 = mapVar2Te.begin(); it1 != mapVar2Te.end(); ++it1)
00706     delete it1.data();
00707   mapVar2Te.clear();
00708   QMap<QString, QCheckBox *>::Iterator it2;
00709   for (it2 = mapVar2Cb.begin(); it2 != mapVar2Cb.end(); ++it2)
00710     delete it2.data();
00711   mapVar2Cb.clear();
00712   delete layoutTop;
00713   delete layoutVar;
00714   delete layoutBtn;
00715   delete layout;
00716 
00717   if (i==0) //if nothing happened this means, that there are no variables to translate
00718     return true; //.. so just return OK
00719 
00720   return bReturn;
00721 //  return true;
00722 }
00723 
00724 
00725 //  fn SnippetWidget::showSingleVarDialog(QString var, QMap<QString, QString> * mapSave)
00730 QString SnippetWidget::showSingleVarDialog(QString var, QMap<QString, QString> * mapSave, QRect & dlgSize)
00731 {
00732   // --BEGIN-- building a dynamic dialog
00733   QDialog dlg(this);
00734   dlg.setCaption(i18n("Enter Values for Variables"));
00735 
00736   QGridLayout * layout = new QGridLayout( &dlg, 1, 1, 11, 6, "layout");
00737   QGridLayout * layoutTop = new QGridLayout( 0, 1, 1, 0, 6, "layoutTop");
00738   QGridLayout * layoutVar = new QGridLayout( 0, 1, 1, 0, 6, "layoutVar");
00739   QGridLayout * layoutBtn = new QGridLayout( 0, 2, 1, 0, 6, "layoutBtn");
00740 
00741   KTextEdit *te = NULL;
00742   QLabel * labTop = NULL;
00743   QCheckBox * cb = NULL;
00744 
00745   labTop = new QLabel( &dlg, "label" );
00746   layoutTop->addWidget(labTop, 0, 0);
00747   labTop->setText(i18n("Enter the replacement values for %1:").arg( var ));
00748   layout->addMultiCellLayout( layoutTop, 0, 0, 0, 1 );
00749 
00750 
00751   cb = new QCheckBox( &dlg, "cbVar" );
00752   cb->setChecked( FALSE );
00753   cb->setText(i18n( "Make value &default" ));
00754 
00755   te = new KTextEdit( &dlg, "teVar" );
00756   layoutVar->addWidget( te, 0, 1, Qt::AlignTop);
00757   layoutVar->addWidget( cb, 1, 1, Qt::AlignTop);
00758   if ((*mapSave)[var].length() > 0) {
00759     cb->setChecked( TRUE );
00760     te->setText((*mapSave)[var]);
00761   }
00762 
00763   QToolTip::add( cb, i18n("Enable this to save the value entered to the right as the default value for this variable") );
00764   QWhatsThis::add( cb, i18n("If you enable this option, the value entered to the right will be saved. "
00765                             "If you use the same variable later, even in another snippet, the value entered to the right "
00766                             "will be the default value for that variable.") );
00767 
00768   layout->addMultiCellLayout( layoutVar, 1, 1, 0, 1 );
00769 
00770   KPushButton * btn1 = new KPushButton( KStdGuiItem::cancel(), &dlg, "pushButton1" );
00771   layoutBtn->addWidget( btn1, 0, 0 );
00772 
00773   KPushButton * btn2 = new KPushButton( KStdGuiItem::apply(), &dlg, "pushButton2" );
00774   btn2->setDefault( TRUE );
00775   layoutBtn->addWidget( btn2, 0, 1 );
00776 
00777   layout->addMultiCellLayout( layoutBtn, 2, 2, 0, 1 );
00778   te->setFocus();
00779   // --END-- building a dynamic dialog
00780 
00781   //connect the buttons to the QDialog default slots
00782   connect(btn1, SIGNAL(clicked()), &dlg, SLOT(reject()) );
00783   connect(btn2, SIGNAL(clicked()), &dlg, SLOT(accept()) );
00784 
00785   //execute the dialog
00786   QString strReturn = "";
00787   if (dlgSize.isValid())
00788     dlg.setGeometry(dlgSize);
00789   if ( dlg.exec() == QDialog::Accepted ) {
00790     if (cb->isChecked())     //if the checkbox is on; save the values for later
00791       (*mapSave)[var] = te->text();
00792     else
00793       (*mapSave).erase(var);
00794 
00795     strReturn = te->text();    //copy the entered values back the the given map
00796 
00797     dlgSize = dlg.geometry();
00798   }
00799 
00800   //do some cleanup
00801   delete cb;
00802   delete te;
00803   delete labTop;
00804   delete btn1;
00805   delete btn2;
00806   delete layoutTop;
00807   delete layoutVar;
00808   delete layoutBtn;
00809   delete layout;
00810 
00811   return strReturn;
00812 }
00813 
00814 //  fn SnippetWidget::acceptDrag (QDropEvent *event) const
00821 bool SnippetWidget::acceptDrag (QDropEvent *event) const
00822 {
00823   kdDebug(5006) << "Format: " << event->format() << "" << event->pos() << endl;
00824 
00825   QListViewItem * item = itemAt(event->pos());
00826 
00827   if (item &&
00828       QString(event->format()).startsWith("text/plain") &&
00829       static_cast<SnippetWidget *>(event->source()) != this) {
00830     kdDebug(5006) << "returning TRUE " << endl;
00831     return TRUE;
00832   } else if(item &&
00833       QString(event->format()).startsWith("x-kmailsnippet") &&
00834       static_cast<SnippetWidget *>(event->source()) != this)
00835   {
00836     kdDebug(5006) << "returning TRUE " << endl;
00837     return TRUE;
00838   } else {
00839     kdDebug(5006) << "returning FALSE" << endl;
00840     event->acceptAction(FALSE);
00841     return FALSE;
00842   }
00843 }
00844 
00845 //  fn SnippetWidget::slotDropped(QDropEvent *e, QListViewItem *after)
00851 void SnippetWidget::slotDropped(QDropEvent *e, QListViewItem *)
00852 {
00853   QListViewItem * item2 = itemAt(e->pos());
00854 
00855   SnippetGroup *group = dynamic_cast<SnippetGroup *>(item2);
00856   if (!group)
00857     group = dynamic_cast<SnippetGroup *>(item2->parent());
00858 
00859   QCString dropped;
00860   QByteArray data = e->encodedData("text/plain");
00861   if ( e->provides("text/plain") && data.size()>0 ) {
00862     //get the data from the event...
00863     QString encData(data.data());
00864     kdDebug(5006) << "encData: " << encData << endl;
00865 
00866     //... then fill the dialog with the given data
00867     SnippetDlg dlg(this, "SnippetDlg", true);
00868     dlg.snippetName->clear();
00869     dlg.snippetText->setText(encData);
00870 
00871     /*fill the combobox with the names of all SnippetGroup entries*/
00872     for (SnippetItem *it=_list.first(); it; it=_list.next()) {
00873       if (dynamic_cast<SnippetGroup*>(it)) {
00874         dlg.cbGroup->insertItem(it->getName());
00875       }
00876     }
00877     dlg.cbGroup->setCurrentText(group->getName());
00878 
00879     if (dlg.exec() == QDialog::Accepted) {
00880       /* get the group that the user selected with the combobox */
00881       group = dynamic_cast<SnippetGroup*>(SnippetItem::findItemByName(dlg.cbGroup->currentText(), _list));
00882       _list.append( new SnippetItem(group, dlg.snippetName->text(), dlg.snippetText->text()) );
00883     }
00884   }
00885 }
00886 
00887 void SnippetWidget::startDrag()
00888 {
00889     QString text = dynamic_cast<SnippetItem*>( currentItem() )->getText();
00890     QTextDrag *drag = new QTextDrag(text, this);
00891     drag->setSubtype("x-textsnippet");
00892     drag->drag();
00893 }
00894 
00895 void SnippetWidget::slotExecute()
00896 {
00897     slotExecuted(currentItem());
00898 }
00899 
00900 
00901 #include "snippet_widget.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys