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 <klocale.h>
00024 #include <kglobal.h>
00025 #include <qpopupmenu.h>
00026 #include <qpushbutton.h>
00027 #include <qtextedit.h>
00028 #include <qlineedit.h>
00029 #include <qtoolbox.h>
00030 #include <kdebug.h>
00031 #include <qfont.h>
00032 #include <kiconloader.h>
00033 #include <kpushbutton.h>
00034 #include <klistview.h>
00035 #include <klineedit.h>
00036 #include <qcombobox.h>
00037 #include <kshortcut.h>
00038 #include <kmessagebox.h>
00039 #include <kkeybutton.h>
00040 #include <kactivelabel.h>
00041
00042 #include "customtemplates_base.h"
00043 #include "customtemplates_kfg.h"
00044 #include "globalsettings.h"
00045 #include "kmkernel.h"
00046 #include "kmmainwidget.h"
00047
00048 #include "customtemplates.h"
00049
00050 CustomTemplates::CustomTemplates( QWidget *parent, const char *name )
00051 :CustomTemplatesBase( parent, name ), mCurrentItem( 0 )
00052 {
00053 QFont f = KGlobalSettings::fixedFont();
00054 mEdit->setFont( f );
00055
00056 mAdd->setIconSet( BarIconSet( "add", KIcon::SizeSmall ) );
00057 mRemove->setIconSet( BarIconSet( "remove", KIcon::SizeSmall ) );
00058
00059 mList->setColumnWidth( 0, 50 );
00060 mList->setColumnWidth( 1, 100 );
00061
00062 mEditFrame->setEnabled( false );
00063
00064 connect( mName, SIGNAL( textChanged ( const QString &) ),
00065 this, SLOT( slotNameChanged( const QString & ) ) );
00066 connect( mEdit, SIGNAL( textChanged() ),
00067 this, SLOT( slotTextChanged( void ) ) );
00068
00069 connect( mInsertCommand, SIGNAL( insertCommand(QString, int) ),
00070 this, SLOT( slotInsertCommand(QString, int) ) );
00071
00072 connect( mAdd, SIGNAL( clicked() ),
00073 this, SLOT( slotAddClicked() ) );
00074 connect( mRemove, SIGNAL( clicked() ),
00075 this, SLOT( slotRemoveClicked() ) );
00076 connect( mList, SIGNAL( selectionChanged() ),
00077 this, SLOT( slotListSelectionChanged() ) );
00078 connect( mType, SIGNAL( activated( int ) ),
00079 this, SLOT( slotTypeActivated( int ) ) );
00080
00081 connect( mKeyButton, SIGNAL( capturedShortcut( const KShortcut& ) ),
00082 this, SLOT( slotShortcutCaptured( const KShortcut& ) ) );
00083
00084 mReplyPix = KIconLoader().loadIcon( "mail_reply", KIcon::Small );
00085 mReplyAllPix = KIconLoader().loadIcon( "mail_replyall", KIcon::Small );
00086 mForwardPix = KIconLoader().loadIcon( "mail_forward", KIcon::Small );
00087
00088 mType->clear();
00089 mType->insertItem( QPixmap(), i18n( "Message->", "Universal" ), TUniversal );
00090 mType->insertItem( mReplyPix, i18n( "Message->", "Reply" ), TReply );
00091 mType->insertItem( mReplyAllPix, i18n( "Message->", "Reply to All" ), TReplyAll );
00092 mType->insertItem( mForwardPix, i18n( "Message->", "Forward" ), TForward );
00093
00094 QString help =
00095 i18n( "<qt>"
00096 "<p>Here you can add, edit, and delete custom message "
00097 "templates to use when you compose a reply or forwarding message. "
00098 "Create the custom template by selecting it using the right mouse "
00099 " button menu or toolbar menu. Also, you can bind a keyboard "
00100 "combination to the template for faster operations.</p>"
00101 "<p>Message templates support substitution commands "
00102 "by simple typing them or selecting them from menu "
00103 "<i>Insert command</i>.</p>"
00104 "<p>There are four types of custom templates: used to "
00105 "<i>Reply</i>, <i>Reply to All</i>, <i>Forward</i>, and "
00106 "<i>Universal</i> which can be used for all kind of operations. "
00107 "You cannot bind keyboard shortcut to <i>Universal</i> templates.</p>"
00108 "</qt>" );
00109 mHelp->setText( i18n( "<a href=\"whatsthis:%1\">How does this work?</a>" ).arg( help ) );
00110 slotNameChanged( mName->text() );
00111 }
00112
00113 CustomTemplates::~CustomTemplates()
00114 {
00115 QDictIterator<CustomTemplateItem> it(mItemList);
00116 for ( ; it.current() ; ++it ) {
00117 CustomTemplateItem *vitem = mItemList.take( it.currentKey() );
00118 if ( vitem ) {
00119 delete vitem;
00120 }
00121 }
00122 }
00123
00124 void CustomTemplates::slotNameChanged( const QString& text )
00125 {
00126 mAdd->setEnabled( !text.isEmpty() );
00127 }
00128
00129 QString CustomTemplates::indexToType( int index )
00130 {
00131 QString typeStr;
00132 switch ( index ) {
00133 case TUniversal:
00134
00135 break;
00136
00137
00138 case TReply:
00139 typeStr = i18n( "Message->", "Reply" ); break;
00140 case TReplyAll:
00141 typeStr = i18n( "Message->", "Reply to All" ); break;
00142 case TForward:
00143 typeStr = i18n( "Message->", "Forward" ); break;
00144 default:
00145 typeStr = i18n( "Message->", "Unknown" ); break;
00146 }
00147 return typeStr;
00148 }
00149
00150 void CustomTemplates::slotTextChanged()
00151 {
00152 emit changed();
00153 }
00154
00155 void CustomTemplates::load()
00156 {
00157 QStringList list = GlobalSettings::self()->customTemplates();
00158 for ( QStringList::iterator it = list.begin(); it != list.end(); ++it ) {
00159 CTemplates t(*it);
00160
00161 QString typeStr;
00162 KShortcut shortcut( t.shortcut() );
00163 CustomTemplateItem *vitem =
00164 new CustomTemplateItem( *it, t.content(),
00165 shortcut,
00166 static_cast<Type>( t.type() ) );
00167 mItemList.insert( *it, vitem );
00168 QListViewItem *item = new QListViewItem( mList, typeStr, *it, t.content() );
00169 switch ( t.type() ) {
00170 case TReply:
00171 item->setPixmap( 0, mReplyPix );
00172 break;
00173 case TReplyAll:
00174 item->setPixmap( 0, mReplyAllPix );
00175 break;
00176 case TForward:
00177 item->setPixmap( 0, mForwardPix );
00178 break;
00179 default:
00180 item->setPixmap( 0, QPixmap() );
00181 item->setText( 0, indexToType( t.type() ) );
00182 break;
00183 };
00184 }
00185 }
00186
00187 void CustomTemplates::save()
00188 {
00189 if ( mCurrentItem ) {
00190 CustomTemplateItem *vitem = mItemList[ mCurrentItem->text( 1 ) ];
00191 if ( vitem ) {
00192 vitem->mContent = mEdit->text();
00193 vitem->mShortcut = mKeyButton->shortcut();
00194 }
00195 }
00196 QStringList list;
00197 QListViewItemIterator lit( mList );
00198 while ( lit.current() ) {
00199 list.append( (*lit)->text( 1 ) );
00200 ++lit;
00201 }
00202 QDictIterator<CustomTemplateItem> it( mItemList );
00203 for ( ; it.current() ; ++it ) {
00204
00205 CTemplates t( (*it)->mName );
00206 QString &content = (*it)->mContent;
00207 if ( content.stripWhiteSpace().isEmpty() ) {
00208 content = "%BLANK";
00209 }
00210 t.setContent( content );
00211 t.setShortcut( (*it)->mShortcut.toString() );
00212 t.setType( (*it)->mType );
00213 t.writeConfig();
00214 }
00215 GlobalSettings::self()->setCustomTemplates( list );
00216 GlobalSettings::self()->writeConfig();
00217
00218
00219 if ( kmkernel->getKMMainWidget() )
00220 kmkernel->getKMMainWidget()->updateCustomTemplateMenus();
00221 }
00222
00223 void CustomTemplates::slotInsertCommand( QString cmd, int adjustCursor )
00224 {
00225 int para, index;
00226 mEdit->getCursorPosition( ¶, &index );
00227 mEdit->insertAt( cmd, para, index );
00228
00229 index += adjustCursor;
00230
00231 mEdit->setCursorPosition( para, index + cmd.length() );
00232 }
00233
00234 void CustomTemplates::slotAddClicked()
00235 {
00236 QString str = mName->text();
00237 if ( !str.isEmpty() ) {
00238 CustomTemplateItem *vitem = mItemList[ str ];
00239 if ( !vitem ) {
00240 vitem = new CustomTemplateItem( str, "", KShortcut::null(), TUniversal );
00241 mItemList.insert( str, vitem );
00242 QListViewItem *item =
00243 new QListViewItem( mList, indexToType( TUniversal ), str, "" );
00244 mList->setSelected( item, true );
00245 mKeyButton->setEnabled( false );
00246 emit changed();
00247 }
00248 }
00249 }
00250
00251 void CustomTemplates::slotRemoveClicked()
00252 {
00253 if ( mCurrentItem ) {
00254 CustomTemplateItem *vitem = mItemList.take( mCurrentItem->text( 1 ) );
00255 if ( vitem ) {
00256 delete vitem;
00257 }
00258 delete mCurrentItem;
00259 mCurrentItem = 0;
00260 emit changed();
00261 }
00262 }
00263
00264 void CustomTemplates::slotListSelectionChanged()
00265 {
00266 if ( mCurrentItem ) {
00267 CustomTemplateItem *vitem = mItemList[ mCurrentItem->text( 1 ) ];
00268 if ( vitem ) {
00269 vitem->mContent = mEdit->text();
00270 vitem->mShortcut = mKeyButton->shortcut();
00271 }
00272 }
00273 QListViewItem *item = mList->selectedItem();
00274 if ( item ) {
00275 mEditFrame->setEnabled( true );
00276 mCurrentItem = item;
00277 CustomTemplateItem *vitem = mItemList[ mCurrentItem->text( 1 ) ];
00278 if ( vitem ) {
00279
00280 disconnect( mEdit, SIGNAL( textChanged() ),
00281 this, SLOT( slotTextChanged( void ) ) );
00282
00283 mEdit->setText( vitem->mContent );
00284 mKeyButton->setShortcut( vitem->mShortcut, false );
00285 mType->setCurrentItem( vitem->mType );
00286
00287 connect( mEdit, SIGNAL( textChanged() ),
00288 this, SLOT( slotTextChanged( void ) ) );
00289
00290 if ( vitem->mType == TUniversal )
00291 {
00292 mKeyButton->setEnabled( false );
00293 } else {
00294 mKeyButton->setEnabled( true );
00295 }
00296 }
00297 } else {
00298 mEditFrame->setEnabled( false );
00299 mCurrentItem = 0;
00300 mEdit->clear();
00301 mKeyButton->setShortcut( KShortcut::null(), false );
00302 mType->setCurrentItem( 0 );
00303 }
00304 }
00305
00306 void CustomTemplates::slotTypeActivated( int index )
00307 {
00308 if ( mCurrentItem ) {
00309
00310 CustomTemplateItem *vitem = mItemList[ mCurrentItem->text( 1 ) ];
00311 if ( !vitem ) {
00312 return;
00313 }
00314 vitem->mType = static_cast<Type>(index);
00315 switch ( vitem->mType ) {
00316 case TReply:
00317 mCurrentItem->setPixmap( 0, mReplyPix );
00318 break;
00319 case TReplyAll:
00320 mCurrentItem->setPixmap( 0, mReplyAllPix );
00321 break;
00322 case TForward:
00323 mCurrentItem->setPixmap( 0, mForwardPix );
00324 break;
00325 default:
00326 mCurrentItem->setPixmap( 0, QPixmap() );
00327 break;
00328 };
00329 if ( index == TUniversal )
00330 {
00331 mKeyButton->setEnabled( false );
00332 } else {
00333 mKeyButton->setEnabled( true );
00334 }
00335 emit changed();
00336 }
00337 }
00338
00339 void CustomTemplates::slotShortcutCaptured( const KShortcut &shortcut )
00340 {
00341 KShortcut sc( shortcut );
00342 if ( sc == mKeyButton->shortcut() )
00343 return;
00344 if ( sc.isNull() || sc.toString().isEmpty() )
00345 sc.clear();
00346 bool assign = true;
00347 bool customused = false;
00348
00349 QDictIterator<CustomTemplateItem> it(mItemList);
00350 for ( ; it.current() ; ++it ) {
00351 if ( !mCurrentItem || (*it)->mName != mCurrentItem->text( 1 ) )
00352 {
00353 if ( (*it)->mShortcut == sc )
00354 {
00355 QString title( I18N_NOOP("Key Conflict") );
00356 QString msg( I18N_NOOP("The selected shortcut is already used "
00357 "for another custom template, "
00358 "would you still like to continue with the assignment?" ) );
00359 assign = ( KMessageBox::warningYesNo( this, msg, title )
00360 == KMessageBox::Yes );
00361 if ( assign )
00362 {
00363 (*it)->mShortcut = KShortcut::null();
00364 }
00365 customused = true;
00366 }
00367 }
00368 }
00369
00370 if ( !customused && !sc.isNull() &&
00371 !( kmkernel->getKMMainWidget()->shortcutIsValid( sc ) ) ) {
00372 QString title( I18N_NOOP("Key Conflict") );
00373 QString msg( I18N_NOOP("The selected shortcut is already used, "
00374 "would you still like to continue with the assignment?" ) );
00375 assign = ( KMessageBox::warningYesNo( this, msg, title )
00376 == KMessageBox::Yes );
00377 }
00378 if ( assign ) {
00379 mKeyButton->setShortcut( sc, false );
00380 emit changed();
00381 }
00382 }
00383
00384 #include "customtemplates.moc"