8 #include <Wt/WApplication> 9 #include <Wt/WComboBox> 10 #include <Wt/WContainerWidget> 11 #include <Wt/WDatePicker> 12 #include <Wt/WDateValidator> 14 #include <Wt/WEnvironment> 15 #include <Wt/WIntValidator> 16 #include <Wt/WItemDelegate> 18 #include <Wt/WLineEdit> 19 #include <Wt/WMessageBox> 20 #include <Wt/WPushButton> 21 #include <Wt/WRegExpValidator> 22 #include <Wt/WGridLayout> 23 #include <Wt/WPopupMenu> 24 #include <Wt/WSortFilterProxyModel> 25 #include <Wt/WStandardItem> 26 #include <Wt/WStandardItemModel> 27 #include <Wt/WTableView> 28 #include <Wt/WTreeView> 30 #include <Wt/WVBoxLayout> 32 #include <Wt/Chart/WPieChart> 57 : WStandardItemModel(parent) { }
86 int modelRow = item_.row();
88 resize(300, WLength::Auto);
95 nameEdit_ =
new WLineEdit(asString(model_->data(modelRow, 1)));
98 typeEdit_ =
new WComboBox();
99 typeEdit_->addItem(
"Document");
100 typeEdit_->addItem(
"Spreadsheet");
101 typeEdit_->addItem(
"Presentation");
102 typeEdit_->setCurrentIndex
103 (typeEdit_->findText(asString(model_->data(modelRow, 2))));
106 sizeEdit_ =
new WLineEdit(asString(model_->data(modelRow, 3)));
107 sizeEdit_->setValidator
108 (
new WIntValidator(0, std::numeric_limits<int>::max(),
this));
111 createdPicker_ =
new WDatePicker();
112 createdPicker_->lineEdit()->validator()->setMandatory(
true);
114 createdPicker_->setDate(boost::any_cast<WDate>(model_->data(modelRow, 4)));
117 modifiedPicker_ =
new WDatePicker();
118 modifiedPicker_->lineEdit()->validator()->setMandatory(
true);
120 modifiedPicker_->setDate(boost::any_cast<WDate>(model_->data(modelRow, 5)));
125 WGridLayout *layout =
new WGridLayout();
130 layout->addWidget(l =
new WLabel(
"Name:"), row, 0);
131 layout->addWidget(nameEdit_, row, 1);
132 l->setBuddy(nameEdit_);
135 layout->addWidget(l =
new WLabel(
"Type:"), row, 0);
136 layout->addWidget(typeEdit_, row, 1);
137 l->setBuddy(typeEdit_);
140 layout->addWidget(l =
new WLabel(
"Size:"), row, 0);
141 layout->addWidget(sizeEdit_, row, 1);
142 l->setBuddy(sizeEdit_);
145 layout->addWidget(l =
new WLabel(
"Created:"), row, 0);
146 layout->addWidget(createdPicker_->lineEdit(), row, 1);
147 layout->addWidget(createdPicker_, row, 2);
148 l->setBuddy(createdPicker_->lineEdit());
151 layout->addWidget(l =
new WLabel(
"Modified:"), row, 0);
152 layout->addWidget(modifiedPicker_->lineEdit(), row, 1);
153 layout->addWidget(modifiedPicker_, row, 2);
154 l->setBuddy(modifiedPicker_->lineEdit());
158 WContainerWidget *buttons =
new WContainerWidget();
159 buttons->addWidget(b =
new WPushButton(
"Save"));
160 b->clicked().connect(
this, &WDialog::accept);
161 contents()->enterPressed().connect(
this, &WDialog::accept);
162 buttons->addWidget(b =
new WPushButton(
"Cancel"));
163 b->clicked().connect(
this, &WDialog::reject);
168 switch (item.column()) {
170 typeEdit_->setFocus();
break;
172 sizeEdit_->setFocus();
break;
174 createdPicker_->lineEdit()->setFocus();
break;
176 modifiedPicker_->lineEdit()->setFocus();
break;
178 nameEdit_->setFocus();
break;
181 layout->addWidget(buttons, row, 0, 0, 3, AlignCenter);
182 layout->setColumnStretch(1, 1);
184 contents()->setLayout(layout);
201 if (result == WDialog::Accepted) {
212 WAbstractItemModel *m = model_;
213 int modelRow = item_.row();
215 WAbstractProxyModel *proxyModel =
dynamic_cast<WAbstractProxyModel *
>(m);
217 m = proxyModel->sourceModel();
218 modelRow = proxyModel->mapToSource(item_).row();
221 m->setData(modelRow, 1, boost::any(nameEdit_->text()));
222 m->setData(modelRow, 2, boost::any(typeEdit_->currentText()));
223 m->setData(modelRow, 3, boost::any(boost::lexical_cast<int>
224 (sizeEdit_->text().toUTF8())));
225 m->setData(modelRow, 4, boost::any(createdPicker_->date()));
226 m->setData(modelRow, 5, boost::any(modifiedPicker_->date()));
247 setCssTheme(
"polished");
252 folderModel_ =
new WStandardItemModel(0, 1,
this);
267 fileFilterModel_ =
new WSortFilterProxyModel(
this);
268 fileFilterModel_->setSourceModel(fileModel_);
269 fileFilterModel_->setDynamicSortFilter(
true);
270 fileFilterModel_->setFilterKeyColumn(0);
271 fileFilterModel_->setFilterRole(UserRole);
281 delete popupActionBox_;
312 WContainerWidget *w = root();
313 w->setStyleClass(
"maindiv");
318 WGridLayout *layout =
new WGridLayout();
319 layout->addWidget(createTitle(
"Folders"), 0, 0);
320 layout->addWidget(createTitle(
"Files"), 0, 1);
321 layout->addWidget(folderView(), 1, 0);
322 layout->setColumnResizable(0);
325 folderView_->select(folderModel_->index(0, 0, folderModel_->index(0, 0)));
327 WVBoxLayout *vbox =
new WVBoxLayout();
328 vbox->addWidget(fileView(), 1);
329 vbox->addWidget(pieChart(), 1);
330 vbox->setResizable(0);
332 layout->addLayout(vbox, 1, 1);
334 layout->addWidget(aboutDisplay(), 2, 0, 1, 2);
339 layout->setRowStretch(1, 1);
340 layout->setColumnStretch(1, 1);
342 w->setLayout(layout);
348 WText *result =
new WText(title);
349 result->setInline(
false);
350 result->setStyleClass(
"title");
367 treeView->setAttributeValue
369 "event.cancelBubble = true; event.returnValue = false; return false;");
370 treeView->setModel(folderModel_);
371 treeView->resize(200, WLength::Auto);
372 treeView->setSelectionMode(SingleSelection);
373 treeView->expandToDepth(1);
374 treeView->selectionChanged()
379 folderView_ = treeView;
387 WTableView *tableView =
new WTableView();
389 tableView->setAlternatingRowColors(
true);
391 tableView->setModel(fileFilterModel_);
392 tableView->setSelectionMode(ExtendedSelection);
393 tableView->setDragEnabled(
true);
395 tableView->setColumnWidth(0, 100);
396 tableView->setColumnWidth(1, 150);
397 tableView->setColumnWidth(2, 100);
398 tableView->setColumnWidth(3, 60);
399 tableView->setColumnWidth(4, 100);
400 tableView->setColumnWidth(5, 100);
402 WItemDelegate *delegate =
new WItemDelegate(
this);
404 tableView->setItemDelegateForColumn(4, delegate);
405 tableView->setItemDelegateForColumn(5, delegate);
407 tableView->setColumnAlignment(3, AlignRight);
408 tableView->setColumnAlignment(4, AlignRight);
409 tableView->setColumnAlignment(5, AlignRight);
411 tableView->sortByColumn(1, AscendingOrder);
415 fileView_ = tableView;
429 using namespace Chart;
431 WPieChart *chart =
new WPieChart();
433 chart->setModel(fileFilterModel_);
434 chart->setTitle(
"File sizes");
436 chart->setLabelsColumn(1);
437 chart->setDataColumn(3);
439 chart->setPerspectiveEnabled(
true, 0.2);
440 chart->setDisplayLabels(Outside | TextLabel);
442 if (!WApplication::instance()->environment().ajax()) {
443 chart->resize(500, 200);
444 chart->setMargin(WLength::Auto, Left | Right);
445 WContainerWidget *w =
new WContainerWidget();
447 w->setStyleClass(
"about");
450 chart->setStyleClass(
"about");
458 WText *result =
new WText(WString::tr(
"about-text"));
459 result->setStyleClass(
"about");
467 if (folderView_->selectedIndexes().empty())
470 WModelIndex selected = *folderView_->selectedIndexes().begin();
471 boost::any d = selected.data(UserRole);
473 std::string folder = boost::any_cast<std::string>(d);
479 fileFilterModel_->setFilterRegExp(folder);
485 void showPopup(
const WModelIndex& item,
const WMouseEvent& event) {
486 if (event.button() == WMouseEvent::RightButton) {
488 if (!folderView_->isSelected(item))
489 folderView_->select(item);
492 popup_ =
new WPopupMenu();
493 popup_->addItem(
"icons/folder_new.gif",
"Create a New Folder");
494 popup_->addItem(
"Rename this Folder")->setCheckable(
true);
495 popup_->addItem(
"Delete this Folder");
496 popup_->addSeparator();
497 popup_->addItem(
"Folder Details");
498 popup_->addSeparator();
499 popup_->addItem(
"Application Inventory");
500 popup_->addItem(
"Hardware Inventory");
501 popup_->addSeparator();
503 WPopupMenu *subMenu =
new WPopupMenu();
504 subMenu->addItem(
"Sub Item 1");
505 subMenu->addItem(
"Sub Item 2");
506 popup_->addMenu(
"File Deployments", subMenu);
518 if (popup_->isHidden())
519 popup_->popup(event);
528 if (popup_->result()) {
533 WString text = popup_->result()->text();
536 popupActionBox_ =
new WMessageBox(
"Sorry.",
"Action '" + text
537 +
"' is not implemented.", NoIcon, Ok);
538 popupActionBox_->buttonClicked()
540 popupActionBox_->show();
549 delete popupActionBox_;
561 fileModel_->invisibleRootItem()->setRowCount(0);
563 std::ifstream f((appRoot() +
"data/files.csv").c_str());
566 throw std::runtime_error(
"Could not read: data/files.csv");
570 for (
int i = 0; i < fileModel_->rowCount(); ++i) {
571 WStandardItem *item = fileModel_->item(i, 0);
572 item->setFlags(item->flags() | ItemIsDragEnabled);
573 item->setIcon(
"icons/file.gif");
575 std::string folderId = item->text().toUTF8();
577 item->setData(boost::any(folderId), UserRole);
578 item->setText(folderNameMap_[folderId]);
580 convertToNumber(fileModel_->item(i, 3));
581 convertToDate(fileModel_->item(i, 4));
582 convertToDate(fileModel_->item(i, 5));
590 item->setData(boost::any(d), DisplayRole);
596 int i = boost::lexical_cast<
int>(item->text());
597 item->setData(boost::any(i), EditRole);
603 WStandardItem *level1, *level2;
605 folderModel_->appendRow(level1 = createFolderItem(
"San Fransisco"));
606 level1->appendRow(level2 = createFolderItem(
"Investors",
"sf-investors"));
607 level1->appendRow(level2 = createFolderItem(
"Fellows",
"sf-fellows"));
609 folderModel_->appendRow(level1 = createFolderItem(
"Sophia Antipolis"));
610 level1->appendRow(level2 = createFolderItem(
"R&D",
"sa-r_d"));
611 level1->appendRow(level2 = createFolderItem(
"Services",
"sa-services"));
612 level1->appendRow(level2 = createFolderItem(
"Support",
"sa-support"));
613 level1->appendRow(level2 = createFolderItem(
"Billing",
"sa-billing"));
615 folderModel_->appendRow(level1 = createFolderItem(
"New York"));
616 level1->appendRow(level2 = createFolderItem(
"Marketing",
"ny-marketing"));
617 level1->appendRow(level2 = createFolderItem(
"Sales",
"ny-sales"));
618 level1->appendRow(level2 = createFolderItem(
"Advisors",
"ny-advisors"));
620 folderModel_->appendRow(level1 = createFolderItem
621 (WString::fromUTF8(
"Frankfürt")));
622 level1->appendRow(level2 = createFolderItem(
"Sales",
"frank-sales"));
624 folderModel_->setHeaderData(0, Horizontal,
625 boost::any(std::string(
"SandBox")));
633 const std::string& folderId = std::string())
635 WStandardItem *result =
new WStandardItem(location);
637 if (!folderId.empty()) {
638 result->setData(boost::any(folderId));
639 result->setFlags(result->flags() | ItemIsDropEnabled);
640 folderNameMap_[folderId] = location;
642 result->setFlags(result->flags().clear(ItemIsSelectable));
644 result->setIcon(
"icons/folder.gif");
654 app->setTwoPhaseRenderingThreshold(0);
655 app->setTitle(
"WTreeView Drag & Drop");
656 app->useStyleSheet(
"styles.css");
657 app->messageResourceBundle().use(WApplication::appRoot() +
"about");
663 int main(
int argc,
char **argv)
TreeViewDragDrop(const WEnvironment &env)
Constructor.
static WString dateDisplayFormat
Date display format.
WStandardItemModel * folderModel_
The folder model (used by folderView_)
static WString dateEditFormat
Date edit format.
WMessageBox * popupActionBox_
Message box to confirm the poup menu action.
void handleFinish(DialogCode result)
WTableView * fileView()
Creates the file table view (a WTableView)
void convertToNumber(WStandardItem *item)
Convert a string to a number.
void convertToDate(WStandardItem *item)
Convert a string to a date.
void populateFiles()
Populate the files model.
WApplication * createApplication(const WEnvironment &env)
virtual std::string mimeType() const
Return the mime type.
WWidget * pieChart()
Creates the chart.
static const char * FileSelectionMimeType
Constant that indicates the mime type for a selection of files.
WTreeView * folderView_
The folder view.
A specialized standard item model which report a specific drag and drop mime type.
WWidget * aboutDisplay()
Creates the hints text.
void dialogDone()
Process the result of the message box.
A specialized treeview that supports a custom drop event.
WDatePicker * modifiedPicker_
WSortFilterProxyModel * fileFilterModel_
The sort filter proxy model that adapts fileModel_.
std::map< std::string, WString > folderNameMap_
Maps folder id's to folder descriptions.
void editFile(const WModelIndex &item)
Edit a particular row.
void createUI()
Setup the user interface.
A dialog for editing a 'file'.
WStandardItem * createFolderItem(const WString &location, const std::string &folderId=std::string())
Create a folder item.
void showPopup(const WModelIndex &item, const WMouseEvent &event)
Show a popup for a folder item.
WPopupMenu * popup_
Popup menu on the folder view.
WAbstractItemModel * model_
void populateFolders()
Populate the folders model.
WTreeView * folderView()
Creates the folder WTreeView.
FileModel(WObject *parent)
Constructor.
void popupAction()
Process the result of the popup menu.
WTableView * fileView_
The file view.
int main(int argc, char **argv)
void folderChanged()
Change the filter on the file view when the selected folder changes.
void readFromCsv(std::istream &f, Wt::WAbstractItemModel *model, int numRows, bool firstLineIsHeaders)
Utility function that reads a model from a CSV file.
FileEditDialog(WAbstractItemModel *model, const WModelIndex &item)
WStandardItemModel * fileModel_
The file model (used by fileView_)
virtual ~TreeViewDragDrop()
WText * createTitle(const WString &title)
Creates a title widget.