Wt examples  3.3.0
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 
32 static const std::string SRC_INTERNAL_PATH = "src";
33 
35 {
36 }
37 
38 Home::Home(const WEnvironment& env, const std::string& title,
39  const std::string& resourceBundle, const std::string& cssPath)
40  : WApplication(env),
41  releases_(0),
42  homePage_(0),
43  sourceViewer_(0)
44 {
45  messageResourceBundle().use(appRoot() + resourceBundle, false);
46 
47  useStyleSheet(cssPath + "/wt.css");
48  useStyleSheet(cssPath + "/wt_ie.css", "lt IE 7");
49  useStyleSheet("css/home.css");
50  useStyleSheet("css/sourceview.css");
51  useStyleSheet("css/chatwidget.css");
52  useStyleSheet("css/chatwidget_ie6.css", "lt IE 7");
53  setTitle(title);
54 
55  setLocale("");
56  language_ = 0;
57 }
58 
59 void Home::init()
60 {
61  internalPathChanged().connect(this, &Home::setup);
64 
65  setup();
66 
68 }
69 
71 {
72  /*
73  * This function switches between the two major components of the homepage,
74  * depending on the internal path:
75  * /src -> source viewer
76  * /... -> homepage
77  *
78  * FIXME: we should take into account language /cn/src ...
79  */
80  std::string base = internalPathNextPart("/");
81 
82  if (base == SRC_INTERNAL_PATH) {
83  if (!sourceViewer_) {
84  delete homePage_;
85  homePage_ = 0;
86 
87  root()->clear();
88 
90  WVBoxLayout *layout = new WVBoxLayout();
91  layout->setContentsMargins(0, 0, 0, 0);
92  layout->addWidget(sourceViewer_);
93  root()->setLayout(layout);
94  }
95  } else {
96  if (!homePage_) {
97  delete sourceViewer_;
98  sourceViewer_ = 0;
99 
100  root()->clear();
101 
102  createHome();
103  root()->addWidget(homePage_);
104 
106  }
107  }
108 }
109 
111 {
112  WTemplate *result = new WTemplate(tr("template"), root());
113  homePage_ = result;
114 
115  WContainerWidget *languagesDiv = new WContainerWidget();
116  languagesDiv->setId("top_languages");
117 
118  for (unsigned i = 0; i < languages.size(); ++i) {
119  if (i != 0)
120  new WText("- ", languagesDiv);
121 
122  const Lang& l = languages[i];
123 
124  new WAnchor(WLink(WLink::InternalPath, l.path_),
125  WString::fromUTF8(l.longDescription_), languagesDiv);
126  }
127 
128  WStackedWidget *contents = new WStackedWidget();
129  WAnimation fade(WAnimation::Fade, WAnimation::Linear, 250);
130  contents->setTransitionAnimation(fade);
131  contents->setId("main_page");
132 
133  mainMenu_ = new WMenu(contents, Vertical);
134 
136  (tr("introduction"), introduction())->setPathComponent("");
137 
139  (tr("blog"), deferCreate(boost::bind(&Home::blog, this)));
140 
142  (tr("features"), wrapView(&Home::features), WMenuItem::PreLoading);
143 
145  (tr("documentation"), wrapView(&Home::documentation),
146  WMenuItem::PreLoading);
147 
149  (tr("examples"), examples(),
150  WMenuItem::PreLoading)->setPathComponent("examples/");
151 
153  (tr("download"), deferCreate(boost::bind(&Home::download, this)),
154  WMenuItem::PreLoading);
155 
157  (tr("community"), wrapView(&Home::community), WMenuItem::PreLoading);
158 
160  (tr("other-language"), wrapView(&Home::otherLanguage),
161  WMenuItem::PreLoading);
162 
164 
166 
167  // Make the menu be internal-path aware.
169 
171 
172  result->bindWidget("languages", languagesDiv);
173  result->bindWidget("menu", mainMenu_);
174  result->bindWidget("contents", contents);
175  result->bindWidget("sidebar", sideBarContent_);
176 }
177 
178 void Home::setLanguage(int index)
179 {
180  if (homePage_) {
181  const Lang& l = languages[index];
182 
183  setLocale(l.code_);
184 
185  std::string langPath = l.path_;
186  mainMenu_->setInternalBasePath(langPath);
187  examplesMenu_->setInternalBasePath(langPath + "examples");
188  BlogView *blog = dynamic_cast<BlogView *>(findWidget("blog"));
189  if (blog)
190  blog->setInternalBasePath(langPath + "blog/");
191  updateTitle();
192 
193  language_ = index;
194  }
195 }
196 
197 WWidget *Home::linkSourceBrowser(const std::string& example)
198 {
199  /*
200  * Instead of using a WAnchor, which will not progress properly because
201  * it is wrapped with wrapView() (-- should we not fix that?), we use
202  * a WText which contains an anchor, and enable internal path encoding.
203  */
204  std::string path = "#/" + SRC_INTERNAL_PATH + "/" + example;
205  WText *a = new WText(tr("source-browser-link").arg(path));
206  a->setInternalPathEncoding(true);
207  return a;
208 }
209 
211 {
212  std::string langPath = internalPathNextPart("/");
213 
214  if (langPath.empty())
215  langPath = '/';
216  else
217  langPath = '/' + langPath + '/';
218 
219  int newLanguage = 0;
220 
221  for (unsigned i = 0; i < languages.size(); ++i) {
222  if (languages[i].path_ == langPath) {
223  newLanguage = i;
224  break;
225  }
226  }
227 
228  if (newLanguage != language_)
229  setLanguage(newLanguage);
230 }
231 
233 {
234  if (mainMenu_->currentItem()) {
235  setTitle(tr("wt") + " - " + mainMenu_->currentItem()->text());
236  }
237 }
238 
239 void Home::logInternalPath(const std::string& path)
240 {
241  // simulate an access log for the interal paths
242  log("path") << path;
243 
244  // If this goes to /src, we need to invoke google analytics method too
245  if (path.size() >= 4 && path.substr(0, 4) == "/src") {
247  }
248 }
249 
251 {
252  return new WText(tr("home.intro"));
253 }
254 
256 {
257  const Lang& l = languages[language_];
258  std::string langPath = l.path_;
259  BlogView *blog = new BlogView(langPath + "blog/",
260  appRoot() + "blog.db", "/wt/blog/feed/");
261  blog->setObjectName("blog");
262 
263  if (!blog->user().empty())
264  chatSetUser(blog->user());
265 
266  blog->userChanged().connect(this, &Home::chatSetUser);
267 
268  return blog;
269 }
270 
271 void Home::chatSetUser(const WString& userName)
272 {
273  WApplication::instance()->doJavaScript
274  ("if (window.chat && window.chat.emit) {"
275  """try {"
276  "" "window.chat.emit(window.chat, 'login', "
277  "" "" + userName.jsStringLiteral() + "); "
278  """} catch (e) {"
279  "" "window.chatUser=" + userName.jsStringLiteral() + ";"
280  """}"
281  "} else "
282  """window.chatUser=" + userName.jsStringLiteral() + ";");
283 }
284 
286 {
287  return new WText(tr("home.status"));
288 }
289 
291 {
292  return new WText(tr("home.features"));
293 }
294 
296 {
297  WText *result = new WText(tr("home.documentation"));
298  result->setInternalPathEncoding(true);
299  return result;
300 }
301 
303 {
304  return new WText(tr("home.other-language"));
305 }
306 
308 {
309  return makeStaticModel(boost::bind(createWidget, this));
310 }
311 
312 std::string Home::href(const std::string& url, const std::string& description)
313 {
314  return "<a href=\"" + url + "\" target=\"_blank\">" + description + "</a>";
315 }
316 
318 {
319  return new WText(tr("home.community"));
320 }
321 
322 void Home::readReleases(WTable *releaseTable)
323 {
324  std::ifstream f((filePrefix() + "releases.txt").c_str());
325 
326  releaseTable->clear();
327 
328  releaseTable->elementAt(0, 0)
329  ->addWidget(new WText(tr("home.download.version")));
330  releaseTable->elementAt(0, 1)
331  ->addWidget(new WText(tr("home.download.date")));
332  releaseTable->elementAt(0, 2)
333  ->addWidget(new WText(tr("home.download.description")));
334 
335  releaseTable->elementAt(0, 0)->resize(WLength(15, WLength::FontEx),
336  WLength::Auto);
337  releaseTable->elementAt(0, 1)->resize(WLength(15, WLength::FontEx),
338  WLength::Auto);
339 
340  int row = 1;
341 
342  while (f) {
343  std::string line;
344  getline(f, line);
345 
346  if (f) {
347  typedef boost::tokenizer<boost::escaped_list_separator<char> >
348  CsvTokenizer;
349  CsvTokenizer tok(line);
350 
351  CsvTokenizer::iterator i=tok.begin();
352 
353  std::string fileName = *i;
354  std::string description = *(++i);
355  releaseTable->elementAt(row, 0)->addWidget
356  (new WText(href("http://prdownloads.sourceforge.net/witty/"
357  + fileName + "?download", description)));
358  releaseTable->elementAt(row, 1)->addWidget(new WText(*(++i)));
359  releaseTable->elementAt(row, 2)->addWidget(new WText(*(++i)));
360 
361  ++row;
362  }
363  }
364 }
365 
366 #ifdef WT_EMWEB_BUILD
368 {
369  WContainerWidget *result = new WContainerWidget();
370  result->setStyleClass("quote");
371 
372  WTemplate *requestTemplate = new WTemplate(tr("quote.request"), result);
373 
374  WPushButton *quoteButton = new WPushButton(tr("quote.requestbutton"));
375  requestTemplate->bindWidget("button", quoteButton);
376 
378  result->addWidget(quoteForm);
379 
380  quoteButton->clicked().connect(quoteForm, &WWidget::show);
381  quoteButton->clicked().connect(requestTemplate, &WWidget::hide);
382 
383  quoteForm->hide();
384 
385  return result;
386 }
387 #endif // WT_EMWEB_BUILD
388 
390 {
391  WContainerWidget *result = new WContainerWidget();
392  result->addWidget(new WText(tr("home.download")));
393 
394  result->addWidget(new WText(tr("home.download.license")));
395 
396 #ifdef WT_EMWEB_BUILD
397  result->addWidget(quoteForm());
398 #endif // WT_EMWEB_BUILD
399 
400  result->addWidget(new WText(tr("home.download.packages")));
401 
402  releases_ = new WTable();
404  result->addWidget(releases_);
405 
406  result->addWidget(new WText(tr("home.download.other")));
407 
408  return result;
409 }
410 
411 
412 WString Home::tr(const char *key)
413 {
414  return WString::tr(key);
415 }
416 
418 {
419  std::string googleCmd =
420  "if (window.pageTracker) {"
421  """try {"
422  "" "setTimeout(function() {"
423  "" "window.pageTracker._trackPageview(\""
424  + environment().deploymentPath() + internalPath() + "\");"
425  "" "}, 1000);"
426  """} catch (e) { }"
427  "}";
428 
429  doJavaScript(googleCmd);
430 }
431 

Generated on Fri May 31 2013 for the C++ Web Toolkit (Wt) by doxygen 1.8.3.1