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.
krecipes/krecipes/src/recipeactionshandler.cpp

476 lines
16 KiB

/***************************************************************************
* Copyright (C) 2003-2004 by *
* Jason Kivlighn (jkivlighn@gmail.com) *
* Unai Garro (ugarro@users.sourceforge.net) *
* Cyril Bosselut (bosselut@b1project.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 "recipeactionshandler.h"
#include <ntqwidget.h>
#include <ntqclipboard.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, SLOT( open() ), CTRL + Key_L );
if ( actions & Edit )
kpop->insertItem( il->loadIcon( "edit", TDEIcon::NoGroup, 16 ), i18n( "&Edit" ), this, SLOT( edit() ), CTRL + Key_E );
if ( actions & Export )
kpop->insertItem( il->loadIcon( "fileexport", TDEIcon::NoGroup, 16 ), i18n( "E&xport" ), this, SLOT( recipeExport() ), 0 );
if ( actions & RemoveFromCategory )
remove_from_cat_item = kpop->insertItem( il->loadIcon( "editshred", TDEIcon::NoGroup, 16 ), i18n( "&Remove From Category" ), this, SLOT( removeFromCategory() ), CTRL + Key_R );
if ( actions & Remove )
kpop->insertItem( il->loadIcon( "editshred", TDEIcon::NoGroup, 16 ), i18n( "&Delete" ), this, SLOT( remove
() ), Key_Delete );
if ( actions & AddToShoppingList )
kpop->insertItem( il->loadIcon( "trolley", TDEIcon::NoGroup, 16 ), i18n( "&Add to Shopping List" ), this, SLOT( addToShoppingList() ), CTRL + Key_A );
if ( actions & CopyToClipboard )
kpop->insertItem( il->loadIcon( "editcopy", TDEIcon::NoGroup, 16 ), i18n( "&Copy to Clipboard" ), this, SLOT( recipesToClipboard() ), CTRL + Key_C );
if ( actions & Categorize )
categorize_item = kpop->insertItem( il->loadIcon( "categories", TDEIcon::NoGroup, 16 ), i18n( "Ca&tegorize..." ), this, SLOT(categorize()), CTRL + Key_T );
kpop->polish();
catPop = new TDEPopupMenu( parentListView );
if ( actions & ExpandAll )
catPop->insertItem( i18n( "&Expand All" ), this, SLOT( expandAll() ), CTRL + Key_Plus );
if ( actions & CollapseAll )
catPop->insertItem( i18n( "&Collapse All" ), this, SLOT( collapseAll() ), CTRL + Key_Minus );
if ( actions & Export )
catPop->insertItem( il->loadIcon( "fileexport", TDEIcon::NoGroup, 16 ), i18n( "E&xport" ), this, SLOT( recipeExport() ), 0 );
catPop->polish();
delete il;
connect( parentListView, SIGNAL( contextMenu( TDEListView *, TQListViewItem *, const TQPoint & ) ), SLOT( showPopup( TDEListView *, TQListViewItem *, const TQPoint & ) ) );
connect( parentListView, SIGNAL( doubleClicked( TQListViewItem*, const TQPoint &, int ) ), 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"