diff options
Diffstat (limited to 'src/recipeactionshandler.cpp')
-rw-r--r-- | src/recipeactionshandler.cpp | 475 |
1 files changed, 475 insertions, 0 deletions
diff --git a/src/recipeactionshandler.cpp b/src/recipeactionshandler.cpp new file mode 100644 index 0000000..dde3fcb --- /dev/null +++ b/src/recipeactionshandler.cpp @@ -0,0 +1,475 @@ +/*************************************************************************** +* Copyright (C) 2003-2004 by * +* Jason Kivlighn ([email protected]) * +* Unai Garro ([email protected]) * +* Cyril Bosselut ([email protected]) * +* * +* 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 "recipeactionshandler.h" + +#include <tqwidget.h> +#include <tqclipboard.h> + +#include <tdeapplication.h> +#include <tdefiledialog.h> +#include <kiconloader.h> +#include <tdelistview.h> +#include <tdelocale.h> +#include <tdemessagebox.h> +#include <tdepopupmenu.h> +#include <kprogress.h> + +#include "dialogs/selectcategoriesdialog.h" + +#include "exporters/cookmlexporter.h" +#include "exporters/htmlexporter.h" +#include "exporters/htmlbookexporter.h" +#include "exporters/kreexporter.h" +#include "exporters/mmfexporter.h" +#include "exporters/recipemlexporter.h" +#include "exporters/plaintextexporter.h" +#include "exporters/rezkonvexporter.h" + +#include "widgets/recipelistview.h" +#include "widgets/categorylistview.h" + +#include "backends/recipedb.h" + +RecipeActionsHandler::RecipeActionsHandler( TDEListView *_parentListView, RecipeDB *db, int actions ) : TQObject( _parentListView ), + parentListView( _parentListView ), + database( db ) +{ + TDEIconLoader * il = new TDEIconLoader; + + kpop = new TDEPopupMenu( parentListView ); + if ( actions & Open ) + kpop->insertItem( il->loadIcon( "ok", TDEIcon::NoGroup, 16 ), i18n( "&Open" ), this, TQ_SLOT( open() ), CTRL + Key_L ); + if ( actions & Edit ) + kpop->insertItem( il->loadIcon( "edit", TDEIcon::NoGroup, 16 ), i18n( "&Edit" ), this, TQ_SLOT( edit() ), CTRL + Key_E ); + if ( actions & Export ) + kpop->insertItem( il->loadIcon( "fileexport", TDEIcon::NoGroup, 16 ), i18n( "E&xport" ), this, TQ_SLOT( recipeExport() ), 0 ); + if ( actions & RemoveFromCategory ) + remove_from_cat_item = kpop->insertItem( il->loadIcon( "editshred", TDEIcon::NoGroup, 16 ), i18n( "&Remove From Category" ), this, TQ_SLOT( removeFromCategory() ), CTRL + Key_R ); + if ( actions & Remove ) + kpop->insertItem( il->loadIcon( "editshred", TDEIcon::NoGroup, 16 ), i18n( "&Delete" ), this, TQ_SLOT( remove + () ), Key_Delete ); + if ( actions & AddToShoppingList ) + kpop->insertItem( il->loadIcon( "trolley", TDEIcon::NoGroup, 16 ), i18n( "&Add to Shopping List" ), this, TQ_SLOT( addToShoppingList() ), CTRL + Key_A ); + if ( actions & CopyToClipboard ) + kpop->insertItem( il->loadIcon( "edit-copy", TDEIcon::NoGroup, 16 ), i18n( "&Copy to Clipboard" ), this, TQ_SLOT( recipesToClipboard() ), CTRL + Key_C ); + + if ( actions & Categorize ) + categorize_item = kpop->insertItem( il->loadIcon( "categories", TDEIcon::NoGroup, 16 ), i18n( "Ca&tegorize..." ), this, TQ_SLOT(categorize()), CTRL + Key_T ); + + kpop->polish(); + + catPop = new TDEPopupMenu( parentListView ); + if ( actions & ExpandAll ) + catPop->insertItem( i18n( "&Expand All" ), this, TQ_SLOT( expandAll() ), CTRL + Key_Plus ); + if ( actions & CollapseAll ) + catPop->insertItem( i18n( "&Collapse All" ), this, TQ_SLOT( collapseAll() ), CTRL + Key_Minus ); + if ( actions & Export ) + catPop->insertItem( il->loadIcon( "fileexport", TDEIcon::NoGroup, 16 ), i18n( "E&xport" ), this, TQ_SLOT( recipeExport() ), 0 ); + + catPop->polish(); + + delete il; + + connect( parentListView, TQ_SIGNAL( contextMenu( TDEListView *, TQListViewItem *, const TQPoint & ) ), TQ_SLOT( showPopup( TDEListView *, TQListViewItem *, const TQPoint & ) ) ); + connect( parentListView, TQ_SIGNAL( doubleClicked( TQListViewItem*, const TQPoint &, int ) ), TQ_SLOT( open() ) ); +} + +void RecipeActionsHandler::exec( ItemType type, const TQPoint &p ) +{ + if ( type == Recipe ) { + if ( kpop->idAt( 0 ) != -1 ) + kpop->exec( p ); + } + else if ( type == Category ) { + if ( catPop->idAt( 0 ) != -1 ) + catPop->exec( p ); + } +} + +void RecipeActionsHandler::showPopup( TDEListView * /*l*/, TQListViewItem *i, const TQPoint &p ) +{ + if ( i ) { // Check if the TQListViewItem actually exists + if ( i->rtti() == 1000 ) { + kpop->setItemVisible( categorize_item, i->parent() && i->parent()->rtti() == 1006 ); + kpop->setItemVisible( remove_from_cat_item, i->parent() && i->parent()->rtti() == 1001 ); + exec( Recipe, p ); + } + else if ( i->rtti() == 1001 ) //is a category... don't pop-up for an empty category though + exec( Category, p ); + } +} + +TQValueList<int> RecipeActionsHandler::recipeIDs( const TQPtrList<TQListViewItem> &items ) const +{ + TQValueList<int> ids; + + TQPtrListIterator<TQListViewItem> it(items); + TQListViewItem *item; + while ( (item = it.current()) != 0 ) { + if ( item->rtti() == 1000 ) { //RecipeListItem + RecipeListItem * recipe_it = ( RecipeListItem* ) item; + if ( ids.find( recipe_it->recipeID() ) == ids.end() ) + ids << recipe_it->recipeID(); + } + else if ( item->rtti() == 1001 ) { + CategoryListItem *cat_it = ( CategoryListItem* ) item; + ElementList list; + database->loadRecipeList( &list, cat_it->element().id, true ); + + for ( ElementList::const_iterator cat_it = list.begin(); cat_it != list.end(); ++cat_it ) { + if ( ids.find( (*cat_it).id ) == ids.end() ) + ids << (*cat_it).id; + } + } + ++it; + } + + return ids; +} + +void RecipeActionsHandler::open() +{ + TQPtrList<TQListViewItem> items = parentListView->selectedItems(); + if ( items.count() > 0 ) { + TQValueList<int> ids = recipeIDs(items); + if ( ids.count() == 1 ) + emit recipeSelected(ids.first(),0); + else if ( ids.count() > 0 ) + emit recipesSelected(ids,0); + #if 0 + else if ( it->rtti() == 1001 && it->firstChild() ) //CategoryListItem and not empty + { + TQValueList<int> ids; + + //do this to only iterate over children of 'it' + TQListViewItem *pEndItem = NULL; + TQListViewItem *pStartItem = it; + do + { + if ( pStartItem->nextSibling() ) + pEndItem = pStartItem->nextSibling(); + else + pStartItem = pStartItem->parent(); + } + while ( pStartItem && !pEndItem ); + + TQListViewItemIterator iterator( it ); + while ( iterator.current() != pEndItem ) + { + if ( iterator.current() ->rtti() == 1000 ) { + RecipeListItem * recipe_it = ( RecipeListItem* ) iterator.current(); + if ( ids.find( recipe_it->recipeID() ) == ids.end() ) { + ids.append( recipe_it->recipeID() ); + } + } + ++iterator; + } + emit recipesSelected( ids, 0 ); + } + #endif + } +} + +void RecipeActionsHandler::categorize() +{ + TQPtrList<TQListViewItem> items = parentListView->selectedItems(); + if ( items.count() > 0 ) { + ElementList categoryList; + SelectCategoriesDialog *editCategoriesDialog = new SelectCategoriesDialog( parentListView, categoryList, database ); + + if ( editCategoriesDialog->exec() == TQDialog::Accepted ) { // user presses Ok + editCategoriesDialog->getSelectedCategories( &categoryList ); // get the category list chosen + + TQPtrListIterator<TQListViewItem> it(items); + TQListViewItem *item; + while ( (item = it.current()) != 0 ) { + if ( item->parent() != 0 ) { + RecipeListItem * recipe_it = ( RecipeListItem* ) item; + int recipe_id = recipe_it->recipeID(); + + database->categorizeRecipe( recipe_id, categoryList ); + } + ++it; + } + } + + delete editCategoriesDialog; + } +} + +void RecipeActionsHandler::edit() +{ + TQPtrList<TQListViewItem> items = parentListView->selectedItems(); + if ( items.count() > 1 ) + KMessageBox::sorry( kapp->mainWidget(), i18n("Please select only one recipe."), i18n("Edit Recipe") ); + else if ( items.count() == 1 && items.at(0)->rtti() == 1000 ) { + RecipeListItem * recipe_it = ( RecipeListItem* ) items.at(0); + emit recipeSelected( recipe_it->recipeID(), 1 ); + } + else //either nothing was selected or a category was selected + KMessageBox::sorry( kapp->mainWidget(), i18n("No recipes selected."), i18n("Edit Recipe") ); +} + +void RecipeActionsHandler::recipeExport() +{ + TQPtrList<TQListViewItem> items = parentListView->selectedItems(); + if ( items.count() > 0 ) { + TQValueList<int> ids = recipeIDs( items ); + + TQString title; + if ( items.count() == 1 && items.at(0)->rtti() == 1000 ) { + RecipeListItem * recipe_it = ( RecipeListItem* ) items.at(0); + title = recipe_it->title(); + } + else + title = i18n( "Recipes" ); + + exportRecipes( ids, i18n( "Export Recipe" ), title, database ); + } + else //if nothing selected, export all visible recipes + { + TQValueList<int> ids = getAllVisibleItems(); + if ( ids.count() > 0 ) { + switch ( KMessageBox::questionYesNo( kapp->mainWidget(), i18n("No recipes are currently selected.\nWould you like to export all recipes in the current view?")) ) + { + case KMessageBox::Yes: + exportRecipes( ids, i18n( "Export Recipes" ), i18n( "Recipes" ), database ); + break; + default: break; + } + } + else + KMessageBox::sorry( kapp->mainWidget(), i18n("No recipes selected."), i18n("Export") ); + } +} + +void RecipeActionsHandler::removeFromCategory() +{ + TQPtrList<TQListViewItem> items = parentListView->selectedItems(); + if ( items.count() > 0 ) { + TQPtrListIterator<TQListViewItem> it(items); + TQListViewItem *item; + while ( (item = it.current()) != 0 ) { + if ( item->parent() != 0 ) { + RecipeListItem * recipe_it = ( RecipeListItem* ) item; + int recipe_id = recipe_it->recipeID(); + + CategoryListItem *cat_it = ( CategoryListItem* ) item->parent(); + database->removeRecipeFromCategory( recipe_id, cat_it->categoryId() ); + } + ++it; + } + } +} + +void RecipeActionsHandler::remove() +{ + TQPtrList<TQListViewItem> items = parentListView->selectedItems(); + if ( items.count() > 0 ) { + TQPtrListIterator<TQListViewItem> it(items); + TQListViewItem *item; + while ( (item = it.current()) != 0 ) { + if ( item->rtti() == RECIPELISTITEM_RTTI ) { + RecipeListItem * recipe_it = ( RecipeListItem* ) item; + emit recipeSelected( recipe_it->recipeID(), 2 ); + } + ++it; + } + } +} + +void RecipeActionsHandler::addToShoppingList() +{ + TQPtrList<TQListViewItem> items = parentListView->selectedItems(); + if ( items.count() > 0 ) { + TQPtrListIterator<TQListViewItem> it(items); + TQListViewItem *item; + while ( (item = it.current()) != 0 ) { + if ( item->parent() != 0 ) { + RecipeListItem * recipe_it = ( RecipeListItem* ) item; + emit recipeSelected( recipe_it->recipeID(), 3 ); + } + ++it; + } + } +} + +void RecipeActionsHandler::expandAll() +{ + TQListViewItemIterator it( parentListView ); + while ( it.current() ) { + TQListViewItem * item = it.current(); + item->setOpen( true ); + ++it; + } +} + +void RecipeActionsHandler::collapseAll() +{ + TQListViewItemIterator it( parentListView ); + while ( it.current() ) { + TQListViewItem * item = it.current(); + item->setOpen( false ); + ++it; + } +} + +void RecipeActionsHandler::exportRecipe( int id, const TQString & caption, const TQString &selection, RecipeDB *db ) +{ + TQValueList<int> ids; + ids.append( id ); + + exportRecipes( ids, caption, selection, db ); +} + +void RecipeActionsHandler::exportRecipes( const TQValueList<int> &ids, const TQString & caption, const TQString &selection, RecipeDB *database ) +{ + KFileDialog * fd = new KFileDialog( TQString::null, + TQString( "*.kre|%1 (*.kre)\n" + "*.kreml|Krecipes (*.kreml)\n" + "*.txt|%3 (*.txt)\n" + //"*.cml|CookML (*.cml)\n" + "*|Web Book\n" + "*.html|%2 (*.html)\n" + "*.mmf|Meal-Master (*.mmf)\n" + "*.xml|RecipeML (*.xml)\n" + "*.rk|Rezkonv (*.rk)" + ).arg( i18n( "Compressed Krecipes format" ) ).arg( i18n( "Web page" ) ).arg( i18n("Plain Text") ), + 0, "export_dlg", true ); + fd->setCaption( caption ); + fd->setOperationMode( KFileDialog::Saving ); + fd->setSelection( selection ); + fd->setMode( KFile::File | KFile::Directory ); + if ( fd->exec() == KFileDialog::Accepted ) { + TQString fileName = fd->selectedFile(); + if ( !fileName.isNull() ) { + BaseExporter * exporter; + if ( fd->currentFilter() == "*.xml" ) + exporter = new RecipeMLExporter( fileName, fd->currentFilter() ); + else if ( fd->currentFilter() == "*.mmf" ) + exporter = new MMFExporter( fileName, fd->currentFilter() ); + else if ( fd->currentFilter() == "*" ) { + CategoryTree *cat_structure = new CategoryTree; + database->loadCategories( cat_structure ); + exporter = new HTMLBookExporter( cat_structure, fd->baseURL().path(), "*.html" ); + } + else if ( fd->currentFilter() == "*.html" ) { + exporter = new HTMLExporter( fileName, fd->currentFilter() ); + } + else if ( fd->currentFilter() == "*.cml" ) + exporter = new CookMLExporter( fileName, fd->currentFilter() ); + else if ( fd->currentFilter() == "*.txt" ) + exporter = new PlainTextExporter( fileName, fd->currentFilter() ); + else if ( fd->currentFilter() == "*.rk" ) + exporter = new RezkonvExporter( fileName, fd->currentFilter() ); + else { + CategoryTree *cat_structure = new CategoryTree; + database->loadCategories( cat_structure ); + exporter = new KreExporter( cat_structure, fileName, fd->currentFilter() ); + } + + int overwrite = -1; + if ( TQFile::exists( exporter->fileName() ) ) { + overwrite = KMessageBox::warningYesNo( 0, TQString( i18n( "File \"%1\" exists. Are you sure you want to overwrite it?" ) ).arg( exporter->fileName() ), i18n( "Saving recipe" ) ); + } + + if ( overwrite == KMessageBox::Yes || overwrite == -1 ) { + KProgressDialog progress_dialog( 0, "export_progress_dialog", TQString::null, i18n( "Saving recipes..." ) ); + exporter->exporter( ids, database, &progress_dialog ); + } + delete exporter; + } + } + delete fd; +} + +void RecipeActionsHandler::recipesToClipboard( const TQValueList<int> &ids, RecipeDB *db ) +{ + TDEConfig *config = TDEGlobal::config(); + config->setGroup("Export"); + TQString formatFilter = config->readEntry("ClipboardFormat"); + + BaseExporter * exporter; + if ( formatFilter == "*.xml" ) + exporter = new RecipeMLExporter( TQString::null, formatFilter ); + else if ( formatFilter == "*.mmf" ) + exporter = new MMFExporter( TQString::null, formatFilter ); + else if ( formatFilter == "*.cml" ) + exporter = new CookMLExporter( TQString::null, formatFilter ); + else if ( formatFilter == "*.rk" ) + exporter = new RezkonvExporter( TQString::null, formatFilter ); + else if ( formatFilter == "*.kre" || formatFilter == "*.kreml" ) { + CategoryTree *cat_structure = new CategoryTree; + db->loadCategories( cat_structure ); + exporter = new KreExporter( cat_structure, TQString::null, formatFilter ); + } + else //default to plain text + exporter = new PlainTextExporter( TQString::null, "*.txt" ); + + RecipeList recipeList; + db->loadRecipes( &recipeList, exporter->supportedItems(), ids ); + + TQString buffer; + TQTextStream stream(buffer,IO_WriteOnly); + exporter->writeStream(stream,recipeList); + + delete exporter; + + TQApplication::clipboard()->setText(buffer); +} + +void RecipeActionsHandler::recipesToClipboard() +{ + TQPtrList<TQListViewItem> items = parentListView->selectedItems(); + if ( items.count() > 0 ) { + TQValueList<int> ids = recipeIDs( items ); + + recipesToClipboard(ids,database); + } +} + +TQValueList<int> RecipeActionsHandler::getAllVisibleItems() +{ + TQValueList<int> ids; + + TQListViewItemIterator iterator( parentListView ); + while ( iterator.current() ) { + if ( iterator.current() ->isVisible() ) { + if ( iterator.current() ->rtti() == RECIPELISTITEM_RTTI ) { + RecipeListItem * recipe_it = ( RecipeListItem* ) iterator.current(); + int recipe_id = recipe_it->recipeID(); + + if ( ids.find( recipe_id ) == ids.end() ) + ids.append( recipe_id ); + } + //it is a category item and isn't populated, so get the unpopulated data from the database + else if ( iterator.current()->rtti() == CATEGORYLISTITEM_RTTI && !iterator.current()->firstChild() ) { + int cat_id = (( CategoryListItem* ) iterator.current())->element().id; + ElementList list; + database->loadRecipeList( &list, cat_id, true ); + + for ( ElementList::const_iterator it = list.begin(); it != list.end(); ++it ) { + if ( ids.find( (*it).id ) == ids.end() ) + ids << (*it).id; + } + } + } + + ++iterator; + } + + return ids; +} + +#include "recipeactionshandler.moc" + |