QMimeData encoding types - qt

In my app I'm doing internal drag and drops with a QTreeView. Using the tutorial I can happily drag and drop a single leaf by encoding it into a string list using the mime type "application/vnd.text.list".
I then wanted to drag and drop a tree node that had some children and thought the best route to doing this would be to encode the pointer to the node and iterate through all the children in the dropMimeData method.
I declared a mime type in the mimeTypes() method:
QStringList toResultModel::mimeTypes() const {
QStringList types;
types << "text/plain";
types << "application/vnd.mypointerlist.list";
return types;
}
And tried to pass the same string list across, but the application crashes in the dropMimeData() method.
It seems the mime type "application/vnd.text.list" has some hidden meaning which I am unable to find.
I have found this source code: http://fossies.org/linux/tora/src/toresultmodel.cpp where the author sets up a custom coding type "application/vnd.tomodel.list" and also uses "application/vnd.int.list".
What are the rules in using encoding types?
Where are the built-in types strings defined?
Which type should I use for passing a pointer to a tree node?

Four years later...
From the information you give, if your method crashes, it's not related to Drag and Drop in particular, there is some error you need to find in the code. that said, let me clarify D&D in Qt, and answer your question about MIME types. While you have indeed solved the problem you had four years ago, this may be useful for other users today.
You may define your own type for the purpose of your application or reuse an existing one. How to choose?
Can you use an existing MIME type, like text/plain?
Think about your application being the target of a D&D operation initiated from another application. Can you accept an existing MIME type and retrieve your data from it?
Think about another application being the target of a D&D operation initiated from within your application. Could this application handle an existing MIME type?
If this answer is no to any of the questions, then you might have to use your own specific MIME type.
The format name itself is not important
The constraint is that it must be unique, so that you can't receive incorrectly formatted MIME data from another application, and other applications can identify the MIME type as one they cannot handle, and ignore it.
The exact MIME type name doesn't matter as you'll provide the encoder and the decoder into your data model (e.g. see this introduction to view/model for Qt), as well as other information about the MIME type(s) used.
In QAbstractItemModel::mimeTypes, list only the MIME types you are able to deal with. If you don't plan to accept or send MIME data from/to other applications, there is no need to allow more than your specific MIME type.
When your application is the source of a D&D operation, encode (serialize) the MIME data in QAbstractItemModel::mimeData(indexes). The result of the serialization must be a byte array, even when there are multiple indexes to be dragged. The internal format is yours. Include any information required to decode (de-serialize) MIME data. Note that you must provide encoded data in each of the MIME type you've listed in QAbstractItemModel::mimeTypes (see previous point).
When your D&D data are dragged over your application UI, QAbstractItemModel::canDropMimeData(self, mime_data, action, row, column, parent) is called to determine if this location is valid for a drop. You may determine here whether the drop should be allowed at this location. In particular, you may test the content of the MIME data provided, and use mime_data.hasFormat(mime_type) to check if the format you expect is found in the data about to be drooped. Returning false will prevent a drop at this location and a "not allowed here" indication will be provided to the user (this won't cancel the D&D operation itself, the user can continue to move the mouse elsewhere).
When the data is actually dropped, QAbstractItemModel::dropMimeData(mime_data, action, row, column, parent) is called. Get the MIME data format(s) used using QMimeData::hasFormat(mime_type). If you don't find the MIME type you expect, ignore the drop operation as you cannot decode the data provided (the D&D was initiated from another application). This shouldn't happen as prior to drop data, the application has called QAbstractItemModel::canDropMimeData as seen in the previous point. If everything is ok decode the MIME data, and update your model with the data received.
On the other hand, your tree leaf data may fit as path+name encoded in text/plain MIME data, so maybe you can just use this type too. However as other applications can generate text/plain data that don't contain a tree leaf description, you need, in this case, to have a mean to identify irrelevant data and ignore them. It's obvious such approach will need more code for verification of the validity of the drop action than when using a specific MIME type. However this allows to interact with other applications, and is indeed relevant to drag from well know applications like Excel (e.g. cell content) or Firefox (e.g. rich text or image), else we couldn't re-use information from these applications using D&D.
Do you need to use vnd prefix?
vnd in the MIME type means "vendor specific". This prefix is used to distinguish vendors created MIME types from those created by IANA authority. From RFC 6838:
Vendor-tree registrations will be distinguished by the leading facet
"vnd.". That may be followed, at the discretion of the registrant, by
either a media subtype name from a well-known producer (e.g.,
"vnd.mudpie") or by an IANA-approved designation of the producer's
name that is followed by a media type or product designation (e.g.,
vnd.bigcompany.funnypictures).
So in your Drag&Drop tutorial the application/vnd.text.list is a specific one supposedly created by some vendor for their own purpose. Same for application/vnd.mypointerlist.list
In contrast, text/plain is a standard MIME type defined by IANA in RFC 2046. This defines a human readable text:
Plain text does not provide for or allow formatting commands, font
attribute specifications, processing instructions, interpretation
directives, or content markup. Plain text is seen simply as a
linear sequence of characters, possibly interrupted by line breaks
or page breaks. Plain text may allow the stacking of several
characters in the same position in the text. Plain text in scripts
like Arabic and Hebrew may also include facilitites that allow the
arbitrary mixing of text segments with opposite writing directions.
For your type, you may want to use vnd followed by a subtype which is specific to your application, for consistency considerations. But as seen, the actual name is not important, as long as you know which one you use and you are not interacting with other applications in the D&D chain.

Related

JSON-LD, is there any way to specify the default URI for the #id of a #type or the values of a property?

(I've already asked this on the W3/JSON mailing list, I'll try here too.)
I'm fairly new to JSON-LD, although I have significant experience with Semantic Web technologies.
I've read the guideline document (https://www.w3.org/TR/json-ld/) and I haven't get if the feature at issue is supported:
Suppose you have JSON objects of #type Person and #type Address, both having the #id property. Typical API-coming data will have values like integers or some internal, context-dependant IDs. It's pretty common to RDF-translate those values to prefix-based URIs like http://www.example.com/Person/123 or http://www.example.com/Address/xh324m44.
What I would like to do is to specify those prefixes and keep data telling #id = '123', with the value joins happening at RDF serialisation stage (the same specification would make it possible to do the opposite conversion too). Clearly, in such a use case, the prefixes depend on the #type of objects, and the #base mechanism is not enough. Moreover, it would be useful to have this mechanism available for properties too, e.g., to associate the address URI prefix to the values of the "address" JSON property.
It doesn't seem that this is currently available in JSON-LD, or am I missing something? Any plan for future extensions?
You can use #base in the context to create a URI base for values of #id, but this will not include something from #type. This sounds like something you might get by defining a URI template and using variables to expand type and id to create a URI. You can do this in a templating language and create the JSON-LD, but not directly in JSON-LD itself. Not likely to be a feature included by the language in the future, either, as it's application is pretty narrow.

HttpServletRequest getting request parameters separated by # instead of?

I am trying to get the Query String Parameters in the controller from the following URL using javax.servlet.http.HttpServletRequest object:
http://example.com:8080/OAuthClient/oauth-callback#access_token=something&expires_in=1209600&username=abcuser
It does not work because it is separated by # instead of ?
Hence it works if I change the request to http://example.com:8080/OAuthClient/oauth-callback?access_token=something&expires_in=1209600&username=abcuser
Is there a way to work around this problem? I have to make it work with # separated query parameters. which property will contain the data after oauth-callback?
Those aren't query parameters. They're the fragment of the URI - and that isn't sent to the server at all. It can only be used client-side.
From RFC 3986:
A fragment identifier component is indicated by the presence of a number sign ("#") character and terminated by the end of the URI.
... and (emphasis mine)
Fragment identifiers have a special role in information retrieval
systems as the primary form of client-side indirect referencing,
allowing an author to specifically identify aspects of an existing
resource that are only indirectly provided by the resource owner. As
such, the fragment identifier is not used in the scheme-specific
processing of a URI; instead, the fragment identifier is separated
from the rest of the URI prior to a dereference, and thus the
identifying information within the fragment itself is dereferenced
solely by the user agent, regardless of the URI scheme.

What are the differences between getRawSomething and getSomething methods on Archetypes contents (eg. ATNewsItem)?

What are the differences between getRawSomething and getSomething methods on Archetypes contents (eg. ATNewsItem)?
For exemple, what is the difference between getRawImage and getImage? Or getRawRelatedItems and getRelatedItems? etc.
getRaw* gives you the direct, unprocessed raw data as stored on the object. The get* methods are allowed to transform that data in some way as needed.
For example, TextField fields will transform text to safe HTML when using get, but getRaw() gives you the untransformed data, be that markdown, restructuredtext or unprocessed HTML.
From the developer documentation:
Archetypes has two kinds of access methods:
normal, getSomething(), which filters output;
raw, the so-called edit accessor, getRawSomething() which does not filter output.
When you want to edit the current contents of a field, use getRaw*, when rendering the contents, use get*.
Specifically, related items are stored in a reference field, where the getRaw() method returns object UIDs, the get() method returns objects, having first resolved the UIDs for you.
Image fields, like file fields, will wrap the data in the associated object type (OFS.Image for image fields) if not already that type when using .get() but return whatever the underlying storage has got for .getRaw(). Usually the object is already wrapped though.

Qt: Pass pointer to QObject in QMimeData

Is it possible to pass a pointer to a QObject using QMimeData during drag-and-drop operation? QMimeData only has this function for storing data:
void QMimeData::setData(constQString &mimeType, const QByteArray &data)
but I can't find a way to safely encode a pointer into a QByteArray.
To clarify my goal: I need to pass a pointer to a QObject from a model to the target widget during the drag-and-drop operation.
Edit:
As far as I undrestand Mime data is all about passing application independent data from one place to another: urls, colors, html code. In my case I need to pass a pointer to a resource object eithin the application. How to you usually deal with this kind of drag-drops?
Thanks
Anton
You can subclass QMimeData and pass whatever you want.
To be on the safe & elegant side, I would come up with unique identifiers (e.g. strings, or numbers) for my objects and pass them as mime objects. Resolving a string back into the corresponding object using QHashmap is fast enough for your purpose.
The dirtiest (not recommended!) way would be that the identifier is the pointer address as int.
If you pass mime data with user interaction, you never know where it goes. If the user drops your pointer onto another application's window, it should fullfill the user's expectations best.
An application that gets a mangled up mime object and crashes for it is worst.
An application that gets a descriptive string and enables the user to understand what he was dropping is probably best.
I know that you can also, using the mime type, somewhat direct where the payload may be dropped and where not. the quintessence however is that you should stay within the mime concept. And that includes not passing a raw pointer.
As Kash said and the Qt docs suggest, subclass QMimeData.
Then, add the following:
text/plain data describing or representing the dragged object, so if you drop this data to notepad.exe, it results in something relevant
custom data type with an identifier or token that enables you to know that some dropped mime data is actually your subclass
add your own data in the subclass
You will still need to test the qobject_cast (or dynamic_cast), because some other program might have proxied your mime data object.

Optional parameters in ASP.NET web service

I have a ASP.NET web service. This web service works fine. However, the WSDL lists some parameters as optional (minoccurs = 0) and others as non-optional. Some of the optional parameters are actually not optional, others which are marked as non-optional are actually optional. I would like to fix this, but I can't find the location where this information is coming from.
It seems to me that all primitive types (int, boolean etc.) are non-optional and all other parameters are marked as optional. However, I can't find a location where I can change this. I would like to specify default values for the primitive values if they are missing in the request and specify which non-primitive parameter is actually optional. Where do I do this?
I am assuming that when you say ASP.net web services, you are creating web services with ASMX extension. I think that what happens in this case is that all nullable types become optional and non-nullable become non-optional.
You could perhaps manually edit the generated WSDL file. But then you would have to redo that work if the wsdl was regenerated.
I would suggest that you switch to WCF with basisHttpBinding (except for the name of you service your clients should not notice the difference).
Using WCF you can simply mark the parameter in the data contract as required or not:
[DataMember(IsRequired="false")]
The primitives are not reference types, but rather they are value types. You can make a value type "nullable" a couple ways.
The short-hand is
int? i;
or long-hand here
Nullable<int> i;

Resources