Skip to content

Commit 1d93271

Browse files
author
Koen Deforche
committed
Several changes:
* Fix infinite loop in chart3D example (Bruce Toll, #3235) * Added custom WItemDelegate editor example in widgetgallery (#3243) * Various doc fixes * Fixed memory leak in WRasterImage-gm (#3291) * Implemented support for image/jpg in WPainter::Image (#1606) * Fixed value retrieved from field with inputmask * Implemented capturing JavaScript errors server-side (#2760) * Implemented email verification required for login (#3246) * implemented refresh() for WMediaPlayer and SoundManager * Fix memory access bug (#3214) * Let WTableView select text after tab in extra header widget * WDoubleVlidator replace . bug fix
1 parent b440da0 commit 1d93271

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+817
-377
lines changed

examples/chart3D/CategoryExample.C

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,6 @@ CategoryExample::CategoryExample(WContainerWidget *parent)
3232
{
3333
setContentAlignment(AlignCenter);
3434
chart_ = new WCartesian3DChart(this);
35-
if (chart_->isAlternative()) {
36-
xPlaneModelColor_ = 0;
37-
xPlaneModel_ = 0;
38-
yPlaneModel_ = 0;
39-
randomModel_ = 0;
40-
planeModel_ = 0;
41-
isotopeModel_ = 0;
42-
43-
return;
44-
}
4535
chart_->setType(CategoryChart);
4636

4737
Wt::WCssDecorationStyle style;

examples/chart3D/NumericalExample.C

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,6 @@ NumericalExample::NumericalExample(WContainerWidget *parent)
1919
setContentAlignment(AlignCenter);
2020

2121
chart_ = new WCartesian3DChart(this);
22-
if (chart_->isAlternative()) {
23-
24-
sombrModel_ = 0;
25-
xPlaneModel_ = 0;
26-
yPlaneModel_ = 0;
27-
xPlaneModelSize_ = 0;
28-
yPlaneModelColor_ = 0;
29-
spiralModel_ = 0;
30-
para1Model_ = 0;
31-
para2Model_ = 0;
32-
return;
33-
}
34-
3522
chart_->setLegendStyle(WFont(), WPen(), WBrush(WColor(lightGray)));
3623

3724
Wt::WCssDecorationStyle style;

examples/feature/auth1/model/Session.C

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ void Session::configureAuth()
3838
{
3939
myAuthService.setAuthTokensEnabled(true, "logincookie");
4040
myAuthService.setEmailVerificationEnabled(true);
41+
myAuthService.setEmailVerificationRequired(true);
4142

4243
Wt::Auth::PasswordVerifier *verifier = new Wt::Auth::PasswordVerifier();
4344
verifier->addHashFunction(new Wt::Auth::BCryptHashFunction(7));

examples/widgetgallery/TreesTables.C

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,15 @@ Wt::WWidget *TreesTables::treeTables()
8181
#include "examples/VirtualModel.cpp"
8282
#include "examples/SmallTableView.cpp"
8383
#include "examples/LargeTableView.cpp"
84+
#include "examples/ComboDelegateTable.cpp"
8485

8586
Wt::WWidget *TreesTables::tableViews()
8687
{
8788
Wt::WTemplate *result = new TopicTemplate("treestables-TableViews");
8889

8990
result->bindWidget("SmallTableView", SmallTableView());
9091
result->bindWidget("LargeTableView", LargeTableView());
92+
result->bindWidget("ComboDelegateTable", ComboDelegateTable());
9193

9294
return result;
9395
}

examples/widgetgallery/approot/src.xml

Lines changed: 269 additions & 154 deletions
Large diffs are not rendered by default.

examples/widgetgallery/approot/text.xml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3300,7 +3300,7 @@
33003300

33013301
<p><a href="#mvc-table-view">Top</a></p>
33023302

3303-
<h3>Editing</h3>
3303+
<h3>Editing + Combo box editor example</h3>
33043304
<p>
33053305
MVC Views will automaticlly react to changes to the underlying
33063306
model, be it in the form of data updates, or the insertion of
@@ -3314,6 +3314,21 @@
33143314
use a line edit for editing, but this can be customized by
33153315
providing your own item delegate implementation.
33163316
</p>
3317+
<p>
3318+
The example below illustrates how to override the editing behaviour of
3319+
${doc-link WItemDelegate}. It uses a combo box to allow the user to edit
3320+
the cell values.
3321+
</p>
3322+
3323+
<fieldset class="example">
3324+
<legend>Example</legend>
3325+
${ComboDelegateTable}
3326+
<p>
3327+
${src ComboDelegateTable}
3328+
</p>
3329+
</fieldset>
3330+
3331+
<p><a href="#mvc-table-view">Top</a></p>
33173332

33183333
<h3>Row headers</h3>
33193334
<p>
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#include <Wt/WStandardItem>
2+
#include <Wt/WStandardItemModel>
3+
#include <Wt/WStringListModel>
4+
#include <Wt/WTableView>
5+
#include <Wt/WItemDelegate>
6+
#include <Wt/WContainerWidget>
7+
#include <Wt/WComboBox>
8+
9+
/*
10+
* This delegate demonstrates how to override the editing behaviour of a
11+
* table cell.
12+
*
13+
* It takes a list of possible items on construction and, when edited, saves
14+
* the selected item from the list to the Wt::DisplayRole in the model for
15+
* Wt::WItemDelegate to render.
16+
* It also saves the items index for future editing (rather than each time
17+
* searching the item in the list). This is done using the general purpose
18+
* Wt::UserRole in the model.
19+
*/
20+
class ComboDelegate : public Wt::WItemDelegate {
21+
public:
22+
ComboDelegate(Wt::WStringListModel* items)
23+
: items_(items)
24+
{}
25+
26+
void setModelData(const boost::any &editState, Wt::WAbstractItemModel* model,
27+
const Wt::WModelIndex &index) const
28+
{
29+
int stringIdx = Wt::asNumber(editState);
30+
model->setData(index, stringIdx, Wt::UserRole);
31+
model->setData(index, items_->stringList()[stringIdx], Wt::DisplayRole);
32+
}
33+
34+
boost::any editState(Wt::WWidget* editor) const
35+
{
36+
Wt::WComboBox* combo = dynamic_cast<Wt::WComboBox*>
37+
(dynamic_cast<Wt::WContainerWidget*>(editor)->widget(0));
38+
return combo->currentIndex();
39+
}
40+
41+
void setEditState(Wt::WWidget* editor, const boost::any &value) const
42+
{
43+
Wt::WComboBox* combo = dynamic_cast<Wt::WComboBox*>
44+
(dynamic_cast<Wt::WContainerWidget*>(editor)->widget(0));
45+
combo->setCurrentIndex(Wt::asNumber(value));
46+
}
47+
48+
protected:
49+
virtual Wt::WWidget* createEditor(const Wt::WModelIndex &index,
50+
Wt::WFlags<Wt::ViewItemRenderFlag> flags) const
51+
{
52+
Wt::WContainerWidget* container = new Wt::WContainerWidget();
53+
Wt::WComboBox* combo = new Wt::WComboBox(container);
54+
combo->setModel(items_);
55+
combo->setCurrentIndex(Wt::asNumber(index.data(Wt::UserRole)));
56+
57+
combo->changed().connect(boost::bind(&ComboDelegate::doCloseEditor, this,
58+
container, true));
59+
combo->enterPressed().connect(boost::bind(&ComboDelegate::doCloseEditor,
60+
this, container, true));
61+
combo->escapePressed().connect(boost::bind(&ComboDelegate::doCloseEditor,
62+
this, container, false));
63+
64+
return container;
65+
}
66+
67+
private:
68+
Wt::WStringListModel* items_;
69+
70+
void doCloseEditor(Wt::WWidget *editor, bool save) const
71+
{
72+
closeEditor().emit(editor, save);
73+
}
74+
};
75+
76+
SAMPLE_BEGIN(ComboDelegateTable)
77+
Wt::WTableView *table = new Wt::WTableView();
78+
79+
// create model
80+
std::vector<Wt::WString> options;
81+
options.push_back("apples");
82+
options.push_back("pears");
83+
options.push_back("bananas");
84+
options.push_back("cherries");
85+
86+
Wt::WStandardItemModel *model = new Wt::WStandardItemModel(table);
87+
for (unsigned i=0; i < 2; i++) {
88+
for (unsigned j=0; j < 2; j++) {
89+
Wt::WStandardItem *item = new Wt::WStandardItem();
90+
item->setData(0, Wt::UserRole);
91+
item->setData(options[0], Wt::DisplayRole);
92+
item->setFlags(Wt::ItemIsEditable);
93+
model->setItem(i, j, item);
94+
}
95+
}
96+
97+
// create table
98+
table->setModel(model);
99+
table->setEditTriggers(Wt::WAbstractItemView::SingleClicked);
100+
Wt::WStringListModel* slModel = new Wt::WStringListModel(table);
101+
slModel->setStringList(options);
102+
ComboDelegate* customdelegate = new ComboDelegate(slModel);
103+
table->setItemDelegate(customdelegate);
104+
105+
table->setSortingEnabled(false);
106+
table->setColumnResizeEnabled(false);
107+
table->setRowHeight(40);
108+
table->setHeaderHeight(0);
109+
110+
const int WIDTH = 120;
111+
for (int i = 0; i < table->model()->columnCount(); ++i)
112+
table->setColumnWidth(i, WIDTH);
113+
table->setWidth((WIDTH + 7) * table->model()->columnCount() + 2);
114+
115+
SAMPLE_END(return table)

src/Wt/Auth/AuthModel.C

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,6 @@ bool AuthModel::validateField(Field field)
143143
return false;
144144
case PasswordValid:
145145
setValid(PasswordField);
146-
147146
return true;
148147
}
149148

@@ -173,22 +172,21 @@ bool AuthModel::login(Login& login)
173172
if (valid()) {
174173
User user = users().findWithIdentity(Identity::LoginName,
175174
valueText(LoginNameField));
176-
if (user.isValid()) {
175+
if (loginUser(login, user)) {
177176
boost::any v = value(RememberMeField);
177+
178178
if (!v.empty() && boost::any_cast<bool>(v) == true) {
179179
WApplication *app = WApplication::instance();
180180
app->setCookie(baseAuth()->authTokenCookieName(),
181181
baseAuth()->createAuthToken(user),
182182
baseAuth()->authTokenValidity() * 60);
183183
}
184184

185-
login.login(user);
186-
187185
return true;
188-
}
189-
}
190-
191-
return false;
186+
} else
187+
return false;
188+
} else
189+
return false;
192190
}
193191

