Disabling F5 key on ListPage AX 2012 - axapta

I want to disable the F5 refresh on a specific listpage, I disabled the refresh action key but the F5 still works. I can't overide the Task method on the SysSetupFormRun because it's a listpage. Is any way to do this?
The reason I want to do this is because some refreshproblems when having multiple datasources and I want to disable it for the customer until microsoft comes with a solution (issue is already logged).
Edit:
As a fix I intercepted the task method on the SysSetupFormRun class, but this method only triggers when you have selected a record in your listpage. When you first open your listpage and immediately press F5 it does refresh and doesn't go in the task method.

I know you mentioned that you had no success with overwriting task of SysSetupFormRun, but the code below worked for me in our test system.
I inserted this code into method task of class SysSetupFormRun to disable F5 for SalesTableListPage:
public int task(int _p1)
{
#task
FormDataSource formDataSource;
int ret;
if (_p1 == #taskFilter)
{
formDataSource = this.objectSet();
if (formDataSource &&
formDataSource.queryRun() &&
formDataSource.queryRun().args() &&
!formDataSource.queryRun().args().caller())
{
formDataSource.queryRun().args().caller(this);
}
}
// -- Here is the interesting stuff
if ((_p1 == #taskF5 || _p1 == #taskRefresh) &&
(this.name() == formStr(SalesTableListPage)))
{
return ret;
}
return super(_p1);
}
If the approach is the same as the one you already tried, then you can ignore this answer - otherwise feel free to try it out ;)

Related

Multiple OnSaving event in DevExpress XAF

Im working on a piece of code using DevExpress XAF, I noticed that if im using the event OnSaving that the code executes 2 times, how can i prevent that
protected override void OnSaving()
{
if (PrestamoP != null)
{
PrestamoP.Prestado -= Monto;
PrestamoP.Save();
}
else if (PrestamoG != null)
{
PrestamoG.Prestado -= Monto;
PrestamoG.Save();
}
base.OnSaving();
}
XPO does not guarantee that the OnSaving method is called once. See the corresponding note in the XPO Best Practices article.
I can see that you are changing the PrestamoP.Prestado property based on the value of the Monto property. This code is fine if you execute it only once and only when the Monto property is specified for the first time. This code is not fine if you:
Save this object without changing the Monto property;
Update the early specified Monto value.
So, it appears that a more complex logic is required for the PrestamoG.Prestado property. First, I would move it to the Monto property setter and take the previous value into account (do not forget to check the IsLoading property in this case). Second, I would consider calculating the Prestado value dynamically instead of storing its value. This will allow you to resolve issues with the duplicate business logic execution. See an example here: How to: Calculate a Property Value Based on Values from a Detail Collection.
I can offer different methods for CRUD functions on onSaving method.
IsNewObject, IsDeleted.
// insert
if (Session.IsNewObject(this))
{
a = new a(Session);
a.CreateReferencedProperties(this);
}
// delete
else if (IsDeleted)
{
a= Session.FindObject<A>(PersistentCriteriaEvaluationBehavior.InTransaction, CriteriaOperator.Parse("A=?", this));
if (a!= null)
a.Delete();
}
// update
else
{
a= Session.FindObject<A>(PersistentCriteriaEvaluationBehavior.InTransaction, CriteriaOperator.Parse("A=?", this));
if (a!= null)
a.CreateReferencedProperties(this);
}
You can use the code below to prevent xaf from entering on saving twice.
base.OnSaving();
SessionObjectLayer sessionObjectLayer = this.Session.ObjectLayer as SessionObjectLayer;
if (sessionObjectLayer == null || sessionObjectLayer.ParentSession == null)
{
//Enter only once
}

JavaFX 8: Intercepting appication "exit"

In order to verify that all changes made by the user have been saved I want to intercept the exiting/quitting of a JavaFX application.
Is there a common way-to-go to achieve this like overriding an event or is there more to it?
As they have already said, this is done by intercepting WindowEvent.WINDOW_CLOSE_REQUEST. You can then stop the suspension by calling event.consume().
This is an example of how to capture the event and display a confirmation dialog. Depending on the user's choice, you can take serialization actions if you wish.
primaryStage.setOnCloseRequest(event -> {
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.initOwner(primaryStage);
alert.initModality(Modality.APPLICATION_MODAL);
alert.setHeaderText("Exit");
alert.setContentText("Do you want to exit?");
alert.getDialogPane().getButtonTypes().setAll(ButtonType.OK, ButtonType.NO);
Optional<ButtonType> optional = alert.showAndWait();
if(optional.isPresent() && optional.get() == ButtonType.OK) {
// save data
return;
}
event.consume();
});
In order for the implementation to be complete, you need to implement a logic for clear exit from the application from control. For example, when choosing from the File menu -> Close. When capturing the event, you must run WindowEvent.WINDOW_CLOSE_REQUEST to trick the exit logic.
closeMenuItem.setOnAction(event -> {
Window window = menuBar.getScene().getWindow();
window.fireEvent(new WindowEvent(window, WindowEvent.WINDOW_CLOSE_REQUEST));
});
In the class Application there is the stop method which you can override possibly.

Trouble getting `QWidget* editor` for a `QModelIndex`

I am having trouble augmenting the default edit behavior of QTableView. I want the following behavior when the Enter key is pressed:
Start editing the current cell if it is not already being edited.
If the cell is being edited,
2a. commit the data and close the editor. Then,
2b. make the cell below, if present, the current cell.
2a is the default behavior, and 2b can likely be achieved by using QAbstractItemView::setCurrentIndex() in a re-implementation of QItemDelegate::eventFilter() (as suggested here in a similar context).
The problem is in achieving 1. I list below the approaches I have tried till now.
Reconfigure the "platform edit key" By default, "Editing starts when the platform edit key has been pressed over an item." (QAbstractItemView::EditKeyPressed) This key is F2 on my platform (Ubuntu 12.04). I could reconfigure the platform edit key to Enter but
Altering platform defaults seems like a bad idea.
I could not find out how to do it.
Capture the Enter key press I use QShortCut to do this as follows:
class CourseTable : public QTableView {
/* ... */
};
/* ... */
CourseTable::CourseTable(/* ... */) {
/* ... */
QShortcut* shortcut = new QShortcut(QKeySequence(Qt::Key_Return), this);
connect(shortcut, SIGNAL(activated()), this, SLOT(handleEnter_()));
/* ... */
}
/* ... */
void CourseTable::handleEnter_() {
QModelIndex idx = this->currentIndex();
if (this->state() != QAbstractItemView::EditingState)
this->edit(idx);
/* else // see below */
}
This does capture the Enter key-press and accomplishes 1 (from above) but now 2 is broken. So, I need to look into the else clause in CourseTable::handleEnter_() above, possibly calling QAbstractItemView::commitData() and QAbstractItemView::closeEditor in it. The problem is that both these functions require a QWidget *editor argument which I just cannot figure out how to get. I could subclass QAbstractItemDelegate, add a getEditor() method to the derived class, and modify existing code to pass instances of the derived delegate class to CourseTable::setItemDelegate*() functions. But that sounds like too much work.
So, any ideas how I can cleanly accomplish both 1 and 2 without having to rewrite my code?
Why cant you just filter the event also for starting the edit?
Just handle the event if state is != QAbstractItemView::EditingState
Returning true in this function makes the event stop propagating to the filtered object.
If state is Editing you can just return falseand allow the table and editor continue processing the event.
Something like this:
bool FilterObject::eventFilter(QObject *object, QEvent *event)
{
if (object == tableView && event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Return && tableView->state() != QAbstractItemView::EditingState) {
// set current cell to edit
return true;
} else
return false;
}
return false;
}

