summaryrefslogtreecommitdiffstats
path: root/src/recipeactionshandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/recipeactionshandler.cpp')
-rw-r--r--src/recipeactionshandler.cpp475
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"
+