Column in gwt celltable doesn't sort - sorting

I want to add sorting for column in celltable with help of ListHandler. But it doesn't sort. I don't understand why it doesn't work. My code is based on GWT tutorial.
Please suggest me something.
Contract.java
public class Contract implements Serializable {
private int contId;
private String contOrgName;
//getters and setters...
}
Main.java
TextColumn<Contract> orgNameColumn = new TextColumn<Contract>() {
#Override
public String getValue(Contract contract) {
return contract.getcontOrgName();
}};
orgNameColumn.setSortable(true);
CellTable<Contract> tableContract = new CellTable<Contract>();
tableContract.addColumn(orgNameColumn, "OrgName");
ListDataProvider<Contract> contractDataProvider = new ListDataProvider<Contract>();
contractDataProvider.addDataDisplay(tableContract);
GetContractsServiceAsync getContractsService = GWT.create(GetContractsService.class);
getContractsService.getContracts(new AsyncCallback<List<Contract>>() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
}
public void onSuccess(List<Contract> result) {
contractDataProvider.getList().clear();
contractDataProvider.getList().addAll(result);
ListHandler<Contract> columnSortHandler = new ListHandler<Contract>(result);
columnSortHandler.setComparator(orgNameColumn, new Comparator<Contract>() {
public int compare(Contract o1, Contract o2) {
if (o1 == o2) {
return 0;
}
if (o1 != null) {
return (o2 != null) ? o1.getcontOrgName().compareTo(o2.getcontOrgName()) : 1;
}
return -1;
}
});
tableContract.addColumnSortHandler(columnSortHandler);
table.getColumnSortList().push(orgNameColumn);
}
});

Hey I was also facing the same issue a long back..Then I got to know that the object reference id is different than the one I have added into table. Once i got the reason it was very easy to find the solution.
Also please register your ListHandler before adding column to CellTable.
Note the edit for your comment :
There is nothing wrong with the comparator. The problem is still same. It reflects the wrong the object in comparator compared to in CellTable.
Please try replace the code as below :
contractDataProvider.getList().addAll(result);
ListHandler<Contract> columnSortHandler = new ListHandler<Contract>(contractDataProvider.getList());

Try to move the creation of your columnSortHandler out of the onSuccess Method. Place it right after you created your column.
At the moment you are adding the results before you add the columnSortHandler. I think that is the wrong order.

i my case, i did my sorting like this:
private void sortColumn( List<CModel> list ) {
int count = listOfColumns.size(); //upon adding the columns, i have created a list that will hold all the columns
if ( list.size() <= 0 ) {
for ( int i = 0; i < count; i++ ) {
listOfColumns.get(i).setSortable( false );
}
} else {
for ( int i = 0; i < count; i++ ) {
sort( i );
dg.redrawHeaders();
}
}
}
private void sort(int i) {
String[] listColHead = { /** list of column headers */ };
Column<CModel,?> column = listCheckoutColumns.get( i );
final String valueToCompare = listColHead[i];
final ListDataProvider<CModel> dataProvider = new ListDataProvider<CModel>();
// Connect the table to the data provider
dataProvider.addDataDisplay( dg );
// Add the data to the data provider, which automatically pushes it to the widget
List<CModel> list = dataProvider.getList();
for ( CModel product : listCheckout ) {
list.add( product );
}
column.setSortable( true );
// Add a ColumnSortEvent.ListHandler to connect sorting to the List
ListHandler<CModel> columnSortHandler = new ListHandler<CModel>( list );
columnSortHandler.setComparator( column, new Comparator<CModel>() {
public int compare( CModel p1, CModel p2 ) {
if ( p1 == p2 ) {
return 0;
}
// Compare the columns.
if ( p1 != null ) {
if ( valueToCompare.equals( "code" ) ) {
return ( p2 != null ) ? p1.getFproductid().compareTo( p2.getFproductid() ) : 1;
}
else if ( valueToCompare.equals( "desc" ) ) {
return ( p2 != null ) ? p1.getFproduct_name().compareTo( p2.getFproduct_name() ) : 1;
}
else if ( valueToCompare.equals( "type" ) ) {
return ( p2 != null ) ?
uec.computeTypeLabel( p1 ).compareTo( uec.computeTypeLabel( p2 ) ) : 1;
}
else if ( valueToCompare.equals( "maxex" ) ) {
return ( p2 != null ) ? uec.exQtyLabel( p1 ).compareTo( uec.exQtyLabel( p2 ) ) : 1;
}
else if ( valueToCompare.equals( "unit" ) ) {
return ( p2 != null ) ? p1.getFuom().compareTo( p2.getFuom() ) : 1;
}
else if ( valueToCompare.equals( "status" ) ) {
return ( p2 != null ) ? uec.qtyLabel( p1 ).compareTo( uec.qtyLabel( p2 ) ) : 1;
}
else if ( valueToCompare.equals( "qty" ) ) {
return ( p2 != null ) ? Double.compare( p1.getFqty(), p2.getFqty() ) : 1;
}
else if ( valueToCompare.equals( "price" ) ) {
return ( p2 != null ) ? uec.extPriceLabel( p1 ).compareTo( uec.extPriceLabel( p2 ) ) : 1;
}
else if ( valueToCompare.equals( "total" ) ) {
return ( p2 != null ) ? Double.compare( p1.getFtotal_line(), p2.getFtotal_line() ) : 1;
}
}
return -1;
}
});
dg.addColumnSortHandler( columnSortHandler );
dg.getColumnSortList().push( column );
}
everytime, i'll set the data for my DataGrid list,
dgCheckout.redraw();
dgCheckout.setRowCount( lengthOfList, true );
dgCheckout.setRowData( 0, newList );
sortColumn( newList );

