#ifndef _MIR_WCUSTOMTABLEVIEW_H_ #define _MIR_WCUSTOMTABLEVIEW_H_ /* * Copyright (c) 2011, * Technical University Of Gdansk, * Faculty of Electronics, Telecommunications and Informatics, * Multimedia Systems Department * and/or its affiliates. All rights reserved. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "utils/mir_trkeys.h" #include "utils/mir_cssclasses.h" #include "widgets/mir_wcustomtableviewpushbutton.h" #include "mir_databasemodule.h" #include "resources/mir_sp_paramselresource.h" namespace SyNaT { namespace MIR { using namespace Wt; using namespace std; namespace dbo = Wt::Dbo; template class WCustomTableView; template class WCustomTableViewImpl : public WContainerWidget { friend class WCustomTableViewPushButton; public: WCustomTableViewImpl(DatabaseModule *dm, dbo::Session *session, bool likeStatement = false, WCustomTableView *ctv = 0) : m_customTableView(ctv), m_checkable(false) , m_current_page(0), m_nav_bar_created(false), m_num_of_pages_in_nav_bar(1) , m_first_page_in_nav_bar(0), m_last_page_in_nav_bar(m_num_of_pages_in_nav_bar-1) , m_dm(dm), m_session(session), m_pref_num_of_pages_in_nav_bar(4) { WContainerWidget *options_bar = new WContainerWidget(); this->addWidget(options_bar); options_bar->setClearSides(Left | Right); // WPushButton *wpb = new WPushButton(tr(MIR_WCTV_SAVE_SEL), options_bar); // wpb->setStyleClass(MIR_STRINGIFY(MIR_CSS_PAGE_NAV_BUTTON)); // new WText("   ", XHTMLText, options_bar); WAnchor *ar = new WAnchor(WLink(new SP::ParamsSelResource(this->m_dm)), tr(MIR_WCTV_EXPORT_SEL_PARS), options_bar); ar->setTarget(TargetNewWindow); options_bar = new WContainerWidget(); this->addWidget(options_bar); options_bar->setClearSides(Left | Right); //this->m_txt = new WText(tr(MIR_TABLE_EXP_SEARCH).arg(WString::Empty), options_bar); //this->m_txt->disable(); this->m_sle = new WLineEdit(options_bar); this->m_sle->setTextSize(30); this->m_scb = new WComboBox(options_bar); //this->m_sle->disable(); //if (likeStatement) //{ // this->m_wcb = new WCheckBox(tr(MIR_TABLE_EXP_LIKE), options_bar); // this->m_wcb->disable(); //} this->m_wpb = new WPushButton(tr(MIR_WCTV_APPLY_SEARCH), options_bar); this->m_show_only_selected = new WCheckBox(tr(MIR_WCTV_SHOW_ONLY_SELECTED), options_bar); this->m_txt_selected = new WText(tr(MIR_WCTV_SELECTED), options_bar); this->m_txt_all_displayed = new WText(tr(MIR_WCTV_ALL_DISPLAYED), options_bar); options_bar = new WContainerWidget(); this->addWidget(options_bar); options_bar->setClearSides(Left | Right); WHBoxLayout *layout = new WHBoxLayout(); this->m_selectAll = new WPushButton(tr(MIR_WCTV_SELECT_ALL_FILTERED)); layout->addWidget(this->m_selectAll); this->m_selectAll->setStyleClass(MIR_STRINGIFY(MIR_CSS_PAGE_NAV_BUTTON)); this->m_inverseSelection = new WPushButton(tr(MIR_WCTV_INVERSE_SELECTION)); layout->addWidget(this->m_inverseSelection); this->m_inverseSelection->setStyleClass(MIR_STRINGIFY(MIR_CSS_PAGE_NAV_BUTTON)); // new WText("   ", XHTMLText, options_bar); this->m_unselectAll = new WPushButton(tr(MIR_WCTV_UNSELECT_ALL_FILTERED)); layout->addWidget(this->m_unselectAll); this->m_unselectAll->setStyleClass(MIR_STRINGIFY(MIR_CSS_PAGE_NAV_BUTTON)); options_bar->setLayout(layout, AlignTop | AlignJustify); options_bar = new WContainerWidget(); options_bar->setClearSides(Left | Right); layout = new WHBoxLayout(); this->m_wtv = new WTableView(); layout->addWidget(this->m_wtv); this->m_slider = new WSlider(Vertical); this->m_slider->setTickPosition(WSlider::TicksRight); layout->addWidget(this->m_slider); options_bar->setLayout(layout, AlignTop | AlignJustify); this->addWidget(options_bar); this->m_page_nav_bar = new WContainerWidget(); this->addWidget(this->m_page_nav_bar); this->m_page_nav_bar->setClearSides(Left | Right); } virtual ~WCustomTableViewImpl() { } WText &selectedText() { return *(this->m_txt_selected); } WText &displayedAllText() { return *(this->m_txt_all_displayed); } WLineEdit &searchLineEdit() { return *(this->m_sle); } WComboBox &searchComboBox() { return *(this->m_scb); } WPushButton &searchPushButton() { return *(this->m_wpb); } WCheckBox &showOnlySelectedCheckBox() { return *(this->m_show_only_selected); } //WCheckBox &searchCheckBoxLike() //{ // return *(this->m_wcb); //} WPushButton &selectAllPushButton() { return *(this->m_selectAll); } WPushButton &inverseSelection() { return *(this->m_inverseSelection); } WPushButton &unselectAllPushButton() { return *(this->m_unselectAll); } WSlider &slider() { return *(this->m_slider); } int update_slider() { int max = this->pageCount() + (this->pageCountReminder() > 0 ? -1 : -2); if (max < 0) max = 1; this->m_slider->setRange(0, max); int tickInterval = (int) (this->height().value() / max); if (tickInterval < 10) tickInterval = (int) ((10 * max) / this->height().value()); if (tickInterval < 1) tickInterval = max; this->m_slider->setTickInterval(tickInterval); return max; } virtual void load() { if (!this->loaded()) { this->m_first_page_in_nav_bar = 0; this->m_page_nav_bar->setLayout(this->create_page_nav_bar(), AlignTop | AlignJustify); this->m_slider->setValue(this->update_slider()); this->m_slider->sliderMoved().connect(this, &WCustomTableViewImpl::slt_sliderMoved); this->m_nav_bar_created = true; } this->WContainerWidget::load(); } int rowsPerPage() const { return this->m_rows_per_page; } void setRowsPerPage(const int rows) { this->m_rows_per_page = rows; } void slt_sliderMoved(int page_clicked) { bool nbnu = false; // if (this->pageCount() >= page_clicked) // { page_clicked = (int) (((this->m_slider->maximum() - page_clicked) / (this->m_slider->maximum() * 1.0)) * (this->pageCount() - 1)); if (this->m_current_page != page_clicked) { if (page_clicked <= this->pageCount()) this->scrollTo( this->model() ->index(page_clicked * this->rowsPerPage(), 0), WTableView::PositionAtTop); this->m_first_page_in_nav_bar = page_clicked; this->m_last_page_in_nav_bar = page_clicked + this->m_num_of_pages_in_nav_bar - 1; if ((this->m_first_page_in_nav_bar + this->m_num_of_pages_in_nav_bar) > this->pageCount()) { this->m_first_page_in_nav_bar = this->pageCount() - this->m_num_of_pages_in_nav_bar; this->m_last_page_in_nav_bar = this->pageCount(); } this->m_current_page = page_clicked; nbnu = true; } // } // else // { // this->update_slider(); // this->m_slider->setValue(this->m_slider->maximum()); // } this->update_page_nav_bar(nbnu); } dbo::QueryModel *model() const { return dynamic_cast *>(this->m_wtv->model()); } void setModel(dbo::QueryModel *model) { if (model) model->layoutChanged().connect(this, &WCustomTableViewImpl::slt_modelLayoutChanged); this->m_wtv->setModel(model); int row_count = this->model()->rowCount(); this->m_page_count_reminder = (row_count > this->rowsPerPage()) ? row_count % this->rowsPerPage() : 0; this->m_page_count = (int) (((row_count * 1.0)/ (this->rowsPerPage()) + ((this->m_page_count_reminder) > 0 ? 1 : 0))); } void slt_modelLayoutChanged() { //int sortColumn = this->sortColumn(); //if (sortColumn > -1) //{ //WString headerName = boost::any_cast(this->model()->headerData(sortColumn)); //this->m_txt->setText(tr(MIR_TABLE_EXP_SEARCH).arg(headerName)); //this->m_txt->enable(); //this->m_sle->enable(); //this->m_wcb->enable(); //} //else //{ //this->m_txt->setText(tr(MIR_TABLE_EXP_SEARCH).arg(WString::Empty)); //this->m_txt->disable(); //this->m_sle->disable(); //this->m_wcb->disable(); //} int row_count = this->model()->rowCount(); this->m_page_count_reminder = (row_count > this->rowsPerPage()) ? row_count % this->rowsPerPage() : 0; this->m_page_count = (int) (((row_count * 1.0)/ (this->rowsPerPage()) + ((this->m_page_count_reminder) > 0 ? 1 : 0))); } void setSortingEnabled(int column, bool enabled) { this->m_wtv->setSortingEnabled(column, enabled); } virtual void setRowHeight(const WLength& rowHeight) { this->m_wtv->setRowHeight(rowHeight); } virtual void setColumnWidth(int column, const WLength& width) { this->m_wtv->setColumnWidth(column, width); } void sortByColumn(int column, SortOrder order) { this->m_wtv->sortByColumn(column, order); } virtual void setAlternatingRowColors(bool enable) { this->m_wtv->setAlternatingRowColors(enable); } void setItemDelegateForColumn(int column, WAbstractItemDelegate *delegate) { this->m_wtv->setItemDelegateForColumn(column, delegate); } virtual void setSelectable(bool selectable) { this->m_wtv->setSelectable(selectable); } virtual void setCheckable(const bool checkable) { this->m_checkable = checkable; } virtual void resize(const int& widthPx, const int& heightPx) { this->WContainerWidget::resize(widthPx, heightPx); this->m_wtv->resize(widthPx, heightPx-120); this->m_slider->setHeight(heightPx-120); } virtual void resize(const WLength& width, const WLength& height) { this->WContainerWidget::resize(width, height); } virtual void resize_inner_table_view(const WLength& width, const WLength& height) { this->m_wtv->resize(width, height); } virtual void scrollTo(const WModelIndex& index, Wt::WTableView::ScrollHint hint = Wt::WTableView::EnsureVisible) { this->m_wtv->scrollTo(index, hint); } virtual int pageCount() const { return this->m_page_count;//(this->model()->rowCount() / (this->rowsPerPage())); } virtual int pageCountReminder() const { return this->m_page_count_reminder;//(this->model()->rowCount() / (this->rowsPerPage())); } virtual int pageSize() const { return this->m_wtv->pageSize(); } virtual void setPrefNumOfPagesInNavBar(int num_of_pages) { this->m_pref_num_of_pages_in_nav_bar = num_of_pages; } virtual int sortColumn() { return this->m_wtv->sortColumn(); } virtual void refresh() { this->m_wtv->refresh(); } void update_page_nav_bar(const bool navBarNeedUpdate = false) { int page_count = this->pageCount(); if (navBarNeedUpdate && this->m_nav_bar_created) { //if (page_count < this->m_first_page_in_nav_bar + this->m_pref_num_of_pages_in_nav_bar - 1) if (page_count < this->m_first_page_in_nav_bar + this->m_num_of_pages_in_nav_bar - 1) { this->m_first_page_in_nav_bar = 0; this->m_num_of_pages_in_nav_bar = page_count - this->m_first_page_in_nav_bar; this->m_current_page = 0; // this->model()->reload(); this->m_wtv ->scrollTo( this->model()->index(0, 0), WTableView::PositionAtTop); } else this->m_num_of_pages_in_nav_bar = this->m_pref_num_of_pages_in_nav_bar; this->m_page_nav_bar->clear(); this->m_page_numbers.clear(); this->m_page_nav_bar->setLayout(this->create_page_nav_bar(), AlignTop | AlignJustify); } if ((this->m_page_numbers.size() > 0) && (this->m_page_numbers.at(0)->text().toUTF8() != boost::lexical_cast(this->m_first_page_in_nav_bar + 1))) { int first_page_in_nav_bar = this->m_first_page_in_nav_bar; BOOST_FOREACH(WCustomTableViewPushButton *b, this->m_page_numbers) { b->setText(boost::lexical_cast(first_page_in_nav_bar++ + 1)); } } string current_page = boost::lexical_cast(this->m_current_page + 1); BOOST_FOREACH(WCustomTableViewPushButton *b, this->m_page_numbers) { if (b->text().toUTF8() == current_page) { b->setStyleClass(MIR_STRCAT3(MIR_CSS_PAGE_NAV_BUTTON," ",MIR_CSS_PAGE_NAV_BUTTON_SELECTED)); } else { b->setStyleClass(MIR_STRINGIFY(MIR_CSS_PAGE_NAV_BUTTON)); } } } protected: virtual WHBoxLayout *create_page_nav_bar() { WHBoxLayout *layout = new WHBoxLayout(); int page_count = this->pageCount(); if (page_count > this->m_pref_num_of_pages_in_nav_bar) page_count = this->m_pref_num_of_pages_in_nav_bar; this->m_num_of_pages_in_nav_bar = page_count; if (this->pageCount() > 1) { WCustomTableViewPushButton *wpb = new WCustomTableViewPushButton(tr(MIR_WCTV_FIRST), this); this->m_wpbFirst = wpb; layout->addWidget(wpb); wpb->setStyleClass(MIR_STRINGIFY(MIR_CSS_PAGE_NAV_BUTTON)); wpb->clicked().connect(wpb, &WCustomTableViewPushButton::slt_first_page_clicked); wpb = new WCustomTableViewPushButton(tr(MIR_WCTV_PREV), this); layout->addWidget(wpb); wpb->setStyleClass(MIR_STRINGIFY(MIR_CSS_PAGE_NAV_BUTTON)); wpb->clicked().connect(wpb, &WCustomTableViewPushButton::slt_prev_page_clicked); wpb = new WCustomTableViewPushButton("<", this); layout->addWidget(wpb); wpb->setStyleClass(MIR_STRINGIFY(MIR_CSS_PAGE_NAV_BUTTON)); wpb->clicked().connect(wpb, &WCustomTableViewPushButton::slt_prev_pages_clicked); for(int i = this->m_first_page_in_nav_bar; i < this->m_first_page_in_nav_bar + page_count; i++) { wpb = new WCustomTableViewPushButton(boost::lexical_cast(i+1), this); layout->addWidget(wpb); wpb->setStyleClass(MIR_STRINGIFY(MIR_CSS_PAGE_NAV_BUTTON)); wpb->clicked().connect(wpb, &WCustomTableViewPushButton::slt_page_clicked); this->m_page_numbers.push_back(wpb); } this->m_last_page_in_nav_bar = this->m_first_page_in_nav_bar + page_count - 1; wpb = new WCustomTableViewPushButton(">", this); layout->addWidget(wpb); wpb->setStyleClass(MIR_STRINGIFY(MIR_CSS_PAGE_NAV_BUTTON)); wpb->clicked().connect(wpb, &WCustomTableViewPushButton::slt_next_pages_clicked); wpb = new WCustomTableViewPushButton(tr(MIR_WCTV_NEXT), this); layout->addWidget(wpb); wpb->setStyleClass(MIR_STRINGIFY(MIR_CSS_PAGE_NAV_BUTTON)); wpb->clicked().connect(wpb, &WCustomTableViewPushButton::slt_next_page_clicked); wpb = new WCustomTableViewPushButton(tr(MIR_WCTV_LAST), this); layout->addWidget(wpb); wpb->setStyleClass(MIR_STRINGIFY(MIR_CSS_PAGE_NAV_BUTTON)); wpb->clicked().connect(wpb, &WCustomTableViewPushButton::slt_last_page_clicked); } this->update_page_nav_bar(); return layout; } private: WTableView *m_wtv; DatabaseModule *m_dm; WContainerWidget *m_page_nav_bar; WLineEdit *m_sle; WComboBox *m_scb; WText *m_txt_selected; WText *m_txt_all_displayed; WPushButton *m_wpb; WCheckBox *m_show_only_selected; //WCheckBox *m_wcb; WPushButton *m_selectAll; WPushButton *m_inverseSelection; WPushButton *m_unselectAll; WSlider *m_slider; dbo::Session *m_session; vector *> m_page_numbers; WCustomTableViewPushButton *m_wpbFirst; bool m_checkable; int m_first_page_in_nav_bar; int m_last_page_in_nav_bar; int m_current_page; int m_num_of_pages_in_nav_bar; int m_pref_num_of_pages_in_nav_bar; int m_rows_per_page; bool m_nav_bar_created; int m_page_count; int m_page_count_reminder; WCustomTableView *m_customTableView; }; template class WCustomTableView : public WCompositeWidget { public: WCustomTableView(DatabaseModule *dm, dbo::Session *session, bool likeStatement = false, WContainerWidget *parent = 0) : WCompositeWidget(parent) { impl_ = new WCustomTableViewImpl(dm, session, likeStatement, this); setImplementation(impl_); } WCustomTableViewImpl *impl() { return this->impl_; } private: WCustomTableViewImpl *impl_; }; } } #endif /* _MIR_WCUSTOMTABLEVIEW_H_ */