194192
void AuthModel::logout(Login& login)

src/Wt/Auth/AuthService

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,12 +392,25 @@ public:
392392
*/
393393
void setEmailVerificationEnabled(bool enabled);
394394

395-
/*! \brief Returns wheter email verification is configured.
395+
/*! \brief Returns whether email verification is configured.
396396
*
397397
* \sa setEmailVerificationEnabled()
398398
*/
399399
bool emailVerificationEnabled() const { return emailVerification_; }
400400

401+
/*! \brief Configure email verificiation to be required for login.
402+
*
403+
* When enabled, a user will not be able to login if the email-address was
404+
* not verified.
405+
*/
406+
void setEmailVerificationRequired(bool enabled);
407+
408+
/*! \ Returns whether email verification is required for login.
409+
*
410+
* \sa setEmailVerificationRequired()
411+
*/
412+
bool emailVerificationRequired() const { return emailVerificationReq_; }
413+
401414
/*! \brief Sets the internal path used to present tokens in emails.
402415
*
403416
* The default path is "/auth/mail/".
@@ -548,6 +561,7 @@ private:
548561
int tokenLength_;
549562

550563
bool emailVerification_;
564+
bool emailVerificationReq_;
551565
int emailTokenValidity_; // minutes
552566
std::string redirectInternalPath_;
553567

src/Wt/Auth/AuthService.C

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,15 @@ AuthService::~AuthService()
151151
void AuthService::setEmailVerificationEnabled(bool enabled)
152152
{
153153
emailVerification_ = enabled;
154+
if (!enabled)
155+
emailVerificationReq_ = false;
156+
}
157+
158+
void AuthService::setEmailVerificationRequired(bool enabled)
159+
{
160+
emailVerificationReq_ = enabled;
161+
if (enabled)
162+
emailVerification_ = true;
154163
}
155164

156165
void AuthService::setEmailRedirectInternalPath(const std::string& internalPath)

0 commit comments

Comments
 (0)