Related

How do I correct an error code 0 in MQL4 OrderModify() call?

I have this code below which I am using to test trailing stop function. It works on some currency pairs and doesn't work in others. It's returning error code 0 (zero). I will be grateful if somebody can help me out
void modifyTrade() {
TrailingStop = MarketInfo(Symbol(), MODE_STOPLEVEL);
if(TrailingStop>0)
{
for(int z = 0; z<OrdersTotal(); z++)
{
OrderSelect(z,SELECT_BY_POS);
if(Bid-OrderOpenPrice()>Point*TrailingStop)
{
if(OrderStopLoss()<Bid-Point*TrailingStop)
{
bool res=OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(Bid-Point*TrailingStop,Digits),OrderTakeProfit(),0,Blue);
if(!res) {
Print("Error in OrderModify. Error code=",GetLastError());
//if(Symbol()=="EURNZD")
Alert("Error in OrderModify. Error code=",GetLastError()," ; ",OrderSymbol());
}
else {
Print("Order modified successfully.");
}
}
}
}
}
}
Error being
0 == ERR_NO_ERROR ... No error returned
is rather ok, no need to "correct" it, it means there was nothing to actually improve.
There are a few risky points to mention - prices move, STOPLEVEL parameter can either ( be careful on this - a hostile case if appears in live-trading ) and also be informed, that there are other levels, that may prohibit an OrderModify()-call from being Broker-T&C-compliant (and will get rejected for that reason)
Somehow improved code may work in this sense :
void modifyTrade()
{
TrailingStop = MarketInfo( Symbol(), MODE_STOPLEVEL );
if ( TrailingStop > 0 )
{
for ( int z = 0; z < OrdersTotal(); z++ )
{
if !OrderSelect( z, SELECT_BY_POS ) continue;
// ______________________________________________________ CRITICAL
RefreshRates();
// ______________________________________________________ Bid + Ask valid...
if ( TrailingStop != MarketInfo( OrderSymbol(), MODE_STOPLEVEL ) )
{ // TrailingStop CHANGED ... LOG, renegotiate such Broker policy
TrailingStop = MarketInfo( OrderSymbol(), MODE_STOPLEVEL
}
// ______________________________________________________ STOPLEVEL valid...
if ( Bid - OrderOpenPrice() > Point * TrailingStop
&& OrderType() == OP_BUY )
{
if ( OrderStopLoss() < Bid - Point * TrailingStop )
{
bool res = OrderModify( OrderTicket(),
OrderOpenPrice(),
NormalizeDouble( Bid - Point * TrailingStop, Digits ),
OrderTakeProfit(),
0,
Blue
);
if ( !res )
{
Print( "Error in OrderModify. Error code=", _LastError );
// if ( Symbol() == "EURNZD" )
Alert( "Error in OrderModify. Error code=", _LastError, " ; ", OrderSymbol() );
}
else
{
Print( "Order modified successfully." );
}
}
}
if ( OrderOpenPrice() - Ask > Point * TrailingStop
&& OrderType() == OP_SELL )
{
...
}
}
}
}
There are a couple of errors in your code.
once called, GetLastError() is reset. If you are both printing and alerting the last error, you should store the error code prior to printing/alerting.
you should check OrderSelect() succeeds.
you should iterate over orders in the opposite direction to ensure your code carried on operating should an order be closed mid-check.
You require different code for longs and shorts
Your code is prone to errors simply because you have no buffer and are trying to trail price at the minimum stop level. By the time your order modification is received by the trading server it is highly likely price may have moved back inside the stop level area resulting in a modification error.
void modifyTrade()
{
TrailingStop = MarketInfo(Symbol(), MODE_STOPLEVEL);
if(TrailingStop>0)
{
for(int z=OrdersTotal()-1; z>=0; z--)
{
if(OrderSelect(z,SELECT_BY_POS))
{
if(OrderType()==OP_BUY)
{
if(Bid-OrderStopLoss()>TrailingStop*point)
{
bool res=OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(Bid-Point*TrailingStop,Digits),OrderTakeProfit(),0,Blue);
if(!res)
{
int err=GetLastError();
Print("Error in OrderModify. Error code=",err);
Alert("Error in OrderModify. Error code=",err);
}
else Print("Order modified successfully.");
}
}
if(OrderType()==OP_SELL)
{
if(OrderStopLoss()-Ask>TrailingStop*point)
{
bool res=OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(Ask+Point*TrailingStop,Digits),OrderTakeProfit(),0,Blue);
if(!res)
{
int err=GetLastError();
Print("Error in OrderModify. Error code=",err);
Alert("Error in OrderModify. Error code=",err);
}
else Print("Order modified successfully.");
}
}
}
}
}
}

