/*************************************************************************** * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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, SLOT( removeIngredient() ), Key_Delete ); kpop->insertItem( i18n("Set &Header") , this, SLOT( convertToHeader() ) ); connect( parseButton, SIGNAL(clicked()), this, SLOT(parseText()) ); connect( buttonGroup, SIGNAL(clicked()), this, 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.
Caution: Fields will be truncated if longer than the database allows" ) ); 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 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 &items ) { if ( items.count() > 0 ) { TQPtrListIterator 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 "<