OpenEdge 10.2A - How to apply the default RETURN / CURSOR-DOWN on Editor widget even if a general code for RETURN / CURSOR-DOWN with ANYWHERE exists? - openedge

I have a code for RETURN / CURSOR-DOWN for all widgets in a window which basically makes it as if TAB is pressed. It works just fine but I want the default functionality of RETURN (Break current line into two lines) / CURSOR-DOWN for EDITOR widgets.
I have tried to add
APPLY "ENTER" TO SELF.
or
APPLY "RETURN" TO SELF.
or
APPLY "CTRL-J" TO SELF. /*Ctrl-Enter*/
for EDITOR widgets but when pressed RETURN / CURSOR-DOWN in an EDITOR it just does not do anything. It stays as if RETURN / CURSOR-DOWN is not pressed.
ON RETURN OF {&WINDOW-NAME} ANYWHERE
DO:
IF SELF:TYPE="EDITOR" THEN
DO:
APPLY "ENTER" TO SELF. /*Does NOT Work*/
END.
ELSE IF SELF:TYPE = "BUTTON" THEN
DO:
APPLY "Choose".
END.
ELSE
DO:
APPLY "Tab".
RETURN NO-APPLY.
END.
END.
ON CURSOR-DOWN OF {&WINDOW-NAME} ANYWHERE
DO:
IF SELF:TYPE="EDITOR" THEN
DO:
APPLY "CURSOR-DOWN" TO SELF. /*Does NOT Work*/
END.
ELSE
DO:
APPLY "Tab".
RETURN NO-APPLY.
END.
END.
Is there a way to do it?

I've tested this in 10.2B08. Here's the main anywhere trigger:
ON RETURN OF {&WINDOW-NAME} ANYWHERE DO:
IF SELF:TYPE = "BUTTON" THEN DO:
APPLY "Choose".
END.
else do:
apply 'tab'.
return no-apply.
end.
end.
ON CURSOR-DOWN OF {&WINDOW-NAME} ANYWHERE DO:
if self:type ne 'EDITOR' then DO:
APPLY "Tab".
RETURN NO-APPLY.
END.
END.
Not much different from what you had.
Now in the editor, add a trigger to RETURN and one to CURSOR-DOWN.
Here's your editor's RETURN trigger:
self:insert-string(chr(13)).
And here's the editor's CURSOR-DOWN trigger:
DEFINE VARIABLE iOffset AS INTEGER NO-UNDO.
assign iOffset = self:cursor-char
self:cursor-line = self:cursor-line + 1
self:cursor-char = ioffset no-error.
do while error-status:get-message(1) begins '**Unable to set attribute CURSOR-CHAR':
assign iOffset = iOffset - 1
self:cursor-char = ioffset no-error.
if iOffset = 1 then leave.
end.
Let me know if this works for you. Seems to be ok for me here.

Related

D365 New Button creates price line with empty line

After adding logic about creating price for object in grid it's always created "one line more" which is empty.
So, if there is need to be created two lines, it will be created 3 lines and that one addition will be empty.
Is there something what I missing in code?
[Control("CommandButton")]
class AreaActionPaneNew
{
void clicked()
{
PMCParameters contractParameters = PMCParameters::find();
PMETmpRentalObjectArea groupedAreaList; // Group by area_type and cost_type
PMERentalObjectPrice priceList;
date workingDate = currWorkingDate.dateValue();
;
super();
// Get grouped area values. Values are summed up by area_type and ancost_type
groupedAreaList = PMERentalObjectAreaCl::getRentalAreaPrCostType(pmeRentalobject.RentalObjectId, userSetting.validFrom(), userSetting.validTo() , workingDate);
ttsbegin;
while select groupedAreaList
{
select forupdate firstonly priceList
where priceList.RentalObjectId == pmeRentalObject.RentalObjectId &&
priceList.RentalCostType == groupedAreaList.RentalCostTypeId &&
priceList.AreaType == groupedAreaList.Areatype && priceList.ValidFrom == pmeRentalObject.ValidFrom;
if (!priceList)
priceList.initValue();
priceList.RentalObjectId = pmeRentalObject.RentalObjectId;
priceList.RentalCostType = groupedAreaList.RentalCostTypeId;
priceList.ValidFrom = pmeRentalobject.ValidFrom;
priceList.AreaType = groupedAreaList.Areatype;
priceList.Amount = groupedAreaList.Price;
priceList.Area = groupedAreaList.AreaValue;
priceList.Quantity = groupedAreaList.RentalQty;
if (!priceList)
priceList.Period = contractParameters.ReportPeriod;
if (priceList)
priceList.update();
else
priceList.insert();
}
ttscommit;
pmeRentalObjectPrice_ds.research();
}
}
The code looks like it only updates/inserts without creating a blank line.
From your attribute, you are using a Command Button (see here), which may have an associated command, such as New, which effectively pushes Ctrl+N, and would explain why you have a blank line.
The simplest way to check is just create a regular Button and override the clicked method, then copy/paste your code and push both buttons and see if they have different behavior.
Check the Command property on the button and see if there's something there. Try commenting out the super(); call.
You should perhaps consider just a Button or a Menu Item Button with an associated object.

