Project

General

Profile

Bug #3975 ยป main.cpp

Will Johnson, 04/10/2015 07:24 PM

 
#include <vector>
#include <string>
#include <iostream>

#include <Wt/WText>
#include <Wt/WLineEdit>
#include <Wt/WApplication>
#include <Wt/WSuggestionPopup>
#include <Wt/WContainerWidget>
#include <Wt/WAbstractItemModel>

#include <boost/thread.hpp>
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace Wt;


#define INLINE_JAVASCRIPT(...) #__VA_ARGS__


class FilterModel : public WAbstractItemModel
{
//FilterModel: minimal class to provide server filtered suggestions for a
// WSuggestionPopup. Uses a limited set of nuclides (ex. Ba133, U235, etc) as
// suggestions.
protected:
std::vector<std::string> m_possibilities;
public:
FilterModel( WObject *parent )
: WAbstractItemModel( parent )
{ }
virtual ~FilterModel()
{ }
virtual WModelIndex index( int row, int column,
const WModelIndex &parent = WModelIndex() ) const
{
const int nrow = static_cast<int>( m_possibilities.size() );
if( parent.isValid() || row < 0 || column != 0 || row >= nrow )
return WModelIndex();
return createIndex( row, column, (void *)0 );
}
virtual WModelIndex parent( const WModelIndex &index ) const
{
return WModelIndex();
}
virtual int rowCount( const WModelIndex &parent = WModelIndex() ) const
{
if( parent.isValid() )
return 0;
return static_cast<int>( m_possibilities.size() );
}
virtual int columnCount( const WModelIndex & parent = WModelIndex() ) const
{
return parent.isValid() ? 0 : 1;
}
virtual boost::any data( const WModelIndex &index, int role = DisplayRole ) const
{
const int row = index.row();
const int nrow = static_cast<int>( m_possibilities.size() );
if( !index.isValid() || row < 0 || index.column() != 0 || row >= nrow )
return boost::any();
return boost::any( WString(m_possibilities[row]) );
}

virtual void filter( const WString &text )
{
static const string nuclides[] =
{ "Ba125", "Ba126", "Ba127", "Ba128", "Ba129", "Ba131", "Ba133", "B10",
"B12", "B14", "B185", "Bi187", "Co60", "U235", "Ir192", "Eu154",
"Na22", "Pu238"
};
const size_t num_nuclides = sizeof(nuclides)/sizeof(nuclides[0]);
const int ninitialrow = rowCount();
if( ninitialrow > 0 )
{
beginRemoveRows( WModelIndex(), 0, ninitialrow-1 );
m_possibilities.clear();
endRemoveRows();
}
std::string simpletxt = text.narrow();
boost::algorithm::to_lower( simpletxt );
vector<string> newpossiblities;
for( size_t i = 0; i < num_nuclides; ++i )
if( boost::algorithm::icontains( nuclides[i], simpletxt ) )
newpossiblities.push_back( nuclides[i] );
const int nrow = static_cast<int>( newpossiblities.size() );
beginInsertRows( WModelIndex(), 0, nrow -1 );
m_possibilities.swap( newpossiblities );
endInsertRows();
}
};


class MinimalWtApp : public WApplication
{
public:
MinimalWtApp(const WEnvironment& env)
: WApplication(env)
{
setTitle("MinimalWtApp");
WText *label = new WText( "Type in server side filtered suggestions of nuclides (ex. Ba133, U235, Co60):", root() );
label->setInline( false );
WLineEdit *edit = new WLineEdit( root() );
WSuggestionPopup::Options opts;
opts.highlightBeginTag = "<b>";
opts.highlightEndTag = "</b>";
opts.listSeparator = ',';
opts.whitespace = " \\n";
opts.wordSeparators = " ";
WSuggestionPopup *suggest = new WSuggestionPopup( opts, root() );
suggest->setMaximumSize( WLength::Auto, WLength(15, WLength::FontEm) );
FilterModel *filterModel = new FilterModel( root() );
filterModel->filter( "" );
suggest->setFilterLength( -1 );
suggest->setModel( filterModel );
suggest->filterModel().connect( filterModel, &FilterModel::filter );
suggest->forEdit( edit, WSuggestionPopup::Editing ); // | WSuggestionPopup::DropDownIcon
/*
//Hack to catch exception JS caused by WSuggestionPopup refilter, so this
// way the whole (client side) app doesnt crash.
//If you define your own matcher javascript, you have to check to make sure
// the edit passed into your function is valid to.
string js = INLINE_JAVASCRIPT(
var addTryCatch = function( elid )
{
var dofix = function(elid){
var el = Wt.WT.getElement(elid);
var self = el ? jQuery.data(el, 'obj') : null;
if( !self ){
//Apparently not immediately available even though suggest should be
// in the DOM by the time this JS gets executed, not quit sure...
// but this works.
setTimeout( function(){dofix(elid);}, 100 );
return;
}
var oldfcn = self.refilter;
self.refilter = function(value){ try{ oldfcn(value); }catch(e){ console.log('My refilter caught: ' + e ); } };
};
dofix(elid);
}; );
suggest->doJavaScript( js + " addTryCatch('" + suggest->id() + "');" );
*/
label = new WText( "<br />If you type in a nuclide (ex Ba133) and quickly hit"
" enter, you will (sometimes) get a JS exception saying "
"\"Cannot read property 'value' of null\"", root() );
label->setInline( false );
}//MinimalWtApp constructor
virtual ~MinimalWtApp()
{
}

protected:
};//class MinimalWtApp


WApplication *createApplication(const WEnvironment& env)
{
return new MinimalWtApp(env);
}

int main(int argc, char **argv)
{
cout << "WT_VERSION=" << std::hex << WT_VERSION << endl;
return WRun(argc, argv, &createApplication);
}

    (1-1/1)