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

main.cpp

Go to the documentation of this file.
00001 /* Copyright (C) 2002, 2003, 2004, 2005, 2006 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 #include "include.hpp"
00017 #include <boost/shared_ptr.hpp>
00018 #include <fstream>
00019 #include <iostream>
00020 #include <kaboutdata.h>
00021 #include <kapplication.h>
00022 #include <kcmdlineargs.h>
00023 #include <kiconloader.h>
00024 #include <kmessagebox.h>
00025 #include <ksplashscreen.h>
00026 #include <magic.h>
00027 #include <mysql/mysql.h>
00028 #include <qimage.h>
00029 #include <qtextcodec.h>
00030 #include <XPath/XPathInit.hpp>
00031 #include <util/PlatformUtils.hpp>
00032 #include "anyMeal.h"
00033 #include "mealMasterCompiler.hpp"
00034 #include "mysqlDatabase.hpp"
00035 #include "mysqlNetwork.hpp"
00036 #include "recoder.hpp"
00037 #include "mealMasterStoreErroneousHandler.hpp"
00038 #include "utils.hpp"
00039 #include "xslCompiler.hpp"
00040 #include "xsu.hpp"
00041 
00042 using namespace boost;
00043 using namespace std;
00044 
00045 // Default-arguments didn't work for some reason.
00046 static const KCmdLineOptions options[] = {
00047   { "i", 0, 0 },
00048   { "input <file>", I18N_NOOP( "Input file name (default: standard input)." ),
00049     0 },
00050   { "o", 0, 0 },
00051   { "output <file>", I18N_NOOP( "Output file name (default: standard "
00052                                 "output)." ), 0 },
00053   { "x", 0, 0 },
00054   { "mm2xml", I18N_NOOP( "Select Mealmaster to anyMeal-XML compiler" ), 0 },
00055   { "e", 0, 0 },
00056   { "mm2xmlerr <file>", I18N_NOOP( "Specify name of file for appending "
00057                                    "erroneous Mealmaster recipes." ), 0 },
00058   { "z", 0, 0 },
00059   { "xsu", I18N_NOOP( "Select XML-SQL-utility as compiler." ), 0 },
00060   { "s", 0, 0 },
00061   { "server <name>", I18N_NOOP( "Server hosting database. [localhost]" ), 0 },
00062   { "d", 0, 0 },
00063   { "database <name>", I18N_NOOP( "Name of MySQL database." ), 0 },
00064   { "u", 0, 0 },
00065   { "user <name>", I18N_NOOP( "User account for accessing database. "
00066                               "[$USER]" ), 0 },
00067   { "p", 0, 0 },
00068   { "password <password>", I18N_NOOP( "Password of database user. []" ), 0 },
00069   { "q", 0, 0 },
00070   { "sqlin", I18N_NOOP( "Select XSL script for converting XML-queries to "
00071                         "SQL" ), 0 },
00072   { "r", 0, 0 },
00073   { "sqlout", I18N_NOOP( "Select XSL script for converting raw XML to "
00074                          "anyMeal-XML" ), 0 },
00075   { "b", 0, 0 },
00076   { "docbook", I18N_NOOP( "Select XSL script for converting anyMeal-XML "
00077                           "to Docbook" ), 0 },
00078   { "l", 0, 0 },
00079   { "recipeml", I18N_NOOP( "Select XSL script for converting anyMeal-XML "
00080                            "to RecipeML" ), 0 },
00081   { "t", 0, 0 },
00082   { "html", I18N_NOOP( "Select XSL script for converting Docbook to HTML" ),
00083     0 },
00084   { "f", 0, 0 },
00085   { "fo", I18N_NOOP( "Select XSL script for converting Docbook to Formatted "
00086                      "Objects XML" ), 0 },
00087   { "m", 0, 0 },
00088   { "xml2mm", I18N_NOOP( "Select XML to Mealmaster compiler" ), 0 },
00089   { "y", 0, 0 },
00090   { "rm2xml", I18N_NOOP( "Select RecipeML to anyMeal-XML compiler" ), 0 },
00091   { "+[input file]", I18N_NOOP("Input file name (default: standard input)."),
00092     0 },
00093   KCmdLineLastOption };
00094 
00095 bool cli(void) throw (Error)
00096 {
00097   bool guiDisabled = false;
00098 
00099   KCmdLineArgs::addCmdLineOptions( options );
00100 
00101   KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00102 
00103   // Get file names and other data.
00104   const char
00105     *inputFileName      = ( args->count() > 0 ? args->arg( 0 ) :
00106                             args->getOption( "input" ).data() ),
00107     *outputFileName     = args->getOption( "output"    ).data(),
00108     *parseErrorFileName = args->getOption( "mm2xmlerr" ).data(),
00109     *server             = args->getOption( "server"    ).data(),
00110     *database           = args->getOption( "database"  ).data(),
00111     *user               = ( args->getOption( "user"      ).isEmpty() ?
00112                             getenv( "USER" ) :
00113                             args->getOption( "user"      ).data() ),
00114     *password           = args->getOption( "password"  ).data();
00115 
00116   // Select compiler.
00117   enum { NONE, MM2AnyMeal, SQL2RAW, XML2SQL, RAW2AnyMeal, AnyMeal2Docbook,
00118          AnyMeal2RecipeML, Docbook2HTML, Docbook2FO, AnyMeal2MM,
00119      RecipeML2AnyMeal } compiler = NONE;
00120   if ( args->isSet( "mm2xml"   ) ) compiler = MM2AnyMeal;
00121   if ( args->isSet( "xsu"      ) ) compiler = SQL2RAW;
00122   if ( args->isSet( "sqlin"    ) ) compiler = XML2SQL;
00123   if ( args->isSet( "sqlout"   ) ) compiler = RAW2AnyMeal;
00124   if ( args->isSet( "docbook"  ) ) compiler = AnyMeal2Docbook;
00125   if ( args->isSet( "recipeml" ) ) compiler = AnyMeal2RecipeML;
00126   if ( args->isSet( "html"     ) ) compiler = Docbook2HTML;
00127   if ( args->isSet( "fo"       ) ) compiler = Docbook2FO;
00128   if ( args->isSet( "xml2mm"   ) ) compiler = AnyMeal2MM;
00129   if ( args->isSet( "rm2xml"   ) ) compiler = RecipeML2AnyMeal;
00130 
00131   if ( compiler != NONE || inputFileName != NULL || 
00132        outputFileName != NULL || parseErrorFileName != NULL ||
00133        server != NULL || database != NULL || password != NULL ||
00134        user != getenv( "USER" ) ) {
00135 
00136     guiDisabled = true;
00137 
00138     // The application object (no GUI)..
00139     KApplication app( true, false );
00140 
00141     // Tell Qt, that source-code is encoded in UTF-8.
00142     QTextCodec::setCodecForCStrings
00143       ( QTextCodec::codecForName( "UTF-8" ) );
00144 
00145     try {
00146 
00147       // Initialise recoder library
00148       // Recoder::outer = recode_new_outer( false );
00149       // ERRORMACRO( Recoder::outer != NULL, Error, ,
00150       //             "Failure initialising recoder library." );
00151 
00152       ERRORMACRO( args->count() <= args->getOption( "input" ).isNull() ? 1 : 0,
00153                   Error, ,
00154                   i18n( "Only one input file may be specified." ) );
00155       
00156       // Open input stream.
00157       shared_ptr< ifstream > inputFile;
00158       istream *input = &cin;
00159       if ( inputFileName ) {
00160         inputFile = shared_ptr< ifstream >( new ifstream( inputFileName,
00161                                                           ios::binary ) );
00162         input = inputFile.get();
00163       };
00164 
00165       // Open output stream.
00166       shared_ptr< ofstream > outputFile;
00167       ostream *output = &cout;
00168       if ( outputFileName ) {
00169         outputFile = shared_ptr< ofstream >( new ofstream( outputFileName,
00170                                                            ios::binary ) );
00171         output = outputFile.get();
00172       };
00173 
00174       switch ( compiler ) {
00175       case MM2AnyMeal: {
00176         shared_ptr< ostream > stream;
00177         MealMasterParseErrorHandlerPtr parseErrorHandler;
00178 
00179         if ( parseErrorFileName != NULL ) {
00180           stream = shared_ptr< ostream >
00181             ( new ofstream( parseErrorFileName, ios::binary ) );
00182           parseErrorHandler = MealMasterParseErrorHandlerPtr
00183             ( new MealMasterStoreErroneousHandler( stream.get(), parseErrorFileName ) );
00184         } else
00185           parseErrorHandler = MealMasterParseErrorHandlerPtr( new MealMasterParseErrorHandler );
00186 
00187         MealMasterCompiler( -1, parseErrorHandler ).translate( *input, *output );
00188         break;}
00189       case SQL2RAW: {
00190         ERRORMACRO( database != NULL, Error, ,
00191                     i18n( "No datasource selected." ) );
00192         assert( user != NULL );
00193         DatabasePtr
00194           connection( new MySQLDatabase
00195                       ( MySQLServerPtr
00196                         ( new MySQLNetwork
00197                           ( user, password == NULL ? "" : password,
00198                             server == NULL ? "localhost" : server,
00199                             MYSQL_PORT ) ),
00200                         database ) );
00201         XSU( connection ).translate( *input, *output );
00202         break;}
00203       case XML2SQL: {
00204         // I don't know, why I have to store it in a temporary variable first.
00205         // But otherwise it won't compile.
00206         string fileName( findAnyMealFile( "appdata", "scripts/mysqlIn.xsl" ) );
00207         XSLCompiler( fileName,
00208                      FormatterListener::OUTPUT_METHOD_TEXT, SQLENCODING, "" ).
00209           translate( *input, *output );
00210         break;}
00211       case RAW2AnyMeal: {
00212         string fileName( findAnyMealFile( "appdata", "scripts/mysqlOut.xsl" ) );
00213         XSLCompiler( fileName,
00214                      FormatterListener::OUTPUT_METHOD_XML, "UTF-8", "" ).
00215           translate( *input, *output );
00216         break;}
00217       case AnyMeal2Docbook: {
00218         string fileName( findAnyMealFile( "appdata",
00219                                           "scripts/recipeToDocbook.xsl" ) );
00220         XSLCompiler compiler
00221           ( fileName,
00222             FormatterListener::OUTPUT_METHOD_XML, HTMLENCODING,
00223             findAnyMealFile( "appdata", "scripts/anymeal.xsd" ) );
00224         // Relative path (quoted)!
00225         compiler.setParam( "lfile", string( "\"file://" ) + dictionaryFile() +
00226                            "\"" );
00227         compiler.setParam( "lname", string( "\"" ) + anyMealLanguage() +
00228                            "\"" );
00229         compiler.translate( *input, *output );
00230         break;}
00231       case AnyMeal2RecipeML: {
00232         string fileName( findAnyMealFile( "appdata",
00233                                           "scripts/recipeToRecipeML.xsl" ) );
00234         XSLCompiler( fileName,
00235                      FormatterListener::OUTPUT_METHOD_XML, HTMLENCODING,
00236                      findAnyMealFile( "appdata", "scripts/anymeal.xsd" ) ).
00237           translate( *input, *output );
00238         break;};      
00239       case Docbook2HTML: {
00240         XSLCompiler( DOCBOOK"/html/docbook.xsl",
00241                      FormatterListener::OUTPUT_METHOD_HTML, HTMLENCODING, "" ).
00242           translate( *input, *output );
00243         break;}
00244       case Docbook2FO: {
00245         string fileName( findAnyMealFile( "appdata",
00246                                           "scripts/docbookToFo.xsl" ) );
00247         XSLCompiler compiler
00248           ( fileName,
00249             FormatterListener::OUTPUT_METHOD_XML, HTMLENCODING, "" );
00250         compiler.setParam( "paper.type", "\"A4\"" );
00251         compiler.translate( *input, *output );
00252         break;}
00253       case AnyMeal2MM: {
00254         string fileName( findAnyMealFile( "appdata",
00255                                           "scripts/recipeToMealMaster.xsl" ) );
00256         XSLCompiler compiler
00257       ( fileName,
00258         FormatterListener::OUTPUT_METHOD_TEXT, MMENCODING,
00259         findAnyMealFile( "appdata", "scripts/anymeal.xsd" ) );
00260         compiler.setParam( "mfile", string( "\"file://" ) +
00261                mealmasterMapFile() + "\"" );
00262     compiler.translate( *input, *output );
00263         break;}
00264       case RecipeML2AnyMeal: {
00265         string fileName( findAnyMealFile( "appdata",
00266                                           "scripts/recipeMLToRecipe.xsl" ) );
00267         XSLCompiler( fileName,
00268                      FormatterListener::OUTPUT_METHOD_XML, "UTF-8",
00269              findAnyMealFile( "appdata", "scripts/recipeML.xsd" ) ).
00270           translate( *input, *output );
00271     break;}
00272       default:
00273         ERRORMACRO( false, Error, , i18n( "No compiler was selected." ) );
00274       };
00275 
00276     } catch ( Error &e ) {
00277 
00278       cerr << i18n( "Error: " ) << e.what() << endl;
00279       
00280     };
00281 
00282     // Destruction of recoder crashes. Symbol clash with mysql library?
00283     // if ( Recoder::outer != NULL ) {
00284     //   recode_delete_outer( Recoder::outer );
00285     //   Recoder::outer = NULL;
00286     // };
00287     
00288   };
00289   
00290   return guiDisabled;
00291 }
00292 
00293 class AnyMealIcons : public QMimeSourceFactory
00294 {
00295 public:
00296   AnyMealIcons(void) {}
00297   const QMimeSource* data( const QString& abs_name ) const {
00298 #ifndef NDEBUG
00299       cerr << "Request for icon \"" <<  abs_name << "\"." << endl;
00300 #endif
00301     const QMimeSource* d = QMimeSourceFactory::data( abs_name );
00302     if ( d || abs_name.isNull() ) return d;
00303     QPixmap pixmap( iconLoader.loadIcon( abs_name.left
00304                                          ( abs_name.length() - 4 ),
00305                                          KIcon::Toolbar, 32,
00306                                          KIcon::DefaultState, 0, true ) );
00307     if ( !pixmap.isNull() ) {
00308       ((QMimeSourceFactory *)this)->setPixmap( abs_name, pixmap );
00309     } else {
00310 #ifndef NDEBUG
00311       cerr << "Could not find icon \"" <<  abs_name
00312            << "\" in standard directory." << endl;
00313 #endif
00314         if ( pixmap.load( QString( "icons/hi32-action-" ) + abs_name ) )
00315           ((QMimeSourceFactory *)this)->setPixmap( abs_name, pixmap );
00316         else if ( pixmap.load( QString( "icons/hi32-app-" ) + abs_name ) )
00317           ((QMimeSourceFactory *)this)->setPixmap( abs_name, pixmap );
00318     };
00319     return QMimeSourceFactory::data( abs_name );
00320   };
00321 protected:
00322   KIconLoader iconLoader;
00323 };
00324 
00325 magic_t magic = NULL;
00326 
00327 shared_ptr< KSplashScreen > splash;
00328 
00329 int gui(void)
00330 {
00331   int retVal;
00332 
00333   // The application object.
00334   KApplication app( true, true );
00335 
00336 
00337   // Mimesource-factory for loading icons. KApplication seems to spoil
00338   // initialisation-code generated by "uic -embed" :-(
00339   AnyMealIcons anyMealIcons;
00340   QMimeSourceFactory::defaultFactory()->addFactory( &anyMealIcons );
00341 
00342   // Tell Qt, that source-code is encoded in UTF-8.
00343   QTextCodec::setCodecForCStrings
00344     ( QTextCodec::codecForName( "UTF-8" ) );
00345 
00346   // Not a matter of taste. It's because the default style has an erroneous
00347   // palette for QComboTableItem.
00348   // app.setStyle( "windows" );
00349 
00350   try {
00351   
00352     // Open splash-screen.
00353     QPixmap pixmap( findAnyMealFile( "appdata", "pics/splash.jpg" ) );
00354     ERRORMACRO( !pixmap.isNull(), Error, ,
00355                 "Could not load image \""
00356                 << findAnyMealFile( "appdata", "pics/splash.jpg" ) << "\"." );
00357     splash = shared_ptr< KSplashScreen >( new KSplashScreen( pixmap ) );
00358     splash->show();
00359   
00360     // Initialise recoder-library
00361     splash->message( i18n( "Initialising recode-library ..." ) );
00362     Recoder::outer = recode_new_outer( false );
00363     ERRORMACRO( Recoder::outer != NULL, Error, ,
00364                 "Failed to initialise recoder library." );
00365 
00366     // Initialise magic-library.
00367     splash->message( i18n( "Initialising magic-library ..." ) );
00368     magic = magic_open( MAGIC_NONE );
00369     ERRORMACRO( magic != NULL, Error, ,
00370                 i18n( "Failed to initialise magic library." ) );
00371     ERRORMACRO( magic_load( magic, NULL ) == 0, Error, ,
00372                 magic_error( magic ) );
00373 
00374     splash->message( i18n( "Reading icons ..." ) );
00375     AnyMeal anyMeal( NULL, "anyMeal mainwindow" );
00376     splash->message( i18n( "Opening main window ..." ) );
00377     app.setMainWidget( &anyMeal );
00378     anyMeal.show();
00379     splash.reset();
00380     retVal = app.exec();
00381 
00382   } catch ( Error &e ) {
00383 
00384     // Remove splash-screen, if it is open already.
00385     splash.reset();
00386 
00387     // This would be a serious software error.
00388     KMessageBox::error( NULL, e.what() );
00389     retVal = 1;
00390 
00391   };
00392 
00393   // Destruct magic library.
00394   if ( magic != NULL ) {
00395     magic_close( magic );
00396     magic = NULL;
00397   };
00398   // Destruction of recoder crashes. Symbol clash with mysql library?
00399   // if ( Recoder::outer != NULL ) {
00400   //   recode_delete_outer( Recoder::outer );
00401   //   Recoder::outer = NULL;
00402   // };
00403 
00404   // Remove factory.
00405   QMimeSourceFactory::defaultFactory()->removeFactory( &anyMealIcons );
00406 
00407   return retVal;
00408 }
00409 
00410 int main( int argc, char *argv[] )
00411 {
00412   int retVal = 0;
00413 
00414   // Disable SuSE KDE integration, because it is breaking this application.
00415   // setenv( "QT_NO_KDE_INTEGRATION", "1", 1 );
00416 
00417   // Static initialisation of xerces must be done in main thread!
00418   XMLPlatformUtils::Initialize();
00419   // Static initialisation of xalan must be done in main thread!
00420   XalanTransformer::initialize();
00421 
00422   {
00423 
00424     // Static initalisation of XPath utilities.
00425     XPathInit theXPathInit;
00426 
00427     // Construct information about anymeal.
00428     KAboutData about
00429       ( "anymeal", I18N_NOOP( "AnyMeal" ), VERSION,
00430         I18N_NOOP( "recipe database application" ),
00431         KAboutData::License_GPL,
00432         I18N_NOOP( "Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, Jan Wedekind, "
00433                    "Sheffield, United Kingdom" ),
00434         I18N_NOOP( "AnyMeal comes with ABSOLUTELY NO WARRANTY.\n"
00435                    "This is free software, and you are welcome to "
00436                    "redistribute it\n"
00437                    "under certain conditions; see file 'COPYING' for "
00438                    "details.\n"
00439                    "See 'anymeal.lsm' file for contact information." ),
00440         "http://sourceforge.net/projects/anymeal/",
00441         "wedesoft@users.sourceforge.net" );
00442     about.addAuthor( "Jan Wedekind", I18N_NOOP( "Main developer" ),
00443                      "jan@wedesoft.de",
00444                      "http://www.wedesoft.de/" );
00445     about.addCredit( "Sandro Tosi",
00446                      I18N_NOOP( "Debian-package and man-page." ),
00447                      "matrixhasu@altervista.org",
00448                      "http://matrixhasu.altervista.org/" );
00449     about.addCredit( "Scott Welliver",
00450                      I18N_NOOP( "Project inspired from original "
00451                                 "Mealmaster-software." ),
00452                      NULL,
00453                      "http://episoft.home.comcast.net/" );
00454     about.addCredit( "Roland Jesse",
00455                      I18N_NOOP( "Recipe-editor inspired from "
00456                                 "mango-software." ),
00457                      "rjesse@users.sourceforge.net",
00458                      "http://mango.sf.net/" );
00459     about.addCredit( "Wikibooks Cookbook",
00460                      I18N_NOOP( "GFDL licensed photos." ),
00461                      NULL,
00462                      "http://en.wikibooks.org/wiki/Cookbook" );
00463     about.addCredit( "krecipes team",
00464                      I18N_NOOP( "Database-wizard inspired from "
00465                                 "krecipes-software." ),
00466                      NULL,
00467                      "http://krecipes.sourceforge.net/" );
00468     about.addCredit( "Free Software Foundation",
00469                      I18N_NOOP( "The GNU/Linux platform." ),
00470                      "gnu@gnu.org",
00471                      "http://www.gnu.org/gnu/the-gnu-project.html" );
00472     about.addCredit( "GCC team",
00473                      I18N_NOOP( "The GNU-C++ compiler" ),
00474                      "gcc@gnu.org",
00475                      "http://www.gnu.org/software/gcc/" );
00476     about.addCredit( "Bram Moolenaar and others",
00477                      I18N_NOOP( "The vi editor" ),
00478                      NULL,
00479                      "http://www.vim.org/" );
00480     about.addCredit( "Dimitri van Heesch",
00481                      I18N_NOOP( "Doxygen documentation system" ),
00482                      "dimitri@stack.nl",
00483                      "http://www.stack.nl/~dimitri/doxygen/" );
00484     about.addCredit( "Apache Software Foundation",
00485                      I18N_NOOP( "Xalan-C and Xerces-C XML-libraries." ),
00486                      "apache@apache.org",
00487                      "http://xml.apache.org/" );
00488     about.addCredit( "MySQL Developers",
00489                      I18N_NOOP( "MySQL database software" ),
00490                      NULL,
00491                      "http://dev.mysql.com/" );
00492     about.addCredit( "Boost team",
00493                      I18N_NOOP( "Boost C++ library" ),
00494                      NULL,
00495                      "http://www.boost.org/" );
00496     about.addCredit( "KDE team",
00497                      I18N_NOOP( "KDE desktop" ),
00498                      NULL,
00499                      "http://www.kde.org/" );
00500     about.addCredit( "Matthias Kiefer",
00501                      I18N_NOOP( "kbabel" ),
00502                      "kiefer@kde.org",
00503                      "http://i18n.kde.org/tools/kbabel/" );
00504     about.addCredit( "Dia team",
00505                      I18N_NOOP( "Diagram editor Dia" ),
00506                      NULL,
00507                      "http://www.gnome.org/projects/dia/" );
00508     about.addCredit( "Graphviz team",
00509                      I18N_NOOP( "Graph visualization software Graphviz" ),
00510                      NULL,
00511                      "http://www.graphviz.org/" );
00512     about.addCredit( "Docbook team",
00513                      I18N_NOOP( "Docbook XSL stylesheets" ),
00514                      NULL,
00515                      "http://docbook.sourceforge.net/" );
00516     about.addCredit( "Nick Gorham",
00517                      I18N_NOOP( "unixODBC software" ),
00518                      "nick.gorham@easysoft.com",
00519                      "http://www.unixodbc.org/" );
00520     about.addCredit( "Trolltech",
00521                      I18N_NOOP( "Qt graphical user-interface library" ),
00522                      "info@trolltech.com",
00523                      "http://www.trolltech.com/" );
00524     about.addCredit( "Sourceforge",
00525                      I18N_NOOP( "Hosting and advertising for AnyMeal" ),
00526                      NULL,
00527                      "http://sourceforge.net/" );
00528     about.addCredit( "Noah Levitt",
00529                      I18N_NOOP( "GNOME Unicode character map" ),
00530                      "nlevitt@columbia.edu",
00531                      "http://gucharmap.sourceforge.net/" );
00532     about.addCredit( "Formatdata Company",
00533                      I18N_NOOP( "This product is RecipeML compatible." ),
00534                      "RecipeML@formatdata.com",
00535                      "http://www.formatdata.com/recipeml/" );
00536     about.setTranslator( I18N_NOOP("_: NAME OF TRANSLATORS\nYour names"),
00537                          I18N_NOOP("_: EMAIL OF TRANSLATORS\nYour emails") );
00538 
00539     KCmdLineArgs::init( argc, argv, &about );
00540 
00541     if ( !cli() ) retVal = gui();
00542 
00543   };
00544 
00545   // Terminate Xalan...
00546   XalanTransformer::terminate();
00547   // Terminate Xerces...
00548   XMLPlatformUtils::Terminate();
00549   // Clean up the ICU, if it's integrated...
00550   // XalanTransformer::ICUCleanUp();
00551   return retVal;
00552 }


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