Merge lp:~carlos-mazieri/ubuntu-filemanager-app/model into lp:ubuntu-filemanager-app/plugin
- model
- Merge into plugin
Proposed by
Carlos Jose Mazieri
Status: | Merged |
---|---|
Approved by: | Carlos Jose Mazieri |
Approved revision: | 54 |
Merged at revision: | 44 |
Proposed branch: | lp:~carlos-mazieri/ubuntu-filemanager-app/model |
Merge into: | lp:ubuntu-filemanager-app/plugin |
Diff against target: |
1905 lines (+968/-547) 10 files modified
folderlistmodel/clipboard.cpp (+495/-0) folderlistmodel/clipboard.h (+132/-0) folderlistmodel/dirmodel.cpp (+37/-8) folderlistmodel/dirmodel.h (+2/-0) folderlistmodel/filesystemaction.cpp (+85/-507) folderlistmodel/filesystemaction.h (+15/-20) folderlistmodel/fmutil.cpp (+132/-0) folderlistmodel/fmutil.h (+46/-0) folderlistmodel/folderlistmodel.pri (+6/-2) test_folderlistmodel/regression/tst_folderlistmodel.cpp (+18/-10) |
To merge this branch: | bzr merge lp:~carlos-mazieri/ubuntu-filemanager-app/model |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Carlos Jose Mazieri | Approve | ||
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
Review via email: mp+203786@code.launchpad.net |
Commit message
separated Clipboard stuff into a new file
created FMUtil class
Description of the change
separated Clipboard stuff into a new file
created FMUtil class
To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
review:
Approve
(continuous-integration)
Revision history for this message
Carlos Jose Mazieri (carlos-mazieri) wrote : | # |
I wish someone else could review my work.
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'folderlistmodel/clipboard.cpp' |
2 | --- folderlistmodel/clipboard.cpp 1970-01-01 00:00:00 +0000 |
3 | +++ folderlistmodel/clipboard.cpp 2014-01-29 16:33:58 +0000 |
4 | @@ -0,0 +1,495 @@ |
5 | +/************************************************************************** |
6 | + * |
7 | + * Copyright 2014 Canonical Ltd. |
8 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
9 | + * |
10 | + * You may use this file under the terms of the BSD license as follows: |
11 | + * |
12 | + * "Redistribution and use in source and binary forms, with or without |
13 | + * modification, are permitted provided that the following conditions are |
14 | + * met: |
15 | + * * Redistributions of source code must retain the above copyright |
16 | + * notice, this list of conditions and the following disclaimer. |
17 | + * * Redistributions in binary form must reproduce the above copyright |
18 | + * notice, this list of conditions and the following disclaimer in |
19 | + * the documentation and/or other materials provided with the |
20 | + * distribution. |
21 | + * * Neither the name of Nemo Mobile nor the names of its contributors |
22 | + * may be used to endorse or promote products derived from this |
23 | + * software without specific prior written permission. |
24 | + * |
25 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
26 | + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
27 | + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
28 | + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
29 | + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
30 | + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
31 | + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
32 | + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
33 | + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
34 | + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
35 | + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." |
36 | + * |
37 | + * File: clipboard.cpp |
38 | + * Date: 1/22/2014 |
39 | + */ |
40 | + |
41 | +#include "clipboard.h" |
42 | + |
43 | +#include <QClipboard> |
44 | +#include <QApplication> |
45 | +#include <QDir> |
46 | +#include <QFileInfo> |
47 | +#include <QDebug> |
48 | + |
49 | +static QLatin1String GNOME_COPIED_MIME_TYPE ("x-special/gnome-copied-files"); |
50 | +static QLatin1String KDE_CUT_MIME_TYPE ("application/x-kde-cutselection"); |
51 | + |
52 | + |
53 | +int DirModelMimeData::m_instances = 0; |
54 | +DirModelMimeData* DirModelMimeData::m_globalMimeData = 0; |
55 | + |
56 | + |
57 | +bool DirModelMimeData::hasFormat ( const QString & mimeType ) const |
58 | +{ |
59 | + bool ret = false; |
60 | + if ( mimeType == KDE_CUT_MIME_TYPE ) |
61 | + { |
62 | + ret = true; |
63 | + } |
64 | + else |
65 | + { |
66 | + ret = m_formats.contains(mimeType); |
67 | + } |
68 | + return ret; |
69 | +} |
70 | + |
71 | +//=============================================================================================== |
72 | +/*! |
73 | + * \brief DirModelMimeData::DirModelMimeData |
74 | + */ |
75 | +DirModelMimeData::DirModelMimeData() : |
76 | + QMimeData() |
77 | + , m_appMime(0) |
78 | +{ |
79 | + m_formats.append("text/uri-list"); |
80 | + m_formats.append(GNOME_COPIED_MIME_TYPE); |
81 | + m_formats.append("text/plain"); |
82 | + m_formats.append("COMPOUND_TEXT"); |
83 | + m_formats.append("TARGETS"); |
84 | + m_formats.append("MULTIPLE"); |
85 | + m_formats.append("TIMESTAMP"); |
86 | + m_formats.append("SAVE_TARGETS"); |
87 | + |
88 | + ++m_instances; |
89 | +#if DEBUG_MESSAGES |
90 | + qDebug() << Q_FUNC_INFO << this << "instances" << m_instances; |
91 | +#endif |
92 | +} |
93 | + |
94 | + |
95 | + |
96 | + |
97 | +DirModelMimeData::~DirModelMimeData() |
98 | +{ |
99 | + --m_instances; |
100 | +#if DEBUG_MESSAGES |
101 | + qDebug() << Q_FUNC_INFO << this << "instances" << m_instances |
102 | + << "m_globalMimeData" << m_globalMimeData; |
103 | +#endif |
104 | + if (m_instances == 1 && m_globalMimeData) |
105 | + { |
106 | + DirModelMimeData * tmp = m_globalMimeData; |
107 | + m_globalMimeData = 0; |
108 | + delete tmp; |
109 | + } |
110 | +} |
111 | + |
112 | +//=============================================================================================== |
113 | +/*! |
114 | + * \brief DirModelMimeData::gnomeUrls |
115 | + * \param mime |
116 | + * \param operation |
117 | + * \return |
118 | + */ |
119 | +QList<QUrl> |
120 | +DirModelMimeData::gnomeUrls(const QMimeData * mime, |
121 | + ClipboardOperation& operation) |
122 | +{ |
123 | + QList<QUrl> urls; |
124 | + if (mime->hasFormat(GNOME_COPIED_MIME_TYPE)) |
125 | + { |
126 | + QByteArray bytes = mime->data(GNOME_COPIED_MIME_TYPE); |
127 | + QList<QString> d = QString(bytes).split(QLatin1String("\n"), |
128 | + QString::SkipEmptyParts); |
129 | + operation = ClipboardCopy; |
130 | + if (d.count() > 0) |
131 | + { |
132 | + if (d.at(0).trimmed().startsWith(QLatin1String("cut"))) |
133 | + { |
134 | + operation = ClipboardCut; |
135 | + } |
136 | + for (int counter= 1; counter < d.count(); counter++) |
137 | + { |
138 | + urls.append(d.at(counter).trimmed()); |
139 | + } |
140 | + } |
141 | + } |
142 | + return urls; |
143 | +} |
144 | + |
145 | +//=============================================================================================== |
146 | +/*! |
147 | + * \brief DirModelMimeData::clipBoardOperation() |
148 | + * \param mime |
149 | + * \return |
150 | + */ |
151 | +ClipboardOperation DirModelMimeData::clipBoardOperation() |
152 | +{ |
153 | + ClipboardOperation op = ClipboardCopy; |
154 | + m_appMime = clipboardMimeData(); |
155 | + if (m_appMime) |
156 | + { |
157 | + //first check for GNOME clipboard format, op comes with Copy/Cut |
158 | + if (gnomeUrls(m_appMime, op).count() == 0) |
159 | + { // there is no gnome format, tries KDE format |
160 | + QStringList formats = m_appMime->formats(); |
161 | + int f = formats.count(); |
162 | + while(f--) |
163 | + { |
164 | + const QString &mi = formats.at(f); |
165 | + if(mi.startsWith(QLatin1String("application/x-kde")) ) |
166 | + { |
167 | + if (mi.contains(QLatin1String("cut"))) |
168 | + { |
169 | + op = ClipboardCut; |
170 | + break; |
171 | + } |
172 | + } |
173 | + } |
174 | + } |
175 | + } |
176 | + return op; |
177 | +} |
178 | + |
179 | + |
180 | +//=============================================================================================== |
181 | +/*! |
182 | + * \brief DirModelMimeData::setIntoClipboard |
183 | + * |
184 | + * Try to put data in the global cliboard |
185 | + * |
186 | + * \note: |
187 | + * On mobile devices clipboard might not work, in this case a local Clipboard is simulated |
188 | + * |
189 | + * \param files |
190 | + * \param path |
191 | + * \param isCut |
192 | + * \return who is owner of clipboard data |
193 | + */ |
194 | +DirModelMimeData::ClipBoardDataOwner |
195 | +DirModelMimeData::setIntoClipboard(const QStringList &files, const QString& path, ClipboardOperation operation) |
196 | +{ |
197 | + static bool firstTime = true; |
198 | + DirModelMimeData::ClipBoardDataOwner ret = Nobody; |
199 | + QClipboard *clipboard = QApplication::clipboard(); |
200 | + if (clipboard) |
201 | + { |
202 | + ret = Application; |
203 | + DirModelMimeData *mime = m_globalMimeData ? m_globalMimeData |
204 | + : new DirModelMimeData(); |
205 | + if (mime->fillClipboard(files, path, operation)) |
206 | + { |
207 | + clipboard->setMimeData(mime); |
208 | + //it looks like some mobile devices does not have X or Clipboard does work for other reason |
209 | + //in this case we simulate our own clipboard, the QClipboard::dataChanged() signal is also |
210 | + //checked in \ref Clipboard::storeOnClipboard() |
211 | + if (firstTime) |
212 | + { |
213 | + firstTime = false; |
214 | + if (!m_globalMimeData && !testClipboardContent(files, path)) |
215 | + { |
216 | + qWarning() << "QClipboard does not work, using own QMimeData storage"; |
217 | + m_globalMimeData = mime; |
218 | + } |
219 | + } |
220 | +#if DEBUG_MESSAGES |
221 | + qDebug() << Q_FUNC_INFO << "mime" << mime |
222 | + << "own Clipboard Mime Data" << m_globalMimeData; |
223 | +#endif |
224 | + } |
225 | + else |
226 | + if (m_globalMimeData != mime) |
227 | + { |
228 | + delete mime; |
229 | + } |
230 | + //check if it is necessary to send notification about Clipboard changed |
231 | + if (m_globalMimeData) |
232 | + { |
233 | + ret = MySelf; |
234 | + } |
235 | + } |
236 | + return ret; |
237 | +} |
238 | + |
239 | + |
240 | + |
241 | +bool DirModelMimeData::fillClipboard(const QStringList& files, const QString &path, ClipboardOperation operation) |
242 | +{ |
243 | + bool ret = false; |
244 | + int index = m_formats.indexOf(KDE_CUT_MIME_TYPE); |
245 | + if (index != -1 && operation != ClipboardCut) |
246 | + { |
247 | + m_formats.removeAt(index); |
248 | + } |
249 | + else |
250 | + if (operation == ClipboardCut) |
251 | + { |
252 | + m_formats.append(KDE_CUT_MIME_TYPE); |
253 | + } |
254 | + m_urls.clear(); |
255 | + m_gnomeData.clear(); |
256 | + m_gnomeData += operation == ClipboardCut ? |
257 | + QLatin1String("cut") : |
258 | + QLatin1String("copy"); |
259 | + QStringList fullPaths = makeFullPath(files, path); |
260 | + for(int counter = 0; counter < fullPaths.count(); counter++) |
261 | + { |
262 | + QUrl item = QUrl::fromLocalFile(fullPaths.at((counter))); |
263 | + m_urls.append(item); |
264 | + m_gnomeData += QLatin1Char('\n') + item.toEncoded() ; |
265 | + } |
266 | + if (m_urls.count() > 0) |
267 | + { |
268 | + setData(GNOME_COPIED_MIME_TYPE, m_gnomeData); |
269 | + setUrls(m_urls); |
270 | + ret = true; |
271 | + } |
272 | + else |
273 | + { |
274 | + // emit error( QObject::tr("Item does not exist"), item); |
275 | + } |
276 | + return ret; |
277 | +} |
278 | + |
279 | +//=============================================================================================== |
280 | +/*! |
281 | + * \brief DirModelMimeData::clipboardMimeData |
282 | + * \return |
283 | + */ |
284 | +const QMimeData *DirModelMimeData::clipboardMimeData() |
285 | +{ |
286 | + const QMimeData *ret = 0; |
287 | + QClipboard *clipboard = QApplication::clipboard(); |
288 | + if (m_globalMimeData) |
289 | + { |
290 | + ret = m_globalMimeData; |
291 | + } |
292 | + else |
293 | + if (clipboard) |
294 | + { |
295 | + ret = clipboard->mimeData(); |
296 | + } |
297 | +#if DEBUG_MESSAGES |
298 | + qDebug() << Q_FUNC_INFO << "clipboard" << clipboard |
299 | + << "m_ownClipboardMimeData" << m_globalMimeData |
300 | + << "clipboard->mimeData()" << ret; |
301 | +#endif |
302 | + return ret; |
303 | +} |
304 | + |
305 | +//=============================================================================================== |
306 | +/*! |
307 | + * \brief DirModelMimeData::localUrls |
308 | + * \return |
309 | + */ |
310 | +QStringList |
311 | +DirModelMimeData::localUrls(ClipboardOperation& operation) |
312 | +{ |
313 | + m_appMime = clipboardMimeData(); |
314 | + QStringList paths; |
315 | + //it may have external urls |
316 | + if (m_appMime) |
317 | + { |
318 | + QList<QUrl> urls; |
319 | + if (m_appMime->hasUrls()) |
320 | + { |
321 | + urls = m_appMime->urls(); |
322 | + operation = clipBoardOperation(); |
323 | + } |
324 | + else |
325 | + { |
326 | + urls = gnomeUrls(m_appMime, operation); |
327 | + } |
328 | + for (int counter=0; counter < urls.count(); counter++) |
329 | + { |
330 | + if (urls.at(counter).toString().startsWith(QLatin1String("file://"))) |
331 | + { |
332 | + paths.append(urls.at(counter).toLocalFile()); |
333 | + } |
334 | + } |
335 | + } |
336 | +#if DEBUG_MESSAGES |
337 | + qDebug() << Q_FUNC_INFO << paths; |
338 | +#endif |
339 | + return paths; |
340 | +} |
341 | + |
342 | + |
343 | +//=============================================================================================== |
344 | +/*! |
345 | + * \brief DirModelMimeData::testClipboardContent() Gets the clipboard content and compare with data previously stored |
346 | + * \param files |
347 | + * \param path |
348 | + * \return true if clipboard has content and it matches data previously stored |
349 | + */ |
350 | +bool DirModelMimeData::testClipboardContent(const QStringList &files, const QString &path) |
351 | +{ |
352 | + bool ret = false; |
353 | + ClipboardOperation tmpOperation; |
354 | + QStringList expectedList = makeFullPath(files,path); |
355 | + QStringList realList = localUrls(tmpOperation); |
356 | + if (realList == expectedList) |
357 | + { |
358 | + ret = true; |
359 | + } |
360 | + else |
361 | + { |
362 | + qWarning() << Q_FUNC_INFO << "FAILED, Clipboard does not work"; |
363 | + } |
364 | + return ret; |
365 | +} |
366 | + |
367 | +//=============================================================================================== |
368 | +/*! |
369 | + * \brief DirModelMimeData::makeFullPath() Just creates a fulpath file list when they do exist |
370 | + * \param files |
371 | + * \param path |
372 | + * \return the list itself |
373 | + */ |
374 | +QStringList DirModelMimeData::makeFullPath(const QStringList& files, const QString &path) |
375 | +{ |
376 | + QStringList fullPathnameList; |
377 | + QFileInfo fi; |
378 | + for(int counter = 0; counter < files.count(); counter++) |
379 | + { |
380 | + const QString& item = files.at(counter); |
381 | + fi.setFile(item); |
382 | + if (!fi.isAbsolute()) |
383 | + { |
384 | + fi.setFile(path + QDir::separator() + item); |
385 | + } |
386 | + if (fi.exists()) |
387 | + { |
388 | + fullPathnameList.append(fi.absoluteFilePath()); |
389 | + } |
390 | + } |
391 | + return fullPathnameList; |
392 | +} |
393 | + |
394 | + |
395 | +//=========================================================================== |
396 | +// |
397 | +//=========================================================================== |
398 | +Clipboard::Clipboard(QObject *parent): |
399 | + QObject(parent) |
400 | + , m_mimeData ( new DirModelMimeData() ) |
401 | + , m_clipboardModifiedByOther(false) |
402 | +{ |
403 | + QClipboard *clipboard = QApplication::clipboard(); |
404 | + |
405 | + connect(clipboard, SIGNAL(dataChanged()), this, SIGNAL(clipboardChanged())); |
406 | + connect(clipboard, SIGNAL(dataChanged()), this, SLOT(onClipboardChanged())); |
407 | +} |
408 | + |
409 | + |
410 | +Clipboard::~Clipboard() |
411 | +{ |
412 | + delete m_mimeData; |
413 | +} |
414 | + |
415 | +//================================================================================ |
416 | +/*! |
417 | + * \brief Clipboard::clipboardHasChanged() used to identify if the clipboard changed during a Cut operation |
418 | + * |
419 | + * \sa \ref endCurrentAction() |
420 | + */ |
421 | +void Clipboard::onClipboardChanged() |
422 | +{ |
423 | + m_clipboardModifiedByOther = true; |
424 | +} |
425 | + |
426 | + |
427 | +//================================================================== |
428 | +/*! |
429 | + * \brief Clipboard::storeOnClipboard() store data on Clipboard |
430 | + * \param pathnames files list |
431 | + * \param op \ref ClipboardOperation as \ref ClipboardCopy or \ref ClipboardCut |
432 | + * |
433 | + * Stores data on clipboard by calling \ref DirModelMimeData::setIntoClipboard() which uses Qt class QClipboard |
434 | + * It is expected that QClipboard class emits the dataChanged() signal when a new content is set into it, |
435 | + * if it does we caught that signal in \ref clipboardHasChanged() which sets \ref m_clipboardModifiedByOther to true. |
436 | + */ |
437 | +void Clipboard::storeOnClipboard(const QStringList &names, ClipboardOperation op, const QString& curPath) |
438 | +{ |
439 | +#if DEBUG_MESSAGES |
440 | + qDebug() << Q_FUNC_INFO << names << "ClipboardOperation" << op; |
441 | +#endif |
442 | + DirModelMimeData::ClipBoardDataOwner owner = |
443 | + m_mimeData->setIntoClipboard(names, curPath, op); |
444 | + if (owner == DirModelMimeData::MySelf || !m_clipboardModifiedByOther) |
445 | + { |
446 | + emit clipboardChanged(); |
447 | + } |
448 | + m_clipboardModifiedByOther = false; |
449 | +} |
450 | + |
451 | +//=============================================================================================== |
452 | +/*! |
453 | + * \brief Clipboard::copy |
454 | + * \param pathnames |
455 | + */ |
456 | +void Clipboard::copy(const QStringList &names, const QString& path) |
457 | +{ |
458 | + storeOnClipboard(names, ClipboardCopy, path); |
459 | +} |
460 | + |
461 | +//=============================================================================================== |
462 | +/*! |
463 | + * \brief Clipboard::cut |
464 | + * \param pathnames |
465 | + */ |
466 | +void Clipboard::cut(const QStringList &names, const QString &path) |
467 | +{ |
468 | + storeOnClipboard(names, ClipboardCut, path); |
469 | +} |
470 | + |
471 | + |
472 | +//======================================================= |
473 | +/*! |
474 | + * \brief Clipboard::clipboardLocalUrlsCounter |
475 | + * \return |
476 | + */ |
477 | +int Clipboard::clipboardLocalUrlsCounter() |
478 | +{ |
479 | + ClipboardOperation operation; |
480 | + return m_mimeData->localUrls(operation).count(); |
481 | +} |
482 | + |
483 | + |
484 | +//======================================================= |
485 | +/*! |
486 | + * \brief Clipboard::paste |
487 | + * \param operation |
488 | + * \return |
489 | + */ |
490 | +QStringList Clipboard::paste(ClipboardOperation &operation) |
491 | +{ |
492 | + QStringList items = m_mimeData->localUrls(operation); |
493 | + if (operation == ClipboardCut) |
494 | + { |
495 | + //this must still be false when cut finishes to change the clipboard to the target |
496 | + m_clipboardModifiedByOther = false; |
497 | + } |
498 | + return items; |
499 | +} |
500 | |
501 | === added file 'folderlistmodel/clipboard.h' |
502 | --- folderlistmodel/clipboard.h 1970-01-01 00:00:00 +0000 |
503 | +++ folderlistmodel/clipboard.h 2014-01-29 16:33:58 +0000 |
504 | @@ -0,0 +1,132 @@ |
505 | +/************************************************************************** |
506 | + * |
507 | + * Copyright 2014 Canonical Ltd. |
508 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
509 | + * |
510 | + * You may use this file under the terms of the BSD license as follows: |
511 | + * |
512 | + * "Redistribution and use in source and binary forms, with or without |
513 | + * modification, are permitted provided that the following conditions are |
514 | + * met: |
515 | + * * Redistributions of source code must retain the above copyright |
516 | + * notice, this list of conditions and the following disclaimer. |
517 | + * * Redistributions in binary form must reproduce the above copyright |
518 | + * notice, this list of conditions and the following disclaimer in |
519 | + * the documentation and/or other materials provided with the |
520 | + * distribution. |
521 | + * * Neither the name of Nemo Mobile nor the names of its contributors |
522 | + * may be used to endorse or promote products derived from this |
523 | + * software without specific prior written permission. |
524 | + * |
525 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
526 | + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
527 | + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
528 | + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
529 | + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
530 | + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
531 | + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
532 | + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
533 | + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
534 | + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
535 | + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." |
536 | + * |
537 | + * File: clipboard.h |
538 | + * Date: 1/22/2014 |
539 | + */ |
540 | + |
541 | +#ifndef CLIPBOARD_H |
542 | +#define CLIPBOARD_H |
543 | + |
544 | +#include <QMimeData> |
545 | +#include <QUrl> |
546 | +#include <QStringList> |
547 | + |
548 | +class DirModelMimeData; |
549 | + |
550 | +enum ClipboardOperation |
551 | +{ |
552 | + NoClipboard, ClipboardCopy, ClipboardCut |
553 | +}; |
554 | + |
555 | + |
556 | + |
557 | +/*! |
558 | + * \brief The Clipboard class handles global clipboard storage |
559 | + */ |
560 | +class Clipboard : public QObject |
561 | +{ |
562 | + Q_OBJECT |
563 | +public: |
564 | + explicit Clipboard(QObject *parent = 0); |
565 | + ~Clipboard(); |
566 | + QStringList paste(ClipboardOperation& operation); |
567 | + int clipboardLocalUrlsCounter(); |
568 | + inline bool hasClipboardModifiedByOtherApplication() const {return m_clipboardModifiedByOther;} |
569 | + |
570 | +public slots: |
571 | + void cut(const QStringList& names, const QString &path); |
572 | + void copy(const QStringList& names, const QString &path); |
573 | + |
574 | + |
575 | +signals: |
576 | + void clipboardChanged(); |
577 | + |
578 | +private slots: |
579 | + void onClipboardChanged (); |
580 | + |
581 | +private: |
582 | + void storeOnClipboard(const QStringList &names, |
583 | + ClipboardOperation op, |
584 | + const QString &curPath); |
585 | +private: |
586 | + DirModelMimeData * m_mimeData; |
587 | + bool m_clipboardModifiedByOther; |
588 | +}; |
589 | + |
590 | + |
591 | + |
592 | +/*! |
593 | + * \brief The DirModelMimeData class is the storage on Clipboard |
594 | + */ |
595 | +class DirModelMimeData : public QMimeData |
596 | +{ |
597 | +public: |
598 | + explicit DirModelMimeData(); |
599 | + ~DirModelMimeData(); |
600 | + virtual QStringList formats() const { return m_formats; } |
601 | + virtual bool hasFormat ( const QString & mimeType ) const; |
602 | + |
603 | +public: |
604 | + enum ClipBoardDataOwner |
605 | + { |
606 | + Nobody, // might have failed |
607 | + Application, |
608 | + MySelf |
609 | + }; |
610 | + |
611 | + ClipBoardDataOwner setIntoClipboard(const QStringList& files, |
612 | + const QString &path, |
613 | + ClipboardOperation operation); |
614 | + const QMimeData * clipboardMimeData(); |
615 | + QStringList localUrls(ClipboardOperation& operation); |
616 | + |
617 | +private: |
618 | + static QList<QUrl> gnomeUrls(const QMimeData *mime, ClipboardOperation& operation); |
619 | + ClipboardOperation clipBoardOperation(); |
620 | + bool fillClipboard(const QStringList& files, const QString &path, ClipboardOperation operation); |
621 | + QStringList makeFullPath(const QStringList& files, const QString &path); |
622 | + bool testClipboardContent(const QStringList& files, const QString &path); |
623 | + |
624 | +private: |
625 | + QStringList m_formats; |
626 | + const QMimeData * m_appMime; |
627 | + QByteArray m_gnomeData; |
628 | + QList<QUrl> m_urls; |
629 | + static DirModelMimeData* m_globalMimeData; //!< some mobile devices do not use X, they may not have clipboard |
630 | + static int m_instances; |
631 | +}; |
632 | + |
633 | + |
634 | + |
635 | +#endif //CLIPBOARD_H |
636 | + |
637 | |
638 | === modified file 'folderlistmodel/dirmodel.cpp' |
639 | --- folderlistmodel/dirmodel.cpp 2013-12-31 16:57:19 +0000 |
640 | +++ folderlistmodel/dirmodel.cpp 2014-01-29 16:33:58 +0000 |
641 | @@ -34,6 +34,8 @@ |
642 | #include "ioworkerthread.h" |
643 | #include "filesystemaction.h" |
644 | #include "externalfswatcher.h" |
645 | +#include "clipboard.h" |
646 | +#include "fmutil.h" |
647 | |
648 | #ifndef DO_NOT_USE_TAG_LIB |
649 | #include <taglib/attachedpictureframe.h> |
650 | @@ -53,7 +55,7 @@ |
651 | #include <QUrl> |
652 | #include <QDesktopServices> |
653 | |
654 | -#if defined(REGRESSION_TEST_FOLDERLISTMODEL) && QT_VERSION >= 0x050000 |
655 | +#if QT_VERSION >= 0x050000 |
656 | # include <QMimeType> |
657 | # include <QMimeDatabase> |
658 | #endif |
659 | @@ -98,7 +100,8 @@ |
660 | , mSortOrder(SortAscending) |
661 | , mCompareFunction(0) |
662 | , mExtFSWatcher(0) |
663 | - , m_fsAction(new FileSystemAction(this) ) |
664 | + , mClipboard(new Clipboard(this)) |
665 | + , m_fsAction(new FileSystemAction(this) ) |
666 | { |
667 | mNameFilters = QStringList() << "*"; |
668 | |
669 | @@ -130,20 +133,35 @@ |
670 | connect(this, SIGNAL(pathChanged(QString)), |
671 | m_fsAction, SLOT(pathChanged(QString))); |
672 | |
673 | - connect(m_fsAction, SIGNAL(clipboardChanged()), |
674 | + connect(mClipboard, SIGNAL(clipboardChanged()), |
675 | this, SIGNAL(clipboardChanged())); |
676 | |
677 | connect(m_fsAction, SIGNAL(changed(QFileInfo)), |
678 | this, SLOT(onItemChanged(QFileInfo))); |
679 | |
680 | + connect(mClipboard, SIGNAL(clipboardChanged()), |
681 | + m_fsAction, SLOT(onClipboardChanged())); |
682 | + |
683 | + connect(m_fsAction, SIGNAL(recopy(QStringList,QString)), |
684 | + mClipboard, SLOT(copy(QStringList,QString))); |
685 | + |
686 | setCompareAndReorder(); |
687 | + |
688 | + if (QIcon::themeName().isEmpty() && !FMUtil::hasTriedThemeName()) |
689 | + { |
690 | + FMUtil::setThemeName(); |
691 | + } |
692 | } |
693 | |
694 | + |
695 | + |
696 | DirModel::~DirModel() |
697 | { |
698 | stoptExternalFsWatcher(); |
699 | } |
700 | |
701 | + |
702 | + |
703 | #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) |
704 | // roleNames has changed between Qt4 and Qt5. In Qt5 it is a virtual |
705 | // function and setRoleNames should not be used. |
706 | @@ -158,6 +176,8 @@ |
707 | } |
708 | #endif |
709 | |
710 | + |
711 | + |
712 | QHash<int, QByteArray> DirModel::buildRoleNames() const |
713 | { |
714 | QHash<int, QByteArray> roles; |
715 | @@ -597,7 +617,7 @@ |
716 | |
717 | void DirModel::copyPaths(const QStringList &items) |
718 | { |
719 | - m_fsAction->copy(items); |
720 | + mClipboard->copy(items, mCurrentDir); |
721 | } |
722 | |
723 | |
724 | @@ -607,7 +627,7 @@ |
725 | { |
726 | const QFileInfo &fi = mDirectoryContents.at(row); |
727 | QStringList list(fi.absoluteFilePath()); |
728 | - m_fsAction->cut(list); |
729 | + this->cutPaths(list); |
730 | } |
731 | else |
732 | { |
733 | @@ -618,13 +638,22 @@ |
734 | |
735 | void DirModel::cutPaths(const QStringList &items) |
736 | { |
737 | - m_fsAction->cut(items); |
738 | + mClipboard->cut(items, mCurrentDir); |
739 | } |
740 | |
741 | |
742 | void DirModel::paste() |
743 | { |
744 | - m_fsAction->paste(); |
745 | + ClipboardOperation operation; |
746 | + QStringList items = mClipboard->paste(operation); |
747 | + if (operation == ClipboardCut) |
748 | + { |
749 | + m_fsAction->moveIntoCurrentPath(items); |
750 | + } |
751 | + else |
752 | + { |
753 | + m_fsAction->copyIntoCurrentPath(items); |
754 | + } |
755 | } |
756 | |
757 | |
758 | @@ -923,7 +952,7 @@ |
759 | |
760 | int DirModel::getClipboardUrlsCounter() const |
761 | { |
762 | - return m_fsAction->clipboardLocalUrlsConunter(); |
763 | + return mClipboard->clipboardLocalUrlsCounter(); |
764 | } |
765 | |
766 | |
767 | |
768 | === modified file 'folderlistmodel/dirmodel.h' |
769 | --- folderlistmodel/dirmodel.h 2013-12-08 13:15:45 +0000 |
770 | +++ folderlistmodel/dirmodel.h 2014-01-29 16:33:58 +0000 |
771 | @@ -44,6 +44,7 @@ |
772 | |
773 | class FileSystemAction; |
774 | class ExternalFSWatcher; |
775 | +class Clipboard; |
776 | |
777 | /*! |
778 | * When the External File System Wathcer is enabled, |
779 | @@ -394,6 +395,7 @@ |
780 | SortOrder mSortOrder; |
781 | CompareFunction mCompareFunction; |
782 | ExternalFSWatcher* mExtFSWatcher; |
783 | + Clipboard * mClipboard; |
784 | |
785 | |
786 | private: |
787 | |
788 | === modified file 'folderlistmodel/filesystemaction.cpp' |
789 | --- folderlistmodel/filesystemaction.cpp 2013-12-31 16:57:19 +0000 |
790 | +++ folderlistmodel/filesystemaction.cpp 2014-01-29 16:33:58 +0000 |
791 | @@ -35,6 +35,7 @@ |
792 | */ |
793 | |
794 | #include "filesystemaction.h" |
795 | +#include "clipboard.h" |
796 | |
797 | #if defined(Q_OS_UNIX) |
798 | #include <sys/statvfs.h> |
799 | @@ -45,10 +46,6 @@ |
800 | #include <QDirIterator> |
801 | #include <QDebug> |
802 | #include <QTimer> |
803 | -#include <QMimeData> |
804 | -#include <QClipboard> |
805 | -#include <QApplication> |
806 | -#include <QUrl> |
807 | #include <QFileInfo> |
808 | #include <QDir> |
809 | #include <QThread> |
810 | @@ -73,48 +70,7 @@ |
811 | #define COMMON_SIZE_ITEM 120 |
812 | |
813 | |
814 | -static QLatin1String GNOME_COPIED_MIME_TYPE ("x-special/gnome-copied-files"); |
815 | -static QLatin1String KDE_CUT_MIME_TYPE ("application/x-kde-cutselection"); |
816 | - |
817 | - |
818 | -class DirModelMimeData : public QMimeData |
819 | -{ |
820 | -public: |
821 | - enum ClipBoardDataOwner |
822 | - { |
823 | - Nobody, // might have failed |
824 | - Application, |
825 | - MySelf |
826 | - }; |
827 | - |
828 | - explicit DirModelMimeData(); |
829 | - ~DirModelMimeData(); |
830 | - virtual QStringList formats() const { return m_formats; } |
831 | - virtual bool hasFormat ( const QString & mimeType ) const; |
832 | -public: |
833 | - ClipBoardDataOwner setIntoClipboard(const QStringList& files, |
834 | - const QString &path, |
835 | - ClipboardOperation operation); |
836 | - const QMimeData *clipboardMimeData(); |
837 | - QStringList localUrls(ClipboardOperation& operation); |
838 | -private: |
839 | - static QList<QUrl> gnomeUrls(const QMimeData *mime, ClipboardOperation& operation); |
840 | - ClipboardOperation clipBoardOperation(); |
841 | - bool fillClipboard(const QStringList& files, const QString &path, ClipboardOperation operation); |
842 | - QStringList makeFullPath(const QStringList& files, const QString &path); |
843 | - bool testClipboardContent(const QStringList& files, const QString &path); |
844 | -private: |
845 | - QStringList m_formats; |
846 | - const QMimeData * m_appMime; |
847 | - QByteArray gnomeData; |
848 | - QList<QUrl> urls; |
849 | - static DirModelMimeData* m_globalMimeData; //!< some mobile devices do not use X, they may not have clipboard |
850 | - static int instances; |
851 | -}; |
852 | - |
853 | - |
854 | -int DirModelMimeData::instances = 0; |
855 | -DirModelMimeData* DirModelMimeData::m_globalMimeData = 0; |
856 | + |
857 | |
858 | void FileSystemAction::CopyFile::clear() |
859 | { |
860 | @@ -125,341 +81,6 @@ |
861 | target = 0; |
862 | } |
863 | |
864 | -bool DirModelMimeData::hasFormat ( const QString & mimeType ) const |
865 | -{ |
866 | - bool ret = false; |
867 | - if ( mimeType == KDE_CUT_MIME_TYPE ) |
868 | - { |
869 | - ret = true; |
870 | - } |
871 | - else |
872 | - { |
873 | - ret = m_formats.contains(mimeType); |
874 | - } |
875 | - return ret; |
876 | -} |
877 | - |
878 | -//=============================================================================================== |
879 | -/*! |
880 | - * \brief DirModelMimeData::DirModelMimeData |
881 | - */ |
882 | -DirModelMimeData::DirModelMimeData() : |
883 | - QMimeData() |
884 | - , m_appMime(0) |
885 | -{ |
886 | - m_formats.append("text/uri-list"); |
887 | - m_formats.append(GNOME_COPIED_MIME_TYPE); |
888 | - m_formats.append("text/plain"); |
889 | - m_formats.append("COMPOUND_TEXT"); |
890 | - m_formats.append("TARGETS"); |
891 | - m_formats.append("MULTIPLE"); |
892 | - m_formats.append("TIMESTAMP"); |
893 | - m_formats.append("SAVE_TARGETS"); |
894 | - |
895 | - ++instances; |
896 | -#if DEBUG_MESSAGES |
897 | - qDebug() << Q_FUNC_INFO << this << "instances" << instances; |
898 | -#endif |
899 | -} |
900 | - |
901 | - |
902 | - |
903 | - |
904 | -DirModelMimeData::~DirModelMimeData() |
905 | -{ |
906 | - --instances; |
907 | -#if DEBUG_MESSAGES |
908 | - qDebug() << Q_FUNC_INFO << this << "instances" << instances |
909 | - << "m_globalMimeData" << m_globalMimeData; |
910 | -#endif |
911 | - if (instances == 1 && m_globalMimeData) |
912 | - { |
913 | - DirModelMimeData * tmp = m_globalMimeData; |
914 | - m_globalMimeData = 0; |
915 | - delete tmp; |
916 | - } |
917 | -} |
918 | - |
919 | -//=============================================================================================== |
920 | -/*! |
921 | - * \brief DirModelMimeData::gnomeUrls |
922 | - * \param mime |
923 | - * \param operation |
924 | - * \return |
925 | - */ |
926 | -QList<QUrl> |
927 | -DirModelMimeData::gnomeUrls(const QMimeData * mime, |
928 | - ClipboardOperation& operation) |
929 | -{ |
930 | - QList<QUrl> urls; |
931 | - if (mime->hasFormat(GNOME_COPIED_MIME_TYPE)) |
932 | - { |
933 | - QByteArray bytes = mime->data(GNOME_COPIED_MIME_TYPE); |
934 | - QList<QString> d = QString(bytes).split(QLatin1String("\n"), |
935 | - QString::SkipEmptyParts); |
936 | - operation = ClipboardCopy; |
937 | - if (d.count() > 0) |
938 | - { |
939 | - if (d.at(0).trimmed().startsWith(QLatin1String("cut"))) |
940 | - { |
941 | - operation = ClipboardCut; |
942 | - } |
943 | - for (int counter= 1; counter < d.count(); counter++) |
944 | - { |
945 | - urls.append(d.at(counter).trimmed()); |
946 | - } |
947 | - } |
948 | - } |
949 | - return urls; |
950 | -} |
951 | - |
952 | -//=============================================================================================== |
953 | -/*! |
954 | - * \brief DirModelMimeData::clipBoardOperation() |
955 | - * \param mime |
956 | - * \return |
957 | - */ |
958 | -ClipboardOperation DirModelMimeData::clipBoardOperation() |
959 | -{ |
960 | - ClipboardOperation op = ClipboardCopy; |
961 | - m_appMime = clipboardMimeData(); |
962 | - if (m_appMime) |
963 | - { |
964 | - //first check for GNOME clipboard format, op comes with Copy/Cut |
965 | - if (gnomeUrls(m_appMime, op).count() == 0) |
966 | - { // there is no gnome format, tries KDE format |
967 | - QStringList formats = m_appMime->formats(); |
968 | - int f = formats.count(); |
969 | - while(f--) |
970 | - { |
971 | - const QString &mi = formats.at(f); |
972 | - if(mi.startsWith(QLatin1String("application/x-kde")) ) |
973 | - { |
974 | - if (mi.contains(QLatin1String("cut"))) |
975 | - { |
976 | - op = ClipboardCut; |
977 | - break; |
978 | - } |
979 | - } |
980 | - } |
981 | - } |
982 | - } |
983 | - return op; |
984 | -} |
985 | - |
986 | - |
987 | -//=============================================================================================== |
988 | -/*! |
989 | - * \brief DirModelMimeData::setIntoClipboard |
990 | - * |
991 | - * Try to put data in the global cliboard |
992 | - * |
993 | - * \note: |
994 | - * On mobile devices clipboard might not work, in this case a local Clipboard is simulated |
995 | - * |
996 | - * \param files |
997 | - * \param path |
998 | - * \param isCut |
999 | - * \return who is owner of clipboard data |
1000 | - */ |
1001 | -DirModelMimeData::ClipBoardDataOwner |
1002 | -DirModelMimeData::setIntoClipboard(const QStringList &files, const QString& path, ClipboardOperation operation) |
1003 | -{ |
1004 | - static bool firstTime = true; |
1005 | - DirModelMimeData::ClipBoardDataOwner ret = Nobody; |
1006 | - QClipboard *clipboard = QApplication::clipboard(); |
1007 | - if (clipboard) |
1008 | - { |
1009 | - ret = Application; |
1010 | - DirModelMimeData *mime = m_globalMimeData ? m_globalMimeData |
1011 | - : new DirModelMimeData(); |
1012 | - if (mime->fillClipboard(files, path, operation)) |
1013 | - { |
1014 | - clipboard->setMimeData(mime); |
1015 | - //it looks like some mobile devices does not have X or Clipboard does work for other reason |
1016 | - //in this case we simulate our own clipboard, the QClipboard::dataChanged() signal is also |
1017 | - //checked in \ref FileSystemAction::storeOnClipboard() |
1018 | - if (firstTime) |
1019 | - { |
1020 | - firstTime = false; |
1021 | - if (!m_globalMimeData && !testClipboardContent(files, path)) |
1022 | - { |
1023 | - qWarning() << "QClipboard does not work, using own QMimeData storage"; |
1024 | - m_globalMimeData = mime; |
1025 | - } |
1026 | - } |
1027 | -#if DEBUG_MESSAGES |
1028 | - qDebug() << Q_FUNC_INFO << "mime" << mime |
1029 | - << "own Clipboard Mime Data" << m_globalMimeData; |
1030 | -#endif |
1031 | - } |
1032 | - else |
1033 | - if (m_globalMimeData != mime) |
1034 | - { |
1035 | - delete mime; |
1036 | - } |
1037 | - //check if it is necessary to send notification about Clipboard changed |
1038 | - if (m_globalMimeData) |
1039 | - { |
1040 | - ret = MySelf; |
1041 | - } |
1042 | - } |
1043 | - return ret; |
1044 | -} |
1045 | - |
1046 | - |
1047 | -bool DirModelMimeData::fillClipboard(const QStringList& files, const QString &path, ClipboardOperation operation) |
1048 | -{ |
1049 | - bool ret = false; |
1050 | - int index = m_formats.indexOf(KDE_CUT_MIME_TYPE); |
1051 | - if (index != -1 && operation != ClipboardCut) |
1052 | - { |
1053 | - m_formats.removeAt(index); |
1054 | - } |
1055 | - else |
1056 | - if (operation == ClipboardCut) |
1057 | - { |
1058 | - m_formats.append(KDE_CUT_MIME_TYPE); |
1059 | - } |
1060 | - urls.clear(); |
1061 | - gnomeData.clear(); |
1062 | - gnomeData += operation == ClipboardCut ? |
1063 | - QLatin1String("cut") : |
1064 | - QLatin1String("copy"); |
1065 | - QStringList fullPaths = makeFullPath(files, path); |
1066 | - for(int counter = 0; counter < fullPaths.count(); counter++) |
1067 | - { |
1068 | - QUrl item = QUrl::fromLocalFile(fullPaths.at((counter))); |
1069 | - urls.append(item); |
1070 | - gnomeData += QLatin1Char('\n') + item.toEncoded() ; |
1071 | - } |
1072 | - if (urls.count() > 0) |
1073 | - { |
1074 | - setData(GNOME_COPIED_MIME_TYPE, gnomeData); |
1075 | - setUrls(urls); |
1076 | - ret = true; |
1077 | - } |
1078 | - else |
1079 | - { |
1080 | - // emit error( QObject::tr("Item does not exist"), item); |
1081 | - } |
1082 | - return ret; |
1083 | -} |
1084 | - |
1085 | -//=============================================================================================== |
1086 | -/*! |
1087 | - * \brief DirModelMimeData::clipboardMimeData |
1088 | - * \return |
1089 | - */ |
1090 | -const QMimeData *DirModelMimeData::clipboardMimeData() |
1091 | -{ |
1092 | - const QMimeData *ret = 0; |
1093 | - QClipboard *clipboard = QApplication::clipboard(); |
1094 | - if (m_globalMimeData) |
1095 | - { |
1096 | - ret = m_globalMimeData; |
1097 | - } |
1098 | - else |
1099 | - if (clipboard) |
1100 | - { |
1101 | - ret = clipboard->mimeData(); |
1102 | - } |
1103 | -#if DEBUG_MESSAGES |
1104 | - qDebug() << Q_FUNC_INFO << "clipboard" << clipboard |
1105 | - << "m_ownClipboardMimeData" << m_globalMimeData |
1106 | - << "clipboard->mimeData()" << ret; |
1107 | -#endif |
1108 | - return ret; |
1109 | -} |
1110 | - |
1111 | -//=============================================================================================== |
1112 | -/*! |
1113 | - * \brief DirModelMimeData::localUrls |
1114 | - * \return |
1115 | - */ |
1116 | -QStringList |
1117 | -DirModelMimeData::localUrls(ClipboardOperation& operation) |
1118 | -{ |
1119 | - m_appMime = clipboardMimeData(); |
1120 | - QStringList paths; |
1121 | - //it may have external urls |
1122 | - if (m_appMime) |
1123 | - { |
1124 | - QList<QUrl> urls; |
1125 | - if (m_appMime->hasUrls()) |
1126 | - { |
1127 | - urls = m_appMime->urls(); |
1128 | - operation = clipBoardOperation(); |
1129 | - } |
1130 | - else |
1131 | - { |
1132 | - urls = gnomeUrls(m_appMime, operation); |
1133 | - } |
1134 | - for (int counter=0; counter < urls.count(); counter++) |
1135 | - { |
1136 | - if (urls.at(counter).toString().startsWith(QLatin1String("file://"))) |
1137 | - { |
1138 | - paths.append(urls.at(counter).toLocalFile()); |
1139 | - } |
1140 | - } |
1141 | - } |
1142 | -#if DEBUG_MESSAGES |
1143 | - qDebug() << Q_FUNC_INFO << paths; |
1144 | -#endif |
1145 | - return paths; |
1146 | -} |
1147 | - |
1148 | - |
1149 | -//=============================================================================================== |
1150 | -/*! |
1151 | - * \brief DirModelMimeData::testClipboardContent() Gets the clipboard content and compare with data previously stored |
1152 | - * \param files |
1153 | - * \param path |
1154 | - * \return true if clipboard has content and it matches data previously stored |
1155 | - */ |
1156 | -bool DirModelMimeData::testClipboardContent(const QStringList &files, const QString &path) |
1157 | -{ |
1158 | - bool ret = false; |
1159 | - ClipboardOperation tmpOperation; |
1160 | - QStringList expectedList = makeFullPath(files,path); |
1161 | - QStringList realList = localUrls(tmpOperation); |
1162 | - if (realList == expectedList) |
1163 | - { |
1164 | - ret = true; |
1165 | - } |
1166 | - else |
1167 | - { |
1168 | - qWarning() << Q_FUNC_INFO << "FAILED, Clipboard does not work"; |
1169 | - } |
1170 | - return ret; |
1171 | -} |
1172 | - |
1173 | -//=============================================================================================== |
1174 | -/*! |
1175 | - * \brief DirModelMimeData::makeFullPath() Just creates a fulpath file list when they do exist |
1176 | - * \param files |
1177 | - * \param path |
1178 | - * \return the list itself |
1179 | - */ |
1180 | -QStringList DirModelMimeData::makeFullPath(const QStringList& files, const QString &path) |
1181 | -{ |
1182 | - QStringList fullPathnameList; |
1183 | - QFileInfo fi; |
1184 | - for(int counter = 0; counter < files.count(); counter++) |
1185 | - { |
1186 | - const QString& item = files.at(counter); |
1187 | - fi.setFile(item); |
1188 | - if (!fi.isAbsolute()) |
1189 | - { |
1190 | - fi.setFile(path + QDir::separator() + item); |
1191 | - } |
1192 | - if (fi.exists()) |
1193 | - { |
1194 | - fullPathnameList.append(fi.absoluteFilePath()); |
1195 | - } |
1196 | - } |
1197 | - return fullPathnameList; |
1198 | -} |
1199 | |
1200 | |
1201 | //=============================================================================================== |
1202 | @@ -471,14 +92,10 @@ |
1203 | QObject(parent) |
1204 | , m_curAction(0) |
1205 | , m_cancelCurrentAction(false) |
1206 | - , m_busy(false) |
1207 | - , m_mimeData ( new DirModelMimeData() ) |
1208 | - , m_clipboardModifiedByOther(false) |
1209 | + , m_busy(false) |
1210 | + , m_clipboardChanged(false) |
1211 | { |
1212 | - QClipboard *clipboard = QApplication::clipboard(); |
1213 | |
1214 | - connect(clipboard, SIGNAL(dataChanged()), this, SIGNAL(clipboardChanged())); |
1215 | - connect(clipboard, SIGNAL(dataChanged()), this, SLOT(clipboardHasChanged())); |
1216 | } |
1217 | |
1218 | //=============================================================================================== |
1219 | @@ -487,7 +104,7 @@ |
1220 | */ |
1221 | FileSystemAction::~FileSystemAction() |
1222 | { |
1223 | - delete m_mimeData; |
1224 | + |
1225 | } |
1226 | |
1227 | //=============================================================================================== |
1228 | @@ -497,7 +114,7 @@ |
1229 | */ |
1230 | void FileSystemAction::remove(const QStringList &paths) |
1231 | { |
1232 | - createAndProcessAction(ActionRemove, paths, NoClipboard); |
1233 | + createAndProcessAction(ActionRemove, paths); |
1234 | } |
1235 | |
1236 | //=============================================================================================== |
1237 | @@ -1092,76 +709,72 @@ |
1238 | m_path = path; |
1239 | } |
1240 | |
1241 | -//=============================================================================================== |
1242 | -/*! |
1243 | - * \brief FileSystemAction::copy |
1244 | - * \param pathnames |
1245 | - */ |
1246 | -void FileSystemAction::copy(const QStringList &pathnames) |
1247 | -{ |
1248 | - storeOnClipboard(pathnames, ClipboardCopy); |
1249 | -} |
1250 | - |
1251 | -//=============================================================================================== |
1252 | -/*! |
1253 | - * \brief FileSystemAction::cut |
1254 | - * \param pathnames |
1255 | - */ |
1256 | -void FileSystemAction::cut(const QStringList &pathnames) |
1257 | -{ |
1258 | - storeOnClipboard(pathnames, ClipboardCut); |
1259 | -} |
1260 | - |
1261 | -//=============================================================================================== |
1262 | -/*! |
1263 | - * \brief FileSystemAction::paste |
1264 | - */ |
1265 | -void FileSystemAction::paste() |
1266 | -{ |
1267 | - ClipboardOperation operation; |
1268 | - QStringList paths = m_mimeData->localUrls(operation); |
1269 | -#if DEBUG_MESSAGES |
1270 | - qDebug() << Q_FUNC_INFO << paths; |
1271 | -#endif |
1272 | - if (paths.count()) |
1273 | - { |
1274 | - QFileInfo destination(m_path); |
1275 | - QFileInfo origin(QFileInfo(paths.at(0)).absolutePath()); |
1276 | - ActionType actionType = ActionCopy; // start with Copy and check for Cut |
1277 | - if (operation == ClipboardCut) |
1278 | - { |
1279 | - //we allow Copy to backup items, but Cut must Fail |
1280 | - if (destination.absoluteFilePath() == origin.absoluteFilePath()) |
1281 | - { |
1282 | - emit error(tr("Cannot paste"), |
1283 | - tr("origin and destination folder are the same")); |
1284 | - return; |
1285 | - } |
1286 | - // cut needs write permission on origin |
1287 | - if (!origin.isWritable()) |
1288 | - { |
1289 | - emit error(tr("Cannot paste"), |
1290 | - tr("no write permission on folder ") + origin.absoluteFilePath() ); |
1291 | - return; |
1292 | - } |
1293 | - //so far it always returns true since on Linux it is possible to rename |
1294 | - // between different file systems |
1295 | - if ( moveUsingSameFileSystem(paths.at(0)) ) { |
1296 | - actionType = ActionMove; |
1297 | - } else { |
1298 | - actionType = ActionHardMoveCopy; // first step |
1299 | - } |
1300 | + |
1301 | + |
1302 | +void FileSystemAction::copyIntoCurrentPath(const QStringList& items) |
1303 | +{ |
1304 | +#if DEBUG_MESSAGES |
1305 | + qDebug() << Q_FUNC_INFO << items; |
1306 | +#endif |
1307 | + m_clipboardChanged = false; |
1308 | + if (items.count()) |
1309 | + { |
1310 | + QFileInfo destination(m_path); |
1311 | + if (destination.isWritable()) |
1312 | + { |
1313 | + createAndProcessAction(ActionCopy, items); |
1314 | + } |
1315 | + else |
1316 | + { |
1317 | + emit error(tr("Cannot copy items"), |
1318 | + tr("no write permission on folder ") + destination.absoluteFilePath() ); |
1319 | + |
1320 | + } |
1321 | + } |
1322 | +} |
1323 | + |
1324 | + |
1325 | +void FileSystemAction::moveIntoCurrentPath(const QStringList& items) |
1326 | +{ |
1327 | +#if DEBUG_MESSAGES |
1328 | + qDebug() << Q_FUNC_INFO << items; |
1329 | +#endif |
1330 | + m_clipboardChanged = false; |
1331 | + if (items.count()) |
1332 | + { |
1333 | + QFileInfo destination(m_path); |
1334 | + QFileInfo origin(QFileInfo(items.at(0)).absolutePath()); |
1335 | + ActionType actionType = ActionMove; |
1336 | + static QString titleError = tr("Cannot move items"); |
1337 | + static QString noWriteError = tr("no write permission on folder "); |
1338 | + //we allow Copy to backup items, but Cut must Fail |
1339 | + if (destination.absoluteFilePath() == origin.absoluteFilePath()) |
1340 | + { |
1341 | + emit error(titleError, |
1342 | + tr("origin and destination folders are the same")); |
1343 | + return; |
1344 | + } |
1345 | + // cut needs write permission on origin |
1346 | + if (!origin.isWritable()) |
1347 | + { |
1348 | + emit error(titleError, noWriteError + origin.absoluteFilePath()); |
1349 | + return; |
1350 | + } |
1351 | + //check if it is possible to move items |
1352 | + if ( !moveUsingSameFileSystem(items.at(0)) ) |
1353 | + { |
1354 | + actionType = ActionHardMoveCopy; // first step |
1355 | } |
1356 | if (!destination.isWritable()) |
1357 | { |
1358 | - emit error(tr("Cannot paste"), |
1359 | - tr("no write permission on folder ") + destination.absoluteFilePath() ); |
1360 | + emit error(titleError, noWriteError + destination.absoluteFilePath()); |
1361 | return; |
1362 | } |
1363 | - createAndProcessAction(actionType, paths, operation); |
1364 | + createAndProcessAction(actionType, items); |
1365 | } |
1366 | } |
1367 | |
1368 | + |
1369 | //=============================================================================================== |
1370 | /*! |
1371 | * \brief FileSystemAction::createAndProcessAction |
1372 | @@ -1169,7 +782,7 @@ |
1373 | * \param paths |
1374 | * \param operation |
1375 | */ |
1376 | -void FileSystemAction::createAndProcessAction(ActionType actionType, const QStringList& paths, ClipboardOperation operation) |
1377 | +void FileSystemAction::createAndProcessAction(ActionType actionType, const QStringList& paths) |
1378 | { |
1379 | #if DEBUG_MESSAGES |
1380 | qDebug() << Q_FUNC_INFO << paths; |
1381 | @@ -1177,7 +790,6 @@ |
1382 | Action *myAction = 0; |
1383 | int origPathLen = 0; |
1384 | myAction = createAction(actionType, origPathLen); |
1385 | - myAction->operation = operation; |
1386 | myAction->origPath = QFileInfo(paths.at(0)).absolutePath(); |
1387 | myAction->baseOrigSize = myAction->origPath.length(); |
1388 | for (int counter=0; counter < paths.count(); counter++) |
1389 | @@ -1197,12 +809,7 @@ |
1390 | //and it is already computed |
1391 | myAction->steps += myAction->totalBytes / (COPY_BUFFER_SIZE * STEP_FILES); |
1392 | } |
1393 | - */ |
1394 | - if (operation == ClipboardCut) |
1395 | - { |
1396 | - //this must still be false when cut finishes to change the clipboard to the target |
1397 | - m_clipboardModifiedByOther = false; |
1398 | - } |
1399 | + */ |
1400 | m_queuedActions.append(myAction); |
1401 | if (!m_busy) |
1402 | { |
1403 | @@ -1278,16 +885,6 @@ |
1404 | return targetFsId == originFsId; |
1405 | } |
1406 | |
1407 | -//======================================================= |
1408 | -/*! |
1409 | - * \brief FileSystemAction::clipboardLocalUrlsConunter |
1410 | - * \return |
1411 | - */ |
1412 | -int FileSystemAction::clipboardLocalUrlsConunter() |
1413 | -{ |
1414 | - ClipboardOperation operation; |
1415 | - return m_mimeData->localUrls(operation).count(); |
1416 | -} |
1417 | |
1418 | //================================================================================ |
1419 | /*! |
1420 | @@ -1296,14 +893,16 @@ |
1421 | * If a Paste was made from a Cut operation, items pasted become avaialable in the clipboard |
1422 | * as from Copy source operation, so items can be now Pasted again, but with no source removal |
1423 | * |
1424 | - * It checks for \a m_clipboardModifiedByOther that idenftifies if the clipboard was modified during the |
1425 | + * It checks for \a m_clipboardChanged that idenftifies if the clipboard was modified during the |
1426 | * operation maybe by another application. |
1427 | */ |
1428 | void FileSystemAction::endCurrentAction() |
1429 | { |
1430 | - if ( m_curAction->origPath != m_curAction->targetPath && |
1431 | - m_curAction->operation == ClipboardCut && |
1432 | - !m_clipboardModifiedByOther ) |
1433 | + |
1434 | + if ( !m_clipboardChanged && |
1435 | + m_curAction->origPath != m_curAction->targetPath && |
1436 | + (m_curAction->type == ActionMove || m_curAction->type == ActionHardMoveRemove) |
1437 | + ) |
1438 | { |
1439 | QStringList items; |
1440 | const ActionEntry *entry; |
1441 | @@ -1319,7 +918,7 @@ |
1442 | { |
1443 | QString targetPath = m_curAction->targetPath; |
1444 | //it is not necessary to handle own clipboard here |
1445 | - m_mimeData->setIntoClipboard(items, targetPath, ClipboardCopy); |
1446 | + emit recopy(items, targetPath); |
1447 | } |
1448 | } |
1449 | } |
1450 | @@ -1544,16 +1143,6 @@ |
1451 | QTimer::singleShot(0, this, slot); |
1452 | } |
1453 | |
1454 | -//================================================================================ |
1455 | -/*! |
1456 | - * \brief FileSystemAction::clipboardHasChanged() used to identify if the clipboard changed during a Cut operation |
1457 | - * |
1458 | - * \sa \ref endCurrentAction() |
1459 | - */ |
1460 | -void FileSystemAction::clipboardHasChanged() |
1461 | -{ |
1462 | - m_clipboardModifiedByOther = true; |
1463 | -} |
1464 | |
1465 | |
1466 | //================================================================================ |
1467 | @@ -1666,29 +1255,6 @@ |
1468 | return steps; |
1469 | } |
1470 | |
1471 | -//================================================================== |
1472 | -/*! |
1473 | - * \brief FileSystemAction::storeOnClipboard() store data on Clipboard |
1474 | - * \param pathnames files list |
1475 | - * \param op \ref ClipboardOperation as \ref ClipboardCopy or \ref ClipboardCut |
1476 | - * |
1477 | - * Stores data on clipboard by calling \ref DirModelMimeData::setIntoClipboard() which uses Qt class QClipboard |
1478 | - * It is expected that QClipboard class emits the dataChanged() signal when a new content is set into it, |
1479 | - * if it does we caught that signal in \ref clipboardHasChanged() which sets \ref m_clipboardModifiedByOther to true. |
1480 | - */ |
1481 | -void FileSystemAction::storeOnClipboard(const QStringList &pathnames, ClipboardOperation op) |
1482 | -{ |
1483 | -#if DEBUG_MESSAGES |
1484 | - qDebug() << Q_FUNC_INFO << pathnames << "ClipboardOperation" << op; |
1485 | -#endif |
1486 | - DirModelMimeData::ClipBoardDataOwner owner = |
1487 | - m_mimeData->setIntoClipboard(pathnames, m_path, op); |
1488 | - if (owner == DirModelMimeData::MySelf || !m_clipboardModifiedByOther) |
1489 | - { |
1490 | - emit clipboardChanged(); |
1491 | - } |
1492 | -} |
1493 | - |
1494 | |
1495 | //================================================================== |
1496 | bool FileSystemAction::endCopySingleFile() |
1497 | @@ -1722,3 +1288,15 @@ |
1498 | #endif |
1499 | return ret; |
1500 | } |
1501 | + |
1502 | + |
1503 | +//================================================================== |
1504 | +/*! |
1505 | + * \brief FileSystemAction::onClipboardChanged() |
1506 | + * |
1507 | + * sets \ref m_clipboardChanged indicating the fhe Clipboard was changed. |
1508 | + */ |
1509 | +void FileSystemAction::onClipboardChanged() |
1510 | +{ |
1511 | + m_clipboardChanged = true; |
1512 | +} |
1513 | |
1514 | === modified file 'folderlistmodel/filesystemaction.h' |
1515 | --- folderlistmodel/filesystemaction.h 2013-12-31 16:57:19 +0000 |
1516 | +++ folderlistmodel/filesystemaction.h 2014-01-29 16:33:58 +0000 |
1517 | @@ -52,10 +52,6 @@ |
1518 | class QFile; |
1519 | class QTemporaryFile; |
1520 | |
1521 | -enum ClipboardOperation |
1522 | -{ |
1523 | - NoClipboard, ClipboardCopy, ClipboardCut |
1524 | -}; |
1525 | |
1526 | /*! |
1527 | * \brief The FileSystemAction class does file system operations copy/cut/paste/remove items |
1528 | @@ -104,16 +100,16 @@ |
1529 | |
1530 | public: |
1531 | bool isBusy() const; |
1532 | - int getProgressCounter() const; |
1533 | - int clipboardLocalUrlsConunter(); |
1534 | + int getProgressCounter() const; |
1535 | |
1536 | public slots: |
1537 | void cancel(); |
1538 | void remove(const QStringList & filePaths); |
1539 | - void pathChanged(const QString& path); |
1540 | - void paste(); |
1541 | - void cut(const QStringList&); |
1542 | - void copy(const QStringList&); |
1543 | + void pathChanged(const QString& path); |
1544 | + void copyIntoCurrentPath(const QStringList& items); |
1545 | + void moveIntoCurrentPath(const QStringList& items); |
1546 | + void onClipboardChanged(); |
1547 | + |
1548 | |
1549 | signals: |
1550 | void error(const QString& errorTitle, const QString &errorMessage); |
1551 | @@ -123,14 +119,13 @@ |
1552 | void added(const QFileInfo& ); |
1553 | void changed(const QFileInfo&); |
1554 | void progress(int curItem, int totalItems, int percent); |
1555 | - void clipboardChanged(); |
1556 | + void recopy(const QStringList &names, const QString& path); |
1557 | |
1558 | private slots: |
1559 | void processAction(); |
1560 | void processActionEntry(); |
1561 | void processCopyEntry(); |
1562 | bool processCopySingleFile(); |
1563 | - void clipboardHasChanged(); |
1564 | |
1565 | private: |
1566 | enum ActionType |
1567 | @@ -141,8 +136,9 @@ |
1568 | ActionHardMoveCopy, |
1569 | ActionHardMoveRemove |
1570 | }; |
1571 | - void createAndProcessAction(ActionType actionType, const QStringList& paths, |
1572 | - ClipboardOperation operation=NoClipboard); |
1573 | + |
1574 | + void createAndProcessAction(ActionType actionType, const QStringList& paths); |
1575 | + |
1576 | struct CopyFile |
1577 | { |
1578 | public: |
1579 | @@ -199,8 +195,7 @@ |
1580 | quint64 totalBytes; |
1581 | quint64 bytesWritten; |
1582 | int currEntryIndex; |
1583 | - ActionEntry * currEntry; |
1584 | - ClipboardOperation operation; |
1585 | + ActionEntry * currEntry; |
1586 | CopyFile copyFile; |
1587 | bool done; |
1588 | Action * auxAction; |
1589 | @@ -213,10 +208,11 @@ |
1590 | bool m_cancelCurrentAction; |
1591 | bool m_busy; |
1592 | QString m_path; |
1593 | - DirModelMimeData * m_mimeData; |
1594 | + |
1595 | QString m_errorTitle; |
1596 | QString m_errorMsg; |
1597 | - bool m_clipboardModifiedByOther; |
1598 | + bool m_clipboardChanged; //!< this is set to false in \ref moveIntoCurrentPath() and \ref copyIntoCurrentPath(); |
1599 | + |
1600 | |
1601 | private: |
1602 | Action * createAction(ActionType, int origBase = 0); |
1603 | @@ -232,8 +228,7 @@ |
1604 | bool copySymLink(const QString& target, const QFileInfo& orig); |
1605 | void scheduleSlot(const char *slot); |
1606 | void moveDirToTempAndRemoveItLater(const QString& dir); |
1607 | - bool makeBackupNameForCurrentItem(Action *action); |
1608 | - void storeOnClipboard(const QStringList &pathnames, ClipboardOperation op); |
1609 | + bool makeBackupNameForCurrentItem(Action *action); |
1610 | bool endCopySingleFile(); |
1611 | bool isThereDiskSpace(qint64 requiredSize); |
1612 | |
1613 | |
1614 | === added file 'folderlistmodel/fmutil.cpp' |
1615 | --- folderlistmodel/fmutil.cpp 1970-01-01 00:00:00 +0000 |
1616 | +++ folderlistmodel/fmutil.cpp 2014-01-29 16:33:58 +0000 |
1617 | @@ -0,0 +1,132 @@ |
1618 | +/************************************************************************** |
1619 | + * |
1620 | + * Copyright 2014 Canonical Ltd. |
1621 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
1622 | + * |
1623 | + * This program is free software; you can redistribute it and/or modify |
1624 | + * it under the terms of the GNU Lesser General Public License as published by |
1625 | + * the Free Software Foundation; version 3. |
1626 | + * |
1627 | + * This program is distributed in the hope that it will be useful, |
1628 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1629 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1630 | + * GNU Lesser General Public License for more details. |
1631 | + * |
1632 | + * You should have received a copy of the GNU Lesser General Public License |
1633 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1634 | + * |
1635 | + * File: fmutil.cpp |
1636 | + * Date: 29/01/2014 |
1637 | + */ |
1638 | + |
1639 | +#include "fmutil.h" |
1640 | + |
1641 | +#include <QIcon> |
1642 | +#include <QFileInfo> |
1643 | +#include <QDir> |
1644 | +#include <QDebug> |
1645 | + |
1646 | +bool FMUtil::m_triedThemeName = false; |
1647 | + |
1648 | +FMUtil::FMUtil() |
1649 | +{ |
1650 | +} |
1651 | + |
1652 | + |
1653 | +/*! |
1654 | + * \brief FMUtil::setThemeName() tries to set a theme name in order to get icons |
1655 | + */ |
1656 | +void FMUtil::setThemeName() |
1657 | +{ |
1658 | + QString name; |
1659 | + //set saying we have tried to set ThemeName |
1660 | + m_triedThemeName = true; |
1661 | + QLatin1String ubuntu_mobileTheme("ubuntu-mobile"); |
1662 | + QStringList paths(QIcon::themeSearchPaths()); |
1663 | +#if defined(Q_OS_UNIX) |
1664 | + if (paths.isEmpty()) |
1665 | + { |
1666 | + paths.append(QLatin1String("/usr/share/icons")); |
1667 | + } |
1668 | +#endif |
1669 | + foreach (const QString& dir, paths) |
1670 | + { |
1671 | + QDir D(dir); |
1672 | + if (D.exists()) |
1673 | + { |
1674 | +#if DEBUG_MESSAGES |
1675 | + qDebug() << Q_FUNC_INFO << "trying theme on Dir" << D.path(); |
1676 | +#endif |
1677 | + QFileInfoList inf = D.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::System ); |
1678 | + int counter = inf.count(); |
1679 | + //specific names |
1680 | + while (counter--) |
1681 | + { |
1682 | + if (inf.at(counter).fileName() == ubuntu_mobileTheme) |
1683 | + { |
1684 | + if (testThemeName(ubuntu_mobileTheme)) |
1685 | + { |
1686 | + return; |
1687 | + } |
1688 | + else |
1689 | + { |
1690 | + inf.removeAt(counter); |
1691 | + } |
1692 | + } |
1693 | + } |
1694 | + //try symlinks |
1695 | + counter = inf.count(); |
1696 | + while (counter--) |
1697 | + { |
1698 | + if (inf.at(counter).isSymLink()) |
1699 | + { |
1700 | + if (testThemeName(inf.at(counter).fileName())) |
1701 | + { |
1702 | + return; |
1703 | + } |
1704 | + else |
1705 | + { |
1706 | + inf.removeAt(counter); |
1707 | + } |
1708 | + } |
1709 | + } |
1710 | + //try common directories |
1711 | + counter = inf.count(); |
1712 | + while (counter--) |
1713 | + { |
1714 | + if (testThemeName(inf.at(counter).fileName())) |
1715 | + { |
1716 | + return; |
1717 | + } |
1718 | + } |
1719 | + } |
1720 | + } |
1721 | + name.clear(); |
1722 | + QIcon::setThemeName(name); |
1723 | +} |
1724 | + |
1725 | + |
1726 | +bool FMUtil::testThemeName(const QString& themeName) |
1727 | +{ |
1728 | + QMimeDatabase mimeBase; |
1729 | + QStringList mimesToTest = QStringList() |
1730 | + << "text/plain" |
1731 | + << "inode/directory" |
1732 | + << "application/pdf" |
1733 | + << "application/postscript" |
1734 | + << "application/x-gzip"; |
1735 | + |
1736 | + QIcon::setThemeName(themeName); |
1737 | + bool hasTheme = true; |
1738 | + int counter = mimesToTest.count(); |
1739 | + while(hasTheme && counter--) |
1740 | + { |
1741 | + QMimeType mimetype = mimeBase.mimeTypeForName(mimesToTest.at(counter)); |
1742 | + hasTheme = QIcon::hasThemeIcon( mimetype.iconName() ) || |
1743 | + QIcon::hasThemeIcon( mimetype.genericIconName() ) ; |
1744 | + } |
1745 | +#if DEBUG_MESSAGES |
1746 | + qDebug() << Q_FUNC_INFO << "trying theme name" << themeName << "ret=" << hasTheme; |
1747 | +#endif |
1748 | + return hasTheme; |
1749 | +} |
1750 | |
1751 | === added file 'folderlistmodel/fmutil.h' |
1752 | --- folderlistmodel/fmutil.h 1970-01-01 00:00:00 +0000 |
1753 | +++ folderlistmodel/fmutil.h 2014-01-29 16:33:58 +0000 |
1754 | @@ -0,0 +1,46 @@ |
1755 | +/************************************************************************** |
1756 | + * |
1757 | + * Copyright 2014 Canonical Ltd. |
1758 | + * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com> |
1759 | + * |
1760 | + * This program is free software; you can redistribute it and/or modify |
1761 | + * it under the terms of the GNU Lesser General Public License as published by |
1762 | + * the Free Software Foundation; version 3. |
1763 | + * |
1764 | + * This program is distributed in the hope that it will be useful, |
1765 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1766 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1767 | + * GNU Lesser General Public License for more details. |
1768 | + * |
1769 | + * You should have received a copy of the GNU Lesser General Public License |
1770 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1771 | + * |
1772 | + * File: fmutil.h |
1773 | + * Date: 29/01/2014 |
1774 | + */ |
1775 | + |
1776 | +#ifndef FMUTIL_H |
1777 | +#define FMUTIL_H |
1778 | + |
1779 | +#include <QStringList> |
1780 | +#include <QMimeType> |
1781 | +#include <QMimeDatabase> |
1782 | + |
1783 | +/*! |
1784 | + * \brief The FMUtil class provides some utitlities |
1785 | + */ |
1786 | +class FMUtil |
1787 | +{ |
1788 | +public: |
1789 | + static void setThemeName(); |
1790 | + static inline bool hasTriedThemeName() { return m_triedThemeName; } |
1791 | + |
1792 | +private: |
1793 | + FMUtil(); |
1794 | + static bool testThemeName(const QString& themeName); |
1795 | + |
1796 | +private: |
1797 | + static bool m_triedThemeName; |
1798 | +}; |
1799 | + |
1800 | +#endif // FMUTIL_H |
1801 | |
1802 | === modified file 'folderlistmodel/folderlistmodel.pri' |
1803 | --- folderlistmodel/folderlistmodel.pri 2013-11-27 12:04:20 +0000 |
1804 | +++ folderlistmodel/folderlistmodel.pri 2014-01-29 16:33:58 +0000 |
1805 | @@ -4,7 +4,9 @@ |
1806 | $$PWD/ioworkerthread.cpp \ |
1807 | $$PWD/filesystemaction.cpp \ |
1808 | $$PWD/filecompare.cpp \ |
1809 | - $$PWD/externalfswatcher.cpp |
1810 | + $$PWD/externalfswatcher.cpp \ |
1811 | + $$PWD/clipboard.cpp \ |
1812 | + $$PWD/fmutil.cpp |
1813 | |
1814 | |
1815 | |
1816 | @@ -15,7 +17,9 @@ |
1817 | $$PWD/ioworkerthread.h \ |
1818 | $$PWD/filesystemaction.h \ |
1819 | $$PWD/filecompare.h \ |
1820 | - $$PWD/externalfswatcher.h |
1821 | + $$PWD/externalfswatcher.h \ |
1822 | + $$PWD/clipboard.h \ |
1823 | + $$PWD/fmutil.h |
1824 | |
1825 | |
1826 | |
1827 | |
1828 | === modified file 'test_folderlistmodel/regression/tst_folderlistmodel.cpp' |
1829 | --- test_folderlistmodel/regression/tst_folderlistmodel.cpp 2013-12-31 16:57:19 +0000 |
1830 | +++ test_folderlistmodel/regression/tst_folderlistmodel.cpp 2014-01-29 16:33:58 +0000 |
1831 | @@ -29,7 +29,7 @@ |
1832 | #include <QPixmap> |
1833 | #include <QFileIconProvider> |
1834 | |
1835 | -#if defined(REGRESSION_TEST_FOLDERLISTMODEL) && QT_VERSION >= 0x050000 |
1836 | +#if QT_VERSION >= 0x050000 |
1837 | #include <QMimeType> |
1838 | #include <QMimeDatabase> |
1839 | #endif |
1840 | @@ -1629,9 +1629,9 @@ |
1841 | } |
1842 | |
1843 | |
1844 | -#if defined(REGRESSION_TEST_FOLDERLISTMODEL) && QT_VERSION >= 0x050000 |
1845 | +#if QT_VERSION >= 0x050000 |
1846 | void TestDirModel::getThemeIcons() |
1847 | -{ |
1848 | +{ |
1849 | QStringList mimesToTest = QStringList() |
1850 | << "text/plain" |
1851 | << "text/x-c++src" |
1852 | @@ -1650,30 +1650,40 @@ |
1853 | QString msg; |
1854 | QHash<QByteArray, QString> md5IconsTable; |
1855 | |
1856 | + qDebug() << "QIcon::themeSearchPaths()" << QIcon::themeSearchPaths(); |
1857 | + qDebug() << "QIcon::themeName()" << QIcon::themeName(); |
1858 | + |
1859 | + |
1860 | for (int counter=0; counter < mimesToTest.count(); counter++) |
1861 | { |
1862 | QMimeType mimetype = mimeBase.mimeTypeForName(mimesToTest.at(counter)); |
1863 | + |
1864 | msg = QLatin1String("invalid mimetype ") + mimesToTest.at(counter); |
1865 | if (!mimetype.isValid()) |
1866 | { |
1867 | QSKIP_ALL_TESTS(qPrintable(msg)); |
1868 | } |
1869 | - QIcon icon = QIcon::fromTheme(mimetype.iconName()); |
1870 | - msg = QLatin1String("invalid QIcon::fromTheme ") + mimetype.iconName(); |
1871 | + QString iconName = mimetype.iconName(); |
1872 | + if (!QIcon::hasThemeIcon(iconName) && QIcon::hasThemeIcon(mimetype.genericIconName())) |
1873 | + { |
1874 | + iconName = mimetype.genericIconName(); |
1875 | + } |
1876 | + QIcon icon = QIcon::fromTheme(iconName); |
1877 | + msg = QLatin1String("invalid QIcon::fromTheme ") + iconName; |
1878 | if (icon.isNull()) |
1879 | { |
1880 | QSKIP_ALL_TESTS(qPrintable(msg)); |
1881 | } |
1882 | |
1883 | QPixmap pix = icon.pixmap(QSize(48,48)); |
1884 | - msg = QLatin1String("invalid QPixmap from icon ") + mimetype.iconName(); |
1885 | + msg = QLatin1String("invalid QPixmap from icon ") + iconName; |
1886 | if (pix.isNull()) |
1887 | { |
1888 | QSKIP_ALL_TESTS(qPrintable(msg)); |
1889 | } |
1890 | |
1891 | QImage image = pix.toImage(); |
1892 | - msg = QLatin1String("invalid QImage from QPixmap/QIcon ") + mimetype.iconName(); |
1893 | + msg = QLatin1String("invalid QImage from QPixmap/QIcon ") + iconName; |
1894 | if (image.isNull()) |
1895 | { |
1896 | QSKIP_ALL_TESTS(qPrintable(msg)); |
1897 | @@ -2059,9 +2069,7 @@ |
1898 | break; |
1899 | } |
1900 | } |
1901 | - int ret = QTest::qExec(&tc, args); |
1902 | - |
1903 | - return ret; |
1904 | + return QTest::qExec(&tc, args); |
1905 | } |
1906 | |
1907 |
PASSED: Continuous integration, rev:54 91.189. 93.70:8080/ job/ubuntu- filemanager- dev-ubuntu- filemanager- app-plugin- ci/14/ 91.189. 93.70:8080/ job/ubuntu- filemanager- dev-ubuntu- filemanager- app-plugin- raring- amd64-ci/ 14 91.189. 93.70:8080/ job/ubuntu- filemanager- dev-ubuntu- filemanager- app-plugin- saucy-amd64- ci/14 91.189. 93.70:8080/ job/ubuntu- filemanager- dev-ubuntu- filemanager- app-plugin- trusty- amd64-ci/ 11
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild: 91.189. 93.70:8080/ job/ubuntu- filemanager- dev-ubuntu- filemanager- app-plugin- ci/14/rebuild
http://