Merge lp:~osomon/unity-2d/drag-from-dash into lp:unity-2d/3.0
- drag-from-dash
- Merge into natty
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Florian Boucault | ||||||||
Approved revision: | 571 | ||||||||
Merged at revision: | 579 | ||||||||
Proposed branch: | lp:~osomon/unity-2d/drag-from-dash | ||||||||
Merge into: | lp:unity-2d/3.0 | ||||||||
Diff against target: |
543 lines (+426/-5) 10 files modified
launcher/UnityApplications/place.cpp (+2/-2) launcher/app/launcherview.cpp (+1/-2) libunity-2d-private/Unity2d/CMakeLists.txt (+4/-0) libunity-2d-private/Unity2d/dragitem.cpp (+159/-0) libunity-2d-private/Unity2d/dragitem.h (+77/-0) libunity-2d-private/Unity2d/dragitemwithurl.cpp (+82/-0) libunity-2d-private/Unity2d/dragitemwithurl.h (+62/-0) libunity-2d-private/Unity2d/plugin.cpp (+2/-0) places/AbstractButton.qml (+8/-1) places/UnityDefaultRenderer.qml (+29/-0) |
||||||||
To merge this branch: | bzr merge lp:~osomon/unity-2d/drag-from-dash | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Florian Boucault (community) | code | Needs Fixing | |
Review via email: mp+61438@code.launchpad.net |
Commit message
[dash] Support dragging files and installed applications from the dash to the launcher, the desktop or file managers.
Description of the change
This branch introduces a new QML item, DragItemWithUrl, used in the dash to allow initiating drag events from the elements displayed in the places.
Installed applications and files can be dragged to the launcher, to the desktop or to any window that accepts drag events with "file://" URLs (e.g. file managers).
Available (non installed) applications cannot be dragged.
The careful reviewer will test that the functionality works as expected, that this doesn’t introduce regressions in the dash (in particular opening files/folders and launching applications) and in the launcher (drag’n’drop of desktop files from a file manager, drag’n’drop of files to the trash, drag’n’drop of URLs from the browser’s address bar).
Florian Boucault (fboucault) wrote : | # |
Olivier Tilloy (osomon) wrote : | # |
No, unfortunately I have no idea how to improve this. The code is quite simple so I’m probably missing something obvious. Any suggestions are welcome.
- 568. By Olivier Tilloy
-
Nice antialiased icons during drag’n’drop if compositing is enabled.
- 569. By Olivier Tilloy
-
Cheap solution to avoid aliasing when compositiong is disabled: draw a solid white background.
Olivier Tilloy (osomon) wrote : | # |
The last two revisions fix the aliasing problem. There are two possible cases:
- if compositing is enabled, the icon is nicely antialiased, as one would expect
- if compositing is disabled, the icon is drawn on a solid white background (with rounded corners to make it easier on the eye), so that aliasing is not visible
Comments on the fallback when compositing is disabled are welcome, we can probably implement something different if needed.
Florian Boucault (fboucault) wrote : | # |
Functionally beautiful now!
Florian Boucault (fboucault) wrote : | # |
Overall the code is nice and simple.
A few comments:
- a Component should be passed as DragItemWithUrl's delegate as to not create Image instances unless necessary. Instead of:
DragItemWithUrl {
delegate: Image {...}
}
Use:
DragItemWithUrl {
delegate: imageComponentId
}
Component {
id: imageComponentId
Image {...}
}
- DeclarativeDrag
- The workaround that has been added to AbstractButton could use a link to qt bug report 13007 that if I am right should remove the need for it in the future (http://
- 570. By Olivier Tilloy
-
Made the delegate a Component so that it’s instantiated on demand only when needed.
- 571. By Olivier Tilloy
-
Add a comment and link to QTBUG-13007.
Olivier Tilloy (osomon) wrote : | # |
> - a Component should be passed as DragItemWithUrl's delegate as to not create
> Image instances unless necessary. Instead of:
Thanks for pointing this out. I had originally tried to write it this way, but I had failed to do so. I tackled the problem again, this time successfully. This is revision 570.
> - DeclarativeDrag
> 'dragInitiated'
Nope, it’s called 'drop' because it’s actually emitted upon dropping the dragged item, not when the drag action is initiated.
> - The workaround that has been added to AbstractButton could use a link to qt
> bug report 13007 that if I am right should remove the need for it in the
> future (http://
You’re right. Added at revision 571.
Preview Diff
1 | === modified file 'launcher/UnityApplications/place.cpp' | |||
2 | --- launcher/UnityApplications/place.cpp 2011-05-03 15:38:35 +0000 | |||
3 | +++ launcher/UnityApplications/place.cpp 2011-05-30 16:06:44 +0000 | |||
4 | @@ -429,8 +429,8 @@ | |||
5 | 429 | /* Cannot set the desktop file to url.host(), because the QUrl constructor | 429 | /* Cannot set the desktop file to url.host(), because the QUrl constructor |
6 | 430 | converts the host name to lower case to conform to the Nameprep | 430 | converts the host name to lower case to conform to the Nameprep |
7 | 431 | RFC (see http://doc.qt.nokia.com/qurl.html#FormattingOption-enum). | 431 | RFC (see http://doc.qt.nokia.com/qurl.html#FormattingOption-enum). |
10 | 432 | Ref: http://bugs.launchpad.net/unity-2d/+bug/723604 */ | 432 | Ref: https://bugs.launchpad.net/unity-place-applications/+bug/784478 */ |
11 | 433 | QString desktopFile = uri.right(uri.size() - uri.indexOf("://") - 3); | 433 | QString desktopFile = uri.mid(uri.indexOf("://") + 3); |
12 | 434 | application.setDesktopFile(desktopFile); | 434 | application.setDesktopFile(desktopFile); |
13 | 435 | application.activate(); | 435 | application.activate(); |
14 | 436 | return; | 436 | return; |
15 | 437 | 437 | ||
16 | === modified file 'launcher/app/launcherview.cpp' | |||
17 | --- launcher/app/launcherview.cpp 2011-05-19 14:12:41 +0000 | |||
18 | +++ launcher/app/launcherview.cpp 2011-05-30 16:06:44 +0000 | |||
19 | @@ -271,8 +271,7 @@ | |||
20 | 271 | foreach (QUrl url, getEventUrls(event)) { | 271 | foreach (QUrl url, getEventUrls(event)) { |
21 | 272 | if (url.scheme() == "file" && url.path().endsWith(".desktop")) { | 272 | if (url.scheme() == "file" && url.path().endsWith(".desktop")) { |
22 | 273 | emit desktopFileDropped(url.path()); | 273 | emit desktopFileDropped(url.path()); |
25 | 274 | } | 274 | } else if (url.scheme().startsWith("http")) { |
24 | 275 | else if (url.scheme().startsWith("http")) { | ||
26 | 276 | emit webpageUrlDropped(url); | 275 | emit webpageUrlDropped(url); |
27 | 277 | } | 276 | } |
28 | 278 | } | 277 | } |
29 | 279 | 278 | ||
30 | === modified file 'libunity-2d-private/Unity2d/CMakeLists.txt' | |||
31 | --- libunity-2d-private/Unity2d/CMakeLists.txt 2011-02-17 12:04:10 +0000 | |||
32 | +++ libunity-2d-private/Unity2d/CMakeLists.txt 2011-05-30 16:06:44 +0000 | |||
33 | @@ -15,6 +15,8 @@ | |||
34 | 15 | cacheeffect.cpp | 15 | cacheeffect.cpp |
35 | 16 | workspacesinfo.cpp | 16 | workspacesinfo.cpp |
36 | 17 | signalwaiter.cpp | 17 | signalwaiter.cpp |
37 | 18 | dragitem.cpp | ||
38 | 19 | dragitemwithurl.cpp | ||
39 | 18 | dropitem.cpp | 20 | dropitem.cpp |
40 | 19 | ) | 21 | ) |
41 | 20 | 22 | ||
42 | @@ -27,6 +29,8 @@ | |||
43 | 27 | cacheeffect.h | 29 | cacheeffect.h |
44 | 28 | workspacesinfo.h | 30 | workspacesinfo.h |
45 | 29 | signalwaiter.h | 31 | signalwaiter.h |
46 | 32 | dragitem.h | ||
47 | 33 | dragitemwithurl.h | ||
48 | 30 | dropitem.h | 34 | dropitem.h |
49 | 31 | ) | 35 | ) |
50 | 32 | 36 | ||
51 | 33 | 37 | ||
52 | === added file 'libunity-2d-private/Unity2d/dragitem.cpp' | |||
53 | --- libunity-2d-private/Unity2d/dragitem.cpp 1970-01-01 00:00:00 +0000 | |||
54 | +++ libunity-2d-private/Unity2d/dragitem.cpp 2011-05-30 16:06:44 +0000 | |||
55 | @@ -0,0 +1,159 @@ | |||
56 | 1 | /* | ||
57 | 2 | * Copyright (C) 2011 Canonical, Ltd. | ||
58 | 3 | * | ||
59 | 4 | * Authors: | ||
60 | 5 | * Olivier Tilloy <olivier.tilloy@canonical.com> | ||
61 | 6 | * | ||
62 | 7 | * This program is free software; you can redistribute it and/or modify | ||
63 | 8 | * it under the terms of the GNU General Public License as published by | ||
64 | 9 | * the Free Software Foundation; version 3. | ||
65 | 10 | * | ||
66 | 11 | * This program is distributed in the hope that it will be useful, | ||
67 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
68 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
69 | 14 | * GNU General Public License for more details. | ||
70 | 15 | * | ||
71 | 16 | * You should have received a copy of the GNU General Public License | ||
72 | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
73 | 18 | */ | ||
74 | 19 | |||
75 | 20 | #include "dragitem.h" | ||
76 | 21 | |||
77 | 22 | #include <QDeclarativeEngine> | ||
78 | 23 | #include <QDeclarativeComponent> | ||
79 | 24 | #include <QGraphicsSceneMouseEvent> | ||
80 | 25 | #include <QApplication> | ||
81 | 26 | #include <QDrag> | ||
82 | 27 | #include <QGraphicsScene> | ||
83 | 28 | #include <QPainter> | ||
84 | 29 | #include <QMimeData> | ||
85 | 30 | #include <QX11Info> | ||
86 | 31 | |||
87 | 32 | DeclarativeDragItem::DeclarativeDragItem(QDeclarativeItem* parent) | ||
88 | 33 | : QDeclarativeItem(parent) | ||
89 | 34 | , m_delegate(NULL) | ||
90 | 35 | , m_supportedActions(Qt::LinkAction) | ||
91 | 36 | , m_defaultAction(Qt::LinkAction) | ||
92 | 37 | { | ||
93 | 38 | setAcceptedMouseButtons(Qt::LeftButton); | ||
94 | 39 | } | ||
95 | 40 | |||
96 | 41 | DeclarativeDragItem::~DeclarativeDragItem() | ||
97 | 42 | { | ||
98 | 43 | } | ||
99 | 44 | |||
100 | 45 | QDeclarativeComponent* | ||
101 | 46 | DeclarativeDragItem::delegate() const | ||
102 | 47 | { | ||
103 | 48 | return m_delegate; | ||
104 | 49 | } | ||
105 | 50 | |||
106 | 51 | void | ||
107 | 52 | DeclarativeDragItem::setDelegate(QDeclarativeComponent* delegate) | ||
108 | 53 | { | ||
109 | 54 | if (delegate != m_delegate) { | ||
110 | 55 | m_delegate = delegate; | ||
111 | 56 | Q_EMIT delegateChanged(); | ||
112 | 57 | } | ||
113 | 58 | } | ||
114 | 59 | |||
115 | 60 | void | ||
116 | 61 | DeclarativeDragItem::resetDelegate() | ||
117 | 62 | { | ||
118 | 63 | setDelegate(NULL); | ||
119 | 64 | } | ||
120 | 65 | |||
121 | 66 | Qt::DropActions | ||
122 | 67 | DeclarativeDragItem::supportedActions() const | ||
123 | 68 | { | ||
124 | 69 | return m_supportedActions; | ||
125 | 70 | } | ||
126 | 71 | |||
127 | 72 | void | ||
128 | 73 | DeclarativeDragItem::setSupportedActions(Qt::DropActions actions) | ||
129 | 74 | { | ||
130 | 75 | if (actions != m_supportedActions) { | ||
131 | 76 | m_supportedActions = actions; | ||
132 | 77 | Q_EMIT supportedActionsChanged(); | ||
133 | 78 | } | ||
134 | 79 | } | ||
135 | 80 | |||
136 | 81 | Qt::DropAction | ||
137 | 82 | DeclarativeDragItem::defaultAction() const | ||
138 | 83 | { | ||
139 | 84 | return m_defaultAction; | ||
140 | 85 | } | ||
141 | 86 | |||
142 | 87 | void | ||
143 | 88 | DeclarativeDragItem::setDefaultAction(Qt::DropAction action) | ||
144 | 89 | { | ||
145 | 90 | if (action != m_defaultAction) { | ||
146 | 91 | m_defaultAction = action; | ||
147 | 92 | Q_EMIT defaultActionChanged(); | ||
148 | 93 | } | ||
149 | 94 | } | ||
150 | 95 | |||
151 | 96 | QMimeData* DeclarativeDragItem::mimeData() const | ||
152 | 97 | { | ||
153 | 98 | // Default implementation, empty mime data. | ||
154 | 99 | return new QMimeData; | ||
155 | 100 | } | ||
156 | 101 | |||
157 | 102 | void | ||
158 | 103 | DeclarativeDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event) | ||
159 | 104 | { | ||
160 | 105 | int distance = (event->buttonDownScreenPos(Qt::LeftButton) - event->screenPos()).manhattanLength(); | ||
161 | 106 | if (distance < QApplication::startDragDistance()) { | ||
162 | 107 | return; | ||
163 | 108 | } | ||
164 | 109 | |||
165 | 110 | QDrag* drag = new QDrag(event->widget()); | ||
166 | 111 | drag->setMimeData(mimeData()); | ||
167 | 112 | |||
168 | 113 | if (m_delegate != NULL) { | ||
169 | 114 | QObject* delegateObject = m_delegate->create(QDeclarativeEngine::contextForObject(this)); | ||
170 | 115 | QDeclarativeItem* delegate = qobject_cast<QDeclarativeItem*>(delegateObject); | ||
171 | 116 | if (delegate != NULL) { | ||
172 | 117 | /* Render the delegate to a pixmap. */ | ||
173 | 118 | QGraphicsScene scene; | ||
174 | 119 | scene.addItem(delegate); | ||
175 | 120 | |||
176 | 121 | QPixmap pixmap(scene.sceneRect().width(), scene.sceneRect().height()); | ||
177 | 122 | bool compositing = QX11Info::isCompositingManagerRunning(); | ||
178 | 123 | if (!compositing) { | ||
179 | 124 | pixmap.fill(Qt::transparent); | ||
180 | 125 | } | ||
181 | 126 | QPainter painter(&pixmap); | ||
182 | 127 | if (compositing) { | ||
183 | 128 | painter.setCompositionMode(QPainter::CompositionMode_Source); | ||
184 | 129 | } else { | ||
185 | 130 | /* Cheap solution to avoid aliasing: draw a solid white background. */ | ||
186 | 131 | painter.setPen(Qt::white); | ||
187 | 132 | painter.setBrush(Qt::white); | ||
188 | 133 | painter.drawRoundedRect(scene.sceneRect(), 5, 5); | ||
189 | 134 | } | ||
190 | 135 | scene.render(&painter); | ||
191 | 136 | scene.removeItem(delegate); | ||
192 | 137 | delete delegate; | ||
193 | 138 | |||
194 | 139 | drag->setPixmap(pixmap); | ||
195 | 140 | drag->setHotSpot(QPoint(pixmap.width() / 2, pixmap.height() / 2)); | ||
196 | 141 | } | ||
197 | 142 | } | ||
198 | 143 | |||
199 | 144 | Qt::DropAction action = drag->exec(m_supportedActions, m_defaultAction); | ||
200 | 145 | Q_EMIT drop(action); | ||
201 | 146 | } | ||
202 | 147 | |||
203 | 148 | void | ||
204 | 149 | DeclarativeDragItem::mousePressEvent(QGraphicsSceneMouseEvent* event) | ||
205 | 150 | { | ||
206 | 151 | Q_EMIT pressed(); | ||
207 | 152 | } | ||
208 | 153 | |||
209 | 154 | void | ||
210 | 155 | DeclarativeDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) | ||
211 | 156 | { | ||
212 | 157 | Q_EMIT released(); | ||
213 | 158 | } | ||
214 | 159 | |||
215 | 0 | 160 | ||
216 | === added file 'libunity-2d-private/Unity2d/dragitem.h' | |||
217 | --- libunity-2d-private/Unity2d/dragitem.h 1970-01-01 00:00:00 +0000 | |||
218 | +++ libunity-2d-private/Unity2d/dragitem.h 2011-05-30 16:06:44 +0000 | |||
219 | @@ -0,0 +1,77 @@ | |||
220 | 1 | /* | ||
221 | 2 | * Copyright (C) 2011 Canonical, Ltd. | ||
222 | 3 | * | ||
223 | 4 | * Authors: | ||
224 | 5 | * Olivier Tilloy <olivier.tilloy@canonical.com> | ||
225 | 6 | * | ||
226 | 7 | * This program is free software; you can redistribute it and/or modify | ||
227 | 8 | * it under the terms of the GNU General Public License as published by | ||
228 | 9 | * the Free Software Foundation; version 3. | ||
229 | 10 | * | ||
230 | 11 | * This program is distributed in the hope that it will be useful, | ||
231 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
232 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
233 | 14 | * GNU General Public License for more details. | ||
234 | 15 | * | ||
235 | 16 | * You should have received a copy of the GNU General Public License | ||
236 | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
237 | 18 | */ | ||
238 | 19 | |||
239 | 20 | #ifndef DeclarativeDragItem_H | ||
240 | 21 | #define DeclarativeDragItem_H | ||
241 | 22 | |||
242 | 23 | #include <QDeclarativeItem> | ||
243 | 24 | |||
244 | 25 | class QMimeData; | ||
245 | 26 | class QDeclarativeComponent; | ||
246 | 27 | |||
247 | 28 | class DeclarativeDragItem : public QDeclarativeItem | ||
248 | 29 | { | ||
249 | 30 | Q_OBJECT | ||
250 | 31 | |||
251 | 32 | Q_PROPERTY(QDeclarativeComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged RESET resetDelegate) | ||
252 | 33 | Q_PROPERTY(Qt::DropActions supportedActions READ supportedActions WRITE setSupportedActions NOTIFY supportedActionsChanged) | ||
253 | 34 | Q_PROPERTY(Qt::DropAction defaultAction READ defaultAction WRITE setDefaultAction NOTIFY defaultActionChanged) | ||
254 | 35 | |||
255 | 36 | public: | ||
256 | 37 | DeclarativeDragItem(QDeclarativeItem* parent=0); | ||
257 | 38 | ~DeclarativeDragItem(); | ||
258 | 39 | |||
259 | 40 | // getters and setters | ||
260 | 41 | QDeclarativeComponent* delegate() const; | ||
261 | 42 | void setDelegate(QDeclarativeComponent* delegate); | ||
262 | 43 | void resetDelegate(); | ||
263 | 44 | Qt::DropActions supportedActions() const; | ||
264 | 45 | void setSupportedActions(Qt::DropActions actions); | ||
265 | 46 | Qt::DropAction defaultAction() const; | ||
266 | 47 | void setDefaultAction(Qt::DropAction action); | ||
267 | 48 | |||
268 | 49 | protected: | ||
269 | 50 | // override in child classes to set a non-empty mime data | ||
270 | 51 | virtual QMimeData* mimeData() const; | ||
271 | 52 | |||
272 | 53 | Q_SIGNALS: | ||
273 | 54 | void delegateChanged(); | ||
274 | 55 | void supportedActionsChanged(); | ||
275 | 56 | void defaultActionChanged(); | ||
276 | 57 | void drop(int action); | ||
277 | 58 | |||
278 | 59 | // Can’t pass around the mouse events as parameters | ||
279 | 60 | // as QDeclarativeMouseEvent is a private class. | ||
280 | 61 | void pressed(); | ||
281 | 62 | void released(); | ||
282 | 63 | |||
283 | 64 | protected: | ||
284 | 65 | // reimplemented | ||
285 | 66 | void mouseMoveEvent(QGraphicsSceneMouseEvent* event); | ||
286 | 67 | void mousePressEvent(QGraphicsSceneMouseEvent* event); | ||
287 | 68 | void mouseReleaseEvent(QGraphicsSceneMouseEvent* event); | ||
288 | 69 | |||
289 | 70 | private: | ||
290 | 71 | QDeclarativeComponent* m_delegate; | ||
291 | 72 | Qt::DropActions m_supportedActions; | ||
292 | 73 | Qt::DropAction m_defaultAction; | ||
293 | 74 | }; | ||
294 | 75 | |||
295 | 76 | #endif // DeclarativeDragItem_H | ||
296 | 77 | |||
297 | 0 | 78 | ||
298 | === added file 'libunity-2d-private/Unity2d/dragitemwithurl.cpp' | |||
299 | --- libunity-2d-private/Unity2d/dragitemwithurl.cpp 1970-01-01 00:00:00 +0000 | |||
300 | +++ libunity-2d-private/Unity2d/dragitemwithurl.cpp 2011-05-30 16:06:44 +0000 | |||
301 | @@ -0,0 +1,82 @@ | |||
302 | 1 | /* | ||
303 | 2 | * Copyright (C) 2011 Canonical, Ltd. | ||
304 | 3 | * | ||
305 | 4 | * Authors: | ||
306 | 5 | * Olivier Tilloy <olivier.tilloy@canonical.com> | ||
307 | 6 | * | ||
308 | 7 | * This program is free software; you can redistribute it and/or modify | ||
309 | 8 | * it under the terms of the GNU General Public License as published by | ||
310 | 9 | * the Free Software Foundation; version 3. | ||
311 | 10 | * | ||
312 | 11 | * This program is distributed in the hope that it will be useful, | ||
313 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
314 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
315 | 14 | * GNU General Public License for more details. | ||
316 | 15 | * | ||
317 | 16 | * You should have received a copy of the GNU General Public License | ||
318 | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
319 | 18 | */ | ||
320 | 19 | |||
321 | 20 | #include "dragitemwithurl.h" | ||
322 | 21 | |||
323 | 22 | // libunity-2d | ||
324 | 23 | #include <gscopedpointer.h> | ||
325 | 24 | |||
326 | 25 | // GIO | ||
327 | 26 | #undef signals | ||
328 | 27 | extern "C" { | ||
329 | 28 | #include <gio/gdesktopappinfo.h> | ||
330 | 29 | } | ||
331 | 30 | |||
332 | 31 | // Qt | ||
333 | 32 | #include <QMimeData> | ||
334 | 33 | |||
335 | 34 | DeclarativeDragItemWithUrl::DeclarativeDragItemWithUrl(QDeclarativeItem* parent) | ||
336 | 35 | : DeclarativeDragItem(parent) | ||
337 | 36 | { | ||
338 | 37 | } | ||
339 | 38 | |||
340 | 39 | DeclarativeDragItemWithUrl::~DeclarativeDragItemWithUrl() | ||
341 | 40 | { | ||
342 | 41 | } | ||
343 | 42 | |||
344 | 43 | const QString& DeclarativeDragItemWithUrl::url() const | ||
345 | 44 | { | ||
346 | 45 | return m_url; | ||
347 | 46 | } | ||
348 | 47 | |||
349 | 48 | void DeclarativeDragItemWithUrl::setUrl(const QString& url) | ||
350 | 49 | { | ||
351 | 50 | if (url != m_url) { | ||
352 | 51 | m_url = url; | ||
353 | 52 | Q_EMIT urlChanged(m_url); | ||
354 | 53 | } | ||
355 | 54 | } | ||
356 | 55 | |||
357 | 56 | QMimeData* DeclarativeDragItemWithUrl::mimeData() const | ||
358 | 57 | { | ||
359 | 58 | QMimeData* data = new QMimeData; | ||
360 | 59 | if (!m_url.isEmpty()) { | ||
361 | 60 | QList<QUrl> urls; | ||
362 | 61 | urls.append(decodeUri(m_url)); | ||
363 | 62 | data->setUrls(urls); | ||
364 | 63 | } | ||
365 | 64 | return data; | ||
366 | 65 | } | ||
367 | 66 | |||
368 | 67 | QUrl DeclarativeDragItemWithUrl::decodeUri(const QString& uri) | ||
369 | 68 | { | ||
370 | 69 | if (uri.startsWith("application://")) { | ||
371 | 70 | QString desktopFileName = uri.mid(14); | ||
372 | 71 | QByteArray bytes = desktopFileName.toUtf8(); | ||
373 | 72 | GObjectScopedPointer<GDesktopAppInfo> appInfo(g_desktop_app_info_new(bytes.constData())); | ||
374 | 73 | if (appInfo.isNull()) { | ||
375 | 74 | return QUrl(uri); | ||
376 | 75 | } | ||
377 | 76 | QString filePath = QString::fromUtf8(g_desktop_app_info_get_filename(appInfo.data())); | ||
378 | 77 | return QUrl("file://" + filePath); | ||
379 | 78 | } else { | ||
380 | 79 | return QUrl(uri); | ||
381 | 80 | } | ||
382 | 81 | } | ||
383 | 82 | |||
384 | 0 | 83 | ||
385 | === added file 'libunity-2d-private/Unity2d/dragitemwithurl.h' | |||
386 | --- libunity-2d-private/Unity2d/dragitemwithurl.h 1970-01-01 00:00:00 +0000 | |||
387 | +++ libunity-2d-private/Unity2d/dragitemwithurl.h 2011-05-30 16:06:44 +0000 | |||
388 | @@ -0,0 +1,62 @@ | |||
389 | 1 | /* | ||
390 | 2 | * Copyright (C) 2011 Canonical, Ltd. | ||
391 | 3 | * | ||
392 | 4 | * Authors: | ||
393 | 5 | * Olivier Tilloy <olivier.tilloy@canonical.com> | ||
394 | 6 | * | ||
395 | 7 | * This program is free software; you can redistribute it and/or modify | ||
396 | 8 | * it under the terms of the GNU General Public License as published by | ||
397 | 9 | * the Free Software Foundation; version 3. | ||
398 | 10 | * | ||
399 | 11 | * This program is distributed in the hope that it will be useful, | ||
400 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
401 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
402 | 14 | * GNU General Public License for more details. | ||
403 | 15 | * | ||
404 | 16 | * You should have received a copy of the GNU General Public License | ||
405 | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
406 | 18 | */ | ||
407 | 19 | |||
408 | 20 | #ifndef DeclarativeDragItemWithUrl_H | ||
409 | 21 | #define DeclarativeDragItemWithUrl_H | ||
410 | 22 | |||
411 | 23 | #include "dragitem.h" | ||
412 | 24 | |||
413 | 25 | // Qt | ||
414 | 26 | #include <QString> | ||
415 | 27 | #include <QUrl> | ||
416 | 28 | |||
417 | 29 | /* A specialized DragItem with a 'url' property that knows how to convert | ||
418 | 30 | application:// URLs into the corresponding file:// URLs. */ | ||
419 | 31 | class DeclarativeDragItemWithUrl : public DeclarativeDragItem | ||
420 | 32 | { | ||
421 | 33 | Q_OBJECT | ||
422 | 34 | |||
423 | 35 | /* The URL cannot be a QUrl due to the malformed URIs returned by the place | ||
424 | 36 | backends (see https://bugs.launchpad.net/unity-place-applications/+bug/784478). */ | ||
425 | 37 | Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged) | ||
426 | 38 | |||
427 | 39 | public: | ||
428 | 40 | DeclarativeDragItemWithUrl(QDeclarativeItem* parent=0); | ||
429 | 41 | ~DeclarativeDragItemWithUrl(); | ||
430 | 42 | |||
431 | 43 | // getters and setters | ||
432 | 44 | const QString& url() const; | ||
433 | 45 | void setUrl(const QString& url); | ||
434 | 46 | |||
435 | 47 | protected: | ||
436 | 48 | // overridden | ||
437 | 49 | QMimeData* mimeData() const; | ||
438 | 50 | |||
439 | 51 | private: | ||
440 | 52 | static QUrl decodeUri(const QString& uri); | ||
441 | 53 | |||
442 | 54 | Q_SIGNALS: | ||
443 | 55 | void urlChanged(const QString&); | ||
444 | 56 | |||
445 | 57 | private: | ||
446 | 58 | QString m_url; | ||
447 | 59 | }; | ||
448 | 60 | |||
449 | 61 | #endif // DeclarativeDragItemWithUrl_H | ||
450 | 62 | |||
451 | 0 | 63 | ||
452 | === modified file 'libunity-2d-private/Unity2d/plugin.cpp' | |||
453 | --- libunity-2d-private/Unity2d/plugin.cpp 2011-04-28 13:09:25 +0000 | |||
454 | +++ libunity-2d-private/Unity2d/plugin.cpp 2011-05-30 16:06:44 +0000 | |||
455 | @@ -34,6 +34,7 @@ | |||
456 | 34 | 34 | ||
457 | 35 | #include "mimedata.h" | 35 | #include "mimedata.h" |
458 | 36 | #include "dragdropevent.h" | 36 | #include "dragdropevent.h" |
459 | 37 | #include "dragitemwithurl.h" | ||
460 | 37 | #include "dropitem.h" | 38 | #include "dropitem.h" |
461 | 38 | 39 | ||
462 | 39 | #include <QtDeclarative/qdeclarative.h> | 40 | #include <QtDeclarative/qdeclarative.h> |
463 | @@ -76,6 +77,7 @@ | |||
464 | 76 | qmlRegisterType<QGraphicsDropShadowEffect>("Effects", 1, 0, "DropShadow"); | 77 | qmlRegisterType<QGraphicsDropShadowEffect>("Effects", 1, 0, "DropShadow"); |
465 | 77 | 78 | ||
466 | 78 | /* Custom drag’n’drop implementation in QML */ | 79 | /* Custom drag’n’drop implementation in QML */ |
467 | 80 | qmlRegisterType<DeclarativeDragItemWithUrl>(uri, 0, 1, "DragItemWithUrl"); | ||
468 | 79 | qmlRegisterType<DeclarativeDropItem>(uri, 0, 1, "DropItem"); | 81 | qmlRegisterType<DeclarativeDropItem>(uri, 0, 1, "DropItem"); |
469 | 80 | qmlRegisterType<DeclarativeMimeData>(); | 82 | qmlRegisterType<DeclarativeMimeData>(); |
470 | 81 | qmlRegisterType<DeclarativeDragDropEvent>(); | 83 | qmlRegisterType<DeclarativeDragDropEvent>(); |
471 | 82 | 84 | ||
472 | === modified file 'places/AbstractButton.qml' | |||
473 | --- places/AbstractButton.qml 2011-03-22 06:15:19 +0000 | |||
474 | +++ places/AbstractButton.qml 2011-05-30 16:06:44 +0000 | |||
475 | @@ -21,6 +21,13 @@ | |||
476 | 21 | FocusScope { | 21 | FocusScope { |
477 | 22 | property bool enabled: true | 22 | property bool enabled: true |
478 | 23 | 23 | ||
479 | 24 | /* Use to manually set the "pressed" state of the button. This is not | ||
480 | 25 | necessary in the normal use case, but is useful when a child item eats | ||
481 | 26 | the mouse events (e.g. a DragArea). | ||
482 | 27 | This is a clumsy workaround for the lack of a MouseProxy element | ||
483 | 28 | (see http://bugreports.qt.nokia.com/browse/QTBUG-13007). */ | ||
484 | 29 | property bool pressed: false | ||
485 | 30 | |||
486 | 24 | signal clicked | 31 | signal clicked |
487 | 25 | 32 | ||
488 | 26 | MouseArea { | 33 | MouseArea { |
489 | @@ -45,7 +52,7 @@ | |||
490 | 45 | } | 52 | } |
491 | 46 | 53 | ||
492 | 47 | state: { | 54 | state: { |
494 | 48 | if(mouse_area.pressed) | 55 | if(pressed || mouse_area.pressed) |
495 | 49 | return "pressed" | 56 | return "pressed" |
496 | 50 | else if(mouse_area.containsMouse) | 57 | else if(mouse_area.containsMouse) |
497 | 51 | return "selected" | 58 | return "selected" |
498 | 52 | 59 | ||
499 | === modified file 'places/UnityDefaultRenderer.qml' | |||
500 | --- places/UnityDefaultRenderer.qml 2011-04-08 11:10:59 +0000 | |||
501 | +++ places/UnityDefaultRenderer.qml 2011-05-30 16:06:44 +0000 | |||
502 | @@ -17,6 +17,7 @@ | |||
503 | 17 | */ | 17 | */ |
504 | 18 | 18 | ||
505 | 19 | import Qt 4.7 | 19 | import Qt 4.7 |
506 | 20 | import Unity2d 1.0 /* required for drag’n’drop handling */ | ||
507 | 20 | 21 | ||
508 | 21 | RendererGrid { | 22 | RendererGrid { |
509 | 22 | cellWidth: 136 | 23 | cellWidth: 136 |
510 | @@ -37,6 +38,34 @@ | |||
511 | 37 | placeEntryModel.place.activate(decodeURIComponent(uri)) | 38 | placeEntryModel.place.activate(decodeURIComponent(uri)) |
512 | 38 | } | 39 | } |
513 | 39 | 40 | ||
514 | 41 | DragItemWithUrl { | ||
515 | 42 | anchors.fill: parent | ||
516 | 43 | url: decodeURIComponent(uri) | ||
517 | 44 | defaultAction: { | ||
518 | 45 | if (!url.indexOf("application://")) return Qt.CopyAction | ||
519 | 46 | else if (!url.indexOf("unity-install://")) return Qt.IgnoreAction | ||
520 | 47 | else return Qt.LinkAction | ||
521 | 48 | } | ||
522 | 49 | supportedActions: defaultAction | ||
523 | 50 | delegate: Component { | ||
524 | 51 | Image { | ||
525 | 52 | source: icon.source | ||
526 | 53 | width: icon.width | ||
527 | 54 | height: icon.height | ||
528 | 55 | fillMode: icon.fillMode | ||
529 | 56 | sourceSize.width: width | ||
530 | 57 | sourceSize.height: height | ||
531 | 58 | asynchronous: true | ||
532 | 59 | } | ||
533 | 60 | } | ||
534 | 61 | onPressed: parent.pressed = true | ||
535 | 62 | onReleased: { | ||
536 | 63 | parent.pressed = false | ||
537 | 64 | parent.clicked() | ||
538 | 65 | } | ||
539 | 66 | onDrop: parent.pressed = false | ||
540 | 67 | } | ||
541 | 68 | |||
542 | 40 | Image { | 69 | Image { |
543 | 41 | id: icon | 70 | id: icon |
544 | 42 | 71 |
WARNING: THIS IS NOT A COMPLETE REVIEW
I did a quick functional test and it's pretty neat, well done! applications from Nautilus for example it will look antialiased. Any idea?
One thing I noticed, the icons are very aliased whereas if I drag&drop an app in /usr/share/