File indexing completed on 2024-04-28 17:06:13

0001 /*
0002     SPDX-FileCopyrightText: 2004 Csaba Karai <krusader@users.sourceforge.net>
0003     SPDX-FileCopyrightText: 2004-2022 Krusader Krew <https://krusader.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "locate.h"
0009 #include "../FileSystem/filesystem.h"
0010 #include "../FileSystem/virtualfilesystem.h"
0011 #include "../GUI/krtreewidget.h"
0012 #include "../KViewer/krviewer.h"
0013 #include "../Panel/krpanel.h"
0014 #include "../Panel/panelfunc.h"
0015 #include "../compat.h"
0016 #include "../defaults.h"
0017 #include "../filelisticon.h"
0018 #include "../kractions.h"
0019 #include "../krglobal.h"
0020 #include "../krservices.h"
0021 #include "../krslots.h"
0022 #include "../krusaderview.h"
0023 #include "../panelmanager.h"
0024 
0025 // QtCore
0026 #include <QDir>
0027 #include <QEventLoop>
0028 #include <QMimeData>
0029 #include <QRegExp>
0030 // QtGui
0031 #include <QClipboard>
0032 #include <QCursor>
0033 #include <QDrag>
0034 #include <QFont>
0035 #include <QFontMetrics>
0036 #include <QKeyEvent>
0037 // QtWidgets
0038 #include <QApplication>
0039 #include <QDialogButtonBox>
0040 #include <QFrame>
0041 #include <QGridLayout>
0042 #include <QHeaderView>
0043 #include <QInputDialog>
0044 #include <QLabel>
0045 #include <QLineEdit>
0046 #include <QMenu>
0047 #include <QTreeWidget>
0048 
0049 #include <KConfigCore/KConfig>
0050 #include <KCoreAddons/KProcess>
0051 #include <KCoreAddons/KShell>
0052 #include <KI18n/KLocalizedString>
0053 #include <KIOCore/KFileItem>
0054 #include <KTextWidgets/KFind>
0055 #include <KTextWidgets/KFindDialog>
0056 #include <KWidgetsAddons/KMessageBox>
0057 
0058 // these are the values that will exist in the menu
0059 #define VIEW_ID 90
0060 #define EDIT_ID 91
0061 #define FIND_ID 92
0062 #define FIND_NEXT_ID 93
0063 #define FIND_PREV_ID 94
0064 #define COPY_SELECTED_TO_CLIPBOARD 95
0065 #define COMPARE_ID 96
0066 //////////////////////////////////////////////////////////
0067 
0068 class LocateListView : public KrTreeWidget
0069 {
0070 public:
0071     explicit LocateListView(QWidget *parent)
0072         : KrTreeWidget(parent)
0073     {
0074         setAlternatingRowColors(true);
0075     }
0076 
0077     void startDrag(Qt::DropActions supportedActs) override
0078     {
0079         Q_UNUSED(supportedActs);
0080 
0081         QList<QUrl> urls;
0082         QList<QTreeWidgetItem *> list = selectedItems();
0083 
0084         QListIterator<QTreeWidgetItem *> it(list);
0085 
0086         while (it.hasNext()) {
0087             QTreeWidgetItem *item = it.next();
0088 
0089             urls.push_back(QUrl::fromLocalFile(item->text(0)));
0090         }
0091 
0092         if (urls.count() == 0)
0093             return;
0094 
0095         auto *drag = new QDrag(this);
0096         auto *mimeData = new QMimeData;
0097         mimeData->setImageData(FileListIcon("file").pixmap());
0098         mimeData->setUrls(urls);
0099         drag->setMimeData(mimeData);
0100         drag->exec();
0101     }
0102 };
0103 
0104 KProcess *LocateDlg::updateProcess = nullptr;
0105 LocateDlg *LocateDlg::LocateDialog = nullptr;
0106 
0107 LocateDlg::LocateDlg(QWidget *parent)
0108     : QDialog(parent)
0109     , isFeedToListBox(false)
0110 {
0111     setWindowTitle(i18n("Krusader::Locate"));
0112     setWindowModality(Qt::NonModal);
0113 
0114     auto *mainLayout = new QVBoxLayout;
0115     setLayout(mainLayout);
0116 
0117     auto *grid = new QGridLayout();
0118     grid->setSpacing(6);
0119     grid->setContentsMargins(11, 11, 11, 11);
0120 
0121     QWidget *hboxWidget = new QWidget(this);
0122     auto *hbox = new QHBoxLayout(hboxWidget);
0123     hbox->setContentsMargins(0, 0, 0, 0);
0124 
0125     QLabel *label = new QLabel(i18n("Search for:"), hboxWidget);
0126     hbox->addWidget(label);
0127 
0128     locateSearchFor = new KrHistoryComboBox(false, hboxWidget);
0129     locateSearchFor->setMinimumContentsLength(10);
0130     hbox->addWidget(locateSearchFor);
0131 
0132     label->setBuddy(locateSearchFor);
0133     KConfigGroup group(krConfig, "Locate");
0134     QStringList list = group.readEntry("Search For", QStringList());
0135     locateSearchFor->setMaxCount(25); // remember 25 items
0136     locateSearchFor->setHistoryItems(list);
0137     locateSearchFor->setEditable(true);
0138     locateSearchFor->setDuplicatesEnabled(false);
0139     locateSearchFor->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
0140     locateSearchFor->lineEdit()->setFocus();
0141 
0142     grid->addWidget(hboxWidget, 0, 0);
0143 
0144     QWidget *hboxWidget2 = new QWidget(this);
0145     auto *hbox2 = new QHBoxLayout(hboxWidget2);
0146     hbox2->setContentsMargins(0, 0, 0, 0);
0147 
0148     auto *spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
0149     hbox2->addItem(spacer);
0150 
0151     dontSearchInPath = new QCheckBox(i18n("Do not search in path"), hboxWidget2);
0152     hbox2->addWidget(dontSearchInPath);
0153     dontSearchInPath->setChecked(group.readEntry("Don't Search In Path", false));
0154 
0155     existingFiles = new QCheckBox(i18n("Show only the existing files"), hboxWidget2);
0156     existingFiles->setChecked(group.readEntry("Existing Files", false));
0157     hbox2->addWidget(existingFiles);
0158 
0159     caseSensitive = new QCheckBox(i18n("Case Sensitive"), hboxWidget2);
0160     caseSensitive->setChecked(group.readEntry("Case Sensitive", false));
0161     hbox2->addWidget(caseSensitive);
0162 
0163     grid->addWidget(hboxWidget2, 1, 0);
0164 
0165     QFrame *line1 = new QFrame(this);
0166     line1->setFrameStyle(QFrame::HLine | QFrame::Sunken);
0167     grid->addWidget(line1, 2, 0);
0168 
0169     resultList = new LocateListView(this); // create the main container
0170     resultList->setColumnCount(1);
0171     resultList->setHeaderLabel(i18n("Results"));
0172 
0173     resultList->setColumnWidth(0, QFontMetrics(resultList->font()).horizontalAdvance("W") * 60);
0174 
0175     KConfigGroup gl(krConfig, "Look&Feel");
0176     resultList->setFont(gl.readEntry("Filelist Font", _FilelistFont));
0177 
0178     resultList->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
0179     resultList->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
0180     resultList->header()->setSortIndicatorShown(false);
0181     resultList->setSortingEnabled(false);
0182     resultList->setSelectionMode(QAbstractItemView::ExtendedSelection);
0183     resultList->setDragEnabled(true);
0184 
0185     connect(resultList, &KrTreeWidget::itemRightClicked, this, &LocateDlg::slotRightClick);
0186     connect(resultList, &KrTreeWidget::itemDoubleClicked, this, &LocateDlg::slotDoubleClick);
0187     connect(resultList, &KrTreeWidget::itemActivated, this, &LocateDlg::slotDoubleClick);
0188 
0189     grid->addWidget(resultList, 3, 0);
0190 
0191     QFrame *line2 = new QFrame(this);
0192     line2->setFrameStyle(QFrame::HLine | QFrame::Sunken);
0193     grid->addWidget(line2, 4, 0);
0194 
0195     mainLayout->addLayout(grid);
0196 
0197     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
0198     mainLayout->addWidget(buttonBox);
0199 
0200     locateButton = new QPushButton(i18n("Locate"));
0201     locateButton->setIcon(Icon(QStringLiteral("system-search")));
0202     locateButton->setDefault(true);
0203     buttonBox->addButton(locateButton, QDialogButtonBox::ActionRole);
0204 
0205     updateDbButton = new QPushButton(i18n("Update DB"));
0206     updateDbButton->setIcon(Icon(QStringLiteral("view-refresh")));
0207     buttonBox->addButton(updateDbButton, QDialogButtonBox::ActionRole);
0208 
0209     feedStopButton = new QPushButton;
0210     buttonBox->addButton(feedStopButton, QDialogButtonBox::ActionRole);
0211 
0212     connect(buttonBox, &QDialogButtonBox::rejected, this, &LocateDlg::reject);
0213     connect(locateButton, &QPushButton::clicked, this, &LocateDlg::slotLocate);
0214     connect(updateDbButton, &QPushButton::clicked, this, &LocateDlg::slotUpdateDb);
0215     connect(feedStopButton, &QPushButton::clicked, this, &LocateDlg::slotFeedStop);
0216 
0217     updateButtons(false);
0218 
0219     if (updateProcess) {
0220         if (updateProcess->state() == QProcess::Running) {
0221             connect(updateProcess, QOverload<int, QProcess::ExitStatus>::of(&KProcess::finished), this, &LocateDlg::updateFinished);
0222             updateDbButton->setEnabled(false);
0223         } else
0224             updateFinished();
0225     }
0226 
0227     show();
0228 
0229     LocateDialog = this;
0230 }
0231 
0232 LocateDlg::~LocateDlg()
0233 {
0234     KConfigGroup group(krConfig, "Locate");
0235     group.writeEntry("Search For", locateSearchFor->historyItems());
0236 }
0237 
0238 void LocateDlg::slotFeedStop() /* The stop / feed to listbox button */
0239 {
0240     if (isFeedToListBox)
0241         feedToListBox();
0242     else
0243         locateProc->kill();
0244 }
0245 
0246 void LocateDlg::slotUpdateDb() /* The Update DB button */
0247 {
0248     if (!updateProcess) {
0249         KConfigGroup group(krConfig, "Locate");
0250 
0251         updateProcess = new KProcess(); // don't set the parent to 'this'! That would cause this process to be deleted once the dialog is closed
0252         *updateProcess << KrServices::fullPathName("updatedb");
0253         *updateProcess << KShell::splitArgs(group.readEntry("UpdateDB Arguments"));
0254 
0255         connect(updateProcess, QOverload<int, QProcess::ExitStatus>::of(&KProcess::finished), this, &LocateDlg::updateFinished);
0256         updateProcess->start();
0257         updateDbButton->setEnabled(false);
0258     }
0259 }
0260 
0261 void LocateDlg::updateFinished()
0262 {
0263     delete updateProcess;
0264     updateProcess = nullptr;
0265     updateDbButton->setEnabled(true);
0266 }
0267 
0268 void LocateDlg::slotLocate() /* The locate button */
0269 {
0270     locateSearchFor->addToHistory(locateSearchFor->currentText());
0271 
0272     KConfigGroup group(krConfig, "Locate");
0273     group.writeEntry("Don't Search In Path", dontSearchPath = dontSearchInPath->isChecked());
0274     group.writeEntry("Existing Files", onlyExist = existingFiles->isChecked());
0275     group.writeEntry("Case Sensitive", isCs = caseSensitive->isChecked());
0276 
0277     if (!KrServices::cmdExist("locate")) {
0278         KMessageBox::error(nullptr, i18n("Cannot start 'locate'. Check the 'Dependencies' page in konfigurator."));
0279         return;
0280     }
0281 
0282     resultList->clear();
0283     lastItem = nullptr;
0284     remaining = "";
0285 
0286     updateButtons(true);
0287 
0288     isFeedToListBox = false;
0289     resultList->setFocus();
0290 
0291     qApp->processEvents(); // FIXME - what's this for ?
0292 
0293     locateProc = new KProcess(this);
0294     locateProc->setOutputChannelMode(KProcess::SeparateChannels); // default is forwarding to the parent channels
0295     connect(locateProc, &KProcess::readyReadStandardOutput, this, &LocateDlg::processStdout);
0296     connect(locateProc, &KProcess::readyReadStandardError, this, &LocateDlg::processStderr);
0297     connect(locateProc, QOverload<int, QProcess::ExitStatus>::of(&KProcess::finished), this, &LocateDlg::locateFinished);
0298     connect(locateProc, QOverload<QProcess::ProcessError>::of(&KProcess::errorOccurred), this, &LocateDlg::locateError);
0299 
0300     *locateProc << KrServices::fullPathName("locate");
0301     if (!isCs)
0302         *locateProc << "-i";
0303     *locateProc << (pattern = locateSearchFor->currentText());
0304 
0305     if (!pattern.startsWith('*'))
0306         pattern = '*' + pattern;
0307     if (!pattern.endsWith('*'))
0308         pattern = pattern + '*';
0309 
0310     collectedErr = "";
0311     locateProc->start();
0312 }
0313 
0314 void LocateDlg::locateError()
0315 {
0316     if (locateProc->error() == QProcess::FailedToStart)
0317         KMessageBox::error(krMainWindow, i18n("Error during the start of 'locate' process."));
0318 }
0319 
0320 void LocateDlg::locateFinished()
0321 {
0322     if (locateProc->exitStatus() != QProcess::NormalExit || locateProc->exitStatus()) {
0323         if (!collectedErr.isEmpty())
0324             KMessageBox::error(krMainWindow, i18n("Locate produced the following error message:\n\n%1", collectedErr));
0325     }
0326 
0327     if (resultList->topLevelItemCount() == 0) {
0328         locateSearchFor->setFocus();
0329         isFeedToListBox = false;
0330     } else {
0331         isFeedToListBox = true;
0332     }
0333 
0334     updateButtons(false);
0335 }
0336 
0337 void LocateDlg::processStdout()
0338 {
0339     remaining += QString::fromLocal8Bit(locateProc->readAllStandardOutput());
0340 
0341     QStringList list = remaining.split('\n');
0342     int items = list.size();
0343 
0344     for (auto &it : list) {
0345         if (--items == 0 && !remaining.endsWith('\n'))
0346             remaining = it;
0347         else {
0348             if (dontSearchPath) {
0349                 QRegExp regExp(pattern, isCs ? Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::Wildcard);
0350                 QString fileName = it.trimmed();
0351                 if (fileName.endsWith(QLatin1String("/")) && fileName != "/") {
0352                     fileName.truncate(fileName.length() - 1);
0353                 }
0354                 fileName = fileName.mid(fileName.lastIndexOf('/') + 1);
0355 
0356                 if (!regExp.exactMatch(fileName))
0357                     continue;
0358             }
0359             if (onlyExist) {
0360                 KFileItem file(QUrl::fromLocalFile(it.trimmed()));
0361                 if (!file.isReadable())
0362                     continue;
0363             }
0364 
0365             if (lastItem)
0366                 lastItem = new QTreeWidgetItem(resultList, lastItem);
0367             else
0368                 lastItem = new QTreeWidgetItem(resultList);
0369 
0370             lastItem->setText(0, it);
0371         }
0372     }
0373 }
0374 
0375 void LocateDlg::processStderr()
0376 {
0377     collectedErr += QString::fromLocal8Bit(locateProc->readAllStandardError());
0378 }
0379 
0380 void LocateDlg::slotRightClick(QTreeWidgetItem *item, const QPoint &pos)
0381 {
0382     if (!item)
0383         return;
0384 
0385     // create the menu
0386     QMenu popup;
0387     popup.setTitle(i18nc("@title:menu", "Locate"));
0388 
0389     QAction *actView = popup.addAction(i18n("View (F3)"));
0390     QAction *actEdit = popup.addAction(i18n("Edit (F4)"));
0391     QAction *actComp = popup.addAction(i18n("Compare by content (F10)"));
0392     if (resultList->selectedItems().count() != 2)
0393         actComp->setEnabled(false);
0394     popup.addSeparator();
0395 
0396     QAction *actFind = popup.addAction(i18n("Find (Ctrl+F)"));
0397     QAction *actNext = popup.addAction(i18n("Find next (Ctrl+N)"));
0398     QAction *actPrev = popup.addAction(i18n("Find previous (Ctrl+P)"));
0399     popup.addSeparator();
0400 
0401     QAction *actClip = popup.addAction(i18n("Copy selected to clipboard"));
0402 
0403     QAction *result = popup.exec(pos);
0404 
0405     int ret = -1;
0406 
0407     if (result == actView)
0408         ret = VIEW_ID;
0409     else if (result == actEdit)
0410         ret = EDIT_ID;
0411     else if (result == actFind)
0412         ret = FIND_ID;
0413     else if (result == actNext)
0414         ret = FIND_NEXT_ID;
0415     else if (result == actPrev)
0416         ret = FIND_PREV_ID;
0417     else if (result == actClip)
0418         ret = COPY_SELECTED_TO_CLIPBOARD;
0419     else if (result == actComp)
0420         ret = COMPARE_ID;
0421 
0422     if (ret != -1)
0423         operate(item, ret);
0424 }
0425 
0426 void LocateDlg::slotDoubleClick(QTreeWidgetItem *item)
0427 {
0428     if (!item)
0429         return;
0430 
0431     QString dirName = item->text(0);
0432     QString fileName;
0433 
0434     if (!QDir(dirName).exists()) {
0435         fileName = dirName.mid(dirName.lastIndexOf('/') + 1);
0436         dirName.truncate(dirName.lastIndexOf('/'));
0437     }
0438 
0439     ACTIVE_FUNC->openUrl(QUrl::fromLocalFile(dirName), fileName);
0440     QDialog::accept();
0441 }
0442 
0443 void LocateDlg::keyPressEvent(QKeyEvent *e)
0444 {
0445     if (KrGlobal::copyShortcut == QKeySequence(e->key() | e->modifiers())) {
0446         operate(nullptr, COPY_SELECTED_TO_CLIPBOARD);
0447         e->accept();
0448         return;
0449     }
0450 
0451     switch (e->key()) {
0452     case Qt::Key_M:
0453         if (e->modifiers() == Qt::ControlModifier) {
0454             resultList->setFocus();
0455             e->accept();
0456         }
0457         break;
0458     case Qt::Key_F3:
0459         if (resultList->currentItem())
0460             operate(resultList->currentItem(), VIEW_ID);
0461         break;
0462     case Qt::Key_F4:
0463         if (resultList->currentItem())
0464             operate(resultList->currentItem(), EDIT_ID);
0465         break;
0466     case Qt::Key_F10:
0467         operate(nullptr, COMPARE_ID);
0468         break;
0469     case Qt::Key_N:
0470         if (e->modifiers() == Qt::ControlModifier)
0471             operate(resultList->currentItem(), FIND_NEXT_ID);
0472         break;
0473     case Qt::Key_P:
0474         if (e->modifiers() == Qt::ControlModifier)
0475             operate(resultList->currentItem(), FIND_PREV_ID);
0476         break;
0477     case Qt::Key_F:
0478         if (e->modifiers() == Qt::ControlModifier)
0479             operate(resultList->currentItem(), FIND_ID);
0480         break;
0481     }
0482 
0483     QDialog::keyPressEvent(e);
0484 }
0485 
0486 void LocateDlg::operate(QTreeWidgetItem *item, int task)
0487 {
0488     QUrl name;
0489     if (item != nullptr)
0490         name = QUrl::fromLocalFile(item->text(0));
0491 
0492     switch (task) {
0493     case VIEW_ID:
0494         KrViewer::view(name, this); // view the file
0495         break;
0496     case EDIT_ID:
0497         KrViewer::edit(name, this); // view the file
0498         break;
0499     case COMPARE_ID: {
0500         QList<QTreeWidgetItem *> list = resultList->selectedItems();
0501         if (list.count() != 2)
0502             break;
0503 
0504         QUrl url1 = QUrl::fromLocalFile(list[0]->text(0));
0505         QUrl url2 = QUrl::fromLocalFile(list[1]->text(0));
0506 
0507         SLOTS->compareContent(url1, url2);
0508     } break;
0509     case FIND_ID: {
0510         KConfigGroup group(krConfig, "Locate");
0511         long options = group.readEntry("Find Options", (long long)0);
0512         QStringList list = group.readEntry("Find Patterns", QStringList());
0513 
0514         QPointer<KFindDialog> dlg = new KFindDialog(this, options, list);
0515         if (dlg->exec() != QDialog::Accepted) {
0516             delete dlg;
0517             return;
0518         }
0519 
0520         QString first;
0521         if (list.count() != 0) {
0522             first = list.first();
0523         }
0524         if (first != (findPattern = dlg->pattern())) {
0525             list.push_front(dlg->pattern());
0526         }
0527 
0528         group.writeEntry("Find Options", (long long)(findOptions = dlg->options()));
0529         group.writeEntry("Find Patterns", list);
0530 
0531         if (!(findOptions & KFind::FromCursor) && resultList->topLevelItemCount())
0532             resultList->setCurrentItem((findOptions & KFind::FindBackwards) ? resultList->topLevelItem(resultList->topLevelItemCount() - 1)
0533                                                                             : resultList->topLevelItem(0));
0534 
0535         findCurrentItem = resultList->currentItem();
0536 
0537         if (find() && findCurrentItem) {
0538             resultList->selectionModel()->clearSelection(); // HACK: QT 4 is not able to paint the focus frame because of a bug
0539             resultList->setCurrentItem(findCurrentItem);
0540         } else {
0541             KMessageBox::information(this, i18n("Search string not found."));
0542         }
0543 
0544         resultList->scrollTo(resultList->currentIndex());
0545 
0546         delete dlg;
0547     } break;
0548     case FIND_NEXT_ID:
0549     case FIND_PREV_ID: {
0550         if (task == FIND_PREV_ID)
0551             findOptions ^= KFind::FindBackwards;
0552 
0553         findCurrentItem = resultList->currentItem();
0554         nextLine();
0555 
0556         if (find() && findCurrentItem) {
0557             resultList->selectionModel()->clearSelection(); // HACK: QT 4 is not able to paint the focus frame because of a bug
0558             resultList->setCurrentItem(findCurrentItem);
0559         } else
0560             KMessageBox::information(this, i18n("Search string not found."));
0561 
0562         resultList->scrollTo(resultList->currentIndex());
0563 
0564         if (task == FIND_PREV_ID)
0565             findOptions ^= KFind::FindBackwards;
0566     } break;
0567     case COPY_SELECTED_TO_CLIPBOARD: {
0568         QList<QUrl> urls;
0569 
0570         QTreeWidgetItemIterator it(resultList);
0571         while (*it) {
0572             if ((*it)->isSelected())
0573                 urls.push_back(QUrl::fromLocalFile((*it)->text(0)));
0574 
0575             it++;
0576         }
0577 
0578         if (urls.count() == 0)
0579             return;
0580 
0581         auto *mimeData = new QMimeData;
0582         mimeData->setImageData(FileListIcon("file").pixmap());
0583         mimeData->setUrls(urls);
0584 
0585         QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard);
0586     } break;
0587     }
0588 }
0589 
0590 void LocateDlg::nextLine()
0591 {
0592     if (findOptions & KFind::FindBackwards)
0593         findCurrentItem = resultList->itemAbove(findCurrentItem);
0594     else
0595         findCurrentItem = resultList->itemBelow(findCurrentItem);
0596 }
0597 
0598 bool LocateDlg::find()
0599 {
0600     while (findCurrentItem) {
0601         QString item = findCurrentItem->text(0);
0602 
0603         if (findOptions & KFind::RegularExpression) {
0604             if (item.contains(QRegExp(findPattern, ((findOptions & KFind::CaseSensitive) != 0) ? Qt::CaseSensitive : Qt::CaseInsensitive)))
0605                 return true;
0606         } else {
0607             if (item.contains(findPattern, ((findOptions & KFind::CaseSensitive) != 0) ? Qt::CaseSensitive : Qt::CaseInsensitive))
0608                 return true;
0609         }
0610 
0611         nextLine();
0612     }
0613 
0614     return false;
0615 }
0616 
0617 void LocateDlg::feedToListBox()
0618 {
0619     VirtualFileSystem virtFilesystem;
0620     virtFilesystem.scanDir(QUrl::fromLocalFile(QStringLiteral("/")));
0621 
0622     KConfigGroup group(krConfig, "Locate");
0623     int listBoxNum = group.readEntry("Feed To Listbox Counter", 1);
0624     QString queryName;
0625     do {
0626         queryName = i18n("Locate results") + QString(" %1").arg(listBoxNum++);
0627     } while (virtFilesystem.getFileItem(queryName) != nullptr);
0628     group.writeEntry("Feed To Listbox Counter", listBoxNum);
0629 
0630     KConfigGroup ga(krConfig, "Advanced");
0631     if (ga.readEntry("Confirm Feed to Listbox", _ConfirmFeedToListbox)) {
0632         bool ok;
0633         queryName = QInputDialog::getText(this, i18n("Query Name"), i18n("Here you can name the file collection:"), QLineEdit::Normal, queryName, &ok);
0634         if (!ok)
0635             return;
0636     }
0637 
0638     QList<QUrl> urlList;
0639     QTreeWidgetItemIterator it(resultList);
0640     while (*it) {
0641         QTreeWidgetItem *item = *it;
0642         urlList.push_back(QUrl::fromLocalFile(item->text(0)));
0643         it++;
0644     }
0645     QUrl url = QUrl(QStringLiteral("virt:/") + queryName);
0646     virtFilesystem.refresh(url); // create directory if it does not exist
0647     virtFilesystem.addFiles(urlList);
0648     // ACTIVE_FUNC->openUrl(url);
0649     ACTIVE_MNG->slotNewTab(url);
0650     accept();
0651 }
0652 
0653 void LocateDlg::reset()
0654 {
0655     locateSearchFor->lineEdit()->setFocus();
0656     locateSearchFor->lineEdit()->selectAll();
0657 }
0658 
0659 void LocateDlg::updateButtons(bool locateIsRunning)
0660 {
0661     locateButton->setEnabled(!locateIsRunning);
0662 
0663     if (locateIsRunning) {
0664         feedStopButton->setEnabled(true);
0665         feedStopButton->setText(i18n("Stop"));
0666         feedStopButton->setIcon(Icon(QStringLiteral("process-stop")));
0667     } else {
0668         if (resultList->topLevelItemCount() == 0) {
0669             feedStopButton->setEnabled(false);
0670             feedStopButton->setText(i18n("Stop"));
0671             feedStopButton->setIcon(Icon(QStringLiteral("process-stop")));
0672         } else {
0673             feedStopButton->setEnabled(true);
0674             feedStopButton->setText(i18n("Feed to listbox"));
0675             feedStopButton->setIcon(Icon(QStringLiteral("list-add")));
0676         }
0677     }
0678 }