From 460c52653ab0dcca6f19a4f492ed2c5e4e963ab0 Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kaddressbook/editors/imeditorwidget.cpp | 491 ++++++++++++++++++++++++++++++++ 1 file changed, 491 insertions(+) create mode 100644 kaddressbook/editors/imeditorwidget.cpp (limited to 'kaddressbook/editors/imeditorwidget.cpp') diff --git a/kaddressbook/editors/imeditorwidget.cpp b/kaddressbook/editors/imeditorwidget.cpp new file mode 100644 index 000000000..f61e06386 --- /dev/null +++ b/kaddressbook/editors/imeditorwidget.cpp @@ -0,0 +1,491 @@ +/* + IM address editor widget for KAddressBook + + Copyright (c) 2004 Will Stephenson + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "imaddresswidget.h" +#include "imeditorbase.h" +#include "imeditorwidget.h" + + +IMAddressLVI::IMAddressLVI( KListView *parent, KPluginInfo *protocol, + const QString &address, const IMContext &context ) + : KListViewItem( parent ) +{ + setProtocol( protocol ); + setAddress( address ); + setContext( context ); + mPreferred = false; +} + +void IMAddressLVI::setPreferred( bool preferred ) +{ + mPreferred = preferred; +} + +bool IMAddressLVI::preferred() const +{ + return mPreferred; +} + +void IMAddressLVI::paintCell( QPainter *p, const QColorGroup &cg, + int column, int width, int alignment ) +{ + if ( mPreferred ) { + QFont font = p->font(); + font.setBold( true ); + p->setFont( font ); + } + + KListViewItem::paintCell( p, cg, column, width, alignment ); +} + +void IMAddressLVI::setAddress( const QString &address ) +{ + // irc uses 0xE120 to seperate the nick and the server group. + QString serverOrGroup = address.section( QChar( 0xE120 ), 1 ); + + if ( serverOrGroup.isEmpty() ) + setText( 1, address ); + else { + QString nickname = address.section( QChar( 0xE120 ), 0, 0 ); + setText( 1, i18n( " on ","%1 on %2" ) + .arg( nickname ).arg( serverOrGroup ) ); + } + + mAddress = address; +} + +void IMAddressLVI::setContext( const IMContext &context ) +{ + mContext = context; + // set context +/* switch ( context ) + { + case Home: + setText( 2, i18n( "Home" ) ); + break; + case Work: + setText( 2, i18n( "Work" ) ); + break; + case Any: + setText( 2, i18n( "Any" ) ); + break; + } +*/ +} + +void IMAddressLVI::setProtocol( KPluginInfo *protocol ) +{ + mProtocol = protocol; + + setPixmap( 0, SmallIcon( mProtocol->icon() ) ); + setText( 0, mProtocol->name() ); +} + +KPluginInfo * IMAddressLVI::protocol() const +{ + return mProtocol; +} + +IMContext IMAddressLVI::context() const +{ + return mContext; +} + +QString IMAddressLVI::address() const +{ + return mAddress; +} + +void IMAddressLVI::activate() +{ + // show editor +} + +/*===========================================================================*/ + +IMEditorWidget::IMEditorWidget( QWidget *parent, const QString &preferredIM, const char *name ) + : KDialogBase( parent, name, false, i18n( "Edit Instant Messenging Address" ), + Help | Ok | Cancel, Ok, false ), + mReadOnly( false ) +{ + mWidget = new IMEditorBase( this ); + setMainWidget( mWidget ); + + connect( mWidget->btnAdd, SIGNAL( clicked() ), SLOT( slotAdd() ) ); + connect( mWidget->btnEdit, SIGNAL( clicked() ), SLOT( slotEdit() ) ); + connect( mWidget->btnDelete, SIGNAL( clicked() ), SLOT( slotDelete() ) ); + connect( mWidget->btnSetStandard, SIGNAL( clicked()), SLOT( slotSetStandard() ) ); + connect( mWidget->lvAddresses, SIGNAL( selectionChanged() ), SLOT( slotUpdateButtons() ) ); + + connect( mWidget->lvAddresses, SIGNAL( doubleClicked( QListViewItem*, const QPoint&, int ) ), + SLOT( slotEdit() ) ); + + setHelp( "managing-contacts-im-addresses" ); + + mWidget->btnEdit->setEnabled( false ); + mWidget->btnDelete->setEnabled( false ); + mWidget->btnSetStandard->setEnabled( false ); + // Disabled pending implementation + //mWidget->btnUp->setEnabled( false ); + //mWidget->btnDown->setEnabled( false ); + mPreferred = preferredIM; + mPreferred = mPreferred.replace( " on ", QString( QChar( 0xE120 ) ), true ); + mProtocols = KPluginInfo::fromServices( KTrader::self()->query( QString::fromLatin1( "KABC/IMProtocol" ) ) ); + + // order the protocols by putting them in a qmap, then sorting the set of keys and recreating the list + QMap protocolMap; + QValueList::ConstIterator it; + QValueList sorted; + for ( it = mProtocols.begin(); it != mProtocols.end(); ++it ) + protocolMap.insert( (*it)->name(), (*it) ); + + QStringList keys = protocolMap.keys(); + keys.sort(); + QStringList::ConstIterator keyIt = keys.begin(); + QStringList::ConstIterator end = keys.end(); + for ( ; keyIt != end; ++keyIt ) + sorted.append( protocolMap[*keyIt] ); + mProtocols = sorted; +} + +QValueList IMEditorWidget::availableProtocols() const +{ + return mProtocols; +} + +void IMEditorWidget::loadContact( KABC::Addressee *addr ) +{ + if ( mWidget->lvAddresses ) + mWidget->lvAddresses->clear(); + + // see README for details of how Evolution stores IM addresses (differently) + const QStringList customs = addr->customs(); + + QStringList::ConstIterator it; + bool isSet = false; + for ( it = customs.begin(); it != customs.end(); ++it ) { + QString app, name, value; + splitField( *it, app, name, value ); + + if ( app.startsWith( QString::fromLatin1( "messaging/" ) ) ) { + if ( name == QString::fromLatin1( "All" ) ) { + KPluginInfo *protocol = protocolFromString( app ); + if ( protocol ) { + QStringList addresses = QStringList::split( QChar( 0xE000 ), value ); + QStringList::iterator end = addresses.end(); + for ( QStringList::ConstIterator it = addresses.begin(); it != end; ++it ) { + IMAddressLVI *imaddresslvi = new IMAddressLVI( mWidget->lvAddresses, protocol, *it, Any/*, false*/ ); + if ( !isSet && (*it).stripWhiteSpace().lower() == mPreferred.stripWhiteSpace().lower() ) { + imaddresslvi->setPreferred( true ); + isSet = true; //Only set one item to be preferred + } + } + } else + kdDebug( 5720 ) << k_funcinfo << " no protocol found for: " << app << endl; + } + } + } + + if ( mWidget->lvAddresses->firstChild() ) + mWidget->lvAddresses->firstChild()->setSelected( true ); +} + +void IMEditorWidget::storeContact( KABC::Addressee *addr ) +{ + // for each changed protocol, write a new custom field containing the current set of + // addresses + QValueList::ConstIterator protocolIt; + for ( protocolIt = mChangedProtocols.begin(); protocolIt != mChangedProtocols.end(); ++protocolIt ) { + QStringList lst; + QListViewItemIterator addressIt( mWidget->lvAddresses ); + while ( addressIt.current() ) { + IMAddressLVI* currentAddress = static_cast( *addressIt ); + if ( currentAddress->protocol() == *protocolIt ) + lst.append( currentAddress->address() ); + ++addressIt; + } + + QString addrBookField = (*protocolIt)->property( "X-KDE-InstantMessagingKABCField" ).toString(); + if ( !lst.isEmpty() ) + addr->insertCustom( addrBookField, QString::fromLatin1( "All" ), lst.join( QChar( 0xE000 ) ) ); + else + addr->removeCustom( addrBookField, QString::fromLatin1( "All" ) ); + } +} + +void IMEditorWidget::setReadOnly( bool readOnly ) +{ + mReadOnly = readOnly; + slotUpdateButtons(); +} + +void IMEditorWidget::slotSetStandard() +{ + QListViewItemIterator it( mWidget->lvAddresses, QListViewItemIterator::Selected ); + + // Just set the first one selected as standard + if ( IMAddressLVI *current = static_cast( it.current() ) ) { + QListViewItemIterator it2( mWidget->lvAddresses ); + while ( it2.current() ) { + IMAddressLVI *item = static_cast( it2.current() ); + + if ( item->preferred() ) { + if ( current == item ) + return; //Selected is already preferred + else { + item->setPreferred( false ); + mWidget->lvAddresses->repaintItem( item ); + break; + } + } + + ++it2; + } + + mPreferred = current->address(); + current->setPreferred( true ); + setModified( true ); + mWidget->lvAddresses->repaintItem( current ); + } +} + +void IMEditorWidget::slotUpdateButtons() +{ + int num_selected = 0; + QListViewItemIterator it( mWidget->lvAddresses, QListViewItemIterator::Selected ); + while ( it.current() ) { + ++num_selected; + if ( num_selected > 1 ) + break; //no need to count above 2. + + ++it; + } + + if ( !mReadOnly && num_selected == 1 ) { + mWidget->btnAdd->setEnabled( true ); + mWidget->btnEdit->setEnabled( true ); + mWidget->btnDelete->setEnabled( true ); + IMAddressLVI *current = static_cast( it.current() ); + + // Disable "set standard" if already standard + mWidget->btnSetStandard->setEnabled( !current || !current->preferred() ); + } else if ( !mReadOnly && num_selected > 1 ) { + mWidget->btnAdd->setEnabled( true ); + mWidget->btnEdit->setEnabled( false ); + mWidget->btnDelete->setEnabled( true ); + mWidget->btnSetStandard->setEnabled( false ); + } else { + mWidget->btnAdd->setEnabled( !mReadOnly ); + mWidget->btnSetStandard->setEnabled( false ); + mWidget->btnEdit->setEnabled( false ); + mWidget->btnDelete->setEnabled( false ); + } +} + +void IMEditorWidget::setModified( bool modified ) +{ + mModified = modified; +} + +bool IMEditorWidget::isModified() const +{ + return mModified; +} + +void IMEditorWidget::slotAdd() +{ + KDialogBase addDialog( this, "addaddress", true, i18n( "Instant messaging", "Add Address" ), + KDialogBase::Ok | KDialogBase::Cancel ); + + IMAddressWidget *addressWid = new IMAddressWidget( &addDialog, mProtocols ); + addDialog.enableButtonOK( false ); + connect( addressWid, SIGNAL( inValidState( bool ) ), + &addDialog, SLOT( enableButtonOK( bool ) ) ); + addDialog.setMainWidget( addressWid ); + + if ( addDialog.exec() == QDialog::Accepted ) { + // add the new item + IMAddressLVI *imaddresslvi = new IMAddressLVI( mWidget->lvAddresses, addressWid->protocol(), + addressWid->address() /*, addressWid->context() */ ); + + // If it's a new address, set is as preferred. + if ( mPreferred.isEmpty() ) { + imaddresslvi->setPreferred( true ); + mPreferred = addressWid->address(); + } + + if ( mChangedProtocols.find( addressWid->protocol() ) == mChangedProtocols.end() ) + mChangedProtocols.append( addressWid->protocol() ); + + mWidget->lvAddresses->sort(); + + setModified( true ); + } +} + +void IMEditorWidget::slotEdit() +{ + QListViewItemIterator it( mWidget->lvAddresses, QListViewItemIterator::Selected ); + + // Just edit the first one selected. + if ( IMAddressLVI *current = static_cast( it.current() ) ) { + KDialogBase editDialog( this, "editaddress", true, i18n( "Instant messaging", "Edit Address" ), + KDialogBase::Ok | KDialogBase::Cancel ); + IMAddressWidget *addressWid = new IMAddressWidget( &editDialog, mProtocols, current->protocol(), + current->address(), current->context() ) ; + connect( addressWid, SIGNAL( inValidState( bool ) ), + &editDialog, SLOT( enableButtonOK( bool ) ) ); + editDialog.setMainWidget( addressWid ); + + if ( editDialog.exec() == QDialog::Accepted ) { + bool modified = false; + if ( addressWid->address() != current->address() ) { + modified = true; + current->setAddress( addressWid->address() ); + } + if ( addressWid->context() != current->context() ) { + modified = true; + current->setContext( addressWid->context() ); + } + + // the entry for the protocol of the current address has changed + if ( mChangedProtocols.find( current->protocol() ) == mChangedProtocols.end() ) { + mChangedProtocols.append( current->protocol() ); + } + // update protocol - has another protocol gained an address? + if ( current->protocol() != addressWid->protocol() ) { + modified = true; + // this proto is losing an entry + current->setProtocol( addressWid->protocol() ); + if ( mChangedProtocols.find( current->protocol() ) == mChangedProtocols.end() ) + mChangedProtocols.append( current->protocol() ); + } + + if ( modified ) + setModified(true); + } + } +} + +void IMEditorWidget::slotDelete() +{ + int num_selected = 0; + + { + QListViewItemIterator it( mWidget->lvAddresses, QListViewItemIterator::Selected ); + while ( it.current() ) { + num_selected++; + ++it; + } + } + + if ( num_selected == 0 ) + return; + + if ( KMessageBox::warningContinueCancel( this, i18n( "Do you really want to delete the selected address?", + "Do you really want to delete the %n selected addresses?", num_selected ), + i18n( "Confirm Delete" ), KStdGuiItem::del() ) != KMessageBox::Continue ) + return; + + QListViewItemIterator it( mWidget->lvAddresses ); + bool deletedPreferred = false; + while( it.current() ) { + if ( it.current()->isSelected() ) { + IMAddressLVI * current = static_cast( *it ); + if ( mChangedProtocols.find( current->protocol() ) == mChangedProtocols.end() ) + mChangedProtocols.append( current->protocol() ); + + if ( current->preferred() ) + deletedPreferred = true; + + delete current; + } else + ++it; + } + + if ( deletedPreferred ) { + IMAddressLVI *first = static_cast( mWidget->lvAddresses->firstChild() ); + if ( first ) { + first->setPreferred( true ); + mPreferred = first->address(); + } else + mPreferred = ""; + } + + setModified( true ); +} + +QString IMEditorWidget::preferred() const +{ + QString retval( mPreferred ); + return retval.replace( QChar( 0xE120 ), " on " ); +} + + +KPluginInfo * IMEditorWidget::protocolFromString( const QString &fieldValue ) const +{ + QValueList::ConstIterator it; + KPluginInfo * protocol = 0; + for ( it = mProtocols.begin(); it != mProtocols.end(); ++it ) { + if ( (*it)->property( "X-KDE-InstantMessagingKABCField" ).toString() == fieldValue ) { + protocol = *it; + break; + } + } + + return protocol; +} + +void IMEditorWidget::splitField( const QString &str, QString &app, QString &name, QString &value ) +{ + int colon = str.find( ':' ); + if ( colon != -1 ) { + QString tmp = str.left( colon ); + value = str.mid( colon + 1 ); + + int dash = tmp.find( '-' ); + if ( dash != -1 ) { + app = tmp.left( dash ); + name = tmp.mid( dash + 1 ); + } + } +} + +#include "imeditorwidget.moc" -- cgit v1.2.1