Wt examples  4.12.2
Loading...
Searching...
No Matches
TreeViewDragDrop.C
Go to the documentation of this file.
1/*
2 * Copyright (C) 2008 Emweb bv, Herent, Belgium.
3 *
4 * See the LICENSE file for terms of use.
5 */
6#include <fstream>
7
8#include <Wt/WApplication.h>
9#include <Wt/WComboBox.h>
10#include <Wt/WContainerWidget.h>
11#include <Wt/WDatePicker.h>
12#include <Wt/WDateValidator.h>
13#include <Wt/WDialog.h>
14#include <Wt/WEnvironment.h>
15#include <Wt/WIntValidator.h>
16#include <Wt/WItemDelegate.h>
17#include <Wt/WLabel.h>
18#include <Wt/WLineEdit.h>
19#include <Wt/WMessageBox.h>
20#include <Wt/WPushButton.h>
21#include <Wt/WRegExpValidator.h>
22#include <Wt/WGridLayout.h>
23#include <Wt/WPopupMenu.h>
24#include <Wt/WSortFilterProxyModel.h>
25#include <Wt/WStandardItem.h>
26#include <Wt/WStandardItemModel.h>
27#include <Wt/WTableView.h>
28#include <Wt/WTreeView.h>
29#include <Wt/WText.h>
30#include <Wt/WVBoxLayout.h>
31
32#include <Wt/Chart/WPieChart.h>
33
34#include "CsvUtil.h"
35#include "FolderView.h"
36
37using namespace Wt;
38
43
52{
53public:
58
61 virtual std::string mimeType() const {
63 }
64
67
70};
71
74
78class FileEditDialog : public WDialog
79{
80public:
81 FileEditDialog(std::shared_ptr<WAbstractItemModel> model, const WModelIndex& item)
82 : WDialog("Edit..."),
83 model_(model),
84 item_(item)
85 {
86 int modelRow = item_.row();
87
89
90 /*
91 * Create the form widgets, and load them with data from the model.
92 */
93
94 // name
95 auto nameEdit = std::make_unique<WLineEdit>(asString(model_->data(modelRow, 1)));
96 nameEdit_ = nameEdit.get();
97
98 // type
99 auto typeEdit = std::make_unique<WComboBox>();
100 typeEdit_ = typeEdit.get();
101 typeEdit_->addItem("Document");
102 typeEdit_->addItem("Spreadsheet");
103 typeEdit_->addItem("Presentation");
105 (typeEdit_->findText(asString(model_->data(modelRow, 2))));
106
107 // size
108 auto sizeEdit = std::make_unique<WLineEdit>(asString(model_->data(modelRow, 3)));
109 sizeEdit_ = sizeEdit.get();
111 (std::make_shared<WIntValidator>(0, std::numeric_limits<int>::max()));
112
113
114 // created
115 auto createdPicker = std::make_unique<WDatePicker>();
116 createdPicker_ = createdPicker.get();
117 createdPicker_->lineEdit()->validator()->setMandatory(true);
119 createdPicker_->setDate(cpp17::any_cast<WDate>(model_->data(modelRow, 4)));
120
121 // modified
122 auto modifiedPicker = std::make_unique<WDatePicker>();
123 modifiedPicker_ = modifiedPicker.get();
124 modifiedPicker_->lineEdit()->validator()->setMandatory(true);
126 modifiedPicker_->setDate(cpp17::any_cast<WDate>(model_->data(modelRow, 5)));
127
128 /*
129 * Use a grid layout for the labels and fields
130 */
131 auto layout = std::make_unique<WGridLayout>();
132
133 std::unique_ptr<WLabel> label;
134 int row = 0;
135
136 label = std::make_unique<WLabel>("Name:");
137 label->setBuddy(nameEdit_);
138 layout->addWidget(std::move(label), row, 0);
139 layout->addWidget(std::move(nameEdit), row, 1);
140 ++row;
141
142 label = std::make_unique<WLabel>("Type:");
143 label->setBuddy(typeEdit_);
144 layout->addWidget(std::move(label), row, 0);
145 layout->addWidget(std::move(typeEdit), row, 1);
146 ++row;
147
148 label = std::make_unique<WLabel>("Size");
149 label->setBuddy(sizeEdit_);
150 layout->addWidget(std::move(label), row, 0);
151 layout->addWidget(std::move(sizeEdit), row, 1);
152 ++row;
153
154 label = std::make_unique<WLabel>("Created:");
155 label->setBuddy(createdPicker_->lineEdit());
156 layout->addWidget(std::move(label), row, 0);
157 layout->addWidget(std::move(createdPicker), row, 2);
158 ++row;
159
160 label = std::make_unique<WLabel>("Modified:");
161 label->setBuddy(modifiedPicker_->lineEdit());
162 layout->addWidget(std::move(label), row, 0);
163 layout->addWidget(std::move(modifiedPicker), row, 2);
164 ++row;
165
166 std::unique_ptr<WPushButton>button;
167 auto buttons = std::make_unique<WContainerWidget>();
168
169 button = std::make_unique<WPushButton>("Save");
170 button->clicked().connect(this, &WDialog::accept);
171 buttons->addWidget(std::move(button));
172
173 button = std::make_unique<WPushButton>("Cancel");
175 button->clicked().connect(this, &WDialog::reject);
176 buttons->addWidget(std::move(button));
177
178 /*
179 * Focus the form widget that corresonds to the selected item.
180 */
181 switch (item.column()) {
182 case 2:
183 typeEdit_->setFocus(); break;
184 case 3:
185 sizeEdit_->setFocus(); break;
186 case 4:
188 break;
189 case 5:
191 break;
192 default:
193 nameEdit_->setFocus(); break;
194 }
195
196 layout->addWidget(std::move(buttons), row, 0, 0, 3, AlignmentFlag::Center);
197 layout->setColumnStretch(1, 1);
198
199 contents()->setLayout(std::move(layout));
200
201 finished().connect(this, &FileEditDialog::handleFinish);
202
203 show();
204 }
205
206private:
207 std::shared_ptr<WAbstractItemModel> model_;
209
213
215 {
216 if (result == DialogCode::Accepted) {
217 /*
218 * Update the model with data from the edit widgets.
219 *
220 * You will want to do some validation here...
221 *
222 * Note that we directly update the source model to avoid
223 * problems caused by the dynamic sorting of the proxy model,
224 * which reorders row numbers, and would cause us to switch to editing
225 * the wrong data.
226 */
227 std::shared_ptr<WAbstractItemModel> m = model_;
228 int modelRow = item_.row();
229
230 std::shared_ptr<WAbstractProxyModel> proxyModel =
231 std::dynamic_pointer_cast<WAbstractProxyModel>(m);
232 if (proxyModel) {
233 m = proxyModel->sourceModel();
234 modelRow = proxyModel->mapToSource(item_).row();
235 }
236
237 m->setData(modelRow, 1, cpp17::any(nameEdit_->text()));
238 m->setData(modelRow, 2, cpp17::any(typeEdit_->currentText()));
239 m->setData(modelRow, 3, cpp17::any(asNumber
240 (sizeEdit_->text().toUTF8())));
241 m->setData(modelRow, 4, cpp17::any(createdPicker_->date()));
242 m->setData(modelRow, 5, cpp17::any(modifiedPicker_->date()));
243 }
244
245 //delete this;
246 }
247
248};
249
254{
255public:
259 : WApplication(env),
260 popup_(nullptr),
261 popupActionBox_(nullptr)
262 {
263 setCssTheme("polished");
264
265 /*
266 * Create the data models.
267 */
269 std::make_shared<WStandardItemModel>(0, 1);
271
272
273 fileModel_ =
274 std::make_shared<FileModel>();
276
277 /*
278 * The header items are also endered using an ItemDelegate, and thus
279 * support other data, e.g.:
280 *
281 * fileModel_->setHeaderFlags(0, Horizontal, HeaderIsUserCheckable);
282 * fileModel_->setHeaderData(0, Horizontal,
283 * std::string("icons/file.gif"),
284 * Wt::DecorationRole);
285 */
286 fileFilterModel_ = std::make_shared<WSortFilterProxyModel>();
287 fileFilterModel_->setSourceModel(fileModel_);
288 fileFilterModel_->setDynamicSortFilter(true);
289 fileFilterModel_->setFilterKeyColumn(0);
290 fileFilterModel_->setFilterRole(ItemDataRole::User);
291
292 /*
293 * Setup the user interface.
294 */
295 createUI();
296
297 }
298
300 {
301 dialog_.reset();
302 }
303
304private:
306 std::shared_ptr<WStandardItemModel> folderModel_;
307
309 std::shared_ptr<WStandardItemModel> fileModel_;
310
312 std::shared_ptr<WSortFilterProxyModel> fileFilterModel_;
313
315 std::map<std::string, WString> folderNameMap_;
316
319
322
323 std::unique_ptr<FileEditDialog> dialog_;
324
326 std::unique_ptr<WPopupMenu> popup_;
327
329 std::unique_ptr<WMessageBox> popupActionBox_;
330
333 void createUI() {
334 WContainerWidget *w = root();
335 w->setStyleClass("maindiv");
336
337 /*
338 * The main layout is a 3x2 grid layout.
339 */
340 std::unique_ptr<WGridLayout> layout =
341 std::make_unique<WGridLayout>();
342 layout->addWidget(createTitle("Folders"), 0, 0);
343 layout->addWidget(createTitle("Files"), 0, 1);
344 layout->addWidget(folderView(), 1, 0);
345 layout->setColumnResizable(0);
346
347 // select the first folder
348 folderView_->select(folderModel_->index(0, 0, folderModel_->index(0, 0)));
349
350 std::unique_ptr<WVBoxLayout> vbox =
351 std::make_unique<WVBoxLayout>();
352 vbox->addWidget(fileView(), 1);
353 vbox->addWidget(pieChart(), 1);
354 vbox->setResizable(0);
355
356 layout->addLayout(std::move(vbox), 1, 1);
357
358 layout->addWidget(aboutDisplay(), 2, 0, 1, 2);
359
360 /*
361 * Let row 1 and column 1 take the excess space.
362 */
363 layout->setRowStretch(1, 1);
364 layout->setColumnStretch(1, 1);
365
366 w->setLayout(std::move(layout));
367 }
368
371 std::unique_ptr<WText> createTitle(const WString& title) {
372 auto result = std::make_unique<WText>(title);
373 result->setInline(false);
374 result->setStyleClass("title");
375
376 return result;
377 }
378
381 std::unique_ptr<WTreeView> folderView() {
382 auto treeView = std::make_unique<FolderView>();
383
384 /*
385 * To support right-click, we need to disable the built-in browser
386 * context menu.
387 *
388 * Note that disabling the context menu and catching the
389 * right-click does not work reliably on all browsers.
390 */
391 // All event handlers ought to be JS, not DOM: #13501
392 WStringStream contextJS;
393 contextJS << WT_CLASS << ".$('" << treeView->id() << "').oncontextmenu = "
394 << "function() { event.cancelBubble = true; event.returnValue = false; return false; };";
396 treeView->setModel(folderModel_);
397 treeView->resize(200, WLength::Auto);
398 treeView->setSelectionMode(SelectionMode::Single);
399 treeView->setEnabledDropLocations(DropLocation::OnItem);
400 treeView->expandToDepth(1);
401 treeView->selectionChanged()
402 .connect(this, &TreeViewDragDrop::folderChanged);
403
404 treeView->mouseWentUp().connect(this, &TreeViewDragDrop::showPopup);
405
406 folderView_ = treeView.get();
407
408 return std::move(treeView);
409 }
410
413 std::unique_ptr<WTableView> fileView() {
414 auto tableView
415 = std::make_unique<WTableView>();
416
417 tableView->setAlternatingRowColors(true);
418
419 tableView->setModel(fileFilterModel_);
420 tableView->setSelectionMode(SelectionMode::Extended);
421 tableView->setDragEnabled(true);
422
423 tableView->setColumnWidth(0, 100);
424 tableView->setColumnWidth(1, 150);
425 tableView->setColumnWidth(2, 100);
426 tableView->setColumnWidth(3, 60);
427 tableView->setColumnWidth(4, 100);
428 tableView->setColumnWidth(5, 100);
429
430 auto delegate = std::make_shared<WItemDelegate>();
431 delegate->setTextFormat(FileModel::dateDisplayFormat);
432 tableView->setItemDelegateForColumn(4, delegate);
433 tableView->setItemDelegateForColumn(5, delegate);
434
435 tableView->setColumnAlignment(3, AlignmentFlag::Right);
436 tableView->setColumnAlignment(4, AlignmentFlag::Right);
437 tableView->setColumnAlignment(5, AlignmentFlag::Right);
438
439 tableView->sortByColumn(1, SortOrder::Ascending);
440
441 tableView->doubleClicked().connect(this, std::bind(&TreeViewDragDrop::editFile,
442 this, std::placeholders::_1));
443
444 fileView_ = tableView.get();
445
446 return tableView;
447 }
448
451 void editFile(const WModelIndex& item) {
452 dialog_ = std::make_unique<FileEditDialog>(fileView_->model(), item);
453 }
454
457 std::unique_ptr<WWidget> pieChart() {
458 using namespace Chart;
459
460 auto chart = std::make_unique<WPieChart>();
461 // chart->setPreferredMethod(WPaintedWidget::PngImage);
462 chart->setModel(fileFilterModel_);
463 chart->setTitle("File sizes");
464
465 chart->setLabelsColumn(1); // Name
466 chart->setDataColumn(3); // Size
467
468 chart->setPerspectiveEnabled(true, 0.2);
469 chart->setDisplayLabels(LabelOption::Outside | LabelOption::TextLabel);
470
471 if (!WApplication::instance()->environment().ajax()) {
472 chart->resize(500, 200);
473 chart->setMargin(WLength::Auto, Side::Left | Side::Right);
474
475 auto w = std::make_unique<WContainerWidget>();
476 w->addWidget(std::move(chart));
477 w->setStyleClass("about");
478 return std::move(w);
479 } else {
480 chart->setStyleClass("about");
481 return std::move(chart);
482 }
483 }
484
487 std::unique_ptr<WWidget> aboutDisplay() {
488 std::unique_ptr<WText> result
489 = std::make_unique<WText>(WString::tr("about-text"));
490 result->setStyleClass("about");
491 return std::move(result);
492 }
493
498 if (folderView_->selectedIndexes().empty())
499 return;
500
501 WModelIndex selected = *folderView_->selectedIndexes().begin();
502 cpp17::any d = selected.data(ItemDataRole::User);
503 if (cpp17::any_has_value(d)) {
504 std::string folder = cpp17::any_cast<std::string>(d);
505
506 // For simplicity, we assume here that the folder-id does not
507 // contain special regexp characters, otherwise these need to be
508 // escaped -- or use the \Q \E qutoing escape regular expression
509 // syntax (and escape \E)
510 fileFilterModel_->setFilterRegExp(std::unique_ptr<std::regex>(new std::regex(folder)));
511 }
512 }
513
516 void showPopup(const WModelIndex& item, const WMouseEvent& event) {
517 if (event.button() == MouseButton::Right) {
518 // Select the item, it was not yet selected.
519 if (!folderView_->isSelected(item))
520 folderView_->select(item);
521
522 if (!popup_) {
523 popup_ = std::make_unique<WPopupMenu>();
524 popup_->addItem("icons/folder_new.gif", "Create a New Folder");
525 popup_->addItem("Rename this Folder")->setCheckable(true);
526 popup_->addItem("Delete this Folder");
527 popup_->addSeparator();
528 popup_->addItem("Folder Details");
529 popup_->addSeparator();
530 popup_->addItem("Application Inventory");
531 popup_->addItem("Hardware Inventory");
532 popup_->addSeparator();
533
534 std::unique_ptr<WPopupMenu> subMenu = std::make_unique<WPopupMenu>();
535 subMenu->addItem("Sub Item 1");
536 subMenu->addItem("Sub Item 2");
537 popup_->addMenu("File Deployments", std::move(subMenu));
538
539 /*
540 * This is one method of executing a popup, which does not block a
541 * thread for a reentrant event loop, and thus scales.
542 *
543 * Alternatively you could call WPopupMenu::exec(), which returns
544 * the result, but while waiting for it, blocks the thread.
545 */
546 popup_->aboutToHide().connect(this, &TreeViewDragDrop::popupAction);
547 }
548
549 if (popup_->isHidden())
550 popup_->popup(event);
551 else
552 popup_->hide();
553 }
554 }
555
558 void popupAction() {
559 if (popup_->result()) {
560 /*
561 * You could also bind extra data to an item using setData() and
562 * check here for the action asked. For now, we just use the text.
563 */
564 WString text = popup_->result()->text();
565 popup_->hide();
566
567 popupActionBox_ = std::make_unique<WMessageBox>("Sorry.","Action '"
568 + text + "' is not implemented.",
569 Icon::None,
570 StandardButton::Ok);
571 popupActionBox_->buttonClicked()
572 .connect(this, &TreeViewDragDrop::dialogDone);
573 popupActionBox_->show();
574 } else {
575 popup_->hide();
576 }
577 }
578
581 void dialogDone() {
582 popupActionBox_.reset();
583 }
584
593 fileModel_->invisibleRootItem()->setRowCount(0);
594
595 std::ifstream f((appRoot() + "data/files.csv").c_str());
596
597 if (!f)
598 throw std::runtime_error("Could not read: data/files.csv");
599
601
602 for (int i = 0; i < fileModel_->rowCount(); ++i) {
603 WStandardItem *item = fileModel_->item(i, 0);
604 item->setFlags(item->flags() | ItemFlag::DragEnabled);
605 item->setIcon("icons/file.gif");
606
607 std::string folderId = item->text().toUTF8();
608
609 item->setData(cpp17::any(folderId), ItemDataRole::User);
610 item->setText(folderNameMap_[folderId]);
611
612 convertToNumber(fileModel_->item(i, 3));
613 convertToDate(fileModel_->item(i, 4));
614 convertToDate(fileModel_->item(i, 5));
615 }
616 }
617
622 item->setData(cpp17::any(d), ItemDataRole::Display);
623 }
624
628 int i = asNumber(item->text());
629 item->setData(cpp17::any(i), ItemDataRole::Edit);
630 }
631
635 std::unique_ptr<WStandardItem> level1;
636
637 level1 = createFolderItem("San Fransisco");
638 level1->appendRow(createFolderItem("Investors", "sf-investors"));
639 level1->appendRow(createFolderItem("Fellows", "sf-fellows"));
640 folderModel_->appendRow(std::move(level1));
641
642 level1 = createFolderItem("Sophia Antipolis");
643 level1->appendRow(createFolderItem("R&D", "sa-r_d"));
644 level1->appendRow(createFolderItem("Services", "sa-services"));
645 level1->appendRow(createFolderItem("Support", "sa-support"));
646 level1->appendRow(createFolderItem("Billing", "sa-billing"));
647 folderModel_->appendRow(std::move(level1));
648
649 level1 = createFolderItem("New York");
650 level1->appendRow(createFolderItem("Marketing", "ny-marketing"));
651 level1->appendRow(createFolderItem("Sales", "ny-sales"));
652 level1->appendRow(createFolderItem("Advisors", "ny-advisors"));
653 folderModel_->appendRow(std::move(level1));
654
655 level1 = createFolderItem(WString(reinterpret_cast<const char*>(u8"Frankf\u00FCrt")));
656 level1->appendRow(createFolderItem("Sales", "frank-sales"));
657 folderModel_->appendRow(std::move(level1));
658
659 folderModel_->setHeaderData(0, Orientation::Horizontal,
660 cpp17::any(std::string("SandBox")));
661 }
662
667 std::unique_ptr<WStandardItem> createFolderItem(const WString& location,
668 const std::string& folderId = std::string())
669 {
670 auto result
671 = std::make_unique<WStandardItem>(location);
672
673 if (!folderId.empty()) {
674 result->setData(cpp17::any(folderId));
675 result->setFlags(result->flags() | ItemFlag::DropEnabled);
676 folderNameMap_[folderId] = location;
677 } else
678 result->setFlags(result->flags().clear(ItemFlag::Selectable));
679
680 result->setIcon("icons/folder.gif");
681
682 return result;
683 }
684};
685
686std::unique_ptr<WApplication> createApplication(const WEnvironment& env)
687{
688 auto app = std::make_unique<TreeViewDragDrop>(env);
689 app->setTwoPhaseRenderingThreshold(0);
690 app->setTitle("WTreeView Drag & Drop");
691 app->useStyleSheet("styles.css");
692 app->messageResourceBundle().use(WApplication::appRoot() + "about");
693 app->refresh();
694
695 return std::move(app);
696}
697
698int main(int argc, char **argv)
699{
700 return WRun(argc, argv, &createApplication);
701}
702
int main(int argc, char **argv)
std::unique_ptr< WApplication > createApplication(const WEnvironment &env)
A dialog for editing a 'file'.
void handleFinish(DialogCode result)
WLineEdit * nameEdit_
std::shared_ptr< WAbstractItemModel > model_
WLineEdit * sizeEdit_
WDatePicker * createdPicker_
WDatePicker * modifiedPicker_
WComboBox * typeEdit_
FileEditDialog(std::shared_ptr< WAbstractItemModel > model, const WModelIndex &item)
A specialized standard item model which report a specific drag and drop mime type.
FileModel()
Constructor.
static WString dateEditFormat
Date edit format.
virtual std::string mimeType() const
Return the mime type.
static WString dateDisplayFormat
Date display format.
static const char * FileSelectionMimeType
Constant that indicates the mime type for a selection of files.
Definition FolderView.h:28
Main application class.
void folderChanged()
Change the filter on the file view when the selected folder changes.
std::unique_ptr< WWidget > aboutDisplay()
Creates the hints text.
std::shared_ptr< WStandardItemModel > fileModel_
The file model (used by fileView_)
std::map< std::string, WString > folderNameMap_
Maps folder id's to folder descriptions.
void editFile(const WModelIndex &item)
Edit a particular row.
std::shared_ptr< WSortFilterProxyModel > fileFilterModel_
The sort filter proxy model that adapts fileModel_.
std::unique_ptr< WTreeView > folderView()
Creates the folder WTreeView.
std::unique_ptr< WText > createTitle(const WString &title)
Creates a title widget.
void createUI()
Setup the user interface.
virtual ~TreeViewDragDrop()
std::shared_ptr< WStandardItemModel > folderModel_
The folder model (used by folderView_)
std::unique_ptr< WMessageBox > popupActionBox_
Message box to confirm the poup menu action.
std::unique_ptr< WTableView > fileView()
Creates the file table view (a WTableView)
std::unique_ptr< WPopupMenu > popup_
Popup menu on the folder view.
WTableView * fileView_
The file view.
void convertToDate(WStandardItem *item)
Convert a string to a date.
std::unique_ptr< WWidget > pieChart()
Creates the chart.
void showPopup(const WModelIndex &item, const WMouseEvent &event)
Show a popup for a folder item.
std::unique_ptr< WStandardItem > createFolderItem(const WString &location, const std::string &folderId=std::string())
Create a folder item.
TreeViewDragDrop(const WEnvironment &env)
Constructor.
void popupAction()
Process the result of the popup menu.
void populateFiles()
Populate the files model.
void convertToNumber(WStandardItem *item)
Convert a string to a number.
void dialogDone()
Process the result of the message box.
WTreeView * folderView_
The folder view.
std::unique_ptr< FileEditDialog > dialog_
void populateFolders()
Populate the folders model.
Wt::Signals::connection connect(F function)
static constexpr const int User
static constexpr const int Edit
static constexpr const int Display
WModelIndexSet selectedIndexes() const
bool isSelected(const WModelIndex &index) const
void select(const WModelIndex &index, SelectionFlag option=SelectionFlag::Select)
std::shared_ptr< WAbstractItemModel > model() const
void setCssTheme(const std::string &name)
void doJavaScript(const std::string &javascript, bool afterLoaded=true)
static WApplication * instance()
WContainerWidget * root() const
static std::string appRoot()
const WEnvironment & environment() const
const WString & title() const
int findText(const WString &text, WFlags< MatchFlag > flags=MatchFlag::Exactly|MatchFlag::CaseSensitive) const
const WString currentText() const
void setCurrentIndex(int index)
void addItem(const WString &text)
virtual void resize(const WLength &width, const WLength &height) override
void setLayout(std::unique_ptr< WLayout > layout)
WDate date() const
void setFormat(const WString &format)
void setDate(const WDate &date)
WLineEdit * lineEdit() const
static WDate fromString(const WString &s)
Signal< DialogCode > & finished()
WContainerWidget * contents() const
DialogCode result() const
virtual void accept()
virtual void reject()
virtual void setValidator(const std::shared_ptr< WValidator > &validator)
virtual std::shared_ptr< WValidator > validator() const
EventSignal & enterPressed()
static WLength Auto
const WString & text() const
int row() const
int column() const
cpp17::any data(ItemDataRole role=ItemDataRole::Display) const
MouseButton button() const
virtual void setData(const cpp17::any &data, ItemDataRole role=ItemDataRole::User)
void setIcon(const std::string &uri)
void setText(const WString &text)
WString text() const
WFlags< ItemFlag > flags() const
void setFlags(WFlags< ItemFlag > flags)
std::string str() const
static WString tr(const char *key)
std::string toUTF8() const
virtual void setStyleClass(const WString &styleClass) override
virtual void setFocus(bool focus) override
WString asString(const cpp17::any &v, const WString &formatString=WString())
double asNumber(const cpp17::any &v)
DialogCode
void readFromCsv(std::istream &f, std::shared_ptr< WAbstractItemModel > model, int numRows, bool firstLineIsHeaders)
Definition CsvUtil.C:54