Esempio n. 1
0
File: BlogView.C Progetto: DTidd/wt
  void loggedIn() {
    WApplication::instance()->changeSessionId();

    refresh();

    loginStatus_->resolveWidget("login")->show();
    loginStatus_->resolveWidget("login-link")->hide();
    loginStatus_->resolveWidget("register-link")->hide();

    WText *profileLink = new WText(tr("profile"));
    profileLink->setStyleClass("link");
    profileLink->clicked().connect(this, &BlogImpl::editProfile);

    dbo::ptr<User> user = session().user();

    if (user->role == User::Admin) {
      WText *editUsersLink = new WText(tr("edit-users"));
      editUsersLink->setStyleClass("link");
      editUsersLink->clicked().connect(SLOT(this, BlogImpl::editUsers));
      loginStatus_->bindWidget("userlist-link", editUsersLink);

      WText *authorPanelLink = new WText(tr("author-post"));
      authorPanelLink->setStyleClass("link");
      authorPanelLink->clicked().connect(SLOT(this, BlogImpl::authorPanel));
      loginStatus_->bindWidget("author-panel-link", authorPanelLink);
    } else {
      loginStatus_->bindEmpty("userlist-link");
      loginStatus_->bindEmpty("author-panel-link");
    }
 
    loginStatus_->bindWidget("profile-link", profileLink);
 
    bindPanelTemplates();
  }
Esempio n. 2
0
void CommentView::renderView()
{
  clear();

  bool isRootComment = !comment_->parent;
  setTemplateText(isRootComment ? tr("blog-root-comment")
		  : tr("blog-comment"));

  bindString("collapse-expand", WString::Empty); // NYI

  WText *replyText = new WText(isRootComment ? tr("comment-add")
			       : tr("comment-reply"));
  replyText->setStyleClass("link");
  replyText->clicked().connect(this, &CommentView::reply);
  bindWidget("reply", replyText);

  bool mayEdit = session_.user()
    && (comment_->author == session_.user()
	|| session_.user()->role == User::Admin);

  if (mayEdit) {
    WText *editText = new WText(tr("comment-edit"));
    editText->setStyleClass("link");
    editText->clicked().connect(this, &CommentView::edit);
    bindWidget("edit", editText);
  } else
    bindString("edit", WString::Empty);

  bool mayDelete
    = (session_.user() && session_.user() == comment_->author)
    || session_.user() == comment_->post->author; 

  if (mayDelete) {
    WText *deleteText = new WText(tr("comment-delete"));
    deleteText->setStyleClass("link");
    deleteText->clicked().connect(this, &CommentView::rm);
    bindWidget("delete", deleteText);
  } else
    bindString("delete", WString::Empty);

  typedef std::vector< dbo::ptr<Comment> > CommentVector;
  CommentVector comments;
  {
    dbo::collection<dbo::ptr<Comment> > cmts
      = comment_->children.find().orderBy("date");
    comments.insert(comments.end(), cmts.begin(), cmts.end());
  }

  WContainerWidget *children = new WContainerWidget();
  for (int i = (int)comments.size() - 1; i >= 0; --i)
    children->addWidget(new CommentView(session_, comments[i]));

  bindWidget("children", children);
}
Esempio n. 3
0
File: BlogView.C Progetto: Unss/wt
  BlogImpl(const std::string& basePath, dbo::SqlConnectionPool& connectionPool,
	   const std::string& rssFeedUrl, BlogView *blogView)
    : basePath_(basePath),
      rssFeedUrl_(rssFeedUrl),
      session_(connectionPool),
      blogView_(blogView),
      panel_(0),
      authorPanel_(0),
      users_(0),
      userEditor_(0),
      mustLoginWarning_(0),
      mustBeAdministratorWarning_(0),
      invalidUser_(0)
  {
    WApplication *app = wApp;

    app->messageResourceBundle().use(WApplication::appRoot() + "blog");
    app->useStyleSheet("/css/blog.css");
    app->useStyleSheet("/css/asciidoc.css");
    app->internalPathChanged().connect(this, &BlogImpl::handlePathChange);

    loginStatus_ = new WTemplate(tr("blog-login-status"), this);
    panel_ = new WStackedWidget(this);
    items_ = new WContainerWidget(this);

    session_.login().changed().connect(this, &BlogImpl::onUserChanged);

    loginWidget_ = new BlogLoginWidget(session_, basePath);
    loginWidget_->hide();

    WText *loginLink = new WText(tr("login"));
    loginLink->setStyleClass("link");
    loginLink->clicked().connect(loginWidget_, &WWidget::show);
    loginLink->clicked().connect(loginLink, &WWidget::hide);

    WText *registerLink = new WText(tr("Wt.Auth.register"));
    registerLink->setStyleClass("link");
    registerLink->clicked().connect(loginWidget_,
				    &BlogLoginWidget::registerNewUser);

    WAnchor* archiveLink = new WAnchor
      (WLink(WLink::InternalPath, basePath_ + "all"), tr("archive"));

    loginStatus_->bindWidget("login", loginWidget_);
    loginStatus_->bindWidget("login-link", loginLink);
    loginStatus_->bindWidget("register-link", registerLink);
    loginStatus_->bindString("feed-url", rssFeedUrl_);
    loginStatus_->bindWidget("archive-link", archiveLink);

    onUserChanged();

    loginWidget_->processEnvironment();
  }
