47 #include <Wt/Dbo/Query.h> 48 #include <Wt/Dbo/ptr.h> 49 #include <Wt/Json/Value.h> 50 #include <Wt/WDialog.h> 52 #include <Wt/WLineEdit.h> 53 #include <Wt/WTemplate.h> 54 #include <Wt/WComboBox.h> 55 #include <Wt/WCheckBox.h> 56 #include <Wt/WPushButton.h> 57 #include <Wt/WTabWidget.h> 58 #include <Wt/WTableView.h> 59 #include <Wt/WStringListModel.h> 61 #include <Wtx/Dbo/Session.h> 62 #include <Wtx/Sys/Config/Item.h> 64 #include "TableViewDef.h" 70 Wt::Dbo::Transaction t(*session);
72 session->
template find<Wtx::Sys::Config::Item>()
73 .where(
"\"keyField\" = ?" )
80 m_def.columnNames.push_back(
"id" );
81 for(
auto fieldDef : tableDef.fieldDefs() )
82 m_def.columnNames.push_back( fieldDef-> fieldName() );
87 Wt::Json::Object result;
89 Wt::Json::parse( item-> varField().Field::value(), result );
91 catch( std::exception & e )
96 m_def.title = result.get(
"title").orIfNull(
"");
97 m_def.tip = result.get(
"tip").orIfNull(
"");
98 m_def.rowHeaderCount = result.get(
"rowHeaderCount").orIfNull(0);
99 m_def.columnResizeEnabled = result.get(
"columnResizeEnabled").orIfNull(
true);
100 m_def.alternatingRowColors = result.get(
"alternatingRowColors").orIfNull(
true);
101 m_def.sql = result.get(
"sql").orIfNull(
"");
102 m_def.filter = result.get(
"filter").orIfNull(
"");
104 m_def.showHeader = result.get(
"showHeader").orIfNull(
true);
105 m_def.showFooter = result.get(
"showFooter").orIfNull(
false);
106 m_def.showPrevNext = result.get(
"showPrevNext").orIfNull(
false);
107 m_def.hideSearch = result.get(
"hideSearch").orIfNull(
false);
108 m_def.allowFilter = result.get(
"allowFilter").orIfNull(
false);
109 m_def.allowAdd = result.get(
"allowAdd").orIfNull(
false);
110 m_def.allowChange = result.get(
"allowChange").orIfNull(
false);
111 m_def.allowDelete = result.get(
"allowDelete").orIfNull(
false);
112 m_def.allowExport = result.get(
"allowExport").orIfNull(
false);
113 m_def.allowSearch = result.get(
"allowSearch").orIfNull(
false);
114 m_def.allowPrint = result.get(
"allowPrint").orIfNull(
false);
115 m_def.allowUnlock = result.get(
"allowUnlock").orIfNull(
false);
116 m_def.additional = result.get(
"additional").orIfNull(
"");
117 m_def.checkBoxSelect = result.get(
"checkBoxSelect").orIfNull(
false);
118 m_def.deleteMessage = result.get(
"deleteMessage").orIfNull(
"");
120 switch( result.get(
"selectionMode").orIfNull(0) )
122 case 0: m_def.selectionMode = Wt::SelectionMode::None;
break;
123 case 1: m_def.selectionMode = Wt::SelectionMode::Single;
break;
124 case 2: m_def.selectionMode = Wt::SelectionMode::Extended;
break;
128 Wt::Json::Array ja = result.get(
"sortFields");
129 for(
auto field : ja )
130 m_def.sortFields.push_back( field );
134 Wt::Json::Array ja = result.get(
"searchFields");
135 for(
auto field : ja )
136 m_def.searchFields.push_back( field );
140 Wt::Json::Array ja = result.get(
"columnDefs");
141 for( Wt::Json::Object jobj : ja )
144 colDef.field = jobj.get(
"field").orIfNull(
"");
145 colDef.label = jobj.get(
"label").orIfNull(
"");
146 colDef.width = jobj.get(
"width").orIfNull(100);
148 colDef.toolTip = jobj.get(
"toolTip").orIfNull(
"");
149 m_def.columnDefs.push_back( colDef );
154 Wt::Json::Array ja = result.get(
"flags");
155 for(
auto flag : ja )
156 m_def.flags.push_back( flag );
161 for(
auto fieldDef : tableDef.fieldDefs() )
162 m_def.columnNames.push_back( fieldDef-> fieldName() );
177 Wt::WString(
"viewDef.{1}.Default")
178 .arg( tableDef.tableName() )
182 m_def.title =
"Default";
184 m_def.columnNames.push_back(
"id" );
185 for(
auto fieldDef : tableDef.fieldDefs() )
186 m_def.columnNames.push_back( fieldDef-> fieldName() );
194 m_def.title = def.title;
196 m_def.rowHeaderCount = def.rowHeaderCount;
197 m_def.selectionMode = def.selectionMode;
198 m_def.columnResizeEnabled = def.columnResizeEnabled;
199 m_def.alternatingRowColors = def.alternatingRowColors;
201 m_def.filter = def.filter;
202 m_def.idin = def.idin;
203 m_def.doubleClick = def.doubleClick;
204 m_def.showHeader = def.showHeader;
205 m_def.showFooter = def.showFooter;
206 m_def.showPrevNext = def.showPrevNext;
207 m_def.hideSearch = def.hideSearch;
208 m_def.allowFilter = def.allowFilter;
209 m_def.allowAdd = def.allowAdd;
210 m_def.allowChange = def.allowChange;
211 m_def.allowDelete = def.allowDelete;
212 m_def.allowExport = def.allowExport;
213 m_def.allowSearch = def.allowSearch;
214 m_def.allowPrint = def.allowPrint;
215 m_def.allowUnlock = def.allowUnlock;
216 m_def.additional = def.additional;
217 m_def.delegate = def.delegate;
218 m_def.checkBoxSelect = def.checkBoxSelect;
219 m_def.deleteMessage = def.deleteMessage;
221 for(
auto sortField : def.sortFields )
222 m_def.sortFields.push_back( sortField );
224 for(
auto searchField : def.searchFields )
225 m_def.searchFields.push_back( searchField );
227 for(
auto colDef : def.columnDefs )
228 m_def.columnDefs.push_back( colDef );
230 for(
auto colName : def.columnNames )
231 m_def.columnNames.push_back( colName );
233 for(
auto flag : def.flags )
234 m_def.flags.push_back( flag );
239 bool Wtx::TableViewDef::save(
const std::string & defName,
Wtx::Dbo::Session * session )
243 Wt::Dbo::Transaction t(*session);
245 session->
template find<Wtx::Sys::Config::Item>()
246 .where(
"\"keyField\" = ?" )
251 if( item.id() == -1 )
253 session->
template addNew<Wtx::Sys::Config::Item>( m_name );
255 Wt::Json::Object jobj;
256 jobj[
"title" ] = Wt::WString( m_def.title );
257 jobj[
"tip" ] = Wt::WString( m_def.tip );
258 jobj[
"rowHeaderCount" ] = m_def.rowHeaderCount;
259 jobj[
"selectionMode" ] = (int)m_def.selectionMode;
260 jobj[
"columnResizeEnabled" ] = m_def.columnResizeEnabled;
261 jobj[
"alternatingRowColors" ] = m_def.alternatingRowColors;
262 jobj[
"sql" ] = Wt::WString( m_def.sql );
263 jobj[
"filter" ] = Wt::WString( m_def.filter );
265 jobj[
"showHeader" ] = m_def.showHeader;
266 jobj[
"showFooter" ] = m_def.showFooter;
267 jobj[
"showPrevNext" ] = m_def.showPrevNext;
268 jobj[
"hideSearch" ] = m_def.hideSearch;
269 jobj[
"allowFilter" ] = m_def.allowFilter;
270 jobj[
"allowAdd" ] = m_def.allowAdd;
271 jobj[
"allowChange" ] = m_def.allowChange;
272 jobj[
"allowDelete" ] = m_def.allowDelete;
273 jobj[
"allowExport" ] = m_def.allowExport;
274 jobj[
"allowSearch" ] = m_def.allowSearch;
275 jobj[
"allowPrint" ] = m_def.allowPrint;
276 jobj[
"allowUnlock" ] = m_def.allowUnlock;
277 jobj[
"additional" ] = Wt::WString( m_def.additional );
278 jobj[
"checkBoxSelect" ] = m_def.checkBoxSelect;
279 jobj[
"deleteMessage" ] = Wt::WString( m_def.deleteMessage );
283 for(
auto sortField : m_def.sortFields )
284 ja.push_back( Wt::WString(sortField) );
285 jobj[
"sortFields" ] = ja;
290 for(
auto searchField : m_def.searchFields )
291 ja.push_back( Wt::WString(searchField) );
292 jobj[
"searchFields" ] = ja;
297 for(
auto colDef : m_def.columnDefs )
300 jo[
"field" ] = Wt::WString(colDef.field);
301 jo[
"label" ] = Wt::WString(colDef.label);
302 jo[
"width" ] = colDef.width.value();
303 jo[
"toolTip" ] = Wt::WString(colDef.toolTip);
306 jobj[
"columnDefs" ] = ja;
311 for(
auto flag : m_def.flags )
312 ja.push_back( Wt::WString(flag) );
313 jobj[
"flags" ] = ja;
316 item.modify()-> varField().setValue( Wt::Json::serialize(jobj) );
322 return item.id() != -1;
328 auto dialog = addChild( std::make_unique<Wt::WDialog>(
"View Properties") );
329 dialog-> rejectWhenEscapePressed(
true);
331 auto templt = dialog-> contents()-> addNew<Wt::WTemplate>
338 " <tr><td> ${ok} </td><td> ${cancel} </td></tr>" 344 auto tabWidget = templt-> bindNew<Wt::WTabWidget>(
"tabWidget");
346 auto props_ = std::make_unique<Wt::WTemplate>
351 " <tr><td> Title: </td><td> ${title} </td>" 352 " <td> Tool Tip: </td><td> ${tip} </td></tr>" 353 " <tr><td> Selection: </td><td> ${selectionMode} </td></tr>" 354 " <tr><td> SQL: </td><td colspan=\"3\"> ${sql} </td></tr>" 355 " <tr><td> Filter: </td><td colspan=\"3\"> ${filter} </td></tr>" 356 " <tr><td> ID in: </td><td colspan=\"3\"> ${idin} </td></tr>" 357 " <tr><td> Column Resize Enabled: </td><td> ${columnResizeEnabled} </td>" 358 " <td> Alternating Row Colors: </td><td> ${alternatingRowColors} </td></tr>" 359 " <tr><td> Show Header: </td><td> ${showHeader} </td>" 360 " <td> Show Footer: </td><td> ${showFooter} </td></tr>" 361 " <td> Show Prev/Next: </td><td> ${showPrevNext} </td></tr>" 362 " <tr><td> Hide Search: </td><td> ${hideSearch} </td></tr>" 363 " <tr><td> Allow Filter: </td><td> ${allowFilter} </td>" 364 " <td> Allow Add: </td><td> ${allowAdd} </td></tr>" 365 " <tr><td> Allow Change: </td><td> ${allowChange} </td>" 366 " <td> Allow Delete: </td><td> ${allowDelete} </td></tr>" 367 " <tr><td> Allow Export: </td><td> ${allowExport} </td>" 368 " <td> Allow Search: </td><td> ${allowSearch} </td></tr>" 369 " <td> Allow Print: </td><td> ${allowPrint} </td></tr>" 370 " <td> Allow Unlock: </td><td> ${allowUnlock} </td></tr>" 371 " <td> Additional: </td><td> ${additional} </td></tr>" 372 " <td> CheckBoxSelect: </td><td> ${checkBoxSelect} </td></tr>" 373 " <td> DeleteMessage: </td><td> ${deleteMessage} </td></tr>" 377 auto props = props_.get();
378 tabWidget-> addTab( std::move(props_),
"Display" );
380 props-> bindNew<Wt::WLineEdit>(
"title", m_def.title );
381 props-> bindNew<Wt::WLineEdit>(
"tip", m_def.tip );
382 props-> bindNew<Wt::WLineEdit>(
"sql", m_def.sql );
383 props-> bindNew<Wt::WLineEdit>(
"filter", m_def.filter );
386 auto cbSelectionMode = props-> bindNew<Wt::WComboBox>(
"selectionMode");
387 cbSelectionMode-> addItem(
"No Selections" );
388 cbSelectionMode-> addItem(
"Single Selection Only" );
389 cbSelectionMode-> addItem(
"Multiple Selection" );
390 cbSelectionMode-> setCurrentIndex( (
int)m_def.selectionMode );
392 auto _checkState = [](
bool value )
395 return( Wt::CheckState::Checked );
397 return( Wt::CheckState::Unchecked );
400 props-> bindNew<Wt::WCheckBox>(
"columnResizeEnabled" )->
401 setCheckState( _checkState( m_def.columnResizeEnabled ) );
403 props-> bindNew<Wt::WCheckBox>(
"alternatingRowColors" )->
404 setCheckState( _checkState( m_def.alternatingRowColors ) );
406 props-> bindNew<Wt::WCheckBox>(
"showHeader" )->
407 setCheckState( _checkState( m_def.showHeader ) );
409 props-> bindNew<Wt::WCheckBox>(
"showFooter" )->
410 setCheckState( _checkState( m_def.showFooter ) );
412 props-> bindNew<Wt::WCheckBox>(
"showPrevNext" )->
413 setCheckState( _checkState( m_def.showPrevNext ) );
415 props-> bindNew<Wt::WCheckBox>(
"hideSearch" )->
416 setCheckState( _checkState( m_def.hideSearch ) );
418 props-> bindNew<Wt::WCheckBox>(
"allowFilter" )->
419 setCheckState( _checkState( m_def.allowFilter ) );
421 props-> bindNew<Wt::WCheckBox>(
"allowAdd" )->
422 setCheckState( _checkState( m_def.allowAdd ) );
424 props-> bindNew<Wt::WCheckBox>(
"allowChange" )->
425 setCheckState( _checkState( m_def.allowChange ) );
427 props-> bindNew<Wt::WCheckBox>(
"allowDelete" )->
428 setCheckState( _checkState( m_def.allowDelete ) );
430 props-> bindNew<Wt::WCheckBox>(
"allowExport" )->
431 setCheckState( _checkState( m_def.allowExport ) );
433 props-> bindNew<Wt::WCheckBox>(
"allowSearch" )->
434 setCheckState( _checkState( m_def.allowSearch ) );
436 props-> bindNew<Wt::WCheckBox>(
"allowPrint" )->
437 setCheckState( _checkState( m_def.allowPrint ) );
439 props-> bindNew<Wt::WCheckBox>(
"allowUnlock" )->
440 setCheckState( _checkState( m_def.allowUnlock ) );
442 props-> bindNew<Wt::WCheckBox>(
"checkBoxSelect" )->
443 setCheckState( _checkState( m_def.checkBoxSelect ) );
445 props-> bindNew<Wt::WLineEdit>(
"additional" )->
446 setValueText( m_def.additional );
448 templt-> bindNew<Wt::WPushButton>(
"ok",
"Ok" )->
449 clicked().connect( dialog, &Wt::WDialog::accept );
451 templt-> bindNew<Wt::WPushButton>(
"cancel",
"Cancel" )->
452 clicked().connect( dialog, &Wt::WDialog::reject );
458 auto cols_ = std::make_unique<Wt::WTemplate>
464 " <td> Columns in View </td>" 465 " <td> Columns not in View </td>" 468 " <td> ${colsIn} </td>" 469 " <td> ${colsNo} </td>" 472 " <td> ${removeCol} </td>" 473 " <td> ${appendCol} </td>" 476 " <td> ${colOption} </td>" 477 " <td> ${insertCol} </td>" 482 auto cols = cols_.get();
483 tabWidget-> addTab( std::move(cols_),
"Columns" );
485 auto tvColsIn = cols-> bindNew<Wt::WTableView>(
"colsIn");
486 auto tvColsNo = cols-> bindNew<Wt::WTableView>(
"colsNo");
488 auto slColsIn = std::make_shared<Wt::WStringListModel>();
489 for(
auto colDef : m_def.columnDefs )
490 slColsIn-> addString( colDef.field );
491 tvColsIn-> setModel( slColsIn );
492 tvColsIn-> setHeight( 200 );
493 tvColsIn-> setSelectionMode( Wt::SelectionMode::Single );
494 tvColsIn-> setEditTriggers( Wt::EditTrigger::None );
496 auto pbRemoveCol = cols-> bindNew<Wt::WPushButton>(
"removeCol",
"Remove Column" );
497 auto pbColOption = cols-> bindNew<Wt::WPushButton>(
"colOption",
"Column Options" );
500 auto slColsNo = std::make_shared<Wt::WStringListModel>();
501 tvColsNo-> setModel( slColsNo );
502 tvColsNo-> setHeight( 200 );
503 tvColsNo-> setSelectionMode( Wt::SelectionMode::Single );
504 tvColsNo-> setEditTriggers( Wt::EditTrigger::None );
506 auto pbAppendCol = cols-> bindNew<Wt::WPushButton>(
"appendCol",
"Append Column" );
507 auto pbInsertCol = cols-> bindNew<Wt::WPushButton>(
"insertCol",
"Insert Column" );
509 auto _refreshCols = [=]()
511 if( slColsNo-> rowCount() > 0 )
512 slColsNo-> removeRows( 0, slColsNo-> rowCount() );
514 for(
auto colName : m_def.columnNames )
515 if( std::find( slColsIn-> stringList().begin(), slColsIn-> stringList().end(), colName ) == slColsIn-> stringList().end() )
516 slColsNo-> addString( colName );
519 auto _enableButtons = [=]()
521 if( slColsIn-> rowCount() > 0 )
523 pbRemoveCol-> setEnabled(
true );
524 pbColOption-> setEnabled(
true );
528 pbRemoveCol-> setEnabled(
false );
529 pbColOption-> setEnabled(
false );
532 if( slColsNo-> rowCount() > 0 )
534 pbAppendCol-> setEnabled(
true );
535 pbInsertCol-> setEnabled(
true );
539 pbAppendCol-> setEnabled(
false );
540 pbInsertCol-> setEnabled(
false );
545 auto _removeCol = [=]()
547 if( tvColsIn-> selectedIndexes().size() > 0 )
549 auto index = *(tvColsIn-> selectedIndexes().begin());
551 if( index.isValid() )
553 slColsIn-> removeRows( index.row(), 1 );
561 auto _appendCol = [=]()
563 if( tvColsNo-> selectedIndexes().size() > 0 )
565 auto index = *(tvColsNo-> selectedIndexes().begin());
567 if( index.isValid() )
569 slColsIn-> addString( Wt::asString( slColsNo-> data( index ) ) );
577 auto _insertCol = [=]()
579 if( tvColsIn-> selectedIndexes().size() > 0
580 && tvColsNo-> selectedIndexes().size() > 0 )
582 auto indexIn = *(tvColsIn-> selectedIndexes().begin());
583 auto indexNo = *(tvColsNo-> selectedIndexes().begin());
585 if( indexIn.isValid()
586 && indexNo.isValid() )
588 slColsIn-> insertString
591 Wt::asString( slColsNo-> data( indexNo ) )
602 pbRemoveCol-> clicked().connect( std::bind( [=](){ _removeCol(); } ) );
603 pbAppendCol-> clicked().connect( std::bind( [=](){ _appendCol(); } ) );
604 pbInsertCol-> clicked().connect( std::bind( [=](){ _insertCol(); } ) );
605 tvColsIn-> clicked().connect( std::bind( [=](){ _enableButtons(); } ) );
606 tvColsIn-> doubleClicked().connect( std::bind( [=](){ _removeCol(); } ) );
607 tvColsNo-> clicked().connect( std::bind( [=](){ _enableButtons(); } ) );
608 tvColsNo-> doubleClicked().connect( std::bind( [=](){ _appendCol(); } ) );
613 pbColOption-> clicked().connect( std::bind( [tvColsIn,slColsIn,
this]()
615 if( tvColsIn-> selectedIndexes().size() == 0 )
618 auto index = *(tvColsIn-> selectedIndexes().begin());
620 if( !index.isValid() )
623 auto colName = slColsIn-> stringList().at( index.row() );
625 for(
int i = 0; i < m_def.columnDefs.size(); i++ )
627 if( m_def.columnDefs[i].field == colName )
629 m_def.columnDefs[i].editProperties();
642 dialog-> finished().connect( std::bind( [=]()
644 if( dialog-> result() != Wt::DialogCode::Accepted )
647 auto _getString = [props](
const std::string & varName, std::string & value )
649 auto w =
static_cast<Wt::WLineEdit*
>( props-> resolveWidget(varName) );
650 value = w-> valueText().toUTF8();
653 _getString(
"title", m_def.title );
654 _getString(
"tip", m_def.tip );
655 _getString(
"sql", m_def.sql );
656 _getString(
"filter", m_def.filter );
659 auto _getChecked = [props](
const std::string & varName,
bool & value )
661 auto w =
static_cast<Wt::WCheckBox*
>( props-> resolveWidget(varName) );
663 if( w-> checkState() == Wt::CheckState::Checked )
669 _getChecked(
"columnResizeEnabled", m_def.columnResizeEnabled );
670 _getChecked(
"alternatingRowColors", m_def.alternatingRowColors );
671 _getChecked(
"showHeader", m_def.showHeader );
672 _getChecked(
"showFooter", m_def.showFooter );
673 _getChecked(
"showPrevNext", m_def.showPrevNext );
674 _getChecked(
"hideSearch", m_def.hideSearch );
675 _getChecked(
"allowFilter", m_def.allowFilter );
676 _getChecked(
"allowAdd", m_def.allowAdd );
677 _getChecked(
"allowChange", m_def.allowChange );
678 _getChecked(
"allowDelete", m_def.allowDelete );
679 _getChecked(
"allowExport", m_def.allowExport );
680 _getChecked(
"allowSearch", m_def.allowSearch );
681 _getChecked(
"allowPrint", m_def.allowPrint );
682 _getChecked(
"allowUnlock", m_def.allowUnlock );
683 _getChecked(
"checkBoxSelect", m_def.checkBoxSelect );
687 auto w =
static_cast<Wt::WComboBox*
>( props-> resolveWidget(
"selectionMode") );
688 switch( w-> currentIndex() )
690 case 0: m_def.selectionMode = Wt::SelectionMode::None;
break;
691 case 1: m_def.selectionMode = Wt::SelectionMode::Single;
break;
692 case 2: m_def.selectionMode = Wt::SelectionMode::Extended;
break;
695 std::vector<ColumnDef> columnDefs;
696 for(
auto slColIn : slColsIn-> stringList() )
698 auto _defExists = [=](
const Wt::WString & value )
700 for(
auto colDef : m_def.columnDefs )
701 if( colDef.field == value )
708 if( _defExists( slColIn ) )
710 for(
auto colDef : m_def.columnDefs )
711 if( colDef.field == slColIn )
712 columnDefs.push_back( colDef );
717 colDef.field = slColIn.toUTF8();
719 columnDefs.push_back( colDef );
724 m_def.columnDefs.clear();
725 for(
auto colDef : columnDefs )
726 m_def.columnDefs.push_back( colDef );
736 void Wtx::TableViewDef::ColumnDef::editProperties()
738 auto dialog =
new Wt::WDialog(
"Column Properties");
739 dialog-> rejectWhenEscapePressed(
true);
741 auto templt = dialog-> contents()-> addNew<Wt::WTemplate>
746 " Field Name: ${fieldName}" 748 " <tr><td> Label: </td><td> ${label} </td></tr>" 749 " <tr><td> Width: </td><td> ${width} </td></tr>" 750 " <tr><td> Tooltip: </td><td> ${toolTip} </td></tr>" 753 " <tr><td> ${ok} </td><td> ${cancel} </td></tr>" 759 templt-> bindString(
"fieldName", field );
760 templt-> bindNew<Wt::WPushButton>(
"ok",
"Ok" )->
761 clicked().connect( dialog, &Wt::WDialog::accept );
763 templt-> bindNew<Wt::WPushButton>(
"cancel",
"Cancel" )->
764 clicked().connect( dialog, &Wt::WDialog::reject );
766 templt-> bindNew<Wt::WLineEdit>(
"label", label );
767 templt-> bindNew<Wt::WLineEdit>(
"width", Wt::WString(
"{1}").arg( width.value() ) );
768 templt-> bindNew<Wt::WLineEdit>(
"toolTip", toolTip );
770 dialog-> finished().connect( std::bind( [templt,dialog,
this]()
772 if( dialog-> result() != Wt::DialogCode::Accepted )
775 auto _getString2 = [templt](
const std::string & varName )
777 auto w =
static_cast<Wt::WLineEdit*
>( templt-> resolveWidget(varName) );
778 return w-> valueText().toUTF8();
781 label = _getString2(
"label" );
782 width = std::stoi( _getString2(
"width" ) );
783 toolTip = _getString2(
"toolTip" );
793 bool Wtx::TableViewDef::hasFlag(
const std::string & value )
795 return std::find( m_def.flags.begin(), m_def.flags.end(), value ) != m_def.flags.end();