summaryrefslogtreecommitdiffstats
path: root/src/dialogs/ingredientparserdialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dialogs/ingredientparserdialog.cpp')
-rw-r--r--src/dialogs/ingredientparserdialog.cpp299
1 files changed, 299 insertions, 0 deletions
diff --git a/src/dialogs/ingredientparserdialog.cpp b/src/dialogs/ingredientparserdialog.cpp
new file mode 100644
index 0000000..0081bcf
--- /dev/null
+++ b/src/dialogs/ingredientparserdialog.cpp
@@ -0,0 +1,299 @@
+/***************************************************************************
+* 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 <tqpushbutton.h>
+#include <tqtextedit.h>
+#include <tqlabel.h>
+#include <tqlineedit.h>
+#include <tqlayout.h>
+#include <tqtooltip.h>
+#include <tqwhatsthis.h>
+#include <tqheader.h>
+#include <tqapplication.h>
+#include <tqclipboard.h>
+#include <tqvbox.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"