I was trying to use a simple drag and drop feature in my Qt app. Here is my code:
MyWindow::MyWindow(QWidget *parent)
{
..........
setAcceptDrops(true);
}
void MyWindow::dragEnterEvent(QDragEnterEvent *e)
{
if (e->mimeData()->hasUrls()) {
e->acceptProposedAction();
}
}
void MyWindow::dropEvent(QDropEvent *e)
{
foreach (const QUrl &url, e->mimeData()->urls()) {
const QString &fileName = url.toLocalFile();
qDebug() << "Dropped file:" << fileName;
}
}
As you see, it simply prints the path name of the file bing dropped into the console. So when I dragged and dropped a file from my desktop into the widget, I expected something like /Users/<myName>/Desktop/<filename>
in the console. But I see something like file:///.file/id=6571367.2773272/
being printed. And when I try to use it in some way, like opening the file (text) in my in-built editor, which was working fine for all OS-es except Os X Yosemite, the app crashes.
It is a known bug, as published here, with a patch here. But I don't know how to use the patch to make my code work. There seems to be a solution with an Objective C wrapper around Qt, however, I don't know how exactly to mix C++ in Qt and Objective C.
Any idea how do I use the patch, or make it work in some other way? Somehow I need to retrieve the actual full path of the file being dropped.
Environment - Os X Yosemite, Qt Creator 3.1.1 with Qt 5.2.1.
I will need to run the same app on Windows as well (we are developing in Qt for both Windows and Mac), so looking for cross-platform solution.
Right, this a generic
How do I patch the Qt source in order to fix a bug or add a feature?
request. This may be useful to document in general, therefore here goes the answer.
You could grab the official release tarball and patch that without git or you can go through the repository. I would personally opt for the second since patching and cherry-picking with git is easier in my humble opinion. These are the steps that you need to take:
Clone the Qt 5 repository
git clone git://gitorious.org/qt/qt5.git qt5
Go to the cloned directory
cd qt5
Initialize the repository
perl init-repository
Go to the qtbase directory which you need to patch
cd qtbase
Create a gerrit account if you have none yet. This step is optional.
a. Fetch and cherry-pick the fix from Gerrit
git fetch https://[email protected]/qt/qtbase refs/changes/11/92611/4 && git cherry-pick FETCH_HEAD
b. Do not create a gerrit account
This will be feasible in this case since it is a very minor change to the source code, and all the rest is just change to the benchmarks. There are no expected updates to the craft of the change, either.
* git apply
* copy and paste the following snippet to the standard input
commit 66a305f282e33b1bf12bec21f416c8ba6730cd40
Author: Cyril Oblikov <[email protected]>
Date: Tue Aug 19 16:18:25 2014 +0300
OSX: convert file reference url to path-based url
According to Apple's spec URL can be:
path-based URL: file://localhost/Users/steve/Documents/MyFile.txt
or
file reference URL: file:///.file/id=6571367.2773272/
On OSX 10.10 file reference urls are copied to clipboard during Drag&Drop.
This patch converts file reference url to path-based url.
Comment on performance: converting 1000 urls on Macbook Air 2013 takes
about 15 ms.
Also benchmark is added.
Change-Id: Ia42386cd90d1eb11d04ab33705f5eece6c13f370
diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm
index 6fcd19e..2bb623f 100644
--- a/src/platformsupport/clipboard/qmacmime.mm
+++ b/src/platformsupport/clipboard/qmacmime.mm
@@ -614,6 +614,8 @@ QVariant QMacPasteboardMimeFileUri::convertToMime(const QString &mime, QList<QBy
QUrl url = QUrl::fromEncoded(data.at(i));
if (url.host().toLower() == QLatin1String("localhost"))
url.setHost(QString());
+ if (url.host().isEmpty() && url.path().startsWith(QLatin1String("/.file/id=")))
+ url = QUrl::fromNSURL([url.toNSURL() filePathURL]);
url.setPath(url.path().normalized(QString::NormalizationForm_C));
ret.append(url);
}
Configure the project
./configure -developer-build -opensource -nomake examples -nomake tests
Build and install the project
make -j4 all install
Go get some tea until it is ready