Binding NSArrayController to moc in NSPersistentDocument subclass in Xcode4 in XIB view - xcode4

I have my subclass of NSPersistentDocument who's superclass has [self managedObjectContext]
Trying to set the bindings of my NSArrayController in the xib. When I set the Parameter's Moc, the bind to choices are: File's Owner, App, and Prefs. (The NSArrayController's entity is set to the Entity name in my context)
Model KeyPath defaults to self.
I then bind the value of a table column to the NSArrayController (Which I'm not sure how to rename under Xcode 4).arrangedObjects.(name of my entity property)
There's a populate button on the UI to self populate the context.
When I run. The UI won't come up and all I get in the console is repeated:
-[MyDoc persistentStoreCoordinator]: unrecognized selector sent to instance 0x10015adf0
Suggestions?

I suspect you have bound the managedObjectContext directly to the NSPersistentDocument. What you probably need to do is in the bindings panel bind to the Files Owner (assuming this is NSPersistentDocument) and then set the binding path (Model Key Path) to managedObjectContext.

Related

Where is the documentation for BizTalk SendPort filters?

I'm talking about this list. I can't find the documentation online. Is it available anywhere?
Here's a fine example, how would I fill this out if I wanted to use it? That's why I need documentation.
Short answer
Each item in that list is defined in a Property Schema that defines the type and hence what the value type in the filter should be. By adding new property schemas, there will be more items in the list. So there won't be any definitive documentation for all of them.
Filters will mostly only work on Message Context Properties that are Promoted.
Long explanation:
This is the documentation Setting Filter Expressions on Send Ports, but it is very bare bones and just tells you how to set a filter. What you need refer to for out of the box is Message Context Properties e.g. File Adapter Property Schema and Properties
But what you need to know is that each item in that list is associated with a Property Schema. If you add more property schemas, those properties will also show in that list, so it is not a static list, but a dynamically generated one. Adding some adapters will add more context properties.
If you look at the context properties for a message from a file receive location you can see the FileCreationTime property there and the value, if it is promoted or not (Type), and the Namespace of the Property Schema it is associated with.
e.g.
Name: FileCreationTime
Value: 19/05/2022 9:59:23 p.m.
Type: Not Promoted
Namespace: http://schemas.microsoft.com/BizTalk/2003/file-properties
Also if you set a value to that filter and try and Enlist it and it is not the right type you get the following error.
You can see the type in the Property Schema
The FileCreationTime is not a Promoted Property, which generally means you generally can't subscribe to it, however there are some exceptions to this, but this is not one of them.
When I changed the rule to > and the value to 19/05/2022 9:59:23 p.m., the send port Enlisted, but did not subscribe to a message.
Below are the properties that are Promoted from a file receive by default
InboundTransportLocation http://schemas.microsoft.com/BizTalk/2003/system-properties
ReceivePortID http://schemas.microsoft.com/BizTalk/2003/system-properties
ReceivePortName http://schemas.microsoft.com/BizTalk/2003/system-properties
InboundTransportType FILE Promoted http://schemas.microsoft.com/BizTalk/2003/system-properties
MessageType Transaction Promoted http://schemas.microsoft.com/BizTalk/2003/system-properties
Note: MessageType will only be present if you've disassembled a message.
You either need to use the properties that are promoted, or to promote the property you do want, or have logic in either an Orchestration or Pipeline Component that inspects that context properties and then sets promoted properties so that you can route the message.
For example I used the BRE Pipeline Framework to Promote the FileCreationTime property, and then the Filter does work.

how to set QLineEdit to readonly if the data mapped by QDataWidgetMapper is readonly?

I have a tree model and use QDataWidgetMapper to map the model data to some widgets.
In the model, some of the data are flagged as read-only, so, what I would like to do is to let the mapped widget, say, a QLineEdit, be able to act upon this flag and set itself to readonly when the model data it points to is readonly.
Any help is appreciated!
Qt's QAbstractDataModel interface doesn't expose writability of a piece of data as an attribute: there's nothing you can read to know whether an item can be modified or not. One could think of some non-general hacks, such as attempting to write back the current value of the item to check if it can be changed. They are but hacks, e.g. a model fulfilling the contract mandated by Qt might return true from setData even on a read-only item if the new value equals old value.
If you're using a model that exposes the writability attribute, you'll need to derive from QDataWidgetMapper and implement that functionality yourself.

Qt MIME-TYPES decodification

I am trying to use the drag & drop functionality on a QTreeView with an underlying QStandardModelItem. The default behavior of the widget is perfect for me until it gets to the drop part where I need to perform some operation. Hence, I am going to override the dropEvent(QDropEvent *event) method of my TreeView where I would like to decode the dropped mime data.
The formats of the data I find in the mime object are "application/x-qabstractitemmodeldatalist" and "application/x-qstandarditemmodeldatalist". Does anyone know how to decode the associated data (or where to find some documentation on it) ?
That mime type is the default type for item views. The qt already handles this when drop is made; To enable drag'n drop do:
itemView->setSelectionMode(QAbstractItemView::SingleSelection);
itemView->setDragEnabled(true);
itemView->viewport()->setAcceptDrops(true);
itemView->setDropIndicatorShown(true);
itemView->setDragDropMode(QAbstractItemView::InternalMove);
To change default behavior take a look at:
http://doc.qt.io/qt-5/model-view-programming.html#using-drag-and-drop-with-item-views

Drag and drop in QTreeView, removeRows not called

I have some problem with drag and drop in QTreeView:
I set flag to Qt::MoveAction and reimplemented removeRows(), dropMimeData() and etc in my model. The Model inherits QAbstractItemModel.
When I drag and drop, mimeData(), dropMimeData() are called automatically,
and also dropMimeData() calls insertRows() automatcally. But removeRows() is not called, so the dragged item is still alive. I googled, but they said their removeRows() was called automatically.
Why isn't my removeRows() called after dropMimeData()?
Shoud I call removeRows() manually in dropMimeData()?
If so, how can I know the previous QModelIndex of start of drag?
When starting drag, in mimeData(), I can save index in private member, but it looks like not good.
Any advice would be appreciated.
Short answer
If everything is correctly configured, the target should not remove the source item, the initiator of the drag should remove the source item if a Qt::MoveAction is performed.
Configuration of the view
QAbstractItemView (which is the base class of QTreeView, QListView, QTableView, ...) implements the initiation and finishing of the QDrag operation in startDrag:
if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction)
d->clearOrRemove();
So, when the requested drop action (returned by QDrag::exec) is a Qt::MoveAction, the item is automatically removed (or cleared as specified by setDragDropOverwriteMode).
Important configuration options of the view are:
setDragDropMode: specifies if the view should accept drag and/or drop items from external or only internal items. This function calls setDragEnabled and setAcceptDrops accordingly.
setDragEnabled: enables the builtin drag mechanism
setAcceptDrops: enables the builtin drop mechanism
setDragDropOverwriteMode: specifies if the source item should be removed (typical in a tree view) or cleared (typical in a table view)
setDefaultDropAction: the default drop action specified when initiating the QDrag operation.
Configuration of the model
Besides the configuration of the view, you should configure your model correctly.
You should implement the editing interface of your model, i.e. removeRows, insertRows, moveRows and setData. Although it may not be necessary to implement all of them depending on your specific situation, it is a good approach to implement them anyway for an editable model.
supportedDropActions: Reimplement this function to return the support drop actions (Qt::CopyAction by default). Note that the user may switch between the different supported actions by pressing some keys. (shift for Qt::MoveAction and control for Qt::CopyAction)
supportedDragActions: Reimplement this function if the supported drag actions are different from the supported drop actions.
Examples
Good examples are the source code of Qt itself. The corresponding Q*Widget classes (ex. QTreeWidget for QTreeView) are provides concrete implementations of the view and a corresponding model.
I had the same issue with my custom model. Setting dragDropOverwriteMode=false for view resolved my problem.
I think yes, you have to call removeRows() from the dropMimeData() if the Qt::DropAction is Qt::MoveAction, i.e. you completely move your tree node from one place to another.
WRT your second question, you can create your custom mime data in QAbstractItemModel::mimeData() and encode your dragged nodes initial information there. So, in dropMimeData() function you can decode and use it.

Handling client-side domain object state in a presentation model

I'm currently building the client side of a Flex/PHP project using the Presentation Model pattern.
What I'm trying to achieve:
I currently have a view displaying non-editable information about a domain object called Node. Depending on if the Node is editable and the user has the right privileges, an additional view becomes available where it's possible to make changes to this object. Any changes made are only committed to the server once the user decides to "Save Changes". If changes are made to a NodeA and the user navigates away to a different NodeB without saving them, NodeA is reverted to its original state.
Design:
I have a PM for the info view holding a reference to the current Node. The PM for the edit view is extended from this info PM, adding methods to make changes to the wrapped Node object. Both PMs has the same Node reference injected into them and all fields in the info/edit views are bound to the Node via their PMs.
The problem:
When the user makes changes to NodeA but doesn't commit them, I can't seem to think of an elegant solution to revert back to the original state. Basically, what I've thought of so far is to hold separate value copies on the edit PM, either clone-creating a new Node reference or through an identical set of Node properties. Of these two the former seems like the better idea because the Node already houses domain logic, but I wonder whether creating clones of unique domain objects is a bad practice, even if it's used in a limited scope.
I handle similar cases by storing the original data in an XML property of the Value Object ("VO"), and reset all of the other property values when the VO is needed.
So, when it is first needed to be viewed, I go get the XML:
<Node>
<prop1>value</prop1>
<prop2>value</prop2>
<prop3>value</prop3>
<prop4>value</prop4>
</Node>
When I retrieve the XML, in my result handler, the first thing I do is create an instance of my VO, and set the XML property, and then call a public function in a separate class to set the VO's properties:
private function getNodeResultHandler(event:ResultEvent):void
{
var myNode:Node = new Node();
myNode.xmlData = new XML(event.result);
nodeUtils.setNodeProperties(myNode);
}
public class nodeUtils
{
public function setNodeProperties(node:Node):void
{
var nodeXmlData:XML = node.xmlData;
myNode.prop1 = nodeXmlData.prop1;
myNode.prop2 = nodeXmlData.prop2;
myNode.prop3 = nodeXmlData.prop3;
myNode.prop4 = nodeXmlData.prop4;
}
}
Then, any time you switch your view to edit mode, you call that same function to reset the properties to the values stored in the XML.
The only other thing you need to do is reset that XML any time the user commits changes to the VO. I usually handle this by passing back the VO's data in the same format on a Save and Get, and then saving the XML just as above.
I usually do this in a Cairngorm MVC application, so I have event/command chains to handle all of this, but you can put this functionality in any number of classes, or in the VO class itself, whichever is easiest for you to maintain.
Each view should have it's own instance of your Presentation Model class. Just maintain it in memory if the user has not saved it when moving to another view. Cloning accomplishes basically the same thing through a more convoluted process.

Resources