Regex to validate dropdown entries

I have a dropdown in which I am having
"-- Select--"
as the first item. I want to check if user has choosen something else from the dropdown instead of Select.
So is there a way around to match if
!-- Select --.
I have done this till now.
"regex": /^[!-- Select --]$/,
Where "!" means when not Select.
I am achieving this client side.
You can try this regex:
/^(!?--\s*[Ss]elect\s*--)$/
You should also find SelectedIndex property to evaluate this item.
It doesn't work because you're using a big character class; instead of trying to match the opposite, try to match what you don't want and then logically reverse that.
/^[-]{2} Select [-]{2}$/
function selectavalue() {
var selectBox = document.getElementById('selectboxid');
var user_input = selectBox.options[selectBox.selectedIndex].innerHTML;
var str = user_input;
if((str.match(/--Select--/i)) )
{
alert("Please select a value");
}
else
{
alert("The value u selected is"+str);
}
}
call this function from your selectbox.onchange="return selectavalue();"
You can use jQuery
if($("#id of your select box").attr("selectedIndex") == 0)
{
alert("You haven't selected anything!");
}
You have to make first value as default value.

Very complicated XQuery transformation

I have a very complex XQuery to write (at least by my standards).
Here is my input xml:
<testRequest>
<request1>
<Line>1</Line>
<action>addtoName</action>
</request1>
<request2>
<Line>2</Line>
<action>addtoSpace</action>
</request2>
<request3>
<Line>3<Line>
<action>addtospace</action>
</request3>
</testRequest>
In my output xml, the actions should be attached as attributes to the "request1" elements. So, based on the action element under a request1 element, the attribute for the request1 element should be one of the following:
if action = IgnoreCase(addtoName), the request1 element should be <request1 action=insertingname>
if action = IgnoreCase(addtoSpace), the request1 element should be <request1 action=updatingspace>
Not only this, but also, I need to add an attribute to the element, based on the action values underneath it.
So, I have to traverse each of the elements under a element and see if any of the elements are equal to "addtospace" if yes, then I need to get the corresponding values of the elements and make up the attribute for the element. From the above xml, my attribute for the element should be,
<testRequest lineFiller="Line Like 2_* AND Line Like 3_*>, where 2 and 3 are the respective line numbers.
and if there are no elements with element= addtoSpace, then the attribute for the element should be "changed".
So, in summary, my transformed xml should look like this:
<testRequest lineFiller="Line Like 2_* AND Line Like 3_*>
<request1 action=insertingname>
<Line>1</Line>
<action>addtoName</action>
</request1>
<request2 action=updatingspace>
<Line>2</Line>
<action>addtoSpace</action>
</request2>
<request3 action=updatingspace>
<Line>3<Line>
<action>addtospace</action>
</request3>
</testRequest>
Any help to accomplish this humungous task will be greatly appreciated.
thanks!!!
You should define functions to generate the attributes that you need to add to your elements.
For adding to the "request" element, this should work:
declare function local:getaction($x) {
if (lower-case($x/action) = "addtoname") then attribute action {"insertingspace"} else
if (lower-case($x/action) = "addtospace") then attribute action {"updatingspace"} else
()
};
The linefiller attribute can be created similarly:
declare function local:getfiller($x) {
attribute lineFiller {
if ($x/*[lower-case(action) = "addtospace"]) then
string-join(
for $r in $x/*[lower-case(action) = "addtospace"]
return concat("Line Like ",$r/Line,"_*")
, " AND ")
else "change"
}
};
Then to put it all together, fun a simple for loop over your original document, adding in the attributes where needed:
let $doc:=<<your original document>>
return
<testRequest>
{ local:getfiller($doc) }
{ for $r in $doc/* return
element { name($r) } {
local:getaction($r),
$r/*
}
}
</testRequest>
EDIT: enhanced getfiller function to return "change" if there are no actions

How to get multiple key presses in single event?

I am creating an application, where "Left Arrow + Down Arrow" press has different behavior ( It is not same as first left arrow and then left arrow ), currently in keyPressEvent event I am getting them one by one in two separate calls.
Is there any way by which I can get multiple keypress in one keyboard event?
Thanks for this. I am posting code for the Python (PyQt) equivalent so that someone else might find it useful.
def keyPressEvent(self, event):
self.firstrelease = True
astr = "pressed: " + str(event.key())
self.keylist.append(astr)
def keyReleaseEvent(self, event):
if self.firstrelease == True:
self.processmultikeys(self.keylist)
self.firstrelease = False
del self.keylist[-1]
def processmultikeys(self,keyspressed):
print keyspressed
I solved the problem by below code.
QSet<Qt::Key> keysPressed;
void Widget::keyPressEvent(QKeyEvent * event) {
m_bFirstRelease = true;
keysPressed+= event->key();
}
void Widget::keyReleaseEvent(QKeyEvent *) {
if(m_bFirstRelease) {
processMultiKeys(keysPressed);
}
m_bFirstRelease = false;
keysPressed-= event->key();
}
Nothing is "at the same time" and I believe in Qt you can't have that type of behaviour (except for modifier keys like shift, alt, etc).
Approach the problem in a different way. When you receive one of the keys, check to see if you received the other in a short while back, say 20ms before.

How to assign dataGrid to other dataGrid in Flex. a = b doesn't work

in Flex I have something like that:
var dg:DataGrid = new DataGrid();
if (something) dg = dg1 else if (something_2) dg = dg2;
dg.dataProvider.getItemAt(3).id;
and dg is ALWAYS pointing at DataGrid (even if dg1 has name DataGrid_test and dg2 = DataGrid_test2) and finally action is made on my first DataGrid (DataGrid_test).
Why?
How can I pass dg1 or dg2 to dg?
Here is pasted almost full code of this part of application. I edited it to make that more clear.
var dg:DataGrid = null;
if ( currentState == "state1" ) { //if this condition is true then app. go into if and
dg = dataGrid_first; // make dg = DataGrid (1)
test.text = "inco"; // shows "inco" in "test" label
} else if ( currentState == "state2" ) { // if this is true then app. go..
dg = dataGrid_second; //here and set dg as DataGrid (exactly!) (2)
test.text = "outgo"; // and change test label into blank text (earlier text disapears)
}
search(dg);
It is modified with advice of '#splash'
Still not working.
EDIT:
I made this sceond edit to answer for all You who are helping me with that :) I think that it will be the best way. In codeblock above I added comments. (please read now comments and after that come back here :) )
Now I will explain exactly what happens.
I debug it many times and here are results:
dg is pointing at DataGrid (as component in flex, not as my dataGrid_first), I needed to extend DataGrid so now it is ColorColumn component (I don't know if I called it properly), not DataGrid. And dg is pointing at ColorColumn not at dataGrid_first or dataGrid_second. I even tried today the same thing what suggest #splash:
if ( currentState == "state1" ) {
test.text = "inco";
search(dataGrid_first);
} else if ( currentState == "state2" ) {
test.text = "outgo";
search(dataGrid_second);
}
and search still points at ColorColumn :/ My problem is really easy- I just want to pass to search different dataGrid on each state. If You have other ideas how I can do that in right way then I will pleased to hear about it. :)
But still I don't understand why it doesn't work. My search function uses algorhitm Boyer-Moor for searching through dataGrid.dataProvider for some text. If it find something then it is pushed into new array and after passing whole dataProvider I colorize rows with searched word.
If dg is never pointing to dg1 and dg2 then your (something) expressions may be evaluate to false. Check the value of your if-conditions - this should be easy to debug.
This should work:
var dg:DataGrid = null;
if (something)
dg = dg1;
else if (something_2)
dg = dg2;
if (dg)
{
// do something with dg
}
[Update]
I still can't see why your code isn't working, but you could simplify it like this:
if ( currentState == "state1" ) {
test.text = "inco";
search(dataGrid_first);
} else if ( currentState == "state2" ) {
test.text = "outgo";
search(dataGrid_second);
}
I'd propose to write this - since I guess either dg1 or dg2 should be assigned:
if (something) {
dg = dg1;
} else {
dg = dg2;
}
There may be cases, where if () {} else () {} neither executes the first or the second conditional block.
Finally a small hint, which structurally eliminates unwanted assignments in if conditions: Always write the literal left of the comparison operation: if ( "state1" == currentState ). If you accidentally typed = instead of ==, the flex compiler emits an error. The other notation silently assigns a value.
Additionally: Did you single-stepped through your code and watched the variables dg1, dg2 and dg? If not, set a breakpoint a few line before the if-statement and run the code step by step from there on. What do you see?
Here's a another tip: Use assertions to check for inconistencies:
package my.company.utilities {
public function assert(expression:Boolean):void {
// probably conditionally compile this statement
if (!expression) {
throw new Error("Assertion failed!");
}
} // assert
}
Use it e.g. at the beginning of a method like this:
public function doTransaction( fromAccount:int, toAccount:int ) {
assert( 0 < fromAccount );
assert( 0 < toAccount );
}
A typically good use of assert is to check variables regarding their range. As of the above example, fromAccount and toAccount should always be positive. Due to a bug, bad values might get passed to doTransaction(). In this case, the assertion fires an error.

Resources