Git commit 3c31df07e12ef288e4b5f7484a2ccf52701da533 by Jonathan Marten. Committed on 04/01/2012 at 12:20. Pushed by marten into branch 'master'.
Improve appearance and operation of the IM address dialogue. Instead of editing in place with an item edit delegate, use a separate add/edit dialogue for the protocol and address. The item delegate is only used for showing the standard address in bold. Open the item editor dialogue on a double click, so those users who are accustomed to the double click to change will not be surprised. Eliminates the confusion when a user clicks on "Add" and then thinks "but I didn't ask for AIM, how do I change it?". BUG:244799 REVIEW:103620 GUI: M +1 -0 akonadi/contact/CMakeLists.txt M +4 -52 akonadi/contact/editor/im/imdelegate.cpp M +0 -2 akonadi/contact/editor/im/imdelegate.h M +53 -17 akonadi/contact/editor/im/imeditordialog.cpp M +2 -0 akonadi/contact/editor/im/imeditordialog.h A +84 -0 akonadi/contact/editor/im/imitemdialog.cpp [License: BSD] C +13 -20 akonadi/contact/editor/im/imitemdialog.h [from: akonadi/contact/editor/im/imeditordialog.h - 062% similarity] [License: UNKNOWN] * The files marked with a * at the end have a non valid license. Please read: http://techbase.kde.org/Policies/Licensing_Policy and use the headers which are listed at that page. http://commits.kde.org/kdepimlibs/3c31df07e12ef288e4b5f7484a2ccf52701da533 diff --git a/akonadi/contact/CMakeLists.txt b/akonadi/contact/CMakeLists.txt index 505031e..ae996c0 100644 --- a/akonadi/contact/CMakeLists.txt +++ b/akonadi/contact/CMakeLists.txt @@ -74,6 +74,7 @@ set(akonadicontact_editor_SRCS editor/im/imeditordialog.cpp editor/im/immodel.cpp editor/im/improtocols.cpp + editor/im/imitemdialog.cpp editor/imagewidget.cpp editor/imeditwidget.cpp editor/kdatepickerpopup.cpp diff --git a/akonadi/contact/editor/im/imdelegate.cpp b/akonadi/contact/editor/im/imdelegate.cpp index 5683022..c3c4fe8 100644 --- a/akonadi/contact/editor/im/imdelegate.cpp +++ b/akonadi/contact/editor/im/imdelegate.cpp @@ -22,11 +22,6 @@ #include "imdelegate.h" #include "immodel.h" -#include "improtocols.h" - -#include <kcombobox.h> -#include <kicon.h> -#include <klocale.h> IMDelegate::IMDelegate( QObject *parent ) : QStyledItemDelegate( parent ) @@ -39,59 +34,16 @@ IMDelegate::~IMDelegate() QWidget* IMDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &item, const QModelIndex &index ) const { - if ( index.column() == 0 ) { - KComboBox *comboBox = new KComboBox( parent ); - comboBox->setFrame( false ); - comboBox->setAutoFillBackground( true ); - - const QStringList protocols = IMProtocols::self()->protocols(); - foreach ( const QString &protocol, protocols ) { - comboBox->addItem( KIcon( IMProtocols::self()->icon( protocol ) ), - IMProtocols::self()->name( protocol ), - protocol ); - } - - return comboBox; - } else { - return QStyledItemDelegate::createEditor( parent, item, index ); - } -} - -void IMDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const -{ - if ( index.column() == 0 ) { - KComboBox *comboBox = qobject_cast<KComboBox*>( editor ); - if ( !comboBox ) - return; - - const QString protocol = index.data( IMModel::ProtocolRole ).toString(); - comboBox->setCurrentIndex( comboBox->findData( protocol ) ); - } else { - QStyledItemDelegate::setEditorData( editor, index ); - } -} - -void IMDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const -{ - if ( index.column() == 0 ) { - KComboBox *comboBox = qobject_cast<KComboBox*>( editor ); - if ( !comboBox ) - return; - - model->setData( index, comboBox->itemData( comboBox->currentIndex() ), IMModel::ProtocolRole ); - } else { - QStyledItemDelegate::setModelData( editor, model, index ); - } + return 0; } void IMDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const { + QStyleOptionViewItem newOption( option ); if ( index.data( IMModel::IsPreferredRole ).toBool() ) { - QStyleOptionViewItem newOption( option ); newOption.font.setBold( true ); + } - QStyledItemDelegate::paint( painter, newOption, index ); - } else - QStyledItemDelegate::paint( painter, option, index ); + QStyledItemDelegate::paint( painter, newOption, index ); } diff --git a/akonadi/contact/editor/im/imdelegate.h b/akonadi/contact/editor/im/imdelegate.h index 9337d9c..34419c8 100644 --- a/akonadi/contact/editor/im/imdelegate.h +++ b/akonadi/contact/editor/im/imdelegate.h @@ -32,8 +32,6 @@ class IMDelegate : public QStyledItemDelegate virtual QWidget* createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const; - virtual void setEditorData( QWidget *editor, const QModelIndex &index ) const; - virtual void setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const; virtual void paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const; }; diff --git a/akonadi/contact/editor/im/imeditordialog.cpp b/akonadi/contact/editor/im/imeditordialog.cpp index 75ca579..443582d 100644 --- a/akonadi/contact/editor/im/imeditordialog.cpp +++ b/akonadi/contact/editor/im/imeditordialog.cpp @@ -23,6 +23,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. #include "imeditordialog.h" #include "imdelegate.h" +#include "imitemdialog.h" #include <QtCore/QStringList> #include <QtGui/QGridLayout> @@ -44,25 +45,26 @@ IMEditorDialog::IMEditorDialog( QWidget *parent ) QGridLayout *layout = new QGridLayout( widget ); - mAddButton = new QPushButton( i18n( "Add" ) ); + mAddButton = new QPushButton( i18n( "Add..." ) ); + mEditButton = new QPushButton( i18n( "Edit..." ) ); mRemoveButton = new QPushButton( i18n( "Remove" ) ); mStandardButton = new QPushButton( i18n( "Set as Standard" ) ); mView = new QTreeView; mView->setRootIsDecorated( false ); - layout->addWidget( mView, 0, 0, 4, 1 ); + layout->addWidget( mView, 0, 0, 5, 1 ); layout->addWidget( mAddButton, 0, 1 ); - layout->addWidget( mRemoveButton, 1, 1 ); - layout->addWidget( mStandardButton, 2, 1 ); + layout->addWidget( mEditButton, 1, 1 ); + layout->addWidget( mRemoveButton, 2, 1 ); + layout->addWidget( mStandardButton, 3, 1 ); + layout->setRowStretch( 4, 1 ); connect( mAddButton, SIGNAL(clicked()), SLOT(slotAdd()) ); + connect( mEditButton, SIGNAL(clicked()), SLOT(slotEdit()) ); connect( mRemoveButton, SIGNAL(clicked()), SLOT(slotRemove()) ); connect( mStandardButton, SIGNAL(clicked()), SLOT(slotSetStandard()) ); - mRemoveButton->setEnabled( false ); - mStandardButton->setEnabled( false ); - mModel = new IMModel( this ); mView->setModel( mModel ); @@ -70,6 +72,9 @@ IMEditorDialog::IMEditorDialog( QWidget *parent ) connect( mView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(slotUpdateButtons()) ); + connect( mView, SIGNAL(doubleClicked(QModelIndex)), + this, SLOT(slotEdit()) ); + slotUpdateButtons(); } void IMEditorDialog::setAddresses( const IMAddress::List &addresses ) @@ -84,34 +89,62 @@ IMAddress::List IMEditorDialog::addresses() const void IMEditorDialog::slotAdd() { - mModel->insertRow( mModel->rowCount() ); + IMItemDialog d( this ); + d.setCaption( i18nc( "@window:title", "Add IM Address" ) ); + if ( d.exec() ) { + IMAddress newAddress = d.address(); + int addedRow = mModel->rowCount(); + mModel->insertRow( addedRow ); + + mModel->setData( mModel->index( addedRow, 0 ), newAddress.protocol(), IMModel::ProtocolRole ); + mModel->setData( mModel->index( addedRow, 1 ), newAddress.name(), Qt::EditRole ); + } +} + +void IMEditorDialog::slotEdit() +{ + const int currentRow = mView->currentIndex().row(); + if (currentRow<0) + return; + + IMItemDialog d( this ); + d.setCaption( i18nc( "@window:title", "Edit IM Address" ) ); + d.setAddress( mModel->addresses().at( currentRow )); + + if ( d.exec() ) { + IMAddress editedAddress = d.address(); + mModel->setData( mModel->index( currentRow, 0 ), editedAddress.protocol(), IMModel::ProtocolRole ); + mModel->setData( mModel->index( currentRow, 1 ), editedAddress.name(), Qt::EditRole ); + } } void IMEditorDialog::slotRemove() { - const QModelIndex currentIndex = mView->currentIndex(); - if ( !currentIndex.isValid() ) + const int currentRow = mView->currentIndex().row(); + if (currentRow<0) return; if ( KMessageBox::warningContinueCancel( this, - i18nc( "Instant messaging", "Do you really want to delete the selected address?" ), - i18n( "Confirm Delete" ), KStandardGuiItem::del() ) != KMessageBox::Continue ) { + i18nc( "Instant messaging", "Do you really want to delete the selected <resource>%1</resource> address?", + mModel->data( mModel->index( currentRow, 0 ), Qt::DisplayRole ).toString() ), + i18nc( "@window:title", "Confirm Delete" ), + KStandardGuiItem::del() ) != KMessageBox::Continue ) { return; } - mModel->removeRow( currentIndex.row() ); + mModel->removeRow( currentRow ); } void IMEditorDialog::slotSetStandard() { - const QModelIndex currentIndex = mView->currentIndex(); - if ( !currentIndex.isValid() ) + const int currentRow = mView->currentIndex().row(); + if ( currentRow < 0 ) return; // set current index as preferred and all other as non-preferred for ( int i = 0; i < mModel->rowCount(); ++i ) { const QModelIndex index = mModel->index( i, 0 ); - mModel->setData( index, (index.row() == currentIndex.row()), IMModel::IsPreferredRole ); + mModel->setData( index, (index.row() == currentRow), IMModel::IsPreferredRole ); } } @@ -120,7 +153,10 @@ void IMEditorDialog::slotUpdateButtons() const QModelIndex currentIndex = mView->currentIndex(); mRemoveButton->setEnabled( currentIndex.isValid() ); - mStandardButton->setEnabled( currentIndex.isValid() ); + mEditButton->setEnabled( currentIndex.isValid() ); + + mStandardButton->setEnabled( currentIndex.isValid() && + !mModel->data( currentIndex, IMModel::IsPreferredRole ).toBool() ); } #include "imeditordialog.moc" diff --git a/akonadi/contact/editor/im/imeditordialog.h b/akonadi/contact/editor/im/imeditordialog.h index 8bf69ea..c665e11 100644 --- a/akonadi/contact/editor/im/imeditordialog.h +++ b/akonadi/contact/editor/im/imeditordialog.h @@ -43,6 +43,7 @@ class IMEditorDialog : public KDialog private Q_SLOTS: void slotAdd(); + void slotEdit(); void slotRemove(); void slotSetStandard(); void slotUpdateButtons(); @@ -50,6 +51,7 @@ class IMEditorDialog : public KDialog private: QTreeView *mView; QPushButton *mAddButton; + QPushButton *mEditButton; QPushButton *mRemoveButton; QPushButton *mStandardButton; diff --git a/akonadi/contact/editor/im/imitemdialog.cpp b/akonadi/contact/editor/im/imitemdialog.cpp new file mode 100644 index 0000000..b8541c6 --- /dev/null +++ b/akonadi/contact/editor/im/imitemdialog.cpp @@ -0,0 +1,84 @@ +/* +IM address item editor widget for KDE PIM + +Copyright 2012 Jonathan Marten <jjm at keelhaul.me.uk> + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) version 3, or any +later version accepted by the membership of KDE e.V. (or its +successor approved by the membership of KDE e.V.), which shall +act as a proxy defined in Section 6 of version 3 of the license. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "imitemdialog.h" + +#include "immodel.h" +#include "improtocols.h" + +#include <QtGui/QComboBox> +#include <QtGui/QFormLayout> + +#include <klineedit.h> +#include <klocale.h> + +IMItemDialog::IMItemDialog( QWidget *parent ) + : KDialog( parent ) +{ + setButtons( Ok | Cancel ); + setDefaultButton( Ok ); + + QWidget *widget = new QWidget( this ); + setMainWidget( widget ); + + QFormLayout *layout = new QFormLayout( widget ); + + mProtocolCombo = new QComboBox; + mProtocolCombo->addItem( i18nc( "@item:inlistbox", "Select..." ) ); + layout->addRow( i18nc( "@label:listbox", "Protocol:" ), mProtocolCombo ); + + const QStringList protocols = IMProtocols::self()->protocols(); + foreach ( const QString &protocol, protocols ) { + mProtocolCombo->addItem( KIcon( IMProtocols::self()->icon( protocol ) ), + IMProtocols::self()->name( protocol ), + protocol ); + } + + mNameEdit = new KLineEdit; + layout->addRow( i18nc( "@label:textbox", "Address:" ), mNameEdit ); + + connect( mProtocolCombo, SIGNAL(currentIndexChanged(int)), SLOT(slotUpdateButtons()) ); + connect( mNameEdit, SIGNAL(textChanged(const QString &)), SLOT(slotUpdateButtons()) ); + + slotUpdateButtons(); +} + +void IMItemDialog::setAddress( const IMAddress &address ) +{ + mProtocolCombo->setCurrentIndex( IMProtocols::self()->protocols().indexOf( address.protocol()) + 1 ); + mNameEdit->setText( address.name() ); + slotUpdateButtons(); +} + +IMAddress IMItemDialog::address() const +{ + return IMAddress( mProtocolCombo->itemData( mProtocolCombo->currentIndex() ).toString(), + mNameEdit->text(), false ); +} + + +void IMItemDialog::slotUpdateButtons() +{ + enableButtonOk( mProtocolCombo->currentIndex()>0 && !mNameEdit->text().isEmpty() ); +} + +#include "imitemdialog.moc" diff --git a/akonadi/contact/editor/im/imeditordialog.h b/akonadi/contact/editor/im/imitemdialog.h similarity index 62% copy from akonadi/contact/editor/im/imeditordialog.h copy to akonadi/contact/editor/im/imitemdialog.h index 8bf69ea..7d9dcda 100644 --- a/akonadi/contact/editor/im/imeditordialog.h +++ b/akonadi/contact/editor/im/imitemdialog.h @@ -1,7 +1,7 @@ /* -IM address editor widget for KDE PIM +IM address item editor widget for KDE PIM -Copyright 2004,2010 Will Stephenson <wstephenson at kde.org> +Copyright 2012 Jonathan Marten <jjm at keelhaul.me.uk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -20,40 +20,33 @@ You should have received a copy of the GNU Lesser General Public License along with this library. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef IMEDITORDIALOG_H -#define IMEDITORDIALOG_H +#ifndef IMITEMDIALOG_H +#define IMITEMDIALOG_H #include <kdialog.h> #include "immodel.h" -class QPushButton; -class QTreeView; +class QComboBox; +class KLineEdit; -class IMEditorDialog : public KDialog +class IMItemDialog : public KDialog { Q_OBJECT public: - IMEditorDialog( QWidget *parent ); - ~IMEditorDialog() {} + IMItemDialog( QWidget *parent ); + ~IMItemDialog() {} - void setAddresses( const IMAddress::List &addresses ); - IMAddress::List addresses() const; + void setAddress(const IMAddress &address); + IMAddress address() const; private Q_SLOTS: - void slotAdd(); - void slotRemove(); - void slotSetStandard(); void slotUpdateButtons(); private: - QTreeView *mView; - QPushButton *mAddButton; - QPushButton *mRemoveButton; - QPushButton *mStandardButton; - - IMModel *mModel; + QComboBox *mProtocolCombo; + KLineEdit *mNameEdit; }; #endif