Esempio n. 4
0
FormExample::FormExample()
    : WContainerWidget()
{
  WContainerWidget *langLayout = this->addWidget(cpp14::make_unique<WContainerWidget>());
  langLayout->setContentAlignment(AlignmentFlag::Right);
  langLayout->addWidget(cpp14::make_unique<WText>(tr("language")));

  const char *lang[] = { "en", "nl" };

  for (int i = 0; i < 2; ++i) {
    WText *t = langLayout->addWidget(cpp14::make_unique<WText>(lang[i]));
    t->setMargin(5);
    t->clicked().connect(std::bind(&FormExample::changeLanguage, this, t));

    languageSelects_.push_back(t);
  }

  /*
   * Start with the reported locale, if available
   */
  setLanguage(wApp->locale().name());

  Form *form = this->addWidget(cpp14::make_unique<Form>());
  form->setMargin(20);
}
Esempio n. 5
0
ItemContaWidget::ItemContaWidget(Wt::WContainerWidget *parent,
				 ContaWidget *view,
				 int id_diario,
				 std::string data,
				 std::string descricao,
				 Moeda debito,
				 Moeda credito):
  WContainerWidget(parent), view_(view), 
  id_diario_(id_diario),
  data_(data), 
  descricao_(descricao),
  debito_(debito), 
  credito_(credito){
  setInline(true);

  WText *btnRemove = new WText("<button class='bg-color-red fg-color-white'>Remove</button>", Wt::XHTMLUnsafeText);
  btnRemove->clicked().connect(this, &ItemContaWidget::removeLancamento);

  WTemplate *t = new WTemplate(this);
  t->setTemplateText(
		     "<tr>"
		     "<td>${data}</td>"
		     "<td>${descricao}</td>"
		     "<td class='right'>${debito}</td>"
		     "<td class='right'>${credito}</td>"
		     "<td>${btnRemove}</td>"
		     "</tr>", XHTMLUnsafeText);
  t->bindString("data", data_);
  t->bindString("descricao", WString(descricao_, UTF8));
  t->bindString("debito", debito_.valStr());
  t->bindString("credito", credito_.valStr());
  t->bindWidget("btnRemove", btnRemove);
  t->setInline(true);
  }
