I have a QAbstractItemModel for a QTreeView. If I reset the model because I am replacing the contents from opening a new file, or if the whole tree is resorted (thus changed) and issuing a beginResetModel and endResetModel, the first item in the tree is automatically selected because currentChanged was emitted with the index of the first entry. Is there a way I can prevent anything from being selected when the model is reset?
Note: this only happens if there already was a selection.
I have tried clearing the selection model before setting the new model in two ways: selectionModel().clearSelection() and selectionModel().setCurrentIndex(QModelIndex(), QItemSelectionModel.Clear) with not luck. I have also tried setting the focus policy of the tree view to ClickFocus so it doesn't automatically select an item if it has focus.
Related
Has anyone had any problems writing data to a web client data field?
Having spied the field to be written in, the write action correctly writes the value from the data item into the web field. We then "Save" the value in the field by clicking the Save button. This is when the value reverts back to the value that was previously in the field and does not save the new value.
Copying the value from the data item and pasting it directly into the web field and hitting save works fine, but for some reason when Blue Prism does the write action and then save, the new value is not saved.
Any suggestions?
This is probably due to the way the web application is coded - specifically, the data in the box is not acknowledged until a keydown event (or similar) is fired. When you copy/paste the data into the field, it fires a similar event where it believes the user to have interacted with the field.
The solution for this type of field is to use the Send Keys or Global Send Keys functionalities of Blue Prism to send the desired text.
It happens when the target application uses java script events to sense the changes in the element. To handle this , you have to use the send keys in following format.
1. Focus the application / Control
2. Send Global mouse click centre to the element
3. Send "Sendkeys" to the application now.
4. Focus a dummy element in the page to let the page sense your input.
If the old value is already higlighted when the spied field is selected, try getting BP to delete it first, then paste in the new value, then click on the field again, then save. If this doesn't work, then uncheck the URL attribute of the application model you are using for the spied field and try this again.
I have a tabbed panel containing different sections of a form. In one section, users are given the ability to add a child document to the currently open document. In a second section, they are given a listbox, where the options are dynamically generated (via #DbLookup) by looking at a view of all the child documents, filtered by the current document's ID. This functionality all works correctly, however, there is a problem with the dynamic listbox options.
When a user adds a new child document, then switches to the next tab, the listbox is not updated with this new document. If they save/re-edit the main document or refresh the page, it makes no different, the user must load another XPage before going back to the original in order for the listbox to update. I have tried to resolve this by doing full updates of the page, using session.evaluate and "NoCache" in the #DBLookup call, or calling database.getView("My view").refresh(), but without luck.
There is also a similar problem where I have a repeat control which uses a view of child documents (again filtered by main document ID) as a datasource. When a user adds a child document using a button, it partially refreshes the repeat - but doesn't show the new child document until the page is refreshed again (or you leave the page and return).
Is there something crucial I am missing with regards to the JSF lifecycle/the way that view data is cached?
As first measure I would add another formula item to the listbox which simply returns the current time (#Now() should work). That way you can check if the listbox options are refreshed on the update in the first place.
If the options are refreshed fine it's indeed clear that the #DbLookup does some caching, although I'm not aware of any default caching logic.
At least for a test I would change the code to use a NotesView object instead of the #DbLookup, something like this:
var nview = database.getView("someview");
var nc = nview.getAllEntriesByKey(currentDocument.getDocument().getUniversalID(), true);
var a = [];
var ve = nc.getFirstEntry();
while (ve) {
a.push(ve.getColumnValues().elementAt(0)); // value of first column
ve = nc.getNextEntry(ve);
}
return a;
(I wrote the code from memory, there may be syntax errors).
Since the code only works with view entries it should be equally fast than the #DbLookup. And you could even do a nview.refresh() if needed.
I have a repeat control for a domino view which displays the results from a search field.
As you type more characters into the search field the number of items in the list is reduced. If/When the the list only contains a single item I would like to open item automatically, without having to click the link.
Any ideas are appreciated.
Edit: after some very interesting responses, here are some screenshots
I have 3 elements on the page, a searchbar, a repeat control and a form:
When I start typing in the search bar, the repeat is refreshed with every keystroke:
the list is reduced, typing the next character ...
again the list is reduced, only 2 left, typing again....
Only one left, now it would be time to open the document in the form ..... without clicking the link.
I've tried several events on the page, but it seems that I could not find the one that will allow me to "select" the document and display the data in the form.
It seems that it's not as simple as I thought
Since you want to open the link automatically I don't know if I would try to base it on the getRowCount() of the repeat itself. You don't want to even get that far right? you just want to go to the single document.
I would put a function in beforePageLoad event maybe. Not totally sure which event but I'd try that first. Use SSJS and do a lookup that would basically return a collection of what the repeat would show. If the collection count = 1 then get your destination from that entry and do your redirection from there.
That what I would try at least. Interesting scenario!
Now that I see the screenshots this might be easier then you think and I have already implemented something similar on an internal application that I have built. It does rely on the fact that each entry in the list is 100% unique.
First of all you will need to bind the search field to a scoped variable and the onchange/onkeypress event will need to perform a partial refresh of a panel that contains both the list and the document portion of the page.
For the list the link on each item should set the value of the same scoped variable used in the search box and clicking the link should be set to run a partial refresh of the document area.
For the document area you will need two panels, the first panel will only display if there is no matching document and the second panel will only display if there is a matching document, you can do this in the rendered section by writing some ssjs that grabs a handle to the db/view and does a dblookup and returns either true or false if the document exists depending on panel your dealing with.
With this setup, when somebody clicks a link or fills out the searchbox the scoped variable will contain a value, the document panels will then check to see if this is a unique value in the view in the db and update themselves to either display the 'no document' panel or the 'document' panel accordingly.
You could add a evaluation script to the entry of your repeat control which checks the size of your repeat control using the method getRowCount() from the component. If this is 1 you could execute a context.redirectToPage("yourpage.xsp?id=yourid",true) this forces the current page to send a redirect request back to the browser and therefore redirects you to the correct page.
All you need to know is which xpage you need to open and which parameters you should use. But these could be retrieved from the content you are iterating over.
First I apologize for the length but I want to ensure I get enough information out. I have an interesting problem that really shouldn't be difficult. I know that if you want to have the NSOutlineView scroll to and want display a specific row you simply use this pattern:
NSInteger row = [self.myOutlineView rowForItem:myItem];
[self.myOutlineView scrollRowToVisible:row];
I am not using a NSTreeController in favor of using delegation.
I am using an adapter pattern class to act as my data. The adapter wraps a number of different types. It is a simple structure:
[adapter children] ----- *[adapter parent]
So the adapter takes care of dealing with child count, can add, can remove, can expand, etc. and also acts like a data transport object.
So with that all out of the way here is the crux of the problem. When I add a new item to the NSOutlineView I start by adding a new child adapter to the adapter that is selected in the outline view. Then I reload the item with the children using:
[self.myOutlineView reloadItem:selectedAdapter reloadChildren:YES];
I then display the view for this object and attempt to synchronize the NSOutlineView so the selected row relates to the newly displayed view. So in a simple way the steps are:
Initially load the NSOutlineView with data utilizing the NSOutlineDataSource protocol
User selects an item (adapter) that can add child items
User clicks "Add" button
A new empty represented object is created
The new represented object is wrapped in an adapter
The newly created adapter is added to the children of the selected adapter
A new view is created using the new represented object and displayed
The selected (parent) node and its children is reloaded in the NSOutlineView
The newly created row in the NSOutlineView is scrolled to view which synchronizes the view and the selection of the NSOutlineView
So here is the problem. The NSOutlineView will not find the newly added item if you use the rowForItem method. Yet after I reload I can expand the parent node and select the newly added item and everything works fine. In an attempt to fix the problem I have programmatically expanded the parent node (exposing the new item) then attempt to scroll to the new item and it still cannot find the row. The rowForItem returns -1.
Have I missed something when adding a new item that I am not updating something in the NSOutlineView? I've tried many different things without success and any help will be greatly appreciated.
Thanks in advance,
Rob
Solved my own problem...finally.
Since I was adding my first child to that node and it was changing from non-expandable to expandable it needed to be expanded first, then scroll to view, then select the item. No more problem.
I have an NSArraycontroller which is bound to my application's AppDelegate's managedObjectContext. It acts as a download queue. Items are added to the NSArraycontroller programmatically
I have a table which shows two of the fields in this, each a column with its value individually bound to the the said NSArraycontroller. When a new download is started it is removed programmatically from the NSArraycontroller.
I have added a button to remove downloads from the queue before they start, the button is bound to the NSArraycontroller's remove: action which should remove the selected item in the table.
My problem is that when clicking the remove button the selected item does not get removed from the table, it remains there until clicking another entry in the table. Selecting the row where the item was causes it to be selected while the mouse button is held down, as if it is still there, but with no values.
In the console the following appears when the remove button is clicked:
-[NSCFDictionary _setUnprocessedDeletion__:]: unrecognized selector sent to instance 0x2000f2220
If I remove items from the table programmatically using
[[downloadsArray content] removeObjectAtIndex:0];
[downloadsTable reloadData];
[downloadsTable deselectAll:nil];
it seems to work fine, except I still get the invisible item left behind that can be selected and remains selected only when the mouse button is down.
I have bound the remove button's enabled attribute to canRemove of the NSArraycontroller and this works correctly.
I have a label which shows the number of items in the queue, this is bound to NSArraycontroller, arrangedObjects, #count. This works correctly when adding items but not when removing them.
Any ideas on what I'm doing wrong would be much appreciated.
I had the same problem when I tried to use an NSFetchRequest with NSManagedObjectIDResultType, and then tried to delete the results with -[NSManagedObjectContext deleteObject:].
Solution: dont use NSManagedObjectIDResultType for an NSFetchRequest if you plan to delete the objects returned.
I just had a similar problem. It turns out that _setUnprocessedDeletion__: is a method defined for NSManagedObject, and apparently its message is sent to an object when it is removed from an array controller which is set to Entity mode. That was my problem; after a day of heavy remodeling I ended up with an array controller set to Entity mode, whose content was bound to an array of regular objects instead of managed objects. One of these errors occurred whenever I removed an object. Look at the contentArray of your array controller.