Wt examples 3.3.12
Home.C
Go to the documentation of this file.
1/*
2 * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
3 *
4 * See the LICENSE file for terms of use.
5 */
6
7#include <fstream>
8#include <iostream>
9
10#include <boost/lexical_cast.hpp>
11#include <boost/tokenizer.hpp>
12#include <boost/algorithm/string.hpp>
13
14#include <Wt/WAnchor>
15#include <Wt/WApplication>
16#include <Wt/WEnvironment>
17#include <Wt/WLogger>
18#include <Wt/WMenu>
19#include <Wt/WPushButton>
20#include <Wt/WStackedWidget>
21#include <Wt/WTabWidget>
22#include <Wt/WTable>
23#include <Wt/WTableCell>
24#include <Wt/WTemplate>
25#include <Wt/WText>
26#include <Wt/WViewWidget>
27#include <Wt/WVBoxLayout>
28
29#include "Home.h"
30#include "view/BlogView.h"
31
32static const std::string SRC_INTERNAL_PATH = "src";
33
35{
36}
37
40 const std::string& title, const std::string& resourceBundle,
41 const std::string& cssPath)
42 : WApplication(env),
43 releases_(0),
44 blogDb_(blogDb),
45 homePage_(0),
46 sourceViewer_(0)
47{
48 messageResourceBundle().use(appRoot() + resourceBundle, false);
49
50 useStyleSheet(cssPath + "/wt.css");
51 useStyleSheet(cssPath + "/wt_ie.css", "lt IE 7", "all");
52 useStyleSheet("css/home.css");
53 useStyleSheet("css/sourceview.css");
54 useStyleSheet("css/chatwidget.css");
55 useStyleSheet("css/chatwidget_ie6.css", "lt IE 7", "all");
57
58 setLocale("");
59 language_ = 0;
60}
61
72
74{
75 /*
76 * This function switches between the two major components of the homepage,
77 * depending on the internal path:
78 * /src -> source viewer
79 * /... -> homepage
80 *
81 * FIXME: we should take into account language /cn/src ...
82 */
83 std::string base = internalPathNextPart("/");
84
85 if (base == SRC_INTERNAL_PATH) {
86 if (!sourceViewer_) {
87 delete homePage_;
88 homePage_ = 0;
89
90 root()->clear();
91
93 WVBoxLayout *layout = new WVBoxLayout();
94 layout->setContentsMargins(0, 0, 0, 0);
95 layout->addWidget(sourceViewer_);
96 root()->setLayout(layout);
97 }
98 } else {
99 if (!homePage_) {
100 delete sourceViewer_;
101 sourceViewer_ = 0;
102
103 root()->clear();
104
105 createHome();
107
109 }
110 }
111}
112
114{
115 WTemplate *result = new WTemplate(tr("template"), root());
116 homePage_ = result;
117
118 WContainerWidget *languagesDiv = new WContainerWidget();
119 languagesDiv->setId("top_languages");
120
121 for (unsigned i = 0; i < languages.size(); ++i) {
122 if (i != 0)
123 new WText("- ", languagesDiv);
124
125 const Lang& l = languages[i];
126
128 WString::fromUTF8(l.longDescription_), languagesDiv);
129 }
130
131 WStackedWidget *contents = new WStackedWidget();
133 contents->setTransitionAnimation(fade);
134 contents->setId("main_page");
135
136 mainMenu_ = new WMenu(contents, Vertical);
137
139 (tr("introduction"), introduction())->setPathComponent("");
140
142 (tr("blog"), deferCreate(boost::bind(&Home::blog, this)));
143
146
148 (tr("documentation"), wrapView(&Home::documentation),
150
152 (tr("examples"), examples(),
154
156 (tr("download"), deferCreate(boost::bind(&Home::download, this)),
158
161
163 (tr("other-language"), wrapView(&Home::otherLanguage),
165
167
169
170 // Make the menu be internal-path aware.
172
174
175 result->bindWidget("languages", languagesDiv);
176 result->bindWidget("menu", mainMenu_);
177 result->bindWidget("contents", contents);
178 result->bindWidget("sidebar", sideBarContent_);
179}
180
181void Home::setLanguage(int index)
182{
183 if (homePage_) {
184 const Lang& l = languages[index];
185
186 setLocale(l.code_);
187
188 std::string langPath = l.path_;
190 examplesMenu_->setInternalBasePath(langPath + "examples");
191 BlogView *blog = dynamic_cast<BlogView *>(findWidget("blog"));
192 if (blog)
193 blog->setInternalBasePath(langPath + "blog/");
194 updateTitle();
195
196 language_ = index;
197 }
198}
199
200WWidget *Home::linkSourceBrowser(const std::string& example)
201{
202 /*
203 * Instead of using a WAnchor, which will not progress properly because
204 * it is wrapped with wrapView() (-- should we not fix that?), we use
205 * a WText which contains an anchor, and enable internal path encoding.
206 */
207 std::string path = "#/" + SRC_INTERNAL_PATH + "/" + example;
208 WText *a = new WText(tr("source-browser-link").arg(path));
210 return a;
211}
212
214{
215 std::string langPath = internalPathNextPart("/");
216
217 if (langPath.empty())
218 langPath = '/';
219 else
220 langPath = '/' + langPath + '/';
221
222 int newLanguage = 0;
223
224 for (unsigned i = 0; i < languages.size(); ++i) {
225 if (languages[i].path_ == langPath) {
226 newLanguage = i;
227 break;
228 }
229 }
230
231 if (newLanguage != language_)
232 setLanguage(newLanguage);
233}
234
236{
237 if (mainMenu_->currentItem()) {
238 setTitle(tr("wt") + " - " + mainMenu_->currentItem()->text());
239 }
240}
241
242void Home::logInternalPath(const std::string& path)
243{
244 // simulate an access log for the interal paths
245 log("path") << path;
246
247 // If this goes to /src, we need to invoke google analytics method too
248 if (path.size() >= 4 && path.substr(0, 4) == "/src") {
250 }
251}
252
254{
255 return new WText(tr("home.intro"));
256}
257
259{
260 const Lang& l = languages[language_];
261 std::string langPath = l.path_;
262 BlogView *blog = new BlogView(langPath + "blog/",
263 blogDb_, "/wt/blog/feed/");
264 blog->setObjectName("blog");
265
266 if (!blog->user().empty())
267 chatSetUser(blog->user());
268
269 blog->userChanged().connect(this, &Home::chatSetUser);
270
271 return blog;
272}
273
274void Home::chatSetUser(const WString& userName)
275{
276 WApplication::instance()->doJavaScript
277 ("if (window.chat && window.chat.emit) {"
278 """try {"
279 "" "window.chat.emit(window.chat, 'login', "
280 "" "" + userName.jsStringLiteral() + "); "
281 """} catch (e) {"
282 "" "window.chatUser=" + userName.jsStringLiteral() + ";"
283 """}"
284 "} else "
285 """window.chatUser=" + userName.jsStringLiteral() + ";");
286}
287
289{
290 return new WText(tr("home.status"));
291}
292
294{
295 return new WText(tr("home.features"));
296}
297
299{
300 WText *result = new WText(tr("home.documentation"));
301 result->setInternalPathEncoding(true);
302 return result;
303}
304
306{
307 return new WText(tr("home.other-language"));
308}
309
311{
312 return makeStaticModel(boost::bind(createWidget, this));
313}
314
315std::string Home::href(const std::string& url, const std::string& description)
316{
317 return "<a href=\"" + url + "\" target=\"_blank\">" + description + "</a>";
318}
319
321{
322 return new WText(tr("home.community"));
323}
324
325void Home::readReleases(WTable *releaseTable)
326{
327 std::ifstream f((filePrefix() + "releases.txt").c_str());
328
329 releaseTable->clear();
330
331 releaseTable->elementAt(0, 0)
332 ->addWidget(new WText(tr("home.download.version")));
333 releaseTable->elementAt(0, 1)
334 ->addWidget(new WText(tr("home.download.date")));
335 releaseTable->elementAt(0, 2)
336 ->addWidget(new WText(tr("home.download.description")));
337
338 releaseTable->elementAt(0, 0)->resize(WLength(15, WLength::FontEx),
340 releaseTable->elementAt(0, 1)->resize(WLength(15, WLength::FontEx),
342
343 int row = 1;
344
345 while (f) {
346 std::string line;
347 getline(f, line);
348
349 if (f) {
350 typedef boost::tokenizer<boost::escaped_list_separator<char> >
351 CsvTokenizer;
352 CsvTokenizer tok(line);
353
354 CsvTokenizer::iterator i=tok.begin();
355
356 std::string fileName = *i;
357 std::string description = *(++i);
358 releaseTable->elementAt(row, 1)->addWidget(new WText(*(++i)));
359 releaseTable->elementAt(row, 2)->addWidget(new WText(*(++i)));
360
361 ++i;
362 std::string url = "http://prdownloads.sourceforge.net/witty/"
363 + fileName + "?download";
364 if (i != tok.end())
365 url = *i;
366
367 releaseTable->elementAt(row, 0)->addWidget
368 (new WText(href(url, description)));
369
370 ++row;
371 }
372 }
373}
374
375#ifdef WT_EMWEB_BUILD
377{
378 WContainerWidget *result = new WContainerWidget();
379 result->setStyleClass("quote");
380
381 WTemplate *requestTemplate = new WTemplate(tr("quote.request"), result);
382
383 WPushButton *quoteButton = new WPushButton(tr("quote.requestbutton"));
384 requestTemplate->bindWidget("button", quoteButton);
385
387 result->addWidget(quoteForm);
388
389 quoteButton->clicked().connect(quoteForm, &WWidget::show);
390 quoteButton->clicked().connect(requestTemplate, &WWidget::hide);
391
392 quoteForm->hide();
393
394 return result;
395}
396#endif // WT_EMWEB_BUILD
397
399{
400 WContainerWidget *result = new WContainerWidget();
401 result->addWidget(new WText(tr("home.download")));
402
403 result->addWidget(new WText(tr("home.download.license")));
404
405#ifdef WT_EMWEB_BUILD
406 result->addWidget(quoteForm());
407#endif // WT_EMWEB_BUILD
408
409 result->addWidget(new WText(tr("home.download.packages")));
410
411 releases_ = new WTable();
413 result->addWidget(releases_);
414
415 result->addWidget(new WText(tr("home.download.other")));
416
417 return result;
418}
419
420
421WString Home::tr(const char *key)
422{
423 return WString::tr(key);
424}
425
427{
428 doJavaScript("if (window.ga) ga('send','pageview',"
429 + WWebWidget::jsStringLiteral(environment().deploymentPath()
430 + internalPath()) + ");");
431}
432
static const std::string SRC_INTERNAL_PATH
Definition Home.C:32
DeferredWidget< Function > * deferCreate(Function f)
Definition Home.h:62
Definition Home.h:68
void setup()
Definition Home.C:73
WWidget * otherLanguage()
Definition Home.C:305
WWidget * status()
Definition Home.C:288
WWidget * features()
Definition Home.C:293
void createHome()
Definition Home.C:113
WTable * releases_
Definition Home.h:94
WWidget * download()
Definition Home.C:398
WTabWidget * examplesMenu_
Definition Home.h:89
void googleAnalyticsLogger()
Definition Home.C:426
WWidget * blog()
Definition Home.C:258
WWidget * introduction()
Definition Home.C:253
WWidget * community()
Definition Home.C:320
std::string href(const std::string &url, const std::string &description)
Definition Home.C:315
WWidget * documentation()
Definition Home.C:298
int language_
Definition Home.h:118
void setLanguage(int language)
Definition Home.C:181
WWidget * homePage_
Definition Home.h:99
WWidget * wrapView(WWidget *(Home::*createFunction)())
Definition Home.C:310
void init()
Definition Home.C:62
WWidget * linkSourceBrowser(const std::string &examplePath)
Definition Home.C:200
void updateTitle()
Definition Home.C:235
virtual ~Home()
Definition Home.C:34
WString tr(const char *key)
Definition Home.C:421
virtual std::string filePrefix() const =0
WWidget * sourceViewer_
Definition Home.h:100
virtual WWidget * examples()=0
virtual WWidget * sourceViewer(const std::string &deployPath)=0
virtual WWidget * createQuoteForm()=0
WMenu * mainMenu_
Definition Home.h:116
void readReleases(WTable *releaseTable)
Definition Home.C:325
Home(const WEnvironment &env, Wt::Dbo::SqlConnectionPool &blogDb, const std::string &title, const std::string &resourceBundle, const std::string &cssPath)
Definition Home.C:38
WContainerWidget * sideBarContent_
Definition Home.h:131
void logInternalPath(const std::string &path)
Definition Home.C:242
Wt::Dbo::SqlConnectionPool & blogDb_
Definition Home.h:98
std::vector< Lang > languages
Definition Home.h:133
WWidget * quoteForm()
void setLanguageFromPath()
Definition Home.C:213
void chatSetUser(const WString &name)
Definition Home.C:274
virtual Wt::Signals::connection connect(WObject *target, WObject::Method method)
WWidget * findWidget(const std::string &name)
void doJavaScript(const std::string &javascript, bool afterLoaded=true)
std::string internalPath() const
WMessageResourceBundle & messageResourceBundle()
friend friend class WContainerWidget
WContainerWidget * root() const
Signal< std::string > & internalPathChanged()
std::string internalPathNextPart(const std::string &path) const
void setTitle(const WString &title)
static std::string appRoot()
void useStyleSheet(const WLink &link, const std::string &media="all")
WLogEntry log(const std::string &type) const
std::string url(const std::string &internalPath=std::string()) const
const WEnvironment & environment() const
void setLocale(const WLocale &locale)
friend friend class WMenu
const WString & title() const
void addWidget(WWidget *widget, int stretch=0, WFlags< AlignmentFlag > alignment=0)
void setLayout(WLayout *layout)
virtual void addWidget(WWidget *widget)
virtual void clear()
EventSignal< WMouseEvent > & clicked()
void setContentsMargins(int left, int top, int right, int bottom)
static WLength Auto
virtual void setPathComponent(const std::string &path)
const WString & text() const
WMenuItem * addItem(const WString &label, WWidget *contents=0, WMenuItem::LoadPolicy policy=WMenuItem::LazyLoading)
Signal< WMenuItem * > & itemSelected()
Signal< WMenuItem * > & itemSelectRendered()
WMenuItem * currentItem() const
void setInternalBasePath(const std::string &basePath)
void setInternalPathEnabled(const std::string &basePath="")
void use(const std::string &path, bool loadInMemory=true)
void setTransitionAnimation(const WAnimation &animation, bool autoReverse=false)
static WString tr(const char *key)
static WString fromUTF8(const std::string &value, bool checkValid=false)
std::string jsStringLiteral(char delimiter='\'') const
void setInternalBasePath(const std::string &path)
virtual void clear()
WTableCell * elementAt(int row, int column)
virtual void bindWidget(const std::string &varName, WWidget *widget)
void setInternalPathEncoding(bool enabled)
virtual void setId(const std::string &id)
virtual void resize(const WLength &width, const WLength &height)
static std::string jsStringLiteral(const std::string &v, char delimiter='\'')
virtual void setStyleClass(const WString &styleClass)
virtual void doJavaScript(const std::string &js)=0
virtual void setObjectName(const std::string &name)
Vertical
WApplication * createWidget(const WEnvironment &env, SimpleChatServer &server)
Definition simpleChat.C:145
Definition Home.h:23
std::string longDescription_
Definition Home.h:33
std::string code_
Definition Home.h:33
std::string path_
Definition Home.h:33

Generated on Fri May 17 2024 for the C++ Web Toolkit (Wt) by doxygen 1.9.8