Wtx ~ Wt Extension Library
WtxLib
FieldDefLookupCombo.cpp
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 
46 #include <Wt/WAbstractItemModel.h>
47 #include <Wt/WComboBox.h>
48 
49 #include <Wtx/Core/Core.h>
50 #include <Wtx/Util/Util.h>
51 #include <Wtx/Dbo/TableDef.h>
52 
53 #include "FieldDefLookupCombo.h"
54 
56 : public Wt::WComboBox
57 {
58  public:
59 
60  SmartComboEdit( int sid, std::shared_ptr<Wt::WAbstractItemModel> (*getModel)(int sid, int tid, const std::string & filter, Wtx::Dbo::Session & session), Wtx::Dbo::Session & s )
61  : m_session(s),
62  m_sourceID(sid),
63  m_getModel(getModel)
64  {
65  setNoSelectionEnabled(true);
66  changed().connect( this, &SmartComboEdit::on_changed );
67  focussed().connect( this, &SmartComboEdit::on_focussed );
68 
69  } // endSmartLineEdit( std::shared_ptr<Wt::WAbstractItemModel> model, Wtx::Dbo::Session & s )
70 
71  /*
72  ** this returns the ID value of the string
73  **
74  */
75  int get_id( const std::string & value )
76  {
77  if( m_model )
78  {
79  for( int i=0; i < m_model-> rowCount(); i++ )
80  {
81  auto id = Wt::asNumber(m_model-> index( i, 0 ).data());
82  auto ky = Wt::asString(m_model-> index( i, 1 ).data()).toUTF8();
83 
84  if( value == ky )
85  {
86  return id;
87  }
88 
89  }
90  }
91 
92  return -1;
93  }
94 
95  /*
96  ** this returns the string value of the ID
97  **
98  */
99  std::string get_string( int index )
100  {
101  if( m_model && index > -1 )
102  {
103  for( int i=0; i < m_model-> rowCount(); i++ )
104  {
105  auto id = Wt::asNumber(m_model-> index( i, 0 ).data());
106  auto ky = Wt::asString(m_model-> index( i, 1 ).data()).toUTF8();
107 
108  if( index == id )
109  {
110  return ky;
111  }
112 
113  }
114 
115  }
116 
117  return "";
118  }
119 
120  /*
121  ** this is kind of crummy. this is supposed to load
122  ** the model, but if an .id. value is specified then
123  ** its supposed to only load that id. but if no .id.
124  ** is specified (id==-1) then this is supposed to
125  ** load the _whole_ model. The idea being, it should
126  ** not load the model until it's absolutely necessary.
127  ** the concept is that we only need to load one item
128  ** out of the model if we're just loading the widget.
129  ** we only need 1 item to get the widget loaded, to
130  ** convert the id number in to a string-value. but
131  ** if the user never selects this control, then there's
132  ** no reason to load ALL the data, it just slows down
133  ** the user interface. this is my best attempt at
134  ** lazy-loading.
135  **
136  */
137  void loadModel( int id )
138  {
139  if( !m_loaded && m_getModel )
140  {
141  setNoSelectionEnabled(true);
142  m_model = m_getModel( m_sourceID, id, "", m_session );
143  setModel( m_model );
144  setModelColumn(1);
145 
146  if( id == -1 )
147  m_loaded = true;
148 
149 #ifdef NEVER
150  std::cout << __FILE__ << ":" << __LINE__
151  << " Loading Model: " << id
152  << " loaded: " << m_loaded
153  << " " << m_sourceID << " " << m_targetID
154  << std::endl;
155 #endif
156  }
157  }
158 
159  void on_focussed()
160  {
161  loadModel(-1);
162  refresh();
163 
164 // for( int i=0; i< count(); i++ )
165 // if( itemText(i) == m_valueText )
166 // setCurrentIndex(i);
167 
168  setValueText( m_valueText );
169 
170  }
171 
172 #ifndef NEVER
173  /*
174  ** this fires when the widget looses focus and the value in it
175  ** is different than from when it started
176  **
177  */
178  void on_changed()
179  {
180  auto value = Wt::WComboBox::valueText().toUTF8();
181 
182  if( value == "" )
183  {
184  m_targetID = -1;
185  m_valueText = "";
186  return;
187  }
188 
189  m_targetID = get_id( value );
190  m_valueText = value;
191 
192 #ifdef NEVER
193  auto dialog = addChild( std::make_unique<Wt::WDialog>() );
194  dialog-> rejectWhenEscapePressed();
195  dialog-> contents()-> addNew<Wt::WText>("cannot put in false data");
196  dialog-> show();
197 #endif
198 
199  } // endvoid on_changed()
200 #endif
201 
202 
203  Wt::WString valueText() const
204  {
205  auto retVal = Wt::WString("[null]");
206 
207  if( m_targetID != -1 )
208  retVal = Wt::WString("{1}: {2}]").arg( m_table ).arg( m_targetID );
209 
210 // std::cout << __FILE__ << ":" << __LINE__ << " " << m_field << " " << retVal << std::endl;
211 
212  return retVal;
213  }
214 
215  void setValueText( const Wt::WString & value )
216  {
217  m_valueText = value.toUTF8();
218 
219  /*
220  ** if the value text is nothing, then wipe
221  ** it so that nothing shows.
222  **
223  */
224  if( m_valueText == "[null]" )
225  m_valueText = "";
226 
227  else
228  {
229  if( m_valueText.find(":") != std::string::npos )
230  {
231  auto v = Wtx::Core::split( m_valueText, ':' );
232  m_table = v.at(0);
233  m_targetID = std::stoi(v.at(1));
234  loadModel(m_targetID);
235  m_valueText = get_string( m_targetID );
236  }
237 
238  }
239 
240 #ifdef NEVER
241  std::cout << __FILE__ << ":" << __LINE__
242  << "\n loaded: " << m_loaded
243  << "\n table: " << m_table
244  << "\n value: " << value
245  << "\n valueText:" << m_valueText
246  << std::endl
247  ;
248 #endif
249 
250  Wt::WComboBox::setValueText( m_valueText );
251 
252  } // endvoid setValueText( const Wt::WString & value )
253 
254  std::shared_ptr<Wt::WAbstractItemModel> (*m_getModel)(int sid, int tid, const std::string & filter, Wtx::Dbo::Session & session) = nullptr;
255  bool m_loaded = false;
256  std::string m_field;
257  std::string m_table;
258  int m_sourceID = -1;
259  int m_targetID = -1;
260  std::string m_valueText;
261  Wtx::Dbo::Session & m_session;
262  std::shared_ptr<Wt::WAbstractItemModel> m_model;
263 
264 }; // endclass SmartComboEdit
265 
267 (
268  TableDef & td,
269  const char * fn,
270  int w,
271  int h,
272  Flags f,
273  std::string lb,
274  std::string ph,
275  std::string inf,
276  std::string tt,
277  int ht
278 )
279 : Wtx::Dbo::FieldDefLookupBase( td, fn, w, w, f, lb, ph, inf, tt, ht )
280 {
281 }
282 
284 (
285  TableDef & td,
286  const char * fn,
287  std::string lb,
288  std::string ph,
289  std::string inf,
290  std::string tt,
291  int ht
292 )
293 : Wtx::Dbo::FieldDefLookupBase( td, fn, lb, ph, inf, tt, ht )
294 {
295 }
296 
297 
298 std::unique_ptr<Wt::WWidget> Wtx::Dbo::FieldDefLookupCombo::createEditWidget( int sid, Wtx::Dbo::Session & session ) const
299 {
300  auto retVal = std::make_unique< SmartComboEdit >( sid, getLookupModel, session );
301  retVal-> m_table = "[" + targetTable;
302  retVal-> m_field = fieldName();
303 
304  if( !m_lazyLoad )
305  retVal-> on_focussed();
306 
307  return retVal;
308 
309 
310 }
311 
312 
Table Definition.
Definition: TableDef.h:72
FieldDefLookupCombo(TableDef &td, const char *fn, int w=-1, int h=-1, Flags f=Flags::None, std::string lb="", std::string ph="", std::string inf="", std::string tt="", int ht=-1)
ctor
Flags
Field Definition Flags.
Definition: FieldDefBase.h:101