Esempio n. 6
0
void CalendarCell::update(const dbo::ptr<UserAccount>& user, const WDate& date)
{
  date_ = date;
  user_ = user;

  clear();

  dbo::Session& session = PlannerApplication::plannerApplication()->session;
  dbo::Transaction transaction(session);
  
  WString day;
  day += boost::lexical_cast<std::string>(date.day());
  if (date.day() == 1)
    day += " " + WDate::longMonthName(date.month());
  WText* header = new WText(day);
  header->setStyleClass("cell-header");
  addWidget(header);

  typedef dbo::collection< dbo::ptr<Entry> > Entries;
  Entries entries = user->entriesInRange(date, date.addDays(1));

  const unsigned maxEntries = 4;
  unsigned counter = 0;
  for (Entries::const_iterator i = entries.begin();
       i != entries.end(); ++i, ++counter) {
    if (counter == maxEntries) {
      WText* extra = 
	new WText(tr("calendar.cell.extra")
		  .arg((int)(entries.size() - maxEntries)));
      extra->setStyleClass("cell-extra");
      addWidget(extra);

      extra->clicked().preventPropagation();
      extra->clicked().connect(this, &CalendarCell::showAllEntriesDialog);
      
      break;
    }

    WString format = EntryDialog::timeFormat;
    addWidget(new WText((*i)->start.toString(format) +
			"-" + 
			(*i)->stop.toString(format) + 
			": " + (*i)->summary));
  }

  transaction.commit();
}
Esempio n. 7
0
void AuthWidget::updatePasswordLoginView()
{
  if (model_->passwordAuth()) {
    setCondition("if:passwords", true);

    updateView(model_);

    WInteractWidget *login = resolve<WInteractWidget *>("login");

    if (!login) {
      login = new WPushButton(tr("Wt.Auth.login"));
      login->clicked().connect(this, &AuthWidget::attemptPasswordLogin);
      bindWidget("login", login);

      model_->configureThrottling(login);

      if (model_->baseAuth()->emailVerificationEnabled()) {
	WText *text = new WText(tr("Wt.Auth.lost-password"));
	text->clicked().connect(this, &AuthWidget::handleLostPassword);
	bindWidget("lost-password", text);
      } else
	bindEmpty("lost-password");

      if (registrationEnabled_) {
	WInteractWidget *w;
	if (!basePath_.empty()) {
	  w = new WAnchor
	    (WLink(WLink::InternalPath, basePath_ + "register"),
	     tr("Wt.Auth.register"));
	} else {
	  w = new WText(tr("Wt.Auth.register"));
	  w->clicked().connect(this, &AuthWidget::registerNewUser);
	}

	bindWidget("register", w);
      } else
	bindEmpty("register");

      if (model_->baseAuth()->emailVerificationEnabled()
	  && registrationEnabled_)
	bindString("sep", " | ");
      else
	bindEmpty("sep");
    }

    model_->updateThrottling(login);
  } else {
    bindEmpty("lost-password");
    bindEmpty("sep");
    bindEmpty("register");
    bindEmpty("login");
  }
}
Esempio n. 8
0
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8/////////9/////////A
void PagesList::load()
{
    impl_->clear();

    // item count
    WText *wtitemt = new WText("Eintraege : ", impl_);
	wtitemt->setStyleClass("tableFilter");
    WText *wtitems = new WText(lexical_cast<string>(table_->entriesCount()), impl_);
	wtitems->setStyleClass("pageNumbersCurr");

    // pages
    WText *wtxtpg = new WText("  Seiten : ", impl_);
	wtxtpg->setStyleClass("tableFilter");
	const unsigned int pagesCount = 1 + table_->entriesCount() / table_->entriesPerPage();
	if(pagesCount > 1 && table_->pageNr() > 1)
	{
        WText *previous = new WText("<", impl_);
        previous->setStyleClass("pageNumbers");
        previous->setToolTip("vorherige");
        previous->clicked().connect(SLOT(this, PagesList::select));
	}
    for(unsigned int i=0; i<pagesCount; ++i)
    {
        WText *wtxt = new WText(lexical_cast<string>(i+1), impl_);
        if(i + 1 == table_->pageNr())
            wtxt->setStyleClass("pageNumbersCurr");
        else
        {
            wtxt->setStyleClass("pageNumbers");
            wtxt->clicked().connect(SLOT(this, PagesList::select));
        }
    }
	if(pagesCount > 1 && table_->pageNr() < pagesCount)
    {
        WText *next = new WText(">", impl_);
        next->setStyleClass("pageNumbers");
        next->setToolTip("nächste");
        next->clicked().connect(SLOT(this, PagesList::select));
    }
}
Esempio n. 9
0
void WMenuItem::setCloseable(bool closeable)
{
  if (closeable_ != closeable) {
    closeable_ = closeable;

    if (closeable_) {
      WText *closeIcon = new WText("");
      insertWidget(0, std::unique_ptr<WText>(closeIcon));
      WApplication *app = WApplication::instance();
      app->theme()->apply(this, closeIcon, WidgetThemeRole::MenuItemClose);

      closeIcon->clicked().connect(this, &WMenuItem::close);
    } else
      removeWidget(widget(0));
  }
}
Esempio n. 10
0
void WMenuItem::setCloseable(bool closeable)
{
  if (closeable_ != closeable) {
    closeable_ = closeable;

    if (closeable_) {
      WText *closeIcon = new WText("");
      insertWidget(0, closeIcon);
      WApplication *app = WApplication::instance();
      app->theme()->apply(this, closeIcon, MenuItemCloseRole);

      closeIcon->clicked().connect(this, &WMenuItem::close);
    } else {
      delete widget(0);
    }
  }
}
Esempio n. 11
0
File: EditUsers.C Progetto: DTidd/wt
void EditUsers::limitList()
{
  WContainerWidget* list = new WContainerWidget;
  bindWidget("user-list",list);

  typedef dbo::collection<dbo::ptr<User> > UserList;
  dbo::Transaction t(session_);
  UserList users = session_.find<User>().where("name like ?").bind("%"+limitEdit_->text()+"%").orderBy("name");

  for (UserList::const_iterator i = users.begin(); i != users.end(); ++i) {
    WText* t = new WText((*i)->name, list);
    t->setStyleClass("link");
    new WBreak(list);
    t->clicked().connect(boost::bind(&EditUsers::onUserClicked, this, (*i).id()));
  }
  if (!users.size())
    new WText(tr("no-users-found"),list);
}
Esempio n. 12
0
WWidget *Cms::Layout()
{
    Div *container = new Div("Cms", "cms-layout container-fluid");
    Div *noScript = new Div(container);
    noScript->addWidget(new WText(tr("no-script")));

    CgiRoot *cgiRoot = static_cast<CgiRoot *>(WApplication::instance());
    CgiEnv *cgiEnv = cgiRoot->GetCgiEnvInstance();

    string htmlData;
    string file;
    if (cgiEnv->GetCurrentLanguage() == CgiEnv::Language::Fa) {
        file = "../templates/cms-fa.wtml";
    } else {
        file = "../templates/cms.wtml";
    }

    if (CoreLib::FileSystem::Read(file, htmlData)) {
        WTemplate *tmpl = new WTemplate(container);
        tmpl->setTemplateText(WString::fromUTF8(htmlData), TextFormat::XHTMLUnsafeText);

        tmpl->bindWidget("brand-title", new WText(tr("cms-page-title")));

        WText *dashboard = new WText(
                    WString("<div><a href=\"javascript:;\"><i class=\"fa fa-dashboard fa-lg\"></i> {1}</a></div>")
                    .arg(tr("cms-dashboard")), TextFormat::XHTMLUnsafeText);
        WText *newsletter = new WText(
                    WString("<div><a href=\"javascript:;\"><i class=\"fa fa-newspaper-o fa-lg\"></i> {1}</a></div>")
                    .arg(tr("cms-dashboard-newsletter")), TextFormat::XHTMLUnsafeText);
        WText *subscribers = new WText(
                    WString("<div><a href=\"javascript:;\"><i class=\"fa fa-users fa-lg\"></i> {1}</a></div>")
                    .arg(tr("cms-dashboard-subscribers")), TextFormat::XHTMLUnsafeText);
        WText *contacts = new WText(
                    WString("<div><a href=\"javascript:;\"><i class=\"fa fa-envelope-o fa-lg\"></i> {1}</a></div>")
                    .arg(tr("cms-dashboard-contacts")), TextFormat::XHTMLUnsafeText);
        WText *settings = new WText(
                    WString("<div><a href=\"javascript:;\"><i class=\"fa fa-gears fa-lg\"></i> {1}</a></div>")
                    .arg(tr("cms-dashboard-settings")), TextFormat::XHTMLUnsafeText);
        WText *changeEmail = new WText(
                    WString("<div><a href=\"javascript:;\"><i class=\"fa fa-envelope-o fa-lg\"></i> {1}</a></div>")
                    .arg(tr("cms-dashboard-admin-change-email")), TextFormat::XHTMLUnsafeText);
        WText *changePassword = new WText(
                    WString("<div><a href=\"javascript:;\"><i class=\"fa fa-key fa-lg\"></i> {1}</a></div>")
                    .arg(tr("cms-dashboard-admin-change-password")), TextFormat::XHTMLUnsafeText);
        WText *sysmon = new WText(
                    WString("<div><a href=\"javascript:;\"><i class=\"fa fa-line-chart fa-lg\"></i> {1}</a></div>")
                    .arg(tr("cms-dashboard-system-monitor")), TextFormat::XHTMLUnsafeText);
        WText *switchLanguage = new WText(
                    WString("<div><a href=\"javascript:;\"><i class=\"fa fa-refresh fa-lg\"></i> {1}</a></div>")
                    .arg(tr("cms-dashboard-switch-language")), TextFormat::XHTMLUnsafeText);
        WText *exit = new WText(
                    WString("<div><a href=\"javascript:;\"><i class=\"fa fa-sign-out fa-lg\"></i> {1}</a></div>")
                    .arg(tr("cms-dashboard-exit")), TextFormat::XHTMLUnsafeText);

        dashboard->setId("menu-item-dashboard");
        newsletter->setId("menu-item-newsletter");
        subscribers->setId("menu-item-subscribers");
        contacts->setId("menu-item-contacts");
        settings->setId("menu-item-settings");
        changeEmail->setId("menu-item-change-email");
        changePassword->setId("menu-item-change-password");
        sysmon->setId("menu-item-system-monitor");
        switchLanguage->setId("menu-item-switch-language");
        exit->setId("menu-item-exit");

        tmpl->bindWidget("dashboard", dashboard);
        tmpl->bindWidget("newsletter", newsletter);
        tmpl->bindWidget("subscribers", subscribers);
        tmpl->bindWidget("contacts", contacts);
        tmpl->bindWidget("settings", settings);
        tmpl->bindWidget("admin", new WText(tr("cms-dashboard-admin")));
        tmpl->bindWidget("change-email", changeEmail);
        tmpl->bindWidget("change-password", changePassword);
        tmpl->bindWidget("system-monitor", sysmon);
        tmpl->bindWidget("switch-language", switchLanguage);
        tmpl->bindWidget("exit", exit);

        m_pimpl->Contents = new Wt::WStackedWidget();
        m_pimpl->Contents->addWidget(new CmsDashboard());
        m_pimpl->Contents->addWidget(new CmsNewsletter());
        m_pimpl->Contents->addWidget(new CmsSubscribers());
        m_pimpl->Contents->addWidget(new CmsContacts());
        m_pimpl->Contents->addWidget(new CmsSettings());
        m_pimpl->Contents->addWidget(new CmsChangeEmail());
        m_pimpl->Contents->addWidget(new CmsChangePassword());
        m_pimpl->SystemMonitor = new SysMon();
        m_pimpl->Contents->addWidget(m_pimpl->SystemMonitor);
        tmpl->bindWidget("stcked-widget", m_pimpl->Contents);

        WSignalMapper<WText *, WStackedWidget *> *menuItemSignalMapper = new WSignalMapper<WText *, WStackedWidget *>(m_pimpl.get());
        menuItemSignalMapper->mapped().connect(m_pimpl.get(), &Cms::Impl::OnMenuItemPressed);
        menuItemSignalMapper->mapConnect(dashboard->clicked(), dashboard);
        menuItemSignalMapper->mapConnect(newsletter->clicked(), newsletter);
        menuItemSignalMapper->mapConnect(subscribers->clicked(), subscribers);
        menuItemSignalMapper->mapConnect(contacts->clicked(), contacts);
        menuItemSignalMapper->mapConnect(settings->clicked(), settings);
        menuItemSignalMapper->mapConnect(changeEmail->clicked(), changeEmail);
        menuItemSignalMapper->mapConnect(changePassword->clicked(), changePassword);
        menuItemSignalMapper->mapConnect(sysmon->clicked(), sysmon);
        menuItemSignalMapper->mapConnect(switchLanguage->clicked(), switchLanguage);
        menuItemSignalMapper->mapConnect(exit->clicked(), exit);
    }

    return container;
}
Esempio n. 13
0
void WCalendar::create()
{
  selectionMode_ = SingleSelection;
  singleClickSelect_ = false;
  horizontalHeaderFormat_ = ShortDayNames;
  firstDayOfWeek_ = 1;
  cellClickMapper_ = 0;
  cellDblClickMapper_ = 0;

  WDate currentDay = WDate::currentDate();

  currentYear_ = currentDay.year();
  currentMonth_ = currentDay.month();

  WStringStream text;

  text <<
    "<table class=\"days ${table-class}\" cellspacing=\"0\" cellpadding=\"0\">"
    """<tr>"
    ""  "<th class=\"caption\">${nav-prev}</th>"
    ""  "<th class=\"caption\"colspan=\"5\">${month} ${year}</th>"
    ""  "<th class=\"caption\">${nav-next}</th>"
    """</tr>"
    """<tr>";

  for (int j = 0; j < 7; ++j)
    text <<
      "<th title=\"${t" << j << "}\" scope=\"col\">${d" << j << "}</th>";

  text << "</tr>";

  for (int i = 0; i < 6; ++i) {
    text << "<tr>";
    for (int j = 0; j < 7; ++j)
      text << "<td>${c" << (i * 7 + j) << "}</td>";
    text << "</tr>";
  }

  text << "</table>";

  setImplementation(impl_ = new WTemplate());
  impl_->setTemplateText(WString::fromUTF8(text.str()), XHTMLUnsafeText);
  impl_->setStyleClass("Wt-cal");

  setSelectable(false);

  WText *prevMonth = new WText(tr("Wt.WCalendar.PrevMonth"));
  prevMonth->setStyleClass("Wt-cal-navbutton");
  prevMonth->clicked().connect(this, &WCalendar::browseToPreviousMonth);

  WText *nextMonth = new WText(tr("Wt.WCalendar.NextMonth"));
  nextMonth->setStyleClass("Wt-cal-navbutton");
  nextMonth->clicked().connect(this, &WCalendar::browseToNextMonth);

  monthEdit_ = new WComboBox();
  monthEdit_->setInline(true);
  for (unsigned i = 0; i < 12; ++i)
    monthEdit_->addItem(WDate::longMonthName(i+1));
  monthEdit_->activated().connect(this, &WCalendar::monthChanged);
  monthEdit_->setDisabled(!WApplication::instance()->environment().ajax());

  yearEdit_ = new WInPlaceEdit("");
  yearEdit_->setButtonsEnabled(false);
  yearEdit_->lineEdit()->setTextSize(4);
  yearEdit_->setStyleClass("Wt-cal-year");
  yearEdit_->valueChanged().connect(this, &WCalendar::yearChanged);

  impl_->bindWidget("nav-prev", prevMonth);
  impl_->bindWidget("nav-next", nextMonth);
  impl_->bindWidget("month", monthEdit_);
  impl_->bindWidget("year", yearEdit_);

  setHorizontalHeaderFormat(horizontalHeaderFormat_);
  setFirstDayOfWeek(firstDayOfWeek_);
}
Esempio n. 14
0
WWidget *RootLogin::Layout()
{
    m_cgiRoot->setTitle(m_lang->GetString("ROOT_LOGIN_TITLE"));

    Div *root = new Div("RootLogin");

    Div *dvNoScript = new Div(root, "dvNoScript");
    new WText(m_lang->GetString("WARN_NO_SCRIPT"), dvNoScript);

    Div *dvLogin = new Div(root, "dvLogin");
    new WText(m_lang->GetString("ROOT_LOGIN_FORM_TITLE"), dvLogin);

    Div *dvLangBar = new Div(dvLogin, "dvLangBar");
    new WText(L"<span style=\"color: #333; font-family: Tahoma !important; letter-spacing: 1px;\">"
	          "<a href=\"?enroot\" style=\"color: #666; text-decoration: none;\">EN</a>"
              "&nbsp;|&nbsp;"
              "<a href=\"?faroot\" style=\"color: #666; text-decoration: none;\">فا</a>"
			  "</span>", dvLangBar);

    Div *dvLoginForm = new Div(dvLogin, "dvLoginForm", "form");
    WGridLayout *dvLoginFormLayout = new WGridLayout();

    m_loginUserEdit = new WLineEdit();
    m_loginPwdEdit = new WLineEdit();
    m_loginPwdEdit->setEchoMode(WLineEdit::Password);
    m_loginCaptchaEdit = new WLineEdit();

    dvLoginFormLayout->addWidget(new WText(m_lang->GetString("ROOT_LOGIN_FORM_USER_TEXT")),
                                 0, 0, AlignLeft | AlignMiddle);
    dvLoginFormLayout->addWidget(m_loginUserEdit, 0, 1);

    dvLoginFormLayout->addWidget(new WText(m_lang->GetString("ROOT_LOGIN_FORM_PWD_TEXT")),
                                 1, 0, AlignLeft | AlignMiddle);
    dvLoginFormLayout->addWidget(m_loginPwdEdit, 1, 1);

    dvLoginFormLayout->addWidget(new WText(m_lang->GetString("ROOT_LOGIN_FORM_CAPTCHA_TEXT")),
                                 2, 0, AlignLeft | AlignMiddle);
    dvLoginFormLayout->addWidget(m_loginCaptchaEdit, 2, 1);

    dvLoginFormLayout->setVerticalSpacing(11);
    dvLoginFormLayout->setColumnStretch(0, 100);
    dvLoginFormLayout->setColumnStretch(1, 200);
    dvLoginForm->resize(300, WLength::Auto);
    dvLoginForm->setLayout(dvLoginFormLayout);

    m_loginCaptchaImage = m_captcha->GenCap();
    dvLogin->addWidget(m_loginCaptchaImage);

    m_errLoginText = new WText(dvLogin);
    WPushButton *loginBtn = new WPushButton(m_lang->GetString("ROOT_LOGIN_FORM_LOGIN_TEXT"),
                                            dvLogin);
    loginBtn->setStyleClass("formButton");

    WText *forgotLink = new WText(
            L"<p style=\"text-align: right !important; margin-top: 25px;\">"
            + m_lang->GetString("ROOT_LOGIN_FORM_FORGOT_TEXT") + L"</p>",
            dvLogin);
    forgotLink->setStyleClass("link");

    m_dvForgot = new Div(dvLogin, "dvForgot");
    m_forgotFormFlag = false;

    Div *dvCopyright = new Div(root, "dvCopyright");
    new WText(Base::Copyright(m_cgiEnv->CurrentLang), dvCopyright);

    WSignalMapper<WText *> *forgotMap = new WSignalMapper<WText *>(this);
    forgotMap->mapped().connect(this, &RootLogin::ForgotForm);
    forgotMap->mapConnect(forgotLink->clicked(), forgotLink);

    WLengthValidator *loginUserValidator = new WLengthValidator(Base::MIN_USERNAME_LENGTH,
                                                                Base::MAX_USERNAME_LENGTH);
    loginUserValidator->setMandatory(true);
    m_loginUserEdit->setValidator(loginUserValidator);

    WLengthValidator *loginPwdValidator = new WLengthValidator(Base::MIN_PASSWORD_LENGTH,
                                                               Base::MAX_PASSWORD_LENGTH);
    loginPwdValidator->setMandatory(true);
    m_loginPwdEdit->setValidator(loginPwdValidator);

    m_loginCaptchaValidator = new WIntValidator(m_captcha->Result, m_captcha->Result);
    m_loginCaptchaValidator->setMandatory(true);
    m_loginCaptchaEdit->setValidator(m_loginCaptchaValidator);

    m_loginUserEdit->enterPressed().connect(this, &RootLogin::LoginOK);
    m_loginPwdEdit->enterPressed().connect(this, &RootLogin::LoginOK);
    m_loginCaptchaEdit->enterPressed().connect(this, &RootLogin::LoginOK);
    loginBtn->clicked().connect(this, &RootLogin::LoginOK);

    return root;
}