Changeset View
Changeset View
Standalone View
Standalone View
containments/desktop/plugins/folder/foldermodel.cpp
Show First 20 Lines • Show All 202 Lines • ▼ Show 20 Line(s) | |||||
203 | } | 203 | } | ||
204 | 204 | | |||
205 | FolderModel::~FolderModel() | 205 | FolderModel::~FolderModel() | ||
206 | { | 206 | { | ||
207 | if (m_usedByContainment) { | 207 | if (m_usedByContainment) { | ||
208 | // disconnect so we don't handle signals from the screen mapper when | 208 | // disconnect so we don't handle signals from the screen mapper when | ||
209 | // removeScreen is called | 209 | // removeScreen is called | ||
210 | m_screenMapper->disconnect(this); | 210 | m_screenMapper->disconnect(this); | ||
211 | m_screenMapper->removeScreen(m_screen, url()); | 211 | m_screenMapper->removeScreen(m_screen, resolvedUrl()); | ||
212 | } | 212 | } | ||
213 | } | 213 | } | ||
214 | 214 | | |||
215 | QHash< int, QByteArray > FolderModel::roleNames() const | 215 | QHash< int, QByteArray > FolderModel::roleNames() const | ||
216 | { | 216 | { | ||
217 | return staticRoleNames(); | 217 | return staticRoleNames(); | ||
218 | } | 218 | } | ||
219 | 219 | | |||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Line(s) | 259 | { | |||
262 | } | 262 | } | ||
263 | 263 | | |||
264 | invalidateFilter(); | 264 | invalidateFilter(); | ||
265 | } | 265 | } | ||
266 | 266 | | |||
267 | void FolderModel::newFileMenuItemCreated(const QUrl &url) | 267 | void FolderModel::newFileMenuItemCreated(const QUrl &url) | ||
268 | { | 268 | { | ||
269 | if (m_usedByContainment) { | 269 | if (m_usedByContainment) { | ||
270 | m_screenMapper->addMapping(url.toString(), m_screen, ScreenMapper::DelayedSignal); | 270 | m_screenMapper->addMapping(url, m_screen, ScreenMapper::DelayedSignal); | ||
271 | m_dropTargetPositions.insert(url.fileName(), m_menuPosition); | 271 | m_dropTargetPositions.insert(url.fileName(), m_menuPosition); | ||
272 | m_menuPosition = {}; | 272 | m_menuPosition = {}; | ||
273 | m_dropTargetPositionsCleanup->start(); | 273 | m_dropTargetPositionsCleanup->start(); | ||
274 | } | 274 | } | ||
275 | } | 275 | } | ||
276 | 276 | | |||
277 | QString FolderModel::url() const | 277 | QString FolderModel::url() const | ||
278 | { | 278 | { | ||
279 | return m_url; | 279 | return m_url; | ||
280 | } | 280 | } | ||
281 | 281 | | |||
282 | void FolderModel::setUrl(const QString& url) | 282 | void FolderModel::setUrl(const QString& url) | ||
283 | { | 283 | { | ||
284 | const QUrl &resolvedUrl = resolve(url); | 284 | const QUrl &resolvedNewUrl = resolve(url); | ||
285 | 285 | | |||
286 | if (url == m_url) { | 286 | if (url == m_url) { | ||
287 | m_dirModel->dirLister()->updateDirectory(resolvedUrl); | 287 | m_dirModel->dirLister()->updateDirectory(resolvedNewUrl); | ||
288 | return; | 288 | return; | ||
289 | } | 289 | } | ||
290 | 290 | | |||
291 | const auto oldUrl = m_url; | 291 | const auto oldUrl = resolvedUrl(); | ||
mwolff: couldn't you use `this->resolvedUrl()` here? | |||||
could you call this at the top? then the this-> call shouldn't be required, I think. mwolff: could you call this at the top? then the `this->` call shouldn't be required, I think. | |||||
292 | 292 | | |||
293 | beginResetModel(); | 293 | beginResetModel(); | ||
294 | m_url = url; | 294 | m_url = url; | ||
295 | m_isDirCache.clear(); | 295 | m_isDirCache.clear(); | ||
296 | m_dirModel->dirLister()->openUrl(resolvedUrl); | 296 | m_dirModel->dirLister()->openUrl(resolvedNewUrl); | ||
297 | clearDragImages(); | 297 | clearDragImages(); | ||
298 | m_dragIndexes.clear(); | 298 | m_dragIndexes.clear(); | ||
299 | endResetModel(); | 299 | endResetModel(); | ||
300 | 300 | | |||
301 | emit urlChanged(); | 301 | emit urlChanged(); | ||
302 | emit resolvedUrlChanged(); | 302 | emit resolvedUrlChanged(); | ||
303 | 303 | | |||
304 | m_errorString.clear(); | 304 | m_errorString.clear(); | ||
305 | emit errorStringChanged(); | 305 | emit errorStringChanged(); | ||
306 | 306 | | |||
307 | if (m_dirWatch) { | 307 | if (m_dirWatch) { | ||
308 | delete m_dirWatch; | 308 | delete m_dirWatch; | ||
309 | m_dirWatch = nullptr; | 309 | m_dirWatch = nullptr; | ||
310 | } | 310 | } | ||
311 | 311 | | |||
312 | if (resolvedUrl.isValid()) { | 312 | if (resolvedNewUrl.isValid()) { | ||
313 | m_dirWatch = new KDirWatch(this); | 313 | m_dirWatch = new KDirWatch(this); | ||
314 | connect(m_dirWatch, &KDirWatch::created, this, &FolderModel::iconNameChanged); | 314 | connect(m_dirWatch, &KDirWatch::created, this, &FolderModel::iconNameChanged); | ||
315 | connect(m_dirWatch, &KDirWatch::dirty, this, &FolderModel::iconNameChanged); | 315 | connect(m_dirWatch, &KDirWatch::dirty, this, &FolderModel::iconNameChanged); | ||
316 | m_dirWatch->addFile(resolvedUrl.toLocalFile() + QLatin1String("/.directory")); | 316 | m_dirWatch->addFile(resolvedNewUrl.toLocalFile() + QLatin1String("/.directory")); | ||
317 | } | 317 | } | ||
318 | 318 | | |||
319 | if (m_dragInProgress) { | 319 | if (m_dragInProgress) { | ||
320 | m_urlChangedWhileDragging = true; | 320 | m_urlChangedWhileDragging = true; | ||
321 | } | 321 | } | ||
322 | 322 | | |||
323 | emit iconNameChanged(); | 323 | emit iconNameChanged(); | ||
324 | 324 | | |||
325 | if (m_usedByContainment) { | 325 | if (m_usedByContainment) { | ||
326 | m_screenMapper->removeScreen(m_screen, oldUrl); | 326 | m_screenMapper->removeScreen(m_screen, oldUrl); | ||
327 | m_screenMapper->addScreen(m_screen, url); | 327 | m_screenMapper->addScreen(m_screen, resolvedUrl()); | ||
mwolff: shouldn't/couldn't this use resolvedUrl? | |||||
is this different from the local resolvedUrl variable? If so, why? confusing ;-) Add a comment then mwolff: is this different from the local `resolvedUrl` variable? If so, why? confusing ;-) Add a… | |||||
328 | } | 328 | } | ||
329 | } | 329 | } | ||
330 | 330 | | |||
331 | QUrl FolderModel::resolvedUrl() const | 331 | QUrl FolderModel::resolvedUrl() const | ||
332 | { | 332 | { | ||
333 | return m_dirModel->dirLister()->url(); | 333 | return m_dirModel->dirLister()->url(); | ||
334 | } | 334 | } | ||
335 | 335 | | |||
▲ Show 20 Lines • Show All 289 Lines • ▼ Show 20 Line(s) | |||||
625 | 625 | | |||
626 | void FolderModel::setScreen(int screen) | 626 | void FolderModel::setScreen(int screen) | ||
627 | { | 627 | { | ||
628 | if (m_screen == screen) | 628 | if (m_screen == screen) | ||
629 | return; | 629 | return; | ||
630 | 630 | | |||
631 | m_screen = screen; | 631 | m_screen = screen; | ||
632 | if (m_usedByContainment) { | 632 | if (m_usedByContainment) { | ||
633 | m_screenMapper->addScreen(screen, url()); | 633 | m_screenMapper->addScreen(screen, resolvedUrl()); | ||
mwolff: `resolvedUrl()`? | |||||
634 | } | 634 | } | ||
635 | emit screenChanged(); | 635 | emit screenChanged(); | ||
636 | } | 636 | } | ||
637 | 637 | | |||
638 | KFileItem FolderModel::rootItem() const | 638 | KFileItem FolderModel::rootItem() const | ||
639 | { | 639 | { | ||
640 | return m_dirModel->dirLister()->rootItem(); | 640 | return m_dirModel->dirLister()->rootItem(); | ||
641 | } | 641 | } | ||
▲ Show 20 Lines • Show All 412 Lines • ▼ Show 20 Line(s) | 1052 | if (dropTargetFolderUrl.fileName() == QLatin1String(".")) { | |||
1054 | dropTargetFolderUrl = dropTargetFolderUrl.adjusted(QUrl::RemoveFilename); | 1054 | dropTargetFolderUrl = dropTargetFolderUrl.adjusted(QUrl::RemoveFilename); | ||
1055 | } | 1055 | } | ||
1056 | 1056 | | |||
1057 | // use dropTargetUrl to resolve desktop:/ to the actual file location which is also used by the mime data | 1057 | // use dropTargetUrl to resolve desktop:/ to the actual file location which is also used by the mime data | ||
1058 | /* QMimeData operates on local URLs, but the dir lister and thus screen mapper and positioner may | 1058 | /* QMimeData operates on local URLs, but the dir lister and thus screen mapper and positioner may | ||
1059 | * use a fancy scheme like desktop:/ instead. Ensure we always use the latter to properly map URLs, | 1059 | * use a fancy scheme like desktop:/ instead. Ensure we always use the latter to properly map URLs, | ||
1060 | * i.e. go from file:///home/user/Desktop/file to desktop:/file | 1060 | * i.e. go from file:///home/user/Desktop/file to desktop:/file | ||
1061 | */ | 1061 | */ | ||
1062 | auto mappableUrl = [this, dropTargetFolderUrl](const QUrl &url) -> QString { | 1062 | auto mappableUrl = [this, dropTargetFolderUrl](const QUrl &url) -> QUrl { | ||
move down into the first conditional, return original url when nothing changed mwolff: move down into the first conditional, return original url when nothing changed | |||||
1063 | QString mappedUrl = url.toString(); | | |||
1064 | if (dropTargetFolderUrl != m_dirModel->dirLister()->url()) { | 1063 | if (dropTargetFolderUrl != m_dirModel->dirLister()->url()) { | ||
1064 | QString mappedUrl = url.toString(); | ||||
1065 | const auto local = dropTargetFolderUrl.toString(); | 1065 | const auto local = dropTargetFolderUrl.toString(); | ||
1066 | const auto internal = m_dirModel->dirLister()->url().toString(); | 1066 | const auto internal = m_dirModel->dirLister()->url().toString(); | ||
1067 | if (mappedUrl.startsWith(local)) { | 1067 | if (mappedUrl.startsWith(local)) { | ||
1068 | mappedUrl.replace(0, local.size(), internal); | 1068 | mappedUrl.replace(0, local.size(), internal); | ||
mwolff: return `QUrl::fromUserInput(mappedUrl, {}, QUrl::AssumeLocalFile)` | |||||
1069 | } | 1069 | } | ||
1070 | return ScreenMapper::stringToUrl(mappedUrl); | ||||
1070 | } | 1071 | } | ||
1071 | return mappedUrl; | 1072 | return url; | ||
mwolff: return url; | |||||
1072 | }; | 1073 | }; | ||
1073 | 1074 | | |||
1074 | const int x = dropEvent->property("x").toInt(); | 1075 | const int x = dropEvent->property("x").toInt(); | ||
1075 | const int y = dropEvent->property("y").toInt(); | 1076 | const int y = dropEvent->property("y").toInt(); | ||
1076 | const QPoint dropPos = {x, y}; | 1077 | const QPoint dropPos = {x, y}; | ||
1077 | 1078 | | |||
1078 | if (m_dragInProgress && row == -1 && !m_urlChangedWhileDragging) { | 1079 | if (m_dragInProgress && row == -1 && !m_urlChangedWhileDragging) { | ||
1079 | if (m_locked || mimeData->urls().isEmpty()) { | 1080 | if (m_locked || mimeData->urls().isEmpty()) { | ||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Line(s) | |||||
1161 | connect(dropJob, &KIO::DropJob::copyJobStarted, this, [this, dropPos, dropTargetUrl](KIO::CopyJob* copyJob) { | 1162 | connect(dropJob, &KIO::DropJob::copyJobStarted, this, [this, dropPos, dropTargetUrl](KIO::CopyJob* copyJob) { | ||
1162 | auto map = [this, dropPos, dropTargetUrl](const QUrl &targetUrl) { | 1163 | auto map = [this, dropPos, dropTargetUrl](const QUrl &targetUrl) { | ||
1163 | m_dropTargetPositions.insert(targetUrl.fileName(), dropPos); | 1164 | m_dropTargetPositions.insert(targetUrl.fileName(), dropPos); | ||
1164 | m_dropTargetPositionsCleanup->start(); | 1165 | m_dropTargetPositionsCleanup->start(); | ||
1165 | 1166 | | |||
1166 | if (m_usedByContainment) { | 1167 | if (m_usedByContainment) { | ||
1167 | // assign a screen for the item before the copy is actually done, so | 1168 | // assign a screen for the item before the copy is actually done, so | ||
1168 | // filterAcceptsRow doesn't assign the default screen to it | 1169 | // filterAcceptsRow doesn't assign the default screen to it | ||
1169 | QUrl url = QUrl::fromUserInput(m_url, {}, QUrl::AssumeLocalFile); | 1170 | QUrl url = resolvedUrl(); | ||
1170 | // if the folderview's folder is a standard path, just use the targetUrl for mapping | 1171 | // if the folderview's folder is a standard path, just use the targetUrl for mapping | ||
1171 | if (targetUrl.toString().startsWith(url.toString())) { | 1172 | if (targetUrl.toString().startsWith(url.toString())) { | ||
1172 | m_screenMapper->addMapping(targetUrl.toString(), m_screen, ScreenMapper::DelayedSignal); | 1173 | m_screenMapper->addMapping(targetUrl, m_screen, ScreenMapper::DelayedSignal); | ||
1173 | } else if (targetUrl.toString().startsWith(dropTargetUrl.toString())) { | 1174 | } else if (targetUrl.toString().startsWith(dropTargetUrl.toString())) { | ||
1174 | // if the folderview's folder is a special path, like desktop:// , we need to convert | 1175 | // if the folderview's folder is a special path, like desktop:// , we need to convert | ||
1175 | // the targetUrl file:// path to a desktop:/ path for mapping | 1176 | // the targetUrl file:// path to a desktop:/ path for mapping | ||
1176 | auto destPath = dropTargetUrl.path(); | 1177 | auto destPath = dropTargetUrl.path(); | ||
1177 | auto filePath = targetUrl.path(); | 1178 | auto filePath = targetUrl.path(); | ||
1178 | if (filePath.startsWith(destPath)) { | 1179 | if (filePath.startsWith(destPath)) { | ||
1179 | url.setPath(filePath.remove(0, destPath.length())); | 1180 | url.setPath(filePath.remove(0, destPath.length())); | ||
1180 | m_screenMapper->addMapping(url.toString(), m_screen, ScreenMapper::DelayedSignal); | 1181 | m_screenMapper->addMapping(url, m_screen, ScreenMapper::DelayedSignal); | ||
1181 | } | 1182 | } | ||
1182 | } | 1183 | } | ||
1183 | } | 1184 | } | ||
1184 | }; | 1185 | }; | ||
1185 | // remember drop target position for target URL and forget about the source URL | 1186 | // remember drop target position for target URL and forget about the source URL | ||
1186 | connect(copyJob, &KIO::CopyJob::copyingDone, | 1187 | connect(copyJob, &KIO::CopyJob::copyingDone, | ||
1187 | this, [this, map](KIO::Job *, const QUrl &, const QUrl &targetUrl, const QDateTime &, bool, bool) { | 1188 | this, [this, map](KIO::Job *, const QUrl &, const QUrl &targetUrl, const QDateTime &, bool, bool) { | ||
1188 | map(targetUrl); | 1189 | map(targetUrl); | ||
▲ Show 20 Lines • Show All 178 Lines • ▼ Show 20 Line(s) | 1366 | if (idx.isValid()) { | |||
1367 | 1368 | | |||
1368 | emit dataChanged(idx, idx, QVector<int>() << IsDirRole); | 1369 | emit dataChanged(idx, idx, QVector<int>() << IsDirRole); | ||
1369 | } | 1370 | } | ||
1370 | } | 1371 | } | ||
1371 | 1372 | | |||
1372 | void FolderModel::evictFromIsDirCache(const KFileItemList& items) | 1373 | void FolderModel::evictFromIsDirCache(const KFileItemList& items) | ||
1373 | { | 1374 | { | ||
1374 | foreach (const KFileItem &item, items) { | 1375 | foreach (const KFileItem &item, items) { | ||
1375 | m_screenMapper->removeFromMap(item.url().toString()); | 1376 | m_screenMapper->removeFromMap(item.url()); | ||
1376 | m_isDirCache.remove(item.url()); | 1377 | m_isDirCache.remove(item.url()); | ||
1377 | } | 1378 | } | ||
1378 | } | 1379 | } | ||
1379 | 1380 | | |||
1380 | bool FolderModel::lessThan(const QModelIndex &left, const QModelIndex &right) const | 1381 | bool FolderModel::lessThan(const QModelIndex &left, const QModelIndex &right) const | ||
1381 | { | 1382 | { | ||
1382 | const KDirModel *dirModel = static_cast<KDirModel*>(sourceModel()); | 1383 | const KDirModel *dirModel = static_cast<KDirModel*>(sourceModel()); | ||
1383 | 1384 | | |||
▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Line(s) | |||||
1493 | } | 1494 | } | ||
1494 | 1495 | | |||
1495 | bool FolderModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const | 1496 | bool FolderModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const | ||
1496 | { | 1497 | { | ||
1497 | const KDirModel *dirModel = static_cast<KDirModel*>(sourceModel()); | 1498 | const KDirModel *dirModel = static_cast<KDirModel*>(sourceModel()); | ||
1498 | const KFileItem item = dirModel->itemForIndex(dirModel->index(sourceRow, KDirModel::Name, sourceParent)); | 1499 | const KFileItem item = dirModel->itemForIndex(dirModel->index(sourceRow, KDirModel::Name, sourceParent)); | ||
1499 | 1500 | | |||
1500 | if (m_usedByContainment) { | 1501 | if (m_usedByContainment) { | ||
1501 | const QString name = item.url().toString(); | 1502 | const QUrl url = item.url(); | ||
1502 | const int screen = m_screenMapper->screenForItem(name); | 1503 | const int screen = m_screenMapper->screenForItem(url); | ||
1503 | // don't do anything if the folderview is not associated with a screen | 1504 | // don't do anything if the folderview is not associated with a screen | ||
1504 | if (m_screen != -1) { | 1505 | if (m_screen != -1) { | ||
1505 | if (screen == -1) { | 1506 | if (screen == -1) { | ||
1506 | // The item is not associated with a screen, probably because this is the first | 1507 | // The item is not associated with a screen, probably because this is the first | ||
1507 | // time we see it or the folderview was previously used as a regular applet. | 1508 | // time we see it or the folderview was previously used as a regular applet. | ||
1508 | // Associated with this folderview if the view is on the first available screen | 1509 | // Associated with this folderview if the view is on the first available screen | ||
1509 | if (m_screen == m_screenMapper->firstAvailableScreen(url())) { | 1510 | if (m_screen == m_screenMapper->firstAvailableScreen(resolvedUrl())) { | ||
1510 | m_screenMapper->addMapping(name, m_screen, ScreenMapper::DelayedSignal); | 1511 | m_screenMapper->addMapping(url, m_screen, ScreenMapper::DelayedSignal); | ||
not your change: why is m_url not an url :-/ also: introduce the helper function you have in the tests here, too - maybe even move it into a static function in the ScreenMapper and then use it everywhere inplace of the QUrl::fromUserInput three-arg function call mwolff: not your change: why is m_url not an url :-/
also: introduce the helper function you have in… | |||||
amantia: m_url is exposed to QML, that doesn't support QUrl. | |||||
1511 | } else { | 1512 | } else { | ||
1512 | return false; | 1513 | return false; | ||
1513 | } | 1514 | } | ||
1514 | } else if (m_screen != screen) { | 1515 | } else if (m_screen != screen) { | ||
1515 | // the item belongs to a different screen, filter it out | 1516 | // the item belongs to a different screen, filter it out | ||
1516 | return false; | 1517 | return false; | ||
1517 | } | 1518 | } | ||
1518 | } | 1519 | } | ||
▲ Show 20 Lines • Show All 439 Lines • ▼ Show 20 Line(s) | |||||
1958 | } | 1959 | } | ||
1959 | 1960 | | |||
1960 | void FolderModel::undoTextChanged(const QString &text) | 1961 | void FolderModel::undoTextChanged(const QString &text) | ||
1961 | { | 1962 | { | ||
1962 | if (QAction *action = m_actionCollection.action(QStringLiteral("undo"))) { | 1963 | if (QAction *action = m_actionCollection.action(QStringLiteral("undo"))) { | ||
1963 | action->setText(text); | 1964 | action->setText(text); | ||
1964 | } | 1965 | } | ||
1965 | } | 1966 | } | ||
1967 | |
couldn't you use this->resolvedUrl() here?