You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdepim/kmail/snippetwidget.cpp

958 lines
32 KiB

/***************************************************************************
* snippet feature from kdevelop/plugins/snippet/ *
* *
* Copyright (C) 2007 by Robert Gruber *
* rgruber@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <kurl.h>
#include <kdebug.h>
#include <klocale.h>
#include <qlayout.h>
#include <kpushbutton.h>
#include <klistview.h>
#include <qheader.h>
#include <klineedit.h>
#include <ktextedit.h>
#include <kmessagebox.h>
#include <kconfig.h>
#include <qtooltip.h>
#include <kpopupmenu.h>
#include <qregexp.h>
#include <qinputdialog.h>
#include <qlabel.h>
#include <qcheckbox.h>
#include <qwhatsthis.h>
#include <qdragobject.h>
#include <qtimer.h>
#include <kcombobox.h>
#include <kmedit.h>
#include <kiconloader.h>
#include <kshortcut.h>
#include <kaction.h>
#include <kkeybutton.h>
#include "snippetdlg.h"
#include "snippetitem.h"
#include "snippetwidget.h"
#include <cassert>
SnippetWidget::SnippetWidget(KMEdit* editor, KActionCollection* actionCollection, QWidget* parent)
: KListView(parent, "snippet widget"), QToolTip( viewport() ),
mEditor( editor ), mActionCollection( actionCollection )
{
// init the QPtrList
_list.setAutoDelete(TRUE);
// init the KListView
setSorting( -1 );
addColumn( "" );
setFullWidth(true);
header()->hide();
setAcceptDrops(true);
setDragEnabled(true);
setDropVisualizer(false);
setRootIsDecorated(true);
//connect the signals
connect( this, SIGNAL( contextMenuRequested ( QListViewItem *, const QPoint & , int ) ),
this, SLOT( showPopupMenu(QListViewItem *, const QPoint & , int ) ) );
connect( this, SIGNAL( doubleClicked (QListViewItem *) ),
this, SLOT( slotEdit( QListViewItem *) ) );
connect( this, SIGNAL( returnPressed (QListViewItem *) ),
this, SLOT( slotExecuted( QListViewItem *) ) );
connect( this, SIGNAL( dropped(QDropEvent *, QListViewItem *) ),
this, SLOT( slotDropped(QDropEvent *, QListViewItem *) ) );
connect( editor, SIGNAL( insertSnippet() ), this, SLOT( slotExecute() ));
_cfg = 0;
QTimer::singleShot(0, this, SLOT(initConfig()));
}
SnippetWidget::~SnippetWidget()
{
writeConfig();
delete _cfg;
/* We need to delete the child items before the parent items
otherwise KDevelop would crash on exiting */
SnippetItem * item;
while (_list.count() > 0) {
for (item=_list.first(); item; item=_list.next()) {
if (item->childCount() == 0)
_list.remove(item);
}
}
}
/*!
\fn SnippetWidget::slotAdd()
Opens the dialog to add a snippet
*/
void SnippetWidget::slotAdd()
{
//kdDebug(5006) << "Ender slotAdd()" << endl;
SnippetDlg dlg( mActionCollection, this, "SnippetDlg");
/*check if the user clicked a SnippetGroup
If not, we set the group variable to the SnippetGroup
which the selected item is a child of*/
SnippetGroup * group = dynamic_cast<SnippetGroup*>(selectedItem());
if ( !group && selectedItem() )
group = dynamic_cast<SnippetGroup*>(selectedItem()->parent());
/* still no group, let's make a default one */
if (!group ) {
if ( _list.isEmpty() ) {
group = new SnippetGroup(this, i18n("General"), SnippetGroup::getMaxId() );
_list.append( group );
} else {
group = dynamic_cast<SnippetGroup*>( _list.first() );
}
}
assert( group );
/*fill the combobox with the names of all SnippetGroup entries*/
for (SnippetItem *it=_list.first(); it; it=_list.next()) {
if (dynamic_cast<SnippetGroup*>(it)) {
dlg.cbGroup->insertItem(it->getName());
}
}
dlg.cbGroup->setCurrentText(group->getName());
if (dlg.exec() == QDialog::Accepted) {
group = dynamic_cast<SnippetGroup*>(SnippetItem::findItemByName(dlg.cbGroup->currentText(), _list));
_list.append( makeItem( group, dlg.snippetName->text(), dlg.snippetText->text(), dlg.keyButton->shortcut() ) );
}
}
/*!
\fn SnippetWidget::makeItem( SnippetItem* parent, const QString& name, const QString& text )
Helper factory method.
*/
SnippetItem* SnippetWidget::makeItem( SnippetItem* parent, const QString& name, const QString& text, const KShortcut& shortcut )
{
SnippetItem * item = new SnippetItem(parent, name, text);
const QString actionName = i18n("Snippet %1").arg(name);
const QString normalizedName = QString(actionName).replace(" ", "_");
if ( !mActionCollection->action(normalizedName.utf8() ) ) {
KAction * action = new KAction( actionName, shortcut, item,
SLOT( slotExecute() ), mActionCollection,
normalizedName.utf8() );
item->setAction(action);
connect( item, SIGNAL( execute( QListViewItem* ) ),
this, SLOT( slotExecuted( QListViewItem* ) ) );
}
return item;
}
/*!
\fn SnippetWidget::slotAddGroup()
Opens the didalog to add a snippet
*/
void SnippetWidget::slotAddGroup()
{
//kdDebug(5006) << "Ender slotAddGroup()" << endl;
SnippetDlg dlg( mActionCollection, this, "SnippetDlg");
dlg.setShowShortcut( false );
dlg.snippetText->setEnabled(false);
dlg.snippetText->setText("GROUP");
dlg.setCaption(i18n("Add Group"));
dlg.cbGroup->insertItem(i18n("All"));
dlg.cbGroup->setCurrentText(i18n("All"));
if (dlg.exec() == QDialog::Accepted) {
_list.append( new SnippetGroup(this, dlg.snippetName->text(), SnippetGroup::getMaxId() ) );
}
}
/*!
\fn SnippetWidget::slotRemove()
Removes the selected snippet
*/
void SnippetWidget::slotRemove()
{
//get current data
QListViewItem * item = currentItem();
SnippetItem *snip = dynamic_cast<SnippetItem*>( item );
SnippetGroup *group = dynamic_cast<SnippetGroup*>( item );
if (!snip)
return;
if (group) {
if (group->childCount() > 0 &&
KMessageBox::warningContinueCancel(this, i18n("Do you really want to remove this group and all its snippets?"),QString::null,KStdGuiItem::del())
== KMessageBox::Cancel)
return;
SnippetItem *it=_list.first();
while ( it ) {
if (it->getParent() == group->getId()) {
SnippetItem *doomed = it;
it = _list.next();
//kdDebug(5006) << "remove " << doomed->getName() << endl;
_list.remove(doomed);
} else {
it = _list.next();
}
}
}
//kdDebug(5006) << "remove " << snip->getName() << endl;
_list.remove(snip);
}
/*!
\fn SnippetWidget::slotEdit()
Opens the dialog of editing the selected snippet
*/
void SnippetWidget::slotEdit( QListViewItem* item )
{
if( item == 0 ) {
item = currentItem();
}
SnippetGroup *pGroup = dynamic_cast<SnippetGroup*>(item);
SnippetItem *pSnippet = dynamic_cast<SnippetItem*>( item );
if (!pSnippet || pGroup) /*selected item must be a SnippetItem but MUST not be a SnippetGroup*/
return;
//init the dialog
SnippetDlg dlg( mActionCollection, this, "SnippetDlg");
dlg.snippetName->setText(pSnippet->getName());
dlg.snippetText->setText(pSnippet->getText());
dlg.keyButton->setShortcut( pSnippet->getAction()->shortcut(), false );
dlg.btnAdd->setText(i18n("&Apply"));
dlg.setCaption(i18n("Edit Snippet"));
/*fill the combobox with the names of all SnippetGroup entries*/
for (SnippetItem *it=_list.first(); it; it=_list.next()) {
if (dynamic_cast<SnippetGroup*>(it)) {
dlg.cbGroup->insertItem(it->getName());
}
}
dlg.cbGroup->setCurrentText(SnippetItem::findGroupById(pSnippet->getParent(), _list)->getName());
if (dlg.exec() == QDialog::Accepted) {
//update the KListView and the SnippetItem
item->setText( 0, dlg.snippetName->text() );
pSnippet->setName( dlg.snippetName->text() );
pSnippet->setText( dlg.snippetText->text() );
pSnippet->getAction()->setShortcut( dlg.keyButton->shortcut());
/* if the user changed the parent we need to move the snippet */
if ( SnippetItem::findGroupById(pSnippet->getParent(), _list)->getName() != dlg.cbGroup->currentText() ) {
SnippetGroup * newGroup = dynamic_cast<SnippetGroup*>(SnippetItem::findItemByName(dlg.cbGroup->currentText(), _list));
pSnippet->parent()->takeItem(pSnippet);
newGroup->insertItem(pSnippet);
pSnippet->resetParent();
}
setSelected(item, TRUE);
}
}
/*!
\fn SnippetWidget::slotEditGroup()
Opens the dialog of editing the selected snippet-group
*/
void SnippetWidget::slotEditGroup()
{
//get current data
QListViewItem * item = currentItem();
SnippetGroup *pGroup = dynamic_cast<SnippetGroup*>( item );
if (!pGroup) /*selected item MUST be a SnippetGroup*/
return;
//init the dialog
SnippetDlg dlg( mActionCollection, this, "SnippetDlg" );
dlg.setShowShortcut( false );
dlg.snippetName->setText(pGroup->getName());
dlg.snippetText->setText(pGroup->getText());
dlg.btnAdd->setText(i18n("&Apply"));
dlg.snippetText->setEnabled(FALSE);
dlg.setCaption(i18n("Edit Group"));
dlg.cbGroup->insertItem(i18n("All"));
if (dlg.exec() == QDialog::Accepted) {
//update the KListView and the SnippetGroup
item->setText( 0, dlg.snippetName->text() );
pGroup->setName( dlg.snippetName->text() );
setSelected(item, TRUE);
}
}
void SnippetWidget::slotExecuted(QListViewItem * item)
{
if( item == 0 )
{
item = currentItem();
}
SnippetItem *pSnippet = dynamic_cast<SnippetItem*>( item );
if (!pSnippet || dynamic_cast<SnippetGroup*>(item))
return;
//process variables if any, then insert into the active view
insertIntoActiveView( parseText(pSnippet->getText(), _SnippetConfig.getDelimiter()) );
}
/*!
\fn SnippetWidget::insertIntoActiveView(QString text)
Inserts the parameter text into the activ view
*/
void SnippetWidget::insertIntoActiveView( const QString &text )
{
mEditor->insert( text );
}
/*!
\fn SnippetWidget::writeConfig()
Write the cofig file
*/
void SnippetWidget::writeConfig()
{
if( !_cfg )
return;
_cfg->deleteGroup("SnippetPart"); //this is neccessary otherwise delete entries will stay in list until
//they get overwritten by a more recent entry
_cfg->setGroup("SnippetPart");
QString strKeyName="";
QString strKeyText="";
QString strKeyId="";
int iSnipCount = 0;
int iGroupCount = 0;
SnippetItem* item=_list.first();
while ( item != 0) {
//kdDebug(5006) << "-->ERROR " << item->getName() << endl;
//kdDebug(5006) << "SnippetWidget::writeConfig() " << item->getName() << endl;
SnippetGroup * group = dynamic_cast<SnippetGroup*>(item);
if (group) {
//kdDebug(5006) << "-->GROUP " << item->getName() << group->getId() << " " << iGroupCount<< endl;
strKeyName=QString("snippetGroupName_%1").arg(iGroupCount);
strKeyId=QString("snippetGroupId_%1").arg(iGroupCount);
_cfg->writeEntry(strKeyName, group->getName());
_cfg->writeEntry(strKeyId, group->getId());
iGroupCount++;
} else if (dynamic_cast<SnippetItem*>(item)) {
//kdDebug(5006) << "-->ITEM " << item->getName() << item->getParent() << " " << iSnipCount << endl;
strKeyName=QString("snippetName_%1").arg(iSnipCount);
strKeyText=QString("snippetText_%1").arg(iSnipCount);
strKeyId=QString("snippetParent_%1").arg(iSnipCount);
_cfg->writeEntry(strKeyName, item->getName());
_cfg->writeEntry(strKeyText, item->getText());
_cfg->writeEntry(strKeyId, item->getParent());
KAction * action = item->getAction();
assert( action );
const KShortcut& sc = action->shortcut();
if (!sc.isNull() ) {
_cfg->writeEntry( QString("snippetShortcut_%1").arg(iSnipCount), sc.toString() );
}
iSnipCount++;
} else {
//kdDebug(5006) << "-->ERROR " << item->getName() << endl;
}
item = _list.next();
}
_cfg->writeEntry("snippetCount", iSnipCount);
_cfg->writeEntry("snippetGroupCount", iGroupCount);
int iCount = 1;
QMap<QString, QString>::Iterator it;
for ( it = _mapSaved.begin(); it != _mapSaved.end(); ++it ) { //write the saved variable values
if (it.data().length()<=0) continue; //is the saved value has no length -> no need to save it
strKeyName=QString("snippetSavedName_%1").arg(iCount);
strKeyText=QString("snippetSavedVal_%1").arg(iCount);
_cfg->writeEntry(strKeyName, it.key());
_cfg->writeEntry(strKeyText, it.data());
iCount++;
}
_cfg->writeEntry("snippetSavedCount", iCount-1);
_cfg->writeEntry( "snippetDelimiter", _SnippetConfig.getDelimiter() );
_cfg->writeEntry( "snippetVarInput", _SnippetConfig.getInputMethod() );
_cfg->writeEntry( "snippetToolTips", _SnippetConfig.useToolTips() );
_cfg->writeEntry( "snippetGroupAutoOpen", _SnippetConfig.getAutoOpenGroups() );
_cfg->writeEntry("snippetSingleRect", _SnippetConfig.getSingleRect() );
_cfg->writeEntry("snippetMultiRect", _SnippetConfig.getMultiRect() );
_cfg->sync();
}
/*!
\fn SnippetWidget::initConfig()
Initial read the cofig file
*/
void SnippetWidget::initConfig()
{
if (_cfg == NULL)
_cfg = new KConfig("kmailsnippetrc", false, false);
_cfg->setGroup("SnippetPart");
QString strKeyName="";
QString strKeyText="";
QString strKeyId="";
SnippetItem *item;
SnippetGroup *group;
//kdDebug(5006) << "SnippetWidget::initConfig() " << endl;
//if entry doesn't get found, this will return -1 which we will need a bit later
int iCount = _cfg->readNumEntry("snippetGroupCount", -1);
for ( int i=0; i<iCount; i++) { //read the group-list
strKeyName=QString("snippetGroupName_%1").arg(i);
strKeyId=QString("snippetGroupId_%1").arg(i);
QString strNameVal="";
int iIdVal=-1;
strNameVal = _cfg->readEntry(strKeyName, "");
iIdVal = _cfg->readNumEntry(strKeyId, -1);
//kdDebug(5006) << "Read group " << " " << iIdVal << endl;
if (strNameVal != "" && iIdVal != -1) {
group = new SnippetGroup(this, strNameVal, iIdVal);
//kdDebug(5006) << "Created group " << group->getName() << " " << group->getId() << endl;
_list.append(group);
}
}
/* Check if the snippetGroupCount property has been found
if iCount is -1 this means, that the user has his snippets
stored without groups. Therefore we will call the
initConfigOldVersion() function below */
// should not happen since this function has been removed
if (iCount != -1) {
iCount = _cfg->readNumEntry("snippetCount", 0);
for ( int i=0; i<iCount; i++) { //read the snippet-list
strKeyName=QString("snippetName_%1").arg(i);
strKeyText=QString("snippetText_%1").arg(i);
strKeyId=QString("snippetParent_%1").arg(i);
QString strNameVal="";
QString strTextVal="";
int iParentVal = -1;
strNameVal = _cfg->readEntry(strKeyName, "");
strTextVal = _cfg->readEntry(strKeyText, "");
iParentVal = _cfg->readNumEntry(strKeyId, -1);
//kdDebug(5006) << "Read item " << strNameVal << " " << iParentVal << endl;
if (strNameVal != "" && strTextVal != "" && iParentVal != -1) {
KShortcut shortcut( _cfg->readEntry( QString("snippetShortcut_%1").arg(i), QString() ) );
item = makeItem( SnippetItem::findGroupById(iParentVal, _list), strNameVal, strTextVal, shortcut );
//kdDebug(5006) << "Created item " << item->getName() << " " << item->getParent() << endl;
_list.append(item);
}
}
} else {
//kdDebug() << "iCount is not -1";
}
iCount = _cfg->readNumEntry("snippetSavedCount", 0);
for ( int i=1; i<=iCount; i++) { //read the saved-values and store in QMap
strKeyName=QString("snippetSavedName_%1").arg(i);
strKeyText=QString("snippetSavedVal_%1").arg(i);
QString strNameVal="";
QString strTextVal="";
strNameVal = _cfg->readEntry(strKeyName, "");
strTextVal = _cfg->readEntry(strKeyText, "");
if (strNameVal != "" && strTextVal != "") {
_mapSaved[strNameVal] = strTextVal;
}
}
_SnippetConfig.setDelimiter( _cfg->readEntry("snippetDelimiter", "$") );
_SnippetConfig.setInputMethod( _cfg->readNumEntry("snippetVarInput", 0) );
_SnippetConfig.setToolTips( _cfg->readBoolEntry("snippetToolTips", true) );
_SnippetConfig.setAutoOpenGroups( _cfg->readNumEntry("snippetGroupAutoOpen", 1) );
_SnippetConfig.setSingleRect( _cfg->readRectEntry("snippetSingleRect", 0L) );
_SnippetConfig.setMultiRect( _cfg->readRectEntry("snippetMultiRect", 0L) );
}
/*!
\fn SnippetWidget::maybeTip( const QPoint & p )
Shows the Snippet-Text as ToolTip
*/
void SnippetWidget::maybeTip( const QPoint & p )
{
SnippetItem * item = dynamic_cast<SnippetItem*>( itemAt( p ) );
if (!item)
return;
QRect r = itemRect( item );
if (r.isValid() &&
_SnippetConfig.useToolTips() )
{
tip( r, item->getText() ); //show the snippet's text
}
}
/*!
\fn SnippetWidget::showPopupMenu( QListViewItem * item, const QPoint & p, int )
Shows the Popup-Menu depending item is a valid pointer
*/
void SnippetWidget::showPopupMenu( QListViewItem * item, const QPoint & p, int )
{
KPopupMenu popup;
SnippetItem * selectedItem = static_cast<SnippetItem *>(item);
if ( item ) {
popup.insertTitle( selectedItem->getName() );
if (dynamic_cast<SnippetGroup*>(item)) {
popup.insertItem( i18n("Edit &group..."), this, SLOT( slotEditGroup() ) );
} else {
popup.insertItem( SmallIconSet("editpaste"), i18n("&Paste"), this, SLOT( slotExecuted() ) );
popup.insertItem( SmallIconSet("edit"), i18n("&Edit..."), this, SLOT( slotEdit() ) );
}
popup.insertItem( SmallIconSet("editdelete"), i18n("&Remove"), this, SLOT( slotRemove() ) );
popup.insertSeparator();
} else {
popup.insertTitle(i18n("Text Snippets"));
}
popup.insertItem( i18n("&Add Snippet..."), this, SLOT( slotAdd() ) );
popup.insertItem( i18n("Add G&roup..."), this, SLOT( slotAddGroup() ) );
popup.exec(p);
}
// fn SnippetWidget::parseText(QString text, QString del)
/*!
This function is used to parse the given QString for variables. If found the user will be prompted
for a replacement value. It returns the string text with all replacements made
*/
QString SnippetWidget::parseText(QString text, QString del)
{
QString str = text;
QString strName = "";
QString strNew = "";
QString strMsg="";
int iFound = -1;
int iEnd = -1;
QMap<QString, QString> mapVar;
int iInMeth = _SnippetConfig.getInputMethod();
QRect rSingle = _SnippetConfig.getSingleRect();
QRect rMulti = _SnippetConfig.getMultiRect();
do {
iFound = text.find(QRegExp("\\"+del+"[A-Za-z-_0-9\\s]*\\"+del), iEnd+1); //find the next variable by this QRegExp
if (iFound >= 0) {
iEnd = text.find(del, iFound+1)+1;
strName = text.mid(iFound, iEnd-iFound);
if ( strName != del+del ) { //if not doubel-delimiter
if (iInMeth == 0) { //if input-method "single" is selected
if ( mapVar[strName].length() <= 0 ) { // and not already in map
strMsg=i18n("Please enter the value for <b>%1</b>:").arg(strName);
strNew = showSingleVarDialog( strName, &_mapSaved, rSingle );
if (strNew=="")
return ""; //user clicked Cancle
} else {
continue; //we have already handled this variable
}
} else {
strNew = ""; //for inputmode "multi" just reset new valaue
}
} else {
strNew = del; //if double-delimiter -> replace by single character
}
if (iInMeth == 0) { //if input-method "single" is selected
str.replace(strName, strNew);
}
mapVar[strName] = strNew;
}
} while (iFound != -1);
if (iInMeth == 1) { //check config, if input-method "multi" is selected
int w, bh, oh;
w = rMulti.width();
bh = rMulti.height();
oh = rMulti.top();
if (showMultiVarDialog( &mapVar, &_mapSaved, w, bh, oh )) { //generate and show the dialog
QMap<QString, QString>::Iterator it;
for ( it = mapVar.begin(); it != mapVar.end(); ++it ) { //walk through the map and do the replacement
str.replace(it.key(), it.data());
}
} else {
return "";
}
rMulti.setWidth(w); //this is a hack to save the dialog's dimensions in only one QRect
rMulti.setHeight(bh);
rMulti.setTop(oh);
rMulti.setLeft(0);
_SnippetConfig.setMultiRect(rMulti);
}
_SnippetConfig.setSingleRect(rSingle);
return str;
}
// fn SnippetWidget::showMultiVarDialog()
/*!
This function constructs a dialog which contains a label and a linedit for every
variable that is stored in the given map except the double-delimiter entry
It return true if everything was ok and false if the user hit cancel
*/
bool SnippetWidget::showMultiVarDialog(QMap<QString, QString> * map, QMap<QString, QString> * mapSave,
int & iWidth, int & iBasicHeight, int & iOneHeight)
{
//if no var -> no need to show
if (map->count() == 0)
return true;
//if only var is the double-delimiter -> no need to show
QMap<QString, QString>::Iterator it = map->begin();
if ( map->count() == 1 && it.data()==_SnippetConfig.getDelimiter()+_SnippetConfig.getDelimiter() )
return true;
QMap<QString, KTextEdit *> mapVar2Te; //this map will help keeping track which TEXTEDIT goes with which variable
QMap<QString, QCheckBox *> mapVar2Cb; //this map will help keeping track which CHECKBOX goes with which variable
// --BEGIN-- building a dynamic dialog
QDialog dlg(this);
dlg.setCaption(i18n("Enter Values for Variables"));
QGridLayout * layout = new QGridLayout( &dlg, 1, 1, 11, 6, "layout");
QGridLayout * layoutTop = new QGridLayout( 0, 1, 1, 0, 6, "layoutTop");
QGridLayout * layoutVar = new QGridLayout( 0, 1, 1, 0, 6, "layoutVar");
QGridLayout * layoutBtn = new QGridLayout( 0, 1, 1, 0, 6, "layoutBtn");
KTextEdit *te = NULL;
QLabel * labTop = NULL;
QCheckBox * cb = NULL;
labTop = new QLabel( &dlg, "label" );
labTop->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0,
labTop->sizePolicy().hasHeightForWidth() ) );
labTop->setText(i18n("Enter the replacement values for these variables:"));
layoutTop->addWidget(labTop, 0, 0);
layout->addMultiCellLayout( layoutTop, 0, 0, 0, 1 );
int i = 0; //walk through the variable map and add
for ( it = map->begin(); it != map->end(); ++it ) { //a checkbox, a lable and a lineedit to the main layout
if (it.key() == _SnippetConfig.getDelimiter() + _SnippetConfig.getDelimiter())
continue;
cb = new QCheckBox( &dlg, "cbVar" );
cb->setChecked( FALSE );
cb->setText(it.key());
layoutVar->addWidget( cb, i ,0, Qt::AlignTop );
te = new KTextEdit( &dlg, "teVar" );
layoutVar->addWidget( te, i, 1, Qt::AlignTop );
if ((*mapSave)[it.key()].length() > 0) {
cb->setChecked( TRUE );
te->setText((*mapSave)[it.key()]);
}
mapVar2Te[it.key()] = te;
mapVar2Cb[it.key()] = cb;
QToolTip::add( cb, i18n("Enable this to save the value entered to the right as the default value for this variable") );
QWhatsThis::add( cb, i18n("If you enable this option, the value entered to the right will be saved. "
"If you use the same variable later, even in another snippet, the value entered to the right "
"will be the default value for that variable.") );
i++;
}
layout->addMultiCellLayout( layoutVar, 1, 1, 0, 1 );
KPushButton * btn1 = new KPushButton( KStdGuiItem::cancel(), &dlg, "pushButton1" );
btn1->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0,
btn1->sizePolicy().hasHeightForWidth() ) );
layoutBtn->addWidget( btn1, 0, 0 );
KPushButton * btn2 = new KPushButton( KStdGuiItem::apply(), &dlg, "pushButton2" );
btn2->setDefault( TRUE );
btn2->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0,
btn2->sizePolicy().hasHeightForWidth() ) );
layoutBtn->addWidget( btn2, 0, 1 );
layout->addMultiCellLayout( layoutBtn, 2, 2, 0, 1 );
// --END-- building a dynamic dialog
//connect the buttons to the QDialog default slots
connect(btn1, SIGNAL(clicked()), &dlg, SLOT(reject()) );
connect(btn2, SIGNAL(clicked()), &dlg, SLOT(accept()) );
//prepare to execute the dialog
bool bReturn = false;
//resize the textedits
if (iWidth > 1) {
QRect r = dlg.geometry();
r.setHeight(iBasicHeight + iOneHeight*mapVar2Te.count());
r.setWidth(iWidth);
dlg.setGeometry(r);
}
if ( i > 0 && // only if there are any variables
dlg.exec() == QDialog::Accepted ) {
QMap<QString, KTextEdit *>::Iterator it2;
for ( it2 = mapVar2Te.begin(); it2 != mapVar2Te.end(); ++it2 ) {
if (it2.key() == _SnippetConfig.getDelimiter() + _SnippetConfig.getDelimiter())
continue;
(*map)[it2.key()] = it2.data()->text(); //copy the entered values back to the given map
if (mapVar2Cb[it2.key()]->isChecked()) //if the checkbox is on; save the values for later
(*mapSave)[it2.key()] = it2.data()->text();
else
(*mapSave).erase(it2.key());
}
bReturn = true;
iBasicHeight = dlg.geometry().height() - layoutVar->geometry().height();
iOneHeight = layoutVar->geometry().height() / mapVar2Te.count();
iWidth = dlg.geometry().width();
}
//do some cleanup
QMap<QString, KTextEdit *>::Iterator it1;
for (it1 = mapVar2Te.begin(); it1 != mapVar2Te.end(); ++it1)
delete it1.data();
mapVar2Te.clear();
QMap<QString, QCheckBox *>::Iterator it2;
for (it2 = mapVar2Cb.begin(); it2 != mapVar2Cb.end(); ++it2)
delete it2.data();
mapVar2Cb.clear();
delete layoutTop;
delete layoutVar;
delete layoutBtn;
delete layout;
if (i==0) //if nothing happened this means, that there are no variables to translate
return true; //.. so just return OK
return bReturn;
// return true;
}
// fn SnippetWidget::showSingleVarDialog(QString var, QMap<QString, QString> * mapSave)
/*!
This function constructs a dialog which contains a label and a linedit for the given variable
It return either the entered value or an empty string if the user hit cancel
*/
QString SnippetWidget::showSingleVarDialog(QString var, QMap<QString, QString> * mapSave, QRect & dlgSize)
{
// --BEGIN-- building a dynamic dialog
QDialog dlg(this);
dlg.setCaption(i18n("Enter Values for Variables"));
QGridLayout * layout = new QGridLayout( &dlg, 1, 1, 11, 6, "layout");
QGridLayout * layoutTop = new QGridLayout( 0, 1, 1, 0, 6, "layoutTop");
QGridLayout * layoutVar = new QGridLayout( 0, 1, 1, 0, 6, "layoutVar");
QGridLayout * layoutBtn = new QGridLayout( 0, 2, 1, 0, 6, "layoutBtn");
KTextEdit *te = NULL;
QLabel * labTop = NULL;
QCheckBox * cb = NULL;
labTop = new QLabel( &dlg, "label" );
layoutTop->addWidget(labTop, 0, 0);
labTop->setText(i18n("Enter the replacement values for %1:").arg( var ));
layout->addMultiCellLayout( layoutTop, 0, 0, 0, 1 );
cb = new QCheckBox( &dlg, "cbVar" );
cb->setChecked( FALSE );
cb->setText(i18n( "Make value &default" ));
te = new KTextEdit( &dlg, "teVar" );
layoutVar->addWidget( te, 0, 1, Qt::AlignTop);
layoutVar->addWidget( cb, 1, 1, Qt::AlignTop);
if ((*mapSave)[var].length() > 0) {
cb->setChecked( TRUE );
te->setText((*mapSave)[var]);
}
QToolTip::add( cb, i18n("Enable this to save the value entered to the right as the default value for this variable") );
QWhatsThis::add( cb, i18n("If you enable this option, the value entered to the right will be saved. "
"If you use the same variable later, even in another snippet, the value entered to the right "
"will be the default value for that variable.") );
layout->addMultiCellLayout( layoutVar, 1, 1, 0, 1 );
KPushButton * btn1 = new KPushButton( KStdGuiItem::cancel(), &dlg, "pushButton1" );
layoutBtn->addWidget( btn1, 0, 0 );
KPushButton * btn2 = new KPushButton( KStdGuiItem::apply(), &dlg, "pushButton2" );
btn2->setDefault( TRUE );
layoutBtn->addWidget( btn2, 0, 1 );
layout->addMultiCellLayout( layoutBtn, 2, 2, 0, 1 );
te->setFocus();
// --END-- building a dynamic dialog
//connect the buttons to the QDialog default slots
connect(btn1, SIGNAL(clicked()), &dlg, SLOT(reject()) );
connect(btn2, SIGNAL(clicked()), &dlg, SLOT(accept()) );
//execute the dialog
QString strReturn = "";
if (dlgSize.isValid())
dlg.setGeometry(dlgSize);
if ( dlg.exec() == QDialog::Accepted ) {
if (cb->isChecked()) //if the checkbox is on; save the values for later
(*mapSave)[var] = te->text();
else
(*mapSave).erase(var);
strReturn = te->text(); //copy the entered values back the the given map
dlgSize = dlg.geometry();
}
//do some cleanup
delete cb;
delete te;
delete labTop;
delete btn1;
delete btn2;
delete layoutTop;
delete layoutVar;
delete layoutBtn;
delete layout;
return strReturn;
}
// fn SnippetWidget::acceptDrag (QDropEvent *event) const
/*!
Reimplementation from KListView.
Check here if the data the user is about to drop fits our restrictions.
We only accept dropps of plaintext, because from the dropped text
we will create a snippet.
*/
bool SnippetWidget::acceptDrag (QDropEvent *event) const
{
//kdDebug(5006) << "Format: " << event->format() << "" << event->pos() << endl;
QListViewItem * item = itemAt(event->pos());
if (item &&
QString(event->format()).startsWith("text/plain") &&
static_cast<SnippetWidget *>(event->source()) != this) {
///kdDebug(5006) << "returning TRUE " << endl;
return TRUE;
} else if(item &&
QString(event->format()).startsWith("x-kmailsnippet") &&
static_cast<SnippetWidget *>(event->source()) != this)
{
//kdDebug(5006) << "returning TRUE " << endl;
return TRUE;
} else {
//kdDebug(5006) << "returning FALSE" << endl;
event->acceptAction(FALSE);
return FALSE;
}
}
// fn SnippetWidget::slotDropped(QDropEvent *e, QListViewItem *after)
/*!
This slot is connected to the dropped signal.
If it is emitted, we need to construct a new snippet entry with
the data given
*/
void SnippetWidget::slotDropped(QDropEvent *e, QListViewItem *)
{
QListViewItem * item2 = itemAt(e->pos());
SnippetGroup *group = dynamic_cast<SnippetGroup *>(item2);
if (!group)
group = dynamic_cast<SnippetGroup *>(item2->parent());
QCString dropped;
QByteArray data = e->encodedData("text/plain");
if ( e->provides("text/plain") && data.size()>0 ) {
//get the data from the event...
QString encData(data.data());
//kdDebug(5006) << "encData: " << encData << endl;
//... then fill the dialog with the given data
SnippetDlg dlg( mActionCollection, this, "SnippetDlg" );
dlg.snippetName->clear();
dlg.snippetText->setText(encData);
/*fill the combobox with the names of all SnippetGroup entries*/
for (SnippetItem *it=_list.first(); it; it=_list.next()) {
if (dynamic_cast<SnippetGroup*>(it)) {
dlg.cbGroup->insertItem(it->getName());
}
}
dlg.cbGroup->setCurrentText(group->getName());
if (dlg.exec() == QDialog::Accepted) {
/* get the group that the user selected with the combobox */
group = dynamic_cast<SnippetGroup*>(SnippetItem::findItemByName(dlg.cbGroup->currentText(), _list));
_list.append( makeItem(group, dlg.snippetName->text(), dlg.snippetText->text(), dlg.keyButton->shortcut() ) );
}
}
}
void SnippetWidget::startDrag()
{
QString text = dynamic_cast<SnippetItem*>( currentItem() )->getText();
QTextDrag *drag = new QTextDrag(text, this);
drag->setSubtype("x-textsnippet");
drag->drag();
}
void SnippetWidget::slotExecute()
{
slotExecuted(currentItem());
}
#include "snippetwidget.moc"