How to change color of each controlP5 dropdown list entry individually?

Using the following MWE:
import controlP5.*;
import java.util.*;
ControlP5 cp5;
void setup() {
size(400, 400);
cp5 = new ControlP5(this);
List l = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h");
/* add a ScrollableList, by default it behaves like a DropdownList */
cp5.addScrollableList("dropdown")
.setPosition(100, 100)
.setSize(200, 100)
.setBarHeight(20)
.setItemHeight(20)
.addItems(l)
// .setType(ScrollableList.LIST) // currently supported DROPDOWN and LIST
;
}
void draw() {
background(240);
}
How can I change the font color of each list entry separately? I assume I'll have to use a for loop of some kind like the following
for (int i =0; i < myarray.length; i++){
dropdown.setColorActive(elementDetermine(myarray[i]));
}
Where elementDetermine() takes an integer and returns a color. Unfortunately, when I run this loop in either the setup or the draw function, the dropdown list doesn't change without error message.
Unfortunately there's no easy readily available method to change the font color of each list entry separately.
As you can see in the documentation the available methods access the main caption which applies to all items.
In fact, the same Label component is re-used accross all list items and simply re-rendered once per item (changing current text/colours) as you can see in the source code
If you really really need to change the font color you can, but that will be quite a few OOP hoops to jump through (since there is no array of Label instances per item):
you'd need to make a custom ControllerView< ScrollableList > to override it's display() method
for the custom display() to work the same as the original ScrollableList you need to pretty much replicate the super class
the ScrollableList super class has a bunch of private properties that can easily be accessed from the ScrollableListView class since it's part of ScrollableList, however in our case all those private / protected properties that need to be accessed in display() need to be accessible. To do this a ScrollableList subclass is implemenented (PopUpScrollableList) which mainly replicates it's superclass behaviours wherever those private/protected properties are used in display() and also makes them available.
Finally the custom scrollable list can have a color[] which can store the custom colours so they can be accessed and rendered in the overriden display() method:
import controlP5.*;
// used by the custom scrollable list view
import static controlP5.ControlP5.b;
import java.util.*;
ControlP5 cp5;
void setup() {
size(400, 400);
cp5 = new ControlP5(this);
List l = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h");
/* add a custom ScrollableList, by default it behaves like a DropdownList */
PopUpScrollableList dropdown = addPopUpScrollableList("dropdown");
dropdown.setPosition(100, 100)
.setSize(200, 100)
.setBarHeight(20)
.setItemHeight(20)
.addItems(l)
// .setType(ScrollableList.LIST) // currently supported DROPDOWN and LIST
;
// a list of (random) colourr: a colour per item
color[] textColors = new color[l.size()];
for(int i = 0 ; i < textColors.length; i++){
textColors[i] = color(255, random(255), random(255), random(255));
}
// set custom text colours: this is a bit hacky: normally you'd check if items.size() matches textColors.length, etc.
dropdown.textColors = textColors;
// set a custom view for the list
dropdown.setView(makeCustomScrollListView());
}
void draw() {
background(240);
}
// simply adds our custom scrollable list
PopUpScrollableList addPopUpScrollableList( final String theName ) {
PopUpScrollableList myController = new PopUpScrollableList(cp5, theName);
return myController;
}
ControllerView< ScrollableList > makeCustomScrollListView(){
// make an custom scrollable list view on the fly and access the fileds it needs
return new ControllerView< ScrollableList >() {
// tweaked version of https://github.com/sojamo/controlp5/blob/1f7cb649865eb8657495b5cfeddd0dbe85d70cac/src/controlP5/ScrollableList.java#L391
public void display( PGraphics g , ScrollableList c ) {
// setHeight( -200 ); /* UP */
PopUpScrollableList d = (PopUpScrollableList)c;
g.noStroke( );
if ( c.isBarVisible( ) ) {
boolean b = d.itemHover() == -1 && d.isInside() && !d.isDragged();
g.fill( b ? c.getColor( ).getForeground( ) : c.getColor( ).getBackground( ) );
g.rect( 0 , 0 , c.getWidth( ) , c.getBarHeight() );
g.pushMatrix( );
g.translate( c.getWidth( ) - 8 , c.getBarHeight() / 2 - 2 );
g.fill( c.getColor( ).getCaptionLabel( ) );
if ( c.isOpen( ) ) {
g.triangle( -3 , 0 , 3 , 0 , 0 , 3 );
} else {
g.triangle( -3 , 3 , 3 , 3 , 0 , 0 );
}
g.popMatrix( );
c.getCaptionLabel( ).draw( g , 4 , c.getBarHeight() / 2 );
}
if ( c.isOpen( ) ) {
int bar = ( c.isBarVisible( ) ? c.getBarHeight() : 0 );
int h = ( ( d.updateHeight( ) ) );
g.pushMatrix( );
// g.translate( 0 , - ( h + bar +
// c.itemSpacing ) ); /* UP */
g.fill( c.getBackgroundColor( ) );
g.rect( 0 , bar , c.getWidth( ) , h );
g.pushMatrix( );
g.translate( 0 , ( bar == 0 ? 0 : ( c.getBarHeight() + d.itemSpacing() ) ) );
/* draw visible items */
c.updateItemIndexOffset( );
int m0 = d.itemIndexOffset;
List items = c.getItems();
int m1 = items.size( ) > d.itemRange() ? ( d.itemIndexOffset + d.itemRange() ) : items.size( );
for ( int i = m0 ; i < m1 ; i++ ) {
Map< String , Object > item = (Map< String , Object >) items.get( i );
CColor itemColor = ( CColor ) item.get( "color" );
g.fill( ( b( item.get( "state" ) ) ) ? itemColor.getActive( ) : ( i == d.itemHover() ) ? ( c.isMousePressed() ? itemColor.getActive( ) : itemColor.getForeground( ) ) : itemColor.getBackground( ) );
float boxY = d.itemHeight() - 1;
g.rect( 0 , 0 , c.getWidth( ) , boxY );
Label label = c.getValueLabel( );
// finally set custom text colour
if(d.textColors != null){
label.setColor(d.textColors[i]);
}
label.set( item.get( "text" ).toString( ) ).draw( g , 4 , d.itemHeight() / 2 );
g.translate( 0 , d.itemHeight() );
}
g.popMatrix( );
if ( c.isInside() ) {
int m = items.size( ) - d.itemRange();
if ( m > 0 ) {
g.fill( c.getColor( ).getCaptionLabel( ) );
g.pushMatrix( );
int s = 4; /* spacing */
int s2 = s / 2;
g.translate( c.getWidth( ) - s , c.getBarHeight() );
int len = ( int ) PApplet.map( ( float ) Math.log( m * 10 ) , 0 , 10 , h , 0 );
int pos = ( int ) ( PApplet.map( d.itemIndexOffset , 0 , m , s2 , h - len - s2 ) );
g.rect( 0 , pos , s2 , len );
g.popMatrix( );
}
}
g.popMatrix( );
}
}
};
}
// a custom ScrollableList subclass: mainly it needs to expose properties the custom view (via setView()) can't access in display()
class PopUpScrollableList extends ScrollableList{
private int itemIndexOffset = 0;
private int _myType = DROPDOWN;
protected boolean isOpen = true;
public color[] textColors;
PopUpScrollableList(ControlP5 cp5, String name){
super(cp5, name);
println("custom PopUpScrollableList named " + name + " constructed");
}
public boolean isOpen( ) {
return isOpen;
}
public ScrollableList open( ) {
return setOpen( true );
}
public ScrollableList close( ) {
return setOpen( false );
}
public ScrollableList setOpen( boolean b ) {
isOpen = b;
return this;
}
public int itemHover(){
return itemHover;
}
public int itemSpacing(){
return 1;
}
public int itemRange(){
return itemRange;
}
public int itemHeight(){
return itemHeight;
}
public boolean isInside(){
return isInside;
}
public boolean isDragged(){
return isDragged;
}
public int barHeight(){
return barHeight;
}
protected int updateHeight( ) {
itemRange = ( PApplet.abs( getHeight( ) ) - ( isBarVisible( ) ? barHeight : 0 ) ) / itemHeight;
return itemHeight * ( items.size( ) < itemRange ? items.size( ) : itemRange );
}
public List< Map< String , Object > > items(){
return items;
}
#Override protected void onRelease( ) {
if ( !isDragged ) {
if ( getPointer( ).y( ) >= 0 && getPointer( ).y( ) <= barHeight ) {
setOpen( !isOpen( ) );
} else if ( isOpen ) {
double n = Math.floor( ( getPointer( ).y( ) - barHeight ) / itemHeight );
// n += itemRange; /* UP */
int index = ( int ) n + itemIndexOffset;
updateIndex( index );
}
}
}
private void updateIndex( int theIndex ) {
if ( theIndex >= items.size( ) ) {
return;
}
Map m = items.get( theIndex );
switch ( _myType ) {
case ( LIST ):
super.setValue( theIndex );
for ( Object o : items ) {
( ( Map ) o ).put( "state" , false );
}
m.put( "state" , !ControlP5.b( m.get( "state" ) ) );
break;
case ( DROPDOWN ):
super.setValue( theIndex );
setOpen( false );
getCaptionLabel( ).setText( ( m.get( "text" ).toString( ) ) );
break;
case ( CHECKBOX ):
m.put( "state" , !ControlP5.b( m.get( "state" ) ) );
break;
}
}
public ScrollableList setValue( float theValue ) {
updateIndex( ( int ) ( theValue ) );
return this;
}
#Override protected void onDrag( ) {
scroll( getPointer( ).dy( ) );
}
#Override protected void onScroll( int theValue ) {
scroll( theValue );
}
private void scroll( int theValue ) {
if ( isOpen() ) {
itemIndexOffset += theValue;
itemIndexOffset = ( int ) ( Math.floor( Math.max( 0 , Math.min( itemIndexOffset , items.size( ) - itemRange ) ) ) );
itemHover = -2;
}
}
#Override protected void onLeave( ) {
itemHover = -1;
}
#Override protected void onEnter( ) {
updateHover( );
}
#Override protected void onMove( ) {
updateHover( );
}
#Override protected void onEndDrag( ) {
updateHover( );
}
private void updateHover( ) {
if ( getPointer( ).y( ) > barHeight ) {
double n = Math.floor( ( getPointer( ).y( ) - barHeight ) / itemHeight );
itemHover = ( int ) ( itemIndexOffset + n );
} else {
itemHover = -1;
}
}
public void updateItemIndexOffset( ) {
int m1 = items.size( ) > itemRange ? ( itemIndexOffset + itemRange ) : items.size( );
int n = ( m1 - items.size( ) );
if ( n >= 0 ) {
itemIndexOffset -= n;
}
}
}

