Wtx ~ Wt Extension Library
WtxLib
TableView_imp.h
1 /**************************************************************************
2 ###########################################################################
3 ##
4 ## $SHOWOFFDB_BEGIN_LICENSE$
5 ## Copyright (C) 2011 Lorimark Solutions, LLC and/or its subsidiary(-ies).
6 ## All rights reserved.
7 ## Contact: Lorimark Solutions, LLC (info@showoff-db.org)
8 ##
9 ## This file is part of the Showoff Database Application Framework.
10 ##
11 ## Commercial Usage
12 ## Licensees holding valid ShowoffDB Commercial licenses may use this file in
13 ## accordance with the ShowoffDB Commercial License Agreement provided with the
14 ## Software or, alternatively, in accordance with the terms contained in
15 ## a written agreement between you and Lorimark Solutions, LLC.
16 ##
17 ## GNU Lesser General Public License Usage
18 ## Alternatively, this file may be used under the terms of the GNU Lesser
19 ## General Public License version 2.1 as published by the Free Software
20 ## Foundation and appearing in the file LICENSE.LGPL included in the
21 ## packaging of this file. Please review the following information to
22 ## ensure the GNU Lesser General Public License version 2.1 requirements
23 ## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ##
25 ## In addition, as a special exception, Lorimark Solutions, LLC gives
26 ## you certain additional rights. These rights are described in the
27 ## Lorimark Solutions, LLC ShowoffDB LGPL Exception version 1.0, included in
28 ## the file LGPL_EXCEPTION.txt in this package.
29 ##
30 ## GNU General Public License Usage
31 ## Alternatively, this file may be used under the terms of the GNU
32 ## General Public License version 3.0 as published by the Free Software
33 ## Foundation and appearing in the file LICENSE.GPL included in the
34 ## packaging of this file. Please review the following information to
35 ## ensure the GNU General Public License version 3.0 requirements will be
36 ## met: http://www.gnu.org/copyleft/gpl.html.
37 ##
38 ## If you have questions regarding the use of this file, please contact
39 ## Lorimark Solutions, LLC at info@showoff-db.org.
40 ## $SHOWOFFDB_END_LICENSE$
41 ##
42 #############################################################################
43 ****************************************************************************/
44 
45 #include <Wt/WLineEdit.h>
46 #include <Wt/WDialog.h>
47 #include <Wt/WTemplate.h>
48 #include <Wt/WItemDelegate.h>
49 #include <Wt/WPushButton.h>
50 #include <Wt/WPopupMenu.h>
51 #include <Wt/Dbo/Json.h>
52 
53 #include <Wtx/Core/Core.h>
54 
55 
56 template <class C>
58 {
59 
60 }
61 
62 template <class C>
64 : Wtx::TableView(),
65  m_session(s)
66 {
67  std::cout
68  << std::string(session()-> template tableName<C>())
69  << std::endl;
70 
71  if( !viewDef().load( std::string(session()-> template tableName<C>()), session() ) )
72  {
73  viewDef().load( C::TableDef(), session() );
74  }
75 
76  init();
77 }
78 
79 template <class C>
80 Wtx::Dbo::TableView<C>::TableView( const std::string & tableDefName, Wtx::Dbo::Session * s )
81 : Wtx::TableView(),
82  m_session(s)
83 {
84  std::cout
85  << layoutName(tableDefName)
86  << std::endl;
87 
88  if( !loadLayout( layoutName(tableDefName) ) )
89  {
90  viewDef().load( C::TableDef(), session() );
91  viewDef().save( layoutName(tableDefName), session() );
92  }
93 
94  init();
95 }
96 
97 template <class C>
99 : Wtx::TableView(),
100  m_session(s)
101 {
102  viewDef().load( vd, s );
103 
104  init();
105 
106 }
107 
108 template <class C>
109 Wtx::Dbo::TableView<C>::TableView( const std::string & tableDefName, const Wtx::TableViewDef::ViewDef & vd, Wtx::Dbo::Session * s )
110 : Wtx::TableView(),
111  m_session(s)
112 {
113  std::cout
114  << layoutName(tableDefName)
115  << std::endl;
116 
117  if( !loadLayout( layoutName(tableDefName) ) )
118  {
119  viewDef().load( vd, session() );
120  viewDef().save( layoutName(tableDefName), session() );
121  }
122 
123  init();
124 }
125 
126 template <class C>
128 {
129  m_model =
130  std::make_shared
131  <
133  <
134  Wt::Dbo::ptr<C>
135  >
136  >();
137 
138  model()-> setSession( session() );
139  model()-> m_countTable = C::TableDef().tableName();
140  model()-> setViewDef( &viewDef() );
141 
142  setQuery();
143  setLayout();
144 
145  viewDef().changed().connect( std::bind( [=]()
146  {
147  setQuery();
148  setLayout();
149  }));
150 
151 }
152 
153 
154 template <class C>
155 std::string Wtx::Dbo::TableView<C>::layoutName( const std::string & name ) const
156 {
157  return
158  Wt::WString("viewDef.{1}.{2}")
159  .arg( C::TableDef().tableName() )
160  .arg( name )
161  .toUTF8()
162  ;
163 }
164 
165 
166 template <class C>
167 void Wtx::Dbo::TableView<C>::showHeaderPopup( const Wt::WMouseEvent & event )
168 {
169  if( event.button() == Wt::MouseButton::Right )
170  {
171  Wt::WPopupMenu* pItemPopup = new Wt::WPopupMenu();
172 
173  pItemPopup-> addItem( Wt::WString/*::tr*/( "Layout..." ) )->
174  triggered().connect( std::bind( [this](){ viewDef().editProperties(); } ) );
175 
176  pItemPopup-> addItem( Wt::WString/*::tr*/( "Save Layout" ) )->
177  triggered().connect( std::bind( [this]()
178  {
179  int col = 0;
180  for( auto columnDef : viewDef().m_def.columnDefs )
181  {
182  viewDef().m_def.columnDefs[col].width = columnWidth( col );
183  col++;
184  }
185 
186  if( viewDef().m_name == "" )
187  {
188  auto dialog = new Wt::WDialog("Save View Layout");
189  dialog-> rejectWhenEscapePressed();
190  auto templt =
191  dialog-> contents()-> addNew<Wt::WTemplate>
192  (
193  "<div>"
194  " Please enter a name for this view"
195  "</div>"
196  "<div>${lineEdit}</div>"
197  "<div><center>"
198  " ${ok class=\"btn-success btn-xs\"}"
199  " ${cancel class=\"btn-danger btn-xs\"}"
200  "</center></div>"
201  );
202 
203  auto lineEdit =
204  templt-> bindNew<Wt::WLineEdit>("lineEdit");
205 
206  templt-> bindNew<Wt::WPushButton>("ok","ok")->
207  clicked().connect( dialog, &Wt::WDialog::accept );
208 
209  templt-> bindNew<Wt::WPushButton>("cancel","cancel")->
210  clicked().connect( dialog, &Wt::WDialog::reject );
211 
212  dialog-> finished().connect( [=]()
213  {
214  if( dialog-> result() != Wt::DialogCode::Accepted )
215  return;
216 
217  if( lineEdit-> text() == "" )
218  return;
219 
220  viewDef().save( lineEdit-> text().toUTF8(), session() );
221  });
222 
223  dialog-> exec();
224  }
225  else
226  {
227  viewDef().save( viewDef().m_name, session() );
228  }
229 
230  }));
231 
232  pItemPopup-> popup( event );
233  }
234 }
235 
236 
237 template <class C>
238 bool Wtx::Dbo::TableView<C>::loadLayout( const std::string & name )
239 {
240  return viewDef().load( layoutName(name), C::TableDef(), session() );
241 }
242 
243 
244 template <class C>
245 void Wtx::Dbo::TableView<C>::saveLayout( const std::string & name )
246 {
247  viewDef().save( layoutName(name), session() );
248 }
249 
250 template <class C>
251 const std::string & Wtx::Dbo::TableView<C>::filter() const
252 {
253  return m_filterValue;
254 }
255 
256 template <class C>
258 {
259  Wt::Dbo::Transaction t(*session());
260 
261  auto where = m_filterValue;
262  if( m_subFilterValue != "" )
263  {
264  if( where != "" )
265  {
266  where += " AND ";
267  }
268 
269  where += m_subFilterValue;
270  }
271 
272  auto query =
273  session()-> template find<C>()
274  .where( where )
275  ;
276 
277  model()-> setCountWhere( "WHERE " + where );
278 
279  m_queryRowCount = query.resultList().size();
280 
281  for( auto sortField : viewDef().m_def.sortFields )
282  {
283  query = query.orderBy( sortField );
284  }
285 
286  model()-> setQuery( query, true );
287 
288  setupLayout();
289 
290  setModel( model() );
291 
292 }
293 
294 template <class C>
295 void Wtx::Dbo::TableView<C>::setFilter( const std::string & f )
296 {
297  viewDef().m_def.filter = f;
298  m_filterValue = f;
299 
300  setFilter();
301 
302 } // endvoid Wtx::Dbo::TableView<C>::setFilter( const std::string & f )
303 
304 template <class C>
305 void Wtx::Dbo::TableView<C>::setSearch( const std::string & s )
306 {
307  std::cout << __FILE__ << ":" << __LINE__ << " todo setSearch:" << s << std::endl;
308 
309 } // endvoid Wtx::Dbo::TableView<C>::setFilter( const std::string & f )
310 
311 template <class C>
312 void Wtx::Dbo::TableView<C>::setSubFilter( const std::string & f )
313 {
314  m_subFilterValue = f;
315 
316  setFilter();
317 
318 } // endvoid Wtx::Dbo::TableView<C>::setFilter( const std::string & f )
319 
320 template <class C>
321 const std::string & Wtx::Dbo::TableView<C>::queryValue() const
322 {
323  return m_queryValue;
324 
325 }
326 
327 template <class C>
328 void Wtx::Dbo::TableView<C>::setQuery( const std::string & s )
329 {
330  std::string qry;
331  std::string search = s;
332 
333  qry = viewDef().m_def.filter;
334 
335  /*
336  ** parse the search string to produce an SQL statement
337  ** to attempt to find files.
338  **
339  */
340  if( search != "" )
341  {
351  {
352  std::size_t start_pos = 0;
353  while( (start_pos = search.find("'",start_pos)) != std::string::npos )
354  {
355  search.replace( start_pos, size_t(1), std::string("''") );
356  start_pos += 2;
357  }
358 
359  }
360 
378  if( qry != "" )
379  qry = "\n (" + qry + ") AND ";
380 
381  /*
382  ** see if the search string can be converted to
383  ** an integer and if so search the id number of
384  ** the items
385  **
386  */
387  try
388  {
389  int id = std::stoi(search);
390 
391  qry +=
392  Wt::WString( "(id = {1}) OR " )
393  .arg(id)
394  .toUTF8()
395  ;
396 
397  }
398  catch(...)
399  {
400  }
401 
402  auto searches = Wtx::Core::split( search, ' ' );
403 
404 // std::cout << __FILE__ << ":" << __LINE__ << " " << search << " " << searches.size() << std::endl;
405  bool x = false;
406  for( auto s : searches )
407  {
408 // std::cout << __FILE__ << ":" << __LINE__ << " '" << s << "'" << std::endl;
409 
410  if( x )
411  qry += " AND (";
412  else
413  qry += "(";
414 
415  /*
416  ** the key field is pretty-much guaranteed to be
417  ** a part of the table, but we should check in the
418  ** event this report view is used on a different
419  ** table
420  **
421  */
422  qry +=
423  Wt::WString( "\n (UPPER(\"keyField\") LIKE UPPER('%{1}%'))" )
424  .arg(s)
425  .toUTF8()
426  ;
427 
428  /*
429  ** the cfy field is pretty-much guaranteed to be
430  ** a part of the table, but we should check in the
431  ** event this report view is used on a different
432  ** table
433  **
434  */
435  qry +=
436  Wt::WString( "\n OR (UPPER(\"cfyField\") LIKE UPPER('%{1}%'))" )
437  .arg(s)
438  .toUTF8()
439  ;
440 
441  /*
442  ** the tag field is pretty-much guaranteed to be
443  ** a part of the table, but we should check in the
444  ** event this report view is used on a different
445  ** table
446  **
447  */
448  qry +=
449  Wt::WString( "\n OR (UPPER(\"tag\") LIKE UPPER('%{1}%'))" )
450  .arg(s)
451  .toUTF8()
452  ;
453 
454  /*
455  ** the tag field is pretty-much guaranteed to be
456  ** a part of the table, but we should check in the
457  ** event this report view is used on a different
458  ** table
459  **
460  */
461  qry +=
462  Wt::WString( "\n OR (\"xid\" LIKE '%{1}%')" )
463  .arg(s)
464  .toUTF8()
465  ;
466 
467  /*
468  ** walk through the list of 'searchFields' and apply
469  ** them as additional OR search criteria
470  **
471  */
472  for( auto searchField : viewDef().m_def.searchFields )
473  {
474  qry +=
475  Wt::WString( "\n OR (UPPER(\"{1}\") LIKE UPPER('%{2}%'))" )
476  .arg( searchField )
477  .arg( s )
478  .toUTF8()
479  ;
480  }
481 
483 
484  qry += ")\n";
485 
486  x = true;
487 
488  } // endfor( auto s : searches )
489 
490  if( viewDef().m_def.idin.size() > 0 )
491  {
492  if( viewDef().m_def.idin.at(0).find("id in") != std::string::npos )
493  {
494  auto f =
495  Wt::WString( viewDef().m_def.idin.at(0) )
496  .arg( search )
497  .toUTF8()
498  ;
499 
500  qry +=
501  Wt::WString(" OR ({1}) ")
502  .arg( f )
503  .toUTF8()
504  ;
505  }
506  else
507  {
508  auto idin = Wtx::Core::split( viewDef().m_def.idin.at(0), '_' );
509 
510  if( idin.size() == 3 )
511  {
512  qry +=
513  Wt::WString(" OR \"{1}\" IN ")
514  .arg( viewDef().m_def.idin.at(0) )
515  .toUTF8()
516  ;
517 
518  auto f =
519  Wt::WString("(UPPER(\"keyField\") LIKE UPPER('%{1}%'))" )
520  .arg( search )
521  .toUTF8()
522  ;
523 
524  f += " OR ";
525 
526  f +=
527  Wt::WString("(UPPER(\"cfyField\") LIKE UPPER('%{1}%'))" )
528  .arg( search )
529  .toUTF8()
530  ;
531 
532  qry +=
533  Wt::WString( "(SELECT id FROM \"{1}\" WHERE ({2}))" )
534  .arg( idin.at(1) )
535  .arg( f )
536  .toUTF8()
537  ;
538 
539 
540  } // endif( idin.size() == 3 )
541 
542  }
543 
544  } // endif( viewDef().m_def.idin.size() > 0 )
545 
546 // std::cout << __FILE__ << ":" << __LINE__ << " " << qry << std::endl;
547 
548  } // endif( search != "" )
549 
550  m_queryValue = qry;
551 
552  /*
553  ** if the query string has ~anything~ in it, then
554  ** we need to prepend the WHERE clause
555  **
556  */
557  if( qry != "" )
558  qry = " WHERE (" + qry + ")";
559 
560 // m_model.setCountTable( C::TableName );
561 // m_model.setCountWhere( qry );
562 
563 
564  if( viewDef().hasFlag( "show-sql" ) )
565  std::cout << __FILE__ << ":" << __LINE__ << " " << qry << std::endl;
566 
567  Wt::Dbo::Transaction t(*session());
568 
569  auto query =
570  session()-> template find<C>(qry)
571  ;
572 
573  model()-> setCountWhere( qry );
574 
575  m_queryRowCount = query.resultList().size();
576 
577  for( auto sortField : viewDef().m_def.sortFields )
578  {
579  query = query.orderBy( sortField );
580  }
581 
582  model()-> setQuery( query, true );
583 
584  setupLayout();
585 
586  setModel( model() );
587 
588 } // endvoid Wtx::Dbo::TableView<C>::setQuery( const std::string & s )
589 
590 
591 template <class C>
592 void Wtx::Dbo::TableView<C>::selectItem( Wt::Dbo::ptr<C> item )
593 {
594  auto row = model()-> indexOf( item );
595 
596  auto index = model()-> index( row, 0 );
597 
598  select( index );
599  scrollTo( index );
600 
601 }
602 
603 template <class C>
605 {
606  setRowHeaderCount( viewDef().m_def.rowHeaderCount );
607 
608  if( viewDef().m_def.columnDefs.size() == 0 )
609  {
610  model()-> addAllFieldsAsColumns();
611  }
612  else
613  {
614 
615  if( !colsSet )
616  {
617  int c=0;
618  for( auto columnDef : viewDef().m_def.columnDefs )
619  {
620  model()-> addColumn( columnDef.field );
621 
622  if( columnDef.label != "" )
623  model()-> setHeaderData( c, Wt::Orientation::Horizontal, columnDef.label, Wt::ItemDataRole::Display );
624 
625  if( columnDef.toolTip != "" )
626  model()-> setHeaderData( c, Wt::Orientation::Horizontal, columnDef.toolTip, Wt::ItemDataRole::ToolTip );
627 
628  if( columnDef.delegate )
629  setItemDelegateForColumn( c, std::shared_ptr<Wt::WItemDelegate>( columnDef.delegate( session() ) ) );
630 
631  setColumnAlignment( c, columnDef.alignment );
632 
633  c++;
634  }
635  colsSet = true;
636  }
637  }
638 
639 }
640 
641 template <class C>
643 {
644  setAlternatingRowColors( viewDef().m_def.alternatingRowColors );
645 
646  setSelectionMode( viewDef().m_def.selectionMode );
647 
648  if( std::find( viewDef().m_def.flags.begin(), viewDef().m_def.flags.end(), "nosort" ) != viewDef().m_def.flags.end() )
649  setSortingEnabled( false );
650 
651  int col = 0;
652  for( auto columnDef : viewDef().m_def.columnDefs )
653  setColumnWidth( col++, columnDef.width );
654 
655 }
656 
657 
658 template <class C>
660 {
661  setQuery();
662  setLayout();
663 }
664 
665 template <class C>
667 {
668  auto selectedIndex = *(selectedIndexes().begin());
669 
670  auto indexBeg = model()-> index( selectedIndex.row(), 0 );
671  auto indexEnd = model()-> index( selectedIndex.row(), model()-> columnCount()-1 );
672 
673  model()-> dataChanged().emit( indexBeg, indexEnd );
674 
675  select( selectedIndex );
676  scrollTo( selectedIndex );
677 
678 }
679 
680 template <class C>
681 Wt::Dbo::ptr<C> Wtx::Dbo::TableView<C>::selectedItem()
682 {
683  return item( *(selectedIndexes().begin()) );
684 
685 }
686 
687 
688 
689 
690 
void setQuery(const std::string &search="")
Wtx::Dbo::Session * session()
Current Session.
Table View Definition.
Definition: TableViewDef.h:171
witty extension library
Definition: Activity.h:51
Dbo Table View.
Definition: TableView.h:68