File indexing completed on 2024-05-12 05:00:20
0001 /* This file is part of the KDE project 0002 SPDX-FileCopyrightText: 2000 David Faure <faure@kde.org> 0003 SPDX-FileCopyrightText: 2002 Michael Brade <brade@kde.org> 0004 SPDX-FileCopyrightText: 2003 Waldo Bastian <bastian@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-only 0007 */ 0008 0009 #include "dirtree_module.h" 0010 #include "dirtree_item.h" 0011 0012 #include <kconfiggroup.h> 0013 #include <kio_version.h> 0014 #include <kprotocolmanager.h> 0015 #include <kdesktopfile.h> 0016 #include <kmessagebox.h> 0017 #include <kiconloader.h> 0018 #include <kdirlister.h> 0019 #include <KLocalizedString> 0020 0021 KonqSidebarDirTreeModule::KonqSidebarDirTreeModule(KonqSidebarTree *parentTree, bool showHidden) 0022 : KonqSidebarTreeModule(parentTree, showHidden), m_dirLister(0L), m_topLevelItem(0L) 0023 { 0024 // SLOW! Get the KConfigGroup from the plugin. 0025 KConfig config("konqsidebartngrc"); 0026 KConfigGroup generalGroup(&config, "General"); 0027 m_showArchivesAsFolders = generalGroup.readEntry("ShowArchivesAsFolders", true); 0028 } 0029 0030 KonqSidebarDirTreeModule::~KonqSidebarDirTreeModule() 0031 { 0032 // KDirLister may still emit canceled while being deleted. 0033 if (m_dirLister) { 0034 disconnect(m_dirLister, &KCoreDirLister::listingDirCanceled, this, &KonqSidebarDirTreeModule::slotListingStopped); 0035 delete m_dirLister; 0036 } 0037 } 0038 0039 QList<QUrl> KonqSidebarDirTreeModule::selectedUrls() 0040 { 0041 QList<QUrl> lst; 0042 KonqSidebarDirTreeItem *selection = static_cast<KonqSidebarDirTreeItem *>(m_pTree->selectedItem()); 0043 if (!selection) { 0044 kError() << "no selection!" << endl; 0045 return lst; 0046 } 0047 lst.append(selection->fileItem().url()); 0048 return lst; 0049 } 0050 0051 void KonqSidebarDirTreeModule::addTopLevelItem(KonqSidebarTreeTopLevelItem *item) 0052 { 0053 if (m_topLevelItem) { // We can handle only one at a time ! 0054 kError() << "Impossible, we can have only one toplevel item !" << endl; 0055 } 0056 0057 KDesktopFile cfg(item->path()); 0058 KConfigGroup desktopGroup = cfg.desktopGroup(); 0059 0060 QUrl targetURL; 0061 targetURL.setPath(item->path()); 0062 0063 if (cfg.hasLinkType()) { 0064 targetURL = cfg.readUrl(); 0065 // some services might want to make their URL configurable in kcontrol 0066 QString configured = desktopGroup.readPathEntry("X-KDE-ConfiguredURL", QString()); 0067 if (!configured.isEmpty()) { 0068 QStringList list = configured.split(':'); 0069 KConfig config(list[0]); 0070 KConfigGroup urlGroup(&config, list[1] != "noGroup" ? list[1] : "General"); 0071 QString conf_url = urlGroup.readEntry(list[2], QString()); 0072 if (!conf_url.isEmpty()) { 0073 targetURL = conf_url; 0074 } 0075 } 0076 } else if (cfg.hasDeviceType()) { 0077 // Determine the mountpoint 0078 QString mp = desktopGroup.readPathEntry("MountPoint", QString()); 0079 if (mp.isEmpty()) { 0080 return; 0081 } 0082 0083 targetURL.setPath(mp); 0084 } else { 0085 return; 0086 } 0087 0088 bool bListable = KProtocolManager::supportsListing(targetURL); 0089 //qCDebug(SIDEBAR_LOG) << targetURL.toDisplayString() << " listable : " << bListable; 0090 0091 if (!bListable) { 0092 item->setExpandable(false); 0093 item->setListable(false); 0094 } 0095 0096 item->setExternalURL(targetURL); 0097 addSubDir(item); 0098 0099 m_topLevelItem = item; 0100 } 0101 0102 void KonqSidebarDirTreeModule::openTopLevelItem(KonqSidebarTreeTopLevelItem *item) 0103 { 0104 if (!item->childCount() && item->isListable()) { 0105 openSubFolder(item); 0106 } 0107 } 0108 0109 void KonqSidebarDirTreeModule::addSubDir(KonqSidebarTreeItem *item) 0110 { 0111 QString id = item->externalURL().adjusted(QUrl::StripTrailingSlash).toString(); 0112 qCDebug(SIDEBAR_LOG) << this << id; 0113 m_dictSubDirs.insert(id, item); 0114 0115 KonqSidebarDirTreeItem *ditem = dynamic_cast<KonqSidebarDirTreeItem *>(item); 0116 if (ditem) { 0117 m_ptrdictSubDirs.insert(ditem->fileItem(), item); 0118 } 0119 } 0120 0121 // Remove <key, item> from dict, taking into account that there maybe 0122 // other items with the same key. 0123 static void remove(Q3Dict<KonqSidebarTreeItem> &dict, const QString &key, KonqSidebarTreeItem *item) 0124 { 0125 Q3PtrList<KonqSidebarTreeItem> *otherItems = 0; 0126 while (true) { 0127 KonqSidebarTreeItem *takeItem = dict.take(key); 0128 if (!takeItem || (takeItem == item)) { 0129 if (!otherItems) { 0130 return; 0131 } 0132 0133 // Insert the otherItems back in 0134 for (KonqSidebarTreeItem * otherItem; (otherItem = otherItems->take(0));) { 0135 dict.insert(key, otherItem); 0136 } 0137 delete otherItems; 0138 return; 0139 } 0140 // Not the item we are looking for 0141 if (!otherItems) { 0142 otherItems = new Q3PtrList<KonqSidebarTreeItem>(); 0143 } 0144 0145 otherItems->prepend(takeItem); 0146 } 0147 } 0148 0149 // Looks up key in dict and returns it in item, if there are multiple items 0150 // with the same key, additional items are returned in itemList which should 0151 // be deleted by the caller. 0152 static void lookupItems(Q3Dict<KonqSidebarTreeItem> &dict, const QString &key, KonqSidebarTreeItem *&item, Q3PtrList<KonqSidebarTreeItem> *&itemList) 0153 { 0154 itemList = 0; 0155 item = dict.take(key); 0156 if (!item) { 0157 return; 0158 } 0159 0160 while (true) { 0161 KonqSidebarTreeItem *takeItem = dict.take(key); 0162 if (!takeItem) { 0163 // 0164 // Insert itemList back in 0165 if (itemList) { 0166 for (KonqSidebarTreeItem *otherItem = itemList->first(); otherItem; otherItem = itemList->next()) { 0167 dict.insert(key, otherItem); 0168 } 0169 } 0170 dict.insert(key, item); 0171 return; 0172 } 0173 if (!itemList) { 0174 itemList = new Q3PtrList<KonqSidebarTreeItem>(); 0175 } 0176 0177 itemList->prepend(takeItem); 0178 } 0179 } 0180 0181 // Remove <key, item> from dict, taking into account that there maybe 0182 // other items with the same key. 0183 static void remove(QHash<KFileItem, KonqSidebarTreeItem *> &dict, const KFileItem &key, KonqSidebarTreeItem *item) 0184 { 0185 Q3PtrList<KonqSidebarTreeItem> *otherItems = 0; 0186 while (true) { 0187 KonqSidebarTreeItem *takeItem = dict.take(key); 0188 if (!takeItem || (takeItem == item)) { 0189 if (!otherItems) { 0190 return; 0191 } 0192 0193 // Insert the otherItems back in 0194 for (KonqSidebarTreeItem * otherItem; (otherItem = otherItems->take(0));) { 0195 dict.insert(key, otherItem); 0196 } 0197 delete otherItems; 0198 return; 0199 } 0200 // Not the item we are looking for 0201 if (!otherItems) { 0202 otherItems = new Q3PtrList<KonqSidebarTreeItem>(); 0203 } 0204 0205 otherItems->prepend(takeItem); 0206 } 0207 } 0208 0209 // Looks up key in dict and returns it in item, if there are multiple items 0210 // with the same key, additional items are returned in itemList which should 0211 // be deleted by the caller. 0212 static void lookupItems(QHash<KFileItem, KonqSidebarTreeItem *> &dict, const KFileItem &key, KonqSidebarTreeItem *&item, Q3PtrList<KonqSidebarTreeItem> *&itemList) 0213 { 0214 itemList = 0; 0215 item = dict.take(key); 0216 if (!item) { 0217 return; 0218 } 0219 0220 while (true) { 0221 KonqSidebarTreeItem *takeItem = dict.take(key); 0222 if (!takeItem) { 0223 // 0224 // Insert itemList back in 0225 if (itemList) { 0226 for (KonqSidebarTreeItem *otherItem = itemList->first(); otherItem; otherItem = itemList->next()) { 0227 dict.insert(key, otherItem); 0228 } 0229 } 0230 dict.insert(key, item); 0231 return; 0232 } 0233 if (!itemList) { 0234 itemList = new Q3PtrList<KonqSidebarTreeItem>(); 0235 } 0236 0237 itemList->prepend(takeItem); 0238 } 0239 } 0240 0241 void KonqSidebarDirTreeModule::removeSubDir(KonqSidebarTreeItem *item, bool childrenOnly) 0242 { 0243 qCDebug(SIDEBAR_LOG) << this << "item=" << item; 0244 if (item->firstChild()) { 0245 KonqSidebarTreeItem *it = static_cast<KonqSidebarTreeItem *>(item->firstChild()); 0246 KonqSidebarTreeItem *next = 0L; 0247 while (it) { 0248 next = static_cast<KonqSidebarTreeItem *>(it->nextSibling()); 0249 removeSubDir(it); 0250 delete it; 0251 it = next; 0252 } 0253 } 0254 0255 if (!childrenOnly) { 0256 QString id = item->externalURL().adjusted(QUrl::StripTrailingSlash).toString(); 0257 remove(m_dictSubDirs, id, item); 0258 while (!(item->alias.isEmpty())) { 0259 remove(m_dictSubDirs, item->alias.front(), item); 0260 item->alias.pop_front(); 0261 } 0262 0263 KonqSidebarDirTreeItem *ditem = dynamic_cast<KonqSidebarDirTreeItem *>(item); 0264 if (ditem) { 0265 remove(m_ptrdictSubDirs, ditem->fileItem(), item); 0266 } 0267 } 0268 } 0269 0270 void KonqSidebarDirTreeModule::openSubFolder(KonqSidebarTreeItem *item) 0271 { 0272 qCDebug(SIDEBAR_LOG) << this << "openSubFolder(" << item->externalURL().prettyUrl() << ")"; 0273 0274 if (!m_dirLister) { // created on demand 0275 m_dirLister = new KDirLister(); 0276 //m_dirLister->setDelayedMimeTypes( true ); // this was set, but it's wrong, without a KMimeTypeResolver... 0277 //m_dirLister->setDirOnlyMode( true ); 0278 // QStringList mimetypes; 0279 // mimetypes<<QString("inode/directory"); 0280 // m_dirLister->setMimeFilter(mimetypes); 0281 0282 connect(m_dirLister, SIGNAL(newItems(KFileItemList)), 0283 this, SLOT(slotNewItems(KFileItemList))); 0284 connect(m_dirLister, SIGNAL(refreshItems(QList<QPair<KFileItem,KFileItem> >)), 0285 this, SLOT(slotRefreshItems(QList<QPair<KFileItem,KFileItem> >))); 0286 connect(m_dirLister, SIGNAL(deleteItem(KFileItem)), 0287 this, SLOT(slotDeleteItem(KFileItem))); 0288 0289 connect(m_dirLister, &KCoreDirLister::listingDirCompleted, this, &KonqSidebarDirTreeModule::slotListingStopped); 0290 connect(m_dirLister, &KCoreDirLister::listingDirCanceled, this, &KonqSidebarDirTreeModule::slotListingStopped); 0291 0292 connect(m_dirLister, SIGNAL(redirection(QUrl,QUrl)), 0293 this, SLOT(slotRedirection(QUrl,QUrl))); 0294 } 0295 0296 if (!item->isTopLevelItem() && 0297 static_cast<KonqSidebarDirTreeItem *>(item)->hasStandardIcon()) { 0298 int size = KIconLoader::global()->currentSize(KIconLoader::Small); 0299 QPixmap pix = DesktopIcon("folder-open", size); 0300 m_pTree->startAnimation(item, "kde", 6, &pix); 0301 } else { 0302 m_pTree->startAnimation(item); 0303 } 0304 0305 listDirectory(item); 0306 } 0307 0308 void KonqSidebarDirTreeModule::listDirectory(KonqSidebarTreeItem *item) 0309 { 0310 // This causes a reparsing, but gets rid of the trailing slash 0311 QString strUrl = item->externalURL().adjusted(QUrl::StripTrailingSlash).toString(); 0312 QUrl url(strUrl); 0313 0314 Q3PtrList<KonqSidebarTreeItem> *itemList; 0315 KonqSidebarTreeItem *openItem; 0316 lookupItems(m_dictSubDirs, strUrl, openItem, itemList); 0317 0318 while (openItem) { 0319 if (openItem->childCount()) { 0320 break; 0321 } 0322 0323 openItem = itemList ? itemList->take(0) : 0; 0324 } 0325 delete itemList; 0326 0327 if (openItem) { 0328 // We have this directory listed already, just copy the entries as we 0329 // can't use the dirlister, it would invalidate the old entries 0330 int size = KIconLoader::global()->currentSize(KIconLoader::Small); 0331 KonqSidebarTreeItem *parentItem = item; 0332 KonqSidebarDirTreeItem *oldItem = static_cast<KonqSidebarDirTreeItem *>(openItem->firstChild()); 0333 while (oldItem) { 0334 const KFileItem fileItem = oldItem->fileItem(); 0335 if (! fileItem.isDir()) { 0336 if (!fileItem.url().isLocalFile()) { 0337 continue; 0338 } 0339 KMimeType::Ptr ptr = fileItem.determineMimeType(); 0340 if (ptr && (ptr->is("inode/directory") || m_showArchivesAsFolders) 0341 && ((!ptr->property("X-KDE-LocalProtocol").toString().isEmpty()))) { 0342 qCDebug(SIDEBAR_LOG) << "Something not really a directory"; 0343 } else { 0344 // kError() << "Item " << fileItem->url().prettyUrl() << " is not a directory!" << endl; 0345 continue; 0346 } 0347 } 0348 0349 KonqSidebarDirTreeItem *dirTreeItem = new KonqSidebarDirTreeItem(parentItem, m_topLevelItem, fileItem); 0350 dirTreeItem->setPixmap(0, fileItem.pixmap(size)); 0351 dirTreeItem->setText(0, KIO::decodeFileName(fileItem.name())); 0352 0353 oldItem = static_cast<KonqSidebarDirTreeItem *>(oldItem->nextSibling()); 0354 } 0355 m_pTree->stopAnimation(item); 0356 0357 return; 0358 } 0359 0360 m_dirLister->setShowingDotFiles(showHidden()); 0361 0362 if (tree()->isOpeningFirstChild()) { 0363 m_dirLister->setAutoErrorHandlingEnabled(false, 0); 0364 } else { 0365 m_dirLister->setAutoErrorHandlingEnabled(true, tree()); 0366 } 0367 0368 m_dirLister->openUrl(url, KDirLister::Keep); 0369 } 0370 0371 void KonqSidebarDirTreeModule::slotNewItems(const KFileItemList &entries) 0372 { 0373 qCDebug(SIDEBAR_LOG) << this << entries.count(); 0374 0375 Q_ASSERT(entries.count()); 0376 const KFileItem firstItem = entries.first(); 0377 0378 // Find parent item - it's the same for all the items 0379 QUrl dir(firstItem.url().adjusted(QUrl::StripTrailingSlash).toString()); 0380 dir = dir.adjusted(QUrl::RemoveFilename); 0381 dir.setPath(dir.path() + ""); 0382 qCDebug(SIDEBAR_LOG) << this << "dir=" << dir.adjusted(QUrl::StripTrailingSlash).toString(); 0383 0384 Q3PtrList<KonqSidebarTreeItem> *parentItemList; 0385 KonqSidebarTreeItem *parentItem; 0386 lookupItems(m_dictSubDirs, dir.adjusted(QUrl::StripTrailingSlash).toString(), parentItem, parentItemList); 0387 0388 if (!parentItem) { // hack for dnssd://domain/type/service listed in dnssd:/type/ dir 0389 dir.setHost(QString()); 0390 lookupItems(m_dictSubDirs, dir.adjusted(QUrl::StripTrailingSlash).toString(), parentItem, parentItemList); 0391 } 0392 0393 if (!parentItem) { 0394 KMessageBox::error(tree(), i18n("Cannot find parent item %1 in the tree. Internal error.", dir.adjusted(QUrl::StripTrailingSlash).toString())); 0395 return; 0396 } 0397 0398 qCDebug(SIDEBAR_LOG) << "number of additional parent items:" << (parentItemList ? parentItemList->count() : 0); 0399 int size = KIconLoader::global()->currentSize(KIconLoader::Small); 0400 do { 0401 qCDebug(SIDEBAR_LOG) << "Parent Item URL:" << parentItem->externalURL(); 0402 KFileItemList::const_iterator kit = entries.begin(); 0403 const KFileItemList::const_iterator kend = entries.end(); 0404 for (; kit != kend; ++kit) { 0405 const KFileItem fileItem = *kit; 0406 0407 if (! fileItem.isDir()) { 0408 if (!fileItem.url().isLocalFile()) { 0409 continue; 0410 } 0411 KMimeType::Ptr ptr = fileItem.determineMimeType(); 0412 0413 if (ptr && (ptr->is("inode/directory") || m_showArchivesAsFolders) 0414 && ((!ptr->property("X-KDE-LocalProtocol").toString().isEmpty()))) { 0415 qCDebug(SIDEBAR_LOG) << "Something really a directory"; 0416 } else { 0417 //kError() << "Item " << fileItem->url().prettyUrl() << " is not a directory!" << endl; 0418 continue; 0419 } 0420 } 0421 0422 KonqSidebarDirTreeItem *dirTreeItem = new KonqSidebarDirTreeItem(parentItem, m_topLevelItem, fileItem); 0423 dirTreeItem->setPixmap(0, fileItem.pixmap(size)); 0424 dirTreeItem->setText(0, KIO::decodeFileName(fileItem.name())); 0425 } 0426 0427 } while ((parentItem = parentItemList ? parentItemList->take(0) : 0)); 0428 delete parentItemList; 0429 } 0430 0431 void KonqSidebarDirTreeModule::slotRefreshItems(const QList<QPair<KFileItem, KFileItem> > &entries) 0432 { 0433 int size = KIconLoader::global()->currentSize(KIconLoader::Small); 0434 0435 qCDebug(SIDEBAR_LOG) << "# of items to refresh:" << entries.count(); 0436 0437 for (int i = 0; i < entries.count(); ++i) { 0438 const KFileItem fileItem(entries.at(i).second); 0439 const KFileItem oldFileItem(entries.at(i).first); 0440 0441 Q3PtrList<KonqSidebarTreeItem> *itemList; 0442 KonqSidebarTreeItem *item; 0443 lookupItems(m_ptrdictSubDirs, oldFileItem, item, itemList); 0444 0445 if (!item) { 0446 kWarning(1201) << "can't find old entry for " << oldFileItem.url().adjusted(QUrl::StripTrailingSlash).toString(); 0447 continue; 0448 } 0449 0450 do { 0451 if (item->isTopLevelItem()) { // we only have dirs and one toplevel item in the dict 0452 kWarning(1201) << "entry for " << oldFileItem.url().adjusted(QUrl::StripTrailingSlash).toString() << "matches against toplevel."; 0453 break; 0454 } 0455 0456 KonqSidebarDirTreeItem *dirTreeItem = static_cast<KonqSidebarDirTreeItem *>(item); 0457 // Item renamed ? 0458 if (dirTreeItem->id != fileItem.url().adjusted(QUrl::StripTrailingSlash).toString()) { 0459 qCDebug(SIDEBAR_LOG) << "renaming" << oldFileItem << "->" << fileItem; 0460 // We need to update the URL in m_dictSubDirs, and to get rid of the child items, so remove and add. 0461 // Then remove + delete 0462 removeSubDir(dirTreeItem, true /*children only*/); 0463 remove(m_dictSubDirs, dirTreeItem->id, dirTreeItem); 0464 remove(m_ptrdictSubDirs, oldFileItem, dirTreeItem); 0465 0466 dirTreeItem->reset(); // Reset id 0467 dirTreeItem->setPixmap(0, fileItem.pixmap(size)); 0468 dirTreeItem->setText(0, KIO::decodeFileName(fileItem.name())); 0469 0470 // Make sure the item doesn't get inserted twice! 0471 // dirTreeItem->id points to the new name 0472 remove(m_dictSubDirs, dirTreeItem->id, dirTreeItem); 0473 remove(m_ptrdictSubDirs, fileItem, dirTreeItem); 0474 m_dictSubDirs.insert(dirTreeItem->id, dirTreeItem); 0475 m_ptrdictSubDirs.insert(fileItem, dirTreeItem); 0476 } else { 0477 dirTreeItem->setPixmap(0, fileItem.pixmap(size)); 0478 dirTreeItem->setText(0, KIO::decodeFileName(fileItem.name())); 0479 } 0480 0481 } while ((item = itemList ? itemList->take(0) : 0)); 0482 delete itemList; 0483 } 0484 } 0485 0486 void KonqSidebarDirTreeModule::slotDeleteItem(const KFileItem &fileItem) 0487 { 0488 qCDebug(SIDEBAR_LOG) << fileItem.url().adjusted(QUrl::StripTrailingSlash).toString(); 0489 0490 // All items are in m_ptrdictSubDirs, so look it up fast 0491 Q3PtrList<KonqSidebarTreeItem> *itemList; 0492 KonqSidebarTreeItem *item; 0493 lookupItems(m_dictSubDirs, fileItem.url().adjusted(QUrl::StripTrailingSlash).toString(), item, itemList); 0494 while (item) { 0495 removeSubDir(item); 0496 delete item; 0497 0498 item = itemList ? itemList->take(0) : 0; 0499 } 0500 delete itemList; 0501 } 0502 0503 void KonqSidebarDirTreeModule::slotRedirection(const QUrl &oldUrl, const QUrl &newUrl) 0504 { 0505 qCDebug(SIDEBAR_LOG) << newUrl; 0506 0507 QString oldUrlStr = oldUrl.adjusted(QUrl::StripTrailingSlash).toString(); 0508 QString newUrlStr = newUrl.adjusted(QUrl::StripTrailingSlash).toString(); 0509 0510 Q3PtrList<KonqSidebarTreeItem> *itemList; 0511 KonqSidebarTreeItem *item; 0512 lookupItems(m_dictSubDirs, oldUrlStr, item, itemList); 0513 0514 if (!item) { 0515 kWarning(1201) << "NOT FOUND oldUrl=" << oldUrlStr; 0516 return; 0517 } 0518 0519 do { 0520 if (item->alias.contains(newUrlStr)) { 0521 continue; 0522 } 0523 qCDebug(SIDEBAR_LOG) << "Redirectiong element"; 0524 // We need to update the URL in m_dictSubDirs 0525 m_dictSubDirs.insert(newUrlStr, item); 0526 item->alias << newUrlStr; 0527 0528 qCDebug(SIDEBAR_LOG) << "Updating url of " << item << " to " << newUrlStr; 0529 0530 } while ((item = itemList ? itemList->take(0) : 0)); 0531 delete itemList; 0532 } 0533 0534 void KonqSidebarDirTreeModule::slotListingStopped(const QUrl &url) 0535 { 0536 //qCDebug(SIDEBAR_LOG) << url; 0537 0538 Q3PtrList<KonqSidebarTreeItem> *itemList; 0539 KonqSidebarTreeItem *item; 0540 lookupItems(m_dictSubDirs, url.adjusted(QUrl::StripTrailingSlash).toString(), item, itemList); 0541 0542 while (item) { 0543 if (item->childCount() == 0) { 0544 item->setExpandable(false); 0545 item->repaint(); 0546 } 0547 m_pTree->stopAnimation(item); 0548 0549 item = itemList ? itemList->take(0) : 0; 0550 } 0551 delete itemList; 0552 0553 //qCDebug(SIDEBAR_LOG) << "m_selectAfterOpening " << m_selectAfterOpening.prettyUrl(); 0554 if (!m_selectAfterOpening.isEmpty() && url.isParentOf(m_selectAfterOpening)) { 0555 QUrl theURL(m_selectAfterOpening); 0556 m_selectAfterOpening = QUrl(); 0557 followURL(theURL); 0558 } 0559 } 0560 0561 void KonqSidebarDirTreeModule::followURL(const QUrl &url) 0562 { 0563 // Check if we already know this URL 0564 KonqSidebarTreeItem *item = m_dictSubDirs[ url.adjusted(QUrl::StripTrailingSlash).toString() ]; 0565 if (item) { // found it -> ensure visible, select, return. 0566 m_pTree->ensureItemVisible(item); 0567 m_pTree->setSelected(item, true); 0568 return; 0569 } 0570 0571 QUrl uParent(url); 0572 KonqSidebarTreeItem *parentItem = 0L; 0573 // Go up to the first known parent 0574 do { 0575 uParent = uParent.upUrl(); 0576 parentItem = m_dictSubDirs[ uParent.adjusted(QUrl::StripTrailingSlash).toString() ]; 0577 } while (!parentItem && !uParent.path().isEmpty() && uParent.path() != "/"); 0578 0579 // Not found !?! 0580 if (!parentItem) { 0581 qCDebug(SIDEBAR_LOG) << "No parent found for url " << url.toDisplayString(); 0582 return; 0583 } 0584 qCDebug(SIDEBAR_LOG) << "Found parent " << uParent.toDisplayString(); 0585 0586 // That's the parent directory we found. Open if not open... 0587 if (!parentItem->isOpen()) { 0588 parentItem->setOpen(true); 0589 if (parentItem->childCount() && m_dictSubDirs[ url.adjusted(QUrl::StripTrailingSlash).toString() ]) { 0590 // Immediate opening, if the dir was already listed 0591 followURL(url); // equivalent to a goto-beginning-of-method 0592 } else { 0593 m_selectAfterOpening = url; 0594 //qCDebug(SIDEBAR_LOG) << "m_selectAfterOpening=" << m_selectAfterOpening.url(); 0595 } 0596 } 0597 } 0598 0599 extern "C" 0600 { 0601 KDE_EXPORT KonqSidebarTreeModule *create_konq_sidebartree_dirtree(KonqSidebarTree *par, const bool showHidden) 0602 { 0603 return new KonqSidebarDirTreeModule(par, showHidden); 0604 } 0605 } 0606