How to simply print both variables' names & values in MQL4?

I hope to write a function PrintVars() that is able to print the variables altogether with their names. e.g.:
int var1 = 1;
bool var2 = True;
int var3 = 2;
PrintVars( var1, var2, var3 );
The expected output to the console is:
var1=1
var2=true
var3=2
The difficulty here is to
Get the variable name;
passing parameters of various types to the function.
Is there a way to achieve 1 and 2?
Neither 1) nor 2)
as MQL4 is a strong typed, compiled language.
Other possibilities to escape from this language syntax constraint ?
One may design a middle-ware tool for doing this, either locally, inside MQL4 or externally, via a messaging based distributed system ( having a remote terminal window ).
MQL4-based polymorphism is somewhat easier with class-based calling interface, while the efforts would be immense if such module ought be elaborated for some production grade deployment.
Somewhat clumsy sketch of the approach follows:
- create your vars as a properly configured polymorphic instance of aNamedVARIABLE class
- create a printing function, receiving a long list ( or a placeholder ( string &NameValueARRAY[] ) for a string array[][2]; initialised with "" and pre-filled with Name-Value pairs by .getName2PRINT(), resp. .getValue2PRINT() public methods ) of string variables to print, unless they are left as just initialised == ""
string printFun( const string N1 = "",
const string V1 = "",
const string N2 = "",
const string V2 = "",
...
..
.
){ string aPrintSTRING = "";
aPrintSTRING += ( ( N1 != "" ) ? ( N1 + " = " + V1 ) : "" );
aPrintSTRING += ( ( N2 != "" ) ? ( N2 + " = " + V2 ) : "" );
aPrintSTRING += ( ( N3 != "" ) ? ( N3 + " = " + V3 ) : "" );
...
..
.
return( aPrintSTRING );
}
...
..
.
print( printFun( aNamedVAR1.getName2PRINT(), aNamedVAR1.getValue2PRINT(),
aNamedVAR2.getName2PRINT(), aNamedVAR2.getValue2PRINT(),
aNamedVAR3.getName2PRINT(), aNamedVAR3.getValue2PRINT(),
aNamedVAR4.getName2PRINT(), aNamedVAR4.getValue2PRINT()
)
);
class aNamedVARIABLE{
private:
string aNameAsSTRING = "";
bool aValueAsBOOL = False;
bool aValueAsBOOL_[] = {};
int aValueAsINT = EMPTY_VALUE;
int aValueAsINT_[] = {};
string aValueAsSTR = "";
string aValueAsSTR_[] = {};
...
..
.
isBoolean = False;
isInteger = False;
isShort = False;
isUint = False;
isUchar = False;
isChar = False;
isString = False;
isDouble = False;
isDatetime = False;
isColor = False;
isClass = False;
isEnum = False;
isStruct = False;
isBooleanArr = False;
isIntegerArr = False;
isUintArr = False;
isShortArr = False;
isUintArr = False;
isUcharArr = False;
isDoubleArr = False;
isDatetimeArr = False;
isColorArr = False;
public:
aNamedVARIABLE() {}; // default constructor
aNamedVARIABLE( const string aName,
const bool aBool ){ aNamedVARIABLE::setBool( aBool );
aNamedVARIABLE::setName( aName );
}
aNamedVARIABLE( const string aName,
const int anInt ){ aNamedVARIABLE::setInt( anInt );
aNamedVARIABLE::setName( aName );
}
...
..
.
getName2PRINT() { return( this.aNameAsSTRING );
}
getValue2PRINT() { if ( this.isBoolean ) return( this.aValueAsBOOL ? "True" : "False" );
if ( this.isInteger ) return( str( this.aValueAsINT ) );
...
..
.
}
}

