summaryrefslogtreecommitdiffstats
path: root/src/krecipesview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/krecipesview.cpp')
-rw-r--r--src/krecipesview.cpp942
1 files changed, 942 insertions, 0 deletions
diff --git a/src/krecipesview.cpp b/src/krecipesview.cpp
new file mode 100644
index 0000000..b9f79d1
--- /dev/null
+++ b/src/krecipesview.cpp
@@ -0,0 +1,942 @@
+
+/***************************************************************************
+* Copyright (C) 2003-2004 by *
+* Unai Garro ([email protected]) *
+* Cyril Bosselut ([email protected]) *
+* Jason Kivlighn ([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 "krecipesview.h"
+
+#include <cstdlib>
+
+#include <tqlayout.h>
+#include <tqimage.h>
+#include <tqpainter.h>
+#include <tqpalette.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"