Main | License | Installation | FAQ | Screenshots | Contact | Links | Sf.net | Freshmeat.net | KDE-Apps.org
Requirements | Design | Modules | Class Hierarchy | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

anyMeal.ui.h

Go to the documentation of this file.
00001 /* Copyright (C) 2002, 2003, 2004, 2005 Jan Wedekind.
00002    This file is part of the recipe database application AnyMeal.
00003 
00004    AnyMeal is free software; you can redistribute it and/or modify it under
00005    the terms of the GNU GENERAL PUBLIC LICENSE as published by the Free
00006    Software Foundation; either version 3 of the License, or (at your option)
00007    any later version.
00008 
00009    AnyMeal is distributed in the hope that it will be useful, but WITHOUT ANY
00010    WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS
00011    FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
00012    details.
00013 
00014    You should have received a copy of the GNU General Public License
00015    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
00016 /****************************************************************************
00017  ** ui.h extension file, included from the uic-generated form implementation.
00018  **
00019  ** If you wish to add, delete or rename slots use Qt Designer which will
00020  ** update this file, preserving your code. Create an init() slot in place of
00021  ** a constructor, and a destroy() slot in place of a destructor.
00022  *****************************************************************************/
00023 
00024 #ifdef XERCES_HAS_CPP_NAMESPACE
00025 using namespace XERCES_CPP_NAMESPACE;
00026 #endif
00027 #ifdef XALAN_HAS_CPP_NAMESPACE
00028 using namespace XALAN_CPP_NAMESPACE;
00029 #endif
00030 
00031 void AnyMeal::helpIndex()
00032 {
00033   
00034 }
00035 
00036 void AnyMeal::helpContents()
00037 {
00038 
00039 }
00040 
00041 void AnyMeal::helpAbout()
00042 {
00043   KAboutApplication aboutDialog( this, "aboutDialog", true );
00044   aboutDialog.exec();
00045   statusBar()->message( i18n( "License was displayed." ), STATUSDISPLAYTIME );
00046 }
00047 
00048 
00049 void AnyMeal::fileImportMM()
00050 {
00052   assert( cookBook );
00053 
00054   ImportMealMasterDialog importMealMasterDialog( this );
00055   importMealMasterDialog.cookBook = cookBook;
00056   
00057   if ( importMealMasterDialog.exec() )
00058     statusBar()->message( i18n( "Imported Mealmaster file(s)." ),
00059                           STATUSDISPLAYTIME );
00060   else
00061     statusBar()->message( i18n( "Import aborted." ), STATUSDISPLAYTIME );
00062 }
00063 
00064 extern boost::shared_ptr< KSplashScreen > splash;
00065 
00066 void AnyMeal::init()
00067 {
00068   assert( splash );
00069   splash->message( i18n( "Initialising docbook export ..." ) );
00070   recipeToDocbook =
00071     XSLCompilerPtr
00072     ( new XSLCompiler( findAnyMealFile( "appdata", "scripts/recipeToDocbook.xsl" ),
00073                        FormatterListener::OUTPUT_METHOD_XML,
00074                        HTMLENCODING,
00075                        findAnyMealFile( "appdata", "scripts/anymeal.xsd" ) ) );
00076   recipeToDocbook->setParam( "lfile", std::string( "\"file://" ) +
00077                              dictionaryFile() + "\"" );
00078   recipeToDocbook->setParam( "lname", std::string( "\"" ) + anyMealLanguage() +
00079                              "\"" );
00080 
00081   splash->message( i18n( "Initialising Mealmaster export ..." ) );
00082   recipeToMealMaster =
00083     XSLCompilerPtr
00084     ( new XSLCompiler( findAnyMealFile( "appdata", "scripts/recipeToMealMaster.xsl" ),
00085                        FormatterListener::OUTPUT_METHOD_TEXT,
00086                        MMENCODING,
00087                        findAnyMealFile( "appdata", "scripts/anymeal.xsd" ) ) );
00088   recipeToMealMaster->setParam( "mfile", std::string( "\"file://" ) +
00089                                 mealmasterMapFile() + "\"" );
00090 
00091   splash->message( i18n( "Initialising HTML export ..." ) );
00092   docbookToHTML =
00093     CompilerPtr
00094     ( new XSLCompiler( DOCBOOK"/html/docbook.xsl",
00095                        FormatterListener::OUTPUT_METHOD_HTML,
00096                        HTMLENCODING, "" ) );
00097 
00098   splash->message( i18n( "Initialising fast HTML ..." ) );
00099   recipeToHTML =
00100     XSLCompilerPtr
00101     ( new XSLCompiler( findAnyMealFile( "appdata", "scripts/recipeToHTML.xsl" ),
00102                        FormatterListener::OUTPUT_METHOD_HTML,
00103                        HTMLENCODING,
00104                        findAnyMealFile( "appdata", "scripts/anymeal.xsd" ) ) );
00105   recipeToHTML->setParam( "lfile", std::string( "\"file://" ) +
00106                           dictionaryFile() + "\"" );
00107   recipeToHTML->setParam( "lname", std::string( "\"" ) + anyMealLanguage() +
00108                           "\"" );
00109 
00110   splash->message( i18n( "Initialising Formatted Objects export ..." ) );
00111   docbookToFO =
00112     XSLCompilerPtr
00113     ( new XSLCompiler( findAnyMealFile( "appdata", "scripts/docbookToFo.xsl" ),
00114                        FormatterListener::OUTPUT_METHOD_XML,
00115                        HTMLENCODING, "" ) );
00116   docbookToFO->setParam( "paper.type", "\"A4\"" );
00117 
00118   splash->message( i18n( "Initialising RecipeML export ..." ) );
00119   recipeToRecipeML =
00120     CompilerPtr
00121     ( new XSLCompiler( findAnyMealFile( "appdata", "scripts/recipeToRecipeML.xsl" ),
00122                        FormatterListener::OUTPUT_METHOD_XML,
00123                        HTMLENCODING,
00124                        findAnyMealFile( "appdata", "scripts/anymeal.xsd" ) ) );
00125 
00126   recipeMLToRecipe =
00127     XSLCompilerPtr
00128     ( new XSLCompiler( findAnyMealFile( "appdata",
00129                                         "scripts/recipeMLToRecipe.xsl" ),
00130                        FormatterListener::OUTPUT_METHOD_XML,
00131                        "UTF-8",
00132                        findAnyMealFile( "appdata", "scripts/recipeML.xsd" ) ) );
00133   statusBar()->message( i18n( "AnyMeal - Make the most of your food!" ),
00134                         STATUSDISPLAYTIME );
00135 }
00136 
00137 
00138 void AnyMeal::destroy()
00139 {
00140   recipeMLToRecipe.reset();
00141   recipeToRecipeML.reset();
00142   docbookToFO.reset();
00143   recipeToHTML.reset();
00144   docbookToHTML.reset();
00145   recipeToMealMaster.reset();
00146   recipeToDocbook.reset();
00147 
00148   cookBook.reset();
00149   mysqlDatabase.reset();
00150   networkServer.reset();
00151   socketServer.reset();
00152 }
00153 
00154 
00155 void AnyMeal::fileConnect()
00156 {
00157   ConnectDialog connectDialog( this, "connectDialog" );
00158 
00159   if ( connectDialog.exec() )
00160     connectDatabase( connectDialog );
00161   else
00162     statusBar()->message
00163       ( i18n( "Connecting to database was aborted." ), STATUSDISPLAYTIME );
00164 
00165 }
00166 
00167 void AnyMeal::connectDatabase( ConnectDialog &connectDialog )
00168 {
00169   MySQLDatabasePtr newMySQLDatabase;
00170 
00171   try {
00172 
00173     DisplayWaitCursor w;
00174 
00175     MySQLNetworkPtr newNetworkServer;
00176     MySQLSocketPtr newSocketServer;
00177     MySQLServerPtr server;
00178     switch ( connectDialog.serverTypeCombo->currentItem() ) {
00179     case 0:
00180       newNetworkServer = MySQLNetworkPtr
00181         ( new MySQLNetwork( connectDialog.userCombo->currentText(),
00182                             connectDialog.passWordCheckBox->isChecked() ?
00183                             (const char *)connectDialog.passWordEdit->text() :
00184                             "",
00185                             connectDialog.serverCombo->currentText(),
00186                             MYSQL_PORT ) );
00187       server = newNetworkServer;
00188       break;
00189     case 1:
00190       newSocketServer = MySQLSocketPtr
00191         ( new MySQLSocket
00192           ( connectDialog.userCombo->currentText(),
00193             connectDialog.passWordCheckBox->isChecked() ?
00194             (const char *)connectDialog.passWordEdit->text() :
00195             "",
00196             connectDialog.socketCombo->currentText(),
00197             MySQLDaemonPtr( new MySQLDaemon
00198                             ( connectDialog.folderEdit->text(), 
00199                               connectDialog.socketCombo->currentText() ) ) ) );
00200       server = newSocketServer;
00201       break;
00202     default:
00203       assert(false);
00204     };
00205 
00206     newMySQLDatabase = MySQLDatabasePtr
00207       ( new MySQLDatabase
00208         ( server, connectDialog.databaseCombo->currentText() ) );
00209 
00210     // Try to connect to database.
00211     CookBookPtr newCookBook
00212       ( new CookBook
00213         ( newMySQLDatabase,
00214           findAnyMealFile( "appdata", "scripts/mysqlIn.xsl" ),
00215           findAnyMealFile( "appdata", "scripts/mysqlOut.xsl" ) ) );
00216       
00217     // Count recipes.
00218     int number = getNumRecipes( newCookBook );
00219 
00220     // Close existing connections.
00221     cookBook = newCookBook;
00222     mysqlDatabase = newMySQLDatabase;
00223     networkServer = newNetworkServer;
00224     socketServer = newSocketServer;
00225 
00226     // Close all windows.
00227     workSpace->closeAllWindows();
00228     searchDialog.reset();
00229 
00230     // Store data in kwallet after successful connection.
00231     connectDialog.updateWallet();
00232 
00233     // Enable/disable some qt actions.
00234     importMMAction->setEnabled( true );
00235     importRecipeMLAction->setEnabled( true );
00236     fileExportMealmasterAction->setEnabled( true );
00237     advancedSearchAction->setEnabled( true );
00238     editNewRecipeAction->setEnabled( true );
00239     databaseInfoAction->setEnabled( true );
00240     databaseLogAction->setEnabled( socketServer );
00241     fileConnectAction->setEnabled( false );
00242     fileDisconnectAction->setEnabled( true );
00243     fileDeleteAction->setEnabled( false );
00244 
00245     statusBar()->message
00246       ( i18n( "Connected to database \"%1\" containing %2 recipes." ).
00247         arg( connectDialog.databaseCombo->currentText() ).
00248         arg( number ),
00249         STATUSDISPLAYTIME );
00250 
00251   } catch ( CookBookDeprecated &e ) {
00252     
00253     try {
00254       
00255       int version = e.getVersion();
00256 
00257       if ( KMessageBox::warningContinueCancel
00258            ( this,
00259              i18n( "Do you want to update the database from version %1 to "
00260                    "version %2? It is recommended to do a backup before." ).
00261              arg( versionText( version ) ).
00262              arg( versionText( DATABASEVERSION ) ),
00263              i18n( "Update Database" ) ) ==
00264            KMessageBox::Continue ) {
00265         
00266         DisplayWaitCursor w;
00267          
00268         // View as cookbook without performing version-check and update.
00269         CookBook( newMySQLDatabase,
00270                   findAnyMealFile( "appdata", "scripts/mysqlIn.xsl" ),
00271                   findAnyMealFile( "appdata", "scripts/mysqlOut.xsl" ),
00272                   false ).update();
00273             
00274         // On success first disconnect.
00275         newMySQLDatabase.reset();
00276         
00277         // Retry connecting.
00278         connectDatabase( connectDialog );
00279         
00280       } else
00281         throw e;
00282 
00283     } catch ( Error &e ) {
00284       
00285       KMessageBox::error( this, e.what() );
00286       statusBar()->message( e.what(), STATUSDISPLAYTIME );
00287 
00288     };
00289 
00290   } catch ( Error &e ) {
00291 
00292     KMessageBox::error( this, e.what() );
00293     statusBar()->message( e.what(), STATUSDISPLAYTIME );
00294 
00295   };
00296 }
00297 
00298 void AnyMeal::displayRecipe( int id )
00299 {
00300   try {
00301 
00302     DisplayWaitCursor w;
00303     
00304     // Query recipe with specified identity number.
00305     std::stringstream query;
00306     query << "<?xml version='1.0' encoding='UTF-8'?>" << std::endl
00307           << "<query><selection><single>" << id
00308           << "</single></selection></query>" << std::endl;
00309     
00310     std::ostringstream xmlOut;
00311     
00312     cookBook->getXMLLayer()->translate( query, xmlOut );
00313     
00314     // Display result.
00315     RecipeDisplay *recipeDisplay =
00316       new RecipeDisplay( workSpace, 0, WDestructiveClose );
00317     recipeDisplay->setRecipeToHTML
00318       ( recipeToHTML );
00319     recipeDisplay->setRecipe( id, xmlOut.str() );
00320     connect( this,
00321              SIGNAL( changeRecipeId( int, int, const QString &, const QString & ) ),
00322              recipeDisplay,
00323              SLOT( recipeIdChanged( int, int, const QString &, const QString & ) ) );
00324     connect( this, SIGNAL( deleteRecipeId( int ) ),
00325              recipeDisplay, SLOT( recipeIdDeleted( int ) ) );
00326     recipeDisplay->show();
00327     
00328     statusBar()->message( i18n( "Displaying recipe number %1." ).arg( id ),
00329                           STATUSDISPLAYTIME );
00330     
00331   } catch ( Error &e ) {
00332 #ifndef NDEBUG
00333     std::cerr << e.what() << std::endl;
00334 #endif
00335     KMessageBox::error( this, e.what() );
00336     statusBar()->message( e.what(), STATUSDISPLAYTIME );
00337   };
00338 }
00339 
00340 void AnyMeal::editRecipe( int id )
00341 {
00342 
00343   try {
00344 
00345     std::ostringstream recipe;
00346     {
00347       DisplayWaitCursor w;
00348 
00349       std::stringstream query;
00350       // Query recipe with specified identity number.
00351       query << "<?xml version='1.0' encoding='UTF-8'?>" << std::endl
00352             << "<query><selection><single>" << id
00353             << "</single></selection></query>" << std::endl;
00354       
00355       cookBook->getXMLLayer()->translate( query, recipe );
00356     };
00357 
00358 #ifndef NDEBUG
00359     std::cerr << recipe.str() << std::endl;
00360 #endif
00361 
00362     RecipeEditor recipeEditor( this, "recipeEditor" );
00363     recipeEditor.setRecipe( recipe.str() );
00364 
00365     if ( recipeEditor.exec() ) {
00366         
00367       DisplayWaitCursor w;
00368 
00369       // Replace recipe.
00370       std::ostringstream query;
00371       query << "<?xml version='1.0' encoding='UTF-8'?>"
00372             << std::endl << "<replace>" << std::endl
00373             << recipeEditor.getRecipe() << std::endl
00374             << "<selection><single>" << id << "</single></selection>"
00375             << std::endl << "</replace>" << std::endl;
00376 
00377 #ifndef NDEBUG
00378       std::cerr << query.str() << std::endl;
00379 #endif
00380 
00381       XMLDocument xmlDocument( "" );
00382       xmlDocument.fromString( cookBook->getXMLLayer()->
00383                               translate( query.str() ) );
00384 
00385       int newId = atoi( xmlDocument.getDocumentElement().
00386                         selectNode( "recipe/id" ).getNodeText().c_str() );
00387       std::string newTitle( xmlDocument.getDocumentElement().
00388                             selectNode( "recipe/title" ).getNodeText() );
00389 
00390       // Inform other windows.
00391       std::ostringstream xmlRecipe;
00392       xmlRecipe << "<?xml version='1.0' encoding='UTF-8'?>" << std::endl
00393                 << "<insert>" << std::endl
00394                 << recipeEditor.getRecipe() << std::endl
00395                 << "</insert>";
00396       emit changeRecipeId( id, newId, newTitle.c_str(),
00397                            xmlRecipe.str().c_str() );
00398 
00399       // Update statusbar.
00400       statusBar()->message( i18n( "Edited recipe number %1 (was %2)." ).
00401                             arg( newId ).arg( id ),
00402                             STATUSDISPLAYTIME );
00403 
00404     }  else
00405       // Update statusbar.
00406       statusBar()->message( i18n( "Editing of recipe was aborted." ),
00407                             STATUSDISPLAYTIME );
00408     
00409   } catch ( Error &e ) {
00410     
00411 #ifndef NDEBUG
00412     std::cerr << e.what() << std::endl;
00413 #endif
00414     KMessageBox::error( this, e.what() );
00415     statusBar()->message( e.what(), STATUSDISPLAYTIME );
00416     
00417   };
00418 
00419 };
00420 
00421 void AnyMeal::exportMealMasterRecipes( const std::string &selection )
00422 {
00423   try {
00424 
00425     QString fileName =
00426       checkOverWrite
00427       ( KFileDialog::getSaveFileName
00428         ( ":export",
00429           i18n( "*.mm *.mmf|UTF-8 Mealmaster (*.mm *.mmf)\n"
00430                 "*|All Files (*)" ),
00431           this, i18n( "Export to MealMaster File" ) ), this );
00432                                     
00433     if ( fileName != QString::null ) {
00434 
00435       DisplayWaitCursor w;
00436 
00437       std::ofstream mealMasterFile( fileName, std::ios::binary );
00438 
00439       std::stringstream query;
00440       query << "<?xml version='1.0' encoding='UTF-8'?>" << std::endl
00441             << "<query><selection>" << selection << "</selection></query>"
00442             << std::endl;
00443         
00444       std::ostringstream mealMasterOut;
00445       
00446       ChainedCompiler( cookBook->getXMLLayer(),
00447                        recipeToMealMaster ).translate( query,
00448                                                        mealMasterOut );
00449       mealMasterFile << mealMasterOut.str();
00450       
00451       ERRORMACRO( mealMasterFile, Error, ,
00452                   QString( i18n( "Error writing to file \"%1\"." ) ).
00453                   arg( fileName ) );
00454       
00455       statusBar()->message( i18n( "Exported Mealmaster file." ),
00456                             STATUSDISPLAYTIME );
00457       
00458     } else
00459       statusBar()->message( i18n( "Export aborted." ), STATUSDISPLAYTIME );
00460     
00461   } catch ( Error &e ) {
00462 #ifndef NDEBUG
00463     std::cerr << e.what() << std::endl;
00464 #endif
00465     KMessageBox::error( this, e.what() );
00466     statusBar()->message( e.what(), STATUSDISPLAYTIME );
00467   };
00468 }
00469 
00470 void AnyMeal::exportDocbookRecipes( const std::string &selection )
00471 {
00472   try {
00473 
00474     QString fileName =
00475       checkOverWrite
00476       ( KFileDialog::getSaveFileName
00477         ( ":export",
00478           i18n( "*.xml|XML (*.xml)\n"
00479                 "*|All Files (*)" ),
00480           this, i18n( "Export to Docbook File" ) ), this );
00481                                     
00482     if ( fileName != QString::null ) {
00483 
00484       DisplayWaitCursor w;
00485 
00486       std::ofstream docbookFile( fileName, std::ios::binary );
00487 
00488       std::stringstream query;
00489       query << "<?xml version='1.0' encoding='UTF-8'?>" << std::endl
00490             << "<query><selection>" << selection << "</selection></query>"
00491             << std::endl;
00492         
00493       std::ostringstream docbookOut;
00494       
00495       ChainedCompiler( cookBook->getXMLLayer(),
00496                        recipeToDocbook ).translate( query,
00497                                                     docbookOut );
00498       docbookFile << docbookOut.str();
00499       
00500       ERRORMACRO( docbookFile, Error, ,
00501                   QString( i18n( "Error writing to file \"%1\"." ) ).
00502                   arg( fileName ) );
00503       
00504       statusBar()->message( i18n( "Exported Docbook file." ),
00505                             STATUSDISPLAYTIME );
00506       
00507     } else
00508       statusBar()->message( i18n( "Export aborted." ), STATUSDISPLAYTIME );
00509     
00510   } catch ( Error &e ) {
00511 #ifndef NDEBUG
00512     std::cerr << e.what() << std::endl;
00513 #endif
00514     KMessageBox::error( this, e.what() );
00515     statusBar()->message( e.what(), STATUSDISPLAYTIME );
00516   };
00517 }
00518 
00519 void AnyMeal::exportFORecipes( const std::string &selection )
00520 {
00521   try {
00522 
00523     QString fileName =
00524       checkOverWrite
00525       ( KFileDialog::getSaveFileName
00526         ( ":export",
00527           i18n( "*.fo|FO (*.fo)\n"
00528                 "*.xml|XML (*.xml)\n"
00529                 "*|All Files (*)" ),
00530           this, i18n( "Export to FO File" ) ), this );
00531                                     
00532     if ( fileName != QString::null ) {
00533 
00534       DisplayWaitCursor w;
00535 
00536       std::ofstream foFile( fileName, std::ios::binary );
00537 
00538       std::stringstream query;
00539       query << "<?xml version='1.0' encoding='UTF-8'?>" << std::endl
00540             << "<query><selection>" << selection << "</selection></query>"
00541             << std::endl;
00542         
00543       std::ostringstream foOut;
00544       
00545       ChainedCompiler( cookBook->getXMLLayer(),
00546                        CompilerPtr( new ChainedCompiler
00547                                     ( recipeToDocbook,
00548                                       docbookToFO ) ) ).translate( query,
00549                                                                    foOut );
00550       foFile << foOut.str();
00551       
00552       ERRORMACRO( foFile, Error, ,
00553                   QString( i18n( "Error writing to file \"%1\"." ) ).
00554                   arg( fileName ) );
00555       
00556       statusBar()->message( i18n( "Exported FO file." ),
00557                             STATUSDISPLAYTIME );
00558       
00559     } else
00560       statusBar()->message( i18n( "Export aborted." ), STATUSDISPLAYTIME );
00561     
00562   } catch ( Error &e ) {
00563 #ifndef NDEBUG
00564     std::cerr << e.what() << std::endl;
00565 #endif
00566     KMessageBox::error( this, e.what() );
00567     statusBar()->message( e.what(), STATUSDISPLAYTIME );
00568   };
00569 }
00570 
00571 void AnyMeal::exportHTMLRecipes( const std::string &selection )
00572 {
00573   try {
00574 
00575     QString fileName =
00576       checkOverWrite
00577       ( KFileDialog::getSaveFileName
00578         ( ":export",
00579           i18n( "*.html *.htm|HTML (*.html *.htm)\n"
00580                 "*|All Files (*)" ),
00581           this, i18n( "Export to HTML File" ) ), this );
00582                                     
00583     if ( fileName != QString::null ) {
00584 
00585       DisplayWaitCursor w;
00586 
00587       std::ofstream htmlFile( fileName, std::ios::binary );
00588 
00589       std::stringstream query;
00590       query << "<?xml version='1.0' encoding='UTF-8'?>" << std::endl
00591             << "<query><selection>" << selection << "</selection></query>"
00592             << std::endl;
00593         
00594       std::ostringstream htmlOut;
00595       
00596       ChainedCompiler( cookBook->getXMLLayer(),
00597                        CompilerPtr( new ChainedCompiler
00598                                     ( recipeToDocbook,
00599                                       docbookToHTML ) ) ).translate( query,
00600                                                                      htmlOut );
00601       htmlFile << htmlOut.str();
00602       
00603       ERRORMACRO( htmlFile, Error, ,
00604                   QString( i18n( "Error writing to file \"%1\"." ) ).
00605                   arg( fileName ) );
00606       
00607       statusBar()->message( i18n( "Exported HTML file." ),
00608                             STATUSDISPLAYTIME );
00609       
00610     } else
00611       statusBar()->message( i18n( "Export aborted." ), STATUSDISPLAYTIME );
00612     
00613   } catch ( Error &e ) {
00614 #ifndef NDEBUG
00615     std::cerr << e.what() << std::endl;
00616 #endif
00617     KMessageBox::error( this, e.what() );
00618     statusBar()->message( e.what(), STATUSDISPLAYTIME );
00619   };
00620 }
00621 
00622 void AnyMeal::exportRecipeMLRecipes( const std::string &selection )
00623 {
00624   try {
00625 
00626     QString fileName =
00627       checkOverWrite
00628       ( KFileDialog::getSaveFileName
00629         ( ":export",
00630           i18n( "*.xml *.recipeml|RecipeML (*.xml *.recipeml)\n"
00631                 "*|All Files (*)" ),
00632           this, i18n( "Export to RecipeML File" ) ), this );
00633                                     
00634     if ( fileName != QString::null ) {
00635 
00636       DisplayWaitCursor w;
00637 
00638       std::ofstream xmlFile( fileName, std::ios::binary );
00639 
00640       std::stringstream query;
00641       query << "<?xml version='1.0' encoding='UTF-8'?>" << std::endl
00642             << "<query><selection>" << selection << "</selection></query>"
00643             << std::endl;
00644         
00645       std::ostringstream xmlOut;
00646       
00647       ChainedCompiler( cookBook->getXMLLayer(),
00648                        recipeToRecipeML ).translate( query, xmlOut );
00649       xmlFile << xmlOut.str();
00650       
00651       ERRORMACRO( xmlFile, Error, ,
00652                   QString( i18n( "Error writing to file \"%1\"." ) ).
00653                   arg( fileName ) );
00654       
00655       statusBar()->message( i18n( "Exported RecipeML file." ),
00656                             STATUSDISPLAYTIME );
00657       
00658     } else
00659       statusBar()->message( i18n( "Export aborted." ), STATUSDISPLAYTIME );
00660     
00661   } catch ( Error &e ) {
00662 #ifndef NDEBUG
00663     std::cerr << e.what() << std::endl;
00664 #endif
00665     KMessageBox::error( this, e.what() );
00666     statusBar()->message( e.what(), STATUSDISPLAYTIME );
00667   };
00668 }
00669 
00670 void AnyMeal::advancedSearch()
00671 {
00672   try {
00673     
00674     if ( !searchDialog ) {
00675       searchDialog =
00676         boost::shared_ptr< SearchDialog >
00677         ( new SearchDialog( this, "searchDialog" ) );
00678       searchDialog->cookBook = cookBook;
00679       searchDialog->reloadCategories();
00680     };
00681     
00682     if ( searchDialog->exec() ) {
00683 
00684       DisplayWaitCursor w;
00685 
00686       XMLDocument xmlDocument( "" );
00687       xmlDocument.fromString( cookBook->getXMLLayer()->
00688                               translate( searchDialog->xmlQuery() ) );
00689       XMLNodeReferenceList nodeList =
00690         xmlDocument.getDocumentElement().selectNodes( "results/table/row" );
00691 
00692       // Display result.
00693 
00694       RecipeListDisplay *recipeListDisplay =
00695         new RecipeListDisplay( workSpace, 0, WDestructiveClose );
00696       recipeListDisplay->recipeList->setSorting( 1, true );
00697       for ( int i=0; i<nodeList.getLength(); i++ ) {
00698 
00699         XMLReference< XalanElement > item
00700           ( dynamic_pointer_cast< XalanElement >( nodeList.item( i ) ) );
00701         new RecipeListItem( recipeListDisplay->recipeList,
00702                             atoi( item.selectNode( "column[position()=1]" ).
00703                                   getNodeText().c_str() ),
00704                             item.selectNode( "column[position()=2]" ).
00705                             getNodeText().c_str(),
00706                             item.selectNode( "column[position()=3]" ).
00707                             getNodeText() == "1" );
00708       };
00709 
00710       connect( recipeListDisplay,
00711                SIGNAL( recipesSelected( const std::string &, bool ) ),
00712                this, SLOT( selectRecipes( const std::string &, bool ) ) );
00713       connect( recipeListDisplay,
00714                SIGNAL( displayRecipe( int ) ),
00715                this, SLOT( displayRecipe( int ) ) );
00716       connect( recipeListDisplay,
00717                SIGNAL( editRecipe( int ) ),
00718                this, SLOT( editRecipe( int ) ) );
00719       connect( recipeListDisplay,
00720                SIGNAL( deleteRecipes( const std::string & ) ),
00721                this, SLOT( deleteRecipes( const std::string & ) ) );
00722       connect( recipeListDisplay,
00723                SIGNAL( exportMealMasterRecipes( const std::string & ) ),
00724                this, SLOT( exportMealMasterRecipes( const std::string & ) ) );
00725       connect( recipeListDisplay,
00726                SIGNAL( exportRecipeMLRecipes( const std::string & ) ),
00727                this, SLOT( exportRecipeMLRecipes( const std::string & ) ) );
00728       connect( recipeListDisplay,
00729                SIGNAL( exportDocbookRecipes( const std::string & ) ),
00730                this, SLOT( exportDocbookRecipes( const std::string & ) ) );
00731       connect( recipeListDisplay,
00732                SIGNAL( exportFORecipes( const std::string & ) ),
00733                this, SLOT( exportFORecipes( const std::string & ) ) );
00734       connect( recipeListDisplay,
00735                SIGNAL( exportHTMLRecipes( const std::string & ) ),
00736                this, SLOT( exportHTMLRecipes( const std::string & ) ) );
00737       connect( this, SIGNAL( recipesSelected( const std::string &, bool ) ),
00738                recipeListDisplay, SLOT( selectRecipes( const std::string &, bool ) ) );
00739       connect( this, SIGNAL( deleteRecipeId( int ) ),
00740                recipeListDisplay, SLOT( recipeIdDeleted( int ) ) );
00741       connect( this,
00742                SIGNAL( changeRecipeId( int, int, const QString &, const QString & ) ),
00743                recipeListDisplay,
00744                SLOT( recipeIdChanged( int, int, const QString &, const QString & ) ) );
00745 
00746       recipeListDisplay->show();
00747 
00748       statusBar()->message( i18n( "Displaying %1 search results." ).
00749                             arg( nodeList.getLength() ),
00750                             STATUSDISPLAYTIME );
00751     };
00752   } catch ( Error &e ) {
00753 #ifndef NDEBUG
00754     std::cerr << e.what() << std::endl;
00755 #endif
00756     KMessageBox::error( this, e.what() );
00757     statusBar()->message( e.what(), STATUSDISPLAYTIME );
00758   };
00759 }
00760 
00761 
00762 void AnyMeal::fileExportMealmaster()
00763 {
00764   try {
00765 
00766     QString fileName =
00767       checkOverWrite
00768       ( KFileDialog::getSaveFileName
00769         ( ":export",
00770           i18n( "*.mm *.mmf|UTF-8 Mealmaster (*.mm *.mmf)\n"
00771                 "*|All Files (*)" ),
00772           this, i18n( "Export to MealMaster File" ) ), this );
00773                                     
00774     if ( fileName != QString::null ) {
00775 
00776       DisplayWaitCursor w;
00777 
00778       std::ofstream mealMasterFile( fileName, std::ios::binary );
00779 
00780       const int
00781         numRecipes = getNumRecipes( cookBook ),
00782         count = 20;
00783 
00784       QProgressDialog progress( i18n( "Exporting Mealmaster file ... " ),
00785                                 i18n( "&Cancel" ), numRecipes, this,
00786                                 "progress", true );
00787 
00788       for ( int i=0; i<numRecipes; i+=count ) {
00789 
00790         progress.setProgress( i );
00791         ERRORMACRO( !progress.wasCanceled(), Error, ,
00792                     i18n( "Export aborted." ) );
00793 
00794         std::stringstream query;
00795         query << "<?xml version='1.0' encoding='UTF-8'?>" << std::endl
00796               << "<query><selection><range><skip>" << i << "</skip><count>"
00797               << count << "</count></range></selection></query>" << std::endl;
00798         
00799         std::ostringstream mealMasterOut;
00800 
00801         ChainedCompiler( cookBook->getXMLLayer(),
00802                          recipeToMealMaster ).translate( query,
00803                                                          mealMasterOut );
00804         mealMasterFile << mealMasterOut.str();
00805 
00806         ERRORMACRO( mealMasterFile, Error, ,
00807                     QString( i18n( "Error writing to file \"%1\"." ) ).
00808                     arg( fileName ) );
00809 
00810       };
00811       
00812       statusBar()->message( i18n( "Exported Mealmaster file." ),
00813                             STATUSDISPLAYTIME );
00814 
00815     } else
00816       statusBar()->message( i18n( "Export aborted." ), STATUSDISPLAYTIME );
00817 
00818   } catch ( Error &e ) {
00819 #ifndef NDEBUG
00820     std::cerr << e.what() << std::endl;
00821 #endif
00822     KMessageBox::error( this, e.what() );
00823     statusBar()->message( e.what(), STATUSDISPLAYTIME );
00824   };
00825 }
00826 
00827 void AnyMeal::deleteRecipes( const std::string &selection )
00828 {
00829   try {
00830 
00831     if ( KMessageBox::warningContinueCancel
00832          ( this, 
00833            i18n( "Do you really want to delete all "
00834                  "highlighted recipes?" ),
00835            i18n( "Delete Recipes" ) ) ==
00836          KMessageBox::Continue ) {
00837 
00838       DisplayWaitCursor w;
00839     
00840       // Delete recipe.
00841       std::stringstream query;
00842       query << "<?xml version='1.0' encoding='UTF-8'?>" << std::endl
00843             << "<delete><selection>" << selection << "</selection></delete>"
00844             << std::endl;
00845       std::ofstream nullDevice( "/dev/null" );
00846       cookBook->getXMLLayer()->translate( query, nullDevice );
00847       
00848       XMLDocument xmlDocument( "" );
00849       xmlDocument.fromString( cookBook->getXMLLayer()->
00850                               translate( query.str() ) );
00851       XMLNodeReferenceList nodeList =
00852         xmlDocument.getDocumentElement().selectNodes( "delete/id" );
00853       for ( int i=0; i<nodeList.getLength(); i++ )
00854         emit deleteRecipeId( atoi( nodeList.item( i ).
00855                                    getNodeText().c_str() ) );
00856       
00857       // Update statusbar.
00858       statusBar()->message( i18n( "Deleted recipes." ), STATUSDISPLAYTIME );
00859 
00860     } else
00861       statusBar()->message( i18n( "Deleting of recipes was aborted" ),
00862                             STATUSDISPLAYTIME );
00863 
00864   } catch ( Error &e ) {
00865 
00866 #ifndef NDEBUG
00867     std::cerr << e.what() << std::endl;
00868 #endif
00869     KMessageBox::error( this, e.what() );
00870     statusBar()->message( e.what(), STATUSDISPLAYTIME );
00871 
00872   };
00873 }
00874 
00875 
00876 void AnyMeal::selectRecipes( const std::string &selection, bool state )
00877 {
00878   try {
00879     assert( mysqlDatabase );
00880     
00881     // Store selection in database.
00882     std::stringstream query;
00883     query << "<?xml version='1.0' encoding='UTF-8'?>" << std::endl
00884           << "<select user='" << mysqlDatabase->getServer()->getUserName()
00885           << "'><selection>" << selection << "</selection><state>"
00886           << state << "</state></select>" << std::endl;
00887     std::ofstream nullDevice( "/dev/null" );
00888     cookBook->getXMLLayer()->translate( query, nullDevice );
00889     
00890     // Inform other windows.
00891     emit recipesSelected( selection, state );
00892   } catch ( Error &e ) {
00893 #ifndef NDEBUG
00894     std::cerr << e.what() << std::endl;
00895 #endif
00896     KMessageBox::error( this, e.what() );
00897     statusBar()->message( e.what(), STATUSDISPLAYTIME );
00898   };
00899 }
00900 
00901 
00902 void AnyMeal::fileDelete()
00903 {
00904   assert( !mysqlDatabase );
00905 
00906   try {
00907 
00908     DestroyDialog destroyDialog( this, "destroyDialog" );
00909 
00910     if ( destroyDialog.exec() ) {
00911 
00912       DisplayWaitCursor w;
00913 
00914       MySQLServerPtr server;
00915       switch ( destroyDialog.serverTypeCombo->currentItem() ) {
00916       case 0:
00917         server = MySQLServerPtr
00918           ( new MySQLNetwork( destroyDialog.rootUserEdit->text(),
00919                               destroyDialog.rootPassWordCheckBox->isChecked() ?
00920                               (const char *)destroyDialog.rootPassWordEdit->
00921                               text() : "",
00922                               destroyDialog.serverEdit->text(),
00923                               MYSQL_PORT ) );
00924         break;
00925       case 1:
00926         server = MySQLServerPtr
00927           ( new MySQLSocket
00928             ( destroyDialog.rootUserEdit->text(),
00929               destroyDialog.rootPassWordCheckBox->isChecked() ?
00930               (const char *)destroyDialog.rootPassWordEdit->
00931               text() : "",
00932               destroyDialog.socketEdit->text(),
00933               MySQLDaemonPtr( new MySQLDaemon
00934                               ( destroyDialog.folderEdit->text(), 
00935                                 destroyDialog.socketEdit->text() ) ) ) );
00936         break;
00937       default:
00938         assert(false);
00939       };
00940 
00941       std::ostringstream destroyQuery;
00942       destroyQuery << "DROP DATABASE "
00943                    << destroyDialog.databaseEdit->text() << ';';
00944 
00945       ERRORMACRO( mysql_query( server->getConnection(),
00946                                destroyQuery.str().c_str() ) == 0,
00947                   Error, , i18n( "Error destroying database: %1" ).
00948                   arg( mysql_error( server->getConnection() ) ) );
00949 
00950       statusBar()->message
00951         ( i18n( "Database \"%1\" was deleted." ).
00952           arg( destroyDialog.databaseEdit->text() ),
00953           STATUSDISPLAYTIME );
00954     };
00955 
00956   } catch ( Error &e ) {
00957 
00958     KMessageBox::error( this, e.what() );
00959     statusBar()->message( e.what(), STATUSDISPLAYTIME );
00960 
00961   };
00962 }
00963 
00964 
00965 int AnyMeal::getNumRecipes( CookBookPtr cookBook )
00966 {
00967   std::string number;
00968   XMLDocument xmlDocument( "" );
00969   xmlDocument.fromString
00970     ( cookBook->getXMLLayer()->translate
00971       ( "<?xml version='1.0' encoding='UTF-8'?>"
00972         "<count><selection><all/></selection></count>" ) );
00973   number = xmlDocument.getDocumentElement().getNodeText();
00974   return atoi( number.c_str() );
00975 }
00976 
00977 
00978 void AnyMeal::editNewRecipe()
00979 {
00980   assert( cookBook );
00981   
00982   try {
00983     
00984     RecipeEditor recipeEditor( this, "recipeEditor" );
00985     
00986     if ( recipeEditor.exec() ) {
00987 
00988       // Insert recipe.
00989       std::stringstream query;
00990       query << "<?xml version='1.0' encoding='UTF-8'?>"
00991             << std::endl << "<insert>" << std::endl
00992             << recipeEditor.getRecipe() << std::endl
00993             << std::endl << "</insert>" << std::endl;
00994 #ifndef NDEBUG
00995       std::cerr << query.str() << std::endl;
00996 #endif
00997       std::ofstream nullDevice( "/dev/null" );
00998       cookBook->getXMLLayer()->translate( query, nullDevice );
00999 
01000       // Update statusbar.
01001       statusBar()->message( i18n( "Created new recipe." ), STATUSDISPLAYTIME );
01002 
01003     }  else
01004       // Update statusbar.
01005       statusBar()->message( i18n( "Creating of recipe was aborted." ),
01006                             STATUSDISPLAYTIME );
01007 
01008   } catch ( Error &e ) {
01009     
01010 #ifndef NDEBUG
01011     std::cerr << e.what() << std::endl;
01012 #endif
01013     KMessageBox::error( this, e.what() );
01014     statusBar()->message( e.what(), STATUSDISPLAYTIME );
01015     
01016   };
01017 }
01018 
01019 
01020 void AnyMeal::databaseInfo()
01021 {
01022   assert( cookBook );
01023 
01024   try {
01025     XMLDocument xmlDocument( "" );
01026     {
01027       DisplayWaitCursor wait;
01028       xmlDocument.fromString( cookBook->getXMLLayer()->translate
01029                               ( "<?xml version='1.0' encoding='UTF-8'?>"
01030                                 "<statistics/>" ) );
01031     };
01032     XMLReference< XalanElement > docElement
01033       ( dynamic_pointer_cast< XalanElement >
01034         ( xmlDocument.getDocumentElement().selectNode( "statistics" ) ) );
01035     
01036     KMessageBox::
01037       information( this,
01038                    i18n( "The database contains %1 recipes.\n"
01039                          "There are %2 categories.\n"
01040                          "The recipes are making use of %3 different "
01041                          "ingredients." ).
01042                    arg( docElement.selectNode( "recipes" ).getNodeText() ).
01043                    arg( docElement.selectNode( "categories" ).getNodeText() ).
01044                    arg( docElement.selectNode( "edibles" ).getNodeText() ),
01045                    i18n( "Database information" ) );
01046   } catch ( Error &e ) {
01047     
01048 #ifndef NDEBUG
01049     std::cerr << e.what() << std::endl;
01050 #endif
01051     KMessageBox::error( this, e.what() );
01052     statusBar()->message( e.what(), STATUSDISPLAYTIME );
01053     
01054   };
01055 }
01056 
01057 
01058 void AnyMeal::fileImportRecipeML()
01059 {
01060 #if 0
01061   try {
01062 
01063     QStringList fileNames =
01064       KFileDialog::getOpenFileNames( ":import",
01065                                      i18n( "*.recipeml *.xml|RecipeML (*.recipeml *.xml)\n"
01066                                            "*|All Files (*)" ),
01067                                      this, i18n( "Import RecipeML File" ) );
01068                                     
01069     if ( !fileNames.empty() ) {
01070 
01071       std::ofstream nullDevice( "/dev/null" );
01072 
01073       QProgressDialog progress( i18n( "Importing RecipeML-files ... " ),
01074                                 i18n( "&Cancel" ), fileNames.size(), this,
01075                                 "progress", true );
01076 
01077       for ( int i=0; i<(signed)fileNames.size(); i++ ) {
01078 
01079         progress.setProgress( i );
01080         ERRORMACRO( !progress.wasCanceled(), Error, ,
01081                     i18n( "Import aborted." ) );
01082 
01083         try {
01084           std::ifstream inputStream( fileNames[i], std::ios::binary );
01085           progress.setLabelText( i18n( "Importing file \"%1\" ..." ).
01086                                  arg( fileNames[i] ) );
01087           
01088           ChainedCompiler
01089             ( recipeMLToRecipe,
01090               cookBook->getXMLLayer() ).translate( inputStream, nullDevice );
01091 
01092         } catch ( Error &e ) {
01093           
01094           ERRORMACRO( KMessageBox::warningContinueCancel
01095                       ( this,
01096                         i18n( "Error importing file %1: %2. "
01097                               "Continue importing recipes?" ).
01098                         arg( fileNames[i] ).
01099                         arg( e.what() ),
01100                         i18n( "Error importing recipe" ) ) ==
01101                       KMessageBox::Continue,
01102                       Error, ,
01103                       i18n( "Import was aborted" ) );
01104         };
01105       };
01106     };
01107 
01108   } catch ( Error &e ) {
01109     
01110     KMessageBox::error( this, e.what() );
01111     statusBar()->message( e.what(), STATUSDISPLAYTIME );
01112     
01113   };
01114 #else
01115 
01116   try {
01117 
01118     ImportRecipeMLDialog importRecipeMLDialog( this );
01119     importRecipeMLDialog.cookBook = cookBook;
01120     importRecipeMLDialog.recipeMLToRecipe = recipeMLToRecipe;
01121     if ( importRecipeMLDialog.exec() )
01122       statusBar()->message( i18n( "Imported RecipeML file(s)." ),
01123                             STATUSDISPLAYTIME );
01124     else
01125       statusBar()->message( i18n( "Import aborted." ), STATUSDISPLAYTIME );
01126 
01127   } catch ( Error &e ) {
01128     
01129     KMessageBox::error( this, e.what() );
01130     statusBar()->message( e.what(), STATUSDISPLAYTIME );
01131     
01132   };
01133 #endif
01134 }
01135 
01136 
01137 void AnyMeal::databaseLog()
01138 {
01139   if( socketServer )
01140     if ( socketServer->getDaemon() ) {
01141       LogWindow w( this );
01142 #ifndef NDEBUG
01143       std::cerr << socketServer->getDaemon()->getLog() << std::endl;
01144 #endif
01145       w.textBrowser->setText( socketServer->getDaemon()->getLog() );
01146       w.exec();
01147     };
01148 }
01149 
01150 
01151 void AnyMeal::fileDisconnect()
01152 {
01153   DisplayWaitCursor w;
01154   
01155   // Close connection, if there is any.
01156   cookBook.reset();
01157   mysqlDatabase.reset();
01158   networkServer.reset();
01159   socketServer.reset();
01160   
01161   // Close all windows.
01162   workSpace->closeAllWindows();
01163   searchDialog.reset();
01164 
01165   // Enable/disable some qt actions.
01166   importMMAction->setEnabled( false );
01167   importRecipeMLAction->setEnabled( false );
01168   fileExportMealmasterAction->setEnabled( false );
01169   advancedSearchAction->setEnabled( false );
01170   editNewRecipeAction->setEnabled( false );
01171   databaseInfoAction->setEnabled( false );
01172   databaseLogAction->setEnabled( false );
01173   fileConnectAction->setEnabled( true );
01174   fileDisconnectAction->setEnabled( false );
01175   fileDeleteAction->setEnabled( true );
01176 }


anymeal 0.30 - recipe management software - Make the most of your food! - © Jan Wedekind Sun Sep 14 16:01:26 2008 - GNU Free Documentation License