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.
 
 
 

355 lines
10 KiB

/******************************************************************************
*
* Copyright 2008 Szymon Tomasz Stefanek <pragma@kvirc.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.
*
* 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.
*
*******************************************************************************/
#include "messagelistview/core/configureaggregationsdialog.h"
#include "messagelistview/core/aggregationeditor.h"
#include "messagelistview/core/aggregation.h"
#include "messagelistview/core/manager.h"
#include <QGridLayout>
#include <QPushButton>
#include <QFrame>
#include <QHash>
#include <KLocale>
#include <KIconLoader>
#include <KMessageBox>
namespace KMail
{
namespace MessageListView
{
namespace Core
{
class AggregationListWidgetItem : public QListWidgetItem
{
private:
Aggregation * mAggregation;
public:
AggregationListWidgetItem( QListWidget * par, const Aggregation &set )
: QListWidgetItem( set.name(), par )
{
mAggregation = new Aggregation( set );
}
~AggregationListWidgetItem()
{
delete mAggregation;
}
public:
Aggregation * aggregation() const
{ return mAggregation; };
void forgetAggregation()
{ mAggregation = 0; };
};
ConfigureAggregationsDialog * ConfigureAggregationsDialog::mInstance = 0;
ConfigureAggregationsDialog::ConfigureAggregationsDialog( QWidget *parent )
: KDialog( parent )
{
mInstance = this;
setAttribute( Qt::WA_DeleteOnClose );
setWindowModality( Qt::ApplicationModal ); // FIXME: Sure ?
setButtons( Ok | Cancel );
setWindowTitle( i18n( "Customize Message Aggregation Modes" ) );
QWidget * base = new QWidget( this );
setMainWidget( base );
QGridLayout * g = new QGridLayout( base );
mAggregationList = new AggregationListWidget( base );
mAggregationList->setSortingEnabled( true );
g->addWidget( mAggregationList, 0, 0, 5, 1 );
connect( mAggregationList, SIGNAL( currentItemChanged( QListWidgetItem *, QListWidgetItem * ) ),
SLOT( aggregationListCurrentItemChanged( QListWidgetItem *, QListWidgetItem * ) ) );
mNewAggregationButton = new QPushButton( i18n( "New Aggregation" ), base );
mNewAggregationButton->setIcon( KIcon( "document-new" ) );
mNewAggregationButton->setIconSize( QSize( KIconLoader::SizeSmall, KIconLoader::SizeSmall ) );
g->addWidget( mNewAggregationButton, 0, 1 );
connect( mNewAggregationButton, SIGNAL( clicked() ),
SLOT( newAggregationButtonClicked() ) );
mCloneAggregationButton = new QPushButton( i18n( "Clone Aggregation" ), base );
mCloneAggregationButton->setIcon( KIcon( "edit-copy" ) );
mCloneAggregationButton->setIconSize( QSize( KIconLoader::SizeSmall, KIconLoader::SizeSmall ) );
g->addWidget( mCloneAggregationButton, 1, 1 );
connect( mCloneAggregationButton, SIGNAL( clicked() ),
SLOT( cloneAggregationButtonClicked() ) );
QFrame * f = new QFrame( base );
f->setFrameStyle( QFrame::Sunken | QFrame::HLine );
f->setMinimumHeight( 24 );
g->addWidget( f, 2, 1, Qt::AlignVCenter );
mDeleteAggregationButton = new QPushButton( i18n( "Delete Aggregation" ), base );
mDeleteAggregationButton->setIcon( KIcon( "edit-delete" ) );
mDeleteAggregationButton->setIconSize( QSize( KIconLoader::SizeSmall, KIconLoader::SizeSmall ) );
g->addWidget( mDeleteAggregationButton, 3, 1 );
connect( mDeleteAggregationButton, SIGNAL( clicked() ),
SLOT( deleteAggregationButtonClicked() ) );
mEditor = new AggregationEditor( base );
g->addWidget( mEditor, 5, 0, 1, 2 );
connect( mEditor, SIGNAL( aggregationNameChanged() ),
SLOT( editedAggregationNameChanged() ) );
g->setColumnStretch( 0, 1 );
g->setRowStretch( 4, 1 );
connect( this, SIGNAL( okClicked() ),
SLOT( okButtonClicked() ) );
fillAggregationList();
}
ConfigureAggregationsDialog::~ConfigureAggregationsDialog()
{
mInstance = 0;
}
void ConfigureAggregationsDialog::display( QWidget *parent, const QString &preselectAggregationId )
{
if ( mInstance )
return; // FIXME: reparent if needed ?
mInstance = new ConfigureAggregationsDialog( parent );
mInstance->selectAggregationById( preselectAggregationId );
mInstance->show();
}
void ConfigureAggregationsDialog::cleanup()
{
if ( !mInstance )
return;
delete mInstance;
mInstance = 0;
}
void ConfigureAggregationsDialog::selectAggregationById( const QString &aggregationId )
{
AggregationListWidgetItem * item = findAggregationItemById( aggregationId );
if ( !item )
return;
mAggregationList->setCurrentItem( item );
}
void ConfigureAggregationsDialog::okButtonClicked()
{
commitEditor();
Manager::instance()->removeAllAggregations();
int c = mAggregationList->count();
int i = 0;
while ( i < c )
{
AggregationListWidgetItem * item = dynamic_cast< AggregationListWidgetItem * >( mAggregationList->item( i ) );
if ( item )
{
Manager::instance()->addAggregation( item->aggregation() );
item->forgetAggregation();
}
i++;
}
Manager::instance()->aggregationsConfigurationCompleted();
close(); // this will delete too
}
void ConfigureAggregationsDialog::commitEditor()
{
Aggregation * editedAggregation = mEditor->editedAggregation();
if ( !editedAggregation )
return;
mEditor->commit();
AggregationListWidgetItem * editedItem = findAggregationItemByAggregation( editedAggregation );
if ( editedItem )
return;
QString goodName = uniqueNameForAggregation( editedAggregation->name(), editedAggregation );
editedAggregation->setName( goodName );
editedItem->setText( goodName );
}
void ConfigureAggregationsDialog::editedAggregationNameChanged()
{
Aggregation * set = mEditor->editedAggregation();
if ( !set )
return;
AggregationListWidgetItem * it = findAggregationItemByAggregation( set );
if ( !it )
return;
QString goodName = uniqueNameForAggregation( set->name(), set );
it->setText( goodName );
}
void ConfigureAggregationsDialog::fillAggregationList()
{
const QHash< QString, Aggregation * > & sets = Manager::instance()->aggregations();
for( QHash< QString, Aggregation * >::ConstIterator it = sets.begin(); it != sets.end(); ++it )
(void)new AggregationListWidgetItem( mAggregationList, *( *it ) );
}
void ConfigureAggregationsDialog::aggregationListCurrentItemChanged( QListWidgetItem * cur, QListWidgetItem * )
{
commitEditor();
AggregationListWidgetItem * item = cur ? dynamic_cast< AggregationListWidgetItem * >( cur ) : 0;
mDeleteAggregationButton->setEnabled( item && ( mAggregationList->count() > 1 ) );
mCloneAggregationButton->setEnabled( item );
mEditor->editAggregation( item ? item->aggregation() : 0 );
if ( item && !item->isSelected() )
item->setSelected( true ); // make sure it's true
}
AggregationListWidgetItem * ConfigureAggregationsDialog::findAggregationItemByName( const QString &name, Aggregation * skipAggregation )
{
int c = mAggregationList->count();
int i = 0;
while ( i < c )
{
AggregationListWidgetItem * item = dynamic_cast< AggregationListWidgetItem * >( mAggregationList->item( i ) );
if ( item )
{
if ( item->aggregation() != skipAggregation )
{
if ( item->aggregation()->name() == name )
return item;
}
}
i++;
}
return 0;
}
AggregationListWidgetItem * ConfigureAggregationsDialog::findAggregationItemById( const QString &aggregationId )
{
int c = mAggregationList->count();
int i = 0;
while ( i < c )
{
AggregationListWidgetItem * item = dynamic_cast< AggregationListWidgetItem * >( mAggregationList->item( i ) );
if ( item )
{
if ( item->aggregation()->id() == aggregationId )
return item;
}
i++;
}
return 0;
}
AggregationListWidgetItem * ConfigureAggregationsDialog::findAggregationItemByAggregation( Aggregation * set )
{
int c = mAggregationList->count();
int i = 0;
while ( i < c )
{
AggregationListWidgetItem * item = dynamic_cast< AggregationListWidgetItem * >( mAggregationList->item( i ) );
if ( item )
{
if ( item->aggregation() == set )
return item;
}
i++;
}
return 0;
}
QString ConfigureAggregationsDialog::uniqueNameForAggregation( QString baseName, Aggregation * skipAggregation )
{
QString ret = baseName;
if( ret.isEmpty() )
ret = i18n( "Unnamed Aggregation" );
int idx = 1;
AggregationListWidgetItem * item = findAggregationItemByName( ret, skipAggregation );
while ( item )
{
idx++;
ret = QString("%1 %2").arg( baseName ).arg( idx );
item = findAggregationItemByName( ret, skipAggregation );
}
return ret;
}
void ConfigureAggregationsDialog::newAggregationButtonClicked()
{
Aggregation emptyAggregation;
emptyAggregation.setName( uniqueNameForAggregation( i18n( "New Aggregation" ) ) );
AggregationListWidgetItem * item = new AggregationListWidgetItem( mAggregationList, emptyAggregation );
mAggregationList->setCurrentItem( item );
}
void ConfigureAggregationsDialog::cloneAggregationButtonClicked()
{
AggregationListWidgetItem * item = dynamic_cast< AggregationListWidgetItem * >( mAggregationList->currentItem() );
if ( !item )
return;
Aggregation copyAggregation( *( item->aggregation() ) );
copyAggregation.generateUniqueId(); // regenerate id so it becomes different
copyAggregation.setName( uniqueNameForAggregation( item->aggregation()->name() ) );
item = new AggregationListWidgetItem( mAggregationList, copyAggregation );
mAggregationList->setCurrentItem( item );
}
void ConfigureAggregationsDialog::deleteAggregationButtonClicked()
{
AggregationListWidgetItem * item = dynamic_cast< AggregationListWidgetItem * >( mAggregationList->currentItem() );
if ( !item )
return;
if ( mAggregationList->count() < 2 )
return; // no way: desperately try to keep at least one option set alive :)
mEditor->editAggregation( 0 ); // forget it
delete item; // this will trigger aggregationListCurrentItemChanged()
}
} // namespace Core
} // namespace MessageListView
} // namespace KMail