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.
300 lines
9.5 KiB
300 lines
9.5 KiB
/***************************************************************************
|
|
* Copyright (C) 2005 by *
|
|
* 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 "ingredientparserdialog.h"
|
|
|
|
#include <ntqpushbutton.h>
|
|
#include <ntqtextedit.h>
|
|
#include <ntqlabel.h>
|
|
#include <ntqlineedit.h>
|
|
#include <ntqlayout.h>
|
|
#include <ntqtooltip.h>
|
|
#include <ntqwhatsthis.h>
|
|
#include <ntqheader.h>
|
|
#include <ntqapplication.h>
|
|
#include <ntqclipboard.h>
|
|
#include <ntqvbox.h>
|
|
|
|
#include <tdelocale.h>
|
|
#include <kdebug.h>
|
|
#include <tdelistview.h>
|
|
#include <kpushbutton.h>
|
|
#include <tdemessagebox.h>
|
|
#include <tdeaction.h>
|
|
#include <tdepopupmenu.h>
|
|
|
|
#include "datablocks/mixednumber.h"
|
|
#include "widgets/inglistviewitem.h"
|
|
|
|
IngredientParserDialog::IngredientParserDialog( const UnitList &units, TQWidget* parent, const char* name )
|
|
: KDialogBase( parent, name, true, i18n( "Ingredient Parser" ),
|
|
KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok ),
|
|
m_unitList(units)
|
|
{
|
|
setButtonBoxOrientation( Vertical );
|
|
|
|
TQVBox *page = makeVBoxMainWidget();
|
|
|
|
textLabel1 = new TQLabel( page, "textLabel1" );
|
|
textLabel1->setTextFormat( TQLabel::RichText );
|
|
|
|
ingredientTextEdit = new TQTextEdit( page, "ingredientTextEdit" );
|
|
ingredientTextEdit->setTextFormat( TQTextEdit::PlainText );
|
|
|
|
parseButton = new KPushButton( page, "parseButton" );
|
|
|
|
previewLabel = new TQLabel( page, "previewLabel" );
|
|
previewLabel->setTextFormat( TQLabel::RichText );
|
|
|
|
previewIngView = new TDEListView( page, "previewIngView" );
|
|
previewIngView->setSorting(-1);
|
|
previewIngView->addColumn( i18n( "Ingredient" ) );
|
|
previewIngView->addColumn( i18n( "Amount" ) );
|
|
previewIngView->addColumn( i18n( "Unit" ) );
|
|
previewIngView->addColumn( i18n( "Preparation Method" ) );
|
|
|
|
languageChange();
|
|
setInitialSize( TQSize(577, 371).expandedTo(minimumSizeHint()) );
|
|
|
|
previewIngView->setItemsRenameable( true );
|
|
previewIngView->setRenameable( 0, true );
|
|
previewIngView->setRenameable( 1, true );
|
|
previewIngView->setRenameable( 2, true );
|
|
previewIngView->setRenameable( 3, true );
|
|
|
|
previewIngView->setSelectionMode( TQListView::Extended );
|
|
|
|
ingredientTextEdit->setText( TQApplication::clipboard()->text() );
|
|
ingredientTextEdit->selectAll();
|
|
|
|
TQWidget *buttonWidget = new TQWidget( page );
|
|
TQHBoxLayout *buttonBox = new TQHBoxLayout(buttonWidget);
|
|
TQSpacerItem *horizontalSpacing = new TQSpacerItem( 20, 20, TQSizePolicy::Expanding, TQSizePolicy::Minimum );
|
|
buttonGroup = new TQPushButton( i18n("Set &Header"), buttonWidget );
|
|
TQWhatsThis::add( buttonGroup, i18n("If an ingredient header is detected as an ingredient, select it and click this button so that Krecipes will recognize it as a header. All the ingredients below the header will be included within that group.\n\nAlternatively, if you select multiple ingredients and click this button, those ingredients will be grouped together.") );
|
|
buttonBox->addWidget( buttonGroup );
|
|
buttonBox->addItem( horizontalSpacing );
|
|
|
|
TDEPopupMenu *kpop = new TDEPopupMenu( previewIngView );
|
|
kpop->insertItem( i18n( "&Delete" ), this, TQ_SLOT( removeIngredient() ), Key_Delete );
|
|
kpop->insertItem( i18n("Set &Header") , this, TQ_SLOT( convertToHeader() ) );
|
|
|
|
connect( parseButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(parseText()) );
|
|
connect( buttonGroup, TQ_SIGNAL(clicked()), this, TQ_SLOT(convertToHeader()) );
|
|
}
|
|
|
|
IngredientParserDialog::~IngredientParserDialog()
|
|
{
|
|
// no need to delete child widgets, TQt does it all for us
|
|
}
|
|
|
|
void IngredientParserDialog::languageChange()
|
|
{
|
|
textLabel1->setText( i18n( "To use: Paste a list of ingredient below, click \"Parse Text\", and then you may correct any incorrectly parsed ingredients.<br><b>Caution: Fields will be truncated if longer than the database allows</b>" ) );
|
|
previewLabel->setText( i18n("Ingredients as understood by Krecipes:") );
|
|
parseButton->setText( i18n( "Parse Text" ) );
|
|
previewIngView->header()->setLabel( 0, i18n( "Ingredient" ) );
|
|
previewIngView->header()->setLabel( 1, i18n( "Amount" ) );
|
|
previewIngView->header()->setLabel( 2, i18n( "Unit" ) );
|
|
previewIngView->header()->setLabel( 3, i18n( "Preparation Method" ) );
|
|
}
|
|
|
|
void IngredientParserDialog::accept()
|
|
{
|
|
for ( TQListViewItem *it = previewIngView->firstChild(); it; it = it->nextSibling() ) {
|
|
if ( it->rtti() == INGGRPLISTVIEWITEM_RTTI ) {
|
|
TQString group = ((IngGrpListViewItem*)it)->group();
|
|
for ( IngListViewItem *sub_it = (IngListViewItem*)it->firstChild(); sub_it; sub_it = (IngListViewItem*)sub_it->nextSibling() ) {
|
|
Ingredient ing = sub_it->ingredient();
|
|
ing.group = group;
|
|
m_ingList.append(ing);
|
|
}
|
|
}
|
|
else
|
|
m_ingList.append(((IngListViewItem*)it)->ingredient());
|
|
}
|
|
|
|
TQDialog::accept();
|
|
}
|
|
|
|
void IngredientParserDialog::removeIngredient()
|
|
{
|
|
delete previewIngView->selectedItem();
|
|
if ( !previewIngView->firstChild() )
|
|
enableButtonOK( false );
|
|
}
|
|
|
|
void IngredientParserDialog::convertToHeader()
|
|
{
|
|
TQPtrList<TQListViewItem> items = previewIngView->selectedItems();
|
|
if ( items.count() == 0 )
|
|
return;
|
|
else if ( items.count() > 1 )
|
|
convertToHeader(items);
|
|
else { //items.count = 1
|
|
TQListViewItem *item = items.first();
|
|
if ( item->rtti() == INGLISTVIEWITEM_RTTI ) {
|
|
TQListViewItem *new_item = new IngGrpListViewItem(previewIngView,
|
|
(item->parent())?item->parent():item,
|
|
((IngListViewItem*)item)->ingredient().name, -1);
|
|
|
|
TQListViewItem *next_sibling;
|
|
TQListViewItem *last_item = 0;
|
|
for ( TQListViewItem * it = (item->parent())?item->nextSibling():new_item->nextSibling(); it; it = next_sibling ) {
|
|
if ( it->rtti() == INGGRPLISTVIEWITEM_RTTI )
|
|
break;
|
|
|
|
next_sibling = it->nextSibling(); //get the next sibling of this item before we move it
|
|
|
|
if ( it->parent() )
|
|
it->parent()->takeItem(it);
|
|
else
|
|
previewIngView->takeItem( it );
|
|
|
|
new_item->insertItem( it );
|
|
|
|
if ( last_item )
|
|
it->moveItem( last_item );
|
|
last_item = it;
|
|
}
|
|
|
|
new_item->setOpen(true);
|
|
|
|
delete item;
|
|
}
|
|
}
|
|
}
|
|
|
|
void IngredientParserDialog::convertToHeader( const TQPtrList<TQListViewItem> &items )
|
|
{
|
|
if ( items.count() > 0 ) {
|
|
TQPtrListIterator<TQListViewItem> it(items);
|
|
TQListViewItem *item = it.current();
|
|
|
|
if ( item->rtti() != INGLISTVIEWITEM_RTTI )
|
|
return;
|
|
|
|
TQString group = ((IngListViewItem*)item)->ingredient().name;
|
|
TQListViewItem *ingGroupItem = new IngGrpListViewItem(previewIngView,
|
|
(item->parent())?item->parent():item, group, -1);
|
|
delete item; //delete the ingredient header which was detected as an ingredient
|
|
++it;
|
|
|
|
TQListViewItem *last_item = 0;
|
|
while ( (item = it.current()) != 0 ) {
|
|
//ignore anything that isn't an ingredient (e.g. headers)
|
|
if ( item->rtti() == INGLISTVIEWITEM_RTTI ) {
|
|
if ( item->parent() )
|
|
item->parent()->takeItem(item);
|
|
else
|
|
previewIngView->takeItem( item );
|
|
|
|
ingGroupItem->insertItem( item );
|
|
|
|
if ( last_item )
|
|
item->moveItem( last_item );
|
|
last_item = item;
|
|
}
|
|
|
|
++it;
|
|
}
|
|
|
|
ingGroupItem->setOpen(true);
|
|
previewIngView->clearSelection();
|
|
}
|
|
}
|
|
|
|
void IngredientParserDialog::parseText()
|
|
{
|
|
previewIngView->clear();
|
|
|
|
TQListViewItem *last_item = 0;
|
|
|
|
int line_num = 0;
|
|
TQStringList ingredients = TQStringList::split("\n",ingredientTextEdit->text());
|
|
for ( TQStringList::const_iterator it = ingredients.begin(); it != ingredients.end(); ++it ) {
|
|
TQString line = (*it).simplifyWhiteSpace();
|
|
|
|
++line_num;
|
|
int format_at = 0;
|
|
Ingredient ing;
|
|
|
|
|
|
//======amount======//
|
|
int first_space = line.find( " ", format_at+1 );
|
|
if ( first_space == -1 )
|
|
first_space = line.length();
|
|
|
|
int second_space = line.find( " ", first_space+1 );
|
|
if ( second_space == -1 )
|
|
second_space = line.length();
|
|
|
|
Ingredient i;
|
|
bool ok;
|
|
i.setAmount(line.mid(format_at,second_space-format_at),&ok);
|
|
if ( !ok ) {
|
|
i.setAmount(line.mid(format_at,first_space-format_at),&ok);
|
|
if ( ok ) format_at = first_space+1;
|
|
}
|
|
else
|
|
format_at = second_space+1;
|
|
|
|
if ( ok ) {
|
|
ing.amount = i.amount;
|
|
ing.amount_offset = i.amount_offset;
|
|
}
|
|
else
|
|
kdDebug()<<"no amount on line "<<line_num<<endl;
|
|
|
|
|
|
//======unit======//
|
|
first_space = line.find( " ", format_at+1 );
|
|
if ( first_space == -1 )
|
|
first_space = line.length();
|
|
|
|
bool isUnit = false;
|
|
TQString unitCheck = line.mid(format_at,first_space-format_at);
|
|
|
|
for ( UnitList::const_iterator unit_it = m_unitList.begin(); unit_it != m_unitList.end(); ++unit_it ) {
|
|
if ( (*unit_it).name == unitCheck || (*unit_it).plural == unitCheck || (*unit_it).name_abbrev == unitCheck || (*unit_it).plural_abbrev == unitCheck ) {
|
|
isUnit = true;
|
|
format_at = first_space+1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( isUnit ) {
|
|
ing.units.name = unitCheck;
|
|
ing.units.plural = unitCheck;
|
|
}
|
|
else
|
|
kdDebug()<<"no unit on line "<<line_num<<endl;
|
|
|
|
|
|
//======ingredient======//
|
|
int ing_end = line.find( TQRegExp("(,|;)"), format_at+1 );
|
|
if ( ing_end == -1 )
|
|
ing_end = line.length();
|
|
|
|
ing.name = line.mid(format_at,ing_end-format_at);
|
|
format_at = ing_end+2;
|
|
|
|
|
|
//======prep method======//
|
|
int end = line.length();
|
|
ing.prepMethodList = ElementList::split(",",line.mid(format_at,end-format_at));
|
|
|
|
last_item = new IngListViewItem(previewIngView,last_item,ing);
|
|
enableButtonOK( true );
|
|
}
|
|
}
|
|
|
|
#include "ingredientparserdialog.moc"
|