1 // This may look like C code, but it's really -*- C++ -*-
2 /*
3  * Copyright (C) 2008 Emweb bv, Herent, Belgium.
4  *
5  * See the LICENSE file for terms of use.
6  */
7 #ifndef HOME_H_
8 #define HOME_H_
9 
10 #include <Wt/WApplication.h>
11 #include <Wt/WContainerWidget.h>
12 
13 namespace Wt {
14   class WMenu;
15   class WStackedWidget;
16   class WTabWidget;
17   class WTreeNode;
18   class WTable;
19 }
20 
21 using namespace Wt;
22 
23 struct Lang {
LangLang24   Lang(const std::string& code, const std::string& path,
25        const std::string& shortDescription,
26        const std::string& longDescription) :
27     code_(code),
28     path_(path),
29     shortDescription_(shortDescription),
30     longDescription_(longDescription) {
31   }
32 
33   std::string code_, path_, shortDescription_, longDescription_;
34 };
35 
36 /*
37  * A utility container widget which defers creation of its single
38  * child widget until the container is loaded (which is done on-demand
39  * by a WMenu). The constructor takes the create function for the
40  * widget as a parameter.
41  *
42  * We use this to defer widget creation until needed.
43  */
44 template <typename Function>
45 class DeferredWidget : public WContainerWidget
46 {
47 public:
DeferredWidget(Function f)48   DeferredWidget(Function f)
49     : f_(f) { }
50 
51 private:
load()52   void load() {
53     WContainerWidget::load();
54     if (count() == 0)
55       addWidget(f_());
56   }
57 
58   Function f_;
59 };
60 
61 template <typename Function>
deferCreate(Function f)62 std::unique_ptr<DeferredWidget<Function>> deferCreate(Function f)
63 {
64   return std::make_unique<DeferredWidget<Function>>(f);
65 }
66 
67 class Home : public WApplication
68 {
69 public:
70   Home(const WEnvironment& env, Dbo::SqlConnectionPool& blogDb,
71        const std::string& title,
72        const std::string& resourceBundle, const std::string& cssPath);
73 
74   virtual ~Home();
75 
76   void googleAnalyticsLogger();
77 
78 protected:
79   virtual std::unique_ptr<WWidget> examples() = 0;
80   virtual std::unique_ptr<WWidget> createQuoteForm() = 0;
81   virtual std::unique_ptr<WWidget> sourceViewer(const std::string &deployPath) = 0;
82   virtual std::string filePrefix() const = 0;
83 
84   void init();
85 
addLanguage(const Lang & l)86   void addLanguage(const Lang& l) { languages.push_back(l); }
87   std::unique_ptr<WWidget> linkSourceBrowser(const std::string& examplePath);
88 
89   WTabWidget *examplesMenu_;
90 
91   WString tr(const char *key);
92   std::string href(const std::string& url, const std::string& description);
93 
94   WTable *releases_;
95   void readReleases(WTable *releaseTable);
96 
97 private:
98   Dbo::SqlConnectionPool& blogDb_;
99   WWidget *homePage_;
100   WWidget *sourceViewer_;
101 
102   WStackedWidget *contents_;
103 
104   void createHome();
105 
106   std::unique_ptr<WWidget> introduction();
107   std::unique_ptr<WWidget> blog();
108   std::unique_ptr<WWidget> status();
109   std::unique_ptr<WWidget> features();
110   std::unique_ptr<WWidget> documentation();
111   std::unique_ptr<WWidget> community();
112   std::unique_ptr<WWidget> otherLanguage();
113   std::unique_ptr<WWidget> download();
114   std::unique_ptr<WWidget> quoteForm();
115 
116   WMenu *mainMenu_;
117 
118   int language_;
119 
120   void readNews(WTable *newsTable, const std::string& newsfile);
121 
122   std::unique_ptr<WWidget> wrapView(std::unique_ptr<WWidget> (Home::*createFunction)());
123 
124   void updateTitle();
125   void setLanguage(int language);
126   void setLanguageFromPath();
127   void setup();
128   void logInternalPath(const std::string& path);
129   void chatSetUser(const WString& name);
130 
131   std::unique_ptr<WContainerWidget> sideBarContent_;
132 
133   std::vector<Lang> languages;
134 };
135 
136 #endif // HOME_H_
137