00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00211 CookBookPtr newCookBook
00212 ( new CookBook
00213 ( newMySQLDatabase,
00214 findAnyMealFile( "appdata", "scripts/mysqlIn.xsl" ),
00215 findAnyMealFile( "appdata", "scripts/mysqlOut.xsl" ) ) );
00216
00217
00218 int number = getNumRecipes( newCookBook );
00219
00220
00221 cookBook = newCookBook;
00222 mysqlDatabase = newMySQLDatabase;
00223 networkServer = newNetworkServer;
00224 socketServer = newSocketServer;
00225
00226
00227 workSpace->closeAllWindows();
00228 searchDialog.reset();
00229
00230
00231 connectDialog.updateWallet();
00232
00233
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
00269 CookBook( newMySQLDatabase,
00270 findAnyMealFile( "appdata", "scripts/mysqlIn.xsl" ),
00271 findAnyMealFile( "appdata", "scripts/mysqlOut.xsl" ),
00272 false ).update();
00273
00274
00275 newMySQLDatabase.reset();
00276
00277
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
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
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
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
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
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
00400 statusBar()->message( i18n( "Edited recipe number %1 (was %2)." ).
00401 arg( newId ).arg( id ),
00402 STATUSDISPLAYTIME );
00403
00404 } else
00405
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
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
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
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
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
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
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
01001 statusBar()->message( i18n( "Created new recipe." ), STATUSDISPLAYTIME );
01002
01003 } else
01004
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
01156 cookBook.reset();
01157 mysqlDatabase.reset();
01158 networkServer.reset();
01159 socketServer.reset();
01160
01161
01162 workSpace->closeAllWindows();
01163 searchDialog.reset();
01164
01165
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 }