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.
943 lines
26 KiB
943 lines
26 KiB
|
|
/***************************************************************************
|
|
* Copyright (C) 2003-2004 by *
|
|
* Unai Garro (ugarro@users.sourceforge.net) *
|
|
* Cyril Bosselut (bosselut@b1project.com) *
|
|
* 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 "krecipesview.h"
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <ntqlayout.h>
|
|
#include <ntqimage.h>
|
|
#include <ntqpainter.h>
|
|
#include <ntqpalette.h>
|
|
|
|
#include <tdeapplication.h>
|
|
#include <tdeconfig.h>
|
|
#include <kdebug.h>
|
|
#include <tdeglobalsettings.h>
|
|
#include <klibloader.h>
|
|
#include <tdelocale.h>
|
|
#include <tdemessagebox.h>
|
|
#include <kprogress.h>
|
|
#include <krun.h>
|
|
#include <ktrader.h>
|
|
#include <kurl.h>
|
|
#include <kcursor.h>
|
|
|
|
#include "recipeactionshandler.h"
|
|
#include "setupwizard.h"
|
|
#include "kstartuplogo.h"
|
|
|
|
#include "dialogs/recipeinputdialog.h"
|
|
#include "dialogs/recipeviewdialog.h"
|
|
#include "dialogs/selectrecipedialog.h"
|
|
#include "dialogs/ingredientsdialog.h"
|
|
#include "dialogs/propertiesdialog.h"
|
|
#include "dialogs/shoppinglistdialog.h"
|
|
#include "dialogs/dietwizarddialog.h"
|
|
#include "dialogs/categorieseditordialog.h"
|
|
#include "dialogs/authorsdialog.h"
|
|
#include "dialogs/unitsdialog.h"
|
|
#include "dialogs/prepmethodsdialog.h"
|
|
#include "dialogs/ingredientmatcherdialog.h"
|
|
|
|
#include "widgets/kremenu.h"
|
|
#include "widgets/paneldeco.h"
|
|
|
|
#include "backends/progressinterface.h"
|
|
|
|
#include "profiling.h"
|
|
|
|
KrecipesView::KrecipesView( TQWidget *parent )
|
|
: DCOPObject( "KrecipesInterface" ), TQVBox( parent )
|
|
{
|
|
#ifndef NDEBUG
|
|
TQTime dbg_total_timer; dbg_total_timer.start();
|
|
#endif
|
|
|
|
kapp->dcopClient()->setDefaultObject( objId() );
|
|
|
|
// Init the setup wizard if necessary
|
|
kdDebug() << "Beginning wizard" << endl;
|
|
wizard();
|
|
kdDebug() << "Wizard finished correctly" << endl;
|
|
|
|
// Show Splash Screen
|
|
|
|
TDEStartupLogo* start_logo = 0L;
|
|
start_logo = new TDEStartupLogo();
|
|
start_logo -> setHideEnabled( true );
|
|
start_logo->show();
|
|
start_logo->raise();
|
|
|
|
// Initialize Database
|
|
|
|
// Read the database setup
|
|
|
|
TDEConfig *config;
|
|
config = kapp->config();
|
|
config->sync();
|
|
|
|
|
|
// Check if the database type is among those supported
|
|
// and initialize the database in each case
|
|
START_TIMER("Initializing database")
|
|
initDatabase( config );
|
|
END_TIMER()
|
|
|
|
|
|
// Design the GUI
|
|
splitter = new TQHBox( this );
|
|
|
|
// Create Left and Right Panels (splitter)
|
|
|
|
|
|
TDEIconLoader il;
|
|
leftPanel = new KreMenu( splitter, "leftPanel" );
|
|
rightPanel = new PanelDeco( splitter, "rightPanel", i18n( "Find/Edit Recipes" ), "filefind" );
|
|
|
|
// Design Left Panel
|
|
|
|
START_TIMER("Setting up buttons")
|
|
// Buttons
|
|
buttonsList = new TQPtrList<KreMenuButton>();
|
|
buttonsList->setAutoDelete( TRUE );
|
|
|
|
button0 = new KreMenuButton( leftPanel, SelectP );
|
|
button0->setIconSet( il.loadIconSet( "filefind", TDEIcon::Panel, 32 ) );
|
|
buttonsList->append( button0 );
|
|
|
|
button1 = new KreMenuButton( leftPanel, ShoppingP );
|
|
button1->setIconSet( il.loadIconSet( "trolley", TDEIcon::Panel, 32 ) );
|
|
buttonsList->append( button1 );
|
|
|
|
button7 = new KreMenuButton( leftPanel, DietP );
|
|
button7->setIconSet( il.loadIconSet( "diet", TDEIcon::Panel, 32 ) );
|
|
buttonsList->append( button7 );
|
|
|
|
button8 = new KreMenuButton( leftPanel, MatcherP );
|
|
button8->setIconSet( il.loadIconSet( "categories", TDEIcon::Panel, 32 ) );
|
|
buttonsList->append( button8 );
|
|
|
|
|
|
// Submenus
|
|
dataMenu = leftPanel->createSubMenu( i18n( "Data" ), "2rightarrow" );
|
|
|
|
button2 = new KreMenuButton( leftPanel, IngredientsP, dataMenu );
|
|
button2->setIconSet( il.loadIconSet( "ingredients", TDEIcon::Panel, 32 ) );
|
|
//buttonsList->append(button2);
|
|
|
|
button3 = new KreMenuButton( leftPanel, PropertiesP, dataMenu );
|
|
button3->setIconSet( il.loadIconSet( "properties", TDEIcon::Panel, 32 ) );
|
|
buttonsList->append( button3 );
|
|
|
|
button4 = new KreMenuButton( leftPanel, UnitsP, dataMenu );
|
|
button4->setIconSet( il.loadIconSet( "units", TDEIcon::Panel, 32 ) );
|
|
buttonsList->append( button4 );
|
|
|
|
button9 = new KreMenuButton( leftPanel, PrepMethodsP, dataMenu );
|
|
button9->setIconSet( il.loadIconSet( "ICON PLEASE", TDEIcon::Panel, 32 ) );
|
|
buttonsList->append( button9 );
|
|
|
|
button5 = new KreMenuButton( leftPanel, CategoriesP, dataMenu );
|
|
button5->setIconSet( il.loadIconSet( "categories", TDEIcon::Panel, 32 ) );
|
|
buttonsList->append( button5 );
|
|
|
|
button6 = new KreMenuButton( leftPanel, AuthorsP, dataMenu );
|
|
button6->setIconSet( il.loadIconSet( "preferences-desktop-personal", TDEIcon::Panel, 32 ) );
|
|
buttonsList->append( button6 );
|
|
|
|
contextButton = new TQPushButton( leftPanel, "contextButton" );
|
|
contextButton->setIconSet( il.loadIconSet( "krectip", TDEIcon::Panel, 32 ) );
|
|
contextButton->setGeometry( leftPanel->width() - 42, leftPanel->height() - 42, 32, 32 );
|
|
contextButton->setPaletteBackgroundColor( contextButton->paletteBackgroundColor().light( 140 ) );
|
|
contextButton->setFlat( true );
|
|
END_TIMER()
|
|
|
|
config->setGroup( "Performance" );
|
|
int limit = config->readNumEntry( "CategoryLimit", -1 );
|
|
database->updateCategoryCache(limit);
|
|
|
|
// Right Panel Widgets
|
|
START_TIMER("Creating input dialog")
|
|
inputPanel = new RecipeInputDialog( rightPanel, database );
|
|
END_TIMER()
|
|
|
|
START_TIMER("Creating recipe view")
|
|
viewPanel = new RecipeViewDialog( rightPanel, database );
|
|
END_TIMER()
|
|
|
|
START_TIMER("Creating recipe selection dialog")
|
|
selectPanel = new SelectRecipeDialog( rightPanel, database );
|
|
END_TIMER()
|
|
|
|
START_TIMER("Creating ingredients component")
|
|
ingredientsPanel = new IngredientsDialog( rightPanel, database );
|
|
END_TIMER()
|
|
|
|
START_TIMER("Creating properties component")
|
|
propertiesPanel = new PropertiesDialog( rightPanel, database );
|
|
END_TIMER()
|
|
|
|
START_TIMER("Creating units component")
|
|
unitsPanel = new UnitsDialog( rightPanel, database );
|
|
END_TIMER()
|
|
|
|
START_TIMER("Creating shopping list dialog")
|
|
shoppingListPanel = new ShoppingListDialog( rightPanel, database );
|
|
END_TIMER()
|
|
|
|
START_TIMER("Creating diet wizard dialog")
|
|
dietPanel = new DietWizardDialog( rightPanel, database );
|
|
END_TIMER()
|
|
|
|
START_TIMER("Creating categories component")
|
|
categoriesPanel = new CategoriesEditorDialog( rightPanel, database );
|
|
END_TIMER()
|
|
|
|
START_TIMER("Creating authors component")
|
|
authorsPanel = new AuthorsDialog( rightPanel, database );
|
|
END_TIMER()
|
|
|
|
START_TIMER("Creating prep methods component")
|
|
prepMethodsPanel = new PrepMethodsDialog( rightPanel, database );
|
|
END_TIMER()
|
|
|
|
START_TIMER("Creating ingredients matcher dialog")
|
|
ingredientMatcherPanel = new IngredientMatcherDialog( rightPanel, database );
|
|
END_TIMER()
|
|
|
|
database->clearCategoryCache();
|
|
|
|
// Use to keep track of the panels
|
|
panelMap.insert( inputPanel, RecipeEdit );
|
|
panelMap.insert( viewPanel, RecipeView );
|
|
panelMap.insert( selectPanel, SelectP );
|
|
panelMap.insert( ingredientsPanel, IngredientsP );
|
|
panelMap.insert( propertiesPanel, PropertiesP );
|
|
panelMap.insert( unitsPanel, UnitsP );
|
|
panelMap.insert( shoppingListPanel, ShoppingP );
|
|
panelMap.insert( dietPanel, DietP );
|
|
panelMap.insert( categoriesPanel, CategoriesP );
|
|
panelMap.insert( authorsPanel, AuthorsP );
|
|
panelMap.insert( prepMethodsPanel, PrepMethodsP );
|
|
panelMap.insert( ingredientMatcherPanel, MatcherP );
|
|
|
|
m_activePanel = RecipeEdit;
|
|
|
|
// i18n
|
|
translate();
|
|
|
|
// Initialize Variables
|
|
recipeButton = 0;
|
|
|
|
|
|
|
|
// Connect Signals from Left Panel to slotSetPanel()
|
|
connect( leftPanel, TQ_SIGNAL( clicked( KrePanel ) ), this, TQ_SLOT( slotSetPanel( KrePanel ) ) );
|
|
|
|
connect( contextButton, TQ_SIGNAL( clicked() ), TQ_SLOT( activateContextHelp() ) );
|
|
|
|
connect( leftPanel, TQ_SIGNAL( resized( int, int ) ), this, TQ_SLOT( resizeRightPane( int, int ) ) );
|
|
|
|
|
|
// Retransmit signal to parent to Enable/Disable the Save Button
|
|
connect ( inputPanel, TQ_SIGNAL( enableSaveOption( bool ) ), this, TQ_SIGNAL( enableSaveOption( bool ) ) );
|
|
|
|
// Create a new button when a recipe is unsaved
|
|
connect ( inputPanel, TQ_SIGNAL( createButton( TQWidget*, const TQString & ) ), this, TQ_SLOT( addRecipeButton( TQWidget*, const TQString & ) ) );
|
|
|
|
// Connect Signals from selectPanel (SelectRecipeDialog)
|
|
|
|
connect ( selectPanel, TQ_SIGNAL( recipeSelected( int, int ) ), this, TQ_SLOT( actionRecipe( int, int ) ) );
|
|
connect ( selectPanel, TQ_SIGNAL( recipesSelected( const TQValueList<int>&, int ) ), this, TQ_SLOT( actionRecipes( const TQValueList<int>&, int ) ) );
|
|
|
|
// Connect Signals from ingredientMatcherPanel (IngredientMatcherDialog)
|
|
|
|
connect ( ingredientMatcherPanel, TQ_SIGNAL( recipeSelected( int, int ) ), TQ_SLOT( actionRecipe( int, int ) ) );
|
|
|
|
// Close a recipe when requested (just switch panels)
|
|
connect( inputPanel, TQ_SIGNAL( closeRecipe() ), this, TQ_SLOT( closeRecipe() ) );
|
|
|
|
// Show a recipe when requested (just switch panels)
|
|
connect( inputPanel, TQ_SIGNAL( showRecipe( int ) ), this, TQ_SLOT( showRecipe( int ) ) );
|
|
|
|
// Create a new shopping list when a new diet is generated and accepted
|
|
connect( dietPanel, TQ_SIGNAL( dietReady() ), this, TQ_SLOT( createShoppingListFromDiet() ) );
|
|
|
|
// Place the Tip Button in correct position when the left pane is resized
|
|
connect( leftPanel, TQ_SIGNAL( resized( int, int ) ), this, TQ_SLOT( moveTipButton( int, int ) ) );
|
|
|
|
connect( rightPanel, TQ_SIGNAL( panelRaised( TQWidget*, TQWidget* ) ), TQ_SLOT( panelRaised( TQWidget*, TQWidget* ) ) );
|
|
|
|
connect( selectPanel, TQ_SIGNAL( recipeSelected(bool) ), TQ_SIGNAL( recipeSelected(bool) ) );
|
|
|
|
// Close Splash Screen
|
|
delete start_logo;
|
|
|
|
#ifndef NDEBUG
|
|
kdDebug()<<"Total time elapsed: "<<dbg_total_timer.elapsed()/1000<<" sec"<<endl;
|
|
#endif
|
|
}
|
|
|
|
KrecipesView::~KrecipesView()
|
|
{
|
|
if (buttonsList)
|
|
delete buttonsList;
|
|
if (viewPanel)
|
|
delete viewPanel; //manually delete viewPanel because we need to be sure it is deleted
|
|
//before the database is because its destructor uses 'database'
|
|
if (database)
|
|
delete database;
|
|
}
|
|
|
|
bool KrecipesView::questionRerunWizard( const TQString &message, const TQString &error )
|
|
{
|
|
TQString yesNoMessage = message + " " + i18n( "\nWould you like to run the setup wizard again? Otherwise, the application will be closed." );
|
|
int answer = KMessageBox::questionYesNo( this, yesNoMessage );
|
|
|
|
if ( answer == KMessageBox::Yes )
|
|
wizard( true );
|
|
else {
|
|
kdError() << error << ". " << i18n( "Exiting" ) << endl;
|
|
kapp->exit( 1 ); exit ( 1 ); //FIXME: why doesn't kapp->exit(1) do anything?
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void KrecipesView::translate()
|
|
{
|
|
button0->setTitle( i18n( "Find/Edit Recipes" ) );
|
|
button1->setTitle( i18n( "Shopping List" ) );
|
|
button2->setTitle( i18n( "Ingredients" ) );
|
|
button3->setTitle( i18n( "Properties" ) );
|
|
button4->setTitle( i18n( "Units" ) );
|
|
button9->setTitle( i18n( "Preparation Methods" ) );
|
|
button5->setTitle( i18n( "Categories" ) );
|
|
button6->setTitle( i18n( "Authors" ) );
|
|
button7->setTitle( i18n( "Diet Helper" ) );
|
|
button8->setTitle( i18n( "Ingredient Matcher" ) );
|
|
}
|
|
|
|
void KrecipesView::print()
|
|
{
|
|
viewPanel->print();
|
|
}
|
|
|
|
|
|
void KrecipesView::slotSetTitle( const TQString& title )
|
|
{
|
|
emit signalChangeCaption( title );
|
|
}
|
|
|
|
// Function to switch panels
|
|
void KrecipesView::slotSetPanel( KrePanel p )
|
|
{
|
|
m_activePanel = p;
|
|
|
|
switch ( m_activePanel ) {
|
|
case SelectP:
|
|
rightPanel->setHeader( i18n( "Find/Edit Recipes" ), "filefind" );
|
|
rightPanel->raise( selectPanel );
|
|
break;
|
|
case ShoppingP:
|
|
rightPanel->setHeader( i18n( "Shopping List" ), "trolley" );
|
|
rightPanel->raise( shoppingListPanel );
|
|
shoppingListPanel->reload( Load );
|
|
break;
|
|
case DietP:
|
|
rightPanel->setHeader( i18n( "Diet Helper" ), "diet" );
|
|
rightPanel->raise( dietPanel );
|
|
dietPanel->reload( Load );
|
|
break;
|
|
case MatcherP:
|
|
rightPanel->setHeader( i18n( "Ingredient Matcher" ), "categories" );
|
|
rightPanel->raise( ingredientMatcherPanel );
|
|
ingredientMatcherPanel->reload( Load );
|
|
break;
|
|
|
|
case IngredientsP:
|
|
rightPanel->setHeader( i18n( "Ingredients" ), "ingredients" );
|
|
rightPanel->raise( ingredientsPanel );
|
|
ingredientsPanel->reload( Load );
|
|
break;
|
|
case PropertiesP:
|
|
rightPanel->setHeader( i18n( "Properties" ), "properties" );
|
|
rightPanel->raise( propertiesPanel );
|
|
//propertiesPanel->reload();
|
|
break;
|
|
case UnitsP:
|
|
rightPanel->setHeader( i18n( "Units" ), "units" );
|
|
rightPanel->raise( unitsPanel );
|
|
unitsPanel->reload( Load );
|
|
break;
|
|
case PrepMethodsP:
|
|
rightPanel->setHeader( i18n( "Preparation Methods" ), "GIVE ME AN ICON :p" );
|
|
rightPanel->raise( prepMethodsPanel );
|
|
prepMethodsPanel->reload( Load );
|
|
break;
|
|
case CategoriesP:
|
|
rightPanel->setHeader( i18n( "Categories" ), "categories" );
|
|
rightPanel->raise( categoriesPanel );
|
|
categoriesPanel->reload( Load );
|
|
break;
|
|
case AuthorsP:
|
|
rightPanel->setHeader( i18n( "Authors" ), "preferences-desktop-personal" );
|
|
rightPanel->raise( authorsPanel );
|
|
authorsPanel->reload( Load );
|
|
break;
|
|
case RecipeEdit:
|
|
rightPanel->setHeader( i18n( "Edit Recipe" ), "edit" );
|
|
rightPanel->raise( inputPanel );
|
|
break;
|
|
case RecipeView:
|
|
rightPanel->setHeader( i18n( "View Recipe" ), "filefind" );
|
|
rightPanel->raise( viewPanel );
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool KrecipesView::save( void )
|
|
{
|
|
return inputPanel->save();
|
|
}
|
|
|
|
/*!
|
|
\fn KrecipesView::exportRecipe()
|
|
*/
|
|
void KrecipesView::exportRecipe()
|
|
{
|
|
TQWidget * vis_panel = rightPanel->visiblePanel();
|
|
if ( vis_panel == viewPanel && viewPanel->recipesLoaded() > 0 ) {
|
|
exportRecipes( viewPanel->currentRecipes() );
|
|
}
|
|
else if ( vis_panel == selectPanel ) {
|
|
selectPanel->getActionsHandler()->recipeExport();
|
|
}
|
|
}
|
|
|
|
void KrecipesView::exportToClipboard()
|
|
{
|
|
TQWidget * vis_panel = rightPanel->visiblePanel();
|
|
if ( vis_panel == viewPanel && viewPanel->recipesLoaded() > 0 ) {
|
|
TQValueList<int> ids = viewPanel->currentRecipes();
|
|
RecipeActionsHandler::recipesToClipboard( ids, database );
|
|
}
|
|
else if ( vis_panel == selectPanel ) {
|
|
selectPanel->getActionsHandler()->recipesToClipboard();
|
|
}
|
|
}
|
|
|
|
void KrecipesView::exportRecipes( const TQValueList<int> &ids )
|
|
{
|
|
if ( ids.count() == 1 )
|
|
RecipeActionsHandler::exportRecipes( ids, i18n( "Export Recipe" ), database->recipeTitle( ids[ 0 ] ), database );
|
|
else
|
|
RecipeActionsHandler::exportRecipes( ids, i18n( "Export Recipe" ), i18n( "Recipes" ), database );
|
|
}
|
|
|
|
void KrecipesView::actionRecipe( int recipeID, int action )
|
|
{
|
|
switch ( action ) {
|
|
case 0: //Show
|
|
{
|
|
showRecipe( recipeID );
|
|
break;
|
|
}
|
|
case 1: // Edit
|
|
{
|
|
if ( !inputPanel->everythingSaved() )
|
|
{
|
|
switch ( KMessageBox::questionYesNoCancel( this,
|
|
TQString( i18n( "A recipe contains unsaved changes.\n"
|
|
"Do you want to save changes made to this recipe before editing another recipe?" ) ),
|
|
i18n( "Unsaved changes" ) ) ) {
|
|
case KMessageBox::Yes:
|
|
inputPanel->save();
|
|
break;
|
|
case KMessageBox::No:
|
|
break;
|
|
case KMessageBox::Cancel:
|
|
return ;
|
|
}
|
|
}
|
|
|
|
inputPanel->loadRecipe( recipeID );
|
|
slotSetPanel( RecipeEdit );
|
|
break;
|
|
}
|
|
case 2: //Remove
|
|
{
|
|
switch ( KMessageBox::questionYesNo( this,
|
|
TQString( i18n( "Are you sure you want to permanently remove the recipe, %1?" ) ).arg(database->recipeTitle(recipeID)),
|
|
i18n( "Confirm remove" ) ) )
|
|
{
|
|
case KMessageBox::Yes:
|
|
database->removeRecipe( recipeID );
|
|
break;
|
|
case KMessageBox::No:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 3: //Add to shopping list
|
|
{
|
|
shoppingListPanel->addRecipeToShoppingList( recipeID );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void KrecipesView::actionRecipes( const TQValueList<int> &ids, int action )
|
|
{
|
|
if ( action == 0 ) //show
|
|
{
|
|
showRecipes( ids );
|
|
}
|
|
}
|
|
|
|
|
|
void KrecipesView::createNewRecipe( void )
|
|
{
|
|
if ( !inputPanel->everythingSaved() ) {
|
|
switch ( KMessageBox::questionYesNoCancel( this,
|
|
TQString( i18n( "A recipe contains unsaved changes.\n"
|
|
"Do you want to save changes made to this recipe before creating a new recipe?" ) ),
|
|
i18n( "Unsaved changes" ) ) ) {
|
|
case KMessageBox::Yes:
|
|
inputPanel->save();
|
|
break;
|
|
case KMessageBox::No:
|
|
break;
|
|
case KMessageBox::Cancel:
|
|
return ;
|
|
}
|
|
}
|
|
|
|
inputPanel->newRecipe();
|
|
slotSetPanel( RecipeEdit );
|
|
}
|
|
|
|
void KrecipesView::createNewElement( void )
|
|
{
|
|
//this is inconstant as the program stands...
|
|
/*if (rightPanel->visiblePanel())==4) //Properties Panel is the active one
|
|
{
|
|
propertiesPanel->createNewProperty();
|
|
}
|
|
else*/{
|
|
createNewRecipe();
|
|
}
|
|
}
|
|
|
|
void KrecipesView::wizard( bool force )
|
|
{
|
|
TDEConfig * config = kapp->config();
|
|
config->setGroup( "Wizard" );
|
|
bool setupDone = config->readBoolEntry( "SystemSetup", false );
|
|
|
|
TQString setupVersion = config->readEntry( "Version", "0.3" ); // By default assume it's 0.3. This parameter didn't exist in that version yet.
|
|
|
|
if ( !setupDone || ( setupVersion.toDouble() < 0.5 ) || force ) // The config structure changed in version 0.4 to have DBType and Config Structure version
|
|
{
|
|
|
|
bool setupUser, initData, doUSDAImport, adminEnabled;
|
|
TQString adminUser, adminPass, user, pass, host, client, dbName;
|
|
int port;
|
|
bool isRemote;
|
|
|
|
SetupWizard *setupWizard = new SetupWizard( this );
|
|
if ( setupWizard->exec() == TQDialog::Accepted )
|
|
{
|
|
TDEConfig * config;
|
|
config = kapp->config();
|
|
config->sync();
|
|
config->setGroup( "DBType" );
|
|
dbType = config->readEntry( "Type", "SQLite" );
|
|
|
|
kdDebug() << "Setting up" << endl;
|
|
setupWizard->getOptions( setupUser, initData, doUSDAImport );
|
|
|
|
// Setup user if necessary
|
|
if ( ( dbType == "MySQL" || dbType == "PostgreSQL" ) && setupUser ) // Don't setup user if checkbox of existing user... was set
|
|
{
|
|
kdDebug() << "Setting up user\n";
|
|
setupWizard->getAdminInfo( adminEnabled, adminUser, adminPass, dbType );
|
|
setupWizard->getServerInfo( isRemote, host, client, dbName, user, pass, port );
|
|
|
|
if ( !adminEnabled ) // Use root without password
|
|
{
|
|
kdDebug() << "Using default admin\n";
|
|
if ( dbType == "MySQL" )
|
|
adminUser = "root";
|
|
else if ( dbType == "PostgreSQL" )
|
|
adminUser = "postgres";
|
|
adminPass = TQString::null;
|
|
}
|
|
if ( !isRemote ) // Use localhost
|
|
{
|
|
kdDebug() << "Using localhost\n";
|
|
host = "localhost";
|
|
client = "localhost";
|
|
}
|
|
|
|
setupUserPermissions( host, client, dbName, user, pass, adminUser, adminPass, port );
|
|
}
|
|
|
|
// Initialize database with data if requested
|
|
if ( initData ) {
|
|
setupWizard->getServerInfo( isRemote, host, client, dbName, user, pass, port );
|
|
initializeData( host, dbName, user, pass, port ); // Populate data as normal user
|
|
}
|
|
|
|
if ( doUSDAImport ) {
|
|
// Open the DB first
|
|
setupWizard->getServerInfo( isRemote, host, client, dbName, user, pass, port ); //only used if needed by backend
|
|
RecipeDB *db = RecipeDB::createDatabase( dbType, host, user, pass, dbName, port, dbName );
|
|
|
|
// Import the data
|
|
if ( db ) {
|
|
db->connect();
|
|
|
|
if ( db->ok() ) {
|
|
ProgressInterface pi(this);
|
|
pi.listenOn(db);
|
|
db->importUSDADatabase();
|
|
}
|
|
|
|
//close the database whether ok() or not
|
|
delete db;
|
|
}
|
|
}
|
|
|
|
//we can do a faster usda import if this is done after it
|
|
if ( initData ) {
|
|
RecipeDB *db = RecipeDB::createDatabase( dbType, host, user, pass, dbName, port, dbName );
|
|
if ( db ) {
|
|
db->connect();
|
|
|
|
if ( db->ok() ) {
|
|
db->importSamples();
|
|
}
|
|
|
|
//close the database whether ok() or not
|
|
delete db;
|
|
}
|
|
}
|
|
|
|
}
|
|
delete setupWizard;
|
|
}
|
|
}
|
|
|
|
|
|
void KrecipesView::setupUserPermissions( const TQString &host, const TQString &client, const TQString &dbName, const TQString &newUser, const TQString &newPass, const TQString &adminUser, const TQString &adminPass, int port )
|
|
{
|
|
TQString user = adminUser;
|
|
TQString pass = adminPass;
|
|
if ( user.isNull() ) {
|
|
pass = TQString::null;
|
|
|
|
if ( dbType == "PostgreSQL" )
|
|
user = "postgres";
|
|
else if ( dbType == "MySQL" )
|
|
user = "root";
|
|
|
|
kdDebug() << "Open db as " << user << ", with no password\n";
|
|
}
|
|
else
|
|
kdDebug() << "Open db as:" << user << ",*** with password ****\n";
|
|
|
|
RecipeDB *db = RecipeDB::createDatabase( dbType, host, user, pass, dbName, port, dbName );
|
|
if ( db ) {
|
|
db->connect(true,false);//create the database, but no tables (do that when connected as the user)
|
|
if ( db->ok() )
|
|
db->givePermissions( dbName, newUser, newPass, client ); // give permissions to the user
|
|
else
|
|
questionRerunWizard( db->err(), i18n( "Unable to setup database" ) );
|
|
}
|
|
|
|
delete db; //it closes the db automatically
|
|
}
|
|
|
|
|
|
void KrecipesView::initializeData( const TQString &host, const TQString &dbName, const TQString &user, const TQString &pass, int port )
|
|
{
|
|
RecipeDB * db = RecipeDB::createDatabase( dbType, host, user, pass, dbName, port, dbName );
|
|
if ( !db ) {
|
|
kdError() << i18n( "Code error. No DB support has been included. Exiting" ) << endl;
|
|
kapp->exit( 1 );
|
|
}
|
|
|
|
db->connect();
|
|
|
|
if ( db->ok() ) {
|
|
db->emptyData();
|
|
db->initializeData();
|
|
}
|
|
|
|
delete db;
|
|
}
|
|
|
|
void KrecipesView::addRecipeButton( TQWidget *w, const TQString &title )
|
|
{
|
|
recipeWidget = w;
|
|
TDEIconLoader il;
|
|
if ( !recipeButton ) {
|
|
recipeButton = new KreMenuButton( leftPanel, RecipeEdit );
|
|
|
|
recipeButton->setIconSet( il.loadIconSet( "document-save", TDEIcon::Small ) );
|
|
|
|
TQString short_title = title.left( 20 );
|
|
if ( title.length() > 20 )
|
|
short_title.append( "..." );
|
|
|
|
recipeButton->setTitle( short_title );
|
|
|
|
buttonsList->append( recipeButton );
|
|
leftPanel->highlightButton( recipeButton );
|
|
|
|
connect( recipeButton, TQ_SIGNAL( clicked() ), this, TQ_SLOT( switchToRecipe() ) );
|
|
connect( ( RecipeInputDialog * ) w, TQ_SIGNAL( titleChanged( const TQString& ) ), recipeButton, TQ_SLOT( setTitle( const TQString& ) ) );
|
|
}
|
|
|
|
}
|
|
|
|
void KrecipesView::switchToRecipe( void )
|
|
{
|
|
slotSetPanel( RecipeEdit );
|
|
}
|
|
|
|
void KrecipesView::closeRecipe( void )
|
|
{
|
|
slotSetPanel( SelectP );
|
|
buttonsList->removeLast();
|
|
recipeButton = 0;
|
|
}
|
|
|
|
//Needed to make sure that the raise() is done after the construction of all the widgets, otherwise childEvent in the PanelDeco is called only _after_ the raise(), and can't be shown.
|
|
|
|
void KrecipesView::show ( void )
|
|
{
|
|
slotSetPanel( SelectP );
|
|
TQWidget::show();
|
|
}
|
|
|
|
void KrecipesView::showRecipe( int recipeID )
|
|
{
|
|
TQValueList<int> ids;
|
|
ids << recipeID;
|
|
showRecipes( ids );
|
|
}
|
|
|
|
void KrecipesView::showRecipes( const TQValueList<int> &recipeIDs )
|
|
{
|
|
if ( viewPanel->loadRecipes( recipeIDs ) )
|
|
slotSetPanel( RecipeView );
|
|
}
|
|
|
|
void KrecipesView::activateContextHelp()
|
|
{
|
|
switch ( m_activePanel ) {
|
|
case RecipeView:
|
|
//kapp->invokeHelp("");
|
|
break;
|
|
|
|
case SelectP:
|
|
kapp->invokeHelp("find-edit");
|
|
break;
|
|
|
|
case ShoppingP:
|
|
kapp->invokeHelp("shopping-list");
|
|
break;
|
|
|
|
case DietP:
|
|
kapp->invokeHelp("diet-helper");
|
|
break;
|
|
|
|
case MatcherP:
|
|
kapp->invokeHelp("ingredient-matcher");
|
|
break;
|
|
|
|
case RecipeEdit:
|
|
kapp->invokeHelp("enter-edit-recipes");
|
|
break;
|
|
|
|
case IngredientsP:
|
|
kapp->invokeHelp("ingredients-component");
|
|
break;
|
|
|
|
case PropertiesP:
|
|
kapp->invokeHelp("properties-component");
|
|
break;
|
|
|
|
case UnitsP:
|
|
kapp->invokeHelp("units-component");
|
|
break;
|
|
|
|
case PrepMethodsP:
|
|
kapp->invokeHelp("prep-methods");
|
|
break;
|
|
|
|
case CategoriesP:
|
|
kapp->invokeHelp("categories-component");
|
|
break;
|
|
|
|
case AuthorsP:
|
|
kapp->invokeHelp("authors-component");
|
|
break;
|
|
}
|
|
}
|
|
|
|
void KrecipesView::panelRaised( TQWidget *w, TQWidget *old_w )
|
|
{
|
|
emit panelShown( panelMap[ old_w ], false );
|
|
emit panelShown( panelMap[ w ], true );
|
|
}
|
|
|
|
|
|
void KrecipesView::createShoppingListFromDiet( void )
|
|
{
|
|
shoppingListPanel->createShopping( dietPanel->dietList() );
|
|
slotSetPanel( ShoppingP );
|
|
}
|
|
|
|
void KrecipesView::moveTipButton( int, int )
|
|
{
|
|
contextButton->setGeometry( leftPanel->width() - 42, leftPanel->height() - 42, 32, 32 );
|
|
}
|
|
|
|
void KrecipesView::resizeRightPane( int lpw, int )
|
|
{
|
|
TQSize rpsize = rightPanel->size();
|
|
TQPoint rpplace = rightPanel->pos();
|
|
rpsize.setWidth( width() - lpw );
|
|
rpplace.setX( lpw );
|
|
rightPanel->move( rpplace );
|
|
rightPanel->resize( rpsize );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KrecipesView::initDatabase( TDEConfig *config )
|
|
{
|
|
|
|
// Read the database type
|
|
config->sync();
|
|
config->setGroup( "DBType" );
|
|
dbType = checkCorrectDBType( config );
|
|
|
|
|
|
|
|
// Open the database
|
|
database = RecipeDB::createDatabase( dbType );
|
|
if ( !database ) {
|
|
// No DB type has been enabled(should not happen at all, but just in case)
|
|
|
|
kdError() << i18n( "Code error. No DB support was built in. Exiting" ) << endl;
|
|
kapp->exit( 1 );
|
|
}
|
|
|
|
database->connect();
|
|
|
|
while ( !database->ok() ) {
|
|
// Ask the user if he wants to rerun the wizard
|
|
bool rerun = questionRerunWizard( database->err(), i18n( "Unable to open database" ) );
|
|
if ( !rerun )
|
|
break;
|
|
|
|
// Reread the configuration file.
|
|
// The user may have changed the data and/or DB type
|
|
|
|
config->sync();
|
|
config->setGroup( "DBType" );
|
|
dbType = checkCorrectDBType( config );
|
|
|
|
delete database;
|
|
database = RecipeDB::createDatabase( dbType );
|
|
if ( database )
|
|
database->connect();
|
|
else {
|
|
// No DB type has been enabled (should not happen at all, but just in case)
|
|
|
|
kdError() << i18n( "Code error. No DB support was built in. Exiting" ) << endl;
|
|
kapp->exit( 1 );
|
|
break;
|
|
}
|
|
}
|
|
kdDebug() << i18n( "DB started correctly\n" ).latin1();
|
|
}
|
|
|
|
TQString KrecipesView::checkCorrectDBType( TDEConfig *config )
|
|
{
|
|
dbType = config->readEntry( "Type", "SQLite" );
|
|
|
|
while ( ( dbType != "SQLite" ) && ( dbType != "MySQL" ) && ( dbType != "PostgreSQL" ) ) {
|
|
questionRerunWizard( i18n( "The configured database type (%1) is unsupported." ).arg( dbType ), i18n( "Unsupported database type. Database must be either MySQL, SQLite, or PostgreSQL." ) );
|
|
|
|
// Read the database setup again
|
|
|
|
config = kapp->config();
|
|
config->sync();
|
|
config->setGroup( "DBType" );
|
|
dbType = config->readEntry( "Type", "SQLite" );
|
|
}
|
|
return ( dbType );
|
|
}
|
|
|
|
void KrecipesView::reloadDisplay()
|
|
{
|
|
viewPanel->reload();
|
|
}
|
|
|
|
void KrecipesView::editRecipe()
|
|
{
|
|
KrePanel vis_panel = panelMap[ rightPanel->visiblePanel() ];
|
|
|
|
switch ( vis_panel ) {
|
|
case RecipeView:
|
|
actionRecipe( viewPanel->currentRecipes() [ 0 ], 1 );
|
|
break;
|
|
case SelectP:
|
|
selectPanel->getActionsHandler()->edit();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void KrecipesView::reload()
|
|
{
|
|
viewPanel->reload();
|
|
selectPanel->reload( ForceReload );
|
|
shoppingListPanel->reload( ReloadIfPopulated );
|
|
ingredientsPanel->reload( ReloadIfPopulated );
|
|
propertiesPanel->reload();
|
|
unitsPanel->reload( ReloadIfPopulated );
|
|
dietPanel->reload( ReloadIfPopulated );
|
|
authorsPanel->reload( ReloadIfPopulated );
|
|
categoriesPanel->reload( ReloadIfPopulated );
|
|
ingredientMatcherPanel->reload( ReloadIfPopulated );
|
|
prepMethodsPanel->reload( ReloadIfPopulated );
|
|
}
|
|
|
|
DCOPRef KrecipesView::currentDatabase() const
|
|
{
|
|
return DCOPRef(database);
|
|
}
|
|
|
|
|
|
#include "krecipesview.moc"
|