InDesign SDK : Drag'n'Drop from a Flex Panel

I have a Flex panel, in InDesign, from which I drag an URL. If I drop this URL on a text editor or a web browser, it works. But when I try to drop it on my InDesign document, it's a little bit harder.
I have implemented a subclass of CDragDropTargetFlavorHelper. The drop works perfectly on Windows. But on mac, I have problems in the method CouldAcceptTypes :
DragDrop::TargetResponse AutocatDNDCustomFlavorHelper::CouldAcceptTypes(const DragDropTarget* target, DataObjectIterator* dataIter, const IDragDropSource* fromSource, const IDragDropController* controller) const
{
if (0 != dataIter && 0 != target)
{
DataExchangeResponse response = dataIter->FlavorExistsWithPriorityInAllObjects(kURLDExternalFlavor);
if (response.CanDo())
{
...
}
}
}
The problem is that response.canDo() answers kTrue on Windows, but kFalse on Mac. I tried to explore the content of dataIter, but a call on dataIter->First() returns nil. I tried a controller->GetItemCount(), which returns 1. But if I try a controller->GetDragItem(1), I get a nil pointer. I have the impress there is no item. Though, the drop works on another app than InDesign, as I said.
Is it a problem of internalization ? Or something else ? It let me dry.
Thanks in advance
-------------------------- EDIT -----------------------------------
I solved this problem, but discovered another one. The flavor sent by the flex panel has been changed, so that it's a text flavor instead of an URL flavor. My method couldAcceptType works now :
DragDrop::TargetResponse AutocatDNDCustomFlavorHelper::CouldAcceptTypes(const DragDropTarget* target, DataObjectIterator* dataIter, const IDragDropSource* fromSource, const IDragDropController* controller) const
{
if (0 != dataIter && 0 != target)
{
// Check for URL Flavor in the drag
DataExchangeResponse response = dataIter->FlavorExistsWithPriorityInAllObjects(kTEXTExternalFlavor);
if (response.CanDo())
{
return DragDrop::TargetResponse(response, DragDrop::kDropWillCopy);
}
}
return DragDrop::kWontAcceptTargetResponse;
}
The problem is now in the ProcessDragDropCommand method. Here is the code :
ErrorCode AutocatDNDCustomFlavorHelper::ProcessDragDropCommand(IDragDropTarget* target, IDragDropController* controller, DragDrop::eCommandType action)
{
// retrieve drop data
IPMDataObject* dragDataObject = controller->GetDragItem(1);
uint32 dataSize = dragDataObject->GetSizeOfFlavorData(kTEXTExternalFlavor) ;
...
}
The problem is the IMPDataObject I get is nil. There is no item in the controller. However, there were items in the CouldAcceptTypes method, in the DataObjectIterator. So, where are my items ?
I tried using a custom CDataExchangeHandlerFor, but could not really understand what its usage was for. It didn't work anyway.
Has anyone an idea ?
Regards,
RĂ©mi
The problem is the argument of the GetDragItem. It is 1 on PC. It is a strange value on Mac (something like 719853). The only dirty solution I found is doing a memcpy from the object retrieved drom the dataIter in the CouldAcceptTypes method, and use it in the ProcessDragDropCommand method.

