00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023 #include <tqpopupmenu.h>
00024 #include <tqpushbutton.h>
00025 #include <tqtextedit.h>
00026 #include <tqlabel.h>
00027 #include <tqlineedit.h>
00028 #include <tqtoolbox.h>
00029 #include <tqtooltip.h>
00030 #include <tqwhatsthis.h>
00031 #include <tqfont.h>
00032
00033 #include <kdebug.h>
00034 #include <klocale.h>
00035 #include <kglobal.h>
00036 #include <kiconloader.h>
00037 #include <kpushbutton.h>
00038 #include <klistview.h>
00039 #include <klineedit.h>
00040 #include <tqcombobox.h>
00041 #include <kshortcut.h>
00042 #include <kmessagebox.h>
00043 #include <kkeybutton.h>
00044 #include <kactivelabel.h>
00045
00046 #include "customtemplates_base.h"
00047 #include "customtemplates_kfg.h"
00048 #include "globalsettings.h"
00049 #include "kmkernel.h"
00050 #include "kmmainwidget.h"
00051 #include "kmfawidgets.h"
00052
00053 #include "customtemplates.h"
00054
00055 CustomTemplates::CustomTemplates( TQWidget *parent, const char *name )
00056 :CustomTemplatesBase( parent, name ),
00057 mCurrentItem( 0 ),
00058 mBlockChangeSignal( false )
00059 {
00060 TQFont f = KGlobalSettings::fixedFont();
00061 mEdit->setFont( f );
00062
00063 mAdd->setIconSet( BarIconSet( "add", KIcon::SizeSmall ) );
00064 mRemove->setIconSet( BarIconSet( "remove", KIcon::SizeSmall ) );
00065
00066 mList->setColumnWidth( 0, 50 );
00067 mList->setColumnWidth( 1, 100 );
00068
00069 mEditFrame->setEnabled( false );
00070
00071 connect( mName, TQT_SIGNAL( textChanged ( const TQString &) ),
00072 this, TQT_SLOT( slotNameChanged( const TQString & ) ) );
00073 connect( mEdit, TQT_SIGNAL( textChanged() ),
00074 this, TQT_SLOT( slotTextChanged( void ) ) );
00075 connect( mToEdit, TQT_SIGNAL( textChanged(const TQString&) ),
00076 this, TQT_SLOT( slotTextChanged( void ) ) );
00077 connect( mCCEdit, TQT_SIGNAL( textChanged(const TQString&) ),
00078 this, TQT_SLOT( slotTextChanged( void ) ) );
00079
00080 connect( mInsertCommand, TQT_SIGNAL( insertCommand(TQString, int) ),
00081 this, TQT_SLOT( slotInsertCommand(TQString, int) ) );
00082
00083 connect( mAdd, TQT_SIGNAL( clicked() ),
00084 this, TQT_SLOT( slotAddClicked() ) );
00085 connect( mRemove, TQT_SIGNAL( clicked() ),
00086 this, TQT_SLOT( slotRemoveClicked() ) );
00087 connect( mList, TQT_SIGNAL( selectionChanged() ),
00088 this, TQT_SLOT( slotListSelectionChanged() ) );
00089 connect( mType, TQT_SIGNAL( activated( int ) ),
00090 this, TQT_SLOT( slotTypeActivated( int ) ) );
00091
00092 connect( mKeyButton, TQT_SIGNAL( capturedShortcut( const KShortcut& ) ),
00093 this, TQT_SLOT( slotShortcutCaptured( const KShortcut& ) ) );
00094
00095 mReplyPix = KIconLoader().loadIcon( "mail_reply", KIcon::Small );
00096 mReplyAllPix = KIconLoader().loadIcon( "mail_replyall", KIcon::Small );
00097 mForwardPix = KIconLoader().loadIcon( "mail_forward", KIcon::Small );
00098
00099 mType->clear();
00100 mType->insertItem( TQPixmap(), i18n( "Message->", "Universal" ), TUniversal );
00101 mType->insertItem( mReplyPix, i18n( "Message->", "Reply" ), TReply );
00102 mType->insertItem( mReplyAllPix, i18n( "Message->", "Reply to All" ), TReplyAll );
00103 mType->insertItem( mForwardPix, i18n( "Message->", "Forward" ), TForward );
00104
00105 TQString help =
00106 i18n( "<qt>"
00107 "<p>Here you can add, edit, and delete custom message "
00108 "templates to use when you compose a reply or forwarding message. "
00109 "Create the custom template by selecting it using the right mouse "
00110 " button menu or toolbar menu. Also, you can bind a keyboard "
00111 "combination to the template for faster operations.</p>"
00112 "<p>Message templates support substitution commands "
00113 "by simple typing them or selecting them from menu "
00114 "<i>Insert command</i>.</p>"
00115 "<p>There are four types of custom templates: used to "
00116 "<i>Reply</i>, <i>Reply to All</i>, <i>Forward</i>, and "
00117 "<i>Universal</i> which can be used for all kind of operations. "
00118 "You cannot bind keyboard shortcut to <i>Universal</i> templates.</p>"
00119 "</qt>" );
00120 mHelp->setText( i18n( "<a href=\"whatsthis:%1\">How does this work?</a>" ).arg( help ) );
00121
00122 const TQString toToolTip = i18n( "Additional recipients of the message when forwarding" );
00123 const TQString ccToolTip = i18n( "Additional recipients who get a copy of the message when forwarding" );
00124 const TQString toWhatsThis = i18n( "When using this template for forwarding, the default recipients are those you enter here. This is a comma-separated list of mail addresses." );
00125 const TQString ccWhatsThis = i18n( "When using this template for forwarding, the recipients you enter here will by default get a copy of this message. This is a comma-separated list of mail addresses." );
00126
00127
00128
00129
00130 KLineEdit *ccLineEdit = dynamic_cast<KLineEdit*>( mCCEdit->child( "addressEdit" ) );
00131 KLineEdit *toLineEdit = dynamic_cast<KLineEdit*>( mToEdit->child( "addressEdit" ) );
00132 Q_ASSERT( ccLineEdit && toLineEdit );
00133
00134 TQToolTip::add( mCCLabel, ccToolTip );
00135 TQToolTip::add( ccLineEdit, ccToolTip );
00136 TQToolTip::add( mToLabel, toToolTip );
00137 TQToolTip::add( toLineEdit, toToolTip );
00138 TQWhatsThis::add( mCCLabel, ccWhatsThis );
00139 TQWhatsThis::add( ccLineEdit, ccWhatsThis );
00140 TQWhatsThis::add( mToLabel, toWhatsThis );
00141 TQWhatsThis::add( toLineEdit, toWhatsThis );
00142
00143 slotNameChanged( mName->text() );
00144 }
00145
00146 CustomTemplates::~CustomTemplates()
00147 {
00148 TQDictIterator<CustomTemplateItem> it(mItemList);
00149 for ( ; it.current() ; ++it ) {
00150 CustomTemplateItem *vitem = mItemList.take( it.currentKey() );
00151 if ( vitem ) {
00152 delete vitem;
00153 }
00154 }
00155 }
00156
00157 void CustomTemplates::setRecipientsEditsEnabled( bool enabled )
00158 {
00159 mToEdit->setHidden( !enabled );
00160 mCCEdit->setHidden( !enabled );
00161 mToLabel->setHidden( !enabled );
00162 mCCLabel->setHidden( !enabled );
00163 }
00164
00165 void CustomTemplates::slotNameChanged( const TQString& text )
00166 {
00167 mAdd->setEnabled( !text.isEmpty() );
00168 }
00169
00170 TQString CustomTemplates::indexToType( int index )
00171 {
00172 TQString typeStr;
00173 switch ( index ) {
00174 case TUniversal:
00175
00176 break;
00177
00178
00179 case TReply:
00180 typeStr = i18n( "Message->", "Reply" ); break;
00181 case TReplyAll:
00182 typeStr = i18n( "Message->", "Reply to All" ); break;
00183 case TForward:
00184 typeStr = i18n( "Message->", "Forward" ); break;
00185 default:
00186 typeStr = i18n( "Message->", "Unknown" ); break;
00187 }
00188 return typeStr;
00189 }
00190
00191 void CustomTemplates::slotTextChanged()
00192 {
00193 if ( !mBlockChangeSignal )
00194 emit changed();
00195 }
00196
00197 void CustomTemplates::load()
00198 {
00199 TQStringList list = GlobalSettings::self()->customTemplates();
00200 for ( TQStringList::iterator it = list.begin(); it != list.end(); ++it ) {
00201 CTemplates t(*it);
00202
00203 TQString typeStr;
00204 KShortcut shortcut( t.shortcut() );
00205 CustomTemplateItem *vitem =
00206 new CustomTemplateItem( *it, t.content(),
00207 shortcut,
00208 static_cast<Type>( t.type() ), t.to(), t.cC() );
00209 mItemList.insert( *it, vitem );
00210 TQListViewItem *item = new TQListViewItem( mList, typeStr, *it, t.content() );
00211 switch ( t.type() ) {
00212 case TReply:
00213 item->setPixmap( 0, mReplyPix );
00214 break;
00215 case TReplyAll:
00216 item->setPixmap( 0, mReplyAllPix );
00217 break;
00218 case TForward:
00219 item->setPixmap( 0, mForwardPix );
00220 break;
00221 default:
00222 item->setPixmap( 0, TQPixmap() );
00223 item->setText( 0, indexToType( t.type() ) );
00224 break;
00225 };
00226 }
00227 }
00228
00229 void CustomTemplates::save()
00230 {
00231
00232
00233 for ( TQStringList::const_iterator it = mItemsToDelete.constBegin();
00234 it != mItemsToDelete.constEnd(); ++it ) {
00235 CTemplates t( (*it) );
00236 const TQString configGroup = t.currentGroup();
00237 kmkernel->config()->deleteGroup( configGroup );
00238 }
00239
00240 if ( mCurrentItem ) {
00241 CustomTemplateItem *vitem = mItemList[ mCurrentItem->text( 1 ) ];
00242 if ( vitem ) {
00243 vitem->mContent = mEdit->text();
00244 vitem->mShortcut = mKeyButton->shortcut();
00245 vitem->mTo = mToEdit->text();
00246 vitem->mCC = mCCEdit->text();
00247 }
00248 }
00249 TQStringList list;
00250 TQListViewItemIterator lit( mList );
00251 while ( lit.current() ) {
00252 list.append( (*lit)->text( 1 ) );
00253 ++lit;
00254 }
00255 for ( TQDictIterator<CustomTemplateItem> it( mItemList ); it.current() ; ++it ) {
00256
00257 CTemplates t( (*it)->mName );
00258 TQString &content = (*it)->mContent;
00259 if ( content.stripWhiteSpace().isEmpty() ) {
00260 content = "%BLANK";
00261 }
00262 t.setContent( content );
00263 t.setShortcut( (*it)->mShortcut.toString() );
00264 t.setType( (*it)->mType );
00265 t.setTo( (*it)->mTo );
00266 t.setCC( (*it)->mCC );
00267 t.writeConfig();
00268 }
00269 GlobalSettings::self()->setCustomTemplates( list );
00270 GlobalSettings::self()->writeConfig();
00271
00272
00273 if ( kmkernel->getKMMainWidget() )
00274 kmkernel->getKMMainWidget()->updateCustomTemplateMenus();
00275 }
00276
00277 void CustomTemplates::slotInsertCommand( TQString cmd, int adjustCursor )
00278 {
00279 int para, index;
00280 mEdit->getCursorPosition( ¶, &index );
00281 mEdit->insertAt( cmd, para, index );
00282
00283 index += adjustCursor;
00284
00285 mEdit->setCursorPosition( para, index + cmd.length() );
00286 }
00287
00288 void CustomTemplates::slotAddClicked()
00289 {
00290 TQString str = mName->text();
00291 if ( !str.isEmpty() ) {
00292 CustomTemplateItem *vitem = mItemList[ str ];
00293 if ( !vitem ) {
00294 vitem = new CustomTemplateItem( str, "", KShortcut::null(), TUniversal,
00295 TQString(), TQString() );
00296 mItemList.insert( str, vitem );
00297 TQListViewItem *item =
00298 new TQListViewItem( mList, indexToType( TUniversal ), str, "" );
00299 mList->setSelected( item, true );
00300 mKeyButton->setEnabled( false );
00301 if ( !mBlockChangeSignal )
00302 emit changed();
00303 }
00304 }
00305 }
00306
00307 void CustomTemplates::slotRemoveClicked()
00308 {
00309 if ( mCurrentItem ) {
00310 const TQString templateName = mCurrentItem->text( 1 );
00311 mItemsToDelete.append( templateName );
00312 CustomTemplateItem *vitem = mItemList.take( templateName );
00313 delete vitem;
00314 delete mCurrentItem;
00315 mCurrentItem = 0;
00316 if ( !mBlockChangeSignal )
00317 emit changed();
00318 }
00319 }
00320
00321 void CustomTemplates::slotListSelectionChanged()
00322 {
00323 if ( mCurrentItem ) {
00324 CustomTemplateItem *vitem = mItemList[ mCurrentItem->text( 1 ) ];
00325 if ( vitem ) {
00326 vitem->mContent = mEdit->text();
00327 vitem->mShortcut = mKeyButton->shortcut();
00328 }
00329 }
00330 TQListViewItem *item = mList->selectedItem();
00331 if ( item ) {
00332 mEditFrame->setEnabled( true );
00333 mCurrentItem = item;
00334 CustomTemplateItem *vitem = mItemList[ mCurrentItem->text( 1 ) ];
00335 if ( vitem ) {
00336
00337 mBlockChangeSignal = true;
00338 mEdit->setText( vitem->mContent );
00339 mKeyButton->setShortcut( vitem->mShortcut, false );
00340 mType->setCurrentItem( vitem->mType );
00341 mToEdit->setText( vitem->mTo );
00342 mCCEdit->setText( vitem->mCC );
00343 mBlockChangeSignal = false;
00344
00345 if ( vitem->mType == TUniversal )
00346 {
00347 mKeyButton->setEnabled( false );
00348 } else {
00349 mKeyButton->setEnabled( true );
00350 }
00351 setRecipientsEditsEnabled( vitem->mType == TForward ||
00352 vitem->mType == TUniversal );
00353 }
00354 } else {
00355 mEditFrame->setEnabled( false );
00356 mCurrentItem = 0;
00357 mEdit->clear();
00358 mToEdit->clear();
00359 mCCEdit->clear();
00360 mKeyButton->setShortcut( KShortcut::null(), false );
00361 mType->setCurrentItem( 0 );
00362 }
00363 }
00364
00365 void CustomTemplates::slotTypeActivated( int index )
00366 {
00367 if ( mCurrentItem ) {
00368
00369 CustomTemplateItem *vitem = mItemList[ mCurrentItem->text( 1 ) ];
00370 if ( !vitem ) {
00371 return;
00372 }
00373 vitem->mType = static_cast<Type>(index);
00374 switch ( vitem->mType ) {
00375 case TReply:
00376 mCurrentItem->setPixmap( 0, mReplyPix );
00377 break;
00378 case TReplyAll:
00379 mCurrentItem->setPixmap( 0, mReplyAllPix );
00380 break;
00381 case TForward:
00382 mCurrentItem->setPixmap( 0, mForwardPix );
00383 break;
00384 default:
00385 mCurrentItem->setPixmap( 0, TQPixmap() );
00386 break;
00387 };
00388 if ( index == TUniversal )
00389 {
00390 mKeyButton->setEnabled( false );
00391 } else {
00392 mKeyButton->setEnabled( true );
00393 }
00394
00395 setRecipientsEditsEnabled( vitem->mType == TForward ||
00396 vitem->mType == TUniversal );
00397 if ( !mBlockChangeSignal )
00398 emit changed();
00399 }
00400 else
00401 setRecipientsEditsEnabled( false );
00402 }
00403
00404 void CustomTemplates::slotShortcutCaptured( const KShortcut &shortcut )
00405 {
00406 KShortcut sc( shortcut );
00407 if ( sc == mKeyButton->shortcut() )
00408 return;
00409 if ( sc.isNull() || sc.toString().isEmpty() )
00410 sc.clear();
00411 bool assign = true;
00412 bool customused = false;
00413
00414 TQDictIterator<CustomTemplateItem> it(mItemList);
00415 for ( ; it.current() ; ++it ) {
00416 if ( !mCurrentItem || (*it)->mName != mCurrentItem->text( 1 ) )
00417 {
00418 if ( (*it)->mShortcut == sc )
00419 {
00420 TQString title( I18N_NOOP("Key Conflict") );
00421 TQString msg( I18N_NOOP("The selected shortcut is already used "
00422 "for another custom template, "
00423 "would you still like to continue with the assignment?" ) );
00424 assign = ( KMessageBox::warningYesNo( this, msg, title )
00425 == KMessageBox::Yes );
00426 if ( assign )
00427 {
00428 (*it)->mShortcut = KShortcut::null();
00429 }
00430 customused = true;
00431 }
00432 }
00433 }
00434
00435 if ( !customused && !sc.isNull() &&
00436 !( kmkernel->getKMMainWidget()->shortcutIsValid( sc ) ) ) {
00437 TQString title( I18N_NOOP("Key Conflict") );
00438 TQString msg( I18N_NOOP("The selected shortcut is already used, "
00439 "would you still like to continue with the assignment?" ) );
00440 assign = ( KMessageBox::warningYesNo( this, msg, title )
00441 == KMessageBox::Yes );
00442 }
00443 if ( assign ) {
00444 mKeyButton->setShortcut( sc, false );
00445 if ( !mBlockChangeSignal )
00446 emit changed();
00447 }
00448 }
00449
00450 #include "customtemplates.moc"