assign lambda to a variable and call it later

It might be a duplicate question, but I couldn't find it, probably due to probably lacking terminology.
Here is the problem: I would like to assign a lambda function to a variable that would be called later on.
class MyClass
{
public:
MyClass( QWdiget* widget );
void doSomething();
private:
QWidget* my_widget;
std::function<QString()> my_text;
}
MyClass::MyClass( QWdiget* widget )
: my_text( [=](){return QString();} )
{
if ( qobject_cast<QLabel*>( widget ) )
{
my_text = [=](){return my_widget ? qobject_cast<QLabel*>( my_widget )->text() : Qstring(); };
}
else if ( qobject_cast<QGroupBox*>( widget ) )
{
my_text = [=](){return my_widget ? qobject_cast<QGroupBox*>( my_widget )->title() : QString(); };
}
else
{
return;
}
my_widget = widget;
}
MyClass::DoSomething()
{
QString str = my_text();
....whatever
}
I am getting a crash and can't find out.
Edit:
Implementing correctly the default value partially solved the issue.
Now, qobject_cast crashes.
Add default implementation like this:
if ( qobject_cast<QLabel*>( widget ) )
{
my_text = [=](){return qobject_cast<QLabel*>( my_wdiget )->text(); };
}
else if ( qobject_cast<QGroupBox*>( widget ) )
{
my_text = [=](){return qobject_cast<QGroupBox*>( my_wdiget )->title(); };
}
else
{
my_text = [=](){ return QString(); };
}

