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