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.
krecipes/krecipes/src/widgets/unitlistview.cpp

370 lines
11 KiB

/***************************************************************************
* Copyright (C) 2004 by *
* Jason Kivlighn (jkivlighn@gmail.com) *
* Unai Garro (ugarro@users.sourceforge.net) *
* Cyril Bosselut (bosselut@b1project.com) *
* *
* Copyright (C) 2006 Jason Kivlighn (jkivlighn@gmail.com) *
* *
* 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. *
***************************************************************************/
#include "unitlistview.h"
#include <ntqcombobox.h>
#include <ntqheader.h>
#include <tdemessagebox.h>
#include <tdeconfig.h>
#include <tdelocale.h>
#include <tdeglobal.h>
#include <kiconloader.h>
#include <tdepopupmenu.h>
#include <kdebug.h>
#include "backends/recipedb.h"
#include "dialogs/createunitdialog.h"
#include "dialogs/dependanciesdialog.h"
#include "datablocks/unit.h"
class UnitListViewItem : public TQListViewItem
{
public:
UnitListViewItem( TQListView* qlv, const Unit &u ) : TQListViewItem( qlv ), m_unit(u)
{
updateType(m_unit.type);
}
virtual TQString text( int column ) const
{
switch ( column ) {
case 0: return m_unit.name;
case 1: return m_unit.name_abbrev;
case 2: return m_unit.plural;
case 3: return m_unit.plural_abbrev;
case 4: return m_type;
case 5: return TQString::number(m_unit.id);
default: return TQString::null;
}
}
void setType( Unit::Type type ){ m_unit.type = type; updateType(type); }
Unit unit() const { return m_unit; };
void setUnit( const Unit &u ) { m_unit = u; }
protected:
virtual void setText( int column, const TQString &text ) {
switch ( column ) {
case 0: m_unit.name = text; break;
case 1: m_unit.name_abbrev = text; break;
case 2: m_unit.plural = text; break;
case 3: m_unit.plural_abbrev = text; break;
}
}
private:
void updateType( Unit::Type t ) {
switch ( t ) {
case Unit::Other: m_type = i18n("Other"); break;
case Unit::Mass: m_type = i18n("Mass"); break;
case Unit::Volume: m_type = i18n("Volume"); break;
default: break;
}
}
Unit m_unit;
TQString m_type;
};
UnitListView::UnitListView( TQWidget *parent, RecipeDB *db ) : DBListViewBase( parent,db,db->unitCount() )
{
setAllColumnsShowFocus( true );
setDefaultRenameAction( TQListView::Reject );
}
void UnitListView::init()
{
connect( database, TQ_SIGNAL( unitCreated( const Unit & ) ), TQ_SLOT( checkCreateUnit( const Unit & ) ) );
connect( database, TQ_SIGNAL( unitRemoved( int ) ), TQ_SLOT( removeUnit( int ) ) );
}
void UnitListView::load( int limit, int offset )
{
UnitList unitList;
database->loadUnits( &unitList, Unit::All, limit, offset );
for ( UnitList::const_iterator it = unitList.begin(); it != unitList.end(); ++it ) {
if ( !( *it ).name.isEmpty() || !( *it ).plural.isEmpty() )
createUnit( *it );
}
}
void UnitListView::checkCreateUnit( const Unit &el )
{
if ( handleElement(el.name) ) { //only create this unit if the base class okays it
createUnit(el);
}
}
StdUnitListView::StdUnitListView( TQWidget *parent, RecipeDB *db, bool editable ) : UnitListView( parent, db )
{
addColumn( i18n( "Unit" ) );
addColumn( i18n( "Abbreviation" ) );
addColumn( i18n( "Plural" ) );
addColumn( i18n( "Abbreviation" ) );
addColumn( i18n( "Type" ) );
TDEConfig * config = TDEGlobal::config();
config->setGroup( "Advanced" );
bool show_id = config->readBoolEntry( "ShowID", false );
addColumn( i18n( "Id" ), show_id ? -1 : 0 );
if ( editable ) {
setRenameable( 0, true );
setRenameable( 1, true );
setRenameable( 2, true );
setRenameable( 3, true );
setRenameable( 4, true );
TDEIconLoader il;
kpop = new TDEPopupMenu( this );
kpop->insertItem( il.loadIcon( "document-new", TDEIcon::NoGroup, 16 ), i18n( "&Create" ), this, TQ_SLOT( createNew() ), CTRL + Key_C );
kpop->insertItem( il.loadIcon( "edit-delete", TDEIcon::NoGroup, 16 ), i18n( "&Delete" ), this, TQ_SLOT( remove
() ), Key_Delete );
kpop->insertItem( il.loadIcon( "edit", TDEIcon::NoGroup, 16 ), i18n( "&Rename" ), this, TQ_SLOT( rename() ), CTRL + Key_R );
kpop->polish();
typeComboBox = new TQComboBox( false, viewport() );
typeComboBox->insertItem(i18n("Other"));
typeComboBox->insertItem(i18n("Mass"));
typeComboBox->insertItem(i18n("Volume"));
addChild( typeComboBox );
typeComboBox->hide();
connect( typeComboBox, TQ_SIGNAL( activated(int) ), TQ_SLOT( updateType(int) ) );
connect( this, TQ_SIGNAL( selectionChanged() ), TQ_SLOT( hideTypeCombo() ) );
connect( this, TQ_SIGNAL( contextMenu( TDEListView *, TQListViewItem *, const TQPoint & ) ), TQ_SLOT( showPopup( TDEListView *, TQListViewItem *, const TQPoint & ) ) );
connect( this, TQ_SIGNAL( doubleClicked( TQListViewItem*, const TQPoint &, int ) ), this, TQ_SLOT( modUnit( TQListViewItem*, const TQPoint &, int ) ) );
connect( this, TQ_SIGNAL( itemRenamed( TQListViewItem*, const TQString &, int ) ), this, TQ_SLOT( saveUnit( TQListViewItem*, const TQString &, int ) ) );
}
}
void StdUnitListView::insertTypeComboBox( TQListViewItem* it )
{
TQRect r;
// Constraints Box1
r = header() ->sectionRect( 4 ); //start at the section 2 header
r.moveBy( 0, itemRect( it ).y() ); //Move down to the item, note that its height is same as header's right now.
r.setHeight( it->height() ); // Set the item's height
r.setWidth( header() ->sectionRect( 4 ).width() ); // and width
typeComboBox->setGeometry( r );
UnitListViewItem *unit_it = (UnitListViewItem*)it;
typeComboBox->setCurrentItem( unit_it->unit().type );
typeComboBox->show();
}
void StdUnitListView::updateType( int type )
{
UnitListViewItem *unit_it = (UnitListViewItem*)currentItem();
unit_it->setType((Unit::Type)type);
database->modUnit( unit_it->unit() );
}
void StdUnitListView::hideTypeCombo()
{
typeComboBox->hide();
}
void StdUnitListView::showPopup( TDEListView * /*l*/, TQListViewItem *i, const TQPoint &p )
{
if ( i )
kpop->exec( p );
}
void StdUnitListView::createNew()
{
CreateUnitDialog * unitDialog = new CreateUnitDialog( this );
if ( unitDialog->exec() == TQDialog::Accepted ) {
Unit result = unitDialog->newUnit();
//check bounds first
if ( checkBounds( result )
&& database->findExistingUnitByName( result.name ) == -1
&& database->findExistingUnitByName( result.plural ) == -1
) {
database->createNewUnit( result );
}
}
delete unitDialog;
}
void StdUnitListView::remove()
{
// Find selected unit item
UnitListViewItem* it = (UnitListViewItem*)currentItem();
if ( it ) {
int unitID = it->unit().id;
ElementList recipeDependancies, propertyDependancies, weightDependancies;
database->findUnitDependancies( unitID, &propertyDependancies, &recipeDependancies, &weightDependancies );
TQValueList<ListInfo> lists;
if ( !recipeDependancies.isEmpty() ) {
ListInfo info;
info.list = recipeDependancies;
info.name = i18n("Recipes");
lists << info;
}
if ( !propertyDependancies.isEmpty() ) {
ListInfo info;
info.list = propertyDependancies;
info.name = i18n("Properties");
lists << info;
}
if ( !weightDependancies.isEmpty() ) {
ListInfo info;
info.list = weightDependancies;
info.name = i18n("Ingredient Weights");
lists << info;
}
if ( lists.isEmpty() )
database->removeUnit( unitID );
else { // need warning!
DependanciesDialog warnDialog( this, lists );
if ( !recipeDependancies.isEmpty() )
warnDialog.setCustomWarning( i18n("You are about to permanantly delete recipes from your database.") );
if ( warnDialog.exec() == TQDialog::Accepted )
database->removeUnit( unitID );
}
}
}
void StdUnitListView::rename()
{
TQListViewItem * item = currentItem();
if ( item ) {
CreateUnitDialog unitDialog( this, item->text(0), item->text(2), item->text(1), item->text(3), false );
if ( unitDialog.exec() == TQDialog::Accepted ) {
UnitListViewItem *unit_item = (UnitListViewItem*)item;
Unit origUnit = unit_item->unit();
Unit newUnit = unitDialog.newUnit();
//for each changed entry, save the change individually
Unit unit = origUnit;
if ( newUnit.name != origUnit.name ) {
unit.name = newUnit.name;
unit_item->setUnit( unit );
saveUnit( unit_item, newUnit.name, 0 );
//saveUnit will call database->modUnit which deletes the list item we were using
unit_item = (UnitListViewItem*) findItem( TQString::number(unit.id), 5 );
}
if ( newUnit.plural != origUnit.plural ) {
unit.plural = newUnit.plural;
unit_item->setUnit( unit );
saveUnit( unit_item, newUnit.plural, 2 );
unit_item = (UnitListViewItem*) findItem( TQString::number(unit.id), 5 );
}
if ( !newUnit.name_abbrev.stripWhiteSpace().isEmpty() && newUnit.name_abbrev != origUnit.name_abbrev ) {
unit.name_abbrev = newUnit.name_abbrev;
unit_item->setUnit( unit );
saveUnit( unit_item, newUnit.name_abbrev, 1 );
unit_item = (UnitListViewItem*) findItem( TQString::number(unit.id), 5 );
}
if ( !newUnit.plural_abbrev.stripWhiteSpace().isEmpty() && newUnit.plural_abbrev != origUnit.plural_abbrev ) {
unit.plural_abbrev = newUnit.plural_abbrev;
unit_item->setUnit( unit );
saveUnit( unit_item, newUnit.plural_abbrev, 3 );
}
}
}
}
void StdUnitListView::createUnit( const Unit &unit )
{
createElement(new UnitListViewItem( this, unit ));
}
void StdUnitListView::removeUnit( int id )
{
TQListViewItem * item = findItem( TQString::number( id ), 5 );
removeElement(item);
}
void StdUnitListView::modUnit( TQListViewItem* i, const TQPoint & /*p*/, int c )
{
if ( i ) {
if ( c != 4 )
UnitListView::rename( i, c );
else {
insertTypeComboBox(i);
}
}
}
void StdUnitListView::saveUnit( TQListViewItem* i, const TQString &text, int c )
{
//skip abbreviations
if ( c == 0 || c == 2 ) {
if ( !checkBounds( Unit( text, text ) ) ) {
reload(ForceReload); //reset the changed text
return ;
}
}
int existing_id = database->findExistingUnitByName( text );
UnitListViewItem *unit_it = (UnitListViewItem*)i;
int unit_id = unit_it->unit().id;
if ( existing_id != -1 && existing_id != unit_id && !text.stripWhiteSpace().isEmpty() ) { //unit already exists with this label... merge the two
switch ( KMessageBox::warningContinueCancel( this, i18n( "This unit already exists. Continuing will merge these two units into one. Are you sure?" ) ) ) {
case KMessageBox::Continue: {
database->modUnit( unit_it->unit() );
database->mergeUnits( unit_id, existing_id );
break;
}
default:
reload(ForceReload);
break;
}
}
else {
database->modUnit( unit_it->unit() );
}
}
bool StdUnitListView::checkBounds( const Unit &unit )
{
if ( unit.name.length() > uint(database->maxUnitNameLength()) || unit.plural.length() > uint(database->maxUnitNameLength()) ) {
KMessageBox::error( this, TQString( i18n( "Unit name cannot be longer than %1 characters." ) ).arg( database->maxUnitNameLength() ) );
return false;
}
else if ( unit.name.stripWhiteSpace().isEmpty() || unit.plural.stripWhiteSpace().isEmpty() )
return false;
return true;
}
#include "unitlistview.moc"