WF4 Rehosted Designer OnActivityAdded Event?

I'm looking at rehosting the workflow designer. I want to be able to run some code whenever the user adds an activity to the designer canvass. Is there an event that fires when the user adds an activity at design time? Or is there an event on the activity that I can consume? Thanks!
For anyone who might stumble onto this, here's what I figured out...
First off, when creating the workflow designer, you need to subscribe to the ModelChanged event.
_workflowDesigner = new WorkflowDesigner();
_workflowDesigner.Load(new Sequence());
ModelService ms = _workflowDesigner.Context.Services.GetService<ModelService>();
if (ms != null)
ms.ModelChanged += new EventHandler<ModelChangedEventArgs>(ms_ModelChanged);
My event handler looks like this...
void ms_ModelChanged(object sender, ModelChangedEventArgs e)
{
if (e.ItemsAdded != null && e.ItemsAdded.Count<ModelItem>() == 1)
{
ModelItem item = e.ItemsAdded.FirstOrDefault<ModelItem>();
var test = item.GetCurrentValue() as MyActivityType;
if (test != null && test.Id == null)
{
//do whatever initialization logic is needed here
}
}
}
I need to give credit to this source for pointing me in the right direction.
One thing to be careful of - when you move an activity within the model, two events are raised, a remove and an add. At this point, I don't need to worry about whether I'm adding or moving an activity as I can tell whether it has been initialized, but if you need to know whether something has really been added to the model, you might need to track both events.

Resources