LINQ lambda syntax for SQL subquery + count(distinct on one column)

How would I write the following SQL query in lambda-notation LINQ?
select 'myString', count(distinct val)
from myChildTable
where mytable_id in (
select id
from myTable
where col1_int = 6
and col2_int between 1 and 366
and col3_str = 'myString'
)
For reference, the two tables in question are:
create table myTable (
id int primary key identity,
col1_int int not null,
col2_int int not null,
col3_str varchar(1024)
)
create table myChildTable (
id int primary key identity,
mytable_id int not null foreign key references myTable(id),
val varbinary(13) not null
)
This could possibly be shortened but I find it easier to read if broken up:
// list ids from table
var ids = myTable.Where(x => x.Col1Int == 6 && x.Col2Int >= 1 && x.Col2Int <= 366 && x.Col3Str == "myString").Select(x => x.Id).ToList();
// use in subquery for values (non-distinct)
var vals = myChildTable.Where(x => ids.Contains(x.Id)).Select(x => x.Val).ToList();
// project to distinct dictionary of value, count
var dict = vals.Distinct().ToDictionary(x => x, x => vals.Count(y => y == x));
This seems to work using classes like these:
class ParentEntity
{
public int Id { get; set; }
public int Col1Int { get; set; }
public int Col2Int { get; set; }
public string Col3Str { get; set; }
public ParentEntity(int id, int col1Int, int col2Int, string col3Str)
{
Id = id;
Col1Int = col1Int;
Col2Int = col2Int;
Col3Str = col3Str;
}
}
class ChildEntity
{
public int Id { get; set; }
public int ParentEntityId { get; set; }
public string Val { get; set; }
public ChildEntity(int id, int parentEntityId, string val)
{
Id = id;
ParentEntityId = parentEntityId;
Val = val;
}
}
This query should to it:
from c in MyChildTables
where MyTables.Any (mt => mt.Col1_int == 6 && mt.Col2_int >= 1 &&
mt.Col2_int <= 366 && mt.Col3_str == "myString" && mt.Id == c.Id)
group c by true into g
select new
{
Col1 = "myString",
Col2 = g.Select (x => x.Val).Distinct().Count ()
}
Or if you rather have it in Lambda-notation:
MyChildTables
.Where (
c =>
MyTables
.Any (
mt =>
(((((mt.Col1_int == 6) && (mt.Col2_int >= 1)) && (mt.Col2_int <= 366)) && (mt.Col3_str == "myString")) && (mt.Id == c.Id))
)
)
.GroupBy (c => True)
.Select (
g =>
new
{
Col1 = "myString",
Col2 = g.Select (x => x.Val).Distinct ().Count ()
}
)

Resources