00001
00002
00003
00004
00005
00006
00007 #include <fstream>
00008 #include <iostream>
00009
00010 #include <boost/lexical_cast.hpp>
00011 #include <boost/tokenizer.hpp>
00012
00013 #include <Wt/WAnchor>
00014 #include <Wt/WApplication>
00015 #include <Wt/WEnvironment>
00016 #include <Wt/WIconPair>
00017 #include <Wt/WImage>
00018 #include <Wt/WLineEdit>
00019 #include <Wt/WLogger>
00020 #include <Wt/WMenu>
00021 #include <Wt/WPushButton>
00022 #include <Wt/WStackedWidget>
00023 #include <Wt/WTabWidget>
00024 #include <Wt/WTable>
00025 #include <Wt/WTableCell>
00026 #include <Wt/WText>
00027 #include <Wt/WTreeNode>
00028 #include <Wt/WViewWidget>
00029
00030 #include "Home.h"
00031
00032 namespace {
00033 struct Lang {
00034 std::string code, path, shortDescription, longDescription;
00035 };
00036
00037 Lang l[] = {
00038 { "en", "/", "en", "English" },
00039 { "cn", "/cn/", "汉语", "中文 (Chinese)" }
00040 };
00041
00042 std::vector<Lang> languages(l, l + 2);
00043 }
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 template <typename Function>
00054 class DeferredWidget : public WContainerWidget
00055 {
00056 public:
00057 DeferredWidget(Function f)
00058 : f_(f) { }
00059
00060 private:
00061 void load() {
00062 WContainerWidget::load();
00063 addWidget(f_());
00064 }
00065
00066 Function f_;
00067 };
00068
00069 template <typename Function>
00070 DeferredWidget<Function> *deferCreate(Function f)
00071 {
00072 return new DeferredWidget<Function>(f);
00073 }
00074
00075
00076 class Div : public WContainerWidget
00077 {
00078 public:
00079 Div(WContainerWidget *parent, const std::string& id)
00080 : WContainerWidget(parent)
00081 {
00082 setId(id);
00083 }
00084 };
00085
00086 Home::Home(const WEnvironment& env)
00087 : WApplication(env),
00088 recentNews_(0),
00089 historicalNews_(0),
00090 releases_(0)
00091 {
00092 messageResourceBundle().use("wt-home", false);
00093 useStyleSheet("images/wt.css");
00094 useStyleSheet("images/wt_ie.css", "lt IE 7");
00095 useStyleSheet("home.css");
00096 setTitle("Wt, C++ Web Toolkit");
00097
00098 setLocale("");
00099 language_ = 0;
00100
00101 Div *topWrapper = new Div(root(), "top_wrapper");
00102 Div *topContent = new Div(topWrapper, "top_content");
00103
00104 Div *languagesDiv = new Div(topContent, "top_languages");
00105
00106 for (unsigned i = 0; i < languages.size(); ++i) {
00107 if (i != 0)
00108 new WText("- ", languagesDiv);
00109
00110 const Lang& l = languages[i];
00111
00112 WAnchor *a = new WAnchor("", l.longDescription, languagesDiv);
00113 a->setRefInternalPath(l.path);
00114 }
00115
00116 WText *topWt = new WText(tr("top_wt"), topContent);
00117 topWt->setInline(false);
00118 topWt->setId("top_wt");
00119
00120 WText *bannerWt = new WText(tr("banner_wrapper"), root());
00121 bannerWt->setId("banner_wrapper");
00122
00123 Div *mainWrapper = new Div(root(), "main_wrapper");
00124 Div *mainContent = new Div(mainWrapper, "main_content");
00125 Div *mainMenu = new Div(mainContent, "main_menu");
00126
00127 WStackedWidget *contents = new WStackedWidget();
00128 contents->setId("main_page");
00129
00130 mainMenu_ = new WMenu(contents, Vertical, mainMenu);
00131 mainMenu_->setRenderAsList(true);
00132
00133
00134 mainMenu_->addItem
00135 (tr("introduction"), introduction())->setPathComponent("");
00136 mainMenu_->addItem
00137 (tr("news"), deferCreate(boost::bind(&Home::news, this)),
00138 WMenuItem::PreLoading);
00139 mainMenu_->addItem
00140 (tr("features"), wrapViewOrDefer(&Home::features),
00141 WMenuItem::PreLoading);
00142 mainMenu_->addItem
00143 (tr("documentation"), wrapViewOrDefer(&Home::documentation),
00144 WMenuItem::PreLoading);
00145 mainMenu_->addItem
00146 (tr("examples"), examples(),
00147 WMenuItem::PreLoading);
00148 mainMenu_->addItem
00149 (tr("download"), deferCreate(boost::bind(&Home::download, this)),
00150 WMenuItem::PreLoading);
00151 mainMenu_->addItem
00152 (tr("community"), wrapViewOrDefer(&Home::community),
00153 WMenuItem::PreLoading);
00154
00155 mainMenu_->itemSelectRendered().connect(SLOT(this, Home::updateTitle));
00156 mainMenu_->itemSelected().connect(SLOT(this, Home::logInternalPath));
00157 mainMenu_->select((int)0);
00158
00159
00160 mainMenu_->setInternalPathEnabled();
00161 mainMenu_->setInternalBasePath("/");
00162
00163 sideBarContent_ = new WContainerWidget(mainMenu);
00164
00165 mainContent->addWidget(contents);
00166 WContainerWidget *clearAll = new WContainerWidget(mainContent);
00167 clearAll->setStyleClass("clearall");
00168
00169 WText *footerWrapper = new WText(tr("footer_wrapper"), root());
00170 footerWrapper->setId("footer_wrapper");
00171
00172 internalPathChanged().connect(SLOT(this, Home::setLanguageFromPath));
00173 }
00174
00175 void Home::setLanguage(int index)
00176 {
00177 const Lang& l = languages[index];
00178
00179 setLocale(l.code);
00180
00181 std::string langPath = l.path;
00182 mainMenu_->setInternalBasePath(langPath);
00183 examplesMenu_->setInternalBasePath(langPath + "examples");
00184 updateTitle();
00185
00186 language_ = index;
00187 }
00188
00189 void Home::setLanguageFromPath(std::string prefix)
00190 {
00191 if (prefix == "/") {
00192 std::string langPath = internalPathNextPart(prefix);
00193
00194 if (langPath.empty())
00195 langPath = '/';
00196 else
00197 langPath = '/' + langPath + '/';
00198
00199 int newLanguage = 0;
00200
00201 for (unsigned i = 0; i < languages.size(); ++i) {
00202 if (languages[i].path == langPath) {
00203 newLanguage = i;
00204 break;
00205 }
00206 }
00207
00208 if (newLanguage != language_)
00209 setLanguage(newLanguage);
00210 }
00211 }
00212
00213 void Home::updateTitle()
00214 {
00215 setTitle(tr("wt") + " - " + mainMenu_->currentItem()->text());
00216 }
00217
00218 void Home::logInternalPath()
00219 {
00220
00221 log("path") << internalPath();
00222 }
00223
00224 WWidget *Home::introduction()
00225 {
00226 return new WText(tr("home.intro"));
00227 }
00228
00229 void Home::refresh()
00230 {
00231 if (recentNews_)
00232 readNews(recentNews_, "latest-news.txt");
00233
00234 if (historicalNews_)
00235 readNews(historicalNews_, "historical-news.txt");
00236
00237 if (releases_)
00238 readReleases(releases_, "releases.txt");
00239
00240 WApplication::refresh();
00241 }
00242
00243 WWidget *Home::news()
00244 {
00245 WContainerWidget *result = new WContainerWidget();
00246
00247 result->addWidget(new WText(tr("home.news")));
00248
00249 result->addWidget(new WText(tr("home.latest-news")));
00250 recentNews_ = new WTable();
00251 readNews(recentNews_, "latest-news.txt");
00252 result->addWidget(recentNews_);
00253
00254 result->addWidget(new WText(tr("home.historical-news")));
00255 historicalNews_ = new WTable();
00256 readNews(historicalNews_, "historical-news.txt");
00257 result->addWidget(historicalNews_);
00258
00259 return result;
00260 }
00261
00262 WWidget *Home::status()
00263 {
00264 return new WText(tr("home.status"));
00265 }
00266
00267 WWidget *Home::features()
00268 {
00269 return new WText(tr("home.features"));
00270 }
00271
00272 WWidget *Home::documentation()
00273 {
00274 return new WText(tr("home.documentation"));
00275 }
00276
00277 WWidget *Home::helloWorldExample()
00278 {
00279 WContainerWidget *result = new WContainerWidget();
00280
00281 new WText(tr("home.examples.hello"), result);
00282
00283 WTreeNode *tree = makeTreeMap("Hello world", 0);
00284 makeTreeFile("hello.C", tree);
00285
00286 tree->expand();
00287
00288 result->addWidget(tree);
00289
00290 return result;
00291 }
00292
00293 WWidget *Home::chartExample()
00294 {
00295 WContainerWidget *result = new WContainerWidget();
00296
00297 new WText(tr("home.examples.chart"), result);
00298
00299 WTreeNode *tree = makeTreeMap("Chart example", 0);
00300 WTreeNode *chartsExample = makeTreeMap("class ChartsExample", tree);
00301 makeTreeFile("ChartsExample.h", chartsExample);
00302 makeTreeFile("ChartsExample.C", chartsExample);
00303 WTreeNode *chartConfig = makeTreeMap("class ChartConfig", tree);
00304 makeTreeFile("ChartConfig.h", chartConfig);
00305 makeTreeFile("ChartConfig.C", chartConfig);
00306 WTreeNode *panelList = makeTreeMap("class PanelList", tree);
00307 makeTreeFile("PanelList.h", panelList);
00308 makeTreeFile("PanelList.C", panelList);
00309 makeTreeFile("CsvUtil.C", tree);
00310 makeTreeFile("charts.xml", tree);
00311 makeTreeFile("charts.css", tree);
00312
00313 tree->expand();
00314
00315 result->addWidget(tree);
00316
00317 return result;
00318 }
00319
00320 WWidget *Home::homepageExample()
00321 {
00322 WContainerWidget *result = new WContainerWidget();
00323
00324 new WText(tr("home.examples.wt"), result);
00325
00326 WTreeNode *tree = makeTreeMap("Wt Homepage", 0);
00327 WTreeNode *home = makeTreeMap("class Home", tree);
00328 makeTreeFile("Home.h", home);
00329 makeTreeFile("Home.C", home);
00330 WTreeNode *treeexample = makeTreeMap("class TreeListExample", tree);
00331 makeTreeFile("TreeListExample.h", treeexample);
00332 makeTreeFile("TreeListExample.C", treeexample);
00333 makeTreeFile("wt-home.xml", tree);
00334
00335 tree->expand();
00336
00337 result->addWidget(tree);
00338
00339 return result;
00340 }
00341
00342 WWidget *Home::treeviewExample()
00343 {
00344 WContainerWidget *result = new WContainerWidget();
00345
00346 new WText(tr("home.examples.treeview"), result);
00347
00348 WTreeNode *tree = makeTreeMap("Treeview example", 0);
00349
00350 WTreeNode *classMap;
00351 classMap = makeTreeMap("class FolderView", tree);
00352 makeTreeFile("FolderView.h", classMap);
00353 makeTreeFile("FolderView.C", classMap);
00354 makeTreeFile("TreeViewDragDrop.C", tree);
00355 makeTreeFile("CsvUtil.C", tree);
00356 makeTreeFile("about.xml", tree);
00357 makeTreeFile("styles.css", tree);
00358
00359 tree->expand();
00360
00361 result->addWidget(tree);
00362
00363 return result;
00364 }
00365
00366 WWidget *Home::gitExample()
00367 {
00368 WContainerWidget *result = new WContainerWidget();
00369
00370 new WText(tr("home.examples.git"), result);
00371
00372 WTreeNode *tree = makeTreeMap("Git example", 0);
00373
00374 WTreeNode *classMap;
00375 classMap = makeTreeMap("class GitModel", tree);
00376 makeTreeFile("GitModel.h", classMap);
00377 makeTreeFile("GitModel.C", classMap);
00378 classMap = makeTreeMap("class Git", tree);
00379 makeTreeFile("Git.h", classMap);
00380 makeTreeFile("Git.C", classMap);
00381 makeTreeFile("GitView.C", tree);
00382 makeTreeFile("gitview.css", tree);
00383
00384 tree->expand();
00385
00386 result->addWidget(tree);
00387
00388 return result;
00389 }
00390
00391 WWidget *Home::chatExample()
00392 {
00393 WContainerWidget *result = new WContainerWidget();
00394
00395 new WText(tr("home.examples.chat"), result);
00396
00397 WTreeNode *tree = makeTreeMap("Chat example", 0);
00398
00399 WTreeNode *classMap;
00400 classMap = makeTreeMap("class SimpleChatWidget", tree);
00401 makeTreeFile("SimpleChatWidget.h", classMap);
00402 makeTreeFile("SimpleChatWidget.C", classMap);
00403 classMap = makeTreeMap("class SimpleChatServer", tree);
00404 makeTreeFile("SimpleChatServer.h", classMap);
00405 makeTreeFile("SimpleChatServer.C", classMap);
00406 makeTreeFile("simpleChat.C", tree);
00407 makeTreeFile("simplechat.css", tree);
00408 makeTreeFile("simplechat.xml", tree);
00409
00410 tree->expand();
00411
00412 result->addWidget(tree);
00413
00414 return result;
00415 }
00416
00417 WWidget *Home::composerExample()
00418 {
00419 WContainerWidget *result = new WContainerWidget();
00420
00421 new WText(tr("home.examples.composer"), result);
00422
00423 WTreeNode *tree = makeTreeMap("Mail composer example", 0);
00424
00425 WTreeNode *classMap;
00426 classMap = makeTreeMap("class AddresseeEdit", tree);
00427 makeTreeFile("AddresseeEdit.h", classMap);
00428 makeTreeFile("AddresseeEdit.C", classMap);
00429 classMap = makeTreeMap("class AttachmentEdit", tree);
00430 makeTreeFile("AttachmentEdit.h", classMap);
00431 makeTreeFile("AttachmentEdit.C", classMap);
00432 classMap = makeTreeMap("class ComposeExample", tree);
00433 makeTreeFile("ComposeExample.h", classMap);
00434 makeTreeFile("ComposeExample.C", classMap);
00435 classMap = makeTreeMap("class Composer", tree);
00436 makeTreeFile("Composer.h", classMap);
00437 makeTreeFile("Composer.C", classMap);
00438 classMap = makeTreeMap("class ContactSuggestions", tree);
00439 makeTreeFile("ContactSuggestions.h", classMap);
00440 makeTreeFile("ContactSuggestions.C", classMap);
00441 classMap = makeTreeMap("class Label", tree);
00442 makeTreeFile("Label.h", classMap);
00443 makeTreeFile("Label.C", classMap);
00444 classMap = makeTreeMap("class Option", tree);
00445 makeTreeFile("Option.h", classMap);
00446 makeTreeFile("Option.C", classMap);
00447 classMap = makeTreeMap("class OptionList", tree);
00448 makeTreeFile("OptionList.h", classMap);
00449 makeTreeFile("OptionList.C", classMap);
00450 makeTreeFile("Contact.h", tree);
00451 makeTreeFile("Attachment.h", tree);
00452 makeTreeFile("composer.xml", tree);
00453 makeTreeFile("composer.css", tree);
00454
00455 tree->expand();
00456
00457 result->addWidget(tree);
00458
00459 return result;
00460 }
00461
00462 WWidget *Home::widgetGalleryExample()
00463 {
00464 WContainerWidget *result = new WContainerWidget();
00465
00466 new WText(tr("home.examples.widgetgallery"), result);
00467
00468 return result;
00469 }
00470
00471 WWidget *Home::wrapViewOrDefer(WWidget *(Home::*createWidget)())
00472 {
00473
00474
00475
00476
00477
00478
00479
00480
00481 if (!environment().agentIEMobile() && environment().javaScript())
00482 return makeStaticModel(boost::bind(createWidget, this));
00483 else
00484 return deferCreate(boost::bind(createWidget, this));
00485 }
00486
00487 WWidget *Home::examples()
00488 {
00489 WContainerWidget *result = new WContainerWidget();
00490
00491 result->addWidget(new WText(tr("home.examples")));
00492
00493 examplesMenu_ = new WTabWidget(result);
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515 examplesMenu_->addTab(wrapViewOrDefer(&Home::helloWorldExample),
00516 tr("hello-world"))->setPathComponent("");
00517
00518 examplesMenu_->addTab(wrapViewOrDefer(&Home::chartExample),
00519 tr("charts"));
00520 examplesMenu_->addTab(wrapViewOrDefer(&Home::homepageExample),
00521 tr("wt-homepage"));
00522 examplesMenu_->addTab(wrapViewOrDefer(&Home::treeviewExample),
00523 tr("treeview"));
00524 examplesMenu_->addTab(wrapViewOrDefer(&Home::gitExample),
00525 tr("git"));
00526 examplesMenu_->addTab(wrapViewOrDefer(&Home::chatExample),
00527 tr("chat"));
00528 examplesMenu_->addTab(wrapViewOrDefer(&Home::composerExample),
00529 tr("mail-composer"));
00530 examplesMenu_->addTab(wrapViewOrDefer(&Home::widgetGalleryExample),
00531 tr("widget-gallery"));
00532
00533 examplesMenu_->currentChanged().connect(SLOT(this, Home::logInternalPath));
00534
00535
00536 examplesMenu_->setInternalPathEnabled();
00537 examplesMenu_->setInternalBasePath("/examples");
00538
00539 return result;
00540 }
00541
00542 WWidget *Home::download()
00543 {
00544 WContainerWidget *result = new WContainerWidget();
00545 result->addWidget(new WText(tr("home.download")));
00546 result->addWidget(new WText(tr("home.download.license")));
00547 result->addWidget(new WText(tr("home.download.requirements")));
00548 result->addWidget(new WText(tr("home.download.cvs")));
00549 result->addWidget(new WText(tr("home.download.packages")));
00550
00551 releases_ = new WTable();
00552 readReleases(releases_, "releases.txt");
00553 result->addWidget(releases_);
00554
00555 result->addWidget
00556 (new WText("<p>Older releases are still available at "
00557 + href("http://sourceforge.net/project/showfiles.php?"
00558 "group_id=153710#files",
00559 "sourceforge.net")
00560 + "</p>"));
00561
00562 return result;
00563 }
00564
00565 std::string Home::href(const std::string url, const std::string description)
00566 {
00567 return "<a href=\"" + url + "\" target=\"_blank\">" + description + "</a>";
00568 }
00569
00570 WWidget *Home::community()
00571 {
00572 return new WText(tr("home.community"));
00573 }
00574
00575 void Home::readNews(WTable *newsTable, const std::string newsfile)
00576 {
00577 std::ifstream f(newsfile.c_str());
00578
00579 newsTable->clear();
00580
00581 int row = 0;
00582
00583 while (f) {
00584 std::string line;
00585 getline(f, line);
00586
00587 if (f) {
00588 typedef boost::tokenizer<boost::escaped_list_separator<char> >
00589 CsvTokenizer;
00590 CsvTokenizer tok(line);
00591
00592 CsvTokenizer::iterator i=tok.begin();
00593
00594 newsTable->elementAt(row, 0)->
00595 addWidget(new WText("<p><b>" + *i + "</b></p>"));
00596 newsTable->elementAt(row, 0)
00597 ->setContentAlignment(AlignCenter | AlignTop);
00598 newsTable->elementAt(row, 0)
00599 ->resize(WLength(16, WLength::FontEx), WLength::Auto);
00600 newsTable
00601 ->elementAt(row, 1)->addWidget(new WText("<p>" + *(++i) + "</p>"));
00602
00603 ++row;
00604 }
00605 }
00606 }
00607
00608 void Home::readReleases(WTable *releaseTable, const std::string releasefile)
00609 {
00610 std::ifstream f(releasefile.c_str());
00611
00612 releaseTable->clear();
00613
00614 releaseTable->elementAt(0, 0)
00615 ->addWidget(new WText(tr("home.download.version")));
00616 releaseTable->elementAt(0, 1)
00617 ->addWidget(new WText(tr("home.download.date")));
00618 releaseTable->elementAt(0, 2)
00619 ->addWidget(new WText(tr("home.download.description")));
00620
00621 releaseTable->elementAt(0, 0)->resize(WLength(10, WLength::FontEx),
00622 WLength::Auto);
00623 releaseTable->elementAt(0, 1)->resize(WLength(15, WLength::FontEx),
00624 WLength::Auto);
00625
00626 int row = 1;
00627
00628 while (f) {
00629 std::string line;
00630 getline(f, line);
00631
00632 if (f) {
00633 typedef boost::tokenizer<boost::escaped_list_separator<char> >
00634 CsvTokenizer;
00635 CsvTokenizer tok(line);
00636
00637 CsvTokenizer::iterator i=tok.begin();
00638
00639 std::string version = *i;
00640 releaseTable->elementAt(row, 0)->addWidget
00641 (new WText(href("http://prdownloads.sourceforge.net/witty/wt-"
00642 + version + ".tar.gz?download", "Wt " + version)));
00643 releaseTable->elementAt(row, 1)->addWidget(new WText(*(++i)));
00644 releaseTable->elementAt(row, 2)->addWidget(new WText(*(++i)));
00645
00646 ++row;
00647 }
00648 }
00649 }
00650
00651 WTreeNode *Home::makeTreeMap(const std::string name, WTreeNode *parent)
00652 {
00653 WIconPair *labelIcon
00654 = new WIconPair("icons/yellow-folder-closed.png",
00655 "icons/yellow-folder-open.png", false);
00656
00657 WTreeNode *node = new WTreeNode(name, labelIcon, parent);
00658 node->label()->setTextFormat(PlainText);
00659
00660 if (!parent) {
00661 node->setImagePack("icons/");
00662 node->expand();
00663 node->setLoadPolicy(WTreeNode::NextLevelLoading);
00664 }
00665
00666 return node;
00667 }
00668
00669 WTreeNode *Home::makeTreeFile(const std::string name, WTreeNode *parent)
00670 {
00671 WIconPair *labelIcon
00672 = new WIconPair("icons/document.png",
00673 "icons/yellow-folder-open.png", false);
00674
00675 return new WTreeNode("<a href=\"" + fixRelativeUrl("wt/src/" + name)
00676 + "\" target=\"_blank\">"
00677 + name + "</a>", labelIcon, parent);
00678 }
00679
00680 WString Home::tr(const char *key)
00681 {
00682 return WString::tr(key);
00683 }
00684
00685 WApplication *createApplication(const WEnvironment& env)
00686 {
00687
00688
00689
00690 const std::string *historyKey = env.getParameter("historyKey");
00691
00692 if (historyKey) {
00693 const char *mainStr[]
00694 = { "main:0", "/",
00695 "main:1", "/news",
00696 "main:2", "/features",
00697 "main:4", "/examples",
00698 "main:3", "/documentation",
00699 "main:5", "/download",
00700 "main:6", "/community" };
00701
00702 const char *exampleStr[]
00703 = { "example:0", "/examples",
00704 "example:1", "/examples/charts",
00705 "example:2", "/examples/wt-homepage",
00706 "example:3", "/examples/treelist",
00707 "example:4", "/examples/hangman",
00708 "example:5", "/examples/chat",
00709 "example:6", "/examples/mail-composer",
00710 "example:7", "/examples/drag-and-drop",
00711 "example:8", "/examples/file-explorer",
00712 "example:9", "/examples/calendar" };
00713
00714 if (historyKey->find("main:4") != std::string::npos) {
00715 for (unsigned i = 0; i < 10; ++i)
00716 if (historyKey->find(exampleStr[i*2]) != std::string::npos) {
00717 WApplication *app = new WApplication(env);
00718 app->log("notice") << "redirecting old style URL '"
00719 << *historyKey << "' to internal path: '"
00720 << exampleStr[i*2+1] << "'";
00721 app->redirect(app->bookmarkUrl(exampleStr[i*2+1]));
00722 app->quit();
00723 return app;
00724 }
00725 } else
00726 for (unsigned i = 0; i < 6; ++i)
00727 if (historyKey->find(mainStr[i*2]) != std::string::npos) {
00728 WApplication *app = new WApplication(env);
00729
00730 app->log("notice") << "redirecting old style URL '"
00731 << *historyKey << "' to internal path: '"
00732 << mainStr[i*2+1] << "'";
00733 app->redirect(app->bookmarkUrl(mainStr[i*2+1]));
00734 app->quit();
00735 return app;
00736 }
00737
00738
00739 }
00740
00741 return new Home(env);
00742 }
00743
00744 int main(int argc, char **argv)
00745 {
00746 return WRun(argc, argv, &createApplication);
00747 }
00748