diff --git a/krusader/Archive/abstractthreadedjob.cpp b/krusader/Archive/abstractthreadedjob.cpp index 21417307..702e50d4 100644 --- a/krusader/Archive/abstractthreadedjob.cpp +++ b/krusader/Archive/abstractthreadedjob.cpp @@ -1,649 +1,649 @@ /*************************************************************************** packjob.cpp - description ------------------- copyright : (C) 2009 + by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "abstractthreadedjob.h" // QtCore #include #include #include #include #include #include // QtWidgets #include #include #include #include #include "krarchandler.h" #include "../krglobal.h" #include "../krservices.h" -#include "../VFS/krvfshandler.h" -#include "../VFS/vfs.h" +#include "../FileSystem/filesystemprovider.h" +#include "../FileSystem/filesystem.h" extern KRarcHandler arcHandler; AbstractThreadedJob::AbstractThreadedJob() : KIO::Job(), _locker(), _waiter(), _stack(), _maxProgressValue(0), _currentProgress(0), _exiting(false), _jobThread(0) { } void AbstractThreadedJob::startAbstractJobThread(AbstractJobThread * jobThread) { _jobThread = jobThread; _jobThread->setJob(this); _jobThread->moveToThread(_jobThread); _jobThread->start(); } AbstractThreadedJob::~AbstractThreadedJob() { _exiting = true; if (_jobThread) { _jobThread->abort(); _locker.lock(); _waiter.wakeAll(); _locker.unlock(); _jobThread->wait(); delete _jobThread; } } bool AbstractThreadedJob::event(QEvent *e) { if (e->type() == QEvent::User) { UserEvent *event = (UserEvent*) e; switch (event->command()) { case CMD_SUCCESS: { emitResult(); } break; case CMD_ERROR: { int error = event->args()[ 0 ].value(); QString errorText = event->args()[ 1 ].value(); setError(error); setErrorText(errorText); emitResult(); } break; case CMD_INFO: { QString info = event->args()[ 0 ].value(); QString arg1 = event->args()[ 1 ].value(); QString arg2 = event->args()[ 2 ].value(); QString arg3 = event->args()[ 3 ].value(); QString arg4 = event->args()[ 4 ].value(); _title = info; emit description(this, info, qMakePair(arg1, arg2), qMakePair(arg3, arg4)); } break; case CMD_RESET: { QString info = event->args()[ 0 ].value(); QString arg1 = event->args()[ 1 ].value(); QString arg2 = event->args()[ 2 ].value(); QString arg3 = event->args()[ 3 ].value(); QString arg4 = event->args()[ 4 ].value(); _title = info; setProcessedAmount(KJob::Bytes, 0); setTotalAmount(KJob::Bytes, 0); emitSpeed(0); emit description(this, info, qMakePair(arg1, arg2), qMakePair(arg3, arg4)); } break; case CMD_UPLOAD_FILES: case CMD_DOWNLOAD_FILES: { QList sources = KrServices::toUrlList(event->args()[ 0 ].value()); QUrl dest = event->args()[ 1 ].value(); KIO::Job *job = KIO::copy(sources, dest, KIO::HideProgressInfo); addSubjob(job); job->setUiDelegate(new KIO::JobUiDelegate()); connect(job, SIGNAL(result(KJob*)), this, SLOT(slotDownloadResult(KJob*))); connect(job, SIGNAL(processedAmount(KJob *, KJob::Unit, qulonglong)), this, SLOT(slotProcessedAmount(KJob *, KJob::Unit, qulonglong))); connect(job, SIGNAL(totalAmount(KJob *, KJob::Unit, qulonglong)), this, SLOT(slotTotalAmount(KJob *, KJob::Unit, qulonglong))); connect(job, SIGNAL(speed(KJob *, unsigned long)), this, SLOT(slotSpeed(KJob *, unsigned long))); connect(job, SIGNAL(description(KJob *, const QString &, const QPair &, const QPair &)), this, SLOT(slotDescription(KJob *, const QString &, const QPair &, const QPair &))); } break; case CMD_MAXPROGRESSVALUE: { qulonglong maxValue = event->args()[ 0 ].value(); _maxProgressValue = maxValue; _currentProgress = 0; } break; case CMD_ADD_PROGRESS: { qulonglong progress = event->args()[ 0 ].value(); _currentProgress += progress; if (_maxProgressValue != 0) { setPercent(100 * _currentProgress / _maxProgressValue); int elapsed = _time.isNull() ? 1 : _time.secsTo(QTime::currentTime()); if (elapsed != 0 && event->args().count() > 1) { _time = QTime::currentTime(); QString progressString = (event->args()[ 1 ].value()); emit description(this, _title, qMakePair(progressString, QString("%1/%2").arg(_currentProgress).arg(_maxProgressValue)), qMakePair(QString(), QString()) ); } } } break; case CMD_GET_PASSWORD: { QString path = event->args()[ 0 ].value(); QString password = KRarcHandler::getPassword(path); QList *resultResp = new QList (); (*resultResp) << password; addEventResponse(resultResp); } break; case CMD_MESSAGE: { QString message = event->args()[ 0 ].value(); KIO::JobUiDelegate *ui = static_cast(uiDelegate()); KMessageBox::information(ui ? ui->window() : 0, message); QList *resultResp = new QList (); addEventResponse(resultResp); } break; } return true; } else { return KIO::Job::event(e); } } void AbstractThreadedJob::addEventResponse(QList * obj) { _locker.lock(); _stack.push(obj); _waiter.wakeOne(); _locker.unlock(); } QList * AbstractThreadedJob::getEventResponse(UserEvent * event) { _locker.lock(); QApplication::postEvent(this, event); _waiter.wait(&_locker); if (_exiting) return 0; QList *resp = _stack.pop(); _locker.unlock(); return resp; } void AbstractThreadedJob::sendEvent(UserEvent * event) { QApplication::postEvent(this, event); } void AbstractThreadedJob::slotDownloadResult(KJob* job) { QList *resultResp = new QList (); if (job) { (*resultResp) << QVariant(job->error()); (*resultResp) << QVariant(job->errorText()); } else { (*resultResp) << QVariant(KJob::UserDefinedError); (*resultResp) << QVariant(QString(i18n("Internal error, undefined in result signal"))); } addEventResponse(resultResp); } void AbstractThreadedJob::slotProcessedAmount(KJob *, KJob::Unit unit, qulonglong xu) { setProcessedAmount(unit, xu); } void AbstractThreadedJob::slotTotalAmount(KJob *, KJob::Unit unit, qulonglong xu) { setTotalAmount(unit, xu); } void AbstractThreadedJob::slotSpeed(KJob *, unsigned long spd) { emitSpeed(spd); } void AbstractThreadedJob::slotDescription(KJob *, const QString &title, const QPair &field1, const QPair &field2) { QString mytitle = title; if (!_title.isNull()) mytitle = _title; emit description(this, mytitle, field1, field2); } class AbstractJobObserver : public KRarcObserver { protected: AbstractJobThread * _jobThread; public: AbstractJobObserver(AbstractJobThread * thread): _jobThread(thread) {} virtual ~AbstractJobObserver() {} virtual void processEvents() Q_DECL_OVERRIDE { usleep(1000); qApp->processEvents(); } virtual void subJobStarted(const QString & jobTitle, int count) Q_DECL_OVERRIDE { _jobThread->sendReset(jobTitle); _jobThread->sendMaxProgressValue(count); } virtual void subJobStopped() Q_DECL_OVERRIDE { } virtual bool wasCancelled() Q_DECL_OVERRIDE { return _jobThread->_exited; } virtual void error(const QString & error) Q_DECL_OVERRIDE { _jobThread->sendError(KIO::ERR_NO_CONTENT, error); } virtual void detailedError(const QString & error, const QString & details) Q_DECL_OVERRIDE { _jobThread->sendError(KIO::ERR_NO_CONTENT, error + '\n' + details); } virtual void incrementProgress(int c) Q_DECL_OVERRIDE { _jobThread->sendAddProgress(c, _jobThread->_progressTitle); } }; AbstractJobThread::AbstractJobThread() : _job(0), _downloadTempDir(0), _observer(0), _tempFile(0), _tempDir(0), _exited(false) { } AbstractJobThread::~AbstractJobThread() { if (_downloadTempDir) { delete _downloadTempDir; _downloadTempDir = 0; } if (_observer) { delete _observer; _observer = 0; } if (_tempFile) { delete _tempFile; _tempFile = 0; } } void AbstractJobThread::run() { QTimer::singleShot(0, this, SLOT(slotStart())); QPointer threadLoop = new QEventLoop(this); _loop = threadLoop; threadLoop->exec(); _loop = 0; delete threadLoop; } void AbstractJobThread::terminate() { if (_loop && !_exited) { _loop->quit(); _exited = true; } } void AbstractJobThread::abort() { terminate(); } QList AbstractJobThread::remoteUrls(const QUrl &baseUrl, const QStringList & files) { QList urlList; foreach(const QString &name, files) { QUrl url = baseUrl; url = url.adjusted(QUrl::StripTrailingSlash); url.setPath(url.path() + '/' + (name)); urlList << url; } return urlList; } QUrl AbstractJobThread::downloadIfRemote(const QUrl &baseUrl, const QStringList & files) { // download remote URL-s if necessary if (!baseUrl.isLocalFile()) { sendInfo(i18n("Downloading remote files")); _downloadTempDir = new QTemporaryDir(); QList urlList = remoteUrls(baseUrl, files); QUrl dest(_downloadTempDir->path()); QList args; args << KrServices::toStringList(urlList); args << dest; UserEvent * downloadEvent = new UserEvent(CMD_DOWNLOAD_FILES, args); QList * result = _job->getEventResponse(downloadEvent); if (result == 0) return QUrl(); int errorCode = (*result)[ 0 ].value(); QString errorText = (*result)[ 1 ].value(); delete result; if (errorCode) { sendError(errorCode, errorText); return QUrl(); } else { return dest; } } else { return baseUrl; } } QString AbstractJobThread::tempFileIfRemote(const QUrl &kurl, const QString &type) { if (kurl.isLocalFile()) { return kurl.path(); } _tempFile = new QTemporaryFile(QDir::tempPath() + QLatin1String("/krusader_XXXXXX.") + type); _tempFile->open(); _tempFileName = _tempFile->fileName(); _tempFile->close(); // necessary to create the filename QFile::remove(_tempFileName); _tempFileTarget = kurl; return _tempFileName; } QString AbstractJobThread::tempDirIfRemote(const QUrl &kurl) { if (kurl.isLocalFile()) { return kurl.adjusted(QUrl::StripTrailingSlash).path(); } _tempDir = new QTemporaryDir(); _tempDirTarget = kurl; return _tempDirName = _tempDir->path(); } void AbstractJobThread::sendSuccess() { terminate(); QList args; UserEvent * errorEvent = new UserEvent(CMD_SUCCESS, args); _job->sendEvent(errorEvent); } void AbstractJobThread::sendError(int errorCode, QString message) { terminate(); QList args; args << errorCode; args << message; UserEvent * errorEvent = new UserEvent(CMD_ERROR, args); _job->sendEvent(errorEvent); } void AbstractJobThread::sendInfo(QString message, QString a1, QString a2, QString a3, QString a4) { QList args; args << message; args << a1; args << a2; args << a3; args << a4; UserEvent * infoEvent = new UserEvent(CMD_INFO, args); _job->sendEvent(infoEvent); } void AbstractJobThread::sendReset(QString message, QString a1, QString a2, QString a3, QString a4) { QList args; args << message; args << a1; args << a2; args << a3; args << a4; UserEvent * infoEvent = new UserEvent(CMD_RESET, args); _job->sendEvent(infoEvent); } void AbstractJobThread::sendMaxProgressValue(qulonglong value) { QList args; args << value; UserEvent * infoEvent = new UserEvent(CMD_MAXPROGRESSVALUE, args); _job->sendEvent(infoEvent); } void AbstractJobThread::sendAddProgress(qulonglong value, const QString &progress) { QList args; args << value; if (!progress.isNull()) args << progress; UserEvent * infoEvent = new UserEvent(CMD_ADD_PROGRESS, args); _job->sendEvent(infoEvent); } void AbstractJobThread::calcSpaceLocal(const QUrl &baseUrl, const QStringList & files, KIO::filesize_t &totalSize, unsigned long &totalDirs, unsigned long &totalFiles) { sendReset(i18n("Calculating space")); - vfs *calcSpaceVfs = KrVfsHandler::instance().getVfs(baseUrl); - calcSpaceVfs->refresh(baseUrl); + FileSystem *calcSpaceFileSystem = FileSystemProvider::instance().getFilesystem(baseUrl); + calcSpaceFileSystem->refresh(baseUrl); for (int i = 0; i != files.count(); i++) { - calcSpaceVfs->calcSpace(files[i], &totalSize, &totalFiles, &totalDirs, &_exited); + calcSpaceFileSystem->calcSpace(files[i], &totalSize, &totalFiles, &totalDirs, &_exited); } - delete calcSpaceVfs; + delete calcSpaceFileSystem; } KRarcObserver * AbstractJobThread::observer() { if (_observer) return _observer; _observer = new AbstractJobObserver(this); return _observer; } bool AbstractJobThread::uploadTempFiles() { if (_tempFile != 0 || _tempDir != 0) { sendInfo(i18n("Uploading to remote destination")); if (_tempFile) { QList urlList; urlList << QUrl::fromLocalFile(_tempFileName); QList args; args << KrServices::toStringList(urlList); args << _tempFileTarget; UserEvent * uploadEvent = new UserEvent(CMD_UPLOAD_FILES, args); QList * result = _job->getEventResponse(uploadEvent); if (result == 0) return false; int errorCode = (*result)[ 0 ].value(); QString errorText = (*result)[ 1 ].value(); delete result; if (errorCode) { sendError(errorCode, errorText); return false; } } if (_tempDir) { QList urlList; QDir tempDir(_tempDirName); QStringList list = tempDir.entryList(); foreach(const QString &name, list) { if (name == "." || name == "..") continue; QUrl url = QUrl::fromLocalFile(_tempDirName).adjusted(QUrl::StripTrailingSlash); url.setPath(url.path() + '/' + (name)); urlList << url; } QList args; args << KrServices::toStringList(urlList); args << _tempDirTarget; UserEvent * uploadEvent = new UserEvent(CMD_UPLOAD_FILES, args); QList * result = _job->getEventResponse(uploadEvent); if (result == 0) return false; int errorCode = (*result)[ 0 ].value(); QString errorText = (*result)[ 1 ].value(); delete result; if (errorCode) { sendError(errorCode, errorText); return false; } } } return true; } QString AbstractJobThread::getPassword(const QString &path) { QList args; args << path; UserEvent * getPasswdEvent = new UserEvent(CMD_GET_PASSWORD, args); QList * result = _job->getEventResponse(getPasswdEvent); if (result == 0) return QString(); QString password = (*result)[ 0 ].value(); if (password.isNull()) password = QString(""); delete result; return password; } void AbstractJobThread::sendMessage(const QString &message) { QList args; args << message; UserEvent * getPasswdEvent = new UserEvent(CMD_MESSAGE, args); QList * result = _job->getEventResponse(getPasswdEvent); if (result == 0) return; delete result; } //! Gets some archive information that is needed in several cases. /*! \param path A path to the archive. \param type The type of the archive. \param password The password of the archive. \param arcName The name of the archive. \param sourceFolder A QUrl, which may be remote, of the folder where the archive is. \return If the archive information has been obtained. */ bool AbstractJobThread::getArchiveInformation(QString &path, QString &type, QString &password, QString &arcName, const QUrl &sourceFolder) { // Safety checks (though the user shouldn't have been able to select something named "" or "..") if (arcName.isEmpty()) return false; if (arcName == "..") return false; QUrl url = sourceFolder.adjusted(QUrl::StripTrailingSlash); url.setPath(url.path() + '/' + arcName); path = url.adjusted(QUrl::StripTrailingSlash).path(); QMimeDatabase db; QMimeType mt = db.mimeTypeForUrl(url); QString mime = mt.isValid() ? mt.name() : QString(); bool encrypted = false; type = arcHandler.getType(encrypted, path, mime); // Check that the archive is supported if (!KRarcHandler::arcSupported(type)) { sendError(KIO::ERR_NO_CONTENT, i18nc("%1=archive filename", "%1, unsupported archive type.", arcName)); return false; } password = encrypted ? getPassword(path) : QString(); return true; } diff --git a/krusader/BookMan/krbookmark.cpp b/krusader/BookMan/krbookmark.cpp index a8ef705a..7aa31e6f 100644 --- a/krusader/BookMan/krbookmark.cpp +++ b/krusader/BookMan/krbookmark.cpp @@ -1,122 +1,122 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "krbookmark.h" #include "../krglobal.h" #include "../Archive/krarchandler.h" -#include "../VFS/krtrashhandler.h" +#include "../FileSystem/krtrashhandler.h" #include #include #include #define BM_NAME(X) (QString("Bookmark:")+X) static const char* NAME_TRASH = I18N_NOOP("Trash bin"); static const char* NAME_VIRTUAL = I18N_NOOP("Virtual Filesystem"); static const char* NAME_LAN = I18N_NOOP("Local Network"); KrBookmark::KrBookmark(QString name, QUrl url, KActionCollection *parent, QString icon, QString actionName) : QAction(parent), _url(url), _icon(icon), _folder(false), _separator(false), _autoDelete(true) { QString actName = actionName.isNull() ? BM_NAME(name) : BM_NAME(actionName); setText(name); parent->addAction(actName, this); connect(this, SIGNAL(triggered()), this, SLOT(activatedProxy())); // do we have an icon? if (!icon.isEmpty()) setIcon(QIcon::fromTheme(icon)); else { // what kind of a url is it? if (_url.isLocalFile()) { setIcon(QIcon::fromTheme("folder")); } else { // is it an archive? if (KRarcHandler::isArchive(_url)) setIcon(QIcon::fromTheme("application-x-tar")); else setIcon(QIcon::fromTheme("folder-html")); } } } KrBookmark::KrBookmark(QString name, QString icon) : QAction(QIcon::fromTheme(icon), name, 0), _icon(icon), _folder(true), _separator(false), _autoDelete(false) { setIcon(QIcon::fromTheme(icon == "" ? "folder" : icon)); } KrBookmark::~KrBookmark() { if (_autoDelete) { QListIterator it(_children); while (it.hasNext()) delete it.next(); _children.clear(); } } KrBookmark* KrBookmark::getExistingBookmark(QString actionName, KActionCollection *collection) { return static_cast(collection->action(BM_NAME(actionName))); } KrBookmark* KrBookmark::trash(KActionCollection *collection) { KrBookmark *bm = getExistingBookmark(i18n(NAME_TRASH), collection); if (!bm) bm = new KrBookmark(i18n(NAME_TRASH), QUrl("trash:/"), collection); bm->setIcon(krLoader->loadIcon(KrTrashHandler::trashIcon(), KIconLoader::Small)); return bm; } KrBookmark* KrBookmark::virt(KActionCollection *collection) { KrBookmark *bm = getExistingBookmark(i18n(NAME_VIRTUAL), collection); if (!bm) { bm = new KrBookmark(i18n(NAME_VIRTUAL), QUrl("virt:/"), collection); bm->setIcon(krLoader->loadIcon("document-open-remote", KIconLoader::Small)); } return bm; } KrBookmark* KrBookmark::lan(KActionCollection *collection) { KrBookmark *bm = getExistingBookmark(i18n(NAME_LAN), collection); if (!bm) { bm = new KrBookmark(i18n(NAME_LAN), QUrl("remote:/"), collection); bm->setIcon(krLoader->loadIcon("network-workgroup", KIconLoader::Small)); } return bm; } KrBookmark* KrBookmark::separator() { KrBookmark *bm = new KrBookmark(""); bm->_separator = true; bm->_folder = false; return bm; } void KrBookmark::activatedProxy() { emit activated(url()); } diff --git a/krusader/BookMan/krbookmarkhandler.cpp b/krusader/BookMan/krbookmarkhandler.cpp index 4854d2a0..a13df127 100644 --- a/krusader/BookMan/krbookmarkhandler.cpp +++ b/krusader/BookMan/krbookmarkhandler.cpp @@ -1,644 +1,644 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "krbookmarkhandler.h" #include "kraddbookmarkdlg.h" #include "../krglobal.h" #include "../krslots.h" #include "../kractions.h" #include "../krmainwindow.h" #include "../Dialogs/popularurls.h" -#include "../VFS/vfs.h" +#include "../FileSystem/filesystem.h" #include "../Panel/krpanel.h" #include "../Panel/listpanelactions.h" // QtCore #include #include #include #include // QtGui #include #include #include #include #include #include #include #include #define SPECIAL_BOOKMARKS true // ------------------------ for internal use #define BOOKMARKS_FILE "krusader/krbookmarks.xml" #define CONNECT_BM(X) { disconnect(X, SIGNAL(activated(const QUrl&)), 0, 0); connect(X, SIGNAL(activated(const QUrl&)), this, SLOT(slotActivated(const QUrl&))); } KrBookmarkHandler::KrBookmarkHandler(KrMainWindow *mainWindow) : QObject(mainWindow->widget()), _mainWindow(mainWindow), _middleClick(false), _mainBookmarkPopup(0), _specialBookmarks() { // create our own action collection and make the shortcuts apply only to parent _privateCollection = new KActionCollection(this); _collection = _mainWindow->actions(); // create _root: father of all bookmarks. it is a dummy bookmark and never shown _root = new KrBookmark(i18n("Bookmarks")); _root->setParent(this); // load bookmarks importFromFile(); // hack QString filename = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + BOOKMARKS_FILE; manager = KBookmarkManager::managerForFile(filename, QStringLiteral("krusader")); connect(manager, SIGNAL(changed(const QString&, const QString&)), this, SLOT(bookmarksChanged(const QString&, const QString&))); } KrBookmarkHandler::~KrBookmarkHandler() { delete manager; delete _privateCollection; } void KrBookmarkHandler::bookmarkCurrent(QUrl url) { QPointer dlg = new KrAddBookmarkDlg(_mainWindow->widget(), url); if (dlg->exec() == QDialog::Accepted) { KrBookmark *bm = new KrBookmark(dlg->name(), dlg->url(), _collection); addBookmark(bm, dlg->folder()); } delete dlg; } void KrBookmarkHandler::addBookmark(KrBookmark *bm, KrBookmark *folder) { if (folder == 0) folder = _root; // add to the list (bottom) folder->children().append(bm); exportToFile(); } void KrBookmarkHandler::deleteBookmark(KrBookmark *bm) { if (bm->isFolder()) clearBookmarks(bm); // remove the child bookmarks removeReferences(_root, bm); foreach(QWidget *w, bm->associatedWidgets()) w->removeAction(bm); delete bm; exportToFile(); } void KrBookmarkHandler::removeReferences(KrBookmark *root, KrBookmark *bmToRemove) { int index = root->children().indexOf(bmToRemove); if (index >= 0) root->children().removeAt(index); QListIterator it(root->children()); while (it.hasNext()) { KrBookmark *bm = it.next(); if (bm->isFolder()) removeReferences(bm, bmToRemove); } } void KrBookmarkHandler::exportToFileBookmark(QDomDocument &doc, QDomElement &where, KrBookmark *bm) { if (bm->isSeparator()) { QDomElement bookmark = doc.createElement("separator"); where.appendChild(bookmark); } else { QDomElement bookmark = doc.createElement("bookmark"); // url bookmark.setAttribute("href", bm->url().toDisplayString()); // icon bookmark.setAttribute("icon", bm->iconName()); // title QDomElement title = doc.createElement("title"); title.appendChild(doc.createTextNode(bm->text())); bookmark.appendChild(title); where.appendChild(bookmark); } } void KrBookmarkHandler::exportToFileFolder(QDomDocument &doc, QDomElement &parent, KrBookmark *folder) { QListIterator it(folder->children()); while (it.hasNext()) { KrBookmark *bm = it.next(); if (bm->isFolder()) { QDomElement newFolder = doc.createElement("folder"); newFolder.setAttribute("icon", bm->iconName()); parent.appendChild(newFolder); QDomElement title = doc.createElement("title"); title.appendChild(doc.createTextNode(bm->text())); newFolder.appendChild(title); exportToFileFolder(doc, newFolder, bm); } else { exportToFileBookmark(doc, parent, bm); } } } // export to file using the xbel standard // // // Developer Web Site // // Title of this folder // KDE Web Site // // My own bookmarks // KOffice Web Site // // KDevelop Web Site // // // void KrBookmarkHandler::exportToFile() { QDomDocument doc("xbel"); QDomElement root = doc.createElement("xbel"); doc.appendChild(root); exportToFileFolder(doc, root, _root); if (!doc.firstChild().isProcessingInstruction()) { // adding: if not already present QDomProcessingInstruction instr = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\" "); doc.insertBefore(instr, doc.firstChild()); } QString filename = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + BOOKMARKS_FILE; QFile file(filename); if (file.open(QIODevice::WriteOnly)) { QTextStream stream(&file); stream.setCodec("UTF-8"); stream << doc.toString(); file.close(); } else { KMessageBox::error(_mainWindow->widget(), i18n("Unable to write to %1", filename), i18n("Error")); } } bool KrBookmarkHandler::importFromFileBookmark(QDomElement &e, KrBookmark *parent, QString path, QString *errorMsg) { QString url, name, icon; // verify tag if (e.tagName() != "bookmark") { *errorMsg = i18n("%1 instead of %2", e.tagName(), QLatin1String("bookmark")); return false; } // verify href if (!e.hasAttribute("href")) { *errorMsg = i18n("missing tag %1", QLatin1String("href")); return false; } else url = e.attribute("href"); // verify title QDomElement te = e.firstChild().toElement(); if (te.tagName() != "title") { *errorMsg = i18n("missing tag %1", QLatin1String("title")); return false; } else name = te.text(); // do we have an icon? if (e.hasAttribute("icon")) { icon = e.attribute("icon"); } // ok: got name and url, let's add a bookmark KrBookmark *bm = KrBookmark::getExistingBookmark(path + name, _collection); if (!bm) { bm = new KrBookmark(name, QUrl(url), _collection, icon, path + name); parent->children().append(bm); } return true; } bool KrBookmarkHandler::importFromFileFolder(QDomNode &first, KrBookmark *parent, QString path, QString *errorMsg) { QString name; QDomNode n = first; while (!n.isNull()) { QDomElement e = n.toElement(); if (e.tagName() == "bookmark") { if (!importFromFileBookmark(e, parent, path, errorMsg)) return false; } else if (e.tagName() == "folder") { QString iconName = ""; if (e.hasAttribute("icon")) iconName = e.attribute("icon"); // the title is the first child of the folder QDomElement tmp = e.firstChild().toElement(); if (tmp.tagName() != "title") { *errorMsg = i18n("missing tag %1", QLatin1String("title")); return false; } else name = tmp.text(); KrBookmark *folder = new KrBookmark(name, iconName); parent->children().append(folder); QDomNode nextOne = tmp.nextSibling(); if (!importFromFileFolder(nextOne, folder, path + name + '/', errorMsg)) return false; } else if (e.tagName() == "separator") { parent->children().append(KrBookmark::separator()); } n = n.nextSibling(); } return true; } void KrBookmarkHandler::importFromFile() { clearBookmarks(_root); QString filename = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + BOOKMARKS_FILE; QFile file(filename); if (!file.open(QIODevice::ReadOnly)) return; // no bookmarks file QString errorMsg; QDomNode n; QDomElement e; QDomDocument doc("xbel"); if (!doc.setContent(&file, &errorMsg)) { goto BM_ERROR; } // iterate through the document: first child should be "xbel" (skip all until we find it) n = doc.firstChild(); while (!n.isNull() && n.toElement().tagName() != "xbel") n = n.nextSibling(); if (n.isNull() || n.toElement().tagName() != "xbel") { errorMsg = i18n("%1 does not seem to be a valid bookmarks file", filename); goto BM_ERROR; } else n = n.firstChild(); // skip the xbel part importFromFileFolder(n, _root, "", &errorMsg); goto BM_SUCCESS; BM_ERROR: KMessageBox::error(_mainWindow->widget(), i18n("Error reading bookmarks file: %1", errorMsg), i18n("Error")); BM_SUCCESS: file.close(); } void KrBookmarkHandler::populate(QMenu *menu) { _mainBookmarkPopup = menu; menu->clear(); _specialBookmarks.clear(); buildMenu(_root, menu); } void KrBookmarkHandler::buildMenu(KrBookmark *parent, QMenu *menu) { static int inSecondaryMenu = 0; // used to know if we're on the top menu // run the loop twice, in order to put the folders on top. stupid but easy :-) // note: this code drops the separators put there by the user QListIterator it(parent->children()); while (it.hasNext()) { KrBookmark *bm = it.next(); if (!bm->isFolder()) continue; QMenu *newMenu = new QMenu(menu); newMenu->setIcon(QIcon(krLoader->loadIcon(bm->iconName(), KIconLoader::Small))); newMenu->setTitle(bm->text()); QAction *menuAction = menu->addMenu(newMenu); QVariant v; v.setValue(bm); menuAction->setData(v); ++inSecondaryMenu; buildMenu(bm, newMenu); --inSecondaryMenu; } it.toFront(); while (it.hasNext()) { KrBookmark *bm = it.next(); if (bm->isFolder()) continue; if (bm->isSeparator()) { menu->addSeparator(); continue; } menu->addAction(bm); CONNECT_BM(bm); } if (!inSecondaryMenu) { KConfigGroup group(krConfig, "Private"); bool hasPopularURLs = group.readEntry("BM Popular URLs", true); bool hasTrash = group.readEntry("BM Trash", true); bool hasLan = group.readEntry("BM Lan", true); bool hasVirtualFS = group.readEntry("BM Virtual FS", true); bool hasJumpback = group.readEntry("BM Jumpback", true); if (hasPopularURLs) { menu->addSeparator(); // add the popular links submenu QMenu *newMenu = new QMenu(menu); newMenu->setTitle(i18n("Popular URLs")); newMenu->setIcon(QIcon(krLoader->loadIcon("folder-bookmark", KIconLoader::Small))); QAction *bmfAct = menu->addMenu(newMenu); _specialBookmarks.append(bmfAct); // add the top 15 urls #define MAX 15 QList list = _mainWindow->popularUrls()->getMostPopularUrls(MAX); QList::Iterator it; for (it = list.begin(); it != list.end(); ++it) { QString name; if ((*it).isLocalFile()) name = (*it).path(); else name = (*it).toDisplayString(); // note: these bookmark are put into the private collection // as to not spam the general collection KrBookmark *bm = KrBookmark::getExistingBookmark(name, _privateCollection); if (!bm) bm = new KrBookmark(name, *it, _privateCollection); newMenu->addAction(bm); CONNECT_BM(bm); } newMenu->addSeparator(); newMenu->addAction(krPopularUrls); newMenu->installEventFilter(this); } // do we need to add special bookmarks? if (SPECIAL_BOOKMARKS) { if (hasTrash || hasLan || hasVirtualFS || hasJumpback) menu->addSeparator(); KrBookmark *bm; // note: special bookmarks are not kept inside the _bookmarks list and added ad-hoc if (hasTrash) { bm = KrBookmark::trash(_collection); menu->addAction(bm); _specialBookmarks.append(bm); CONNECT_BM(bm); } if (hasLan) { bm = KrBookmark::lan(_collection); menu->addAction(bm); _specialBookmarks.append(bm); CONNECT_BM(bm); } if (hasVirtualFS) { bm = KrBookmark::virt(_collection); menu->addAction(bm); _specialBookmarks.append(bm); CONNECT_BM(bm); } if (hasJumpback) { // add the jump-back button ListPanelActions *actions = _mainWindow->listPanelActions(); menu->addAction(actions->actJumpBack); _specialBookmarks.append(actions->actJumpBack); menu->addSeparator(); menu->addAction(actions->actSetJumpBack); _specialBookmarks.append(actions->actSetJumpBack); } } if (!hasJumpback) menu->addSeparator(); menu->addAction(KrActions::actAddBookmark); _specialBookmarks.append(KrActions::actAddBookmark); QAction *bmAct = menu->addAction(krLoader->loadIcon("bookmarks", KIconLoader::Small), i18n("Manage Bookmarks"), manager, SLOT(slotEditBookmarks())); _specialBookmarks.append(bmAct); // make sure the menu is connected to us disconnect(menu, SIGNAL(triggered(QAction *)), 0, 0); } menu->installEventFilter(this); } void KrBookmarkHandler::clearBookmarks(KrBookmark *root) { QList::iterator it = root->children().begin(); while (it != root->children().end()) { KrBookmark *bm = *it; if (bm->isFolder()) clearBookmarks(bm); else { foreach(QWidget *w, bm->associatedWidgets()) w->removeAction(bm); delete bm; } it = root->children().erase(it); } } void KrBookmarkHandler::bookmarksChanged(const QString&, const QString&) { importFromFile(); } bool KrBookmarkHandler::eventFilter(QObject *obj, QEvent *ev) { if (ev->type() == QEvent::MouseButtonRelease) { switch (static_cast(ev)->button()) { case Qt::RightButton: _middleClick = false; if (obj->inherits("QMenu")) { QMenu * menu = static_cast(obj); QAction * act = menu->actionAt(static_cast(ev)->pos()); if (obj == _mainBookmarkPopup && _specialBookmarks.contains(act)) { rightClickOnSpecialBookmark(); return true; } KrBookmark * bm = dynamic_cast(act); if (bm != 0) { rightClicked(menu, bm); return true; } else if (act && act->data().canConvert()) { KrBookmark * bm = act->data().value (); rightClicked(menu, bm); } } case Qt::LeftButton: _middleClick = false; break; case Qt::MidButton: _middleClick = true; break; default: break; } } return QObject::eventFilter(obj, ev); } #define POPULAR_URLS_ID 100100 #define TRASH_ID 100101 #define LAN_ID 100103 #define VIRTUAL_FS_ID 100102 #define JUMP_BACK_ID 100104 void KrBookmarkHandler::rightClickOnSpecialBookmark() { KConfigGroup group(krConfig, "Private"); bool hasPopularURLs = group.readEntry("BM Popular URLs", true); bool hasTrash = group.readEntry("BM Trash", true); bool hasLan = group.readEntry("BM Lan", true); bool hasVirtualFS = group.readEntry("BM Virtual FS", true); bool hasJumpback = group.readEntry("BM Jumpback", true); QMenu menu(_mainBookmarkPopup); menu.setTitle(i18n("Enable special bookmarks")); QAction *act; act = menu.addAction(i18n("Popular URLs")); act->setData(QVariant(POPULAR_URLS_ID)); act->setCheckable(true); act->setChecked(hasPopularURLs); act = menu.addAction(i18n("Trash bin")); act->setData(QVariant(TRASH_ID)); act->setCheckable(true); act->setChecked(hasTrash); act = menu.addAction(i18n("Local Network")); act->setData(QVariant(LAN_ID)); act->setCheckable(true); act->setChecked(hasLan); act = menu.addAction(i18n("Virtual Filesystem")); act->setData(QVariant(VIRTUAL_FS_ID)); act->setCheckable(true); act->setChecked(hasVirtualFS); act = menu.addAction(i18n("Jump back")); act->setData(QVariant(JUMP_BACK_ID)); act->setCheckable(true); act->setChecked(hasJumpback); connect(_mainBookmarkPopup, SIGNAL(highlighted(int)), &menu, SLOT(close())); connect(_mainBookmarkPopup, SIGNAL(activated(int)), &menu, SLOT(close())); int result = -1; QAction *res = menu.exec(QCursor::pos()); if (res && res->data().canConvert()) result = res->data().toInt(); bool doCloseMain = true; switch (result) { case POPULAR_URLS_ID: group.writeEntry("BM Popular URLs", !hasPopularURLs); break; case TRASH_ID: group.writeEntry("BM Trash", !hasTrash); break; case LAN_ID: group.writeEntry("BM Lan", !hasLan); break; case VIRTUAL_FS_ID: group.writeEntry("BM Virtual FS", !hasVirtualFS); break; case JUMP_BACK_ID: group.writeEntry("BM Jumpback", !hasJumpback); break; default: doCloseMain = false; break; } menu.close(); if (doCloseMain && _mainBookmarkPopup) _mainBookmarkPopup->close(); } #define OPEN_ID 100200 #define OPEN_NEW_TAB_ID 100201 #define DELETE_ID 100202 void KrBookmarkHandler::rightClicked(QMenu *menu, KrBookmark * bm) { QMenu popup(_mainBookmarkPopup); QAction * act; if (!bm->isFolder()) { act = popup.addAction(krLoader->loadIcon("document-open", KIconLoader::Panel), i18n("Open")); act->setData(QVariant(OPEN_ID)); act = popup.addAction(krLoader->loadIcon("tab-new", KIconLoader::Panel), i18n("Open in a new tab")); act->setData(QVariant(OPEN_NEW_TAB_ID)); popup.addSeparator(); } act = popup.addAction(krLoader->loadIcon("edit-delete", KIconLoader::Panel), i18n("Delete")); act->setData(QVariant(DELETE_ID)); connect(menu, SIGNAL(highlighted(int)), &popup, SLOT(close())); connect(menu, SIGNAL(activated(int)), &popup, SLOT(close())); int result = -1; QAction *res = popup.exec(QCursor::pos()); if (res && res->data().canConvert ()) result = res->data().toInt(); popup.close(); if (_mainBookmarkPopup && result >= OPEN_ID && result <= DELETE_ID) { _mainBookmarkPopup->close(); } switch (result) { case OPEN_ID: SLOTS->refresh(bm->url()); break; case OPEN_NEW_TAB_ID: _mainWindow->activeManager()->newTab(bm->url()); break; case DELETE_ID: deleteBookmark(bm); break; } } // used to monitor middle clicks. if mid is found, then the // bookmark is opened in a new tab. ugly, but easier than overloading // KAction and KActionCollection. void KrBookmarkHandler::slotActivated(const QUrl &url) { if (_mainBookmarkPopup && !_mainBookmarkPopup->isHidden()) _mainBookmarkPopup->close(); if (_middleClick) _mainWindow->activeManager()->newTab(url); else SLOTS->refresh(url); } diff --git a/krusader/CMakeLists.txt b/krusader/CMakeLists.txt index 0c65fea9..610e0cb0 100644 --- a/krusader/CMakeLists.txt +++ b/krusader/CMakeLists.txt @@ -1,130 +1,130 @@ include_directories(${KF5_INCLUDES_DIRS} ${QT_INCLUDES}) configure_file(krusaderversion.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/krusaderversion.h) add_subdirectory(ActionMan) add_subdirectory(Archive) add_subdirectory(BookMan) add_subdirectory(Dialogs) add_subdirectory(DiskUsage) +add_subdirectory(FileSystem) add_subdirectory(Filter) add_subdirectory(GUI) add_subdirectory(Konfigurator) add_subdirectory(KViewer) add_subdirectory(JobMan) add_subdirectory(Locate) add_subdirectory(MountMan) add_subdirectory(Panel) add_subdirectory(Search) add_subdirectory(Splitter) add_subdirectory(UserAction) -add_subdirectory(VFS) if(SYNCHRONIZER_ENABLED) add_subdirectory(Synchronizer) endif(SYNCHRONIZER_ENABLED) message(STATUS "${CMAKE_CURRENT_SOURCE_DIR}: skipped subdir $(KRJSDIR)") set(krusader_SRCS krglobal.cpp actionsbase.cpp tabactions.cpp kractions.cpp paneltabbar.cpp panelmanager.cpp krservices.cpp main.cpp krusaderview.cpp krusader.cpp krslots.cpp kicons.cpp krdebuglogger.cpp ) # TODO porting: missing kf5 equivalent #kde4_add_app_icon(krusader_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/hi*-app-krusader_user.png") qt5_add_resources(krusader_RC_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/resources.qrc" ) add_executable(krusader ${krusader_SRCS} ${krusader_RC_SRCS}) target_link_libraries(krusader Panel BookMan Dialogs DiskUsage GUI Konfigurator KViewer MountMan - VFS + FileSystem Search Splitter Locate UserAction ActionMan KViewer Filter Dialogs GUI Archive JobMan KF5::Notifications KF5::Parts KF5::WindowSystem Qt5::PrintSupport ) if(SYNCHRONIZER_ENABLED) target_link_libraries( krusader Synchronizer ) endif(SYNCHRONIZER_ENABLED) install(TARGETS krusader ${INSTALL_TARGETS_DEFAULT_ARGS}) install(PROGRAMS org.kde.krusader.desktop org.kde.krusader.root-mode.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) install(FILES krusaderui.rc krusaderlisterui.rc krviewer.rc DESTINATION ${KXMLGUI_INSTALL_DIR}/krusader) install(FILES midnight_commander.color total_commander.color total_commander.keymap total_commander.keymap.info useraction_examples.xml layout.xml splash.png DESTINATION ${DATA_INSTALL_DIR}/krusader) install(FILES org.kde.krusader.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) ecm_install_icons(ICONS icons/16-apps-krusader_blue.png icons/16-apps-krusader_red.png icons/16-apps-krusader_root.png icons/16-apps-krusader_user.png icons/22-apps-krusader_blue.png icons/22-apps-krusader_red.png icons/22-apps-krusader_root.png icons/22-apps-krusader_shield.png icons/22-apps-krusader_user.png icons/32-apps-krusader_blue.png icons/32-apps-krusader_red.png icons/32-apps-krusader_root.png icons/32-apps-krusader_shield.png icons/32-apps-krusader_user.png icons/48-apps-krusader_blue.png icons/48-apps-krusader_red.png icons/48-apps-krusader_root.png icons/48-apps-krusader_shield.png icons/48-apps-krusader_user.png icons/64-apps-krusader_blue.png icons/64-apps-krusader_red.png icons/64-apps-krusader_root.png icons/64-apps-krusader_shield.png icons/64-apps-krusader_user.png icons/128-apps-krusader_root.png icons/128-apps-krusader_user.png DESTINATION ${ICON_INSTALL_DIR} ) diff --git a/krusader/Dialogs/krdialogs.cpp b/krusader/Dialogs/krdialogs.cpp index b6773688..2b9a1d32 100644 --- a/krusader/Dialogs/krdialogs.cpp +++ b/krusader/Dialogs/krdialogs.cpp @@ -1,263 +1,263 @@ /***************************************************************************** * Copyright (C) 2000 Shie Erlich * * Copyright (C) 2000 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "krdialogs.h" // QtCore #include // QtGui #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include #include "../krglobal.h" -#include "../VFS/vfs.h" +#include "../FileSystem/filesystem.h" #include "../defaults.h" #include "../JobMan/jobman.h" QUrl KChooseDir::getFile(const QString &text, const QUrl& url, const QUrl& cwd) { return get(text, url, cwd, KFile::File); } QUrl KChooseDir::getDir(const QString &text, const QUrl& url, const QUrl& cwd) { return get(text, url, cwd, KFile::Directory); } QUrl KChooseDir::get(const QString &text, const QUrl &url, const QUrl &cwd, KFile::Modes mode) { - QScopedPointer dlg(new KUrlRequesterDialog(vfs::ensureTrailingSlash(url), text, krMainWindow)); + QScopedPointer dlg(new KUrlRequesterDialog(FileSystem::ensureTrailingSlash(url), text, krMainWindow)); dlg->urlRequester()->setStartDir(cwd); dlg->urlRequester()->setMode(mode); dlg->exec(); QUrl u = dlg->selectedUrl(); // empty if cancelled if (u.scheme() == "zip" || u.scheme() == "krarc" || u.scheme() == "tar" || u.scheme() == "iso") { if (QDir(u.path()).exists()) { u.setScheme("file"); } } return u; } KChooseDir::ChooseResult KChooseDir::getCopyDir(const QString &text, const QUrl &url, const QUrl &cwd, bool preserveAttrs, const QUrl &baseURL) { QScopedPointer dlg(new KUrlRequesterDlgForCopy( - vfs::ensureTrailingSlash(url), text, preserveAttrs, krMainWindow, true, baseURL)); + FileSystem::ensureTrailingSlash(url), text, preserveAttrs, krMainWindow, true, baseURL)); if (!preserveAttrs) dlg->hidePreserveAttrs(); dlg->urlRequester()->setStartDir(cwd); dlg->urlRequester()->setMode(KFile::Directory); dlg->exec(); QUrl u = dlg->selectedURL(); if (u.scheme() == "zip" || u.scheme() == "krarc" || u.scheme() == "tar" || u.scheme() == "iso") { if (QDir(u.path()).exists()) { u.setScheme("file"); } } ChooseResult result; result.url = u; result.reverseQueueMode = dlg->isReverseQueueMode(); result.startPaused = dlg->isStartPaused(); result.preserveAttrs = dlg->preserveAttrs(); result.baseURL = dlg->copyDirStructure() ? dlg->baseURL() : QUrl(); return result; } KUrlRequesterDlgForCopy::KUrlRequesterDlgForCopy(const QUrl &urlName, const QString &_text, bool /*presAttrs*/, QWidget *parent, bool modal, QUrl baseURL) : QDialog(parent), baseUrlCombo(0), copyDirStructureCB(0) { setWindowModality(modal ? Qt::WindowModal : Qt::NonModal); QVBoxLayout *mainLayout = new QVBoxLayout; setLayout(mainLayout); mainLayout->addWidget(new QLabel(_text)); urlRequester_ = new KUrlRequester(urlName, this); urlRequester_->setMinimumWidth(urlRequester_->sizeHint().width() * 3); mainLayout->addWidget(urlRequester_); // preserveAttrsCB = new QCheckBox(i18n("Preserve attributes (only for local targets)"), widget); // preserveAttrsCB->setChecked(presAttrs); // topLayout->addWidget(preserveAttrsCB); if (!baseURL.isEmpty()) { QFrame *line = new QFrame(this); line->setFrameStyle(QFrame::HLine | QFrame::Sunken); mainLayout->addWidget(line); copyDirStructureCB = new QCheckBox(i18n("Keep virtual folder structure"), this); connect(copyDirStructureCB, SIGNAL(toggled(bool)), this, SLOT(slotDirStructCBChanged())); copyDirStructureCB->setChecked(false); mainLayout->addWidget(copyDirStructureCB); QWidget *hboxWidget = new QWidget(this); QHBoxLayout * hbox = new QHBoxLayout(hboxWidget); QLabel * lbl = new QLabel(i18n("Base URL:"), hboxWidget); hbox->addWidget(lbl); baseUrlCombo = new QComboBox(hboxWidget); baseUrlCombo->setMinimumWidth(baseUrlCombo->sizeHint().width() * 3); baseUrlCombo->setEnabled(copyDirStructureCB->isChecked()); hbox->addWidget(baseUrlCombo); QUrl temp = baseURL, tempOld; do { QString baseURLText = temp.toDisplayString(QUrl::PreferLocalFile); baseUrlCombo->addItem(baseURLText); tempOld = temp; temp = KIO::upUrl(temp); } while (!tempOld.matches(temp, QUrl::StripTrailingSlash)); baseUrlCombo->setCurrentIndex(0); mainLayout->addWidget(hboxWidget); } QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); mainLayout->addWidget(buttonBox); okButton = buttonBox->button(QDialogButtonBox::Ok); okButton->setDefault(true); pauseBox = new QCheckBox(i18n("Start &Paused"), this); buttonBox->addButton(pauseBox, QDialogButtonBox::ActionRole); QPushButton *reverseQueueModeButton = new QPushButton(krJobMan->isQueueModeEnabled() ? i18n("F2 Run Immediately") : i18n("F2 Queue"), this); reverseQueueModeButton->setToolTip(krJobMan->isQueueModeEnabled() ? i18n("Immediately start job even if there are running jobs in queue.") : i18n("Enqueue the job if queue is not empty. Otherwise start the job immediately.")); buttonBox->addButton(reverseQueueModeButton, QDialogButtonBox::ActionRole); connect(buttonBox, SIGNAL(accepted()), SLOT(accept())); connect(buttonBox, SIGNAL(rejected()), SLOT(reject())); connect(reverseQueueModeButton, SIGNAL(clicked()), SLOT(slotReverseQueueMode())); connect(urlRequester_, SIGNAL(textChanged(QString)), SLOT(slotTextChanged(QString))); urlRequester_->setFocus(); bool state = !urlName.isEmpty(); okButton->setEnabled(state); } void KUrlRequesterDlgForCopy::keyPressEvent(QKeyEvent *e) { switch (e->key()) { case Qt::Key_F2: slotReverseQueueMode(); return; default: QDialog::keyPressEvent(e); } } void KUrlRequesterDlgForCopy::slotReverseQueueMode() { reverseQueueMode = true; accept(); } bool KUrlRequesterDlgForCopy::preserveAttrs() { // return preserveAttrsCB->isChecked(); return true; } bool KUrlRequesterDlgForCopy::copyDirStructure() { if (copyDirStructureCB == 0) return false; return copyDirStructureCB->isChecked(); } void KUrlRequesterDlgForCopy::slotTextChanged(const QString & text) { bool state = !text.trimmed().isEmpty(); okButton->setEnabled(state); } void KUrlRequesterDlgForCopy::slotDirStructCBChanged() { baseUrlCombo->setEnabled(copyDirStructureCB->isChecked()); } QUrl KUrlRequesterDlgForCopy::selectedURL() const { if (result() == QDialog::Accepted) { QUrl url = urlRequester_->url(); if (url.isValid()) KRecentDocument::add(url); return url; } else return QUrl(); } KUrlRequester * KUrlRequesterDlgForCopy::urlRequester() { return urlRequester_; } QUrl KUrlRequesterDlgForCopy::baseURL() const { if (baseUrlCombo == 0) return QUrl(); return QUrl::fromUserInput(baseUrlCombo->currentText(), QString(), QUrl::AssumeLocalFile); } KRGetDate::KRGetDate(QDate date, QWidget *parent) : QDialog(parent, Qt::MSWindowsFixedSizeDialogHint) { setWindowModality(Qt::WindowModal); dateWidget = new KDatePicker(this); dateWidget->setDate(date); dateWidget->resize(dateWidget->sizeHint()); setMinimumSize(dateWidget->sizeHint()); setMaximumSize(dateWidget->sizeHint()); resize(minimumSize()); connect(dateWidget, SIGNAL(dateSelected(QDate)), this, SLOT(setDate(QDate))); connect(dateWidget, SIGNAL(dateEntered(QDate)), this, SLOT(setDate(QDate))); // keep the original date - incase ESC is pressed originalDate = date; } QDate KRGetDate::getDate() { if (exec() == QDialog::Rejected) chosenDate = QDate(); hide(); return chosenDate; } void KRGetDate::setDate(QDate date) { chosenDate = date; accept(); } diff --git a/krusader/Dialogs/krspwidgets.h b/krusader/Dialogs/krspwidgets.h index cc5b48a9..f2a6d346 100644 --- a/krusader/Dialogs/krspwidgets.h +++ b/krusader/Dialogs/krspwidgets.h @@ -1,92 +1,92 @@ /*************************************************************************** krspwidgets.h ------------------- copyright : (C) 2000 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KRSPWIDGETS_H #define KRSPWIDGETS_H // QtCore #include // QtGui #include #include #include #include "krmaskchoice.h" #include "newftpgui.h" -#include "../VFS/krquery.h" +#include "../FileSystem/krquery.h" class KRMaskChoiceSub; class KRSpWidgets { friend class KRMaskChoiceSub; public: KRSpWidgets(); static KRQuery getMask(QString caption, bool nameOnly = false, QWidget * parent = 0); // get file-mask for (un)selecting files static QUrl newFTP(); private: static QStringList maskList; // used by KRMaskChoiceSub }; /////////////////////////// newFTPSub /////////////////////////////////////// class newFTPSub : public newFTPGUI { public: newFTPSub(); protected: void reject(); void accept(); }; /////////////////////////// KRMaskChoiceSub ///////////////////////////////// // Inherits KRMaskChoice's generated code to fully implement the functions // ///////////////////////////////////////////////////////////////////////////// class KRMaskChoiceSub : public KRMaskChoice { public: KRMaskChoiceSub(QWidget * parent = 0); public slots: void addSelection(); void deleteSelection(); void clearSelections(); void acceptFromList(QListWidgetItem *i); void currentItemChanged(QListWidgetItem *i); protected: void reject(); void accept(); }; #endif diff --git a/krusader/Dialogs/kurllistrequester.cpp b/krusader/Dialogs/kurllistrequester.cpp index b7d61157..5b2f6dad 100644 --- a/krusader/Dialogs/kurllistrequester.cpp +++ b/krusader/Dialogs/kurllistrequester.cpp @@ -1,200 +1,200 @@ /*************************************************************************** kurllistrequester.cpp - description ------------------- copyright : (C) 2005 by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "kurllistrequester.h" -#include "../VFS/vfs.h" +#include "../FileSystem/filesystem.h" // QtGui #include #include #include // QtWidgets #include #include #include #include #include #include #include #define DELETE_ITEM_ID 100 KURLListRequester::KURLListRequester(Mode requestMode, QWidget *parent) : QWidget(parent), mode(requestMode) { // Creating the widget QGridLayout *urlListRequesterGrid = new QGridLayout(this); urlListRequesterGrid->setSpacing(0); urlListRequesterGrid->setContentsMargins(0, 0, 0, 0); urlLineEdit = new KLineEdit(this); urlListRequesterGrid->addWidget(urlLineEdit, 0, 0); urlListBox = new KrListWidget(this); urlListBox->setSelectionMode(QAbstractItemView::ExtendedSelection); urlListRequesterGrid->addWidget(urlListBox, 1, 0, 1, 3); urlAddBtn = new QToolButton(this); urlAddBtn->setText(""); urlAddBtn->setIcon(QIcon::fromTheme("arrow-down")); urlListRequesterGrid->addWidget(urlAddBtn, 0, 1); urlBrowseBtn = new QToolButton(this); urlBrowseBtn->setText(""); urlBrowseBtn->setIcon(QIcon::fromTheme("folder")); urlListRequesterGrid->addWidget(urlBrowseBtn, 0, 2); // add shell completion completion.setMode(KUrlCompletion::FileCompletion); urlLineEdit->setCompletionObject(&completion); // connection table connect(urlAddBtn, SIGNAL(clicked()), this, SLOT(slotAdd())); connect(urlBrowseBtn, SIGNAL(clicked()), this, SLOT(slotBrowse())); connect(urlLineEdit, SIGNAL(returnPressed(const QString&)), this, SLOT(slotAdd())); connect(urlListBox, SIGNAL(itemRightClicked(QListWidgetItem *, const QPoint &)), this, SLOT(slotRightClicked(QListWidgetItem *, const QPoint &))); connect(urlLineEdit, SIGNAL(textChanged(const QString &)), this, SIGNAL(changed())); } void KURLListRequester::slotAdd() { QString text = urlLineEdit->text().simplified(); if (text.length()) { QString error; emit checkValidity(text, error); if (!error.isNull()) KMessageBox::error(this, error); else { urlListBox->addItem(text); urlLineEdit->clear(); emit changed(); } } } void KURLListRequester::slotBrowse() { QUrl url; switch (mode) { case RequestFiles: url = QFileDialog::getOpenFileUrl(this); break; case RequestDirs: url = QFileDialog::getExistingDirectoryUrl(this); break; } if (!url.isEmpty()) urlLineEdit->setText(url.toDisplayString(QUrl::PreferLocalFile)); urlLineEdit->setFocus(); } void KURLListRequester::keyPressEvent(QKeyEvent *e) { if (e->key() == Qt::Key_Delete) { if (urlListBox->hasFocus()) { deleteSelectedItems(); return; } } QWidget::keyPressEvent(e); } void KURLListRequester::deleteSelectedItems() { QList delList = urlListBox->selectedItems(); for (int i = 0; i != delList.count(); i++) delete delList[ i ]; emit changed(); } void KURLListRequester::slotRightClicked(QListWidgetItem *item, const QPoint &pos) { if (item == 0) return; QMenu popupMenu(this); QAction * menuAction = popupMenu.addAction(i18n("Delete")); if (menuAction == popupMenu.exec(pos)) { if (item->isSelected()) deleteSelectedItems(); else { delete item; emit changed(); } } } QList KURLListRequester::urlList() { QList urls; QString text = urlLineEdit->text().simplified(); if (!text.isEmpty()) { QString error; emit checkValidity(text, error); if (error.isNull()) urls.append(QUrl::fromUserInput(text, QString(), QUrl::AssumeLocalFile)); } for (int i = 0; i != urlListBox->count(); i++) { QListWidgetItem *item = urlListBox->item(i); QString text = item->text().simplified(); QString error; emit checkValidity(text, error); if (error.isNull()) urls.append(QUrl::fromUserInput(text, QString(), QUrl::AssumeLocalFile)); } return urls; } void KURLListRequester::setUrlList(QList urlList) { urlLineEdit->clear(); urlListBox->clear(); QList::iterator it; for (it = urlList.begin(); it != urlList.end(); ++it) urlListBox->addItem(it->toDisplayString(QUrl::PreferLocalFile)); emit changed(); } diff --git a/krusader/DiskUsage/diskusage.cpp b/krusader/DiskUsage/diskusage.cpp index 0ab611d4..bdb9a53b 100644 --- a/krusader/DiskUsage/diskusage.cpp +++ b/krusader/DiskUsage/diskusage.cpp @@ -1,1136 +1,1136 @@ /*************************************************************************** diskusage.cpp - description ------------------- copyright : (C) 2004 + by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "diskusage.h" // QtCore #include #include #include #include #include // QtGui #include #include #include #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include "../VFS/krpermhandler.h" -#include "../VFS/krvfshandler.h" +#include "../FileSystem/krpermhandler.h" +#include "../FileSystem/filesystemprovider.h" #include "../kicons.h" #include "../defaults.h" #include "../krglobal.h" #include "../Panel/krpanel.h" #include "../Panel/panelfunc.h" #include "filelightParts/Config.h" #include "dulines.h" #include "dulistview.h" #include "dufilelight.h" // these are the values that will exist in the menu #define DELETE_ID 90 #define EXCLUDE_ID 91 #define PARENT_DIR_ID 92 #define NEW_SEARCH_ID 93 #define REFRESH_ID 94 #define STEP_INTO_ID 95 #define INCLUDE_ALL_ID 96 #define VIEW_POPUP_ID 97 #define LINES_VIEW_ID 98 #define DETAILED_VIEW_ID 99 #define FILELIGHT_VIEW_ID 100 #define NEXT_VIEW_ID 101 #define PREVIOUS_VIEW_ID 102 #define ADDITIONAL_POPUP_ID 103 #define MAX_FILENUM 100 LoaderWidget::LoaderWidget(QWidget *parent) : QScrollArea(parent), cancelled(false) { QPalette palette = viewport()->palette(); palette.setColor(viewport()->backgroundRole(), Qt::white); viewport()->setPalette(palette); widget = new QWidget(parent); QGridLayout *loaderLayout = new QGridLayout(widget); loaderLayout->setSpacing(0); loaderLayout->setContentsMargins(0, 0, 0, 0); QFrame *loaderBox = new QFrame(widget); loaderBox->setFrameShape(QFrame::Box); loaderBox->setFrameShadow(QFrame::Sunken); loaderBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); loaderBox->setFrameStyle(QFrame::Panel + QFrame::Raised); loaderBox->setLineWidth(2); QGridLayout *synchGrid = new QGridLayout(loaderBox); synchGrid->setSpacing(6); synchGrid->setContentsMargins(11, 11, 11, 11); QLabel *titleLabel = new QLabel(i18n("Loading Usage Information"), loaderBox); titleLabel->setAlignment(Qt::AlignHCenter); synchGrid->addWidget(titleLabel, 0, 0, 1, 2); QLabel *filesLabel = new QLabel(i18n("Files:"), loaderBox); filesLabel->setFrameShape(QLabel::StyledPanel); filesLabel->setFrameShadow(QLabel::Sunken); synchGrid->addWidget(filesLabel, 1, 0); QLabel *directoriesLabel = new QLabel(i18n("Directories:"), loaderBox); directoriesLabel->setFrameShape(QLabel::StyledPanel); directoriesLabel->setFrameShadow(QLabel::Sunken); synchGrid->addWidget(directoriesLabel, 2, 0); QLabel *totalSizeLabel = new QLabel(i18n("Total Size:"), loaderBox); totalSizeLabel->setFrameShape(QLabel::StyledPanel); totalSizeLabel->setFrameShadow(QLabel::Sunken); synchGrid->addWidget(totalSizeLabel, 3, 0); files = new QLabel(loaderBox); files->setFrameShape(QLabel::StyledPanel); files->setFrameShadow(QLabel::Sunken); files->setAlignment(Qt::AlignRight); synchGrid->addWidget(files, 1, 1); directories = new QLabel(loaderBox); directories->setFrameShape(QLabel::StyledPanel); directories->setFrameShadow(QLabel::Sunken); directories->setAlignment(Qt::AlignRight); synchGrid->addWidget(directories, 2, 1); totalSize = new QLabel(loaderBox); totalSize->setFrameShape(QLabel::StyledPanel); totalSize->setFrameShadow(QLabel::Sunken); totalSize->setAlignment(Qt::AlignRight); synchGrid->addWidget(totalSize, 3, 1); int width; searchedDirectory = new KSqueezedTextLabel(loaderBox); searchedDirectory->setFrameShape(QLabel::StyledPanel); searchedDirectory->setFrameShadow(QLabel::Sunken); searchedDirectory->setMinimumWidth(width = QFontMetrics(searchedDirectory->font()).width("W") * 30); searchedDirectory->setMaximumWidth(width); synchGrid->addWidget(searchedDirectory, 4, 0, 1, 2); QFrame *line = new QFrame(loaderBox); line->setFrameStyle(QFrame::HLine | QFrame::Sunken); synchGrid->addWidget(line, 5, 0, 1, 2); QWidget *hboxWidget = new QWidget(loaderBox); QHBoxLayout * hbox = new QHBoxLayout(hboxWidget); QSpacerItem* spacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding); hbox->addItem(spacer); QPushButton *cancelButton = new QPushButton(hboxWidget); KStandardGuiItem::assign(cancelButton, KStandardGuiItem::Cancel); hbox->addWidget(cancelButton); synchGrid->addWidget(hboxWidget, 6, 1); loaderLayout->addWidget(loaderBox, 0, 0); setWidget(widget); setAlignment(Qt::AlignCenter); connect(cancelButton, SIGNAL(clicked()), this, SLOT(slotCancelled())); } void LoaderWidget::init() { cancelled = false; } void LoaderWidget::setCurrentURL(const QUrl &url) { - searchedDirectory->setText(vfs::ensureTrailingSlash(url).toDisplayString(QUrl::PreferLocalFile)); + searchedDirectory->setText(FileSystem::ensureTrailingSlash(url).toDisplayString(QUrl::PreferLocalFile)); } void LoaderWidget::setValues(int fileNum, int dirNum, KIO::filesize_t total) { files->setText(QString("%1").arg(fileNum)); directories->setText(QString("%1").arg(dirNum)); totalSize->setText(QString("%1").arg(KRpermHandler::parseSize(total).trimmed())); } void LoaderWidget::slotCancelled() { cancelled = true; } DiskUsage::DiskUsage(QString confGroup, QWidget *parent) : QStackedWidget(parent), currentDirectory(0), root(0), configGroup(confGroup), loading(false), - abortLoading(false), clearAfterAbort(false), deleting(false), searchVfs(0) + abortLoading(false), clearAfterAbort(false), deleting(false), searchFileSystem(0) { listView = new DUListView(this); lineView = new DULines(this); filelightView = new DUFilelight(this); loaderView = new LoaderWidget(this); addWidget(listView); addWidget(lineView); addWidget(filelightView); addWidget(loaderView); setView(VIEW_LINES); Filelight::Config::read(); connect(&loadingTimer, SIGNAL(timeout()), this, SLOT(slotLoadDirectory())); } DiskUsage::~DiskUsage() { if (listView) // don't remove these lines. The module will crash at exit if removed delete listView; if (lineView) delete lineView; if (filelightView) delete filelightView; if (root) delete root; QHashIterator< File *, Properties * > lit(propertyMap); while (lit.hasNext()) delete lit.next().value(); } void DiskUsage::load(const QUrl &baseDir) { fileNum = dirNum = 0; currentSize = 0; emit status(i18n("Loading the disk usage information...")); clear(); baseURL = baseDir.adjusted(QUrl::StripTrailingSlash); root = new Directory(baseURL.fileName(), baseDir.toDisplayString(QUrl::PreferLocalFile)); directoryStack.clear(); parentStack.clear(); directoryStack.push(""); parentStack.push(root); - if (searchVfs) { - delete searchVfs; - searchVfs = 0; + if (searchFileSystem) { + delete searchFileSystem; + searchFileSystem = 0; } - searchVfs = KrVfsHandler::instance().getVfs(baseDir); - if (searchVfs == 0) { - krOut << "diskusage could not get VFS for directory " << baseDir; + searchFileSystem = FileSystemProvider::instance().getFilesystem(baseDir); + if (searchFileSystem == 0) { + krOut << "diskusage could not get filesystem for directory " << baseDir; loading = abortLoading = clearAfterAbort = false; emit loadFinished(false); return; } - currentVfile = 0; + currentFileItem = 0; if (!loading) { viewBeforeLoad = activeView; setView(VIEW_LOADER); } loading = true; loaderView->init(); loaderView->setCurrentURL(baseURL); loaderView->setValues(fileNum, dirNum, currentSize); loadingTimer.setSingleShot(true); loadingTimer.start(0); } void DiskUsage::slotLoadDirectory() { - if ((currentVfile == 0 && directoryStack.isEmpty()) || loaderView->wasCancelled() || abortLoading) { - if (searchVfs) - delete searchVfs; + if ((currentFileItem == 0 && directoryStack.isEmpty()) || loaderView->wasCancelled() || abortLoading) { + if (searchFileSystem) + delete searchFileSystem; - searchVfs = 0; - currentVfile = 0; + searchFileSystem = 0; + currentFileItem = 0; setView(viewBeforeLoad); if (clearAfterAbort) clear(); else { calculateSizes(); changeDirectory(root); } emit loadFinished(!(loaderView->wasCancelled() || abortLoading)); loading = abortLoading = clearAfterAbort = false; } else if (loading) { for (int counter = 0; counter != MAX_FILENUM; counter ++) { - if (currentVfile == 0) { + if (currentFileItem == 0) { if (directoryStack.isEmpty()) break; dirToCheck = directoryStack.pop(); currentParent = parentStack.pop(); contentMap.insert(dirToCheck, currentParent); QUrl url = baseURL; if (!dirToCheck.isEmpty()) { url = url.adjusted(QUrl::StripTrailingSlash); url.setPath(url.path() + '/' + (dirToCheck)); } #ifdef BSD if (url.isLocalFile() && url.path().left(7) == "/procfs") break; #else if (url.isLocalFile() && url.path().left(5) == "/proc") break; #endif loaderView->setCurrentURL(url); - if (!searchVfs->refresh(url)) + if (!searchFileSystem->refresh(url)) break; - vfiles = searchVfs->vfiles(); + fileItems = searchFileSystem->fileItems(); dirNum++; - currentVfile = vfiles.isEmpty() ? 0 : vfiles.takeFirst(); + currentFileItem = fileItems.isEmpty() ? 0 : fileItems.takeFirst(); } else { fileNum++; File *newItem = 0; - QString mime = currentVfile->vfile_getMime(); // fast == not using mimetype magic + QString mime = currentFileItem->getMime(); // fast == not using mimetype magic - if (currentVfile->vfile_isDir() && !currentVfile->vfile_isSymLink()) { - newItem = new Directory(currentParent, currentVfile->vfile_getName(), dirToCheck, currentVfile->vfile_getSize(), - currentVfile->vfile_getMode(), currentVfile->vfile_getOwner(), currentVfile->vfile_getGroup(), - currentVfile->vfile_getPerm(), currentVfile->vfile_getTime_t(), currentVfile->vfile_isSymLink(), + if (currentFileItem->isDir() && !currentFileItem->isSymLink()) { + newItem = new Directory(currentParent, currentFileItem->getName(), dirToCheck, currentFileItem->getSize(), + currentFileItem->getMode(), currentFileItem->getOwner(), currentFileItem->getGroup(), + currentFileItem->getPerm(), currentFileItem->getTime_t(), currentFileItem->isSymLink(), mime); - directoryStack.push((dirToCheck.isEmpty() ? "" : dirToCheck + '/') + currentVfile->vfile_getName()); + directoryStack.push((dirToCheck.isEmpty() ? "" : dirToCheck + '/') + currentFileItem->getName()); parentStack.push(dynamic_cast(newItem)); } else { - newItem = new File(currentParent, currentVfile->vfile_getName(), dirToCheck, currentVfile->vfile_getSize(), - currentVfile->vfile_getMode(), currentVfile->vfile_getOwner(), currentVfile->vfile_getGroup(), - currentVfile->vfile_getPerm(), currentVfile->vfile_getTime_t(), currentVfile->vfile_isSymLink(), + newItem = new File(currentParent, currentFileItem->getName(), dirToCheck, currentFileItem->getSize(), + currentFileItem->getMode(), currentFileItem->getOwner(), currentFileItem->getGroup(), + currentFileItem->getPerm(), currentFileItem->getTime_t(), currentFileItem->isSymLink(), mime); - currentSize += currentVfile->vfile_getSize(); + currentSize += currentFileItem->getSize(); } currentParent->append(newItem); - currentVfile = vfiles.isEmpty() ? 0 : vfiles.takeFirst(); + currentFileItem = fileItems.isEmpty() ? 0 : fileItems.takeFirst(); } } loaderView->setValues(fileNum, dirNum, currentSize); loadingTimer.setSingleShot(true); loadingTimer.start(0); } } void DiskUsage::stopLoad() { abortLoading = true; } void DiskUsage::close() { if (loading) { abortLoading = true; clearAfterAbort = true; } } void DiskUsage::dirUp() { if (currentDirectory != 0) { if (currentDirectory->parent() != 0) changeDirectory((Directory *)(currentDirectory->parent())); else { QUrl up = KIO::upUrl(baseURL); if (KMessageBox::questionYesNo(this, i18n("Stepping into the parent folder requires " "loading the content of the \"%1\" URL. Do you wish " "to continue?", up.toDisplayString(QUrl::PreferLocalFile)), i18n("Krusader::DiskUsage"), KStandardGuiItem::yes(), KStandardGuiItem::no(), "DiskUsageLoadParentDir" ) == KMessageBox::Yes) load(up); } } } Directory * DiskUsage::getDirectory(QString dir) { while (dir.endsWith('/')) dir.truncate(dir.length() - 1); if (dir.isEmpty()) return root; if (contentMap.find(dir) == contentMap.end()) return 0; return contentMap[ dir ]; } File * DiskUsage::getFile(QString path) { if (path.isEmpty()) return root; QString dir = path; int ndx = path.lastIndexOf('/'); QString file = path.mid(ndx + 1); if (ndx == -1) dir = ""; else dir.truncate(ndx); Directory *dirEntry = getDirectory(dir); if (dirEntry == 0) return 0; for (Iterator it = dirEntry->iterator(); it != dirEntry->end(); ++it) if ((*it)->name() == file) return *it; return 0; } void DiskUsage::clear() { baseURL = QUrl(); emit clearing(); QHashIterator< File *, Properties * > lit(propertyMap); while (lit.hasNext()) delete lit.next().value(); propertyMap.clear(); contentMap.clear(); if (root) delete root; root = currentDirectory = 0; } int DiskUsage::calculateSizes(Directory *dirEntry, bool emitSig, int depth) { int changeNr = 0; if (dirEntry == 0) dirEntry = root; KIO::filesize_t own = 0, total = 0; for (Iterator it = dirEntry->iterator(); it != dirEntry->end(); ++it) { File * item = *it; if (!item->isExcluded()) { if (item->isDir()) changeNr += calculateSizes(dynamic_cast(item), emitSig, depth + 1); else own += item->size(); total += item->size(); } } KIO::filesize_t oldOwn = dirEntry->ownSize(), oldTotal = dirEntry->size(); dirEntry->setSizes(total, own); if (dirEntry == currentDirectory) currentSize = total; if (emitSig && (own != oldOwn || total != oldTotal)) { emit changed(dirEntry); changeNr++; } if (depth == 0 && changeNr != 0) emit changeFinished(); return changeNr; } int DiskUsage::exclude(File *file, bool calcPercents, int depth) { int changeNr = 0; if (!file->isExcluded()) { file->exclude(true); emit changed(file); changeNr++; if (file->isDir()) { Directory *dir = dynamic_cast(file); for (Iterator it = dir->iterator(); it != dir->end(); ++it) changeNr += exclude(*it, false, depth + 1); } } if (calcPercents) { calculateSizes(root, true); calculatePercents(true); createStatus(); } if (depth == 0 && changeNr != 0) emit changeFinished(); return changeNr; } int DiskUsage::include(Directory *dir, int depth) { int changeNr = 0; if (dir == 0) return 0; for (Iterator it = dir->iterator(); it != dir->end(); ++it) { File *item = *it; if (item->isDir()) changeNr += include(dynamic_cast(item), depth + 1); if (item->isExcluded()) { item->exclude(false); emit changed(item); changeNr++; } } if (depth == 0 && changeNr != 0) emit changeFinished(); return changeNr; } void DiskUsage::includeAll() { include(root); calculateSizes(root, true); calculatePercents(true); createStatus(); } int DiskUsage::del(File *file, bool calcPercents, int depth) { int deleteNr = 0; if (file == root) return 0; KConfigGroup gg(krConfig, "General"); bool trash = gg.readEntry("Move To Trash", _MoveToTrash); QUrl url = QUrl::fromLocalFile(file->fullPath()); if (calcPercents) { // now ask the user if he want to delete: KConfigGroup ga(krConfig, "Advanced"); if (ga.readEntry("Confirm Delete", _ConfirmDelete)) { QString s; KGuiItem b; if (trash && url.isLocalFile()) { s = i18nc("singularOnly", "Do you really want to move this item to the trash?"); b = KGuiItem(i18n("&Trash")); } else { s = i18nc("singularOnly", "Do you really want to delete this item?"); b = KStandardGuiItem::del(); } QStringList name; name.append(file->fullPath()); // show message // note: i'm using continue and not yes/no because the yes/no has cancel as default button if (KMessageBox::warningContinueCancelList(krMainWindow, s, name, i18n("Warning"), b) != KMessageBox::Continue) return 0; } emit status(i18n("Deleting %1...", file->name())); } if (file == currentDirectory) dirUp(); if (file->isDir()) { Directory *dir = dynamic_cast(file); Iterator it; while ((it = dir->iterator()) != dir->end()) deleteNr += del(*it, false, depth + 1); QString path; for (const Directory *d = (Directory*)file; d != root && d && d->parent() != 0; d = d->parent()) { if (!path.isEmpty()) path = '/' + path; path = d->name() + path; } contentMap.remove(path); } emit deleted(file); deleteNr++; KIO::Job *job; if (trash) { job = KIO::trash(url); } else { job = KIO::del(QUrl::fromLocalFile(file->fullPath()), KIO::HideProgressInfo); } deleting = true; // during qApp->processEvent strange things can occur grabMouse(); // that's why we disable the mouse and keyboard events grabKeyboard(); job->exec(); delete job; releaseMouse(); releaseKeyboard(); deleting = false; ((Directory *)(file->parent()))->remove(file); delete file; if (depth == 0) createStatus(); if (calcPercents) { calculateSizes(root, true); calculatePercents(true); createStatus(); emit enteringDirectory(currentDirectory); } if (depth == 0 && deleteNr != 0) emit deleteFinished(); return deleteNr; } void * DiskUsage::getProperty(File *item, QString key) { QHash< File *, Properties *>::iterator itr = propertyMap.find(item); if (itr == propertyMap.end()) return 0; QHash::iterator it = (*itr)->find(key); if (it == (*itr)->end()) return 0; return it.value(); } void DiskUsage::addProperty(File *item, QString key, void * prop) { Properties *props; QHash< File *, Properties *>::iterator itr = propertyMap.find(item); if (itr == propertyMap.end()) { props = new Properties(); propertyMap.insert(item, props); } else props = *itr; props->insert(key, prop); } void DiskUsage::removeProperty(File *item, QString key) { QHash< File *, Properties *>::iterator itr = propertyMap.find(item); if (itr == propertyMap.end()) return; (*itr)->remove(key); if ((*itr)->count() == 0) propertyMap.remove(item); } void DiskUsage::createStatus() { Directory *dirEntry = currentDirectory; if (dirEntry == 0) return; QUrl url = baseURL; if (dirEntry != root) { url = url.adjusted(QUrl::StripTrailingSlash); url.setPath(url.path() + '/' + (dirEntry->directory())); } emit status(i18n("Current folder:%1, Total size:%2, Own size:%3", url.toDisplayString(QUrl::PreferLocalFile | QUrl::StripTrailingSlash), ' ' + KRpermHandler::parseSize(dirEntry->size()), ' ' + KRpermHandler::parseSize(dirEntry->ownSize()))); } void DiskUsage::changeDirectory(Directory *dir) { currentDirectory = dir; currentSize = dir->size(); calculatePercents(true, dir); createStatus(); emit enteringDirectory(dir); } Directory* DiskUsage::getCurrentDir() { return currentDirectory; } void DiskUsage::rightClickMenu(const QPoint & pos, File *fileItem, QMenu *addPopup, QString addPopupName) { QMenu popup(this); popup.setTitle(i18n("Disk Usage")); QHash actionHash; if (fileItem != 0) { QAction * actDelete = popup.addAction(i18n("Delete")); actionHash[ actDelete ] = DELETE_ID; actDelete->setShortcut(Qt::Key_Delete); QAction * actExclude = popup.addAction(i18n("Exclude")); actionHash[ actExclude ] = EXCLUDE_ID; actExclude->setShortcut(Qt::CTRL + Qt::Key_E); popup.addSeparator(); } QAction * myAct = popup.addAction(i18n("Up one folder")); actionHash[ myAct ] = PARENT_DIR_ID; myAct->setShortcut(Qt::SHIFT + Qt::Key_Up); myAct = popup.addAction(i18n("New search")); actionHash[ myAct ] = NEW_SEARCH_ID; myAct->setShortcut(Qt::CTRL + Qt::Key_N); myAct = popup.addAction(i18n("Refresh")); actionHash[ myAct ] = REFRESH_ID; myAct->setShortcut(Qt::CTRL + Qt::Key_R); myAct = popup.addAction(i18n("Include all")); actionHash[ myAct ] = INCLUDE_ALL_ID; myAct->setShortcut(Qt::CTRL + Qt::Key_I); myAct = popup.addAction(i18n("Step into")); actionHash[ myAct ] = STEP_INTO_ID; myAct->setShortcut(Qt::SHIFT + Qt::Key_Down); popup.addSeparator(); if (addPopup != 0) { QAction * menu = popup.addMenu(addPopup); menu->setText(addPopupName); } QMenu viewPopup; myAct = viewPopup.addAction(i18n("Lines")); actionHash[ myAct ] = LINES_VIEW_ID; myAct->setShortcut(Qt::CTRL + Qt::Key_L); myAct = viewPopup.addAction(i18n("Detailed")); actionHash[ myAct ] = DETAILED_VIEW_ID; myAct->setShortcut(Qt::CTRL + Qt::Key_D); myAct = viewPopup.addAction(i18n("Filelight")); actionHash[ myAct ] = FILELIGHT_VIEW_ID; myAct->setShortcut(Qt::CTRL + Qt::Key_F); viewPopup.addSeparator(); myAct = viewPopup.addAction(i18n("Next")); actionHash[ myAct ] = NEXT_VIEW_ID; myAct->setShortcut(Qt::SHIFT + Qt::Key_Right); myAct = viewPopup.addAction(i18n("Previous")); actionHash[ myAct ] = PREVIOUS_VIEW_ID; myAct->setShortcut(Qt::SHIFT + Qt::Key_Left); QAction * menu = popup.addMenu(&viewPopup); menu->setText(i18n("View")); QAction * res = popup.exec(pos); if (actionHash.contains(res)) executeAction(actionHash[ res ], fileItem); } void DiskUsage::executeAction(int action, File * fileItem) { // check out the user's option switch (action) { case DELETE_ID: if (fileItem) del(fileItem); break; case EXCLUDE_ID: if (fileItem) exclude(fileItem); break; case PARENT_DIR_ID: dirUp(); break; case NEW_SEARCH_ID: emit newSearch(); break; case REFRESH_ID: load(baseURL); break; case INCLUDE_ALL_ID: includeAll(); break; case STEP_INTO_ID: { QString uri; if (fileItem && fileItem->isDir()) uri = fileItem->fullPath(); else uri = currentDirectory->fullPath(); ACTIVE_FUNC->openUrl(QUrl::fromLocalFile(uri)); } break; case LINES_VIEW_ID: setView(VIEW_LINES); break; case DETAILED_VIEW_ID: setView(VIEW_DETAILED); break; case FILELIGHT_VIEW_ID: setView(VIEW_FILELIGHT); break; case NEXT_VIEW_ID: setView((activeView + 1) % 3); break; case PREVIOUS_VIEW_ID: setView((activeView + 2) % 3); break; } // currentWidget()->setFocus(); } void DiskUsage::keyPressEvent(QKeyEvent *e) { if (activeView != VIEW_LOADER) { switch (e->key()) { case Qt::Key_E: if (e->modifiers() == Qt::ControlModifier) { executeAction(EXCLUDE_ID, getCurrentFile()); return; } case Qt::Key_D: if (e->modifiers() == Qt::ControlModifier) { executeAction(DETAILED_VIEW_ID); return; } case Qt::Key_F: if (e->modifiers() == Qt::ControlModifier) { executeAction(FILELIGHT_VIEW_ID); return; } case Qt::Key_I: if (e->modifiers() == Qt::ControlModifier) { executeAction(INCLUDE_ALL_ID); return; } break; case Qt::Key_L: if (e->modifiers() == Qt::ControlModifier) { executeAction(LINES_VIEW_ID); return; } case Qt::Key_N: if (e->modifiers() == Qt::ControlModifier) { executeAction(NEW_SEARCH_ID); return; } break; case Qt::Key_R: if (e->modifiers() == Qt::ControlModifier) { executeAction(REFRESH_ID); return; } break; case Qt::Key_Up: if (e->modifiers() == Qt::ShiftModifier) { executeAction(PARENT_DIR_ID); return; } break; case Qt::Key_Down: if (e->modifiers() == Qt::ShiftModifier) { executeAction(STEP_INTO_ID); return; } break; case Qt::Key_Left: if (e->modifiers() == Qt::ShiftModifier) { executeAction(PREVIOUS_VIEW_ID); return; } break; case Qt::Key_Right: if (e->modifiers() == Qt::ShiftModifier) { executeAction(NEXT_VIEW_ID); return; } break; case Qt::Key_Delete: if (!e->modifiers()) { executeAction(DELETE_ID, getCurrentFile()); return; } case Qt::Key_Plus: if (activeView == VIEW_FILELIGHT) { filelightView->zoomIn(); return; } break; case Qt::Key_Minus: if (activeView == VIEW_FILELIGHT) { filelightView->zoomOut(); return; } break; } } QStackedWidget::keyPressEvent(e); } QPixmap DiskUsage::getIcon(QString mime) { QPixmap icon; if (!QPixmapCache::find(mime, icon)) { // get the icon. if (mime == "Broken Link !") // FIXME: this doesn't work anymore - the reported mimetype for a broken link is now "unknown" icon = FL_LOADICON("file-broken"); else { QMimeDatabase db; QMimeType mt = db.mimeTypeForName(mime); if (mt.isValid()) icon = FL_LOADICON(mt.iconName()); else icon = FL_LOADICON("file-broken"); } // insert it into the cache QPixmapCache::insert(mime, icon); } return icon; } int DiskUsage::calculatePercents(bool emitSig, Directory *dirEntry, int depth) { int changeNr = 0; if (dirEntry == 0) dirEntry = root; for (Iterator it = dirEntry->iterator(); it != dirEntry->end(); ++it) { File *item = *it; if (!item->isExcluded()) { int newPerc; if (dirEntry->size() == 0 && item->size() == 0) newPerc = 0; else if (dirEntry->size() == 0) newPerc = -1; else newPerc = (int)((double)item->size() / (double)currentSize * 10000. + 0.5); int oldPerc = item->intPercent(); item->setPercent(newPerc); if (emitSig && newPerc != oldPerc) { emit changed(item); changeNr++; } if (item->isDir()) changeNr += calculatePercents(emitSig, dynamic_cast(item), depth + 1); } } if (depth == 0 && changeNr != 0) emit changeFinished(); return changeNr; } QString DiskUsage::getToolTip(File *item) { QMimeDatabase db; QMimeType mt = db.mimeTypeForName(item->mime()); QString mime; if (mt.isValid()) mime = mt.comment(); time_t tma = item->time(); struct tm* t = localtime((time_t *) & tma); QDateTime tmp(QDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday), QTime(t->tm_hour, t->tm_min)); QString date = QLocale().toString(tmp, QLocale::ShortFormat); QString str = "
" + "" + ""; if (item->isDir()) str += ""; str += "" + "" + "" + "
" + i18n("Name:") + "" + item->name() + "
" + i18n("Type:") + "" + mime + "
" + i18n("Size:") + "" + KRpermHandler::parseSize(item->size()) + "
" + i18n("Own size:") + "" + KRpermHandler::parseSize(item->ownSize()) + "
" + i18n("Last modified:") + "" + date + "
" + i18n("Permissions:") + "" + item->perm() + "
" + i18n("Owner:") + "" + item->owner() + " - " + item->group() + "
"; str.replace(' ', " "); return str; } void DiskUsage::setView(int view) { switch (view) { case VIEW_LINES: setCurrentWidget(lineView); break; case VIEW_DETAILED: setCurrentWidget(listView); break; case VIEW_FILELIGHT: setCurrentWidget(filelightView); break; case VIEW_LOADER: setCurrentWidget(loaderView); break; } // currentWidget()->setFocus(); emit viewChanged(activeView = view); } File * DiskUsage::getCurrentFile() { File * file = 0; switch (activeView) { case VIEW_LINES: file = lineView->getCurrentFile(); break; case VIEW_DETAILED: file = listView->getCurrentFile(); break; case VIEW_FILELIGHT: file = filelightView->getCurrentFile(); break; } return file; } bool DiskUsage::event(QEvent * e) { if (deleting) { // if we are deleting, disable the mouse and switch (e->type()) { // keyboard events case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: case QEvent::MouseButtonDblClick: case QEvent::MouseMove: case QEvent::KeyPress: case QEvent::KeyRelease: return true; default: break; } } if (e->type() == QEvent::ShortcutOverride) { QKeyEvent* ke = (QKeyEvent*) e; if (ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::KeypadModifier) { switch (ke->key()) { case Qt::Key_Delete: case Qt::Key_Plus: case Qt::Key_Minus: ke->accept(); break; } } else if (ke->modifiers() == Qt::ShiftModifier) { switch (ke->key()) { case Qt::Key_Left: case Qt::Key_Right: case Qt::Key_Up: case Qt::Key_Down: ke->accept(); break; } } else if (ke->modifiers() & Qt::ControlModifier) { switch (ke->key()) { case Qt::Key_D: case Qt::Key_E: case Qt::Key_F: case Qt::Key_I: case Qt::Key_L: case Qt::Key_N: case Qt::Key_R: ke->accept(); break; } } } return QStackedWidget::event(e); } diff --git a/krusader/DiskUsage/diskusage.h b/krusader/DiskUsage/diskusage.h index 85f7a30c..43a976d3 100644 --- a/krusader/DiskUsage/diskusage.h +++ b/krusader/DiskUsage/diskusage.h @@ -1,218 +1,218 @@ /*************************************************************************** diskusage.h - description ------------------- copyright : (C) 2004 by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DISKUSAGE_H #define DISKUSAGE_H // QtCore #include #include #include #include #include // QtGui #include #include #include // QtWidgets #include #include #include #include #include -#include "../VFS/vfs.h" +#include "../FileSystem/filesystem.h" #include "filelightParts/fileTree.h" #define VIEW_LINES 0 #define VIEW_DETAILED 1 #define VIEW_FILELIGHT 2 #define VIEW_LOADER 3 typedef QHash Properties; class DUListView; class DULines; class DUFilelight; class QMenu; class LoaderWidget; class DiskUsage : public QStackedWidget { Q_OBJECT public: DiskUsage(QString confGroup, QWidget *parent = 0); ~DiskUsage(); void load(const QUrl &dirName); void close(); void stopLoad(); bool isLoading() { return loading; } void setView(int view); int getActiveView() { return activeView; } Directory* getDirectory(QString path); File * getFile(QString path); QString getConfigGroup() { return configGroup; } void * getProperty(File *, QString); void addProperty(File *, QString, void *); void removeProperty(File *, QString); int exclude(File *file, bool calcPercents = true, int depth = 0); void includeAll(); int del(File *file, bool calcPercents = true, int depth = 0); QString getToolTip(File *); void rightClickMenu(const QPoint &, File *, QMenu * = 0, QString = QString()); void changeDirectory(Directory *dir); Directory* getCurrentDir(); File* getCurrentFile(); QPixmap getIcon(QString mime); QUrl getBaseURL() { return baseURL; } public slots: void dirUp(); void clear(); signals: void enteringDirectory(Directory *); void clearing(); void changed(File *); void changeFinished(); void deleted(File *); void deleteFinished(); void status(QString); void viewChanged(int); void loadFinished(bool); void newSearch(); protected slots: void slotLoadDirectory(); protected: QHash< QString, Directory * > contentMap; QHash< File *, Properties *> propertyMap; Directory* currentDirectory; KIO::filesize_t currentSize; virtual void keyPressEvent(QKeyEvent *) Q_DECL_OVERRIDE; virtual bool event(QEvent *) Q_DECL_OVERRIDE; int calculateSizes(Directory *dir = 0, bool emitSig = false, int depth = 0); int calculatePercents(bool emitSig = false, Directory *dir = 0 , int depth = 0); int include(Directory *dir, int depth = 0); void createStatus(); void executeAction(int, File * = 0); QUrl baseURL; //< the base URL of loading DUListView *listView; DULines *lineView; DUFilelight *filelightView; LoaderWidget *loaderView; Directory *root; int activeView; QString configGroup; bool first; bool loading; bool abortLoading; bool clearAfterAbort; bool deleting; QStack directoryStack; QStack parentStack; - vfs * searchVfs; - vfile * currentVfile; - QList vfiles; + FileSystem * searchFileSystem; + FileItem * currentFileItem; + QList fileItems; Directory * currentParent; QString dirToCheck; int fileNum; int dirNum; int viewBeforeLoad; QTimer loadingTimer; }; class LoaderWidget : public QScrollArea { Q_OBJECT public: LoaderWidget(QWidget *parent = 0); void init(); void setCurrentURL(const QUrl &url); void setValues(int fileNum, int dirNum, KIO::filesize_t total); bool wasCancelled() { return cancelled; } public slots: void slotCancelled(); protected: QLabel *totalSize; QLabel *files; QLabel *directories; KSqueezedTextLabel *searchedDirectory; QWidget *widget; bool cancelled; }; #endif /* __DISK_USAGE_GUI_H__ */ diff --git a/krusader/DiskUsage/diskusagegui.cpp b/krusader/DiskUsage/diskusagegui.cpp index b529e974..e4d98b39 100644 --- a/krusader/DiskUsage/diskusagegui.cpp +++ b/krusader/DiskUsage/diskusagegui.cpp @@ -1,250 +1,250 @@ /*************************************************************************** diskusagegui.cpp - description ------------------- copyright : (C) 2004 by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "diskusagegui.h" // QtCore #include // QtGui #include // QtWidgets #include #include #include #include #include #include #include #include "../kicons.h" #include "../krglobal.h" -#include "../VFS/vfs.h" +#include "../FileSystem/filesystem.h" #include "../Dialogs/krdialogs.h" DiskUsageGUI::DiskUsageGUI(QUrl openDir, QWidget* parent) : QDialog(parent), exitAtFailure(true) { setWindowTitle(i18n("Krusader::Disk Usage")); baseDirectory = openDir; if (!newSearch()) return; QVBoxLayout *mainLayout = new QVBoxLayout; setLayout(mainLayout); QGridLayout *duGrid = new QGridLayout(); duGrid->setSpacing(6); duGrid->setContentsMargins(11, 11, 11, 11); QWidget *duTools = new QWidget(this); QHBoxLayout *duHBox = new QHBoxLayout(duTools); duHBox->setContentsMargins(0, 0, 0, 0); duTools->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); btnNewSearch = new QToolButton(duTools); btnNewSearch->setIcon(QIcon(krLoader->loadIcon("document-open", KIconLoader::Desktop))); duHBox->addWidget(btnNewSearch); btnNewSearch->setToolTip(i18n("Start new disk usage search")); btnRefresh = new QToolButton(duTools); btnRefresh->setIcon(QIcon(krLoader->loadIcon("view-refresh", KIconLoader::Desktop))); duHBox->addWidget(btnRefresh); btnRefresh->setToolTip(i18n("Refresh")); btnDirUp = new QToolButton(duTools); btnDirUp->setIcon(QIcon(krLoader->loadIcon("go-up", KIconLoader::Desktop))); duHBox->addWidget(btnDirUp); btnDirUp->setToolTip(i18n("Parent folder")); QWidget * separatorWidget = new QWidget(duTools); separatorWidget->setMinimumWidth(10); duHBox->addWidget(separatorWidget); btnLines = new QToolButton(duTools); btnLines->setIcon(QIcon(krLoader->loadIcon("view-list-details", KIconLoader::Desktop))); btnLines->setCheckable(true); duHBox->addWidget(btnLines); btnLines->setToolTip(i18n("Line view")); btnDetailed = new QToolButton(duTools); btnDetailed->setIcon(QIcon(krLoader->loadIcon("view-list-tree", KIconLoader::Desktop))); btnDetailed->setCheckable(true); duHBox->addWidget(btnDetailed); btnDetailed->setToolTip(i18n("Detailed view")); btnFilelight = new QToolButton(duTools); btnFilelight->setIcon(QIcon(krLoader->loadIcon("kr_diskusage", KIconLoader::Desktop))); btnFilelight->setCheckable(true); duHBox->addWidget(btnFilelight); btnFilelight->setToolTip(i18n("Filelight view")); QWidget *spacerWidget = new QWidget(duTools); duHBox->addWidget(spacerWidget); QHBoxLayout *hboxlayout = new QHBoxLayout(spacerWidget); QSpacerItem* spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed); hboxlayout->addItem(spacer); duGrid->addWidget(duTools, 0, 0); diskUsage = new DiskUsage("DiskUsage", this); duGrid->addWidget(diskUsage, 1, 0); status = new KSqueezedTextLabel(this); duGrid->addWidget(status, 2, 0); mainLayout->addLayout(duGrid); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); mainLayout->addWidget(buttonBox); connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); connect(diskUsage, SIGNAL(status(QString)), this, SLOT(setStatus(QString))); connect(diskUsage, SIGNAL(viewChanged(int)), this, SLOT(slotViewChanged(int))); connect(diskUsage, SIGNAL(newSearch()), this, SLOT(newSearch())); connect(diskUsage, SIGNAL(loadFinished(bool)), this, SLOT(slotLoadFinished(bool))); connect(btnNewSearch, SIGNAL(clicked()), this, SLOT(newSearch())); connect(btnRefresh, SIGNAL(clicked()), this, SLOT(loadUsageInfo())); connect(btnDirUp, SIGNAL(clicked()), diskUsage, SLOT(dirUp())); connect(btnLines, SIGNAL(clicked()), this, SLOT(selectLinesView())); connect(btnDetailed, SIGNAL(clicked()), this, SLOT(selectListView())); connect(btnFilelight, SIGNAL(clicked()), this, SLOT(selectFilelightView())); KConfigGroup group(krConfig, "DiskUsage"); int view = group.readEntry("View", VIEW_LINES); if (view < VIEW_LINES || view > VIEW_FILELIGHT) view = VIEW_LINES; diskUsage->setView(view); sizeX = group.readEntry("Window Width", QFontMetrics(font()).width("W") * 70); sizeY = group.readEntry("Window Height", QFontMetrics(font()).height() * 25); resize(sizeX, sizeY); if (group.readEntry("Window Maximized", false)) showMaximized(); else show(); exec(); } DiskUsageGUI::~DiskUsageGUI() { } void DiskUsageGUI::slotLoadFinished(bool result) { if (exitAtFailure && !result) reject(); else exitAtFailure = false; } void DiskUsageGUI::enableButtons(bool isOn) { btnNewSearch->setEnabled(isOn); btnRefresh->setEnabled(isOn); btnDirUp->setEnabled(isOn); btnLines->setEnabled(isOn); btnDetailed->setEnabled(isOn); btnFilelight->setEnabled(isOn); } void DiskUsageGUI::resizeEvent(QResizeEvent *e) { if (!isMaximized()) { sizeX = e->size().width(); sizeY = e->size().height(); } QDialog::resizeEvent(e); } void DiskUsageGUI::reject() { KConfigGroup group(krConfig, "DiskUsage"); group.writeEntry("Window Width", sizeX); group.writeEntry("Window Height", sizeY); group.writeEntry("Window Maximized", isMaximized()); group.writeEntry("View", diskUsage->getActiveView()); QDialog::reject(); } void DiskUsageGUI::loadUsageInfo() { diskUsage->load(baseDirectory); } void DiskUsageGUI::setStatus(QString stat) { status->setText(stat); } void DiskUsageGUI::slotViewChanged(int view) { if (view == VIEW_LOADER) { enableButtons(false); return; } enableButtons(true); btnLines->setChecked(false); btnDetailed->setChecked(false); btnFilelight->setChecked(false); switch (view) { case VIEW_LINES: btnLines->setChecked(true); break; case VIEW_DETAILED: btnDetailed->setChecked(true); break; case VIEW_FILELIGHT: btnFilelight->setChecked(true); break; case VIEW_LOADER: break; } } bool DiskUsageGUI::newSearch() { // ask the user for the copy dest QUrl tmp = KChooseDir::getDir(i18n("Viewing the usage of folder:"), baseDirectory, baseDirectory); if (tmp.isEmpty()) return false; baseDirectory = tmp; QTimer::singleShot(0, this, SLOT(loadUsageInfo())); return true; } diff --git a/krusader/DiskUsage/dulines.cpp b/krusader/DiskUsage/dulines.cpp index e80f29c7..27dbda2e 100644 --- a/krusader/DiskUsage/dulines.cpp +++ b/krusader/DiskUsage/dulines.cpp @@ -1,544 +1,544 @@ /*************************************************************************** dulines.cpp - description ------------------- copyright : (C) 2004 by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "dulines.h" #include "../kicons.h" #include "../krglobal.h" -#include "../VFS/krpermhandler.h" +#include "../FileSystem/krpermhandler.h" // QtCore #include // QtGui #include #include #include #include #include #include // QtWidgets #include #include #include #include #include #include #include class DULinesItemDelegate : public QItemDelegate { public: DULinesItemDelegate(QObject *parent = 0) : QItemDelegate(parent) {} virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE { QItemDelegate::paint(painter, option, index); QVariant value = index.data(Qt::UserRole); if (value.isValid()) { QString text = value.toString(); value = index.data(Qt::DisplayRole); QString display; if (value.isValid()) display = value.toString(); QSize iconSize; value = index.data(Qt::DecorationRole); if (value.isValid()) iconSize = qvariant_cast(value).actualSize(option.decorationSize); painter->save(); painter->setClipRect(option.rect); QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; if (cg == QPalette::Normal && !(option.state & QStyle::State_Active)) cg = QPalette::Inactive; if (option.state & QStyle::State_Selected) { painter->setPen(option.palette.color(cg, QPalette::HighlightedText)); } else { painter->setPen(option.palette.color(cg, QPalette::Text)); } QFont fnt = option.font; fnt.setItalic(true); painter->setFont(fnt); QFontMetrics fm(fnt); QString renderedText = text; int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin); int pos = 3 * textMargin + option.fontMetrics.width(display) + iconSize.width(); bool truncd = false; QRect rct = option.rect; if (rct.width() > pos) { rct.setX(rct.x() + pos); if (fm.width(renderedText) > rct.width()) { truncd = true; int points = fm.width("..."); while (!renderedText.isEmpty() && (fm.width(renderedText) + points > rct.width())) renderedText.truncate(renderedText.length() - 1); renderedText += "..."; } painter->drawText(rct, Qt::AlignLeft, renderedText); } else truncd = true; if (truncd) ((QAbstractItemModel *)index.model())->setData(index, QVariant(display + " " + text), Qt::ToolTipRole); else ((QAbstractItemModel *)index.model())->setData(index, QVariant(), Qt::ToolTipRole); painter->restore(); } } }; class DULinesItem : public QTreeWidgetItem { public: DULinesItem(DiskUsage *diskUsageIn, File *fileItem, QTreeWidget * parent, QString label1, QString label2, QString label3) : QTreeWidgetItem(parent), diskUsage(diskUsageIn), file(fileItem) { setText(0, label1); setText(1, label2); setText(2, label3); setTextAlignment(1, Qt::AlignRight); } DULinesItem(DiskUsage *diskUsageIn, File *fileItem, QTreeWidget * parent, QTreeWidgetItem * after, QString label1, QString label2, QString label3) : QTreeWidgetItem(parent, after), diskUsage(diskUsageIn), file(fileItem) { setText(0, label1); setText(1, label2); setText(2, label3); setTextAlignment(1, Qt::AlignRight); } virtual bool operator<(const QTreeWidgetItem &other) const Q_DECL_OVERRIDE { int column = treeWidget() ? treeWidget()->sortColumn() : 0; if (text(0) == "..") return true; const DULinesItem *compWith = dynamic_cast< const DULinesItem * >(&other); if (compWith == 0) return false; switch (column) { case 0: case 1: return file->size() > compWith->file->size(); default: return text(column) < other.text(column); } } inline File * getFile() { return file; } private: DiskUsage *diskUsage; File *file; }; DULines::DULines(DiskUsage *usage) : KrTreeWidget(usage), diskUsage(usage), refreshNeeded(false), started(false) { setItemDelegate(itemDelegate = new DULinesItemDelegate()); setAllColumnsShowFocus(true); setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); setIndentation(10); int defaultSize = QFontMetrics(font()).width("W"); QStringList labels; labels << i18n("Line View"); labels << i18n("Percent"); labels << i18n("Name"); setHeaderLabels(labels); header()->setSectionResizeMode(QHeaderView::Interactive); KConfigGroup group(krConfig, diskUsage->getConfigGroup()); showFileSize = group.readEntry("L Show File Size", true); if (group.hasKey("L State")) header()->restoreState(group.readEntry("L State", QByteArray())); else { setColumnWidth(0, defaultSize * 20); setColumnWidth(1, defaultSize * 6); setColumnWidth(2, defaultSize * 20); } setStretchingColumn(0); header()->setSortIndicatorShown(true); sortItems(1, Qt::AscendingOrder); // toolTip = new DULinesToolTip( diskUsage, viewport(), this ); connect(diskUsage, SIGNAL(enteringDirectory(Directory *)), this, SLOT(slotDirChanged(Directory *))); connect(diskUsage, SIGNAL(clearing()), this, SLOT(clear())); connect(header(), SIGNAL(sectionResized(int, int, int)), this, SLOT(sectionResized(int))); connect(this, SIGNAL(itemRightClicked(QTreeWidgetItem*, const QPoint &, int)), this, SLOT(slotRightClicked(QTreeWidgetItem *, const QPoint &))); connect(diskUsage, SIGNAL(changed(File *)), this, SLOT(slotChanged(File *))); connect(diskUsage, SIGNAL(deleted(File *)), this, SLOT(slotDeleted(File *))); started = true; } DULines::~DULines() { KConfigGroup group(krConfig, diskUsage->getConfigGroup()); group.writeEntry("L State", header()->saveState()); delete itemDelegate; } bool DULines::event(QEvent * event) { switch (event->type()) { case QEvent::ToolTip: { QHelpEvent *he = static_cast(event); if (viewport()) { QPoint pos = viewport()->mapFromGlobal(he->globalPos()); QTreeWidgetItem * item = itemAt(pos); int column = columnAt(pos.x()); if (item && column == 1) { File *fileItem = ((DULinesItem *)item)->getFile(); QToolTip::showText(he->globalPos(), diskUsage->getToolTip(fileItem), this); return true; } } } break; default: break; } return KrTreeWidget::event(event); } void DULines::slotDirChanged(Directory *dirEntry) { clear(); QTreeWidgetItem * lastItem = 0; if (!(dirEntry->parent() == 0)) { lastItem = new QTreeWidgetItem(this); lastItem->setText(0, ".."); lastItem->setIcon(0, FL_LOADICON("go-up")); lastItem->setFlags(lastItem->flags() & (~Qt::ItemIsSelectable)); } int maxPercent = -1; for (Iterator it = dirEntry->iterator(); it != dirEntry->end(); ++it) { File *item = *it; if (!item->isExcluded() && item->intPercent() > maxPercent) maxPercent = item->intPercent(); } for (Iterator it = dirEntry->iterator(); it != dirEntry->end(); ++it) { File *item = *it; QString fileName = item->name(); if (lastItem == 0) lastItem = new DULinesItem(diskUsage, item, this, "", item->percent() + " ", fileName); else lastItem = new DULinesItem(diskUsage, item, this, lastItem, "", item->percent() + " ", fileName); if (item->isExcluded()) lastItem->setHidden(true); int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; lastItem->setIcon(2, diskUsage->getIcon(item->mime())); lastItem->setData(0, Qt::DecorationRole, createPixmap(item->intPercent(), maxPercent, header()->sectionSize(0) - 2 * textMargin)); if (showFileSize) lastItem->setData(2, Qt::UserRole, " [" + KIO::convertSize(item->size()) + ']'); QSize size = lastItem->sizeHint(0); size.setWidth(16); lastItem->setSizeHint(0, size); } if (topLevelItemCount() > 0) { setCurrentItem(topLevelItem(0)); } } QPixmap DULines::createPixmap(int percent, int maxPercent, int maxWidth) { if (percent < 0 || percent > maxPercent || maxWidth < 2 || maxPercent == 0) return QPixmap(); maxWidth -= 2; int actualWidth = maxWidth * percent / maxPercent; if (actualWidth == 0) return QPixmap(); QPen pen; pen.setColor(Qt::black); QPainter painter; int size = QFontMetrics(font()).height() - 2; QRect rect(0, 0, actualWidth, size); QRect frameRect(0, 0, actualWidth - 1, size - 1); QPixmap pixmap(rect.width(), rect.height()); painter.begin(&pixmap); painter.setPen(pen); for (int i = 1; i < actualWidth - 1; i++) { int color = (511 * i / (maxWidth - 1)); if (color < 256) pen.setColor(QColor(255 - color, 255, 0)); else pen.setColor(QColor(color - 256, 511 - color, 0)); painter.setPen(pen); painter.drawLine(i, 1, i, size - 1); } pen.setColor(Qt::black); painter.setPen(pen); if (actualWidth != 1) painter.drawRect(frameRect); else painter.drawLine(0, 0, 0, size); painter.end(); pixmap.detach(); return pixmap; } void DULines::resizeEvent(QResizeEvent * re) { KrTreeWidget::resizeEvent(re); if (started && (re->oldSize() != re->size())) sectionResized(0); } void DULines::sectionResized(int column) { if (topLevelItemCount() == 0 || column != 0) return; Directory * currentDir = diskUsage->getCurrentDir(); if (currentDir == 0) return; int maxPercent = -1; for (Iterator it = currentDir->iterator(); it != currentDir->end(); ++it) { File *item = *it; if (!item->isExcluded() && item->intPercent() > maxPercent) maxPercent = item->intPercent(); } QTreeWidgetItemIterator it2(this); while (*it2) { QTreeWidgetItem *lvitem = *it2; if (lvitem->text(0) != "..") { DULinesItem *duItem = dynamic_cast< DULinesItem *>(lvitem); if (duItem) { int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; duItem->setData(0, Qt::DecorationRole, createPixmap(duItem->getFile()->intPercent(), maxPercent, header()->sectionSize(0) - 2 * textMargin)); QSize size = duItem->sizeHint(0); size.setWidth(16); duItem->setSizeHint(0, size); } } it2++; } } bool DULines::doubleClicked(QTreeWidgetItem * item) { if (item) { if (item->text(0) != "..") { File *fileItem = ((DULinesItem *)item)->getFile(); if (fileItem->isDir()) diskUsage->changeDirectory(dynamic_cast(fileItem)); return true; } else { Directory *upDir = (Directory *)diskUsage->getCurrentDir()->parent(); if (upDir) diskUsage->changeDirectory(upDir); return true; } } return false; } void DULines::mouseDoubleClickEvent(QMouseEvent * e) { if (e || e->button() == Qt::LeftButton) { QPoint vp = viewport()->mapFromGlobal(e->globalPos()); QTreeWidgetItem * item = itemAt(vp); if (doubleClicked(item)) return; } KrTreeWidget::mouseDoubleClickEvent(e); } void DULines::keyPressEvent(QKeyEvent *e) { switch (e->key()) { case Qt::Key_Return : case Qt::Key_Enter : if (doubleClicked(currentItem())) return; break; case Qt::Key_Left : case Qt::Key_Right : case Qt::Key_Up : case Qt::Key_Down : if (e->modifiers() == Qt::ShiftModifier) { e->ignore(); return; } break; case Qt::Key_Delete : e->ignore(); return; } KrTreeWidget::keyPressEvent(e); } void DULines::slotRightClicked(QTreeWidgetItem *item, const QPoint &pos) { File * file = 0; if (item && item->text(0) != "..") file = ((DULinesItem *)item)->getFile(); QMenu linesPopup; QAction *act = linesPopup.addAction(i18n("Show file sizes"), this, SLOT(slotShowFileSizes())); act->setChecked(showFileSize); diskUsage->rightClickMenu(pos, file, &linesPopup, i18n("Lines")); } void DULines::slotShowFileSizes() { showFileSize = !showFileSize; slotDirChanged(diskUsage->getCurrentDir()); } File * DULines::getCurrentFile() { QTreeWidgetItem *item = currentItem(); if (item == 0 || item->text(0) == "..") return 0; return ((DULinesItem *)item)->getFile(); } void DULines::slotChanged(File * item) { QTreeWidgetItemIterator it(this); while (*it) { QTreeWidgetItem *lvitem = *it; it++; if (lvitem->text(0) != "..") { DULinesItem *duItem = (DULinesItem *)(lvitem); if (duItem->getFile() == item) { setSortingEnabled(false); duItem->setHidden(item->isExcluded()); duItem->setText(1, item->percent()); if (!refreshNeeded) { refreshNeeded = true; QTimer::singleShot(0, this, SLOT(slotRefresh())); } break; } } } } void DULines::slotDeleted(File * item) { QTreeWidgetItemIterator it(this); while (*it) { QTreeWidgetItem *lvitem = *it; it++; if (lvitem->text(0) != "..") { DULinesItem *duItem = (DULinesItem *)(lvitem); if (duItem->getFile() == item) { delete duItem; break; } } } } void DULines::slotRefresh() { if (refreshNeeded) { refreshNeeded = false; setSortingEnabled(true); sortItems(1, Qt::AscendingOrder); } } diff --git a/krusader/DiskUsage/dulistview.cpp b/krusader/DiskUsage/dulistview.cpp index 5e9ecafb..939effab 100644 --- a/krusader/DiskUsage/dulistview.cpp +++ b/krusader/DiskUsage/dulistview.cpp @@ -1,283 +1,283 @@ /*************************************************************************** dulistview.cpp - description ------------------- copyright : (C) 2004 by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "dulistview.h" #include "../krglobal.h" #include "../kicons.h" -#include "../VFS/krpermhandler.h" +#include "../FileSystem/krpermhandler.h" // QtCore #include #include // QtGui #include #include #include // QtWidgets #include #include #include DUListView::DUListView(DiskUsage *usage) : KrTreeWidget(usage), diskUsage(usage) { setAllColumnsShowFocus(true); setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); setRootIsDecorated(true); setIndentation(10); setItemsExpandable(true); QStringList labels; labels << i18n("Name"); labels << i18n("Percent"); labels << i18n("Total size"); labels << i18n("Own size"); labels << i18n("Type"); labels << i18n("Date"); labels << i18n("Permissions"); labels << i18n("Owner"); labels << i18n("Group"); setHeaderLabels(labels); header()->setSectionResizeMode(QHeaderView::Interactive); KConfigGroup group(krConfig, diskUsage->getConfigGroup()); if (group.hasKey("D State")) header()->restoreState(group.readEntry("D State", QByteArray())); else { int defaultSize = QFontMetrics(font()).width("W"); setColumnWidth(0, defaultSize * 20); setColumnWidth(1, defaultSize * 5); setColumnWidth(2, defaultSize * 10); setColumnWidth(3, defaultSize * 10); setColumnWidth(4, defaultSize * 10); setColumnWidth(5, defaultSize * 10); setColumnWidth(6, defaultSize * 6); setColumnWidth(7, defaultSize * 5); setColumnWidth(8, defaultSize * 5); } header()->setSortIndicatorShown(true); sortItems(2, Qt::AscendingOrder); connect(diskUsage, SIGNAL(enteringDirectory(Directory *)), this, SLOT(slotDirChanged(Directory *))); connect(diskUsage, SIGNAL(clearing()), this, SLOT(clear())); connect(diskUsage, SIGNAL(changed(File *)), this, SLOT(slotChanged(File *))); connect(diskUsage, SIGNAL(deleted(File *)), this, SLOT(slotDeleted(File *))); connect(this, SIGNAL(itemRightClicked(QTreeWidgetItem*, const QPoint &, int)), this, SLOT(slotRightClicked(QTreeWidgetItem *, const QPoint &))); connect(this, SIGNAL(itemExpanded(QTreeWidgetItem *)), this, SLOT(slotExpanded(QTreeWidgetItem *))); } DUListView::~ DUListView() { KConfigGroup group(krConfig, diskUsage->getConfigGroup()); group.writeEntry("D State", header()->saveState()); } void DUListView::addDirectory(Directory *dirEntry, QTreeWidgetItem *parent) { QTreeWidgetItem * lastItem = 0; if (parent == 0 && !(dirEntry->parent() == 0)) { lastItem = new QTreeWidgetItem(this); lastItem->setText(0, ".."); lastItem->setIcon(0, FL_LOADICON("go-up")); lastItem->setFlags(Qt::ItemIsEnabled); } for (Iterator it = dirEntry->iterator(); it != dirEntry->end(); ++it) { File *item = *it; QMimeDatabase db; QMimeType mt = db.mimeTypeForName(item->mime()); QString mime; if (mt.isValid()) mime = mt.comment(); time_t tma = item->time(); struct tm* t = localtime((time_t *) & tma); QDateTime tmp(QDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday), QTime(t->tm_hour, t->tm_min)); QString date = QLocale().toString(tmp, QLocale::ShortFormat); QString totalSize = KRpermHandler::parseSize(item->size()) + ' '; QString ownSize = KRpermHandler::parseSize(item->ownSize()) + ' '; QString percent = item->percent(); if (lastItem == 0 && parent == 0) lastItem = new DUListViewItem(diskUsage, item, this, item->name(), percent, totalSize, ownSize, mime, date, item->perm(), item->owner(), item->group()); else if (lastItem == 0) lastItem = new DUListViewItem(diskUsage, item, parent, item->name(), percent, totalSize, ownSize, mime, date, item->perm(), item->owner(), item->group()); else if (parent == 0) lastItem = new DUListViewItem(diskUsage, item, this, lastItem, item->name(), percent, totalSize, ownSize, mime, date, item->perm(), item->owner(), item->group()); else lastItem = new DUListViewItem(diskUsage, item, parent, lastItem, item->name(), percent, totalSize, ownSize, mime, date, item->perm(), item->owner(), item->group()); if (item->isExcluded()) lastItem->setHidden(true); lastItem->setIcon(0, diskUsage->getIcon(item->mime())); if (item->isDir() && !item->isSymLink()) lastItem->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator); } if (topLevelItemCount() > 0) { setCurrentItem(topLevelItem(0)); } } void DUListView::slotDirChanged(Directory *dirEntry) { clear(); addDirectory(dirEntry, 0); } File * DUListView::getCurrentFile() { QTreeWidgetItem *item = currentItem(); if (item == 0 || item->text(0) == "..") return 0; return ((DUListViewItem *)item)->getFile(); } void DUListView::slotChanged(File * item) { void * itemPtr = diskUsage->getProperty(item, "ListView-Ref"); if (itemPtr == 0) return; DUListViewItem *duItem = (DUListViewItem *)itemPtr; duItem->setHidden(item->isExcluded()); duItem->setText(1, item->percent()); duItem->setText(2, KRpermHandler::parseSize(item->size()) + ' '); duItem->setText(3, KRpermHandler::parseSize(item->ownSize()) + ' '); } void DUListView::slotDeleted(File * item) { void * itemPtr = diskUsage->getProperty(item, "ListView-Ref"); if (itemPtr == 0) return; DUListViewItem *duItem = (DUListViewItem *)itemPtr; delete duItem; } void DUListView::slotRightClicked(QTreeWidgetItem *item, const QPoint & pos) { File * file = 0; if (item && item->text(0) != "..") file = ((DUListViewItem *)item)->getFile(); diskUsage->rightClickMenu(pos, file); } bool DUListView::doubleClicked(QTreeWidgetItem * item) { if (item) { if (item->text(0) != "..") { File *fileItem = ((DUListViewItem *)item)->getFile(); if (fileItem->isDir()) diskUsage->changeDirectory(dynamic_cast(fileItem)); return true; } else { Directory *upDir = (Directory *)diskUsage->getCurrentDir()->parent(); if (upDir) diskUsage->changeDirectory(upDir); return true; } } return false; } void DUListView::mouseDoubleClickEvent(QMouseEvent * e) { if (e || e->button() == Qt::LeftButton) { QPoint vp = viewport()->mapFromGlobal(e->globalPos()); QTreeWidgetItem * item = itemAt(vp); if (doubleClicked(item)) return; } KrTreeWidget::mouseDoubleClickEvent(e); } void DUListView::keyPressEvent(QKeyEvent *e) { switch (e->key()) { case Qt::Key_Return : case Qt::Key_Enter : if (doubleClicked(currentItem())) return; break; case Qt::Key_Left : case Qt::Key_Right : case Qt::Key_Up : case Qt::Key_Down : if (e->modifiers() == Qt::ShiftModifier) { e->ignore(); return; } break; case Qt::Key_Delete : e->ignore(); return; } KrTreeWidget::keyPressEvent(e); } void DUListView::slotExpanded(QTreeWidgetItem * item) { if (item == 0 || item->text(0) == "..") return; if (item->childCount() == 0) { File *fileItem = ((DUListViewItem *)item)->getFile(); if (fileItem->isDir()) addDirectory(dynamic_cast(fileItem), item); } } diff --git a/krusader/FileSystem/CMakeLists.txt b/krusader/FileSystem/CMakeLists.txt new file mode 100644 index 00000000..5ac61612 --- /dev/null +++ b/krusader/FileSystem/CMakeLists.txt @@ -0,0 +1,26 @@ +include_directories(${KF5_INCLUDES_DIRS} ${QT_INCLUDES}) + +set(FileSystem_SRCS + defaultfilesystem.cpp + dirlisterinterface.cpp + fileitem.cpp + filesystem.cpp + filesystemprovider.cpp + krpermhandler.cpp + krquery.cpp + krtrashhandler.cpp + virtualfilesystem.cpp + ../../krArc/krlinecountingprocess.cpp +) + +add_library(FileSystem STATIC ${FileSystem_SRCS}) + +target_link_libraries(FileSystem + KF5::I18n + KF5::KIOCore + KF5::KIOWidgets +) + +if(ACL_FOUND) + target_link_libraries(FileSystem ${ACL_LIBS}) +endif(ACL_FOUND) diff --git a/krusader/VFS/default_vfs.cpp b/krusader/FileSystem/defaultfilesystem.cpp similarity index 78% rename from krusader/VFS/default_vfs.cpp rename to krusader/FileSystem/defaultfilesystem.cpp index 59fcf562..46625b6c 100644 --- a/krusader/VFS/default_vfs.cpp +++ b/krusader/FileSystem/defaultfilesystem.cpp @@ -1,387 +1,387 @@ /*************************************************************************** - default_vfs.cpp + defaultfilesystem.cpp ------------------- copyright : (C) 2000 by Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ -#include "default_vfs.h" +#include "defaultfilesystem.h" // QtCore #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../defaults.h" #include "../krglobal.h" #include "../krservices.h" #include "../JobMan/jobman.h" #include "../JobMan/krjob.h" -default_vfs::default_vfs(): vfs(), _watcher() +DefaultFileSystem::DefaultFileSystem(): FileSystem(), _watcher() { - _type = VFS_DEFAULT; + _type = FS_DEFAULT; } -void default_vfs::copyFiles(const QList &urls, const QUrl &destination, +void DefaultFileSystem::copyFiles(const QList &urls, const QUrl &destination, KIO::CopyJob::CopyMode mode, bool showProgressInfo, bool reverseQueueMode, bool startPaused) { // resolve relative path before resolving symlinks const QUrl dest = resolveRelativePath(destination); KIO::JobFlags flags = showProgressInfo ? KIO::DefaultFlags : KIO::HideProgressInfo; // allow job to be started only manually when startPaused=true AND queueMode=false bool queueMode = krJobMan->isQueueModeEnabled() != reverseQueueMode; KrJob *krJob = KrJob::createCopyJob(mode, urls, destination, flags, startPaused && !queueMode); connect(krJob, &KrJob::started, [=](KIO::Job *job) { connectJob(job, dest); }); if (mode == KIO::CopyJob::Move) { // notify source about removed files - connect(krJob, &KrJob::started, [=](KIO::Job *job) { connectSourceVFS(job, urls); }); + connect(krJob, &KrJob::started, [=](KIO::Job *job) { connectSourceFileSystem(job, urls); }); } krJobMan->manageJob(krJob, reverseQueueMode, startPaused); } -void default_vfs::dropFiles(const QUrl &destination, QDropEvent *event) +void DefaultFileSystem::dropFiles(const QUrl &destination, QDropEvent *event) { // resolve relative path before resolving symlinks const QUrl dest = resolveRelativePath(destination); KIO::DropJob *job = KIO::drop(event, dest); // NOTE: DropJob does not provide information about the actual user choice // (move/copy/link/abort). We have to assume the worst (move) connectJob(job, dest); - connectSourceVFS(job, KUrlMimeData::urlsFromMimeData(event->mimeData())); + connectSourceFileSystem(job, KUrlMimeData::urlsFromMimeData(event->mimeData())); // NOTE: DrobJobs are internally recorded //recordJobUndo(job, type, dst, src); } -void default_vfs::connectSourceVFS(KJob *job, const QList urls) +void DefaultFileSystem::connectSourceFileSystem(KJob *job, const QList urls) { if (!urls.isEmpty()) { // NOTE: we assume that all files were in the same directory and only emit one signal for // the directory of the first file URL const QUrl url = urls.first().adjusted(QUrl::RemoveFilename); - connect(job, &KIO::Job::result, [=]() { emit filesystemChanged(url); }); + connect(job, &KIO::Job::result, [=]() { emit fileSystemChanged(url); }); } } -void default_vfs::addFiles(const QList &fileUrls, KIO::CopyJob::CopyMode mode, QString dir) +void DefaultFileSystem::addFiles(const QList &fileUrls, KIO::CopyJob::CopyMode mode, QString dir) { QUrl destination(_currentDirectory); if (!dir.isEmpty()) { destination.setPath(QDir::cleanPath(destination.path() + '/' + dir)); const QString scheme = destination.scheme(); if (scheme == "tar" || scheme == "zip" || scheme == "krarc") { if (QDir(cleanUrl(destination).path()).exists()) // if we get out from the archive change the protocol destination.setScheme("file"); } } copyFiles(fileUrls, destination, mode); } -void default_vfs::mkDir(const QString &name) +void DefaultFileSystem::mkDir(const QString &name) { KIO::SimpleJob* job = KIO::mkdir(getUrl(name)); connectJob(job, currentDirectory()); } -void default_vfs::rename(const QString &oldName, const QString &newName) +void DefaultFileSystem::rename(const QString &oldName, const QString &newName) { const QUrl oldUrl = getUrl(oldName); const QUrl newUrl = getUrl(newName); KIO::Job *job = KIO::moveAs(oldUrl, newUrl, KIO::HideProgressInfo); connectJob(job, currentDirectory()); KIO::FileUndoManager::self()->recordJob(KIO::FileUndoManager::Rename, {oldUrl}, newUrl, job); } -QUrl default_vfs::getUrl(const QString& name) +QUrl DefaultFileSystem::getUrl(const QString& name) { // NOTE: on non-local fs file URL does not have to be path + name! - vfile *vf = getVfile(name); - if (vf) - return vf->vfile_getUrl(); + FileItem *fileItem = getFileItem(name); + if (fileItem) + return fileItem->getUrl(); QUrl absoluteUrl(_currentDirectory); absoluteUrl.setPath(absoluteUrl.path() + "/" + name); return absoluteUrl; } -void default_vfs::updateFilesystemInfo() +void DefaultFileSystem::updateFilesystemInfo() { if (!KConfigGroup(krConfig, "Look&Feel").readEntry("ShowSpaceInformation", true)) { _mountPoint = ""; - emit filesystemInfoChanged(i18n("Space information disabled"), "", 0, 0); + emit fileSystemInfoChanged(i18n("Space information disabled"), "", 0, 0); return; } if (!_currentDirectory.isLocalFile()) { _mountPoint = ""; - emit filesystemInfoChanged(i18n("No space information on non-local filesystems"), "", 0, 0); + emit fileSystemInfoChanged(i18n("No space information on non-local filesystems"), "", 0, 0); return; } const QString path = _currentDirectory.path(); const KDiskFreeSpaceInfo info = KDiskFreeSpaceInfo::freeSpaceInfo(path); if (!info.isValid()) { _mountPoint = ""; - emit filesystemInfoChanged(i18n("Space information unavailable"), "", 0, 0); + emit fileSystemInfoChanged(i18n("Space information unavailable"), "", 0, 0); return; } _mountPoint = info.mountPoint(); const KMountPoint::Ptr mountPoint = KMountPoint::currentMountPoints().findByPath(path); const QString fsType = mountPoint ? mountPoint->mountType() : ""; - emit filesystemInfoChanged("", fsType, info.size(), info.available()); + emit fileSystemInfoChanged("", fsType, info.size(), info.available()); } // ==== protected ==== -bool default_vfs::refreshInternal(const QUrl &directory, bool showHidden) +bool DefaultFileSystem::refreshInternal(const QUrl &directory, bool showHidden) { if (!KProtocolManager::supportsListing(directory)) { emit error(i18n("Protocol not supported by Krusader:\n%1", directory.url())); return false; } delete _watcher; // stop watching the old dir if (directory.isLocalFile()) { // we could read local directories with KIO but using Qt is a lot faster! return refreshLocal(directory); } _currentDirectory = cleanUrl(directory); // start the listing job KIO::ListJob *job = KIO::listDir(_currentDirectory, KIO::HideProgressInfo, showHidden); - connect(job, &KIO::ListJob::entries, this, &default_vfs::slotAddFiles); - connect(job, &KIO::ListJob::redirection, this, &default_vfs::slotRedirection); - connect(job, &KIO::ListJob::permanentRedirection, this, &default_vfs::slotRedirection); - connect(job, &KIO::Job::result, this, &default_vfs::slotListResult); + connect(job, &KIO::ListJob::entries, this, &DefaultFileSystem::slotAddFiles); + connect(job, &KIO::ListJob::redirection, this, &DefaultFileSystem::slotRedirection); + connect(job, &KIO::ListJob::permanentRedirection, this, &DefaultFileSystem::slotRedirection); + connect(job, &KIO::Job::result, this, &DefaultFileSystem::slotListResult); // ensure connection credentials are asked only once if(!parentWindow.isNull()) { KIO::JobUiDelegate *ui = static_cast(job->uiDelegate()); ui->setWindow(parentWindow); } emit refreshJobStarted(job); _listError = false; // ugly: we have to wait here until the list job is finished QEventLoop eventLoop; connect(job, &KJob::finished, &eventLoop, &QEventLoop::quit); eventLoop.exec(); // blocking until quit() return !_listError; } // ==== protected slots ==== -void default_vfs::slotListResult(KJob *job) +void DefaultFileSystem::slotListResult(KJob *job) { if (job && job->error()) { // we failed to refresh _listError = true; emit error(job->errorString()); // display error message (in panel) } } -void default_vfs::slotAddFiles(KIO::Job *, const KIO::UDSEntryList& entries) +void DefaultFileSystem::slotAddFiles(KIO::Job *, const KIO::UDSEntryList& entries) { for (const KIO::UDSEntry entry : entries) { - vfile *vfile = vfs::createVFileFromKIO(entry, _currentDirectory); - if (vfile) { - addVfile(vfile); + FileItem *fileItem = FileSystem::createFileItemFromKIO(entry, _currentDirectory); + if (fileItem) { + addFileItem(fileItem); } } } -void default_vfs::slotRedirection(KIO::Job *job, const QUrl &url) +void DefaultFileSystem::slotRedirection(KIO::Job *job, const QUrl &url) { - krOut << "default_vfs; redirection to " << url; + krOut << "redirection to " << url; // some protocols (zip, tar) send redirect to local URL without scheme const QUrl newUrl = preferLocalUrl(url); if (newUrl.scheme() != _currentDirectory.scheme()) { // abort and start over again, // some protocols (iso, zip, tar) do this on transition to local fs job->kill(); _isRefreshing = false; refresh(newUrl); return; } _currentDirectory = cleanUrl(newUrl); } -void default_vfs::slotWatcherDirty(const QString& path) +void DefaultFileSystem::slotWatcherDirty(const QString& path) { if (path == realPath()) { // this happens // 1. if a directory was created/deleted/renamed inside this directory. No deleted // 2. during and after a file operation (create/delete/rename/touch) inside this directory // KDirWatcher doesn't reveal the name of changed directories and we have to refresh. // (QFileSystemWatcher in Qt5.7 can't help here either) refresh(); return; } const QString name = QUrl::fromLocalFile(path).fileName(); - vfile *vf = getVfile(name); - if (!vf) { + FileItem *fileItem = getFileItem(name); + if (!fileItem) { krOut << "dirty watcher file not found (unexpected): " << path; // this happens at least for cifs mounted filesystems: when a new file is created, a dirty // signal with its file path but no other signals are sent (buggy behaviour of KDirWatch) refresh(); return; } // we have an updated file.. - vfile *newVf = createLocalVFile(name); - *vf = *newVf; - delete newVf; - emit updatedVfile(vf); + FileItem *newFileItem = createLocalFileItem(name); + *fileItem = *newFileItem; + delete newFileItem; + emit updatedFileItem(fileItem); } -void default_vfs::slotWatcherDeleted(const QString& path) +void DefaultFileSystem::slotWatcherDeleted(const QString& path) { if (path != realPath()) { // ignore deletion of files here, a 'dirty' signal will be send anyway return; } // the current directory was deleted, try a refresh, which will fail. An error message will // be emitted and the empty (non-existing) directory remains. refresh(); } -bool default_vfs::refreshLocal(const QUrl &directory) { +bool DefaultFileSystem::refreshLocal(const QUrl &directory) { const QString path = KrServices::urlToLocalPath(directory); #ifdef Q_WS_WIN if (!path.contains("/")) { // change C: to C:/ path = path + QString("/"); } #endif // check if the new directory exists if (!QDir(path).exists()) { emit error(i18n("The folder %1 does not exist.", path)); return false; } // mount if needed emit aboutToOpenDir(path); // set the current directory... _currentDirectory = directory; _currentDirectory.setPath(QDir::cleanPath(_currentDirectory.path())); // Note: we are using low-level Qt functions here. // It's around twice as fast as using the QDir class. QT_DIR* dir = QT_OPENDIR(path.toLocal8Bit()); if (!dir) { emit error(i18n("Cannot open the folder %1.", path)); return false; } // change directory to the new directory const QString savedDir = QDir::currentPath(); if (!QDir::setCurrent(path)) { emit error(i18nc("%1=folder path", "Access to %1 denied", path)); QT_CLOSEDIR(dir); return false; } QT_DIRENT* dirEnt; QString name; const bool showHidden = showHiddenFiles(); while ((dirEnt = QT_READDIR(dir)) != NULL) { name = QString::fromLocal8Bit(dirEnt->d_name); // show hidden files? if (!showHidden && name.left(1) == ".") continue ; // we don't need the "." and ".." entries if (name == "." || name == "..") continue; - vfile* temp = createLocalVFile(name); - addVfile(temp); + FileItem* temp = createLocalFileItem(name); + addFileItem(temp); } // clean up QT_CLOSEDIR(dir); QDir::setCurrent(savedDir); // start watching the new dir for file changes _watcher = new KDirWatch(this); // if the current dir is a link path the watcher needs to watch the real path - and signal // parameters will be the real path _watcher->addDir(realPath(), KDirWatch::WatchFiles); - connect(_watcher.data(), &KDirWatch::dirty, this, &default_vfs::slotWatcherDirty); + connect(_watcher.data(), &KDirWatch::dirty, this, &DefaultFileSystem::slotWatcherDirty); // NOTE: not connecting 'created' signal. A 'dirty' is send after that anyway //connect(_watcher, SIGNAL(created(const QString&)), this, SLOT(slotWatcherCreated(const QString&))); - connect(_watcher.data(), &KDirWatch::deleted, this, &default_vfs::slotWatcherDeleted); + connect(_watcher.data(), &KDirWatch::deleted, this, &DefaultFileSystem::slotWatcherDeleted); _watcher->startScan(false); return true; } -vfile *default_vfs::createLocalVFile(const QString &name) +FileItem *DefaultFileSystem::createLocalFileItem(const QString &name) { - return vfs::createLocalVFile(name, _currentDirectory.path()); + return FileSystem::createLocalFileItem(name, _currentDirectory.path()); } -QString default_vfs::default_vfs::realPath() +QString DefaultFileSystem::DefaultFileSystem::realPath() { return QDir(_currentDirectory.toLocalFile()).canonicalPath(); } -QUrl default_vfs::resolveRelativePath(const QUrl &url) +QUrl DefaultFileSystem::resolveRelativePath(const QUrl &url) { // if e.g. "/tmp/bin" is a link to "/bin", // resolve "/tmp/bin/.." to "/tmp" and not "/" return url.adjusted(QUrl::NormalizePathSegments); } diff --git a/krusader/VFS/default_vfs.h b/krusader/FileSystem/defaultfilesystem.h similarity index 90% rename from krusader/VFS/default_vfs.h rename to krusader/FileSystem/defaultfilesystem.h index d8a38f17..cffb3224 100644 --- a/krusader/VFS/default_vfs.h +++ b/krusader/FileSystem/defaultfilesystem.h @@ -1,105 +1,105 @@ /*************************************************************************** - default_vfs.h + defaultfilesystem.h ------------------- begin : Thu May 4 2000 copyright : (C) 2000 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ -#ifndef DEFAULT_VFS_H -#define DEFAULT_VFS_H +#ifndef DEFAULTFILESYSTEM_H +#define DEFAULTFILESYSTEM_H -#include "vfs.h" +#include "filesystem.h" #include #include /** * @brief Default filesystem implementation supporting all KIO protocols * - * This vfs implementation allows file operations and listing for all supported KIO protocols (local + * This filesystem implementation allows file operations and listing for all supported KIO protocols (local * and remote/network). * * Refreshing local directories is optimized for performance. * * NOTE: For detecting local file changes a filesystem watcher is used. It cannot be used for * refreshing the view after own file operations are performed because the detection is to slow * (~500ms delay between operation finished and watcher emits signals). * */ -class default_vfs : public vfs { +class DefaultFileSystem : public FileSystem { Q_OBJECT public: - default_vfs(); + DefaultFileSystem(); void copyFiles(const QList &urls, const QUrl &destination, KIO::CopyJob::CopyMode mode = KIO::CopyJob::Copy, bool showProgressInfo = true, bool reverseQueueMode = false, bool startPaused = false) Q_DECL_OVERRIDE; void dropFiles(const QUrl &destination, QDropEvent *event) Q_DECL_OVERRIDE; void addFiles(const QList &fileUrls, KIO::CopyJob::CopyMode mode, QString dir = "") Q_DECL_OVERRIDE; void mkDir(const QString &name) Q_DECL_OVERRIDE; void rename(const QString &fileName, const QString &newName) Q_DECL_OVERRIDE; /// Return URL for file name - even if file does not exist. QUrl getUrl(const QString &name) Q_DECL_OVERRIDE; bool canMoveToTrash(const QStringList &) Q_DECL_OVERRIDE { return isLocal(); } QString mountPoint() { return _mountPoint; } bool hasAutoUpdate() Q_DECL_OVERRIDE { return !_watcher.isNull(); } void updateFilesystemInfo() Q_DECL_OVERRIDE; protected: bool refreshInternal(const QUrl &origin, bool showHidden) Q_DECL_OVERRIDE; protected slots: /// Handle result after dir listing job is finished void slotListResult(KJob *job); /// Fill directory file list with new files from the dir lister void slotAddFiles(KIO::Job *job, const KIO::UDSEntryList &entries); /// URL redirection signal from dir lister void slotRedirection(KIO::Job *job, const QUrl &url); // React to filesystem changes nofified by watcher // NOTE: the path parameter can be the directory itself or files in this directory void slotWatcherDirty(const QString &path); void slotWatcherDeleted(const QString &path); private: - void connectSourceVFS(KJob *job, const QList urls); + void connectSourceFileSystem(KJob *job, const QList urls); bool refreshLocal(const QUrl &directory); // NOTE: this is very fast - vfile *createLocalVFile(const QString &name); + FileItem *createLocalFileItem(const QString &name); /// Returns the current path with symbolic links resolved QString realPath(); static QUrl resolveRelativePath(const QUrl &url); QPointer _watcher; // dir watcher used to detect changes in the current dir bool _listError; // for async operation, return list job result QString _mountPoint; // the mount point of the current dir }; #endif diff --git a/krusader/VFS/vfilecontainer.cpp b/krusader/FileSystem/dirlisterinterface.cpp similarity index 97% rename from krusader/VFS/vfilecontainer.cpp rename to krusader/FileSystem/dirlisterinterface.cpp index 21ae88ba..56dfdd59 100644 --- a/krusader/VFS/vfilecontainer.cpp +++ b/krusader/FileSystem/dirlisterinterface.cpp @@ -1,21 +1,21 @@ /***************************************************************************** * Copyright (C) 2010 Jan Lepper * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ // dummy file to force generation of metaobject code -#include "vfilecontainer.h" +#include "dirlisterinterface.h" diff --git a/krusader/VFS/vfilecontainer.h b/krusader/FileSystem/dirlisterinterface.h similarity index 74% rename from krusader/VFS/vfilecontainer.h rename to krusader/FileSystem/dirlisterinterface.h index d6ce27b3..9f990675 100644 --- a/krusader/VFS/vfilecontainer.h +++ b/krusader/FileSystem/dirlisterinterface.h @@ -1,53 +1,53 @@ /***************************************************************************** * Copyright (C) 2010 Jan Lepper * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -#ifndef VFILECONTAINER_H -#define VFILECONTAINER_H +#ifndef DIRLISTERINTERFACE_H +#define DIRLISTERINTERFACE_H // QtCore #include -class vfile; +class FileItem; /** * A minimal interface for access to the files inside a filesystem directory. */ -class VfileContainer : public QObject +class DirListerInterface : public QObject { Q_OBJECT public: - VfileContainer(QObject *parent) : QObject(parent) {} - virtual ~VfileContainer() {} + DirListerInterface(QObject *parent) : QObject(parent) {} + virtual ~DirListerInterface() {} - virtual QList vfiles() = 0; - virtual unsigned long numVfiles() = 0; + virtual QList fileItems() = 0; + virtual unsigned long numFileItems() = 0; virtual bool isRoot() = 0; signals: - /// Emitted when refreshing finished. The list of vfiles should now be updated by the view. + /// Emitted when refreshing finished. The list of file items should now be updated by the view. /// dirChange is true if refresh was a change to another directory. Else it was only an update /// of the file list in the current directory. void refreshDone(bool dirChange); - /// Emitted when all vfiles in the VFS were removed + /// Emitted when all file items in the filesystem were removed void cleared(); - void addedVfile(vfile *vf); - void updatedVfile(vfile *vf); + void addedFileItem(FileItem *fileItem); + void updatedFileItem(FileItem *fileItem); }; -#endif // VFILECONTAINER_H +#endif // DIRLISTERINTERFACE_H diff --git a/krusader/VFS/vfile.cpp b/krusader/FileSystem/fileitem.cpp similarity index 69% rename from krusader/VFS/vfile.cpp rename to krusader/FileSystem/fileitem.cpp index 3b2a0f94..f94bc844 100644 --- a/krusader/VFS/vfile.cpp +++ b/krusader/FileSystem/fileitem.cpp @@ -1,209 +1,209 @@ /*************************************************************************** - vfile.cpp + fileitem.cpp ------------------- copyright : (C) 2000 by Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ -#include "vfile.h" +#include "fileitem.h" // QtCore #include #include #include #include #include "krpermhandler.h" -#include "krvfshandler.h" +#include "filesystemprovider.h" -bool vfile::vfile_userDefinedFolderIcons = true; +bool FileItem::userDefinedFolderIcons = true; -// TODO set default vfile_size to '-1' to distinguish between empty directories and directories with +// TODO set default size to '-1' to distinguish between empty directories and directories with // unknown size -vfile::vfile(const QString &name, const QUrl &url, bool isDir, +FileItem::FileItem(const QString &name, const QUrl &url, bool isDir, KIO::filesize_t size, mode_t mode, time_t mtime, uid_t uid, gid_t gid, const QString &owner, const QString &group, bool isLink, const QString &linkDest, bool isBrokenLink, const QString &acl, const QString &defaultAcl) : m_name(name), m_url(url), m_isDir(isDir), m_size(size), m_mode(mode), m_mtime(mtime), m_uid(uid), m_gid(gid), m_owner(owner), m_group(group), m_isLink(isLink), m_linkDest(linkDest), m_isBrokenLink(isBrokenLink), m_acl(acl), m_defaulfAcl(defaultAcl), m_AclLoaded(false), m_mimeType(), m_icon() { m_permissions = KRpermHandler::mode2QString(mode); if (m_owner.isEmpty()) m_owner = KRpermHandler::uid2user(m_uid); if (m_group.isEmpty()) m_group = KRpermHandler::gid2group(m_gid); if (m_isDir && !m_isLink) m_size = 0; } -vfile *vfile::createDummy() +FileItem *FileItem::createDummy() { - vfile *file = new vfile("..", QUrl(), true, + FileItem *file = new FileItem("..", QUrl(), true, 0, 0, 0); - file->vfile_setIcon("go-up"); + file->setIcon("go-up"); return file; } -vfile *vfile::createVirtualDir(const QString &name, const QUrl &url) +FileItem *FileItem::createVirtualDir(const QString &name, const QUrl &url) { - return new vfile(name, url, true, + return new FileItem(name, url, true, 0, 0700, time(0), getuid(), getgid()); } -vfile *vfile::createCopy(const vfile &file, const QString &newName) +FileItem *FileItem::createCopy(const FileItem &file, const QString &newName) { - return new vfile(newName, file.vfile_getUrl(), file.vfile_isDir(), - file.vfile_getSize(), file.vfile_getMode(), file.vfile_getTime_t(), - file.m_uid, file.m_gid, file.vfile_getOwner(), file.vfile_getGroup(), - file.vfile_isSymLink(), file.vfile_getSymDest(), file.vfile_isBrokenLink()); + return new FileItem(newName, file.getUrl(), file.isDir(), + file.getSize(), file.getMode(), file.getTime_t(), + file.m_uid, file.m_gid, file.getOwner(), file.getGroup(), + file.isSymLink(), file.getSymDest(), file.isBrokenLink()); } -char vfile::vfile_isReadable() const +char FileItem::isReadable() const { if (m_uid != (uid_t)-1 && m_gid != (gid_t)-1) return KRpermHandler::readable(m_permissions, m_gid, m_uid); else return KRpermHandler::ftpReadable(m_owner, m_url.userName(), m_permissions); } -char vfile::vfile_isWriteable() const +char FileItem::isWriteable() const { if (m_uid != (uid_t)-1 && m_gid != (gid_t)-1) return KRpermHandler::writeable(m_permissions, m_gid, m_uid); else return KRpermHandler::ftpWriteable(m_owner, m_url.userName(), m_permissions); } -char vfile::vfile_isExecutable() const +char FileItem::isExecutable() const { if (m_uid != (uid_t)-1 && m_gid != (gid_t)-1) return KRpermHandler::executable(m_permissions, m_gid, m_uid); else return KRpermHandler::ftpExecutable(m_owner, m_url.userName(), m_permissions); } -const QString &vfile::vfile_getMime() +const QString &FileItem::getMime() { if (m_mimeType.isEmpty()) { if (m_isDir) { m_mimeType = "inode/directory"; m_icon = "inode-directory"; - } else if (vfile_isBrokenLink()) { + } else if (isBrokenLink()) { m_mimeType = "unknown"; m_icon = "file-broken"; } else { const QMimeDatabase db; - const QMimeType mt = db.mimeTypeForUrl(vfile_getUrl()); + const QMimeType mt = db.mimeTypeForUrl(getUrl()); m_mimeType = mt.isValid() ? mt.name() : "unknown"; m_icon = mt.isValid() ? mt.iconName() : "file-broken"; if (m_mimeType == "inode/directory") { // TODO view update needed? and does this ever happen? m_isDir = true; } } - if (m_isDir && vfile_userDefinedFolderIcons) { - const QUrl url = vfile_getUrl(); + if (m_isDir && userDefinedFolderIcons) { + const QUrl url = getUrl(); if (url.isLocalFile()) { const QString file = url.toLocalFile() + "/.directory"; const KDesktopFile cfg(file); const QString icon = cfg.readIcon(); if (!icon.isEmpty()) m_icon = icon.startsWith(QLatin1String("./")) ? // relative path url.toLocalFile() + '/' + icon : icon; } } } return m_mimeType; } -const QString &vfile::vfile_getIcon() +const QString &FileItem::getIcon() { if (m_icon.isEmpty()) { - vfile_getMime(); // sets the icon + getMime(); // sets the icon } return m_icon; } -const QString &vfile::vfile_getACL() +const QString &FileItem::getACL() { if (!m_AclLoaded) - vfile_loadACL(); + loadACL(); return m_acl; } -void vfile::vfile_loadACL() +void FileItem::loadACL() { if (m_url.isLocalFile()) { - KrVfsHandler::getACL(this, m_acl, m_defaulfAcl); + FileSystemProvider::getACL(this, m_acl, m_defaulfAcl); } m_AclLoaded = true; } -const KIO::UDSEntry vfile::vfile_getEntry() +const KIO::UDSEntry FileItem::getEntry() { KIO::UDSEntry entry; - entry.insert(KIO::UDSEntry::UDS_NAME, vfile_getName()); - entry.insert(KIO::UDSEntry::UDS_SIZE, vfile_getSize()); - entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, vfile_getTime_t()); - entry.insert(KIO::UDSEntry::UDS_USER, vfile_getOwner()); - entry.insert(KIO::UDSEntry::UDS_GROUP, vfile_getGroup()); - entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, vfile_getMime()); - entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, vfile_getMode() & S_IFMT); - entry.insert(KIO::UDSEntry::UDS_ACCESS, vfile_getMode() & 07777); + entry.insert(KIO::UDSEntry::UDS_NAME, getName()); + entry.insert(KIO::UDSEntry::UDS_SIZE, getSize()); + entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, getTime_t()); + entry.insert(KIO::UDSEntry::UDS_USER, getOwner()); + entry.insert(KIO::UDSEntry::UDS_GROUP, getGroup()); + entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, getMime()); + entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, getMode() & S_IFMT); + entry.insert(KIO::UDSEntry::UDS_ACCESS, getMode() & 07777); - if (vfile_isSymLink()) - entry.insert(KIO::UDSEntry::UDS_LINK_DEST, vfile_getSymDest()); + if (isSymLink()) + entry.insert(KIO::UDSEntry::UDS_LINK_DEST, getSymDest()); if (!m_AclLoaded) - vfile_loadACL(); + loadACL(); if (!m_acl.isNull() || !m_defaulfAcl.isNull()) { entry.insert(KIO::UDSEntry::UDS_EXTENDED_ACL, 1); if (!m_acl.isNull()) entry.insert(KIO::UDSEntry::UDS_ACL_STRING, m_acl); if (!m_defaulfAcl.isNull()) entry.insert(KIO::UDSEntry::UDS_DEFAULT_ACL_STRING, m_defaulfAcl); } return entry; } diff --git a/krusader/VFS/vfile.h b/krusader/FileSystem/fileitem.h similarity index 68% rename from krusader/VFS/vfile.h rename to krusader/FileSystem/fileitem.h index 6a57eccd..6d998ef8 100644 --- a/krusader/VFS/vfile.h +++ b/krusader/FileSystem/fileitem.h @@ -1,158 +1,158 @@ /*************************************************************************** - vfile.h + fileitem.h ------------------- begin : Thu May 4 2000 copyright : (C) 2000 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ -#ifndef VFILE_H -#define VFILE_H +#ifndef FILEITEM_H +#define FILEITEM_H #include // QtCore #include #include #include #include /** - * The Virtual File class handles all the details of maintaining a single - * file component within the virtual file system (vfs). a vfile object - * contains the necessary details about a file and member functions which - * allow the object to give out the needed details about the file. + * A file item gives access all meta information of a (virtual, dummy or real) file or directory in + * the filesystem. + * + * NOTE: The name of a file item is supposed to be unique within a directory. */ -class vfile +class FileItem { public: /** * Create a new file item. * - * Don't use this constructor outside of VFS! If you really need to, create a new static + * Don't use this constructor outside of FileSystem! If you really need to, create a new static * factory method below. * * NOTE: According to Unix standard uid and gid CAN have signed or unsigned type. We use (e.g.) * "(uid_t) -1" as a special invalid user ID for non-local files. - * Note: ACLs are currently only used by Synchronizer. + * NOTE: ACLs are currently only used by Synchronizer. * * @param name the display name of this file. Don't have to be the real filename. * @param url (real) absolute URL of this file * @param isDir true if this file is a directory. Else false. * @param size size of file * @param mode mode of file (file type and permissions) * @param mtime file modification time * @param uid Unix user id of file owner. Use -1 here and provide an owner name for non-local files. * @param gid Unix group id of file group. Use -1 here and provide a group name for non-local files. * @param owner user name of file owner. Can be empty for local files * @param group group name of file group. Cam be empty for local files. * @param isLink true if file is a symbolic link. Else false. * @param linkDest link destination path if file is a link. Relative or absolute. Empty by default. * @param isBrokenLink true if file is a symbolic link and destination file does not exists. Else false. * @param acl ACL string of file. Can be empty and is loaded on demand. * @param defaultAcl default ACL string of file (only for directories). Can be empty and is loaded on demand. */ - vfile(const QString &name, const QUrl &url, bool isDir, + FileItem(const QString &name, const QUrl &url, bool isDir, KIO::filesize_t size, mode_t mode, time_t mtime, uid_t uid = -1, gid_t gid = -1, const QString &owner = QString(), const QString &group = QString(), bool isLink = false, const QString &linkDest = QString(), bool isBrokenLink = false, const QString &acl = QString(), const QString &defaultAcl = QString()); /** Create a new ".." dummy file item. */ - static vfile *createDummy(); + static FileItem *createDummy(); /** Create a new virtual directory. */ - static vfile *createVirtualDir(const QString &name, const QUrl &url); + static FileItem *createVirtualDir(const QString &name, const QUrl &url); /** Create a new file item copy with a different name. */ - static vfile *createCopy(const vfile &file, const QString &newName); + static FileItem *createCopy(const FileItem &file, const QString &newName); // following functions give-out file details - inline const QString &vfile_getName() const { return m_name; } - inline KIO::filesize_t vfile_getSize() const { return m_size; } - inline const QString &vfile_getPerm() const { return m_permissions; } - inline bool vfile_isDir() const { return m_isDir; } - inline bool vfile_isSymLink() const { return m_isLink; } - inline bool vfile_isBrokenLink() const { return m_isBrokenLink; } - inline const QString &vfile_getSymDest() const { return m_linkDest; } - inline mode_t vfile_getMode() const { return m_mode; } - inline time_t vfile_getTime_t() const { return m_mtime; } - inline const QUrl &vfile_getUrl() const { return m_url; } - inline const QString &vfile_getOwner() const { return m_owner; } - inline const QString &vfile_getGroup() const { return m_group; } - - const QString &vfile_getMime(); - const QString &vfile_getIcon(); - - const QString &vfile_getACL(); - const QString &vfile_getDefaultACL(); - const KIO::UDSEntry vfile_getEntry(); //< return the UDSEntry from the vfile - char vfile_isReadable() const; - char vfile_isWriteable() const; - char vfile_isExecutable() const; + inline const QString &getName() const { return m_name; } + inline KIO::filesize_t getSize() const { return m_size; } + inline const QString &getPerm() const { return m_permissions; } + inline bool isDir() const { return m_isDir; } + inline bool isSymLink() const { return m_isLink; } + inline bool isBrokenLink() const { return m_isBrokenLink; } + inline const QString &getSymDest() const { return m_linkDest; } + inline mode_t getMode() const { return m_mode; } + inline time_t getTime_t() const { return m_mtime; } + inline const QUrl &getUrl() const { return m_url; } + inline const QString &getOwner() const { return m_owner; } + inline const QString &getGroup() const { return m_group; } + + const QString &getMime(); + const QString &getIcon(); + + const QString &getACL(); + const QString &getDefaultACL(); + const KIO::UDSEntry getEntry(); //< return the UDSEntry from the file item + char isReadable() const; + char isWriteable() const; + char isExecutable() const; /** * Set the file size. * used ONLY when calculating a directory's space, needs to change the - * displayed size of the viewitem and thus the vfile. For INTERNAL USE ! + * displayed size of the viewitem and thus the file item. For INTERNAL USE ! */ - void vfile_setSize(KIO::filesize_t size) { m_size = size; } + void setSize(KIO::filesize_t size) { m_size = size; } - inline static void vfile_loadUserDefinedFolderIcons(bool load) { - vfile_userDefinedFolderIcons = load; + inline static void loadUserDefinedFolderIcons(bool load) { + userDefinedFolderIcons = load; } private: - void vfile_setIcon(const QString &icon) { m_icon = icon; m_mimeType = "?"; } - void vfile_loadACL(); + void setIcon(const QString &icon) { m_icon = icon; m_mimeType = "?"; } + void loadACL(); QString m_name; //< file name QUrl m_url; //< file URL bool m_isDir; //< flag, true if it's a directory KIO::filesize_t m_size; //< file size mode_t m_mode; //< file mode (file type and permissions) time_t m_mtime; //< file modification time uid_t m_uid; //< file owner id gid_t m_gid; //< file group id QString m_owner; //< file owner name QString m_group; //< file group name bool m_isLink; //< true if the file is a symlink QString m_linkDest; //< if it's a sym link - its detination bool m_isBrokenLink; //< true if the link destianation does not exist QString m_permissions; //< file permissions string QString m_acl; //< ACL permission string, may lazy initialized QString m_defaulfAcl; //< ACL default string, may lazy initialized bool m_AclLoaded; //< flag, indicates that ACL permissions already loaded QString m_mimeType; //< file mimetype, lazy initialized QString m_icon; //< the name of the icon file, lazy initialized - static bool vfile_userDefinedFolderIcons; + static bool userDefinedFolderIcons; }; #endif diff --git a/krusader/VFS/vfs.cpp b/krusader/FileSystem/filesystem.cpp similarity index 78% rename from krusader/VFS/vfs.cpp rename to krusader/FileSystem/filesystem.cpp index 834f04ca..93bd74cf 100644 --- a/krusader/VFS/vfs.cpp +++ b/krusader/FileSystem/filesystem.cpp @@ -1,427 +1,427 @@ /*************************************************************************** - vfs.cpp + filesystem.cpp ------------------- copyright : (C) 2000 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net ------------------------------------------------------------------------ - the vfs class is an extendable class which by itself does (almost) - nothing. other VFSs like the normal_vfs inherits from this class and - make it possible to use a consistent API for all types of VFSs. + the filesystem class is an extendable class which by itself does (almost) + nothing. other filesystems like the normal_filesystem inherits from this class and + make it possible to use a consistent API for all types of filesystems. *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ -#include "vfs.h" +#include "filesystem.h" // QtCore #include #include #include // QtWidgets #include #include #include #include #include #include #include "../defaults.h" #include "../krglobal.h" #include "../JobMan/jobman.h" #include "../JobMan/krjob.h" #include "krpermhandler.h" -vfs::vfs() : VfileContainer(0), _isRefreshing(false) {} +FileSystem::FileSystem() : DirListerInterface(0), _isRefreshing(false) {} -vfs::~vfs() +FileSystem::~FileSystem() { - clear(_vfiles); + clear(_fileItems); emit cleared(); // please don't remove this line. This informs the view about deleting the references } -QList vfs::getUrls(const QStringList &names) +QList FileSystem::getUrls(const QStringList &names) { QList urls; for (const QString name : names) { urls.append(getUrl(name)); } return urls; } -vfile *vfs::getVfile(const QString &name) +FileItem *FileSystem::getFileItem(const QString &name) { - return _vfiles.contains(name) ? _vfiles.value(name) : 0; + return _fileItems.contains(name) ? _fileItems.value(name) : 0; } -QList vfs::searchVfiles(const KRQuery &filter) +QList FileSystem::searchFileItems(const KRQuery &filter) { - QList result; - for (vfile *vf : _vfiles.values()) { - if (filter.match(vf)) { - result.append(vf); + QList result; + for (FileItem *item : _fileItems.values()) { + if (filter.match(item)) { + result.append(item); } } return result; } -KIO::filesize_t vfs::vfs_totalSize() +KIO::filesize_t FileSystem::totalSize() { KIO::filesize_t temp = 0; - for (vfile *vf : _vfiles.values()) { - if (!vf->vfile_isDir() && vf->vfile_getName() != "." && vf->vfile_getName() != "..") { - temp += vf->vfile_getSize(); + for (FileItem *item : _fileItems.values()) { + if (!item->isDir() && item->getName() != "." && item->getName() != "..") { + temp += item->getSize(); } } return temp; } -void vfs::calcSpace(const QString &name, KIO::filesize_t *totalSize, +void FileSystem::calcSpace(const QString &name, KIO::filesize_t *totalSize, unsigned long *totalFiles, unsigned long *totalDirs, bool *stop) { const QUrl url = getUrl(name); if (url.isEmpty()) { krOut << "item for calculating space not found: " << name; return; } calcSpace(url, totalSize, totalFiles, totalDirs, stop); } -QUrl vfs::ensureTrailingSlash(const QUrl &url) +QUrl FileSystem::ensureTrailingSlash(const QUrl &url) { if (url.path().endsWith('/')) { return url; } QUrl adjustedUrl(url); adjustedUrl.setPath(adjustedUrl.path() + '/'); return adjustedUrl; } -QUrl vfs::preferLocalUrl(const QUrl &url){ +QUrl FileSystem::preferLocalUrl(const QUrl &url){ if (url.isEmpty() || !url.scheme().isEmpty()) return url; QUrl adjustedUrl = url; adjustedUrl.setScheme("file"); return adjustedUrl; } -bool vfs::refresh(const QUrl &directory) +bool FileSystem::refresh(const QUrl &directory) { if (_isRefreshing) { // NOTE: this does not happen (unless async)"; return false; } // workaround for krarc: find out if transition to local fs is wanted and adjust URL manually QUrl url = directory; if (_currentDirectory.scheme() == "krarc" && url.scheme() == "krarc" && QDir(url.path()).exists()) { url.setScheme("file"); } const bool dirChange = !url.isEmpty() && cleanUrl(url) != _currentDirectory; const QUrl toRefresh = dirChange ? url.adjusted(QUrl::NormalizePathSegments) : _currentDirectory; if (!toRefresh.isValid()) { emit error(i18n("Malformed URL:\n%1", toRefresh.toDisplayString())); return false; } _isRefreshing = true; - vfileDict tempVfiles(_vfiles); // old vfiles are still used during refresh - _vfiles.clear(); + FileItemDict tempFileItems(_fileItems); // old file items are still used during refresh + _fileItems.clear(); if (dirChange) // show an empty directory while loading the new one and clear selection emit cleared(); const bool res = refreshInternal(toRefresh, showHiddenFiles()); _isRefreshing = false; if (!res) { // cleanup and abort if (!dirChange) emit cleared(); - clear(tempVfiles); + clear(tempFileItems); return false; } emit refreshDone(dirChange); - clear(tempVfiles); + clear(tempFileItems); updateFilesystemInfo(); return true; } -void vfs::deleteFiles(const QStringList &fileNames, bool moveToTrash) +void FileSystem::deleteFiles(const QStringList &fileNames, bool moveToTrash) { // get absolute URLs for file names const QList fileUrls = getUrls(fileNames); KrJob *krJob = KrJob::createDeleteJob(fileUrls, moveToTrash); connect(krJob, &KrJob::started, [=](KIO::Job *job) { connectJob(job, currentDirectory()); }); if (moveToTrash) { // update destination: the trash bin (in case a panel/tab is showing it) connect(krJob, &KrJob::started, [=](KIO::Job *job) { // Note: the "trash" protocal should always have only one "/" after the "scheme:" part - connect(job, &KIO::Job::result, [=]() { emit filesystemChanged(QUrl("trash:/")); }); + connect(job, &KIO::Job::result, [=]() { emit fileSystemChanged(QUrl("trash:/")); }); }); } krJobMan->manageJob(krJob); } -void vfs::connectJob(KJob *job, const QUrl &destination) +void FileSystem::connectJob(KJob *job, const QUrl &destination) { // (additional) direct refresh if on local fs because watcher is too slow const bool refresh = cleanUrl(destination) == _currentDirectory && isLocal(); connect(job, &KIO::Job::result, this, [=](KJob* job) { slotJobResult(job, refresh); }); - connect(job, &KIO::Job::result, [=]() { emit filesystemChanged(destination); }); + connect(job, &KIO::Job::result, [=]() { emit fileSystemChanged(destination); }); } -bool vfs::showHiddenFiles() +bool FileSystem::showHiddenFiles() { const KConfigGroup gl(krConfig, "Look&Feel"); return gl.readEntry("Show Hidden", _ShowHidden); } -void vfs::calcSpace(const QUrl &url, KIO::filesize_t *totalSize, unsigned long *totalFiles, +void FileSystem::calcSpace(const QUrl &url, KIO::filesize_t *totalSize, unsigned long *totalFiles, unsigned long *totalDirs, bool *stop) { if (url.isLocalFile()) { calcSpaceLocal(cleanUrl(url).path(), totalSize, totalFiles, totalDirs, stop); } else { calcSpaceKIO(url, totalSize, totalFiles, totalDirs, stop); } } -void vfs::calcSpaceLocal(const QString &path, KIO::filesize_t *totalSize, unsigned long *totalFiles, +void FileSystem::calcSpaceLocal(const QString &path, KIO::filesize_t *totalSize, unsigned long *totalFiles, unsigned long *totalDirs, bool *stop) { if (stop && *stop) return; if (path == "/proc") return; QT_STATBUF stat_p; // KDE lstat is necessary as QFileInfo and KFileItem // if the name is wrongly encoded, then we zero the size out stat_p.st_size = 0; stat_p.st_mode = 0; QT_LSTAT(path.toLocal8Bit(), &stat_p); // reports wrong size for a symbolic link if (S_ISLNK(stat_p.st_mode) || !S_ISDIR(stat_p.st_mode)) { // single files are easy : ) ++(*totalFiles); (*totalSize) += stat_p.st_size; } else { // handle directories avoid a nasty crash on un-readable dirs bool readable = ::access(path.toLocal8Bit(), R_OK | X_OK) == 0; if (!readable) return; QDir dir(path); if (!dir.exists()) return; ++(*totalDirs); dir.setFilter(QDir::TypeMask | QDir::System | QDir::Hidden); dir.setSorting(QDir::Name | QDir::DirsFirst); // recurse on all the files in the directory QFileInfoList fileList = dir.entryInfoList(); for (int k = 0; k != fileList.size(); k++) { if (*stop) return; QFileInfo qfiP = fileList[k]; if (qfiP.fileName() != "." && qfiP.fileName() != "..") calcSpaceLocal(path + '/' + qfiP.fileName(), totalSize, totalFiles, totalDirs, stop); } } } // TODO called from another thread, creating KIO jobs does not work here -void vfs::calcSpaceKIO(const QUrl &url, KIO::filesize_t *totalSize, unsigned long *totalFiles, +void FileSystem::calcSpaceKIO(const QUrl &url, KIO::filesize_t *totalSize, unsigned long *totalFiles, unsigned long *totalDirs, bool *stop) { return; if (stop && *stop) return; _calcKdsBusy = stop; _calcKdsTotalSize = totalSize; _calcKdsTotalFiles = totalFiles; _calcKdsTotalDirs = totalDirs; _calcStatBusy = true; KIO::StatJob *statJob = KIO::stat(url, KIO::HideProgressInfo); // thread problem here - connect(statJob, &KIO::Job::result, this, &vfs::slotCalcStatResult); + connect(statJob, &KIO::Job::result, this, &FileSystem::slotCalcStatResult); while (!(*stop) && _calcStatBusy) { usleep(1000); } if (_calcEntry.count() == 0) return; // statJob failed const KFileItem kfi(_calcEntry, url, true); if (kfi.isFile() || kfi.isLink()) { (*totalFiles)++; *totalSize += kfi.size(); return; } KIO::DirectorySizeJob *directorySizeJob = KIO::directorySize(url); - connect(directorySizeJob, &KIO::Job::result, this, &vfs::slotCalcKdsResult); + connect(directorySizeJob, &KIO::Job::result, this, &FileSystem::slotCalcKdsResult); while (!(*stop)) { // we are in a separate thread - so sleeping is OK usleep(1000); } } -vfile *vfs::createLocalVFile(const QString &name, const QString &directory, bool virt) +FileItem *FileSystem::createLocalFileItem(const QString &name, const QString &directory, bool virt) { const QDir dir = QDir(directory); const QString path = dir.filePath(name); const QByteArray filePath = path.toLocal8Bit(); QT_STATBUF stat_p; stat_p.st_size = 0; stat_p.st_mode = 0; stat_p.st_mtime = 0; stat_p.st_uid = 0; stat_p.st_gid = 0; QT_LSTAT(filePath.data(), &stat_p); const KIO::filesize_t size = stat_p.st_size; bool isDir = S_ISDIR(stat_p.st_mode); const bool isLink = S_ISLNK(stat_p.st_mode); QString linkDestination; bool brokenLink = false; if (isLink) { // find where the link is pointing to // the path of the symlink target cannot be longer than the file size of the symlink char buffer[stat_p.st_size]; memset(buffer, 0, sizeof(buffer)); int bytesRead = readlink(filePath.data(), buffer, sizeof(buffer)); if (bytesRead != -1) { linkDestination = QString::fromLocal8Bit(buffer, bytesRead); // absolute or relative const QFileInfo linkFile(dir, linkDestination); if (!linkFile.exists()) brokenLink = true; else if (linkFile.isDir()) isDir = true; } else { krOut << "Failed to read link: " << path; } } - return new vfile(virt ? path : name, QUrl::fromLocalFile(path), isDir, + return new FileItem(virt ? path : name, QUrl::fromLocalFile(path), isDir, size, stat_p.st_mode, stat_p.st_mtime, stat_p.st_uid, stat_p.st_gid, QString(), QString(), isLink, linkDestination, brokenLink); } -vfile *vfs::createVFileFromKIO(const KIO::UDSEntry &entry, const QUrl &directory, bool virt) +FileItem *FileSystem::createFileItemFromKIO(const KIO::UDSEntry &entry, const QUrl &directory, bool virt) { const KFileItem kfi(entry, directory, true, true); const QString name = kfi.text(); // ignore un-needed entries if (name.isEmpty() || name == "." || name == "..") { return 0; } const QString localPath = kfi.localPath(); const QUrl url = !localPath.isEmpty() ? QUrl::fromLocalFile(localPath) : kfi.url(); const QString fname = virt ? url.toDisplayString() : name; // get file statistics... const time_t mtime = kfi.time(KFileItem::ModificationTime).toTime_t(); const mode_t mode = kfi.mode() | kfi.permissions(); // NOTE: we could get the mimetype (and file icon) from the kfileitem here but this is very - // slow. Instead, the vfile class has it's own (faster) way to determine the file type. + // slow. Instead, the file item class has it's own (faster) way to determine the file type. // NOTE: "broken link" flag is always false, checking link destination existence is // considered to be too expensive - return new vfile(fname, url, kfi.isDir(), + return new FileItem(fname, url, kfi.isDir(), kfi.size(), mode, mtime, (uid_t) -1, (gid_t) -1, kfi.user(), kfi.group(), kfi.isLink(), kfi.linkDest(), false, kfi.ACL().asString(), kfi.defaultACL().asString()); } // ==== protected slots ==== -void vfs::slotJobResult(KJob *job, bool refresh) +void FileSystem::slotJobResult(KJob *job, bool refresh) { if (job->error() && job->uiDelegate()) { // show errors for modifying operations as popup (works always) job->uiDelegate()->showErrorMessage(); } if (refresh) { - vfs::refresh(); + FileSystem::refresh(); } } /// to be implemented -void vfs::slotCalcKdsResult(KJob *job) +void FileSystem::slotCalcKdsResult(KJob *job) { if (!job->error()) { KIO::DirectorySizeJob *kds = static_cast(job); *_calcKdsTotalSize += kds->totalSize(); *_calcKdsTotalFiles += kds->totalFiles(); *_calcKdsTotalDirs += kds->totalSubdirs(); } *_calcKdsBusy = true; } -void vfs::slotCalcStatResult(KJob *job) +void FileSystem::slotCalcStatResult(KJob *job) { _calcEntry = job->error() ? KIO::UDSEntry() : static_cast(job)->statResult(); _calcStatBusy = false; } // ==== private ==== -void vfs::clear(vfileDict &vfiles) +void FileSystem::clear(FileItemDict &fileItems) { - QHashIterator lit(vfiles); + QHashIterator lit(fileItems); while (lit.hasNext()) { delete lit.next().value(); } - vfiles.clear(); + fileItems.clear(); } diff --git a/krusader/VFS/vfs.h b/krusader/FileSystem/filesystem.h similarity index 74% rename from krusader/VFS/vfs.h rename to krusader/FileSystem/filesystem.h index 9412902a..63d5e706 100644 --- a/krusader/VFS/vfs.h +++ b/krusader/FileSystem/filesystem.h @@ -1,243 +1,243 @@ /*************************************************************************** - vfs.h + filesystem.h ------------------- begin : Thu May 4 2000 copyright : (C) 2000 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ -#ifndef VFS_H -#define VFS_H +#ifndef FILESYSTEM_H +#define FILESYSTEM_H -#include "vfilecontainer.h" +#include "dirlisterinterface.h" // QtCore #include #include #include #include #include // QtGui #include // QtWidgets #include #include -#include "vfile.h" +#include "fileitem.h" #include "krquery.h" /** - * An abstract virtual filesystem. Use the implementations of this class for all file operations. + * An abstract filesystem. Use the implementations of this class for all file operations. * * It represents a directory and gives access to its files. All common file operations * are supported. Methods with absolute URL as argument can be used independently from the current * directory. Otherwise - if the methods argument is a file name - the operation is performed inside * the current directory. * * Notification signals are emitted if the directory content may have been changed. */ -class vfs : public VfileContainer +class FileSystem : public DirListerInterface { Q_OBJECT public: - enum VFS_TYPE { + enum FS_TYPE { /// Virtual filesystem. Krusaders custom virt:/ protocol - VFS_VIRT, + FS_VIRTUAL, /// Filesystem supporting all KIO protocols (file:/, ftp:/, smb:/, etc.) - VFS_DEFAULT + FS_DEFAULT }; - vfs(); - virtual ~vfs(); + FileSystem(); + virtual ~FileSystem(); - // VfileContainer implementation - inline QList vfiles() { return _vfiles.values(); } - inline unsigned long numVfiles() { return _vfiles.count(); } + // DirListerInterface implementation + inline QList fileItems() { return _fileItems.values(); } + inline unsigned long numFileItems() { return _fileItems.count(); } inline bool isRoot() { const QString path = _currentDirectory.path(); return path.isEmpty() || path == "/"; } - /// Copy (copy, move or link) files in this VFS. + /// Copy (copy, move or link) files in this FILESYSTEM. /// Destination is absolute URL. May implemented async. virtual void copyFiles(const QList &urls, const QUrl &destination, KIO::CopyJob::CopyMode mode = KIO::CopyJob::Copy, bool showProgressInfo = true, bool reverseQueueMode = false, bool startPaused = false) = 0; - /// Handle file dropping in this VFS. Destination is absolute URL. May implemented async. + /// Handle file dropping in this FILESYSTEM. Destination is absolute URL. May implemented async. virtual void dropFiles(const QUrl &destination, QDropEvent *event) = 0; - /// Copy (copy, move or link) files to the current VFS directory or to "dir", the + /// Copy (copy, move or link) files to the current FILESYSTEM directory or to "dir", the /// directory name relative to the current dir. May implemented async. virtual void addFiles(const QList &fileUrls, KIO::CopyJob::CopyMode mode, QString dir = "") = 0; /// Create a new directory in the current directory. May implemented async. virtual void mkDir(const QString &name) = 0; /// Rename file/directory in the current directory. May implemented async. virtual void rename(const QString &fileName, const QString &newName) = 0; /// Return an absolute URL for a single file/directory name in the current directory - with no /// trailing slash. virtual QUrl getUrl(const QString &name) = 0; /// Return a list of URLs for multiple files/directories in the current directory. QList getUrls(const QStringList &names); /// Return true if all files can be moved to trash, else false. virtual bool canMoveToTrash(const QStringList &fileNames) = 0; /// Return the filesystem mount point of the current directory. Empty string by default. virtual QString mountPoint() { return QString(); } - /// Returns true if this VFS implementation does not need to be notified about changes in the + /// Returns true if this FILESYSTEM implementation does not need to be notified about changes in the /// current directory. Else false. virtual bool hasAutoUpdate() { return false; } - /// Notify this VFS that the filesystem info of the current directory may have changed. + /// Notify this FILESYSTEM that the filesystem info of the current directory may have changed. virtual void updateFilesystemInfo() {} - /// Returns the current directory path of this VFS. + /// Returns the current directory path of this FILESYSTEM. inline QUrl currentDirectory() { return _currentDirectory; } - /// Return the vfile for a file name in the current directory. Or 0 if not found. - vfile *getVfile(const QString &name); - /// Return a list of vfiles for a search query. Or an empty list if nothing was found. - QList searchVfiles(const KRQuery &filter); + /// Return the file item for a file name in the current directory. Or 0 if not found. + FileItem *getFileItem(const QString &name); + /// Return a list of file items for a search query. Or an empty list if nothing was found. + QList searchFileItems(const KRQuery &filter); /// The total size of all files in the current directory (only valid after refresh). // TODO unused - KIO::filesize_t vfs_totalSize(); - /// Return the VFS type. - inline VFS_TYPE type() { return _type; } + KIO::filesize_t totalSize(); + /// Return the FILESYSTEM type. + inline FS_TYPE type() { return _type; } /// Return true if the current directory is local (without recognizing mount points). inline bool isLocal() { return _currentDirectory.isLocalFile(); } /// Return true if the current directory is a remote (network) location. inline bool isRemote() { const QString sc = _currentDirectory.scheme(); return (sc == "fish" || sc == "ftp" || sc == "sftp" || sc == "nfs" || sc == "smb" || sc == "webdav"); } - /// Returns true if this VFS is currently refreshing the current directory. + /// Returns true if this FILESYSTEM is currently refreshing the current directory. inline bool isRefreshing() { return _isRefreshing; } /// Delete or trash files in the current directory. Implemented async. void deleteFiles(const QStringList &fileNames, bool moveToTrash = true); /// Calculate the amount of space occupied by a file or directory in the current directory /// (recursive). virtual void calcSpace(const QString &name, KIO::filesize_t *totalSize, unsigned long *totalFiles, unsigned long *totalDirs, bool *stop); /// Return the input URL with a trailing slash if absent. static QUrl ensureTrailingSlash(const QUrl &url); /// Return the input URL without trailing slash. static QUrl cleanUrl(const QUrl &url) { return url.adjusted(QUrl::StripTrailingSlash); } /// Add 'file' scheme to non-empty URL without scheme static QUrl preferLocalUrl(const QUrl &url); - /// Return a vfile for a local file inside a directory - static vfile *createLocalVFile(const QString &name, const QString &directory, + /// Return a file item for a local file inside a directory + static FileItem *createLocalFileItem(const QString &name, const QString &directory, bool virt = false); - /// Return a vfile for a KIO result. Returns 0 if entry is not needed - static vfile *createVFileFromKIO(const KIO::UDSEntry &_calcEntry, const QUrl &directory, + /// Return a file item for a KIO result. Returns 0 if entry is not needed + static FileItem *createFileItemFromKIO(const KIO::UDSEntry &_calcEntry, const QUrl &directory, bool virt = false); // set the parent window to be used for dialogs void setParentWindow(QWidget *widget) { parentWindow = widget; } public slots: /// Re-read the current directory files or change to another directory. Blocking. /// Returns true if directory was read. Returns false if failed or refresh job was killed. // optional TODO: add an async version of this bool refresh(const QUrl &directory = QUrl()); signals: - /// Emitted when this VFS is currently refreshing the VFS directory. + /// Emitted when this FILESYSTEM is currently refreshing the FILESYSTEM directory. void refreshJobStarted(KIO::Job *job); - /// Emitted when an error occured in this VFS during refresh. + /// Emitted when an error occured in this FILESYSTEM during refresh. void error(const QString &msg); - /// Emitted when the content of a directory was changed by this VFS. - void filesystemChanged(const QUrl &directory); + /// Emitted when the content of a directory was changed by this FILESYSTEM. + void fileSystemChanged(const QUrl &directory); /// Emitted when the information for the filesystem of the current directory changed. /// Information is either /// * 'metaInfo': a displayable string about the fs, empty by default, OR /// * 'fsType', 'total' and 'free': filesystem type, size and free space, /// empty string or 0 by default - void filesystemInfoChanged(const QString &metaInfo, const QString &fsType, + void fileSystemInfoChanged(const QString &metaInfo, const QString &fsType, KIO::filesize_t total, KIO::filesize_t free); /// Emitted before a directory path is opened for reading. Used for automounting. void aboutToOpenDir(const QString &path); protected: - /// Fill the vfs dictionary with vfiles, must be implemented for each VFS. + /// Fill the filesystem dictionary with file items, must be implemented for each FILESYSTEM. virtual bool refreshInternal(const QUrl &origin, bool showHidden) = 0; /// Connect the result signal of a file operation job. void connectJob(KJob *job, const QUrl &destination); /// Returns true if showing hidden files is set in config. bool showHiddenFiles(); - /// Add a new vfile to the internal dictionary (while refreshing). - inline void addVfile(vfile *vf) { _vfiles.insert(vf->vfile_getName(), vf); } + /// Add a new file item to the internal dictionary (while refreshing). + inline void addFileItem(FileItem *item) { _fileItems.insert(item->getName(), item); } /// Calculate the size of a file or directory (recursive). void calcSpace(const QUrl &url, KIO::filesize_t *totalSize, unsigned long *totalFiles, unsigned long *totalDirs, bool *stop); /// Calculate the size of a local file or directory (recursive). void calcSpaceLocal(const QString &path, KIO::filesize_t *totalSize, unsigned long *totalFiles, unsigned long *totalDirs, bool *stop); /// Calculate the size of any KIO file or directory. void calcSpaceKIO(const QUrl &url, KIO::filesize_t *totalSize, unsigned long *totalFiles, unsigned long *totalDirs, bool *stop); - VFS_TYPE _type; // the vfs type. - QUrl _currentDirectory; // the path or file the VFS originates from. - bool _isRefreshing; // true if vfs is busy with refreshing + FS_TYPE _type; // the filesystem type. + QUrl _currentDirectory; // the path or file the FILESYSTEM originates from. + bool _isRefreshing; // true if filesystem is busy with refreshing QPointer parentWindow; protected slots: /// Handle result after job (except when refreshing!) finished void slotJobResult(KJob *job, bool refresh); private slots: /// Handle result of KIO::DirectorySizeJob when calculating URL size void slotCalcKdsResult(KJob *job); /// Handle result of KIO::StatJob when calculating URL size void slotCalcStatResult(KJob *job); private: - typedef QHash vfileDict; + typedef QHash FileItemDict; - /// Delete and clear vfiles. - void clear(vfileDict &vfiles); + /// Delete and clear file items. + void clear(FileItemDict &fileItems); - vfileDict _vfiles; // The list of files in the current dictionary + FileItemDict _fileItems; // The list of files in the current dictionary // used in the calcSpace function bool *_calcKdsBusy; bool _calcStatBusy; KIO::UDSEntry _calcEntry; KIO::filesize_t *_calcKdsTotalSize; unsigned long *_calcKdsTotalFiles; unsigned long *_calcKdsTotalDirs; }; #endif diff --git a/krusader/VFS/krvfshandler.cpp b/krusader/FileSystem/filesystemprovider.cpp similarity index 59% rename from krusader/VFS/krvfshandler.cpp rename to krusader/FileSystem/filesystemprovider.cpp index eaa3e42f..afc4422c 100644 --- a/krusader/VFS/krvfshandler.cpp +++ b/krusader/FileSystem/filesystemprovider.cpp @@ -1,191 +1,191 @@ /***************************************************************************** * Copyright (C) 2003 Shie Erlich * * Copyright (C) 2003 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -#include "krvfshandler.h" +#include "filesystemprovider.h" #ifdef HAVE_POSIX_ACL #include #ifdef HAVE_NON_POSIX_ACL_EXTENSIONS #include #endif #endif // QtCore #include #include -#include "default_vfs.h" -#include "virt_vfs.h" +#include "defaultfilesystem.h" +#include "virtualfilesystem.h" #include "../krservices.h" -KrVfsHandler::KrVfsHandler() : _defaultVFS(0), _virtVFS(0) {} +FileSystemProvider::FileSystemProvider() : _defaultFileSystem(0), _virtFileSystem(0) {} -vfs *KrVfsHandler::getVfs(const QUrl &url, vfs *oldVfs) +FileSystem *FileSystemProvider::getFilesystem(const QUrl &url, FileSystem *oldFilesystem) { - const vfs::VFS_TYPE type = getVfsType(url); - return oldVfs && oldVfs->type() == type ? oldVfs : createVfs(type); + const FileSystem::FS_TYPE type = getFilesystemType(url); + return oldFilesystem && oldFilesystem->type() == type ? oldFilesystem : createFilesystem(type); } -void KrVfsHandler::startCopyFiles(const QList &urls, const QUrl &destination, +void FileSystemProvider::startCopyFiles(const QList &urls, const QUrl &destination, KIO::CopyJob::CopyMode mode, bool showProgressInfo, bool reverseQueueMode, bool startPaused) { - const vfs::VFS_TYPE type = getVfsType(destination); - vfs *vfs; + const FileSystem::FS_TYPE type = getFilesystemType(destination); + FileSystem *fs; switch (type) { - case vfs::VFS_VIRT: - if (!_virtVFS) - _virtVFS = createVfs(type); - vfs = _virtVFS; + case FileSystem::FS_VIRTUAL: + if (!_virtFileSystem) + _virtFileSystem = createFilesystem(type); + fs = _virtFileSystem; break; default: - if (!_defaultVFS) - _defaultVFS = createVfs(type); - vfs = _defaultVFS; + if (!_defaultFileSystem) + _defaultFileSystem = createFilesystem(type); + fs = _defaultFileSystem; } - vfs->copyFiles(urls, destination, mode, showProgressInfo, reverseQueueMode, startPaused); + fs->copyFiles(urls, destination, mode, showProgressInfo, reverseQueueMode, startPaused); } -void KrVfsHandler::refreshVfs(const QUrl &directory) +void FileSystemProvider::refreshFilesystem(const QUrl &directory) { - QMutableListIterator> it(_vfs_list); + QMutableListIterator> it(_fileSystems); while (it.hasNext()) { if (it.next().isNull()) { it.remove(); } } QString mountPoint = ""; if (directory.isLocalFile()) { KMountPoint::Ptr kMountPoint = KMountPoint::currentMountPoints().findByPath(directory.path()); if (kMountPoint) mountPoint = kMountPoint->mountPoint(); } - for(QPointer vfsPointer: _vfs_list) { - // always refresh virtual vfs showing a virtual directory; it can contain files from various + for(QPointer fileSystemPointer: _fileSystems) { + // always refresh filesystems showing a virtual directory; it can contain files from various // places, we don't know if they were (re)moved, refreshing is also fast enough - vfs *vfs = vfsPointer.data(); - const QUrl vfsDir = vfs->currentDirectory(); - if ((vfsDir == vfs::cleanUrl(directory) || (vfsDir.scheme() == "virt" && !vfs->isRoot())) - && !vfs->hasAutoUpdate()) { - // refresh all vfs currently showing this directory... - vfs->refresh(); - } else if (!mountPoint.isEmpty() && mountPoint == vfs->mountPoint()) { + FileSystem *fs = fileSystemPointer.data(); + const QUrl fileSystemDir = fs->currentDirectory(); + if ((fileSystemDir == FileSystem::cleanUrl(directory) || (fileSystemDir.scheme() == "virt" && !fs->isRoot())) + && !fs->hasAutoUpdate()) { + // refresh all filesystem currently showing this directory... + fs->refresh(); + } else if (!mountPoint.isEmpty() && mountPoint == fs->mountPoint()) { // ..or refresh filesystem info if mount point is the same (for free space update) - vfs->updateFilesystemInfo(); + fs->updateFilesystemInfo(); } } } -vfs *KrVfsHandler::createVfs(vfs::VFS_TYPE type) +FileSystem *FileSystemProvider::createFilesystem(FileSystem::FS_TYPE type) { - vfs *newVfs; + FileSystem *newFilesystem; switch (type) { - case (vfs::VFS_VIRT): newVfs = new virt_vfs(); break; - default: newVfs = new default_vfs(); + case (FileSystem::FS_VIRTUAL): newFilesystem = new VirtualFileSystem(); break; + default: newFilesystem = new DefaultFileSystem(); } - QPointer vfsPointer(newVfs); - _vfs_list.append(vfsPointer); - connect(newVfs, &vfs::filesystemChanged, this, &KrVfsHandler::refreshVfs); - return newVfs; + QPointer fileSystemPointer(newFilesystem); + _fileSystems.append(fileSystemPointer); + connect(newFilesystem, &FileSystem::fileSystemChanged, this, &FileSystemProvider::refreshFilesystem); + return newFilesystem; } // ==== static ==== -KrVfsHandler &KrVfsHandler::instance() +FileSystemProvider &FileSystemProvider::instance() { - static KrVfsHandler instance; + static FileSystemProvider instance; return instance; } -vfs::VFS_TYPE KrVfsHandler::getVfsType(const QUrl &url) +FileSystem::FS_TYPE FileSystemProvider::getFilesystemType(const QUrl &url) { - return url.scheme() == QStringLiteral("virt") ? vfs::VFS_VIRT : vfs::VFS_DEFAULT; + return url.scheme() == QStringLiteral("virt") ? FileSystem::FS_VIRTUAL : FileSystem::FS_DEFAULT; } -void KrVfsHandler::getACL(vfile *file, QString &acl, QString &defAcl) +void FileSystemProvider::getACL(FileItem *file, QString &acl, QString &defAcl) { Q_UNUSED(file); acl.clear(); defAcl.clear(); #ifdef HAVE_POSIX_ACL - QString fileName = vfs::cleanUrl(file->vfile_getUrl()).path(); + QString fileName = FileSystem::cleanUrl(file->getUrl()).path(); #ifdef HAVE_NON_POSIX_ACL_EXTENSIONS if (acl_extended_file(fileName)) { #endif acl = getACL(fileName, ACL_TYPE_ACCESS); - if (file->vfile_isDir()) + if (file->isDir()) defAcl = getACL(fileName, ACL_TYPE_DEFAULT); #ifdef HAVE_NON_POSIX_ACL_EXTENSIONS } #endif #endif } -QString KrVfsHandler::getACL(const QString & path, int type) +QString FileSystemProvider::getACL(const QString & path, int type) { Q_UNUSED(path); Q_UNUSED(type); #ifdef HAVE_POSIX_ACL acl_t acl = 0; // do we have an acl for the file, and/or a default acl for the dir, if it is one? if ((acl = acl_get_file(path.toLocal8Bit(), type)) != 0) { bool aclExtended = false; #ifdef HAVE_NON_POSIX_ACL_EXTENSIONS aclExtended = acl_equiv_mode(acl, 0); #else acl_entry_t entry; int ret = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry); while (ret == 1) { acl_tag_t currentTag; acl_get_tag_type(entry, ¤tTag); if (currentTag != ACL_USER_OBJ && currentTag != ACL_GROUP_OBJ && currentTag != ACL_OTHER) { aclExtended = true; break; } ret = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry); } #endif if (!aclExtended) { acl_free(acl); acl = 0; } } if (acl == 0) return QString(); char *aclString = acl_to_text(acl, 0); QString ret = QString::fromLatin1(aclString); acl_free((void*)aclString); acl_free(acl); return ret; #else return QString(); #endif } diff --git a/krusader/VFS/krvfshandler.h b/krusader/FileSystem/filesystemprovider.h similarity index 70% rename from krusader/VFS/krvfshandler.h rename to krusader/FileSystem/filesystemprovider.h index a481fffc..83f37016 100644 --- a/krusader/VFS/krvfshandler.h +++ b/krusader/FileSystem/filesystemprovider.h @@ -1,79 +1,79 @@ /***************************************************************************** * Copyright (C) 2003 Shie Erlich * * Copyright (C) 2003 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -#ifndef KRVFSHANDLER_H -#define KRVFSHANDLER_H +#ifndef FILESYSTEMPROVIDER_H +#define FILESYSTEMPROVIDER_H // QtCore #include #include #include -#include "vfs.h" +#include "filesystem.h" /** * @brief Provider for virtual file systems. * * This is a singleton. */ -class KrVfsHandler : public QObject { +class FileSystemProvider : public QObject { Q_OBJECT public: /** - * Get a VFS implementation for the filesystem target specified by URL. oldVfs is returned if + * Get a filesystem implementation for the filesystem target specified by URL. oldFilesystem is returned if * the filesystem did not change. * - * The VFS instances returned by this method are already connected with this handler and will + * The filesystem instances returned by this method are already connected with this handler and will * notify each other about filesystem changes. */ - vfs *getVfs(const QUrl &url, vfs *oldVfs = 0); + FileSystem *getFilesystem(const QUrl &url, FileSystem *oldFilesystem = 0); /** * Start a copy job for copying, moving or linking files to a destination directory. * May be implemented async depending on destination filesystem. */ void startCopyFiles(const QList &urls, const QUrl &destination, KIO::CopyJob::CopyMode mode = KIO::CopyJob::Copy, bool showProgressInfo = true, bool reverseQueueMode = false, bool startPaused = false); - static KrVfsHandler &instance(); - static vfs::VFS_TYPE getVfsType(const QUrl &url); + static FileSystemProvider &instance(); + static FileSystem::FS_TYPE getFilesystemType(const QUrl &url); /** Get ACL permissions for a file */ - static void getACL(vfile *file, QString &acl, QString &defAcl); + static void getACL(FileItem *file, QString &acl, QString &defAcl); public slots: - void refreshVfs(const QUrl &directory); + void refreshFilesystem(const QUrl &directory); private: - vfs *createVfs(const vfs::VFS_TYPE type); - KrVfsHandler(); + FileSystem *createFilesystem(const FileSystem::FS_TYPE type); + FileSystemProvider(); - // vfs instances for directory independent file operations, lazy initialized - vfs *_defaultVFS; - vfs *_virtVFS; + // filesystem instances for directory independent file operations, lazy initialized + FileSystem *_defaultFileSystem; + FileSystem *_virtFileSystem; - QList> _vfs_list; + QList> _fileSystems; static QString getACL(const QString & path, int type); }; #endif diff --git a/krusader/VFS/krpermhandler.cpp b/krusader/FileSystem/krpermhandler.cpp similarity index 100% rename from krusader/VFS/krpermhandler.cpp rename to krusader/FileSystem/krpermhandler.cpp diff --git a/krusader/VFS/krpermhandler.h b/krusader/FileSystem/krpermhandler.h similarity index 100% rename from krusader/VFS/krpermhandler.h rename to krusader/FileSystem/krpermhandler.h diff --git a/krusader/VFS/krquery.cpp b/krusader/FileSystem/krquery.cpp similarity index 96% rename from krusader/VFS/krquery.cpp rename to krusader/FileSystem/krquery.cpp index 90158c46..670f46f7 100644 --- a/krusader/VFS/krquery.cpp +++ b/krusader/FileSystem/krquery.cpp @@ -1,740 +1,740 @@ /*************************************************************************** krquery.cpp ------------------- copyright : (C) 2001 by Shie Erlich & Rafi Yanai email : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "krquery.h" // QtCore #include #include #include #include #include #include #include #include -#include "vfs.h" +#include "filesystem.h" #include "krpermhandler.h" #include "../Archive/krarchandler.h" #define STATUS_SEND_DELAY 250 #define MAX_LINE_LEN 1000 // set the defaults KRQuery::KRQuery(): QObject(), matchesCaseSensitive(true), bNull(true), contain(QString()), containCaseSensetive(true), containWholeWord(false), containRegExp(false), minSize(0), maxSize(0), newerThen(0), olderThen(0), owner(QString()), group(QString()), perm(QString()), type(QString()), inArchive(false), recurse(true), followLinksP(true), receivedBuffer(0), receivedBufferLen(0), processEventsConnected(0), codec(QTextCodec::codecForLocale()) { QChar ch = '\n'; QTextCodec::ConverterState state(QTextCodec::IgnoreHeader); encodedEnterArray = codec->fromUnicode(&ch, 1, &state); encodedEnter = encodedEnterArray.data(); encodedEnterLen = encodedEnterArray.size(); } // set the defaults KRQuery::KRQuery(const QString &name, bool matchCase) : QObject(), bNull(true), contain(QString()), containCaseSensetive(true), containWholeWord(false), containRegExp(false), minSize(0), maxSize(0), newerThen(0), olderThen(0), owner(QString()), group(QString()), perm(QString()), type(QString()), inArchive(false), recurse(true), followLinksP(true), receivedBuffer(0), receivedBufferLen(0), processEventsConnected(0), codec(QTextCodec::codecForLocale()) { QChar ch = '\n'; QTextCodec::ConverterState state(QTextCodec::IgnoreHeader); encodedEnterArray = codec->fromUnicode(&ch, 1, &state); encodedEnter = encodedEnterArray.data(); encodedEnterLen = encodedEnterArray.size(); setNameFilter(name, matchCase); } KRQuery::KRQuery(const KRQuery & that) : QObject(), receivedBuffer(0), receivedBufferLen(0), processEventsConnected(0) { *this = that; } KRQuery::~KRQuery() { if (receivedBuffer) delete []receivedBuffer; receivedBuffer = 0; } KRQuery& KRQuery::operator=(const KRQuery & old) { matches = old.matches; excludes = old.excludes; includedDirs = old.includedDirs; excludedDirs = old.excludedDirs; matchesCaseSensitive = old.matchesCaseSensitive; bNull = old.bNull; contain = old.contain; containCaseSensetive = old.containCaseSensetive; containWholeWord = old.containWholeWord; containRegExp = old.containRegExp; minSize = old.minSize; maxSize = old.maxSize; newerThen = old.newerThen; olderThen = old.olderThen; owner = old.owner; group = old.group; perm = old.perm; type = old.type; customType = old.customType; inArchive = old.inArchive; recurse = old.recurse; followLinksP = old.followLinksP; whereToSearch = old.whereToSearch; whereNotToSearch = old.whereNotToSearch; origFilter = old.origFilter; codec = old.codec; encodedEnterArray = old.encodedEnterArray; encodedEnter = encodedEnterArray.data(); encodedEnterLen = encodedEnterArray.size(); return *this; } void KRQuery::load(KConfigGroup cfg) { *this = KRQuery(); // reset parameters first if(cfg.readEntry("IsNull", true)) return; #define LOAD(key, var) (var = cfg.readEntry(key, var)) LOAD("Matches", matches); LOAD("Excludes", excludes); LOAD("IncludedDirs", includedDirs); LOAD("ExcludedDirs", excludedDirs); LOAD("MatchesCaseSensitive", matchesCaseSensitive); LOAD("Contain", contain); LOAD("ContainCaseSensetive", containCaseSensetive); LOAD("ContainWholeWord", containWholeWord); LOAD("ContainRegExp", containRegExp); LOAD("MinSize", minSize); LOAD("MaxSize", maxSize); newerThen = QDateTime::fromString(cfg.readEntry("NewerThan", QDateTime::fromTime_t(newerThen).toString())).toTime_t(); olderThen = QDateTime::fromString(cfg.readEntry("OlderThan", QDateTime::fromTime_t(olderThen).toString())).toTime_t(); LOAD("Owner", owner); LOAD("Group", group); LOAD("Perm", perm); LOAD("Type", type); LOAD("CustomType", customType); LOAD("InArchive", inArchive); LOAD("Recurse", recurse); LOAD("FollowLinks", followLinksP); // KF5 TODO? //LOAD("WhereToSearch", whereToSearch); //LOAD("WhereNotToSearch", whereNotToSearch); LOAD("OrigFilter", origFilter); codec = QTextCodec::codecForName(cfg.readEntry("Codec", codec->name())); if(!codec) codec = QTextCodec::codecForLocale(); LOAD("EncodedEnterArray", encodedEnterArray); encodedEnter = encodedEnterArray.data(); encodedEnterLen = encodedEnterArray.size(); #undef LOAD bNull = false; } void KRQuery::save(KConfigGroup cfg) { cfg.writeEntry("IsNull", bNull); if(bNull) return; cfg.writeEntry("Matches", matches); cfg.writeEntry("Excludes", excludes); cfg.writeEntry("IncludedDirs", includedDirs); cfg.writeEntry("ExcludedDirs", excludedDirs); cfg.writeEntry("MatchesCaseSensitive", matchesCaseSensitive); cfg.writeEntry("Contain", contain); cfg.writeEntry("ContainCaseSensetive", containCaseSensetive); cfg.writeEntry("ContainWholeWord", containWholeWord); cfg.writeEntry("ContainRegExp", containRegExp); cfg.writeEntry("MinSize", minSize); cfg.writeEntry("MaxSize", maxSize); cfg.writeEntry("NewerThan", QDateTime::fromTime_t(newerThen).toString()); cfg.writeEntry("OlderThan", QDateTime::fromTime_t(olderThen).toString()); cfg.writeEntry("Owner", owner); cfg.writeEntry("Group", group); cfg.writeEntry("Perm", perm); cfg.writeEntry("Type", type); cfg.writeEntry("CustomType", customType); cfg.writeEntry("InArchive", inArchive); cfg.writeEntry("Recurse", recurse); cfg.writeEntry("FollowLinks", followLinksP); // KF5 TODO? //cfg.writeEntry("WhereToSearch", whereToSearch); //cfg.writeEntry("WhereNotToSearch", whereNotToSearch); cfg.writeEntry("OrigFilter", origFilter); cfg.writeEntry("Codec", codec->name()); cfg.writeEntry("EncodedEnterArray", encodedEnterArray); cfg.writeEntry("EncodedEnter", encodedEnter); cfg.writeEntry("EncodedEnterLen", encodedEnterLen); } void KRQuery::connectNotify(const QMetaMethod &signal) { if (signal == QMetaMethod::fromSignal(&KRQuery::processEvents)) processEventsConnected++; } void KRQuery::disconnectNotify(const QMetaMethod &signal) { if (signal == QMetaMethod::fromSignal(&KRQuery::processEvents)) processEventsConnected--; } bool KRQuery::checkPerm(QString filePerm) const { for (int i = 0; i < 9; ++i) if (perm[ i ] != '?' && perm[ i ] != filePerm[ i + 1 ]) return false; return true; } bool KRQuery::checkType(QString mime) const { if (type == mime) return true; if (type == i18n("Archives")) return KRarcHandler::arcSupported(mime); if (type == i18n("Folders")) return mime.contains("directory"); if (type == i18n("Image Files")) return mime.contains("image/"); if (type == i18n("Text Files")) return mime.contains("text/"); if (type == i18n("Video Files")) return mime.contains("video/"); if (type == i18n("Audio Files")) return mime.contains("audio/"); if (type == i18n("Custom")) return customType.contains(mime); return false; } bool KRQuery::match(const QString & name) const { return matchCommon(name, matches, excludes); } bool KRQuery::matchDirName(const QString & name) const { return matchCommon(name, includedDirs, excludedDirs); } bool KRQuery::matchCommon(const QString &nameIn, const QStringList &matchList, const QStringList &excludeList) const { if (excludeList.count() == 0 && matchList.count() == 0) /* true if there's no match condition */ return true; QString name(nameIn); int ndx = nameIn.lastIndexOf('/'); // virtual filenames may contain '/' if (ndx != -1) // but the end of the filename is OK name = nameIn.mid(ndx + 1); for (int i = 0; i < excludeList.count(); ++i) { if (QRegExp(excludeList[ i ], matchesCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::Wildcard).exactMatch(name)) return false; } if (matchList.count() == 0) return true; for (int i = 0; i < matchList.count(); ++i) { if (QRegExp(matchList[ i ], matchesCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::Wildcard).exactMatch(name)) return true; } return false; } -bool KRQuery::match(vfile *vf) const +bool KRQuery::match(FileItem *item) const { - if (vf->vfile_isDir() && !matchDirName(vf->vfile_getName())) return false; + if (item->isDir() && !matchDirName(item->getName())) return false; // see if the name matches - if (!match(vf->vfile_getName())) return false; + if (!match(item->getName())) return false; // checking the mime - if (!type.isEmpty() && !checkType(vf->vfile_getMime())) return false; + if (!type.isEmpty() && !checkType(item->getMime())) return false; // check that the size fit - KIO::filesize_t size = vf->vfile_getSize(); + KIO::filesize_t size = item->getSize(); if (minSize && size < minSize) return false; if (maxSize && size > maxSize) return false; // check the time frame - time_t mtime = vf->vfile_getTime_t(); + time_t mtime = item->getTime_t(); if (olderThen && mtime > olderThen) return false; if (newerThen && mtime < newerThen) return false; // check owner name - if (!owner.isEmpty() && vf->vfile_getOwner() != owner) return false; + if (!owner.isEmpty() && item->getOwner() != owner) return false; // check group name - if (!group.isEmpty() && vf->vfile_getGroup() != group) return false; + if (!group.isEmpty() && item->getGroup() != group) return false; //check permission - if (!perm.isEmpty() && !checkPerm(vf->vfile_getPerm())) return false; + if (!perm.isEmpty() && !checkPerm(item->getPerm())) return false; if (!contain.isEmpty()) { - if ((totalBytes = vf->vfile_getSize()) == 0) + if ((totalBytes = item->getSize()) == 0) totalBytes++; // sanity receivedBytes = 0; if (receivedBuffer) delete receivedBuffer; receivedBuffer = 0; receivedBufferLen = 0; - fileName = vf->vfile_getName(); + fileName = item->getName(); timer.start(); // search locally - if (vf->vfile_getUrl().isLocalFile()) { - return containsContent(vf->vfile_getUrl().path()); + if (item->getUrl().isLocalFile()) { + return containsContent(item->getUrl().path()); } // search remotely if (processEventsConnected == 0) { return false; } - return containsContent(vf->vfile_getUrl()); + return containsContent(item->getUrl()); } return true; } // takes the string and adds BOLD to it, so that when it is displayed, // the grepped text will be bold void fixFoundTextForDisplay(QString& haystack, int start, int length) { QString before = haystack.left(start); QString text = haystack.mid(start, length); QString after = haystack.mid(start + length); before.replace('&', "&"); before.replace('<', "<"); before.replace('>', ">"); text.replace('&', "&"); text.replace('<', "<"); text.replace('>', ">"); after.replace('&', "&"); after.replace('<', "<"); after.replace('>', ">"); haystack = ("" + before + "" + text + "" + after + ""); } bool KRQuery::checkBuffer(const char * data, int len) const { bool result = false; char * mergedBuffer = new char [ len + receivedBufferLen ]; if (receivedBufferLen) memcpy(mergedBuffer, receivedBuffer, receivedBufferLen); if (len) memcpy(mergedBuffer + receivedBufferLen, data, len); int maxLen = len + receivedBufferLen; int maxBuffer = maxLen - encodedEnterLen; int lastLinePosition = 0; for (int enterIndex = 0; enterIndex < maxBuffer; enterIndex++) { if (memcmp(mergedBuffer + enterIndex, encodedEnter, encodedEnterLen) == 0) { QString str = codec->toUnicode(mergedBuffer + lastLinePosition, enterIndex + encodedEnterLen - lastLinePosition); if (str.endsWith('\n')) { str.chop(1); result = result || checkLine(str); lastLinePosition = enterIndex + encodedEnterLen; enterIndex = lastLinePosition; continue; } } } if (maxLen - lastLinePosition > MAX_LINE_LEN || len == 0) { QString str = codec->toUnicode(mergedBuffer + lastLinePosition, maxLen - lastLinePosition); result = result || checkLine(str); lastLinePosition = maxLen; } delete []receivedBuffer; receivedBuffer = 0; receivedBufferLen = maxLen - lastLinePosition; if (receivedBufferLen) { receivedBuffer = new char [ receivedBufferLen ]; memcpy(receivedBuffer, mergedBuffer + lastLinePosition, receivedBufferLen); } delete []mergedBuffer; return result; } bool KRQuery::checkLine(const QString & line, bool backwards) const { if (containRegExp) { QRegExp rexp(contain, containCaseSensetive ? Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::RegExp); int ndx = backwards ? rexp.lastIndexIn(line) : rexp.indexIn(line); bool result = ndx >= 0; if (result) fixFoundTextForDisplay(lastSuccessfulGrep = line, lastSuccessfulGrepMatchIndex = ndx, lastSuccessfulGrepMatchLength = rexp.matchedLength()); return result; } int ndx = backwards ? -1 : 0; if (line.isNull()) return false; if (containWholeWord) { while ((ndx = (backwards) ? line.lastIndexOf(contain, ndx, containCaseSensetive ? Qt::CaseSensitive : Qt::CaseInsensitive) : line.indexOf(contain, ndx, containCaseSensetive ? Qt::CaseSensitive : Qt::CaseInsensitive) ) != -1) { QChar before = '\n'; QChar after = '\n'; if (ndx > 0) before = line.at(ndx - 1); if (ndx + contain.length() < line.length()) after = line.at(ndx + contain.length()); if (!before.isLetterOrNumber() && !after.isLetterOrNumber() && after != '_' && before != '_') { lastSuccessfulGrep = line; fixFoundTextForDisplay(lastSuccessfulGrep, lastSuccessfulGrepMatchIndex = ndx, lastSuccessfulGrepMatchLength = contain.length()); return true; } if (backwards) ndx -= line.length() + 1; else ndx++; } } else if ((ndx = (backwards) ? line.lastIndexOf(contain, -1, containCaseSensetive ? Qt::CaseSensitive : Qt::CaseInsensitive) : line.indexOf(contain, 0, containCaseSensetive ? Qt::CaseSensitive : Qt::CaseInsensitive)) != -1) { lastSuccessfulGrep = line; fixFoundTextForDisplay(lastSuccessfulGrep, lastSuccessfulGrepMatchIndex = ndx, lastSuccessfulGrepMatchLength = contain.length()); return true; } return false; } bool KRQuery::containsContent(QString file) const { QFile qf(file); if (!qf.open(QIODevice::ReadOnly)) return false; char buffer[ 1440 ]; // 2k buffer while (!qf.atEnd()) { int bytes = qf.read(buffer, sizeof(buffer)); if (bytes <= 0) break; receivedBytes += bytes; if (checkBuffer(buffer, bytes)) return true; if (checkTimer()) { bool stopped = false; emit((KRQuery *)this)->processEvents(stopped); if (stopped) return false; } } if (checkBuffer(buffer, 0)) return true; lastSuccessfulGrep.clear(); // nothing was found return false; } bool KRQuery::containsContent(QUrl url) const { KIO::TransferJob *contentReader = KIO::get(url, KIO::NoReload, KIO::HideProgressInfo); connect(contentReader, &KIO::TransferJob::data, this, &KRQuery::containsContentData); connect(contentReader, &KIO::Job::result, this, &KRQuery::containsContentFinished); busy = true; containsContentResult = false; bool stopped = false; while (busy && !stopped) { checkTimer(); emit((KRQuery *)this)->processEvents(stopped); } if (busy) { contentReader->kill(KJob::EmitResult); busy = false; } return containsContentResult; } void KRQuery::containsContentData(KIO::Job *job, const QByteArray &array) { receivedBytes += array.size(); if (checkBuffer(array.data(), array.size())) { containsContentResult = true; containsContentFinished(job); job->kill(KJob::EmitResult); return; } checkTimer(); } void KRQuery::containsContentFinished(KJob *) { busy = false; } bool KRQuery::checkTimer() const { if (timer.elapsed() >= STATUS_SEND_DELAY) { int pcnt = (int)(100.*(double)receivedBytes / (double)totalBytes + .5); QString message = i18nc("%1=filename, %2=percentage", "Searching content of '%1' (%2%)", fileName, pcnt); timer.start(); emit((KRQuery *)this)->status(message); return true; } return false; } QStringList KRQuery::split(QString str) { QStringList list; int splitNdx = 0; int startNdx = 0; bool quotation = false; while (splitNdx < str.length()) { if (str[ splitNdx ] == '"') quotation = !quotation; if (!quotation && str[ splitNdx ] == ' ') { QString section = str.mid(startNdx, splitNdx - startNdx); startNdx = splitNdx + 1; if (section.startsWith('\"') && section.endsWith('\"') && section.length() >= 2) section = section.mid(1, section.length() - 2); if (!section.isEmpty()) list.append(section); } splitNdx++; } if (startNdx < splitNdx) { QString section = str.mid(startNdx, splitNdx - startNdx); if (section.startsWith('\"') && section.endsWith('\"') && section.length() >= 2) section = section.mid(1, section.length() - 2); if (!section.isEmpty()) list.append(section); } return list; } void KRQuery::setNameFilter(const QString &text, bool cs) { bNull = false; matchesCaseSensitive = cs; origFilter = text; QString matchText = text; QString excludeText; int excludeNdx = 0; bool quotationMark = 0; while (excludeNdx < matchText.length()) { if (matchText[ excludeNdx ] == '"') quotationMark = !quotationMark; if (!quotationMark) { if (matchText[ excludeNdx ] == '|') break; } excludeNdx++; } if (excludeNdx < matchText.length()) { excludeText = matchText.mid(excludeNdx + 1).trimmed(); matchText.truncate(excludeNdx); matchText = matchText.trimmed(); if (matchText.isEmpty()) matchText = '*'; } int i; matches = split(matchText); includedDirs.clear(); for (i = 0; i < matches.count();) { if (matches[ i ].endsWith('/')) { includedDirs.push_back(matches[ i ].left(matches[ i ].length() - 1)); matches.removeAll(matches.at(i)); continue; } if (!matches[ i ].contains("*") && !matches[ i ].contains("?")) matches[ i ] = '*' + matches[ i ] + '*'; i++; } excludes = split(excludeText); excludedDirs.clear(); for (i = 0; i < excludes.count();) { if (excludes[ i ].endsWith('/')) { excludedDirs.push_back(excludes[ i ].left(excludes[ i ].length() - 1)); excludes.removeAll(excludes.at(i)); continue; } if (!excludes[ i ].contains("*") && !excludes[ i ].contains("?")) excludes[ i ] = '*' + excludes[ i ] + '*'; i++; } } void KRQuery::setContent(const QString &content, bool cs, bool wholeWord, QString encoding, bool regExp) { bNull = false; contain = content; containCaseSensetive = cs; containWholeWord = wholeWord; containRegExp = regExp; if (encoding.isEmpty()) codec = QTextCodec::codecForLocale(); else { codec = QTextCodec::codecForName(encoding.toLatin1()); if (codec == 0) codec = QTextCodec::codecForLocale(); } QChar ch = '\n'; QTextCodec::ConverterState state(QTextCodec::IgnoreHeader); encodedEnterArray = codec->fromUnicode(&ch, 1, &state); encodedEnter = encodedEnterArray.data(); encodedEnterLen = encodedEnterArray.size(); } void KRQuery::setMinimumFileSize(KIO::filesize_t minimumSize) { bNull = false; minSize = minimumSize; } void KRQuery::setMaximumFileSize(KIO::filesize_t maximumSize) { bNull = false; maxSize = maximumSize; } void KRQuery::setNewerThan(time_t time) { bNull = false; newerThen = time; } void KRQuery::setOlderThan(time_t time) { bNull = false; olderThen = time; } void KRQuery::setOwner(const QString &ownerIn) { bNull = false; owner = ownerIn; } void KRQuery::setGroup(const QString &groupIn) { bNull = false; group = groupIn; } void KRQuery::setPermissions(const QString &permIn) { bNull = false; perm = permIn; } void KRQuery::setMimeType(const QString &typeIn, QStringList customList) { bNull = false; type = typeIn; customType = customList; } bool KRQuery::isExcluded(const QUrl &url) { for (int i = 0; i < whereNotToSearch.count(); ++i) if (whereNotToSearch [ i ].isParentOf(url) || url.matches(whereNotToSearch [ i ], QUrl::StripTrailingSlash)) return true; if (!matchDirName(url.fileName())) return true; return false; } void KRQuery::setSearchInDirs(const QList &urls) { whereToSearch.clear(); for (int i = 0; i < urls.count(); ++i) { QString url = urls[ i ].url(); QUrl completed = QUrl::fromUserInput(KUrlCompletion::replacedPath(url, true, true), QString(), QUrl::AssumeLocalFile); whereToSearch.append(completed); } } void KRQuery::setDontSearchInDirs(const QList &urls) { whereNotToSearch.clear(); for (int i = 0; i < urls.count(); ++i) { QString url = urls[ i ].url(); QUrl completed = QUrl::fromUserInput(KUrlCompletion::replacedPath(url, true, true), QString(), QUrl::AssumeLocalFile); whereNotToSearch.append(completed); } } diff --git a/krusader/VFS/krquery.h b/krusader/FileSystem/krquery.h similarity index 98% rename from krusader/VFS/krquery.h rename to krusader/FileSystem/krquery.h index 47910bc1..afd45db9 100644 --- a/krusader/VFS/krquery.h +++ b/krusader/FileSystem/krquery.h @@ -1,266 +1,266 @@ /*************************************************************************** krquery.h ------------------- copyright : (C) 2001 by Shie Erlich & Rafi Yanai email : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KRQUERY_H #define KRQUERY_H // QtCore #include #include #include #include #include class KFileItem; class QTextCodec; -class vfile; +class FileItem; /** * @brief A search query for files * * Can be used for finding or selecting files and folders by multiple limiting search criteria */ class KRQuery : public QObject { Q_OBJECT public: // null query KRQuery(); // query only with name filter KRQuery(const QString &name, bool matchCase = true); // copy constructor KRQuery(const KRQuery &); // let operator KRQuery& operator=(const KRQuery &); // destructor virtual ~KRQuery(); //load parameters from config void load(KConfigGroup cfg); //save parameters to config void save(KConfigGroup cfg); // matching a file with the query - bool match(vfile *file) const; // checks if the given vfile object matches the conditions + bool match(FileItem *file) const; // checks if the given fileItem object matches the conditions // matching a name with the query bool match(const QString &name) const; // matching the filename only // matching the name of the directory bool matchDirName(const QString &name) const; // sets the text for name filtering void setNameFilter(const QString &text, bool cs = true); // returns the current filter mask const QString& nameFilter() const { return origFilter; } // returns whether the filter is case sensitive bool isCaseSensitive() { return matchesCaseSensitive; } // returns if the filter is null (was cancelled) bool isNull() { return bNull; }; // sets the content part of the query void setContent(const QString &content, bool cs = true, bool wholeWord = false, QString encoding = QString(), bool regExp = false); const QString content() { return contain; } // sets the minimum file size limit void setMinimumFileSize(KIO::filesize_t); // sets the maximum file size limit void setMaximumFileSize(KIO::filesize_t); // sets the time the file newer than void setNewerThan(time_t time); // sets the time the file older than void setOlderThan(time_t time); // sets the owner void setOwner(const QString &ownerIn); // sets the group void setGroup(const QString &groupIn); // sets the permissions void setPermissions(const QString &permIn); // sets the mimetype for the query // type, must be one of the following: // 1. a valid mime type name // 2. one of: i18n("Archives"), i18n("Folders"), i18n("Image Files") // i18n("Text Files"), i18n("Video Files"), i18n("Audio Files") // 3. i18n("Custom") in which case you must supply a list of valid mime-types // in the member QStringList customType void setMimeType(const QString &typeIn, QStringList customList = QStringList()); // true if setMimeType was called bool hasMimeType() { return type.isEmpty(); } // sets the search in archive flag void setSearchInArchives(bool flag) { inArchive = flag; } // gets the search in archive flag bool searchInArchives() { return inArchive; } // sets the recursive flag void setRecursive(bool flag) { recurse = flag; } // gets the recursive flag bool isRecursive() { return recurse; } // sets whether to follow symbolic links void setFollowLinks(bool flag) { followLinksP = flag; } // gets whether to follow symbolic links bool followLinks() { return followLinksP; } // sets the folders where the searcher will search void setSearchInDirs(const QList &urls); // gets the folders where the searcher searches const QList & searchInDirs() { return whereToSearch; } // sets the folders where search is not permitted void setDontSearchInDirs(const QList &urls); // gets the folders where search is not permitted const QList & dontSearchInDirs() { return whereNotToSearch; } // checks if a URL is excluded bool isExcluded(const QUrl &url); // gives whether we search for content bool isContentSearched() const { return !contain.isEmpty(); } bool checkLine(const QString &line, bool backwards = false) const; const QString& foundText() const { return lastSuccessfulGrep; } int matchIndex() const { return lastSuccessfulGrepMatchIndex; } int matchLength() const { return lastSuccessfulGrepMatchLength; } protected: // important to know whether the event processor is connected virtual void connectNotify(const QMetaMethod &signal) Q_DECL_OVERRIDE; // important to know whether the event processor is connected virtual void disconnectNotify(const QMetaMethod &signal) Q_DECL_OVERRIDE; protected: QStringList matches; // what to search QStringList excludes; // what to exclude QStringList includedDirs; // what dirs to include QStringList excludedDirs; // what dirs to exclude bool matchesCaseSensitive; bool bNull; // flag if the query is null QString contain; // file must contain this string bool containCaseSensetive; bool containWholeWord; bool containRegExp; KIO::filesize_t minSize; KIO::filesize_t maxSize; time_t newerThen; time_t olderThen; QString owner; QString group; QString perm; QString type; QStringList customType; bool inArchive; // if true- search in archive. bool recurse; // if true recurse ob sub-dirs... bool followLinksP; QList whereToSearch; // directories to search QList whereNotToSearch; // directories NOT to search signals: void status(const QString &name); void processEvents(bool & stopped); private: bool matchCommon(const QString &, const QStringList &, const QStringList &) const; bool checkPerm(QString perm) const; bool checkType(QString mime) const; bool containsContent(QString file) const; bool containsContent(QUrl url) const; bool checkBuffer(const char * data, int len) const; bool checkTimer() const; QStringList split(QString); private slots: void containsContentData(KIO::Job *, const QByteArray &); void containsContentFinished(KJob*); private: QString origFilter; mutable bool busy; mutable bool containsContentResult; mutable char * receivedBuffer; mutable int receivedBufferLen; mutable QString lastSuccessfulGrep; mutable int lastSuccessfulGrepMatchIndex; mutable int lastSuccessfulGrepMatchLength; mutable QString fileName; mutable KIO::filesize_t receivedBytes; mutable KIO::filesize_t totalBytes; mutable int processEventsConnected; mutable QTime timer; QTextCodec * codec; const char * encodedEnter; int encodedEnterLen; QByteArray encodedEnterArray; }; #endif diff --git a/krusader/VFS/krtrashhandler.cpp b/krusader/FileSystem/krtrashhandler.cpp similarity index 93% rename from krusader/VFS/krtrashhandler.cpp rename to krusader/FileSystem/krtrashhandler.cpp index 6bde538a..3fff6716 100644 --- a/krusader/VFS/krtrashhandler.cpp +++ b/krusader/FileSystem/krtrashhandler.cpp @@ -1,124 +1,124 @@ /*************************************************************************** krtrashhandler.cpp - description ------------------- copyright : (C) 2009 + by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "krtrashhandler.h" // QtCore #include #include #include #include #include #include #include #include #include -#include "krvfshandler.h" +#include "filesystemprovider.h" #include "../kractions.h" #include "../krglobal.h" KrTrashWatcher * KrTrashHandler::_trashWatcher = 0; bool KrTrashHandler::isTrashEmpty() { KConfig trashConfig("trashrc"); KConfigGroup cfg(&trashConfig, "Status"); return cfg.readEntry("Empty", false); } QString KrTrashHandler::trashIcon() { return isTrashEmpty() ? "user-trash" : "user-trash-full"; } void KrTrashHandler::emptyTrash() { KIO::JobUiDelegate uiDelegate; uiDelegate.setWindow(krMainWindow); if (!uiDelegate.askDeleteConfirmation(QList(), KIO::JobUiDelegate::EmptyTrash, KIO::JobUiDelegate::DefaultConfirmation)) return; KIO::Job *job = KIO::emptyTrash(); KJobWidgets::setWindow(job, krMainWindow); job->ui()->setAutoErrorHandlingEnabled(true); const QUrl url = QUrl("trash:/"); - QObject::connect(job, &KIO::Job::result, [=]() { KrVfsHandler::instance().refreshVfs(url); }); + QObject::connect(job, &KIO::Job::result, [=]() { FileSystemProvider::instance().refreshFilesystem(url); }); } void KrTrashHandler::restoreTrashedFiles(const QList &urls) { if (urls.isEmpty()) return; KIO::RestoreJob *job = KIO::restoreFromTrash(urls); KJobWidgets::setWindow(job, krMainWindow); job->uiDelegate()->setAutoErrorHandlingEnabled(true); const QUrl url = urls.first().adjusted(QUrl::RemoveFilename); - QObject::connect(job, &KIO::Job::result, [=]() { KrVfsHandler::instance().refreshVfs(url); }); + QObject::connect(job, &KIO::Job::result, [=]() { FileSystemProvider::instance().refreshFilesystem(url); }); } void KrTrashHandler::startWatcher() { if (!_trashWatcher) _trashWatcher = new KrTrashWatcher(); } void KrTrashHandler::stopWatcher() { delete _trashWatcher; _trashWatcher = 0; } KrTrashWatcher::KrTrashWatcher() { _watcher = new KDirWatch(); connect(_watcher, &KDirWatch::created, this, &KrTrashWatcher::slotTrashChanged); connect(_watcher, &KDirWatch::dirty, this, &KrTrashWatcher::slotTrashChanged); const QString trashrcFile = QDir(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)).filePath("trashrc"); _watcher->addFile(trashrcFile); _watcher->startScan(true); } KrTrashWatcher::~KrTrashWatcher() { delete _watcher; _watcher = 0; } void KrTrashWatcher::slotTrashChanged() { KrActions::actTrashBin->setIcon(QIcon::fromTheme(KrTrashHandler::trashIcon())); } diff --git a/krusader/VFS/krtrashhandler.h b/krusader/FileSystem/krtrashhandler.h similarity index 100% rename from krusader/VFS/krtrashhandler.h rename to krusader/FileSystem/krtrashhandler.h diff --git a/krusader/VFS/virt_vfs.cpp b/krusader/FileSystem/virtualfilesystem.cpp similarity index 63% rename from krusader/VFS/virt_vfs.cpp rename to krusader/FileSystem/virtualfilesystem.cpp index 2b037d57..92c91ede 100644 --- a/krusader/VFS/virt_vfs.cpp +++ b/krusader/FileSystem/virtualfilesystem.cpp @@ -1,365 +1,365 @@ /***************************************************************************** * Copyright (C) 2003 Shie Erlich * * Copyright (C) 2003 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -#include "virt_vfs.h" +#include "virtualfilesystem.h" // QtCore #include #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include "../defaults.h" #include "../krglobal.h" #include "../krservices.h" -#define VIRT_VFS_DB "virt_vfs.db" +#define VIRTUALFILESYSTEM_DB "virtualfilesystem.db" -QHash *> virt_vfs::_virtVfsDict; -QHash virt_vfs::_metaInfoDict; +QHash *> VirtualFileSystem::_virtFilesystemDict; +QHash VirtualFileSystem::_metaInfoDict; -virt_vfs::virt_vfs() : vfs() +VirtualFileSystem::VirtualFileSystem() : FileSystem() { - if (_virtVfsDict.isEmpty()) { + if (_virtFilesystemDict.isEmpty()) { restore(); } - _type = VFS_VIRT; + _type = FS_VIRTUAL; } -void virt_vfs::copyFiles(const QList &urls, const QUrl &destination, +void VirtualFileSystem::copyFiles(const QList &urls, const QUrl &destination, KIO::CopyJob::CopyMode /*mode*/, bool /*showProgressInfo*/, bool /*reverseQueueMode*/, bool /*startPaused*/) { const QString dir = QDir(destination.path()).absolutePath().remove('/'); if (dir.isEmpty()) { showError(i18n("You cannot copy files directly to the 'virt:/' folder.\n" "You can create a sub folder and copy your files into it.")); return; } - if (!_virtVfsDict.contains(dir)) { + if (!_virtFilesystemDict.contains(dir)) { mkDirInternal(dir); } - QList *urlList = _virtVfsDict[dir]; + QList *urlList = _virtFilesystemDict[dir]; for (const QUrl &fileUrl : urls) { if (!urlList->contains(fileUrl)) { urlList->push_back(fileUrl); } } - emit filesystemChanged(QUrl("virt:///" + dir)); // may call refresh() + emit fileSystemChanged(QUrl("virt:///" + dir)); // may call refresh() } -void virt_vfs::dropFiles(const QUrl &destination, QDropEvent *event) +void VirtualFileSystem::dropFiles(const QUrl &destination, QDropEvent *event) { const QList &urls = KUrlMimeData::urlsFromMimeData(event->mimeData()); - // dropping on virtual vfs (sic!) is always copy operation + // dropping on virtual filesystem is always copy operation copyFiles(urls, destination); } -void virt_vfs::addFiles(const QList &fileUrls, KIO::CopyJob::CopyMode /*mode*/, QString dir) +void VirtualFileSystem::addFiles(const QList &fileUrls, KIO::CopyJob::CopyMode /*mode*/, QString dir) { QUrl destination(_currentDirectory); if (!dir.isEmpty()) { destination.setPath(QDir::cleanPath(destination.path() + '/' + dir)); } copyFiles(fileUrls, destination); } -void virt_vfs::remove(const QStringList &fileNames) +void VirtualFileSystem::remove(const QStringList &fileNames) { const QString parentDir = currentDir(); if (parentDir == "/") { // remove virtual directory for (const QString &filename : fileNames) { - _virtVfsDict["/"]->removeAll(QUrl(QStringLiteral("virt:/") + filename)); - delete _virtVfsDict[filename]; - _virtVfsDict.remove(filename); + _virtFilesystemDict["/"]->removeAll(QUrl(QStringLiteral("virt:/") + filename)); + delete _virtFilesystemDict[filename]; + _virtFilesystemDict.remove(filename); _metaInfoDict.remove(filename); } } else { // remove the URLs from the collection for (const QString name : fileNames) { - if (_virtVfsDict.find(parentDir) != _virtVfsDict.end()) { - QList *urlList = _virtVfsDict[parentDir]; + if (_virtFilesystemDict.find(parentDir) != _virtFilesystemDict.end()) { + QList *urlList = _virtFilesystemDict[parentDir]; urlList->removeAll(getUrl(name)); } } } - emit filesystemChanged(currentDirectory()); // will call refresh() + emit fileSystemChanged(currentDirectory()); // will call refresh() } -QUrl virt_vfs::getUrl(const QString &name) +QUrl VirtualFileSystem::getUrl(const QString &name) { - vfile *vf = getVfile(name); - if (!vf) { + FileItem *item = getFileItem(name); + if (!item) { return QUrl(); // not found } - return vf->vfile_getUrl(); + return item->getUrl(); } -void virt_vfs::mkDir(const QString &name) +void VirtualFileSystem::mkDir(const QString &name) { if (currentDir() != "/") { showError(i18n("Creating new folders is allowed only in the 'virt:/' folder.")); return; } mkDirInternal(name); - emit filesystemChanged(currentDirectory()); // will call refresh() + emit fileSystemChanged(currentDirectory()); // will call refresh() } -void virt_vfs::rename(const QString &fileName, const QString &newName) +void VirtualFileSystem::rename(const QString &fileName, const QString &newName) { - vfile *vf = getVfile(fileName); - if (!vf) + FileItem *item = getFileItem(fileName); + if (!item) return; // not found if (currentDir() == "/") { // rename virtual directory - _virtVfsDict["/"]->append(QUrl(QStringLiteral("virt:/") + newName)); - _virtVfsDict["/"]->removeAll(QUrl(QStringLiteral("virt:/") + fileName)); - _virtVfsDict.insert(newName, _virtVfsDict.take(fileName)); + _virtFilesystemDict["/"]->append(QUrl(QStringLiteral("virt:/") + newName)); + _virtFilesystemDict["/"]->removeAll(QUrl(QStringLiteral("virt:/") + fileName)); + _virtFilesystemDict.insert(newName, _virtFilesystemDict.take(fileName)); refresh(); return; } // newName can be a (local) path or a full url QUrl dest(newName); if (dest.scheme().isEmpty()) dest.setScheme("file"); // add the new url to the list // the list is refreshed, only existing files remain - // so we don't have to worry if the job was successful - _virtVfsDict[currentDir()]->append(dest); + _virtFilesystemDict[currentDir()]->append(dest); - KIO::Job *job = KIO::moveAs(vf->vfile_getUrl(), dest, KIO::HideProgressInfo); + KIO::Job *job = KIO::moveAs(item->getUrl(), dest, KIO::HideProgressInfo); connect(job, &KIO::Job::result, this, [=](KJob* job) { slotJobResult(job, false); }); - connect(job, &KIO::Job::result, [=]() { emit filesystemChanged(currentDirectory()); }); + connect(job, &KIO::Job::result, [=]() { emit fileSystemChanged(currentDirectory()); }); } -void virt_vfs::calcSpace(const QString &name, KIO::filesize_t *totalSize, unsigned long *totalFiles, +void VirtualFileSystem::calcSpace(const QString &name, KIO::filesize_t *totalSize, unsigned long *totalFiles, unsigned long *totalDirs, bool *stop) { if (currentDir() == "/") { - if (!_virtVfsDict.contains(name)) { + if (!_virtFilesystemDict.contains(name)) { return; // virtual folder not found } - const QList *urlList = _virtVfsDict[name]; + const QList *urlList = _virtFilesystemDict[name]; if (urlList) { for (int i = 0; (i != urlList->size()) && !(*stop); i++) { - vfs::calcSpace((*urlList)[i], totalSize, totalFiles, totalDirs, stop); + FileSystem::calcSpace((*urlList)[i], totalSize, totalFiles, totalDirs, stop); } } return; } - vfs::calcSpace(name, totalSize, totalFiles, totalDirs, stop); + FileSystem::calcSpace(name, totalSize, totalFiles, totalDirs, stop); } -bool virt_vfs::canMoveToTrash(const QStringList &fileNames) +bool VirtualFileSystem::canMoveToTrash(const QStringList &fileNames) { if (isRoot()) return false; for (const QString fileName : fileNames) { if (!getUrl(fileName).isLocalFile()) { return false; } } return true; } -void virt_vfs::setMetaInformation(const QString &info) +void VirtualFileSystem::setMetaInformation(const QString &info) { _metaInfoDict[currentDir()] = info; } // ==== protected ==== -bool virt_vfs::refreshInternal(const QUrl &directory, bool /*showHidden*/) +bool VirtualFileSystem::refreshInternal(const QUrl &directory, bool /*showHidden*/) { _currentDirectory = cleanUrl(directory); _currentDirectory.setHost(""); // remove invalid subdirectories _currentDirectory.setPath("/" + _currentDirectory.path().remove('/')); - if (!_virtVfsDict.contains(currentDir())) { + if (!_virtFilesystemDict.contains(currentDir())) { // NOTE: silently creating non-existing directories here. The search and locate tools expect // this. (And user can enter some directory and it will be created). mkDirInternal(currentDir()); save(); // infinite loop possible - //emit filesystemChanged(currentDirectory()); + //emit fileSystemChanged(currentDirectory()); return true; } - QList *urlList = _virtVfsDict[currentDir()]; + QList *urlList = _virtFilesystemDict[currentDir()]; const QString metaInfo = _metaInfoDict[currentDir()]; - emit filesystemInfoChanged(metaInfo.isEmpty() ? i18n("Virtual filesystem") : metaInfo, "", 0, 0); + emit fileSystemInfoChanged(metaInfo.isEmpty() ? i18n("Virtual filesystem") : metaInfo, "", 0, 0); QMutableListIterator it(*urlList); while (it.hasNext()) { const QUrl url = it.next(); - vfile *vf = createVFile(url); - if (!vf) { // remove URL from the list for a file that no longer exists + FileItem *item = createFileItem(url); + if (!item) { // remove URL from the list for a file that no longer exists it.remove(); } else { - addVfile(vf); + addFileItem(item); } } save(); return true; } // ==== private ==== -void virt_vfs::mkDirInternal(const QString &name) +void VirtualFileSystem::mkDirInternal(const QString &name) { // clean path, consistent with currentDir() QString dirName = name; dirName = dirName.remove('/'); if (dirName.isEmpty()) dirName = "/"; - _virtVfsDict.insert(dirName, new QList()); - _virtVfsDict["/"]->append(QUrl(QStringLiteral("virt:/") + dirName)); + _virtFilesystemDict.insert(dirName, new QList()); + _virtFilesystemDict["/"]->append(QUrl(QStringLiteral("virt:/") + dirName)); } -void virt_vfs::save() +void VirtualFileSystem::save() { - KConfig *db = &virt_vfs::getVirtDB(); + KConfig *db = &VirtualFileSystem::getVirtDB(); db->deleteGroup("virt_db"); KConfigGroup group(db, "virt_db"); - QHashIterator *> it(_virtVfsDict); + QHashIterator *> it(_virtFilesystemDict); while (it.hasNext()) { it.next(); QList *urlList = it.value(); QList::iterator url; QStringList entry; for (url = urlList->begin(); url != urlList->end(); ++url) { entry.append((*url).toDisplayString()); } // KDE 4.0 workaround: 'Item_' prefix is added as KConfig fails on 1 char names (such as /) group.writeEntry("Item_" + it.key(), entry); group.writeEntry("MetaInfo_" + it.key(), _metaInfoDict[it.key()]); } db->sync(); } -void virt_vfs::restore() +void VirtualFileSystem::restore() { - KConfig *db = &virt_vfs::getVirtDB(); + KConfig *db = &VirtualFileSystem::getVirtDB(); const KConfigGroup dbGrp(db, "virt_db"); const QMap map = db->entryMap("virt_db"); QMapIterator it(map); while (it.hasNext()) { it.next(); // KDE 4.0 workaround: check and remove 'Item_' prefix if (!it.key().startsWith(QLatin1String("Item_"))) continue; const QString key = it.key().mid(5); const QList urlList = KrServices::toUrlList(dbGrp.readEntry(it.key(), QStringList())); - _virtVfsDict.insert(key, new QList(urlList)); + _virtFilesystemDict.insert(key, new QList(urlList)); _metaInfoDict.insert(key, dbGrp.readEntry("MetaInfo_" + key, QString())); } - if (!_virtVfsDict["/"]) { // insert root element if missing for some reason - _virtVfsDict.insert("/", new QList()); + if (!_virtFilesystemDict["/"]) { // insert root element if missing for some reason + _virtFilesystemDict.insert("/", new QList()); } } -vfile *virt_vfs::createVFile(const QUrl &url) +FileItem *VirtualFileSystem::createFileItem(const QUrl &url) { if (url.scheme() == "virt") { // return a virtual directory in root QString path = url.path().mid(1); if (path.isEmpty()) path = '/'; - return vfile::createVirtualDir(path, url); + return FileItem::createVirtualDir(path, url); } const QUrl directory = url.adjusted(QUrl::RemoveFilename); if (url.isLocalFile()) { QFileInfo file(url.path()); - return file.exists() ? vfs::createLocalVFile(url.fileName(), directory.path(), true) : 0; + return file.exists() ? FileSystem::createLocalFileItem(url.fileName(), directory.path(), true) : 0; } KIO::StatJob *statJob = KIO::stat(url, KIO::HideProgressInfo); - connect(statJob, &KIO::Job::result, this, &virt_vfs::slotStatResult); + connect(statJob, &KIO::Job::result, this, &VirtualFileSystem::slotStatResult); // ugly: we have to wait here until the stat job is finished QEventLoop eventLoop; connect(statJob, &KJob::finished, &eventLoop, &QEventLoop::quit); eventLoop.exec(); // blocking until quit() if (_fileEntry.count() == 0) { return 0; // stat job failed } if (!_fileEntry.contains(KIO::UDSEntry::UDS_MODIFICATION_TIME)) { // TODO this also happens for FTP directories return 0; // file not found } - return vfs::createVFileFromKIO(_fileEntry, directory, true); + return FileSystem::createFileItemFromKIO(_fileEntry, directory, true); } -KConfig &virt_vfs::getVirtDB() +KConfig &VirtualFileSystem::getVirtDB() { - //virt_vfs_db = new KConfig("data",VIRT_VFS_DB,KConfig::NoGlobals); - static KConfig db(VIRT_VFS_DB, KConfig::CascadeConfig, QStandardPaths::AppDataLocation); + //virtualfilesystem_db = new KConfig("data",VIRTUALFILESYSTEM_DB,KConfig::NoGlobals); + static KConfig db(VIRTUALFILESYSTEM_DB, KConfig::CascadeConfig, QStandardPaths::AppDataLocation); return db; } -void virt_vfs::slotStatResult(KJob *job) +void VirtualFileSystem::slotStatResult(KJob *job) { _fileEntry = job->error() ? KIO::UDSEntry() : static_cast(job)->statResult(); } -void virt_vfs::showError(const QString &error) +void VirtualFileSystem::showError(const QString &error) { QWidget *window = QApplication::activeWindow(); KMessageBox::sorry(window, error); // window can be null, is allowed } diff --git a/krusader/VFS/virt_vfs.h b/krusader/FileSystem/virtualfilesystem.h similarity index 89% rename from krusader/VFS/virt_vfs.h rename to krusader/FileSystem/virtualfilesystem.h index 9be741dc..52765b2a 100644 --- a/krusader/VFS/virt_vfs.h +++ b/krusader/FileSystem/virtualfilesystem.h @@ -1,105 +1,105 @@ /***************************************************************************** * Copyright (C) 2003 Shie Erlich * * Copyright (C) 2003 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ -#ifndef VIRT_VFS_H -#define VIRT_VFS_H +#ifndef VIRTUALFILESYSTEM_H +#define VIRTUALFILESYSTEM_H // QtCore #include -#include "vfs.h" +#include "filesystem.h" /** * Custom virtual filesystem implementation: It holds arbitrary lists of files which are only * virtual references to real files. The filename of a virtual file is the full path of the real * file. * * Only two filesystem levels are supported: On root level only directories can be created; these * virtual root directories can contain a set of virtual files and directories. Entering a directory * on the sublevel is out of scope and the real directory will be opened. * * The filesystem content is saved in a separate config file and preserved between application runs. * * Used at least by bookmarks, locate, search and synchronizer dialog. */ -class virt_vfs : public vfs +class VirtualFileSystem : public FileSystem { Q_OBJECT public: - virt_vfs(); + VirtualFileSystem(); - /// Create virtual files in this VFS. Copy mode and showProgressInfo are ignored. + /// Create virtual files in this filesystem. Copy mode and showProgressInfo are ignored. void copyFiles(const QList &urls, const QUrl &destination, KIO::CopyJob::CopyMode mode = KIO::CopyJob::Copy, bool showProgressInfo = true, bool reverseQueueMode = false, bool startPaused = false) Q_DECL_OVERRIDE; - /// Handle file dropping in this VFS: Always creates virtual files. + /// Handle file dropping in this filesystem: Always creates virtual files. void dropFiles(const QUrl &destination, QDropEvent *event) Q_DECL_OVERRIDE; /// Add virtual files to the current directory. void addFiles(const QList &fileUrls, KIO::CopyJob::CopyMode mode = KIO::CopyJob::Copy, QString dir = "") Q_DECL_OVERRIDE; /// Create a virtual directory. Only possible in the root directory. void mkDir(const QString &name) Q_DECL_OVERRIDE; /// Rename a (real) file in the current directory. void rename(const QString &fileName, const QString &newName) Q_DECL_OVERRIDE; void calcSpace(const QString &name, KIO::filesize_t *totalSize, unsigned long *totalFiles, unsigned long *totalDirs, bool *stop) Q_DECL_OVERRIDE; /// Returns the URL of the real file or an empty URL if file with name does not exist. QUrl getUrl(const QString& name) Q_DECL_OVERRIDE; bool canMoveToTrash(const QStringList &fileNames) Q_DECL_OVERRIDE; /// Remove virtual files or directories. Real files stay untouched. void remove(const QStringList &fileNames); /// Set meta information to be displayed in UI for the current directory void setMetaInformation(const QString &info); protected: bool refreshInternal(const QUrl &origin, bool showHidden) Q_DECL_OVERRIDE; private: /// Return current dir: "/" or pure directory name inline QString currentDir() { const QString path = _currentDirectory.path().mid(1); // remove slash return path.isEmpty() ? "/" : path; } void mkDirInternal(const QString& name); /// Save the dictionary to file void save(); /// Restore the dictionary from file void restore(); - /// Create local or KIO vfile. Returns 0 if file does not exist - vfile *createVFile(const QUrl &url); + /// Create local or KIO fileItem. Returns 0 if file does not exist + FileItem *createFileItem(const QUrl &url); /// Return the configuration file storing the urls of virtual files KConfig &getVirtDB(); private slots: void slotStatResult(KJob *job); private: void showError(const QString &error); - static QHash *> _virtVfsDict; // map virtual directories to containing files + static QHash *> _virtFilesystemDict; // map virtual directories to containing files static QHash _metaInfoDict; // map virtual directories to meta infos QString _metaInfo; // displayable string with information about the current virtual directory KIO::UDSEntry _fileEntry; // for async call, save stat job result here }; #endif diff --git a/krusader/Filter/filterdialog.h b/krusader/Filter/filterdialog.h index d5b4ccd8..e09414f4 100644 --- a/krusader/Filter/filterdialog.h +++ b/krusader/Filter/filterdialog.h @@ -1,69 +1,69 @@ /*************************************************************************** filterdialog.h - description ------------------- copyright : (C) 2005 + by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILTERDIALOG_H #define FILTERDIALOG_H #include "filtersettings.h" -#include "../VFS/krquery.h" +#include "../FileSystem/krquery.h" // QtWidgets #include class FilterTabs; class GeneralFilter; class FilterDialog : public QDialog { Q_OBJECT public: FilterDialog(QWidget *parent = 0, QString caption = QString(), QStringList extraOptions = QStringList(), bool modal = true); KRQuery getQuery(); const FilterSettings& getSettings() { return settings; } void applySettings(const FilterSettings &s); bool isExtraOptionChecked(QString name); void checkExtraOption(QString name, bool check); public slots: void slotCloseRequest(bool doAccept); void slotReset(); void slotOk(); private: FilterTabs * filterTabs; GeneralFilter * generalFilter; FilterSettings settings; }; #endif /* FILTERDIALOG_H */ diff --git a/krusader/Filter/filtersettings.h b/krusader/Filter/filtersettings.h index 8edceca1..cd5c3146 100644 --- a/krusader/Filter/filtersettings.h +++ b/krusader/Filter/filtersettings.h @@ -1,126 +1,126 @@ /*************************************************************************** filtersettings.h - description ------------------- copyright : (C) 2011 + by Jan Lepper e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILTERSETTINGS_H #define FILTERSETTINGS_H -#include "../VFS/krquery.h" +#include "../FileSystem/krquery.h" #include class FilterSettings { friend class FilterTabs; friend class GeneralFilter; friend class AdvancedFilter; public: FilterSettings(); FilterSettings& operator=(const FilterSettings& other); bool isValid() const { return valid; } void load(KConfigGroup cfg); void save(KConfigGroup cfg) const; KRQuery toQuery() const; private: enum SizeUnit { Byte = 0, KiloByte, MegaByte, GigaByte }; enum TimeUnit { Day = 0, Week, Month, Year }; class FileSize { public: FileSize() : amount(0), unit(Byte) {} FileSize& operator=(const FileSize &other); KIO::filesize_t size() const; KIO::filesize_t amount; SizeUnit unit; }; class TimeSpan { public: TimeSpan() : amount(0), unit(Day) {} TimeSpan& operator=(const TimeSpan &other); int days() const; int amount; TimeUnit unit; }; static void saveDate(QString key, const QDate &date, KConfigGroup &cfg); static time_t qdate2time_t(QDate d, bool start); bool valid; QString searchFor; bool searchForCase; QString mimeType; bool searchInArchives; bool recursive; bool followLinks; QList searchIn; QList dontSearchIn; QString contentEncoding; QString containsText; bool containsTextCase; bool containsWholeWord; bool containsRegExp; bool minSizeEnabled; FileSize minSize; bool maxSizeEnabled; FileSize maxSize; bool modifiedBetweenEnabled; QDate modifiedBetween1; QDate modifiedBetween2; bool notModifiedAfterEnabled; QDate notModifiedAfter; bool modifiedInTheLastEnabled; TimeSpan modifiedInTheLast; TimeSpan notModifiedInTheLast; bool ownerEnabled; QString owner; bool groupEnabled; QString group; bool permissionsEnabled; QString permissions; }; #endif //FILTERSETTINGS_H diff --git a/krusader/Filter/generalfilter.cpp b/krusader/Filter/generalfilter.cpp index ac10688a..2d286b89 100644 --- a/krusader/Filter/generalfilter.cpp +++ b/krusader/Filter/generalfilter.cpp @@ -1,599 +1,599 @@ /*************************************************************************** generalfilter.cpp - description ------------------- copyright : (C) 2003 + by Shie Erlich & Rafi Yanai & Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "generalfilter.h" #include "filtertabs.h" #include "../krglobal.h" #include "../krservices.h" -#include "../VFS/vfs.h" +#include "../FileSystem/filesystem.h" // QtWidgets #include #include #include #include #include #include #include #include #include #include typedef struct { const char *description; const char *regExp; int cursorAdjustment; } term; static const term items[] = { { I18N_NOOP("Any Character"), ".", 0 }, { I18N_NOOP("Start of Line"), "^", 0 }, { I18N_NOOP("End of Line"), "$", 0 }, { I18N_NOOP("Set of Characters"), "[]", -1 }, { I18N_NOOP("Repeats, Zero or More Times"), "*", 0 }, { I18N_NOOP("Repeats, One or More Times"), "+", 0 }, { I18N_NOOP("Optional"), "?", 0 }, { I18N_NOOP("Escape"), "\\", 0 }, { I18N_NOOP("TAB"), "\\t", 0 }, { I18N_NOOP("Newline"), "\\n", 0 }, { I18N_NOOP("Carriage Return"), "\\r", 0 }, { I18N_NOOP("White Space"), "\\s", 0 }, { I18N_NOOP("Digit"), "\\d", 0 }, }; class RegExpAction : public QAction { public: RegExpAction(QObject *parent, const QString &text, const QString ®Exp, int cursor) : QAction(text, parent), mText(text), mRegExp(regExp), mCursor(cursor) { } QString text() const { return mText; } QString regExp() const { return mRegExp; } int cursor() const { return mCursor; } private: QString mText; QString mRegExp; int mCursor; }; GeneralFilter::GeneralFilter(FilterTabs *tabs, int properties, QWidget *parent, QStringList extraOptions) : QWidget(parent), profileManager(0), fltTabs(tabs) { QGridLayout *filterLayout = new QGridLayout(this); filterLayout->setSpacing(6); filterLayout->setContentsMargins(11, 11, 11, 11); this->properties = properties; // Options for name filtering QGroupBox *nameGroup = new QGroupBox(this); nameGroup->setTitle(i18n("File Name")); QGridLayout *nameGroupLayout = new QGridLayout(nameGroup); nameGroupLayout->setAlignment(Qt::AlignTop); nameGroupLayout->setSpacing(6); nameGroupLayout->setContentsMargins(11, 11, 11, 11); searchForCase = new QCheckBox(nameGroup); searchForCase->setText(i18n("&Case sensitive")); searchForCase->setChecked(false); nameGroupLayout->addWidget(searchForCase, 1, 2); QLabel *searchForLabel = new QLabel(nameGroup); searchForLabel->setText(i18n("Search &for:")); nameGroupLayout->addWidget(searchForLabel, 0, 0); searchFor = new KHistoryComboBox(false, nameGroup/*, "searchFor"*/); QSizePolicy searchForPolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); searchForPolicy.setHeightForWidth(searchFor->sizePolicy().hasHeightForWidth()); searchFor->setSizePolicy(searchForPolicy); searchFor->setEditable(true); searchFor->setDuplicatesEnabled(false); searchFor->setMaxCount(25); searchFor->setMinimumContentsLength(10); searchForLabel->setBuddy(searchFor); nameGroupLayout->addWidget(searchFor, 0, 1, 1, 2); QString s = "

" + i18n("

The filename filtering criteria is defined here.

You can make use of wildcards. Multiple patterns are separated by space (means logical OR) and patterns are excluded from the search using the pipe symbol.

If the pattern is ended with a slash (*pattern*/), that means that pattern relates to recursive search of folders.

  • pattern - means to search those files/folders that name is pattern, recursive search goes through all subfolders independently of the value of pattern
  • pattern/ - means to search all files/folders, but recursive search goes through/excludes the folders that name is pattern

It is allowed to use quotation marks for names that contain space. Filter \"Program Files\" searches out those files/folders that name is Program Files.

Examples:

  • *.o
  • *.h *.c\?\?
  • *.cpp *.h | *.moc.cpp
  • * | .svn/ .git/

Note: the search term 'text' is equivalent to '*text*'.

"); searchFor->setWhatsThis(s); searchForLabel->setWhatsThis(s); QLabel *searchType = new QLabel(nameGroup); searchType->setText(i18n("&Of type:")); nameGroupLayout->addWidget(searchType, 1, 0); ofType = new KComboBox(false, nameGroup); ofType->setObjectName("ofType"); QSizePolicy ofTypePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); ofTypePolicy.setHeightForWidth(ofType->sizePolicy().hasHeightForWidth()); ofType->setSizePolicy(ofTypePolicy); ofType->setEditable(false); searchType->setBuddy(ofType); ofType->addItem(i18n("All Files")); ofType->addItem(i18n("Archives")); ofType->addItem(i18n("Folders")); ofType->addItem(i18n("Image Files")); ofType->addItem(i18n("Text Files")); ofType->addItem(i18n("Video Files")); ofType->addItem(i18n("Audio Files")); connect(ofType, SIGNAL(currentIndexChanged(int)), this, SLOT(slotDisable())); nameGroupLayout->addWidget(ofType, 1, 1); filterLayout->addWidget(nameGroup, 0, 0); middleLayout = new QHBoxLayout(); middleLayout->setSpacing(6); middleLayout->setContentsMargins(0, 0, 0, 0); QSpacerItem* middleSpacer = new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::Fixed); middleLayout->addItem(middleSpacer); if (properties & FilterTabs::HasProfileHandler) { // The profile handler QGroupBox *profileHandler = new QGroupBox(this); profileHandler->setTitle(i18n("&Profile handler")); QGridLayout *profileLayout = new QGridLayout(profileHandler); profileLayout->setAlignment(Qt::AlignTop); profileLayout->setSpacing(6); profileLayout->setContentsMargins(11, 11, 11, 11); profileListBox = new KrListWidget(profileHandler); profileLayout->addWidget(profileListBox, 0, 0, 4, 1); profileAddBtn = new QPushButton(profileHandler); KStandardGuiItem::assign(profileAddBtn, KStandardGuiItem::Add); profileLayout->addWidget(profileAddBtn, 0, 1); profileLoadBtn = new QPushButton(i18n("&Load"), profileHandler); profileLoadBtn->setEnabled(false); profileLayout->addWidget(profileLoadBtn, 1, 1); profileOverwriteBtn = new QPushButton(profileHandler); profileOverwriteBtn->setEnabled(false); KStandardGuiItem::assign(profileOverwriteBtn, KStandardGuiItem::Overwrite); profileLayout->addWidget(profileOverwriteBtn, 2, 1); profileRemoveBtn = new QPushButton(profileHandler); profileRemoveBtn->setEnabled(false); KStandardGuiItem::assign(profileRemoveBtn, KStandardGuiItem::Remove); profileLayout->addWidget(profileRemoveBtn, 3, 1); profileManager = new ProfileManager("SelectionProfile", this); profileManager->hide(); middleLayout->addWidget(profileHandler); refreshProfileListBox(); } if (properties & FilterTabs::HasSearchIn) { // Options for search in QGroupBox *searchInGroup = new QGroupBox(this); searchInGroup->setTitle(i18n("Searc&h in")); QGridLayout *searchInLayout = new QGridLayout(searchInGroup); searchInLayout->setAlignment(Qt::AlignTop); searchInLayout->setSpacing(6); searchInLayout->setContentsMargins(11, 11, 11, 11); searchIn = new KURLListRequester(KURLListRequester::RequestDirs, searchInGroup); searchInLayout->addWidget(searchIn, 0, 0); connect(searchIn, SIGNAL(changed()), this, SLOT(slotDisable())); middleLayout->addWidget(searchInGroup); } if (properties & FilterTabs::HasDontSearchIn) { // Options for don't search in QGroupBox *dontSearchInGroup = new QGroupBox(this); dontSearchInGroup->setTitle(i18n("&Do not search in")); QGridLayout *dontSearchInLayout = new QGridLayout(dontSearchInGroup); dontSearchInLayout->setAlignment(Qt::AlignTop); dontSearchInLayout->setSpacing(6); dontSearchInLayout->setContentsMargins(11, 11, 11, 11); dontSearchIn = new KURLListRequester(KURLListRequester::RequestDirs, dontSearchInGroup); dontSearchInLayout->addWidget(dontSearchIn, 0, 0); middleLayout->addWidget(dontSearchInGroup); } filterLayout->addLayout(middleLayout, 1, 0); // Options for containing text QGroupBox *containsGroup = new QGroupBox(this); containsGroup->setTitle(i18n("Containing text")); QGridLayout *containsLayout = new QGridLayout(containsGroup); containsLayout->setAlignment(Qt::AlignTop); containsLayout->setSpacing(6); containsLayout->setContentsMargins(11, 11, 11, 11); QHBoxLayout *containsTextLayout = new QHBoxLayout(); containsTextLayout->setSpacing(6); containsTextLayout->setContentsMargins(0, 0, 0, 0); containsLabel = new QLabel(containsGroup); QSizePolicy containsLabelPolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); containsLabelPolicy.setHeightForWidth(containsLabel->sizePolicy().hasHeightForWidth()); containsLabel->setSizePolicy(containsLabelPolicy); containsLabel->setText(i18n("&Text:")); containsTextLayout->addWidget(containsLabel); containsText = new KHistoryComboBox(false, containsGroup/*, "containsText"*/); QSizePolicy containsTextPolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); containsTextPolicy.setHeightForWidth(containsText->sizePolicy().hasHeightForWidth()); containsText->setSizePolicy(containsTextPolicy); containsText->setDuplicatesEnabled(false); containsText->setMaxCount(25); containsText->setMinimumContentsLength(10); containsTextLayout->addWidget(containsText); containsLabel->setBuddy(containsText); containsRegExp = new QToolButton(containsGroup); containsRegExp->setPopupMode(QToolButton::MenuButtonPopup); containsRegExp->setCheckable(true); containsRegExp->setText(i18n("RegExp")); // Populate the popup menu. QMenu *patterns = new QMenu(containsRegExp); for (int i = 0; (unsigned)i < sizeof(items) / sizeof(items[0]); i++) { patterns->addAction(new RegExpAction(patterns, i18n(items[i].description), items[i].regExp, items[i].cursorAdjustment)); } connect(containsRegExp, SIGNAL(toggled(bool)), this, SLOT(slotDisable())); connect(containsRegExp, SIGNAL(triggered(QAction *)), this, SLOT(slotRegExpTriggered(QAction *))); containsRegExp->setMenu(patterns); patterns->setEnabled(false); containsTextLayout->addWidget(containsRegExp); containsLayout->addLayout(containsTextLayout, 0, 0); QHBoxLayout *containsCbsLayout = new QHBoxLayout(); containsCbsLayout->setSpacing(6); containsCbsLayout->setContentsMargins(0, 0, 0, 0); encLabel = new QLabel(i18n("Encoding:"), containsGroup); containsCbsLayout->addWidget(encLabel); contentEncoding = new KComboBox(containsGroup); contentEncoding->setEditable(false); contentEncoding->addItem(i18nc("Default encoding", "Default")); contentEncoding->addItems(KCharsets::charsets()->descriptiveEncodingNames()); containsCbsLayout->addWidget(contentEncoding); QSpacerItem* cbSpacer = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); containsCbsLayout->addItem(cbSpacer); containsWholeWord = new QCheckBox(containsGroup); QSizePolicy containsWholeWordPolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); containsWholeWordPolicy.setHeightForWidth(containsWholeWord->sizePolicy().hasHeightForWidth()); containsWholeWord->setSizePolicy(containsWholeWordPolicy); containsWholeWord->setText(i18n("&Match whole word only")); containsWholeWord->setChecked(false); containsCbsLayout->addWidget(containsWholeWord); containsTextCase = new QCheckBox(containsGroup); QSizePolicy containsTextCasePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); containsTextCasePolicy.setHeightForWidth(containsTextCase->sizePolicy().hasHeightForWidth()); containsTextCase->setSizePolicy(containsTextCasePolicy); containsTextCase->setText(i18n("Cas&e sensitive")); containsTextCase->setChecked(true); containsCbsLayout->addWidget(containsTextCase); containsLayout->addLayout(containsCbsLayout, 1, 0); filterLayout->addWidget(containsGroup, 2, 0); QHBoxLayout *recurseLayout = new QHBoxLayout(); recurseLayout->setSpacing(6); recurseLayout->setContentsMargins(0, 0, 0, 0); QSpacerItem* recurseSpacer = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); recurseLayout->addItem(recurseSpacer); if (properties & FilterTabs::HasRecurseOptions) { // Options for recursive searching searchInDirs = new QCheckBox(this); searchInDirs->setText(i18n("Search in s&ub folders")); searchInDirs->setChecked(true); recurseLayout->addWidget(searchInDirs); searchInArchives = new QCheckBox(this); searchInArchives->setText(i18n("Search in arch&ives")); recurseLayout->addWidget(searchInArchives); followLinks = new QCheckBox(this); followLinks->setText(i18n("Follow &links")); recurseLayout->addWidget(followLinks); } filterLayout->addLayout(recurseLayout, 3, 0); for(int i = 0; i < extraOptions.length(); i++) { QCheckBox *option = new QCheckBox(this); option->setText(extraOptions[i]); recurseLayout->addWidget(option); this->extraOptions.insert(extraOptions[i], option); } // Connection table if (properties & FilterTabs::HasProfileHandler) { connect(profileAddBtn, SIGNAL(clicked()) , this, SLOT(slotAddBtnClicked())); connect(profileLoadBtn, SIGNAL(clicked()) , this, SLOT(slotLoadBtnClicked())); connect(profileOverwriteBtn, SIGNAL(clicked()) , this, SLOT(slotOverwriteBtnClicked())); connect(profileRemoveBtn, SIGNAL(clicked()) , this, SLOT(slotRemoveBtnClicked())); connect(profileListBox, SIGNAL(itemDoubleClicked(QListWidgetItem *)) , this, SLOT(slotProfileDoubleClicked(QListWidgetItem *))); connect(profileManager, SIGNAL(loadFromProfile(QString)), fltTabs, SLOT(loadFromProfile(QString))); connect(profileManager, SIGNAL(saveToProfile(QString)), fltTabs, SLOT(saveToProfile(QString))); } connect(searchFor, SIGNAL(activated(const QString&)), searchFor, SLOT(addToHistory(const QString&))); connect(containsText, SIGNAL(activated(const QString&)), containsText, SLOT(addToHistory(const QString&))); // load the completion and history lists // ==> search for KConfigGroup group(krConfig, "Search"); QStringList list = group.readEntry("SearchFor Completion", QStringList()); searchFor->completionObject()->setItems(list); list = group.readEntry("SearchFor History", QStringList()); searchFor->setHistoryItems(list); // ==> grep list = group.readEntry("ContainsText Completion", QStringList()); containsText->completionObject()->setItems(list); list = group.readEntry("ContainsText History", QStringList()); containsText->setHistoryItems(list); setTabOrder(searchFor, containsText); // search for -> content setTabOrder(containsText, searchType); // content -> search type slotDisable(); } GeneralFilter::~GeneralFilter() { // save the history combos // ==> search for QStringList list = searchFor->completionObject()->items(); KConfigGroup group(krConfig, "Search"); group.writeEntry("SearchFor Completion", list); list = searchFor->historyItems(); group.writeEntry("SearchFor History", list); // ==> grep text list = containsText->completionObject()->items(); group.writeEntry("ContainsText Completion", list); list = containsText->historyItems(); group.writeEntry("ContainsText History", list); krConfig->sync(); } bool GeneralFilter::isExtraOptionChecked(QString name) { QCheckBox *option = extraOptions[name]; return option ? option->isChecked() : false; } void GeneralFilter::checkExtraOption(QString name, bool check) { QCheckBox *option = extraOptions[name]; if(option) option->setChecked(check); } void GeneralFilter::queryAccepted() { searchFor->addToHistory(searchFor->currentText()); containsText->addToHistory(containsText->currentText()); } void GeneralFilter::refreshProfileListBox() { profileListBox->clear(); profileListBox->addItems(ProfileManager::availableProfiles("SelectionProfile")); if (profileListBox->count() != 0) { profileLoadBtn->setEnabled(true); profileOverwriteBtn->setEnabled(true); profileRemoveBtn->setEnabled(true); } else { profileLoadBtn->setEnabled(false); profileOverwriteBtn->setEnabled(false); profileRemoveBtn->setEnabled(false); } } void GeneralFilter::slotAddBtnClicked() { profileManager->newProfile(searchFor->currentText().simplified()); refreshProfileListBox(); } void GeneralFilter::slotOverwriteBtnClicked() { QListWidgetItem *item = profileListBox->currentItem(); if (item != 0) profileManager->overwriteProfile(item->text()); } void GeneralFilter::slotRemoveBtnClicked() { QListWidgetItem *item = profileListBox->currentItem(); if (item != 0) { profileManager->deleteProfile(item->text()); refreshProfileListBox(); } } void GeneralFilter::slotProfileDoubleClicked(QListWidgetItem *item) { if (item != 0) { QString profileName = item->text(); profileManager->loadProfile(profileName); fltTabs->close(true); } } void GeneralFilter::slotLoadBtnClicked() { QListWidgetItem *item = profileListBox->currentItem(); if (item != 0) profileManager->loadProfile(item->text()); } void GeneralFilter::slotDisable() { bool state = containsRegExp->isChecked(); bool global = ofType->currentText() != i18n("Folders"); bool remoteOnly = false; if (properties & FilterTabs::HasSearchIn) { QList urlList = searchIn->urlList(); remoteOnly = urlList.count() != 0; foreach(const QUrl &url, urlList) if (url.scheme() == "file") remoteOnly = false; } containsWholeWord->setEnabled(!state && global); containsRegExp->menu()->setEnabled(state && global); encLabel->setEnabled(global); contentEncoding->setEnabled(global); containsTextCase->setEnabled(global); containsRegExp->setEnabled(global); if (properties & FilterTabs::HasRecurseOptions) searchInArchives->setEnabled(global && !remoteOnly); containsLabel->setEnabled(global); containsText->setEnabled(global); } void GeneralFilter::slotRegExpTriggered(QAction * act) { if (act == 0) return; RegExpAction *regAct = dynamic_cast(act); if (regAct == 0) return; containsText->lineEdit()->insert(regAct->regExp()); containsText->lineEdit()->setCursorPosition(containsText->lineEdit()->cursorPosition() + regAct->cursor()); containsText->lineEdit()->setFocus(); } bool GeneralFilter::getSettings(FilterSettings &s) { // check that we have (at least) what to search, and where to search in if (searchFor->currentText().simplified().isEmpty()) { KMessageBox::error(this , i18n("No search criteria entered.")); searchFor->setFocus(); return false; } s.searchFor = searchFor->currentText().trimmed(); s.searchForCase = searchForCase->isChecked(); if (ofType->currentText() != i18n("All Files")) s.mimeType = ofType->currentText(); if (containsText->isEnabled()) { s.containsText = containsText->currentText(); s.containsTextCase = containsTextCase->isChecked(); s.containsWholeWord = containsWholeWord->isChecked(); s.containsRegExp = containsRegExp->isChecked(); } if (contentEncoding->currentIndex() != 0) s.contentEncoding = KCharsets::charsets()->encodingForName(contentEncoding->currentText()); if (properties & FilterTabs::HasRecurseOptions) { s.recursive = searchInDirs->isChecked(); s.searchInArchives = searchInArchives->isChecked(); s.followLinks = followLinks->isChecked(); } if (properties & FilterTabs::HasSearchIn) { s.searchIn = searchIn->urlList(); if (s.searchIn.isEmpty()) { // we need a place to search in KMessageBox::error(this , i18n("Please specify a location to search in.")); searchIn->lineEdit()->setFocus(); return false; } } if (properties & FilterTabs::HasDontSearchIn) s.dontSearchIn = dontSearchIn->urlList(); return true; } void GeneralFilter::applySettings(const FilterSettings &s) { searchFor->setEditText(s.searchFor); searchForCase->setChecked(s.searchForCase); setComboBoxValue(ofType, s.mimeType); containsText->setEditText(s.containsText); containsTextCase->setChecked(s.containsTextCase); containsWholeWord->setChecked(s.containsWholeWord); containsRegExp->setChecked(s.containsRegExp); setComboBoxValue(contentEncoding, KCharsets::charsets()->descriptionForEncoding(s.contentEncoding)); if (properties & FilterTabs::HasRecurseOptions) { searchInDirs->setChecked(s.recursive); searchInArchives->setChecked(s.searchInArchives); followLinks->setChecked(s.followLinks); } if (properties & FilterTabs::HasSearchIn) { searchIn->lineEdit()->clear(); searchIn->listBox()->clear(); searchIn->listBox()->addItems(KrServices::toStringList(s.searchIn)); } if (properties & FilterTabs::HasDontSearchIn) { dontSearchIn->lineEdit()->clear(); dontSearchIn->listBox()->clear(); dontSearchIn->listBox()->addItems(KrServices::toStringList(s.dontSearchIn)); } } diff --git a/krusader/GUI/dirhistorybutton.cpp b/krusader/GUI/dirhistorybutton.cpp index 1d73d056..df021a49 100644 --- a/krusader/GUI/dirhistorybutton.cpp +++ b/krusader/GUI/dirhistorybutton.cpp @@ -1,93 +1,93 @@ /***************************************************************************** * Copyright (C) 2004 Shie Erlich * * Copyright (C) 2004 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "dirhistorybutton.h" #include "../Panel/dirhistoryqueue.h" -#include "../VFS/vfs.h" +#include "../FileSystem/filesystem.h" // QtCore #include #include // QtGui #include // QtWidgets #include #include DirHistoryButton::DirHistoryButton(DirHistoryQueue* hQ, QWidget *parent) : QToolButton(parent) { setAutoRaise(true); setIcon(QIcon::fromTheme("chronometer")); setText(i18n("Open the folder history list")); setToolTip(i18n("Open the folder history list")); setPopupMode(QToolButton::InstantPopup); setAcceptDrops(false); popupMenu = new QMenu(this); Q_CHECK_PTR(popupMenu); setMenu(popupMenu); historyQueue = hQ; connect(popupMenu, SIGNAL(aboutToShow()), this, SLOT(slotAboutToShow())); connect(popupMenu, SIGNAL(triggered(QAction *)), this, SLOT(slotPopupActivated(QAction *))); } DirHistoryButton::~DirHistoryButton() {} void DirHistoryButton::showMenu() { QMenu * pP = menu(); if (pP) { menu() ->exec(mapToGlobal(QPoint(0, height()))); } } /** No descriptions */ void DirHistoryButton::slotPopup() { // qDebug() << "History slot" << endl; } /** No descriptions */ void DirHistoryButton::slotAboutToShow() { emit aboutToShow(); // qDebug() << "about to show" << endl; popupMenu->clear(); for (int i = 0; i < historyQueue->count(); i++) { QAction *act = popupMenu->addAction(historyQueue->get(i).toDisplayString()); act->setData(QVariant(i)); if(historyQueue->currentPos() == i) { act->setCheckable(true); act->setChecked(true); } } } /** No descriptions */ void DirHistoryButton::slotPopupActivated(QAction * action) { if (action && action->data().canConvert()) { int id = action->data().toInt(); emit gotoPos(id); } } diff --git a/krusader/GUI/terminaldock.cpp b/krusader/GUI/terminaldock.cpp index 32ef2f4c..e160fa89 100644 --- a/krusader/GUI/terminaldock.cpp +++ b/krusader/GUI/terminaldock.cpp @@ -1,291 +1,291 @@ /***************************************************************************** * Copyright (C) 2008 Václav Juza * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "terminaldock.h" // QtCore #include #include #include #include #include // QtGui #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include "../kractions.h" #include "../krusaderview.h" #include "../krmainwindow.h" #include "kcmdline.h" -#include "../VFS/vfs.h" +#include "../FileSystem/filesystem.h" #include "../Panel/listpanel.h" #include "../Panel/panelfunc.h" #include "../Panel/listpanelactions.h" #include "../krservices.h" /** * A widget containing the konsolepart for the Embedded terminal emulator */ TerminalDock::TerminalDock(QWidget* parent, KrMainWindow *mainWindow) : QWidget(parent), _mainWindow(mainWindow), konsole_part(0), t(0), initialised(false) { terminal_hbox = new QHBoxLayout(this); } TerminalDock::~TerminalDock() { } bool TerminalDock::initialise() { if (! initialised) { // konsole part is not yet loaded or it has already failed KService::Ptr service = KService::serviceByDesktopName("konsolepart"); if (service) { QWidget *focusW = qApp->focusWidget(); // Create the part QString error; konsole_part = service->createInstance(this, this, QVariantList(), &error); if (konsole_part) { //loaded successfully terminal_hbox->addWidget(konsole_part->widget()); setFocusProxy(konsole_part->widget()); connect(konsole_part, SIGNAL(destroyed()), this, SLOT(killTerminalEmulator())); // must filter app events, because some of them are processed // by child widgets of konsole_part->widget() // and would not be received on konsole_part->widget() qApp->installEventFilter(this); t = qobject_cast(konsole_part); if (t) { lastPath = QDir::currentPath(); t->showShellInDir(lastPath); } initialised = true; } else KMessageBox::error(0, i18n("Cannot create embedded terminal.
" "The reported error was: %1", error)); // the Terminal Emulator may be hidden (if we are creating it only // to send command there and see the results later) if (focusW) { focusW->setFocus(); } else { ACTIVE_PANEL->gui->slotFocusOnMe(); } } else KMessageBox::sorry(0, i18nc("missing program - arg1 is a URL", "Cannot create embedded terminal.
" "You can fix this by installing Konsole:
%1", QString("%1").arg( "http://www.kde.org/applications/system/konsole")), 0, KMessageBox::AllowLink); } return isInitialised(); } void TerminalDock::killTerminalEmulator() { initialised = false; konsole_part = NULL; t = NULL; qApp->removeEventFilter(this); MAIN_VIEW->setTerminalEmulator(false); } void TerminalDock::sendInput(const QString& input, bool clearCommand) { if (!t) return; if (clearCommand) { // send SIGINT before input command to avoid unwanted behaviour when current line is not empty // and command is appended to current input (e.g. "rm -rf x " concatenated with 'cd /usr'); // code "borrowed" from Dolphin, Copyright (C) 2007-2010 by Peter Penz const int processId = t->terminalProcessId(); if (processId > 0) { kill(processId, SIGINT); } } t->sendInput(input); } /*! Sends a `cd` command to the embedded terminal emulator so as to synchronize the directory of the actual panel and the directory of the embedded terminal emulator. To avoid that Krusader's embedded terminal adds a lot of `cd` messages to the shell history: the user has to use bash and have set `HISTCONTROL=ignorespace` or `HISTCONTROL=ignoreboth` (which is the default in a lot of Linux distributions so in that case the user hasn't got to do anything), or the user has to use an equivalent method. */ void TerminalDock::sendCd(const QString& path) { if (path.compare(lastPath) != 0) { // A space exists in front of the `cd` so as to avoid that Krusader's embedded terminal adds a lot of `cd` // messages to the shell history, in Dolphin it's done the same way: https://bugs.kde.org/show_bug.cgi?id=204039 sendInput(QString(" cd ") + KrServices::quote(path) + QString("\n")); lastPath = path; } } bool TerminalDock::applyShortcuts(QKeyEvent * ke) { int pressedKey = (ke->key() | ke->modifiers()); // TODO KF5 removed if (KrActions::actToggleTerminal->shortcut().matches(pressedKey)) { KrActions::actToggleTerminal->activate(QAction::Trigger); return true; } if (!krSwitchFullScreenTE->shortcut().isEmpty() && krSwitchFullScreenTE->shortcut().matches(pressedKey)) { krSwitchFullScreenTE->activate(QAction::Trigger); return true; } if (_mainWindow->listPanelActions()->actPaste->shortcut().matches(pressedKey)) { QString text = QApplication::clipboard()->text(); if (! text.isEmpty()) { text.replace('\n', '\r'); sendInput(text, false); } return true; } //insert current to the terminal if ((ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return) && ((ke->modifiers() & ~Qt::ShiftModifier) == Qt::ControlModifier)) { QString filename = ACTIVE_PANEL->view->getCurrentItem(); if (filename.isEmpty()) { return true; } if (ke->modifiers() & Qt::ShiftModifier) { - QString path = vfs::ensureTrailingSlash(ACTIVE_FUNC->files()->currentDirectory()).toDisplayString(QUrl::PreferLocalFile); + QString path = FileSystem::ensureTrailingSlash(ACTIVE_FUNC->files()->currentDirectory()).toDisplayString(QUrl::PreferLocalFile); filename = path + filename; } filename = KrServices::quote(filename); sendInput(QString(" ") + filename + QString(" "), false); return true; } //navigation if ((ke->key() == Qt::Key_Down) && (ke->modifiers() == Qt::ControlModifier)) { if (MAIN_VIEW->cmdLine()->isVisible()) { MAIN_VIEW->cmdLine()->setFocus(); } return true; } else if ((ke->key() == Qt::Key_Up) && ((ke->modifiers() == Qt::ControlModifier) || (ke->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)))) { ACTIVE_PANEL->gui->slotFocusOnMe(); return true; } return false; } bool TerminalDock::eventFilter(QObject * watched, QEvent * e) { if (konsole_part == NULL || konsole_part->widget() == NULL) return false; // we must watch for child widgets as well, // otherwise some shortcuts are "eaten" by them before // being procesed in konsole_part->widget() context // examples are Ctrl+F, Ctrl+Enter QObject *w; for (w = watched; w != NULL; w = w->parent()) if (w == konsole_part->widget()) break; if (w == NULL) // is not a child of konsole_part return false; switch (e->type()) { case QEvent::ShortcutOverride: { QKeyEvent *ke = (QKeyEvent *)e; // If not present, some keys would be considered a shortcut, for example "a" if ((ke->key() == Qt::Key_Insert) && (ke->modifiers() == Qt::ShiftModifier)) { ke->accept(); return true; } if ((ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier) && (ke->key() >= 32) && (ke->key() <= 127)) { ke->accept(); return true; } break; } case QEvent::KeyPress: { QKeyEvent *ke = (QKeyEvent *)e; if (applyShortcuts(ke)) { ke->accept(); return true; } break; } default: return false; } return false; } bool TerminalDock::isTerminalVisible() const { return isVisible() && konsole_part != NULL && konsole_part->widget() != NULL && konsole_part->widget()->isVisible(); } bool TerminalDock::isInitialised() const { return konsole_part != NULL && konsole_part->widget() != NULL; } void TerminalDock::hideEvent(QHideEvent * /*e*/) { // BUGFIX: when the terminal emulator is toggled on, first it is shown in minimum size // then QSplitter resizes it to the desired size. // this minimum resize scrolls up the content of the konsole widget // SOLUTION: // we hide the console widget while the resize ceremony happens, then reenable it if (konsole_part && konsole_part->widget()) konsole_part->widget()->hide(); // hide the widget to prevent from resize } void TerminalDock::showEvent(QShowEvent * /*e*/) { if (konsole_part && konsole_part->widget()) { // BUGFIX: TE scrolling bug (see upper) // show the Konsole part delayed QTimer::singleShot(0, konsole_part->widget(), SLOT(show())); } } diff --git a/krusader/JobMan/jobman.h b/krusader/JobMan/jobman.h index 2ce66f25..3469aca7 100644 --- a/krusader/JobMan/jobman.h +++ b/krusader/JobMan/jobman.h @@ -1,126 +1,126 @@ /***************************************************************************** * Copyright (C) 2010 Jan Lepper * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #ifndef JOBMAN_H #define JOBMAN_H // QtCore #include // QtWidgets #include #include #include #include #include class KrJob; /** * @brief The job manager provides a progress dialog and control over (KIO) file operation jobs. * * Job manager does not have a window (or dialog). All functions are provided via toolbar actions. * Icon, text and tooltip are already set, shortcuts are missing. * * If Job manager queue mode is activated only the first job is started. If more jobs are incoming * via manageJob() they are not started. If the running job finishes the next job in line is * started. * * Note that the desktop system (e.g. KDE Plasma Shell) may also has control over the jobs. * * Reference: plasma-workspace/kuiserver/progresslistdelegate.h * * If a job still exists Krusader does not exit on quit() until the job is finished. If the job is * paused this takes forever. Call waitForJobs() before exit to prevent this. * - * About undoing jobs: If jobs are recorded (all KrJobs are, some in VFS) we can undo them with + * About undoing jobs: If jobs are recorded (all KrJobs are, some in FileSystem) we can undo them with * FileUndoManager (which is a singleton) here. * It would be great if each job in the job list could be undone invividually but FileUndoManager * is currently (KF5.27) only able to undo the last recorded job. */ class JobMan : public QObject { Q_OBJECT public: explicit JobMan(QObject *parent = 0); /** Toolbar action icon for pausing/starting all jobs with drop down menu showing all jobs.*/ QAction *controlAction() const { return _controlAction; } /** Toolbar action progress bar showing the average job progress percentage of all jobs.*/ QAction *progressAction() const { return _progressAction; } /** Toolbar action combo box for changing the .*/ QAction *modeAction() const { return _modeAction; } QAction *undoAction() const { return _undoAction; } /** Wait for all jobs to terminate (blocking!). * * Returns true immediately if there are no jobs and user input is not required. Otherwise a * modal UI dialog is shown and the user can abort all jobs or cancel the dialog. * * @param waitForUserInput if true dialog is only closed after user interaction (button click) * @return true if no jobs are running (anymore) and user wants to quit. Else false */ bool waitForJobs(bool waitForUserInput); /* Curent info about _queueMode state */ bool isQueueModeEnabled() { return _queueMode; }; public slots: /** Display, monitor and give user ability to control a job. * * If reverseQueueMode is false, job is queued or run in parallel accordingly * to job manager mode. When reverseQueueMode is true, opposite manager mode is chosen. * * When startPaused is true, job is never started immediately. Instead, it is waiting * to be manually unpaused. Or in case of enabled queueMode it is started automatically * when other jobs are finished. */ void manageJob(KrJob *krJob, bool reverseQueueMode = false, bool startPaused = false); protected slots: void slotKJobStarted(KJob *krJob); void slotControlActionTriggered(); void slotPercent(KJob *, unsigned long); void slotDescription(KJob*,const QString &description, const QPair &field1, const QPair &field2); void slotTerminated(KrJob *krJob); void slotUpdateControlAction(); void slotUndoTextChange(const QString &text); void slotUpdateMessageBox(); private: void updateUI(); bool jobsAreRunning(); QList _jobs; // all jobs not terminated (finished or canceled) yet bool _queueMode; KToolBarPopupAction *_controlAction; QProgressBar *_progressBar; QAction *_progressAction; QAction *_modeAction; QAction *_undoAction; QMessageBox *_messageBox; bool _autoCloseMessageBox; static const QString sDefaultToolTip; }; #endif // JOBMAN_H diff --git a/krusader/KViewer/diskusageviewer.cpp b/krusader/KViewer/diskusageviewer.cpp index 3fb2cbca..75644697 100644 --- a/krusader/KViewer/diskusageviewer.cpp +++ b/krusader/KViewer/diskusageviewer.cpp @@ -1,130 +1,130 @@ /*************************************************************************** diskusageviewer.cpp - description ------------------- copyright : (C) 2005 by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "diskusageviewer.h" // QtWidgets #include #include #include #include "../krglobal.h" #include "../Panel/krpanel.h" #include "../Panel/panelfunc.h" DiskUsageViewer::DiskUsageViewer(QWidget *parent) : QWidget(parent), diskUsage(0), statusLabel(0) { layout = new QGridLayout(this); layout->setContentsMargins(0, 0, 0, 0); } DiskUsageViewer::~ DiskUsageViewer() { if (diskUsage) { KConfigGroup group(krConfig, "DiskUsageViewer"); group.writeEntry("View", diskUsage->getActiveView()); delete diskUsage; } } void DiskUsageViewer::openUrl(QUrl url) { if (diskUsage == 0) { diskUsage = new DiskUsage("DiskUsageViewer", this); connect(diskUsage, SIGNAL(enteringDirectory(Directory *)), this, SLOT(slotUpdateStatus())); connect(diskUsage, SIGNAL(status(QString)), this, SLOT(slotUpdateStatus(QString))); connect(diskUsage, SIGNAL(newSearch()), this, SLOT(slotNewSearch())); layout->addWidget(diskUsage, 0, 0); this->show(); diskUsage->show(); KConfigGroup group(krConfig, "DiskUsageViewer"); int view = group.readEntry("View", VIEW_FILELIGHT); if (view < VIEW_LINES || view > VIEW_FILELIGHT) view = VIEW_FILELIGHT; diskUsage->setView(view); } url.setPath(url.adjusted(QUrl::StripTrailingSlash).path()); QUrl baseURL = diskUsage->getBaseURL(); if (!diskUsage->isLoading() && !baseURL.isEmpty()) { if (url.scheme() == baseURL.scheme() && (url.host().isEmpty() || url.host() == baseURL.host())) { - QString baseStr = vfs::ensureTrailingSlash(baseURL).path(); - QString urlStr = vfs::ensureTrailingSlash(url).path(); + QString baseStr = FileSystem::ensureTrailingSlash(baseURL).path(); + QString urlStr = FileSystem::ensureTrailingSlash(url).path(); if (urlStr.startsWith(baseStr)) { QString relURL = urlStr.mid(baseStr.length()); if (relURL.endsWith('/')) relURL.truncate(relURL.length() - 1); Directory *dir = diskUsage->getDirectory(relURL); if (dir) { diskUsage->changeDirectory(dir); return; } } } } diskUsage->load(url); } void DiskUsageViewer::closeUrl() { if (diskUsage) diskUsage->close(); } void DiskUsageViewer::setStatusLabel(QLabel *statLabel, QString pref) { statusLabel = statLabel; prefix = pref; } void DiskUsageViewer::slotUpdateStatus(QString status) { if (statusLabel) { if (status.isEmpty()) { Directory * dir = diskUsage->getCurrentDir(); if (dir) status = prefix + dir->name() + " [" + KIO::convertSize(dir->size()) + ']'; } statusLabel->setText(status); } } void DiskUsageViewer::slotNewSearch() { diskUsage->load(ACTIVE_PANEL->func->files()->currentDirectory()); } diff --git a/krusader/KViewer/lister.h b/krusader/KViewer/lister.h index 85c6294b..994688f9 100644 --- a/krusader/KViewer/lister.h +++ b/krusader/KViewer/lister.h @@ -1,333 +1,333 @@ /*************************************************************************** lister.h - description ------------------- copyright : (C) 2009 + by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LISTER_H #define LISTER_H // QtCore #include #include // QtGui #include // QtWidgets #include #include #include #include #include #include -#include "../VFS/krquery.h" +#include "../FileSystem/krquery.h" #define SLIDER_MAX 10000 #define MAX_CHAR_LENGTH 4 class Lister; class QLabel; class QProgressBar; class QPushButton; class QToolButton; class QAction; class QTemporaryFile; class ListerEncodingMenu; class ListerTextArea : public KTextEdit { Q_OBJECT public: ListerTextArea(Lister *lister, QWidget *parent); void reset(); void calculateText(bool forcedUpdate = false); void redrawTextArea(bool forcedUpdate = false); qint64 textToFilePosition(int x, int y, bool &isfirst); void fileToTextPosition(qint64 p, bool isfirst, int &x, int &y); QTextCodec * codec(); int tabWidth() { return _tabWidth; } bool hexMode() { return _hexMode; } void setHexMode(bool hexMode); void copySelectedToClipboard(); QString getSelectedText(); void clearSelection(); void getCursorPosition(int &x, int &y); qint64 getCursorPosition(bool &isfirst); qint64 getCursorAnchor() { return _cursorAnchorPos; } void setCursorPosition(qint64 p, bool isfirst); void ensureVisibleCursor(); void deleteAnchor() { _cursorAnchorPos = -1; } void setAnchorAndCursor(qint64 anchor, qint64 cursor); void sizeChanged(); protected: virtual void resizeEvent(QResizeEvent * event) Q_DECL_OVERRIDE; virtual void keyPressEvent(QKeyEvent * e) Q_DECL_OVERRIDE; virtual void mousePressEvent(QMouseEvent * e) Q_DECL_OVERRIDE; virtual void mouseDoubleClickEvent(QMouseEvent * e) Q_DECL_OVERRIDE; virtual void mouseMoveEvent(QMouseEvent * e) Q_DECL_OVERRIDE; virtual void wheelEvent(QWheelEvent * event) Q_DECL_OVERRIDE; QStringList readLines(qint64 filePos, qint64 &endPos, int lines, QList * locs = 0); QString readSection(qint64 p1, qint64 p2); void setUpScrollBar(); void setCursorPosition(int x, int y, int anchorX = -1, int anchorY = -1); void handleAnchorChange(int oldAnchor); void performAnchorChange(int anchor); void getScreenPosition(int position, int &x, int &y); protected slots: void slotActionTriggered(int action); void slotCursorPositionChanged(); void blinkCursor(); void zoomIn(int range = 1); void zoomOut(int range = 1); protected: Lister *_lister; qint64 _screenStartPos; qint64 _screenEndPos; qint64 _averagePageSize; qint64 _lastPageStartPos; int _sizeX; int _sizeY; int _pageSize; int _tabWidth; bool _sizeChanged; QStringList _rowContent; QList _rowStarts; qint64 _cursorPos; bool _cursorAtFirstColumn; qint64 _cursorAnchorPos; int _skippedLines; bool _inSliderOp; bool _inCursorUpdate; bool _hexMode; bool _cursorState = false; }; class ListerBrowserExtension : public KParts::BrowserExtension { Q_OBJECT public: ListerBrowserExtension(Lister * lister); public slots: void copy(); void print(); protected: Lister *_lister; }; class ListerPane : public QWidget { Q_OBJECT public: ListerPane(Lister *lister, QWidget *parent); protected: virtual bool event(QEvent *event) Q_DECL_OVERRIDE; protected: bool handleCloseEvent(QEvent *e); Lister *_lister; }; class Lister : public KParts::ReadOnlyPart { Q_OBJECT public: Lister(QWidget *parent); ~Lister(); QScrollBar *scrollBar() { return _scrollBar; } ListerTextArea *textArea() { return _textArea; } inline qint64 fileSize() { return _fileSize; } char * cacheRef(qint64 filePos, int &size); bool isSearchEnabled(); void enableSearch(bool); void enableActions(bool); QString characterSet() { return _characterSet; } void setCharacterSet(QString set); void setHexMode(bool); QStringList readHexLines(qint64 &filePos, qint64 endPos, int columns, int lines); int hexBytesPerLine(int columns); int hexPositionDigits(); int hexIndexToPosition(int columns, int index); int hexPositionToIndex(int columns, int position); public slots: void searchAction() { enableSearch(true); } void searchNext(); void searchPrev(); void searchDelete(); void jumpToPosition(); void saveAs(); void saveSelected(); void print(); void toggleHexMode(); protected slots: void slotUpdate(); void slotSearchMore(); void searchSucceeded(); void searchFailed(); void searchTextChanged(); void slotFileDataReceived(KIO::Job *, const QByteArray &); void slotFileFinished(KJob *); void slotDataSend(KIO::Job *, QByteArray &); void slotSendFinished(KJob *); protected: virtual bool openUrl(const QUrl &url) Q_DECL_OVERRIDE; virtual bool closeUrl() Q_DECL_OVERRIDE { return true; } virtual bool openFile() Q_DECL_OVERRIDE { return true; } virtual void guiActivateEvent(KParts::GUIActivateEvent * event) Q_DECL_OVERRIDE; void setColor(bool match, bool restore); void hideProgressBar(); void updateProgressBar(); void resetSearchPosition(); qint64 getFileSize(); void search(bool forward, bool restart = false); QStringList readLines(qint64 &filePos, qint64 endPos, int columns, int lines); QTimer _updateTimer; ListerTextArea *_textArea; QScrollBar *_scrollBar; QLabel *_listerLabel; KLineEdit *_searchLineEdit; QProgressBar *_searchProgressBar; QToolButton *_searchStopButton; QPushButton *_searchNextButton; QPushButton *_searchPrevButton; bool _searchInProgress; bool _searchHexadecimal; QPushButton *_searchOptions; QLabel *_statusLabel; QAction *_fromCursorAction; QAction *_caseSensitiveAction; QAction *_matchWholeWordsOnlyAction; QAction *_regExpAction; QAction *_hexAction; QAction *_actionSaveSelected; QAction *_actionSaveAs; QAction *_actionPrint; QAction *_actionSearch; QAction *_actionSearchNext; QAction *_actionSearchPrev; QAction *_actionJumpToPosition; QAction *_actionHexMode; ListerEncodingMenu *_actionEncoding; QString _filePath; qint64 _fileSize; char *_cache; int _cacheSize; qint64 _cachePos; bool _active; KRQuery _searchQuery; QByteArray _searchHexQuery; qint64 _searchPosition; bool _searchIsForward; qint64 _searchLastFailedPosition; int _searchProgressCounter; QColor _originalBackground; QColor _originalForeground; QString _characterSet; QTemporaryFile *_tempFile; bool _downloading; bool _restartFromBeginning; qint64 _savePosition; qint64 _saveEnd; }; #endif // __LISTER_H__ diff --git a/krusader/Locate/locate.cpp b/krusader/Locate/locate.cpp index 8a61e7a5..4e5aa1f4 100644 --- a/krusader/Locate/locate.cpp +++ b/krusader/Locate/locate.cpp @@ -1,702 +1,702 @@ /*************************************************************************** locate.cpp - description ------------------- copyright : (C) 2004 by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "locate.h" #include "../kractions.h" #include "../krglobal.h" #include "../krslots.h" #include "../krusaderview.h" #include "../Panel/krpanel.h" #include "../Panel/panelfunc.h" #include "../GUI/krtreewidget.h" #include "../defaults.h" #include "../krservices.h" -#include "../VFS/vfs.h" -#include "../VFS/virt_vfs.h" +#include "../FileSystem/filesystem.h" +#include "../FileSystem/virtualfilesystem.h" #include "../KViewer/krviewer.h" #include "../panelmanager.h" #include "../kicons.h" // QtCore #include #include #include #include // QtGui #include #include #include #include #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // these are the values that will exist in the menu #define VIEW_ID 90 #define EDIT_ID 91 #define FIND_ID 92 #define FIND_NEXT_ID 93 #define FIND_PREV_ID 94 #define COPY_SELECTED_TO_CLIPBOARD 95 #define COMPARE_ID 96 ////////////////////////////////////////////////////////// class LocateListView : public KrTreeWidget { public: LocateListView(QWidget * parent) : KrTreeWidget(parent) { setAlternatingRowColors(true); } void startDrag(Qt::DropActions supportedActs) { Q_UNUSED(supportedActs); QList urls; QList list = selectedItems() ; QListIterator it(list); while (it.hasNext()) { QTreeWidgetItem * item = it.next(); urls.push_back(QUrl::fromLocalFile(item->text(0))); } if (urls.count() == 0) return; QDrag *drag = new QDrag(this); QMimeData *mimeData = new QMimeData; mimeData->setImageData(FL_LOADICON("file")); mimeData->setUrls(urls); drag->setMimeData(mimeData); drag->start(); } }; KProcess * LocateDlg::updateProcess = 0; LocateDlg * LocateDlg::LocateDialog = 0; LocateDlg::LocateDlg() : QDialog(0), isFeedToListBox(false) { setWindowTitle(i18n("Krusader::Locate")); setWindowModality(Qt::NonModal); QVBoxLayout *mainLayout = new QVBoxLayout; setLayout(mainLayout); QGridLayout *grid = new QGridLayout(); grid->setSpacing(6); grid->setContentsMargins(11, 11, 11, 11); QWidget *hboxWidget = new QWidget(this); QHBoxLayout *hbox = new QHBoxLayout(hboxWidget); hbox->setContentsMargins(0, 0, 0, 0); QLabel *label = new QLabel(i18n("Search for:"), hboxWidget); hbox->addWidget(label); locateSearchFor = new KHistoryComboBox(false, hboxWidget); locateSearchFor->setMinimumContentsLength(10); hbox->addWidget(locateSearchFor); label->setBuddy(locateSearchFor); KConfigGroup group(krConfig, "Locate"); QStringList list = group.readEntry("Search For", QStringList()); locateSearchFor->setMaxCount(25); // remember 25 items locateSearchFor->setHistoryItems(list); locateSearchFor->setEditable(true); locateSearchFor->setDuplicatesEnabled(false); locateSearchFor->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); locateSearchFor->lineEdit()->setFocus(); grid->addWidget(hboxWidget, 0, 0); QWidget *hboxWidget2 = new QWidget(this); QHBoxLayout * hbox2 = new QHBoxLayout(hboxWidget2); hbox2->setContentsMargins(0, 0, 0, 0); QSpacerItem* spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); hbox2->addItem(spacer); dontSearchInPath = new QCheckBox(i18n("Do not search in path"), hboxWidget2); hbox2->addWidget(dontSearchInPath); dontSearchInPath->setChecked(group.readEntry("Don't Search In Path", false)); existingFiles = new QCheckBox(i18n("Show only the existing files"), hboxWidget2); existingFiles->setChecked(group.readEntry("Existing Files", false)); hbox2->addWidget(existingFiles); caseSensitive = new QCheckBox(i18n("Case Sensitive"), hboxWidget2); caseSensitive->setChecked(group.readEntry("Case Sensitive", false)); hbox2->addWidget(caseSensitive); grid->addWidget(hboxWidget2, 1, 0); QFrame *line1 = new QFrame(this); line1->setFrameStyle(QFrame::HLine | QFrame::Sunken); grid->addWidget(line1, 2, 0); resultList = new LocateListView(this); // create the main container resultList->setColumnCount(1); resultList->setHeaderLabel(i18n("Results")); resultList->setColumnWidth(0, QFontMetrics(resultList->font()).width("W") * 60); KConfigGroup gl(krConfig, "Look&Feel"); resultList->setFont(gl.readEntry("Filelist Font", _FilelistFont)); resultList->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); resultList->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); resultList->header()->setSortIndicatorShown(false); resultList->setSortingEnabled(false); resultList->setSelectionMode(QAbstractItemView::ExtendedSelection); resultList->setDragEnabled(true); connect(resultList, SIGNAL(itemRightClicked(QTreeWidgetItem *, const QPoint &, int)), this, SLOT(slotRightClick(QTreeWidgetItem *, const QPoint &))); connect(resultList, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(slotDoubleClick(QTreeWidgetItem *))); connect(resultList, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, SLOT(slotDoubleClick(QTreeWidgetItem *))); grid->addWidget(resultList, 3, 0); QFrame *line2 = new QFrame(this); line2->setFrameStyle(QFrame::HLine | QFrame::Sunken); grid->addWidget(line2, 4, 0); mainLayout->addLayout(grid); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); mainLayout->addWidget(buttonBox); locateButton = new QPushButton(i18n("Locate")); locateButton->setIcon(QIcon::fromTheme(QStringLiteral("system-search"))); locateButton->setDefault(true); buttonBox->addButton(locateButton, QDialogButtonBox::ActionRole); updateDbButton = new QPushButton(i18n("Update DB")); updateDbButton->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh"))); buttonBox->addButton(updateDbButton, QDialogButtonBox::ActionRole); feedStopButton = new QPushButton; buttonBox->addButton(feedStopButton, QDialogButtonBox::ActionRole); connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); connect(locateButton, SIGNAL(clicked()), this, SLOT(slotLocate())); connect(updateDbButton, SIGNAL(clicked()), this, SLOT(slotUpdateDb())); connect(feedStopButton, SIGNAL(clicked()), this, SLOT(slotFeedStop())); updateButtons(false); if (updateProcess) { if (updateProcess->state() == QProcess::Running) { connect(updateProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(updateFinished())); updateDbButton->setEnabled(false); } else updateFinished(); } show(); LocateDialog = this; } void LocateDlg::slotFeedStop() /* The stop / feed to listbox button */ { if (isFeedToListBox) feedToListBox(); else locateProc->kill(); } void LocateDlg::slotUpdateDb() /* The Update DB button */ { if (!updateProcess) { KConfigGroup group(krConfig, "Locate"); updateProcess = new KProcess(); // don't set the parent to 'this'! That would cause this process to be deleted once the dialog is closed *updateProcess << KrServices::fullPathName("updatedb"); *updateProcess << KShell::splitArgs(group.readEntry("UpdateDB Arguments")); connect(updateProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(updateFinished())); updateProcess->start(); updateDbButton->setEnabled(false); } } void LocateDlg::updateFinished() { delete updateProcess; updateProcess = 0; updateDbButton->setEnabled(true); } void LocateDlg::slotLocate() /* The locate button */ { locateSearchFor->addToHistory(locateSearchFor->currentText()); QStringList list = locateSearchFor->historyItems(); KConfigGroup group(krConfig, "Locate"); group.writeEntry("Search For", list); group.writeEntry("Don't Search In Path", dontSearchPath = dontSearchInPath->isChecked()); group.writeEntry("Existing Files", onlyExist = existingFiles->isChecked()); group.writeEntry("Case Sensitive", isCs = caseSensitive->isChecked()); if (!KrServices::cmdExist("locate")) { KMessageBox::error(0, i18n("Cannot start 'locate'. Check the 'Dependencies' page in konfigurator.")); return; } resultList->clear(); lastItem = 0; remaining = ""; updateButtons(true); isFeedToListBox = false; resultList->setFocus(); qApp->processEvents(); //FIXME - whats's this for ? locateProc = new KProcess(this); locateProc->setOutputChannelMode(KProcess::SeparateChannels); // default is forwarding to the parent channels connect(locateProc, SIGNAL(readyReadStandardOutput()), SLOT(processStdout())); connect(locateProc, SIGNAL(readyReadStandardError()), SLOT(processStderr())); connect(locateProc, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(locateFinished())); connect(locateProc, SIGNAL(error(QProcess::ProcessError)), SLOT(locateError())); *locateProc << KrServices::fullPathName("locate"); if (!isCs) *locateProc << "-i"; *locateProc << (pattern = locateSearchFor->currentText()); if (!pattern.startsWith('*')) pattern = '*' + pattern; if (!pattern.endsWith('*')) pattern = pattern + '*'; collectedErr = ""; locateProc->start(); } void LocateDlg::locateError() { if (locateProc->error() == QProcess::FailedToStart) KMessageBox::error(krMainWindow, i18n("Error during the start of 'locate' process.")); } void LocateDlg::locateFinished() { if (locateProc->exitStatus() != QProcess::NormalExit || locateProc->exitStatus()) { if (!collectedErr.isEmpty()) KMessageBox::error(krMainWindow, i18n("Locate produced the following error message:\n\n%1", collectedErr)); } if (resultList->topLevelItemCount() == 0) { locateSearchFor->setFocus(); isFeedToListBox = false; } else { isFeedToListBox = true; } updateButtons(false); } void LocateDlg::processStdout() { remaining += QString::fromLocal8Bit(locateProc->readAllStandardOutput()); QStringList list = remaining.split('\n'); int items = list.size(); for (QStringList::Iterator it = list.begin(); it != list.end(); ++it) { if (--items == 0 && !remaining.endsWith('\n')) remaining = *it; else { if (dontSearchPath) { QRegExp regExp(pattern, isCs ? Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::Wildcard); QString fileName = (*it).trimmed(); if (fileName.endsWith(QLatin1String("/")) && fileName != "/") { fileName.truncate(fileName.length() - 1); } fileName = fileName.mid(fileName.lastIndexOf('/') + 1); if (!regExp.exactMatch(fileName)) continue; } if (onlyExist) { KFileItem file(QUrl::fromLocalFile((*it).trimmed())); if (!file.isReadable()) continue; } if (lastItem) lastItem = new QTreeWidgetItem(resultList, lastItem); else lastItem = new QTreeWidgetItem(resultList); lastItem->setText(0, *it); } } } void LocateDlg::processStderr() { collectedErr += QString::fromLocal8Bit(locateProc->readAllStandardError()); } void LocateDlg::slotRightClick(QTreeWidgetItem *item, const QPoint &pos) { if (!item) return; // create the menu QMenu popup; popup.setTitle(i18nc("@title:menu", "Locate")); QAction * actView = popup.addAction(i18n("View (F3)")); QAction * actEdit = popup.addAction(i18n("Edit (F4)")); QAction * actComp = popup.addAction(i18n("Compare by content (F10)")); if (resultList->selectedItems().count() != 2) actComp->setEnabled(false); popup.addSeparator(); QAction * actFind = popup.addAction(i18n("Find (Ctrl+F)")); QAction * actNext = popup.addAction(i18n("Find next (Ctrl+N)")); QAction * actPrev = popup.addAction(i18n("Find previous (Ctrl+P)")); popup.addSeparator(); QAction * actClip = popup.addAction(i18n("Copy selected to clipboard")); QAction * result = popup.exec(pos); int ret = -1; if (result == actView) ret = VIEW_ID; else if (result == actEdit) ret = EDIT_ID; else if (result == actFind) ret = FIND_ID; else if (result == actNext) ret = FIND_NEXT_ID; else if (result == actPrev) ret = FIND_PREV_ID; else if (result == actClip) ret = COPY_SELECTED_TO_CLIPBOARD; else if (result == actComp) ret = COMPARE_ID; if (ret != - 1) operate(item, ret); } void LocateDlg::slotDoubleClick(QTreeWidgetItem *item) { if (!item) return; QString dirName = item->text(0); QString fileName; if (!QDir(dirName).exists()) { fileName = dirName.mid(dirName.lastIndexOf('/') + 1); dirName.truncate(dirName.lastIndexOf('/')); } ACTIVE_FUNC->openUrl(QUrl::fromLocalFile(dirName), fileName); QDialog::accept(); } void LocateDlg::keyPressEvent(QKeyEvent *e) { if (KrGlobal::copyShortcut == QKeySequence(e->key() | e->modifiers())) { operate(0, COPY_SELECTED_TO_CLIPBOARD); e->accept(); return; } switch (e->key()) { case Qt::Key_M : if (e->modifiers() == Qt::ControlModifier) { resultList->setFocus(); e->accept(); } break; case Qt::Key_F3 : if (resultList->currentItem()) operate(resultList->currentItem(), VIEW_ID); break; case Qt::Key_F4 : if (resultList->currentItem()) operate(resultList->currentItem(), EDIT_ID); break; case Qt::Key_F10 : operate(0, COMPARE_ID); break; case Qt::Key_N : if (e->modifiers() == Qt::ControlModifier) operate(resultList->currentItem(), FIND_NEXT_ID); break; case Qt::Key_P : if (e->modifiers() == Qt::ControlModifier) operate(resultList->currentItem(), FIND_PREV_ID); break; case Qt::Key_F : if (e->modifiers() == Qt::ControlModifier) operate(resultList->currentItem(), FIND_ID); break; } QDialog::keyPressEvent(e); } void LocateDlg::operate(QTreeWidgetItem *item, int task) { QUrl name; if (item != 0) name = QUrl::fromLocalFile(item->text(0)); switch (task) { case VIEW_ID: KrViewer::view(name, this); // view the file break; case EDIT_ID: KrViewer::edit(name, this); // view the file break; case COMPARE_ID: { QList list = resultList->selectedItems(); if (list.count() != 2) break; QUrl url1 = QUrl::fromLocalFile(list[ 0 ]->text(0)); QUrl url2 = QUrl::fromLocalFile(list[ 1 ]->text(0)); SLOTS->compareContent(url1, url2); } break; case FIND_ID: { KConfigGroup group(krConfig, "Locate"); long options = group.readEntry("Find Options", (long long)0); QStringList list = group.readEntry("Find Patterns", QStringList()); QPointer dlg = new KFindDialog(this, options, list); if (dlg->exec() != QDialog::Accepted) { delete dlg; return; } QString first; if (list.count() != 0) { first = list.first(); } if (first != (findPattern = dlg->pattern())) { list.push_front(dlg->pattern()); } group.writeEntry("Find Options", (long long)(findOptions = dlg->options())); group.writeEntry("Find Patterns", list); if (!(findOptions & KFind::FromCursor) && resultList->topLevelItemCount()) resultList->setCurrentItem((findOptions & KFind::FindBackwards) ? resultList->topLevelItem(resultList->topLevelItemCount() - 1) : resultList->topLevelItem(0)); findCurrentItem = resultList->currentItem(); if (find() && findCurrentItem) { resultList->selectionModel()->clearSelection(); // HACK: QT 4 is not able to paint the focus frame because of a bug resultList->setCurrentItem(findCurrentItem); } else { KMessageBox::information(this, i18n("Search string not found.")); } resultList->scrollTo(resultList->currentIndex()); delete dlg; } break; case FIND_NEXT_ID: case FIND_PREV_ID: { if (task == FIND_PREV_ID) findOptions ^= KFind::FindBackwards; findCurrentItem = resultList->currentItem(); nextLine(); if (find() && findCurrentItem) { resultList->selectionModel()->clearSelection(); // HACK: QT 4 is not able to paint the focus frame because of a bug resultList->setCurrentItem(findCurrentItem); } else KMessageBox::information(this, i18n("Search string not found.")); resultList->scrollTo(resultList->currentIndex()); if (task == FIND_PREV_ID) findOptions ^= KFind::FindBackwards; } break; case COPY_SELECTED_TO_CLIPBOARD: { QList urls; QTreeWidgetItemIterator it(resultList); while (*it) { if ((*it)->isSelected()) urls.push_back(QUrl::fromLocalFile((*it)->text(0))); it++; } if (urls.count() == 0) return; QMimeData *mimeData = new QMimeData; mimeData->setImageData(FL_LOADICON("file")); mimeData->setUrls(urls); QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); } break; } } void LocateDlg::nextLine() { if (findOptions & KFind::FindBackwards) findCurrentItem = resultList->itemAbove(findCurrentItem); else findCurrentItem = resultList->itemBelow(findCurrentItem); } bool LocateDlg::find() { while (findCurrentItem) { QString item = findCurrentItem->text(0); if (findOptions & KFind::RegularExpression) { if (item.contains(QRegExp(findPattern, ((findOptions & KFind::CaseSensitive) != 0) ? Qt::CaseSensitive : Qt::CaseInsensitive))) return true; } else { if (item.contains(findPattern, ((findOptions & KFind::CaseSensitive) != 0) ? Qt::CaseSensitive : Qt::CaseInsensitive)) return true; } nextLine(); } return false; } void LocateDlg::feedToListBox() { - virt_vfs virtVfs; - virtVfs.refresh(QUrl::fromLocalFile(QStringLiteral("/"))); + VirtualFileSystem virtFilesystem; + virtFilesystem.refresh(QUrl::fromLocalFile(QStringLiteral("/"))); KConfigGroup group(krConfig, "Locate"); int listBoxNum = group.readEntry("Feed To Listbox Counter", 1); QString queryName; do { queryName = i18n("Locate results") + QString(" %1").arg(listBoxNum++); - } while (virtVfs.getVfile(queryName) != 0); + } while (virtFilesystem.getFileItem(queryName) != 0); group.writeEntry("Feed To Listbox Counter", listBoxNum); KConfigGroup ga(krConfig, "Advanced"); if (ga.readEntry("Confirm Feed to Listbox", _ConfirmFeedToListbox)) { bool ok; queryName = QInputDialog::getText(this, i18n("Query Name"), i18n("Here you can name the file collection:"), QLineEdit::Normal, queryName, &ok); if (! ok) return; } QList urlList; QTreeWidgetItemIterator it(resultList); while (*it) { QTreeWidgetItem * item = *it; urlList.push_back(QUrl::fromLocalFile(item->text(0))); it++; } QUrl url = QUrl(QStringLiteral("virt:/") + queryName); - virtVfs.refresh(url); - virtVfs.addFiles(urlList); + virtFilesystem.refresh(url); + virtFilesystem.addFiles(urlList); //ACTIVE_FUNC->openUrl(url); ACTIVE_MNG->slotNewTab(url); accept(); } void LocateDlg::reset() { locateSearchFor->lineEdit()->setFocus(); locateSearchFor->lineEdit()->selectAll(); } void LocateDlg::updateButtons(bool locateIsRunning) { locateButton->setEnabled(!locateIsRunning); if (locateIsRunning) { feedStopButton->setEnabled(true); feedStopButton->setText(i18n("Stop")); feedStopButton->setIcon(QIcon::fromTheme(QStringLiteral("process-stop"))); } else { if (resultList->topLevelItemCount() == 0) { feedStopButton->setEnabled(false); feedStopButton->setText(i18n("Stop")); feedStopButton->setIcon(QIcon::fromTheme(QStringLiteral("process-stop"))); } else { feedStopButton->setEnabled(true); feedStopButton->setText(i18n("Feed to listbox")); feedStopButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); } } } diff --git a/krusader/MountMan/kmountman.cpp b/krusader/MountMan/kmountman.cpp index 644261c4..159a78ee 100644 --- a/krusader/MountMan/kmountman.cpp +++ b/krusader/MountMan/kmountman.cpp @@ -1,532 +1,532 @@ /*************************************************************************** kmountman.cpp ------------------- copyright : (C) 2000 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "kmountman.h" // QtCore #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../krglobal.h" #include "../kractions.h" #include "../defaults.h" #include "../Dialogs/krdialogs.h" #include "../krservices.h" #include "kmountmangui.h" -#include "../VFS/krpermhandler.h" +#include "../FileSystem/krpermhandler.h" #ifdef _OS_SOLARIS_ -#define FSTAB "/etc/vfstab" +#define FSTAB "/etc/filesystemtab" #else #define FSTAB "/etc/fstab" #endif static int __delayedIdx; // ugly: pass the processEvents deadlock KMountMan::KMountMan(QWidget *parent) : QObject(), Operational(false), waiting(false), mountManGui(0), parentWindow(parent) { _actions = 0L; _action = new KToolBarPopupAction(QIcon::fromTheme("kr_mountman"), i18n("&MountMan..."), this); connect(_action, SIGNAL(triggered(bool)), SLOT(mainWindow())); connect(_action->menu(), SIGNAL(aboutToShow()), SLOT(quickList())); // added as a precaution, although we use kde services now if (!KrServices::cmdExist("mount")) { Operational = false; } else { Operational = true; } network_fs << "nfs" << "smbfs" << "fuse.fusesmb" << "fuse.sshfs"; //TODO: is this list complete ? // list of FS that we don't manage at all invalid_fs << "swap" << "/dev/pts" << "tmpfs" << "devpts" << "sysfs" << "rpc_pipefs" << "usbfs" << "binfmt_misc"; #ifdef BSD invalid_fs << "procfs"; #else invalid_fs << "proc"; #endif // list of FS that we don't allow to mount/unmount nonmount_fs << "supermount"; { KConfigGroup group(krConfig, "Advanced"); QStringList nonmount = group.readEntry("Nonmount Points", _NonMountPoints).split(','); nonmount_fs_mntpoint += nonmount; // simplify the white space for (QStringList::Iterator it = nonmount_fs_mntpoint.begin(); it != nonmount_fs_mntpoint.end(); ++it) { *it = (*it).simplified(); } } } KMountMan::~KMountMan() {} bool KMountMan::invalidFilesystem(QString type) { return (invalid_fs.contains(type) > 0); } // this is an ugly hack, but type can actually be a mountpoint. oh well... bool KMountMan::nonmountFilesystem(QString type, QString mntPoint) { return((nonmount_fs.contains(type) > 0) || (nonmount_fs_mntpoint.contains(mntPoint) > 0)); } bool KMountMan::networkFilesystem(QString type) { return (network_fs.contains(type) > 0); } void KMountMan::mainWindow() { // left as a precaution, although we use kde's services now if (!KrServices::cmdExist("mount")) { KMessageBox::error(0, i18n("Cannot start 'mount'. Check the 'Dependencies' page in konfigurator.")); return; } mountManGui = new KMountManGUI(this); delete mountManGui; /* as KMountManGUI is modal, we can now delete it */ mountManGui = 0; /* for sanity */ } QExplicitlySharedDataPointer KMountMan::findInListByMntPoint(KMountPoint::List &lst, QString value) { if (value.length() > 1 && value.endsWith('/')) value = value.left(value.length() - 1); QExplicitlySharedDataPointer m; for (KMountPoint::List::iterator it = lst.begin(); it != lst.end(); ++it) { m = it->data(); QString mntPnt = m->mountPoint(); if (mntPnt.length() > 1 && mntPnt.endsWith('/')) mntPnt = mntPnt.left(mntPnt.length() - 1); if (mntPnt == value) return m; } return QExplicitlySharedDataPointer(); } void KMountMan::jobResult(KJob *job) { waiting = false; if (job->error()) job->uiDelegate()->showErrorMessage(); } void KMountMan::mount(QString mntPoint, bool blocking) { QString udi = findUdiForPath(mntPoint, Solid::DeviceInterface::StorageAccess); if (!udi.isNull()) { Solid::Device device(udi); Solid::StorageAccess *access = device.as(); if (access && !access->isAccessible()) { connect(access, SIGNAL(setupDone(Solid::ErrorType, QVariant, const QString &)), this, SLOT(slotSetupDone(Solid::ErrorType, QVariant, const QString &))); if (blocking) waiting = true; // prepare to block access->setup(); } } else { KMountPoint::List possible = KMountPoint::possibleMountPoints(KMountPoint::NeedMountOptions); QExplicitlySharedDataPointer m = findInListByMntPoint(possible, mntPoint); if (!((bool)m)) return; if (blocking) waiting = true; // prepare to block // KDE4 doesn't allow mounting devices as user, because they think it's the right behaviour. // I add this patch, as I don't think so. if (geteuid()) { // tries to mount as an user? KProcess proc; proc << KrServices::fullPathName("mount") << mntPoint; proc.start(); if (!blocking) return; proc.waitForFinished(-1); // -1 msec blocks without timeout if (proc.exitStatus() == QProcess::NormalExit && proc.exitCode() == 0) return; } KIO::SimpleJob *job = KIO::mount(false, m->mountType().toLocal8Bit(), m->mountedFrom(), m->mountPoint(), KIO::DefaultFlags); job->setUiDelegate(new KIO::JobUiDelegate()); KIO::getJobTracker()->registerJob(job); connect(job, SIGNAL(result(KJob*)), this, SLOT(jobResult(KJob*))); } while (blocking && waiting) { qApp->processEvents(); usleep(1000); } } void KMountMan::unmount(QString mntPoint, bool blocking) { //if working dir is below mountpoint cd to ~ first if(QUrl::fromLocalFile(QDir(mntPoint).canonicalPath()).isParentOf(QUrl::fromLocalFile(QDir::current().canonicalPath()))) QDir::setCurrent(QDir::homePath()); QString udi = findUdiForPath(mntPoint, Solid::DeviceInterface::StorageAccess); if (!udi.isNull()) { Solid::Device device(udi); Solid::StorageAccess *access = device.as(); if (access && access->isAccessible()) { connect(access, SIGNAL(teardownDone(Solid::ErrorType, QVariant, const QString &)), this, SLOT(slotTeardownDone(Solid::ErrorType, QVariant, const QString &))); access->teardown(); } } else { if (blocking) waiting = true; // prepare to block // KDE4 doesn't allow unmounting devices as user, because they think it's the right behaviour. // I add this patch, as I don't think so. if (geteuid()) { // tries to mount as an user? KProcess proc; proc << KrServices::fullPathName("umount") << mntPoint; proc.start(); if (!blocking) return; proc.waitForFinished(-1); // -1 msec blocks without timeout if (proc.exitStatus() == QProcess::NormalExit && proc.exitCode() == 0) return; } KIO::SimpleJob *job = KIO::unmount(mntPoint, KIO::DefaultFlags); job->setUiDelegate(new KIO::JobUiDelegate()); KIO::getJobTracker()->registerJob(job); connect(job, SIGNAL(result(KJob*)), this, SLOT(jobResult(KJob*))); } while (blocking && waiting) { qApp->processEvents(); usleep(1000); } } KMountMan::mntStatus KMountMan::getStatus(QString mntPoint) { KMountPoint::List::iterator it; QExplicitlySharedDataPointer m; // 1: is it already mounted KMountPoint::List current = KMountPoint::currentMountPoints(); m = findInListByMntPoint(current, mntPoint); if ((bool)m) return MOUNTED; // 2: is it a mount point but not mounted? KMountPoint::List possible = KMountPoint::possibleMountPoints(); m = findInListByMntPoint(possible, mntPoint); if ((bool)m) return NOT_MOUNTED; // 3: unknown return DOESNT_EXIST; } void KMountMan::toggleMount(QString mntPoint) { mntStatus status = getStatus(mntPoint); switch (status) { case MOUNTED: unmount(mntPoint); break; case NOT_MOUNTED: mount(mntPoint); break; case DOESNT_EXIST: // do nothing: no-op to make the compiler quiet ;-) break; } } void KMountMan::autoMount(QString path) { KConfigGroup group(krConfig, "Advanced"); if (!group.readEntry("AutoMount", _AutoMount)) return; // auto mount disabled if (getStatus(path) == NOT_MOUNTED) mount(path); } void KMountMan::eject(QString mntPoint) { QString udi = findUdiForPath(mntPoint, Solid::DeviceInterface::OpticalDrive); if (udi.isNull()) return; Solid::Device dev(udi); Solid::OpticalDrive *drive = dev.as(); if (drive == 0) return; //if working dir is below mountpoint cd to ~ first if(QUrl::fromLocalFile(QDir(mntPoint).canonicalPath()).isParentOf(QUrl::fromLocalFile(QDir::current().canonicalPath()))) QDir::setCurrent(QDir::homePath()); connect(drive, SIGNAL(ejectDone(Solid::ErrorType, QVariant, const QString &)), this, SLOT(slotTeardownDone(Solid::ErrorType, QVariant, const QString &))); drive->eject(); } // returns true if the path is an ejectable mount point (at the moment CDROM and DVD) bool KMountMan::ejectable(QString path) { QString udi = findUdiForPath(path, Solid::DeviceInterface::OpticalDisc); if (udi.isNull()) return false; Solid::Device dev(udi); return dev.as() != 0; } bool KMountMan::removable(QString path) { QString udi = findUdiForPath(path, Solid::DeviceInterface::StorageAccess); if (udi.isNull()) return false; return removable(Solid::Device(udi)); } bool KMountMan::removable(Solid::Device d) { if(!d.isValid()) return false; Solid::StorageDrive *drive = d.as(); if(drive) return drive->isRemovable(); else return(removable(d.parent())); } // a mountMan special version of KIO::convertSize, which deals // with large filesystems ==> > 4GB, it actually receives size in // a minimum block of 1024 ==> data is KB not bytes QString KMountMan::convertSize(KIO::filesize_t size) { float fsize; QString s; QLocale loc; // Tera-byte if (size >= 1073741824) { fsize = (float) size / (float) 1073741824; if (fsize > 1024) // no name for something bigger than tera byte // let's call it Zega-Byte, who'll ever find out? :-) s = i18n("%1 ZB", loc.toString(fsize / (float) 1024, 'f', 1)); else s = i18n("%1 TB", loc.toString(fsize, 'f', 1)); } // Giga-byte else if (size >= 1048576) { fsize = (float) size / (float) 1048576; s = i18n("%1 GB", loc.toString(fsize, 'f', 1)); } // Mega-byte else if (size > 1024) { fsize = (float) size / (float) 1024; s = i18n("%1 MB", loc.toString(fsize, 'f', 1)); } // Kilo-byte else { fsize = (float) size; s = i18n("%1 KB", loc.toString(fsize, 'f', 0)); } return s; } // populate the pop-up menu of the mountman tool-button with actions void KMountMan::quickList() { if (!Operational) { KMessageBox::error(0, i18n("MountMan is not operational. Sorry")); return ; } // clear the popup menu _action->menu() ->clear(); // create lists of current and possible mount points KMountPoint::List current = KMountPoint::currentMountPoints(); KMountPoint::List possible = KMountPoint::possibleMountPoints(); // create a menu, displaying mountpoints with possible actions // also, populate a small array with the actions if (_actions) delete[] _actions; _actions = new QString[ possible.size()]; KMountPoint::List::iterator it; QExplicitlySharedDataPointer m; int idx; for (it = possible.begin(), idx = 0; it != possible.end(); ++it, ++idx) { m = it->data(); // skip nonmountable file systems if (nonmountFilesystem(m->mountType(), m->mountPoint()) || invalidFilesystem(m->mountType())) continue; // does the mountpoint exist in current list? if so, it can only // be umounted, otherwise, it can be mounted bool needUmount = false; KMountPoint::List::iterator otherIt; for (otherIt = current.begin(); otherIt != current.end(); ++otherIt) { if ((*otherIt) ->mountPoint() == m->mountPoint()) { // found it, in needs umount needUmount = true; break; } } // add the item to the menu _actions[ idx ] = QString(needUmount ? "_U_" : "_M_") + m->mountPoint(); QString text = QString((needUmount ? i18n("Unmount") : i18n("Mount"))) + ' ' + m->mountPoint() + " (" + m->mountedFrom() + ')'; QAction * act = _action->menu() ->addAction(text); act->setData(QVariant(idx)); } connect(_action->menu(), SIGNAL(triggered(QAction *)), this, SLOT(delayedPerformAction(QAction *))); } void KMountMan::delayedPerformAction(QAction * act) { int idx = -1; if (act && act->data().canConvert()) idx = act->data().toInt(); __delayedIdx = idx; if (idx < 0) return ; QTimer::singleShot(0, this, SLOT(performAction())); } void KMountMan::performAction() { if (_actions == 0 || __delayedIdx < 0) // for sanity return; // ugly !!! take idx from the value put there by delayedPerformAction so // as to NOT DIE because of a processEvents deadlock!!! @#$@!@ int idx = __delayedIdx; bool domount = _actions[ idx ].left(3) == "_M_"; QString mountPoint = _actions[ idx ].mid(3); if (!domount) { // umount unmount(mountPoint); } else { // mount mount(mountPoint); } // free memory delete[] _actions; _actions = 0L; disconnect(_action->menu(), SIGNAL(triggered(QAction *)), 0, 0); } QString KMountMan::findUdiForPath(QString path, const Solid::DeviceInterface::Type &expType) { KMountPoint::List current = KMountPoint::currentMountPoints(); KMountPoint::List possible = KMountPoint::possibleMountPoints(); QExplicitlySharedDataPointer mp = findInListByMntPoint(current, path); if (!(bool)mp) { mp = findInListByMntPoint(possible, path); if (!(bool)mp) return QString(); } QString dev = QDir(mp->mountedFrom()).canonicalPath(); QList storageDevices = Solid::Device::listFromType(Solid::DeviceInterface::Block); for (int p = storageDevices.count() - 1 ; p >= 0; p--) { Solid::Device device = storageDevices[ p ]; QString udi = device.udi(); Solid::Block * sb = device.as(); if (sb) { QString devb = QDir(sb->device()).canonicalPath(); if (expType != Solid::DeviceInterface::Unknown && !device.isDeviceInterface(expType)) continue; if (devb == dev) return udi; } } return QString(); } QString KMountMan::pathForUdi(QString udi) { Solid::Device device(udi); Solid::StorageAccess *access = device.as(); if(access) return access->filePath(); else return QString(); } void KMountMan::slotTeardownDone(Solid::ErrorType error, QVariant errorData, const QString& /*udi*/) { waiting = false; if (error != Solid::NoError && errorData.isValid()) { KMessageBox::sorry(parentWindow, errorData.toString()); } } void KMountMan::slotSetupDone(Solid::ErrorType error, QVariant errorData, const QString& /*udi*/) { waiting = false; if (error != Solid::NoError && errorData.isValid()) { KMessageBox::sorry(parentWindow, errorData.toString()); } } diff --git a/krusader/MountMan/kmountmangui.cpp b/krusader/MountMan/kmountmangui.cpp index 1ec04699..dba87a6a 100644 --- a/krusader/MountMan/kmountmangui.cpp +++ b/krusader/MountMan/kmountmangui.cpp @@ -1,540 +1,540 @@ /*************************************************************************** kmountmangui.cpp ------------------- copyright : (C) 2000 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "kmountmangui.h" #include "../krglobal.h" #include "../Dialogs/krspecialwidgets.h" #include "../kicons.h" #include "../defaults.h" -#include "../VFS/vfs.h" +#include "../FileSystem/filesystem.h" // QtCore #include #include #include // QtGui #include #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef BSD #define MTAB "/etc/mtab" #endif KMountManGUI::KMountManGUI(KMountMan *mntMan) : QDialog(mntMan->parentWindow), mountMan(mntMan), info(0), mountList(0), cbShowOnlyRemovable(0), watcher(0), sizeX(-1), sizeY(-1) { setWindowTitle(i18n("MountMan - Your Mount-Manager")); setWindowModality(Qt::WindowModal); QVBoxLayout *mainLayout = new QVBoxLayout; setLayout(mainLayout); watcher = new QTimer(this); connect(watcher, SIGNAL(timeout()), this, SLOT(checkMountChange())); mainLayout->addLayout(createMainPage()); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); mainLayout->addWidget(buttonBox); ejectButton = new QPushButton(i18n("&Eject")); ejectButton->setIcon(QIcon::fromTheme(QStringLiteral("media-eject"))); ejectButton->setEnabled(false); buttonBox->addButton(ejectButton, QDialogButtonBox::ActionRole); mountButton = new QPushButton(i18n("&Unmount")); mountButton->setEnabled(false); buttonBox->addButton(mountButton, QDialogButtonBox::ActionRole); // connections connect(buttonBox, SIGNAL(rejected()), SLOT(reject())); connect(ejectButton, SIGNAL(clicked()), SLOT(slotEject())); connect(mountButton, SIGNAL(clicked()), SLOT(slotToggleMount())); connect(mountList, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(doubleClicked(QTreeWidgetItem *))); connect(mountList, SIGNAL(itemRightClicked(QTreeWidgetItem *, const QPoint &, int)), this, SLOT(clicked(QTreeWidgetItem*, const QPoint &))); connect(mountList, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(changeActive(QTreeWidgetItem *))); connect(mountList, SIGNAL(itemSelectionChanged()), this, SLOT(changeActive())); KConfigGroup group(krConfig, "MountMan"); int sx = group.readEntry("Window Width", -1); int sy = group.readEntry("Window Height", -1); if (sx != -1 && sy != -1) resize(sx, sy); else resize(600, 300); if (group.readEntry("Window Maximized", false)) showMaximized(); else show(); getSpaceData(); exec(); } KMountManGUI::~KMountManGUI() { watcher->stop(); delete watcher; KConfigGroup group(krConfig, "MountMan"); group.writeEntry("Window Width", sizeX); group.writeEntry("Window Height", sizeY); group.writeEntry("Window Maximized", isMaximized()); group.writeEntry("Last State", mountList->header()->saveState()); group.writeEntry("ShowOnlyRemovable", cbShowOnlyRemovable->isChecked()); } void KMountManGUI::resizeEvent(QResizeEvent *e) { if (!isMaximized()) { sizeX = e->size().width(); sizeY = e->size().height(); } QDialog::resizeEvent(e); } QLayout *KMountManGUI::createMainPage() { QGridLayout *layout = new QGridLayout(); layout->setSpacing(10); mountList = new KrTreeWidget(this); // create the main container KConfigGroup grp(krConfig, "Look&Feel"); mountList->setFont(grp.readEntry("Filelist Font", _FilelistFont)); mountList->setSelectionMode(QAbstractItemView::SingleSelection); mountList->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); mountList->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); QStringList labels; labels << i18n("Name"); labels << i18n("Type"); labels << i18n("Mnt.Point"); labels << i18n("Total Size"); labels << i18n("Free Size"); labels << i18n("Free %"); mountList->setHeaderLabels(labels); mountList->header()->setSectionResizeMode(QHeaderView::Interactive); grp = KConfigGroup(krConfig, "MountMan"); if (grp.hasKey("Last State")) mountList->header()->restoreState(grp.readEntry("Last State", QByteArray())); else { int i = QFontMetrics(mountList->font()).width("W"); int j = QFontMetrics(mountList->font()).width("0"); j = (i > j ? i : j); mountList->setColumnWidth(0, j*8); mountList->setColumnWidth(1, j*4); mountList->setColumnWidth(2, j*8); mountList->setColumnWidth(3, j*6); mountList->setColumnWidth(4, j*6); mountList->setColumnWidth(5, j*5); } mountList->setAllColumnsShowFocus(true); mountList->header()->setSortIndicatorShown(true); mountList->sortItems(0, Qt::AscendingOrder); // now the list is created, time to fill it with data. //=>mountMan->forceUpdate(); QGroupBox *box = new QGroupBox(i18n("MountMan.Info"), this); box->setAlignment(Qt::AlignHCenter); QVBoxLayout *vboxl = new QVBoxLayout(box); info = new KRFSDisplay(box); vboxl->addWidget(info); info->resize(info->width(), height()); cbShowOnlyRemovable = new QCheckBox(i18n("Show only removable devices"), this); cbShowOnlyRemovable->setChecked(grp.readEntry("ShowOnlyRemovable", false)); connect(cbShowOnlyRemovable , SIGNAL(stateChanged(int)), SLOT(updateList())); layout->addWidget(box, 0, 0); layout->addWidget(cbShowOnlyRemovable, 1, 0); layout->addWidget(mountList, 0, 1, 2, 1); return layout; } void KMountManGUI::getSpaceData() { fileSystems.clear(); KrMountDetector::getInstance()->hasMountsChanged(); mounted = KMountPoint::currentMountPoints(); possible = KMountPoint::possibleMountPoints(); if (mounted.size() == 0) { // nothing is mounted addNonMounted(); updateList(); // let's continue return ; } for (KMountPoint::List::iterator it = mounted.begin(); it != mounted.end(); ++it) { // don't bother with invalid file systems if (mountMan->invalidFilesystem((*it)->mountType())) { continue; } KDiskFreeSpaceInfo info = KDiskFreeSpaceInfo::freeSpaceInfo((*it) ->mountPoint()); if(!info.isValid()) { continue; } fsData data; data.setMntPoint((*it) ->mountPoint()); data.setMounted(true); data.setTotalBlks(info.size() / 1024); data.setFreeBlks(info.available() / 1024); data.setName((*it)->mountedFrom()); data.setType((*it)->mountType()); fileSystems.append(data); } addNonMounted(); updateList(); } void KMountManGUI::addNonMounted() { // handle the non-mounted ones for (KMountPoint::List::iterator it = possible.begin(); it != possible.end(); ++it) { // make sure we don't add things we've already added if (KMountMan::findInListByMntPoint(mounted, (*it)->mountPoint())) { continue; } else { fsData data; data.setMntPoint((*it)->mountPoint()); data.setMounted(false); data.setType((*it)->mountType()); data.setName((*it)->mountedFrom()); if (mountMan->invalidFilesystem(data.type())) continue; fileSystems.append(data); } } } void KMountManGUI::addItemToMountList(KrTreeWidget *lst, fsData &fs) { Solid::Device device(mountMan->findUdiForPath(fs.mntPoint(), Solid::DeviceInterface::StorageAccess)); if (cbShowOnlyRemovable->isChecked() && !mountMan->removable(device)) return; bool mtd = fs.mounted(); QString tSize = QString("%1").arg(KIO::convertSizeFromKiB(fs.totalBlks())); QString fSize = QString("%1").arg(KIO::convertSizeFromKiB(fs.freeBlks())); QString sPrct = QString("%1%").arg(100 - (fs.usedPerct())); QTreeWidgetItem *item = new QTreeWidgetItem(lst); item->setText(0, fs.name()); item->setText(1, fs.type()); item->setText(2, fs.mntPoint()); item->setText(3, (mtd ? tSize : QString("N/A"))); item->setText(4, (mtd ? fSize : QString("N/A"))); item->setText(5, (mtd ? sPrct : QString("N/A"))); Solid::StorageVolume *vol = device.as (); QString icon; if(device.isValid()) icon = device.icon(); else if(mountMan->networkFilesystem(fs.type())) icon = "folder-remote"; QStringList overlays; if (mtd) { overlays << "emblem-mounted"; } else { overlays << QString(); // We have to guarantee the placement of the next emblem } if (vol && vol->usage() == Solid::StorageVolume::Encrypted) { overlays << "security-high"; } item->setIcon(0, KDE::icon(icon, overlays)); } void KMountManGUI::updateList() { QString currentMP; int currentIdx = 0; QTreeWidgetItem *currentItem = mountList->currentItem(); if(currentItem) { currentMP = getMntPoint(currentItem); currentIdx = mountList->indexOfTopLevelItem(currentItem); } mountList->clearSelection(); mountList->clear(); for (QList::iterator it = fileSystems.begin(); it != fileSystems.end() ; ++it) addItemToMountList(mountList, *it); currentItem = mountList->topLevelItem(currentIdx); for(int i = 0; i < mountList->topLevelItemCount(); i++) { QTreeWidgetItem *item = mountList->topLevelItem(i); if(getMntPoint(item) == currentMP) currentItem = item; } if(!currentItem) currentItem = mountList->topLevelItem(0); mountList->setCurrentItem(currentItem); changeActive(currentItem); mountList->setFocus(); watcher->setSingleShot(true); watcher->start(WATCHER_DELAY); // starting the watch timer ( single shot ) } void KMountManGUI::checkMountChange() { if (KrMountDetector::getInstance()->hasMountsChanged()) getSpaceData(); watcher->setSingleShot(true); watcher->start(WATCHER_DELAY); // starting the watch timer ( single shot ) } void KMountManGUI::doubleClicked(QTreeWidgetItem *i) { if (!i) return; // we don't want to refresh to swap, do we ? // change the active panel to this mountpoint mountMan->emitRefreshPanel(QUrl::fromLocalFile(getMntPoint(i))); close(); } void KMountManGUI::changeActive() { QList seld = mountList->selectedItems(); if (seld.count() > 0) changeActive(seld[ 0 ]); } // when user clicks on a filesystem, change information void KMountManGUI::changeActive(QTreeWidgetItem *i) { if (!i) { if (info) { info->setEmpty(true); info->update(); } mountButton->setEnabled(false); ejectButton->setEnabled(false); return; } fsData *system = getFsData(i); info->setAlias(system->mntPoint()); info->setRealName(system->name()); info->setMounted(system->mounted()); info->setEmpty(false); info->setTotalSpace(system->totalBlks()); info->setFreeSpace(system->freeBlks()); info->repaint(); if(system->mounted()) mountButton->setText(i18n("&Unmount")); else mountButton->setText(i18n("&Mount")); ejectButton->setEnabled(mountMan->ejectable(system->mntPoint())); mountButton->setEnabled(true); } // called when right-clicked on a filesystem void KMountManGUI::clicked(QTreeWidgetItem *item, const QPoint & pos) { // these are the values that will exist in the menu #define MOUNT_ID 90 #define UNMOUNT_ID 91 #define FORMAT_ID 93 #define EJECT_ID 94 ////////////////////////////////////////////////////////// if (!item) return ; fsData *system = getFsData(item); // create the menu QMenu popup; popup.setTitle(i18n("MountMan")); if (!system->mounted()) { QAction *mountAct = popup.addAction(i18n("Mount")); mountAct->setData(QVariant(MOUNT_ID)); bool enable = !(mountMan->nonmountFilesystem(system->type(), system->mntPoint())); mountAct->setEnabled(enable); } else { QAction * umountAct = popup.addAction(i18n("Unmount")); umountAct->setData(QVariant(UNMOUNT_ID)); bool enable = !(mountMan->nonmountFilesystem(system->type(), system->mntPoint())); umountAct->setEnabled(enable); } if (mountMan->ejectable(system->mntPoint())) // if (system->type()=="iso9660" || mountMan->followLink(system->name()).left(2)=="cd") popup.addAction(i18n("Eject"))->setData(QVariant(EJECT_ID)); else { QAction *formatAct = popup.addAction(i18n("Format")); formatAct->setData(QVariant(FORMAT_ID)); formatAct->setEnabled(false); } QString mountPoint = system->mntPoint(); QAction * res = popup.exec(pos); int result = -1; if (res && res->data().canConvert()) result = res->data().toInt(); // check out the user's option switch (result) { case - 1 : return ; // the user clicked outside of the menu case MOUNT_ID : case UNMOUNT_ID : mountMan->toggleMount(mountPoint); break; case FORMAT_ID : break; case EJECT_ID : mountMan->eject(mountPoint); break; } } void KMountManGUI::slotToggleMount() { QTreeWidgetItem *item = mountList->currentItem(); if(item) { mountMan->toggleMount(getFsData(item)->mntPoint()); } } void KMountManGUI::slotEject() { QTreeWidgetItem *item = mountList->currentItem(); if(item) { mountMan->eject(getFsData(item)->mntPoint()); } } fsData* KMountManGUI::getFsData(QTreeWidgetItem *item) { for (QList::Iterator it = fileSystems.begin(); it != fileSystems.end(); ++it) { // the only thing which is unique is the mount point if ((*it).mntPoint() == getMntPoint(item)) { return & (*it); } } //this point shouldn't be reached abort(); return 0; } QString KMountManGUI::getMntPoint(QTreeWidgetItem *item) { return item->text(2); // text(2) ? ugly ugly ugly } KrMountDetector::KrMountDetector() { hasMountsChanged(); } bool KrMountDetector::hasMountsChanged() { bool result = false; #ifndef BSD QFileInfo mtabInfo(MTAB); if (!mtabInfo.exists() || mtabInfo.isSymLink()) { // if mtab is a symlimk to /proc/mounts the mtime is unusable #endif KMountPoint::List mountPoints = KMountPoint::currentMountPoints(KMountPoint::NeedRealDeviceName); QCryptographicHash md5(QCryptographicHash::Md5); for (KMountPoint::List::iterator i = mountPoints.begin(); i != mountPoints.end(); ++i) { md5.addData((*i)->mountedFrom().toUtf8()); md5.addData((*i)->realDeviceName().toUtf8()); md5.addData((*i)->mountPoint().toUtf8()); md5.addData((*i)->mountType().toUtf8()); } QString s = md5.result(); result = s != checksum; checksum = s; #ifndef BSD } else { result = mtabInfo.lastModified() != lastMtab; lastMtab = mtabInfo.lastModified(); } #endif return result; } KrMountDetector krMountDetector; KrMountDetector * KrMountDetector::getInstance() { return & krMountDetector; } diff --git a/krusader/Panel/dirhistoryqueue.cpp b/krusader/Panel/dirhistoryqueue.cpp index 58d8ea65..37e52e57 100644 --- a/krusader/Panel/dirhistoryqueue.cpp +++ b/krusader/Panel/dirhistoryqueue.cpp @@ -1,171 +1,171 @@ /***************************************************************************** * Copyright (C) 2004 Shie Erlich * * Copyright (C) 2004 Rafi Yanai * * Copyright (C) 2010 Jan Lepper * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "dirhistoryqueue.h" #include "krpanel.h" #include "krview.h" #include "../defaults.h" #include "../krservices.h" // QtCore #include DirHistoryQueue::DirHistoryQueue(KrPanel *panel) : _panel(panel), _state(0), _currentPos(0) { } DirHistoryQueue::~DirHistoryQueue() {} void DirHistoryQueue::clear() { _urlQueue.clear(); _currentItems.clear(); _currentPos = 0; _state++; } QUrl DirHistoryQueue::currentUrl() { if(_urlQueue.count()) return _urlQueue[_currentPos]; else return QUrl(); } void DirHistoryQueue::setCurrentUrl(const QUrl &url) { if(_urlQueue.count()) _urlQueue[_currentPos] = url; } QString DirHistoryQueue::currentItem() { if(count()) return _currentItems[_currentPos]; else return QString(); } void DirHistoryQueue::saveCurrentItem() { - // if the vfs-url hasn't been refreshed yet, + // if the filesystem-url hasn't been refreshed yet, // avoid saving current item for the wrong url if(count() && _panel->virtualPath().matches(_urlQueue[_currentPos], QUrl::StripTrailingSlash)) _currentItems[_currentPos] = _panel->view->getCurrentItem(); } void DirHistoryQueue::add(QUrl url, QString currentItem) { url.setPath(QDir::cleanPath(url.path())); if(_urlQueue.isEmpty()) { _urlQueue.push_front(url); _currentItems.push_front(currentItem); _state++; return; } if(_urlQueue[_currentPos].matches(url, QUrl::StripTrailingSlash)) { _currentItems[_currentPos] = currentItem; return; } for (int i = 0; i < _currentPos; i++) { _urlQueue.pop_front(); _currentItems.pop_front(); } _currentPos = 0; // do we have room for another ? if (_urlQueue.count() > 12) { // FIXME: use user-defined size // no room - remove the oldest entry _urlQueue.pop_back(); _currentItems.pop_back(); } saveCurrentItem(); _urlQueue.push_front(url); _currentItems.push_front(currentItem); _state++; } void DirHistoryQueue::pushBackRoot() { _urlQueue.push_back(QUrl::fromLocalFile(ROOT_DIR)); _currentItems.push_back(QString()); } bool DirHistoryQueue::gotoPos(int pos) { if(pos >= 0 && pos < _urlQueue.count()) { saveCurrentItem(); _currentPos = pos; _state++; return true; } return false; } bool DirHistoryQueue::goBack() { return gotoPos(_currentPos + 1); } bool DirHistoryQueue::goForward() { return gotoPos(_currentPos - 1); } void DirHistoryQueue::save(KConfigGroup cfg) { saveCurrentItem(); QList urls; foreach(QUrl url, _urlQueue) { // make sure no passwords are permanently stored url.setPassword(QString()); urls << url; } cfg.writeEntry("Entrys", KrServices::toStringList(urls)); cfg.writeEntry("CurrentItems", _currentItems); cfg.writeEntry("CurrentIndex", _currentPos); } bool DirHistoryQueue::restore(KConfigGroup cfg) { clear(); _urlQueue = KrServices::toUrlList(cfg.readEntry("Entrys", QStringList())); _currentItems = cfg.readEntry("CurrentItems", QStringList()); if(!_urlQueue.count() || _urlQueue.count() != _currentItems.count()) { clear(); return false; } _currentPos = cfg.readEntry("CurrentIndex", 0); if(_currentPos >= _urlQueue.count() || _currentPos < 0) _currentPos = 0; _state++; return true; } diff --git a/krusader/Panel/krcalcspacedialog.cpp b/krusader/Panel/krcalcspacedialog.cpp index 93f1d1a9..017e75b8 100644 --- a/krusader/Panel/krcalcspacedialog.cpp +++ b/krusader/Panel/krcalcspacedialog.cpp @@ -1,234 +1,234 @@ /*************************************************************************** krcalcspacedialog.cpp - description ------------------- begin : Fri Jan 2 2004 copyright : (C) 2004 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "krcalcspacedialog.h" // QtCore #include #include // QtWidgets #include #include #include #include #include #include #include "krpanel.h" #include "panelfunc.h" #include "../krglobal.h" -#include "../VFS/krpermhandler.h" -#include "../VFS/krvfshandler.h" +#include "../FileSystem/krpermhandler.h" +#include "../FileSystem/filesystemprovider.h" /* --=={ Patch by Heiner }==-- */ KrCalcSpaceDialog::CalcThread::CalcThread(QUrl url, const QStringList & items) : m_totalSize(0), m_currentSize(0), m_totalFiles(0), m_totalDirs(0), m_items(items), m_url(url), m_stop(false) {} void KrCalcSpaceDialog::CalcThread::getStats(KIO::filesize_t &totalSize, unsigned long &totalFiles, unsigned long &totalDirs) const { QMutexLocker locker(&m_mutex); totalSize = m_totalSize + m_currentSize; totalFiles = m_totalFiles; totalDirs = m_totalDirs; } void KrCalcSpaceDialog::CalcThread::updateItems(KrView *view) const { QMutexLocker locker(&m_mutex); for (QStringList::const_iterator it = m_items.constBegin(); it != m_items.constEnd(); ++it) { KrViewItem *viewItem = view->findItemByName(*it); if (viewItem) { viewItem->setSize(m_sizes[*it]); viewItem->redraw(); } } } void KrCalcSpaceDialog::CalcThread::run() { if (!m_items.isEmpty()) { // if something to do: do the calculation - vfs *files = KrVfsHandler::instance().getVfs(m_url); + FileSystem *files = FileSystemProvider::instance().getFilesystem(m_url); if(!files->refresh(m_url)) return; for (QStringList::ConstIterator it = m_items.begin(); it != m_items.end(); ++it) { files->calcSpace(*it, &m_currentSize, &m_totalFiles, &m_totalDirs , & m_stop); if (m_stop) break; m_mutex.lock(); m_sizes[*it] = m_currentSize; m_totalSize += m_currentSize; m_currentSize = 0; m_mutex.unlock(); } delete files; } } void KrCalcSpaceDialog::CalcThread::stop() { // cancel was pressed m_stop = true; } KrCalcSpaceDialog::KrCalcSpaceDialog(QWidget *parent, KrPanel * panel, const QStringList & items, bool autoclose) : QDialog(parent), m_autoClose(autoclose), m_canceled(false), m_timerCounter(0), m_items(items), m_view(panel->view) { setWindowTitle(i18n("Calculate Occupied Space")); setWindowModality(Qt::WindowModal); QVBoxLayout *mainLayout = new QVBoxLayout; setLayout(mainLayout); m_thread = new CalcThread(panel->virtualPath(), items); m_pollTimer = new QTimer(this); m_label = new QLabel("", this); mainLayout->addWidget(m_label); showResult(); // fill m_label with something useful mainLayout->addStretch(10); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); mainLayout->addWidget(buttonBox); okButton = buttonBox->button(QDialogButtonBox::Ok); okButton->setDefault(true); okButton->setShortcut(Qt::CTRL | Qt::Key_Return); // the dialog: The Ok button is hidden until it is needed okButton->setVisible(false); cancelButton = buttonBox->button(QDialogButtonBox::Cancel); connect(buttonBox, SIGNAL(accepted()), SLOT(accept())); connect(buttonBox, SIGNAL(rejected()), SLOT(slotCancel())); } void KrCalcSpaceDialog::calculationFinished() { m_thread->updateItems(m_view); // close dialog if auto close is true if (m_autoClose) { done(0); return; } // otherwise hide cancel and show ok button cancelButton->setVisible(false); okButton->setVisible(true); showResult(); // and show final result } /* This timer has two jobs: it polls the thread if it is finished. Polling is better here as it might finish while the dialog builds up. Secondly it refreshes the displayed result. */ void KrCalcSpaceDialog::timer() { // thread finished? if (m_thread->isFinished()) { // close dialog or switch buttons calculationFinished(); m_pollTimer->stop(); // stop the polling. No longer needed return; } // Every 10 pollings (1 second) refresh the displayed result if (++m_timerCounter > 10) { m_timerCounter = 0; showResult(); m_thread->updateItems(m_view); } } void KrCalcSpaceDialog::showResult() { if (!m_thread) return; KIO::filesize_t totalSize; unsigned long totalFiles, totalDirs; m_thread->getStats(totalSize, totalFiles, totalDirs); QString msg; QString fileName = (m_items.count() == 1) ? i18n("Name: %1\n", m_items.first()) : QString(""); msg = fileName + i18n("Total occupied space: %1", KIO::convertSize(totalSize)); if (totalSize >= 1024) msg += i18np(" (%1 byte)", " (%1 bytes)", KRpermHandler::parseSize(totalSize)); msg += '\n'; msg += i18np("in %1 folder", "in %1 folders", totalDirs); msg += ' '; msg += i18np("and %1 file", "and %1 files", totalFiles); m_label->setText(msg); } void KrCalcSpaceDialog::slotCancel() { m_thread->stop(); // notify the thread to stop m_canceled = true; // set the cancel flag reject(); // close the dialog } KrCalcSpaceDialog::~KrCalcSpaceDialog() { if(m_thread->isFinished()) delete m_thread; else { m_thread->stop(); connect(m_thread, SIGNAL(finished()), m_thread, SLOT(deleteLater())); } } int KrCalcSpaceDialog::exec() { m_thread->start(); // start the thread if (m_autoClose) { // autoclose // set the cursor to busy mode and wait 1 second or until the thread finishes krMainWindow->setCursor(Qt::WaitCursor); m_thread->wait(1000); krMainWindow->setCursor(Qt::ArrowCursor); // return the cursor to normal mode m_thread->updateItems(m_view); if(m_thread->isFinished()) return -1; // thread finished: do not show the dialog showResult(); // fill the invisible dialog with useful data } // prepare and start the poll timer connect(m_pollTimer, SIGNAL(timeout()), this, SLOT(timer())); m_pollTimer->start(100); return QDialog::exec(); // show the dialog } /* --=={ End of patch by Heiner }==-- */ diff --git a/krusader/Panel/krcalcspacedialog.h b/krusader/Panel/krcalcspacedialog.h index 1b4ded71..099d04db 100644 --- a/krusader/Panel/krcalcspacedialog.h +++ b/krusader/Panel/krcalcspacedialog.h @@ -1,121 +1,121 @@ /*************************************************************************** krcalcspacedialog.h - description ------------------- begin : Fri Jan 2 2004 copyright : (C) 2004 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KRCALCSPACEDIALOG_H #define KRCALCSPACEDIALOG_H /* --=={ Patch by Heiner }==-- */ // QtCore #include #include // QtWidgets #include #include -#include "../VFS/vfs.h" +#include "../FileSystem/filesystem.h" class KrPanel; class KrView; /** * Dialog calculating showing the number of files and directories and its total * size in a dialog. If wanted, the dialog appears after 3 seconds of * calculation, to avoid a short appearance if the result was found quickly. * Computes the result in a different thread. */ class KrCalcSpaceDialog : public QDialog { Q_OBJECT friend class CalcThread; class QTimer * m_pollTimer; class CalcThread : public QThread { KIO::filesize_t m_totalSize; KIO::filesize_t m_currentSize; unsigned long m_totalFiles; unsigned long m_totalDirs; const QStringList m_items; QHash m_sizes; QUrl m_url; mutable QMutex m_mutex; bool m_stop; public: CalcThread(QUrl url, const QStringList & items); KIO::filesize_t getItemSize(QString item) const; void updateItems(KrView *view) const; void getStats(KIO::filesize_t &totalSize, unsigned long &totalFiles, unsigned long &totalDirs) const; void run(); // start calculation - void stop(); // stop it. Thread continues until vfs_calcSpace returns + void stop(); // stop it. Thread continues until filesystem_calcSpace returns } * m_thread; QLabel *m_label; QPushButton *okButton; QPushButton *cancelButton; bool m_autoClose; // true: wait 3 sec. before showing the dialog. Close it, when done bool m_canceled; // true: cancel was pressed int m_timerCounter; // internal counter. The timer runs faster as the rehresh (see comment there) const QStringList m_items; KrView *m_view; void calculationFinished(); // called if the calculation is done void showResult(); // show the current result in teh dialog protected slots: void timer(); // poll timer was fired void slotCancel(); // cancel was pressed public: // autoclose: wait 3 sec. before showing the dialog. Close it, when done KrCalcSpaceDialog(QWidget *parent, KrPanel * panel, const QStringList & items, bool autoclose); ~KrCalcSpaceDialog(); void getStats(KIO::filesize_t &totalSize, unsigned long &totalFiles, unsigned long &totalDirs) const { m_thread->getStats(totalSize, totalFiles, totalDirs); } bool wasCanceled() const { return m_canceled; } // cancel was pressed; result is probably wrong public slots: int exec() Q_DECL_OVERRIDE; // start calculation }; /* End of patch by Heiner */ #endif diff --git a/krusader/Panel/krinterbriefview.cpp b/krusader/Panel/krinterbriefview.cpp index 28c88b9d..0dc1098a 100644 --- a/krusader/Panel/krinterbriefview.cpp +++ b/krusader/Panel/krinterbriefview.cpp @@ -1,714 +1,714 @@ /***************************************************************************** * Copyright (C) 2009 Csaba Karai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "krinterbriefview.h" // QtCore #include #include #include #include // QtGui #include #include #include // QtWidgets #include #include #include #include #include #include #include #include "krviewfactory.h" #include "krviewitemdelegate.h" #include "krviewitem.h" #include "krvfsmodel.h" #include "krmousehandler.h" #include "krcolorcache.h" -#include "../VFS/krpermhandler.h" +#include "../FileSystem/krpermhandler.h" #include "../defaults.h" #include "../GUI/krstyleproxy.h" KrInterBriefView::KrInterBriefView(QWidget *parent, KrViewInstance &instance, KConfig *cfg) : QAbstractItemView(parent), KrInterView(instance, cfg, this), _header(0) { setWidget(this); setModel(_model); setSelectionMode(QAbstractItemView::NoSelection); setSelectionModel(new DummySelectionModel(_model, this)); KConfigGroup grpSvr(_config, "Look&Feel"); _viewFont = grpSvr.readEntry("Filelist Font", _FilelistFont); setStyle(new KrStyleProxy()); setItemDelegate(new KrViewItemDelegate()); setMouseTracking(true); setAcceptDrops(true); setDropIndicatorShown(true); connect(_mouseHandler, SIGNAL(renameCurrentItem()), SLOT(renameCurrentItem())); _model->setExtensionEnabled(false); _model->setAlternatingTable(true); connect(_model, SIGNAL(layoutChanged()), SLOT(updateGeometries())); } KrInterBriefView::~KrInterBriefView() { delete _properties; _properties = 0; delete _operator; _operator = 0; } void KrInterBriefView::doRestoreSettings(KConfigGroup group) { _properties->numberOfColumns = group.readEntry("Number Of Brief Columns", _NumberOfBriefColumns); if (_properties->numberOfColumns < 1) _properties->numberOfColumns = 1; else if (_properties->numberOfColumns > MAX_BRIEF_COLS) _properties->numberOfColumns = MAX_BRIEF_COLS; _numOfColumns = _properties->numberOfColumns; KrInterView::doRestoreSettings(group); updateGeometries(); } void KrInterBriefView::saveSettings(KConfigGroup grp, KrViewProperties::PropertyType properties) { KrInterView::saveSettings(grp, properties); if(properties & KrViewProperties::PropColumns) grp.writeEntry("Number Of Brief Columns", _numOfColumns); } int KrInterBriefView::itemsPerPage() { int height = getItemHeight(); if (height == 0) height ++; int numRows = viewport()->height() / height; return numRows; } void KrInterBriefView::updateView() { } void KrInterBriefView::setup() { _header = new QHeaderView(Qt::Horizontal, this); _header->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter); _header->setParent(this); _header->setModel(_model); _header->hideSection(KrViewProperties::Type); _header->hideSection(KrViewProperties::Permissions); _header->hideSection(KrViewProperties::KrPermissions); _header->hideSection(KrViewProperties::Owner); _header->hideSection(KrViewProperties::Group); _header->setStretchLastSection(true); _header->setSectionResizeMode(QHeaderView::Fixed); _header->setSectionsClickable(true); _header->setSortIndicatorShown(true); connect(_header, SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), _model, SLOT(sort(int, Qt::SortOrder))); _header->installEventFilter(this); _numOfColumns = _properties->numberOfColumns; setSortMode(_properties->sortColumn, (_properties->sortOptions & KrViewProperties::Descending)); } void KrInterBriefView::keyPressEvent(QKeyEvent *e) { if (!e || !_model->ready()) return ; // subclass bug if (handleKeyEvent(e)) return; QAbstractItemView::keyPressEvent(e); } bool KrInterBriefView::handleKeyEvent(QKeyEvent *e) { if ((e->key() != Qt::Key_Left && e->key() != Qt::Key_Right) && (KrView::handleKeyEvent(e))) // did the view class handled the event? return true; switch (e->key()) { case Qt::Key_Right : { if (e->modifiers() == Qt::ControlModifier) { // let the panel handle it e->ignore(); break; } KrViewItem *i = getCurrentKrViewItem(); KrViewItem *newCurrent = i; if (!i) break; int num = itemsPerPage() + 1; if (e->modifiers() & Qt::ShiftModifier) i->setSelected(!i->isSelected()); while (i && num > 0) { if (e->modifiers() & Qt::ShiftModifier) i->setSelected(!i->isSelected()); newCurrent = i; i = getNext(i); num--; } if (newCurrent) { setCurrentKrViewItem(newCurrent); makeCurrentVisible(); } if (e->modifiers() & Qt::ShiftModifier) op()->emitSelectionChanged(); return true; } case Qt::Key_Left : { if (e->modifiers() == Qt::ControlModifier) { // let the panel handle it e->ignore(); break; } KrViewItem *i = getCurrentKrViewItem(); KrViewItem *newCurrent = i; if (!i) break; int num = itemsPerPage() + 1; if (e->modifiers() & Qt::ShiftModifier) i->setSelected(!i->isSelected()); while (i && num > 0) { if (e->modifiers() & Qt::ShiftModifier) i->setSelected(!i->isSelected()); newCurrent = i; i = getPrev(i); num--; } if (newCurrent) { setCurrentKrViewItem(newCurrent); makeCurrentVisible(); } if (e->modifiers() & Qt::ShiftModifier) op()->emitSelectionChanged(); return true; } } return false; } void KrInterBriefView::wheelEvent(QWheelEvent *ev) { if (!_mouseHandler->wheelEvent(ev)) QApplication::sendEvent(horizontalScrollBar(), ev); } bool KrInterBriefView::eventFilter(QObject *object, QEvent *event) { if (object == _header) { if (event->type() == QEvent::ContextMenu) { QContextMenuEvent *me = (QContextMenuEvent *)event; showContextMenu(me->globalPos()); return true; } } return false; } void KrInterBriefView::showContextMenu(const QPoint & p) { QMenu popup(this); popup.setTitle(i18n("Columns")); int COL_ID = 14700; for (int i = 1; i <= MAX_BRIEF_COLS; i++) { QAction *act = popup.addAction(QString("%1").arg(i)); act->setData(QVariant(COL_ID + i)); act->setCheckable(true); act->setChecked(properties()->numberOfColumns == i); } QAction * res = popup.exec(p); int result = -1; if (res && res->data().canConvert()) result = res->data().toInt(); if (result > COL_ID && result <= COL_ID + MAX_BRIEF_COLS) { _properties->numberOfColumns = result - COL_ID; _numOfColumns = _properties->numberOfColumns; updateGeometries(); op()->settingsChanged(KrViewProperties::PropColumns); } } QRect KrInterBriefView::visualRect(const QModelIndex&ndx) const { int width = (viewport()->width()) / _numOfColumns; if ((viewport()->width()) % _numOfColumns) width++; int height = getItemHeight(); int numRows = viewport()->height() / height; if (numRows == 0) numRows++; int x = width * (ndx.row() / numRows); int y = height * (ndx.row() % numRows); return mapToViewport(QRect(x, y, width, height)); } void KrInterBriefView::scrollTo(const QModelIndex &ndx, QAbstractItemView::ScrollHint hint) { const QRect rect = visualRect(ndx); if (hint == EnsureVisible && viewport()->rect().contains(rect)) { setDirtyRegion(rect); return; } const QRect area = viewport()->rect(); const bool leftOf = rect.left() < area.left(); const bool rightOf = rect.right() > area.right(); int horizontalValue = horizontalScrollBar()->value(); if (leftOf) horizontalValue -= area.left() - rect.left(); else if (rightOf) horizontalValue += rect.right() - area.right(); horizontalScrollBar()->setValue(horizontalValue); } QModelIndex KrInterBriefView::indexAt(const QPoint& p) const { int x = p.x() + horizontalOffset(); int y = p.y() + verticalOffset(); int itemWidth = (viewport()->width()) / _numOfColumns; if ((viewport()->width()) % _numOfColumns) itemWidth++; int itemHeight = getItemHeight(); int numRows = viewport()->height() / itemHeight; if (numRows == 0) numRows++; int row = y / itemHeight; int col = x / itemWidth; int numColsTotal = _model->rowCount() / numRows; if(_model->rowCount() % numRows) numColsTotal++; if(row < numRows && col < numColsTotal) return _model->index((col * numRows) + row, 0); return QModelIndex(); } QModelIndex KrInterBriefView::moveCursor(QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers) { if (_model->rowCount() == 0) return QModelIndex(); QModelIndex current = currentIndex(); if (!current.isValid()) return _model->index(0, 0); switch (cursorAction) { case MoveLeft: case MovePageDown: { int newRow = current.row() - itemsPerPage(); if (newRow < 0) newRow = 0; return _model->index(newRow, 0); } case MoveRight: case MovePageUp: { int newRow = current.row() + itemsPerPage(); if (newRow >= _model->rowCount()) newRow = _model->rowCount() - 1; return _model->index(newRow, 0); } case MovePrevious: case MoveUp: { int newRow = current.row() - 1; if (newRow < 0) newRow = 0; return _model->index(newRow, 0); } case MoveNext: case MoveDown: { int newRow = current.row() + 1; if (newRow >= _model->rowCount()) newRow = _model->rowCount() - 1; return _model->index(newRow, 0); } case MoveHome: return _model->index(0, 0); case MoveEnd: return _model->index(_model->rowCount() - 1, 0); } return current; } int KrInterBriefView::horizontalOffset() const { return horizontalScrollBar()->value(); } int KrInterBriefView::verticalOffset() const { return 0; } bool KrInterBriefView::isIndexHidden(const QModelIndex&ndx) const { return ndx.column() != 0; } #if 0 QRegion KrInterBriefView::visualRegionForSelection(const QItemSelection &selection) const { if (selection.isEmpty()) return QRegion(); QRegion selectionRegion; for (int i = 0; i < selection.count(); ++i) { QItemSelectionRange range = selection.at(i); if (!range.isValid()) continue; QModelIndex leftIndex = range.topLeft(); if (!leftIndex.isValid()) continue; const QRect leftRect = visualRect(leftIndex); int top = leftRect.top(); QModelIndex rightIndex = range.bottomRight(); if (!rightIndex.isValid()) continue; const QRect rightRect = visualRect(rightIndex); int bottom = rightRect.bottom(); if (top > bottom) qSwap(top, bottom); int height = bottom - top + 1; QRect combined = leftRect | rightRect; combined.setX(range.left()); selectionRegion += combined; } return selectionRegion; } #endif void KrInterBriefView::paintEvent(QPaintEvent *e) { QStyleOptionViewItem option = viewOptions(); option.widget = this; option.decorationSize = QSize(_fileIconSize, _fileIconSize); option.decorationPosition = QStyleOptionViewItem::Left; QPainter painter(viewport()); QModelIndex curr = currentIndex(); QVector intersectVector; QRect area = e->rect(); area.adjust(horizontalOffset(), verticalOffset(), horizontalOffset(), verticalOffset()); intersectionSet(area, intersectVector); foreach(const QModelIndex &mndx, intersectVector) { option.state = QStyle::State_None; option.rect = visualRect(mndx); painter.save(); itemDelegate()->paint(&painter, option, mndx); // (always) draw dashed line border around current item row const bool isCurrent = curr.isValid() && curr.row() == mndx.row(); if (isCurrent) { QStyleOptionFocusRect o; o.QStyleOption::operator=(option); QPalette::ColorGroup cg = QPalette::Normal; o.backgroundColor = option.palette.color(cg, QPalette::Background); style()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, &painter); } painter.restore(); } } int KrInterBriefView::getItemHeight() const { int textHeight = QFontMetrics(_viewFont).height(); int height = textHeight; int iconSize = 0; if (properties()->displayIcons) iconSize = _fileIconSize; if (iconSize > textHeight) height = iconSize; if (height == 0) height++; return height; } void KrInterBriefView::updateGeometries() { if (_header) { QSize hint = _header->sizeHint(); setViewportMargins(0, hint.height(), 0, 0); QRect vg = viewport()->geometry(); QRect geometryRect(vg.left(), vg.top() - hint.height(), vg.width(), hint.height()); _header->setGeometry(geometryRect); int items = 0; for (int i = 0; i != _header->count(); i++) if (!_header->isSectionHidden(i)) items++; if (items == 0) items++; int sectWidth = viewport()->width() / items; for (int i = 0; i != _header->count(); i++) if (!_header->isSectionHidden(i)) _header->resizeSection(i, sectWidth); QMetaObject::invokeMethod(_header, "updateGeometries"); } if (_model->rowCount() <= 0) horizontalScrollBar()->setRange(0, 0); else { int itemsPerColumn = viewport()->height() / getItemHeight(); if (itemsPerColumn <= 0) itemsPerColumn = 1; int columnWidth = (viewport()->width()) / _numOfColumns; if ((viewport()->width()) % _numOfColumns) columnWidth++; int maxWidth = _model->rowCount() / itemsPerColumn; if (_model->rowCount() % itemsPerColumn) maxWidth++; maxWidth *= columnWidth; if (maxWidth > viewport()->width()) { horizontalScrollBar()->setSingleStep(columnWidth); horizontalScrollBar()->setPageStep(columnWidth * _numOfColumns); horizontalScrollBar()->setRange(0, maxWidth - viewport()->width()); } else { horizontalScrollBar()->setRange(0, 0); } } QAbstractItemView::updateGeometries(); } void KrInterBriefView::setSortMode(KrViewProperties::ColumnType sortColumn, bool descending) { Qt::SortOrder sortDir = descending ? Qt::DescendingOrder : Qt::AscendingOrder; _header->setSortIndicator(sortColumn, sortDir); } int KrInterBriefView::elementWidth(const QModelIndex & index) { QString text = index.data(Qt::DisplayRole).toString(); int textWidth = QFontMetrics(_viewFont).width(text); const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; textWidth += 2 * textMargin; QVariant decor = index.data(Qt::DecorationRole); if (decor.isValid() && decor.type() == QVariant::Pixmap) { QPixmap p = decor.value(); textWidth += p.width() + 2 * textMargin; } return textWidth; } void KrInterBriefView::intersectionSet(const QRect &rect, QVector &ndxList) { int maxNdx = _model->rowCount(); int width = (viewport()->width()) / _numOfColumns; if ((viewport()->width()) % _numOfColumns) width++; int height = getItemHeight(); int items = viewport()->height() / height; if (items == 0) items++; int xmin = -1; int ymin = -1; int xmax = -1; int ymax = -1; xmin = rect.x() / width; ymin = rect.y() / height; xmax = (rect.x() + rect.width()) / width; if ((rect.x() + rect.width()) % width) xmax++; ymax = (rect.y() + rect.height()) / height; if ((rect.y() + rect.height()) % height) ymax++; for (int i = ymin; i < ymax; i++) for (int j = xmin; j < xmax; j++) { int ndx = j * items + i; if (ndx < maxNdx) ndxList.append(_model->index(ndx, 0)); } } -QRect KrInterBriefView::itemRect(const vfile *vf) +QRect KrInterBriefView::itemRect(const FileItem *item) { - return visualRect(_model->vfileIndex(vf)); + return visualRect(_model->fileItemIndex(item)); } void KrInterBriefView::copySettingsFrom(KrView *other) { if(other->instance() == instance()) { // the other view is of the same type KrInterBriefView *v = static_cast(other); int column = v->_model->lastSortOrder(); Qt::SortOrder sortDir = v->_model->lastSortDir(); _header->setSortIndicator(column, sortDir); _model->sort(column, sortDir); setFileIconSize(v->fileIconSize()); } } void KrInterBriefView::setFileIconSize(int size) { KrView::setFileIconSize(size); setIconSize(QSize(fileIconSize(), fileIconSize())); updateGeometries(); } void KrInterBriefView::currentChanged(const QModelIndex & current, const QModelIndex & previous) { if (_model->ready()) { KrViewItem * item = getKrViewItem(currentIndex()); op()->emitCurrentChanged(item); } QAbstractItemView::currentChanged(current, previous); } void KrInterBriefView::renameCurrentItem() { QModelIndex cIndex = currentIndex(); QModelIndex nameIndex = _model->index(cIndex.row(), KrViewProperties::Name); edit(nameIndex); updateEditorData(); update(nameIndex); } bool KrInterBriefView::event(QEvent * e) { _mouseHandler->otherEvent(e); return QAbstractItemView::event(e); } void KrInterBriefView::mousePressEvent(QMouseEvent * ev) { if (!_mouseHandler->mousePressEvent(ev)) QAbstractItemView::mousePressEvent(ev); } void KrInterBriefView::mouseReleaseEvent(QMouseEvent * ev) { if (!_mouseHandler->mouseReleaseEvent(ev)) QAbstractItemView::mouseReleaseEvent(ev); } void KrInterBriefView::mouseDoubleClickEvent(QMouseEvent *ev) { if (!_mouseHandler->mouseDoubleClickEvent(ev)) QAbstractItemView::mouseDoubleClickEvent(ev); } void KrInterBriefView::mouseMoveEvent(QMouseEvent * ev) { if (!_mouseHandler->mouseMoveEvent(ev)) QAbstractItemView::mouseMoveEvent(ev); } void KrInterBriefView::dragEnterEvent(QDragEnterEvent *ev) { if (!_mouseHandler->dragEnterEvent(ev)) QAbstractItemView::dragEnterEvent(ev); } void KrInterBriefView::dragMoveEvent(QDragMoveEvent *ev) { QAbstractItemView::dragMoveEvent(ev); _mouseHandler->dragMoveEvent(ev); } void KrInterBriefView::dragLeaveEvent(QDragLeaveEvent *ev) { if (!_mouseHandler->dragLeaveEvent(ev)) QAbstractItemView::dragLeaveEvent(ev); } void KrInterBriefView::dropEvent(QDropEvent *ev) { if (!_mouseHandler->dropEvent(ev)) QAbstractItemView::dropEvent(ev); } bool KrInterBriefView::viewportEvent(QEvent * event) { if (event->type() == QEvent::ToolTip) { QHelpEvent *he = static_cast(event); const QModelIndex index = indexAt(he->pos()); if (index.isValid()) { int width = visualRect(index).width(); int textWidth = elementWidth(index); if (textWidth <= width) { event->accept(); return true; } } } return QAbstractItemView::viewportEvent(event); } QRect KrInterBriefView::mapToViewport(const QRect &rect) const { if (!rect.isValid()) return rect; QRect result = rect; int dx = -horizontalOffset(); int dy = -verticalOffset(); result.adjust(dx, dy, dx, dy); return result; } diff --git a/krusader/Panel/krinterbriefview.h b/krusader/Panel/krinterbriefview.h index f74070f0..0e96e98f 100644 --- a/krusader/Panel/krinterbriefview.h +++ b/krusader/Panel/krinterbriefview.h @@ -1,120 +1,120 @@ /***************************************************************************** * Copyright (C) 2009 Csaba Karai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #ifndef KRINTERBRIEFVIEW_H #define KRINTERBRIEFVIEW_H // QtCore #include // QtGui #include // QtWidgets #include #include #include #include "krinterview.h" /** * @brief Compact view showing only icon and file name of view items */ class KrInterBriefView : public QAbstractItemView, public KrInterView { Q_OBJECT public: KrInterBriefView(QWidget *parent, KrViewInstance &instance, KConfig *cfg); virtual ~KrInterBriefView(); // ---- reimplemented from QAbstractItemView ---- QRect visualRect(const QModelIndex&) const Q_DECL_OVERRIDE; QModelIndex indexAt(const QPoint&) const Q_DECL_OVERRIDE; void scrollTo(const QModelIndex &, QAbstractItemView::ScrollHint = QAbstractItemView::EnsureVisible) Q_DECL_OVERRIDE; // ---- reimplemented from KrView ---- int itemsPerPage() Q_DECL_OVERRIDE; void updateView() Q_DECL_OVERRIDE; bool ensureVisibilityAfterSelect() Q_DECL_OVERRIDE { return false; } void setSortMode(KrViewProperties::ColumnType sortColumn, bool descending) Q_DECL_OVERRIDE; // ---- reimplemented from QAbstractItemView ---- // Don't do anything, selections are handled by the mouse handler void setSelection(const QRect &, QItemSelectionModel::SelectionFlags) Q_DECL_OVERRIDE {} void selectAll() Q_DECL_OVERRIDE {} // this shouldn't be called QRegion visualRegionForSelection(const QItemSelection&) const Q_DECL_OVERRIDE { return QRegion(); } // ---- reimplemented from KrView ---- void setFileIconSize(int size) Q_DECL_OVERRIDE; protected slots: // ---- reimplemented from QAbstractItemView ---- void updateGeometries() Q_DECL_OVERRIDE; // ---- reimplemented from KrView ---- void currentChanged(const QModelIndex & current, const QModelIndex & previous) Q_DECL_OVERRIDE; void renameCurrentItem() Q_DECL_OVERRIDE; protected: // ---- reimplemented from KrView ---- bool handleKeyEvent(QKeyEvent *e) Q_DECL_OVERRIDE; // ---- reimplemented from QAbstractItemView ---- bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE; void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; void paintEvent(QPaintEvent *e) Q_DECL_OVERRIDE; QModelIndex moveCursor(QAbstractItemView::CursorAction, Qt::KeyboardModifiers) Q_DECL_OVERRIDE; int horizontalOffset() const Q_DECL_OVERRIDE; int verticalOffset() const Q_DECL_OVERRIDE; bool isIndexHidden(const QModelIndex&) const Q_DECL_OVERRIDE; // QRegion visualRegionForSelection(const QItemSelection&) const Q_DECL_OVERRIDE; bool event(QEvent * e) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE; void mouseDoubleClickEvent(QMouseEvent *ev) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *) Q_DECL_OVERRIDE; void wheelEvent(QWheelEvent *) Q_DECL_OVERRIDE; void dragEnterEvent(QDragEnterEvent *e) Q_DECL_OVERRIDE; void dragMoveEvent(QDragMoveEvent *e) Q_DECL_OVERRIDE; void dragLeaveEvent(QDragLeaveEvent *e) Q_DECL_OVERRIDE; void dropEvent(QDropEvent *) Q_DECL_OVERRIDE; bool viewportEvent(QEvent * event) Q_DECL_OVERRIDE; // ---- reimplemented from KrView ---- void setup() Q_DECL_OVERRIDE; void doRestoreSettings(KConfigGroup group) Q_DECL_OVERRIDE; void saveSettings(KConfigGroup grp, KrViewProperties::PropertyType properties) Q_DECL_OVERRIDE; void copySettingsFrom(KrView *other) Q_DECL_OVERRIDE; - QRect itemRect(const vfile *vf) Q_DECL_OVERRIDE; + QRect itemRect(const FileItem *fileitem) Q_DECL_OVERRIDE; void showContextMenu(const QPoint & p) Q_DECL_OVERRIDE; QRect mapToViewport(const QRect &rect) const; int getItemHeight() const; int elementWidth(const QModelIndex & index); void intersectionSet(const QRect &, QVector &); private: QFont _viewFont; int _numOfColumns; QHeaderView * _header; }; #endif // KRINTERBRIEFVIEW_H diff --git a/krusader/Panel/krinterdetailedview.cpp b/krusader/Panel/krinterdetailedview.cpp index 2704d067..8fddc991 100644 --- a/krusader/Panel/krinterdetailedview.cpp +++ b/krusader/Panel/krinterdetailedview.cpp @@ -1,423 +1,423 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "krinterdetailedview.h" // QtCore #include #include // QtWidgets #include #include #include #include #include #include #include #include "krviewfactory.h" #include "krviewitemdelegate.h" #include "krviewitem.h" #include "krvfsmodel.h" -#include "../VFS/krpermhandler.h" +#include "../FileSystem/krpermhandler.h" #include "../defaults.h" #include "../krglobal.h" #include "krmousehandler.h" #include "krcolorcache.h" #include "../GUI/krstyleproxy.h" KrInterDetailedView::KrInterDetailedView(QWidget *parent, KrViewInstance &instance, KConfig *cfg): QTreeView(parent), KrInterView(instance, cfg, this), _autoResizeColumns(true) { connect(_mouseHandler, SIGNAL(renameCurrentItem()), this, SLOT(renameCurrentItem())); setWidget(this); KConfigGroup group(krConfig, "Private"); KConfigGroup grpSvr(_config, "Look&Feel"); _viewFont = grpSvr.readEntry("Filelist Font", _FilelistFont); this->setModel(_model); this->setRootIsDecorated(false); setSelectionModel(new DummySelectionModel(_model, this)); header()->installEventFilter(this); setSelectionMode(QAbstractItemView::NoSelection); setAllColumnsShowFocus(true); setUniformRowHeights(true); KrStyleProxy *krstyle = new KrStyleProxy(); krstyle->setParent(this); setStyle(krstyle); setItemDelegate(new KrViewItemDelegate(this)); setMouseTracking(true); setAcceptDrops(true); setDropIndicatorShown(true); header()->setSectionResizeMode(QHeaderView::Interactive); header()->setStretchLastSection(false); connect(header(), SIGNAL(sectionResized(int, int, int)), this, SLOT(sectionResized(int, int, int))); connect(header(), SIGNAL(sectionMoved(int, int, int)), this, SLOT(sectionMoved(int, int, int))); } KrInterDetailedView::~KrInterDetailedView() { delete _properties; _properties = 0; delete _operator; _operator = 0; } void KrInterDetailedView::currentChanged(const QModelIndex & current, const QModelIndex & previous) { if (_model->ready()) { KrViewItem * item = getKrViewItem(currentIndex()); op()->emitCurrentChanged(item); } QTreeView::currentChanged(current, previous); } void KrInterDetailedView::doRestoreSettings(KConfigGroup grp) { _autoResizeColumns = grp.readEntry("AutoResizeColumns", true); QByteArray savedState = grp.readEntry("Saved State", QByteArray()); if (savedState.isEmpty()) { hideColumn(KrViewProperties::Type); hideColumn(KrViewProperties::Permissions); hideColumn(KrViewProperties::Owner); hideColumn(KrViewProperties::Group); header()->resizeSection(KrViewProperties::Ext, QFontMetrics(_viewFont).width("tar.bz2 ")); header()->resizeSection(KrViewProperties::KrPermissions, QFontMetrics(_viewFont).width("rwx ")); header()->resizeSection(KrViewProperties::Size, QFontMetrics(_viewFont).width("9") * 10); QDateTime tmp(QDate(2099, 12, 29), QTime(23, 59)); QString desc = QLocale().toString(tmp, QLocale::ShortFormat) + " "; header()->resizeSection(KrViewProperties::Modified, QFontMetrics(_viewFont).width(desc)); } else { header()->restoreState(savedState); _model->setExtensionEnabled(!isColumnHidden(KrViewProperties::Ext)); } KrInterView::doRestoreSettings(grp); } void KrInterDetailedView::saveSettings(KConfigGroup grp, KrViewProperties::PropertyType properties) { KrInterView::saveSettings(grp, properties); grp.writeEntry("AutoResizeColumns", _autoResizeColumns); if(properties & KrViewProperties::PropColumns) { QByteArray state = header()->saveState(); grp.writeEntry("Saved State", state); } } int KrInterDetailedView::itemsPerPage() { QRect rect = visualRect(currentIndex()); if (!rect.isValid()) { for (int i = 0; i != _model->rowCount(); i++) { rect = visualRect(_model->index(i, 0)); if (rect.isValid()) break; } } if (!rect.isValid()) return 0; int size = (height() - header()->height()) / rect.height(); if (size < 0) size = 0; return size; } void KrInterDetailedView::updateView() { } void KrInterDetailedView::setup() { setSortMode(_properties->sortColumn, (_properties->sortOptions & KrViewProperties::Descending)); setSortingEnabled(true); } void KrInterDetailedView::keyPressEvent(QKeyEvent *e) { if (!e || !_model->ready()) return ; // subclass bug if (handleKeyEvent(e)) // did the view class handled the event? return; QTreeView::keyPressEvent(e); } void KrInterDetailedView::mousePressEvent(QMouseEvent * ev) { if (!_mouseHandler->mousePressEvent(ev)) QTreeView::mousePressEvent(ev); } void KrInterDetailedView::mouseReleaseEvent(QMouseEvent * ev) { if (!_mouseHandler->mouseReleaseEvent(ev)) QTreeView::mouseReleaseEvent(ev); } void KrInterDetailedView::mouseDoubleClickEvent(QMouseEvent *ev) { if (!_mouseHandler->mouseDoubleClickEvent(ev)) QTreeView::mouseDoubleClickEvent(ev); } void KrInterDetailedView::mouseMoveEvent(QMouseEvent * ev) { if (!_mouseHandler->mouseMoveEvent(ev)) QTreeView::mouseMoveEvent(ev); } void KrInterDetailedView::wheelEvent(QWheelEvent *ev) { if (!_mouseHandler->wheelEvent(ev)) QTreeView::wheelEvent(ev); } void KrInterDetailedView::dragEnterEvent(QDragEnterEvent *ev) { if (!_mouseHandler->dragEnterEvent(ev)) QTreeView::dragEnterEvent(ev); } void KrInterDetailedView::dragMoveEvent(QDragMoveEvent *ev) { QTreeView::dragMoveEvent(ev); _mouseHandler->dragMoveEvent(ev); } void KrInterDetailedView::dragLeaveEvent(QDragLeaveEvent *ev) { if (!_mouseHandler->dragLeaveEvent(ev)) QTreeView::dragLeaveEvent(ev); } void KrInterDetailedView::dropEvent(QDropEvent *ev) { if (!_mouseHandler->dropEvent(ev)) QTreeView::dropEvent(ev); } bool KrInterDetailedView::event(QEvent * e) { _mouseHandler->otherEvent(e); return QTreeView::event(e); } void KrInterDetailedView::renameCurrentItem() { QModelIndex cIndex = currentIndex(); QModelIndex nameIndex = _model->index(cIndex.row(), KrViewProperties::Name); edit(nameIndex); updateEditorData(); update(nameIndex); } bool KrInterDetailedView::eventFilter(QObject *object, QEvent *event) { if (object == header()) { if (event->type() == QEvent::ContextMenu) { QContextMenuEvent *me = (QContextMenuEvent *)event; showContextMenu(me->globalPos()); return true; } else if (event->type() == QEvent::Resize) { recalculateColumnSizes(); return false; } } return false; } void KrInterDetailedView::showContextMenu(const QPoint & p) { QMenu popup(this); popup.setTitle(i18n("Columns")); QVector actions; for(int i = KrViewProperties::Ext; i < KrViewProperties::MAX_COLUMNS; i++) { QString text = (_model->headerData(i, Qt::Horizontal)).toString(); QAction *act = popup.addAction(text); act->setCheckable(true); act->setChecked(!header()->isSectionHidden(i)); act->setData(i); actions.append(act); } popup.addSeparator(); QAction *actAutoResize = popup.addAction(i18n("Automatically Resize Columns")); actAutoResize->setCheckable(true); actAutoResize->setChecked(_autoResizeColumns); QAction *res = popup.exec(p); if (res == 0) return; if(res == actAutoResize) { _autoResizeColumns = actAutoResize->isChecked(); recalculateColumnSizes(); } else { int column = res->data().toInt(); if(header()->isSectionHidden(column)) header()->showSection(column); else header()->hideSection(column); if(KrViewProperties::Ext == column) _model->setExtensionEnabled(!header()->isSectionHidden(KrViewProperties::Ext)); } op()->settingsChanged(KrViewProperties::PropColumns); } void KrInterDetailedView::sectionResized(int /*column*/, int oldSize, int newSize) { // *** taken from dolphin *** // If the user changes the size of the headers, the autoresize feature should be // turned off. As there is no dedicated interface to find out whether the header // section has been resized by the user or by a resize event, another approach is used. // Attention: Take care when changing the if-condition to verify that there is no // regression in combination with bug 178630 (see fix in comment #8). if ((QApplication::mouseButtons() & Qt::LeftButton) && header()->underMouse()) { _autoResizeColumns = false; op()->settingsChanged(KrViewProperties::PropColumns); } if (oldSize == newSize || !_model->ready()) return; recalculateColumnSizes(); } void KrInterDetailedView::sectionMoved(int /*logicalIndex*/, int /*oldVisualIndex*/, int /*newVisualIndex*/) { op()->settingsChanged(KrViewProperties::PropColumns); } void KrInterDetailedView::recalculateColumnSizes() { if(!_autoResizeColumns) return; int sum = 0; for (int i = 0; i != _model->columnCount(); i++) { if (!isColumnHidden(i)) sum += header()->sectionSize(i); } if (sum != header()->width()) { int delta = sum - header()->width(); int nameSize = header()->sectionSize(KrViewProperties::Name); if (nameSize - delta > 20) header()->resizeSection(KrViewProperties::Name, nameSize - delta); } } bool KrInterDetailedView::viewportEvent(QEvent * event) { if (event->type() == QEvent::ToolTip) { QHelpEvent *he = static_cast(event); const QModelIndex index = indexAt(he->pos()); if (index.isValid()) { int width = header()->sectionSize(index.column()); QString text = index.data(Qt::DisplayRole).toString(); int textWidth = QFontMetrics(_viewFont).width(text); const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; textWidth += 2 * textMargin; QVariant decor = index.data(Qt::DecorationRole); if (decor.isValid() && decor.type() == QVariant::Pixmap) { QPixmap p = decor.value(); textWidth += p.width() + 2 * textMargin; } if (textWidth <= width) { event->accept(); return true; } } } return QTreeView::viewportEvent(event); } void KrInterDetailedView::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const { QTreeView::drawRow(painter, options, index); // (always) draw dashed line border around current item row. This is done internally in // QTreeView::drawRow() only when panel is focused, we have to repeat it here. if (index == currentIndex()) { QStyleOptionFocusRect o; o.backgroundColor = options.palette.color(QPalette::Normal, QPalette::Background); const QRect focusRect(0, options.rect.y(), header()->length(), options.rect.height()); o.rect = style()->visualRect(layoutDirection(), viewport()->rect(), focusRect); style()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter); } } void KrInterDetailedView::setSortMode(KrViewProperties::ColumnType sortColumn, bool descending) { Qt::SortOrder sortDir = descending ? Qt::DescendingOrder : Qt::AscendingOrder; sortByColumn(sortColumn, sortDir); } void KrInterDetailedView::setFileIconSize(int size) { KrView::setFileIconSize(size); setIconSize(QSize(fileIconSize(), fileIconSize())); } -QRect KrInterDetailedView::itemRect(const vfile *vf) +QRect KrInterDetailedView::itemRect(const FileItem *item) { - QRect r = visualRect(_model->vfileIndex(vf)); + QRect r = visualRect(_model->fileItemIndex(item)); r.setLeft(0); r.setWidth(header()->length()); return r; } void KrInterDetailedView::copySettingsFrom(KrView *other) { if(other->instance() == instance()) { // the other view is of the same type KrInterDetailedView *v = static_cast(other); _autoResizeColumns = v->_autoResizeColumns; header()->restoreState(v->header()->saveState()); _model->setExtensionEnabled(!isColumnHidden(KrViewProperties::Ext)); recalculateColumnSizes(); setFileIconSize(v->fileIconSize()); } } diff --git a/krusader/Panel/krinterdetailedview.h b/krusader/Panel/krinterdetailedview.h index 663fa0ef..23556080 100644 --- a/krusader/Panel/krinterdetailedview.h +++ b/krusader/Panel/krinterdetailedview.h @@ -1,94 +1,94 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #ifndef KRINTERDETAILEDVIEW_H #define KRINTERDETAILEDVIEW_H // QtCore #include // QtGui #include // QtWidgets #include #include "krinterview.h" class QMouseEvent; class QKeyEvent; class QDragEnterEvent; class KrInterDetailedView : public QTreeView, public KrInterView { Q_OBJECT public: KrInterDetailedView(QWidget *parent, KrViewInstance &instance, KConfig *cfg); virtual ~KrInterDetailedView(); void updateView() Q_DECL_OVERRIDE; bool ensureVisibilityAfterSelect() Q_DECL_OVERRIDE { return false; } int itemsPerPage() Q_DECL_OVERRIDE; void setSortMode(KrViewProperties::ColumnType sortColumn, bool descending) Q_DECL_OVERRIDE; void setFileIconSize(int size) Q_DECL_OVERRIDE; void doRestoreSettings(KConfigGroup grp) Q_DECL_OVERRIDE; protected slots: void renameCurrentItem() Q_DECL_OVERRIDE; void sectionResized(int, int, int); void sectionMoved(int, int, int); void currentChanged(const QModelIndex & current, const QModelIndex & previous) Q_DECL_OVERRIDE; protected: void setup() Q_DECL_OVERRIDE; void copySettingsFrom(KrView *other) Q_DECL_OVERRIDE; void saveSettings(KConfigGroup grp, KrViewProperties::PropertyType properties) Q_DECL_OVERRIDE; // Don't do anything, selections are handled by the mouse handler void setSelection(const QRect &, QItemSelectionModel::SelectionFlags) Q_DECL_OVERRIDE {} void selectAll() Q_DECL_OVERRIDE {} void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE; void mouseDoubleClickEvent(QMouseEvent *ev) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *) Q_DECL_OVERRIDE; void wheelEvent(QWheelEvent *) Q_DECL_OVERRIDE; bool event(QEvent * e) Q_DECL_OVERRIDE; void dragEnterEvent(QDragEnterEvent *e) Q_DECL_OVERRIDE; void dragMoveEvent(QDragMoveEvent *e) Q_DECL_OVERRIDE; void dragLeaveEvent(QDragLeaveEvent *e) Q_DECL_OVERRIDE; void dropEvent(QDropEvent *) Q_DECL_OVERRIDE; bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE; bool viewportEvent(QEvent * event) Q_DECL_OVERRIDE; void drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const Q_DECL_OVERRIDE; - QRect itemRect(const vfile *vf) Q_DECL_OVERRIDE; + QRect itemRect(const FileItem *fileitem) Q_DECL_OVERRIDE; void showContextMenu(const QPoint & p) Q_DECL_OVERRIDE; void recalculateColumnSizes(); private: QFont _viewFont; bool _autoResizeColumns; }; #endif // __krinterview__ diff --git a/krusader/Panel/krinterview.cpp b/krusader/Panel/krinterview.cpp index d5b46352..bb386362 100644 --- a/krusader/Panel/krinterview.cpp +++ b/krusader/Panel/krinterview.cpp @@ -1,383 +1,383 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * Copyright (C) 2010 Jan Lepper * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "krinterview.h" #include "krcolorcache.h" #include "krmousehandler.h" #include "krpreviews.h" #include "krvfsmodel.h" #include "krviewitem.h" -#include "../VFS/vfilecontainer.h" +#include "../FileSystem/dirlisterinterface.h" KrInterView::KrInterView(KrViewInstance &instance, KConfig *cfg, QAbstractItemView *itemView) : KrView(instance, cfg), _itemView(itemView), _mouseHandler(0) { _model = new KrVfsModel(this); // fix the context menu problem int j = QFontMetrics(_itemView->font()).height() * 2; _mouseHandler = new KrMouseHandler(this, j); } KrInterView::~KrInterView() { // any references to the model should be cleared ar this point, // but sometimes for some reason it is still referenced by // QPersistentModelIndex instances held by QAbstractItemView and/or QItemSelectionModel(child object) - // so schedule _model for later deletion _model->clear(); _model->deleteLater(); _model = 0; delete _mouseHandler; _mouseHandler = 0; - QHashIterator< vfile *, KrViewItem *> it(_itemHash); + QHashIterator< FileItem *, KrViewItem *> it(_itemHash); while (it.hasNext()) delete it.next().value(); _itemHash.clear(); } void KrInterView::selectRegion(KrViewItem *i1, KrViewItem *i2, bool select) { - vfile* vf1 = (vfile *)i1->getVfile(); - QModelIndex mi1 = _model->vfileIndex(vf1); - vfile* vf2 = (vfile *)i2->getVfile(); - QModelIndex mi2 = _model->vfileIndex(vf2); + FileItem* file1 = (FileItem *)i1->getFileItem(); + QModelIndex mi1 = _model->fileItemIndex(file1); + FileItem* file2 = (FileItem *)i2->getFileItem(); + QModelIndex mi2 = _model->fileItemIndex(file2); if (mi1.isValid() && mi2.isValid()) { int r1 = mi1.row(); int r2 = mi2.row(); if (r1 > r2) { int t = r1; r1 = r2; r2 = t; } op()->setMassSelectionUpdate(true); for (int row = r1; row <= r2; row++) - setSelected(_model->vfileAt(_model->index(row, 0)), select); + setSelected(_model->fileItemAt(_model->index(row, 0)), select); op()->setMassSelectionUpdate(false); redraw(); } else if (mi1.isValid() && !mi2.isValid()) i1->setSelected(select); else if (mi2.isValid() && !mi1.isValid()) i2->setSelected(select); } -void KrInterView::intSetSelected(const vfile* vf, bool select) +void KrInterView::intSetSelected(const FileItem* item, bool select) { if(select) - _selection.insert(vf); + _selection.insert(item); else - _selection.remove(vf); + _selection.remove(item); } bool KrInterView::isSelected(const QModelIndex &ndx) { - return isSelected(_model->vfileAt(ndx)); + return isSelected(_model->fileItemAt(ndx)); } KrViewItem* KrInterView::findItemByName(const QString &name) { if (!_model->ready()) return 0; QModelIndex ndx = _model->nameIndex(name); if (!ndx.isValid()) return 0; return getKrViewItem(ndx); } QString KrInterView::getCurrentItem() const { if (!_model->ready()) return QString(); - vfile *vf = _model->vfileAt(_itemView->currentIndex()); - if (vf == 0) + FileItem *fileitem = _model->fileItemAt(_itemView->currentIndex()); + if (fileitem == 0) return QString(); - return vf->vfile_getName(); + return fileitem->getName(); } KrViewItem* KrInterView::getCurrentKrViewItem() { if (!_model->ready()) return 0; return getKrViewItem(_itemView->currentIndex()); } KrViewItem* KrInterView::getFirst() { if (!_model->ready()) return 0; return getKrViewItem(_model->index(0, 0, QModelIndex())); } KrViewItem* KrInterView::getLast() { if (!_model->ready()) return 0; return getKrViewItem(_model->index(_model->rowCount() - 1, 0, QModelIndex())); } KrViewItem* KrInterView::getNext(KrViewItem *current) { - vfile* vf = (vfile *)current->getVfile(); - QModelIndex ndx = _model->vfileIndex(vf); + FileItem* fileItem = (FileItem *)current->getFileItem(); + QModelIndex ndx = _model->fileItemIndex(fileItem); if (ndx.row() >= _model->rowCount() - 1) return 0; return getKrViewItem(_model->index(ndx.row() + 1, 0, QModelIndex())); } KrViewItem* KrInterView::getPrev(KrViewItem *current) { - vfile* vf = (vfile *)current->getVfile(); - QModelIndex ndx = _model->vfileIndex(vf); + FileItem* fileItem = (FileItem *)current->getFileItem(); + QModelIndex ndx = _model->fileItemIndex(fileItem); if (ndx.row() <= 0) return 0; return getKrViewItem(_model->index(ndx.row() - 1, 0, QModelIndex())); } KrViewItem* KrInterView::getKrViewItemAt(const QPoint &vp) { if (!_model->ready()) return 0; return getKrViewItem(_itemView->indexAt(vp)); } -KrViewItem *KrInterView::findItemByVfile(vfile *vf) { - return getKrViewItem(vf); +KrViewItem *KrInterView::findItemByFileItem(FileItem *fileItem) { + return getKrViewItem(fileItem); } -KrViewItem * KrInterView::getKrViewItem(vfile *vf) +KrViewItem * KrInterView::getKrViewItem(FileItem *fileItem) { - QHash::iterator it = _itemHash.find(vf); + QHash::iterator it = _itemHash.find(fileItem); if (it == _itemHash.end()) { - KrViewItem * newItem = new KrViewItem(vf, this); - _itemHash[ vf ] = newItem; + KrViewItem * newItem = new KrViewItem(fileItem, this); + _itemHash[ fileItem ] = newItem; return newItem; } return *it; } KrViewItem * KrInterView::getKrViewItem(const QModelIndex & ndx) { if (!ndx.isValid()) return 0; - vfile * vf = _model->vfileAt(ndx); - if (vf == 0) + FileItem * fileitem = _model->fileItemAt(ndx); + if (fileitem == 0) return 0; else - return getKrViewItem(vf); + return getKrViewItem(fileitem); } void KrInterView::makeCurrentVisible() { _itemView->scrollTo(_itemView->currentIndex()); } void KrInterView::makeItemVisible(const KrViewItem *item) { if (item == 0) return; - vfile* vf = (vfile *)item->getVfile(); - QModelIndex ndx = _model->vfileIndex(vf); + FileItem* fileitem = (FileItem *)item->getFileItem(); + QModelIndex ndx = _model->fileItemIndex(fileitem); if (ndx.isValid()) _itemView->scrollTo(ndx); } bool KrInterView::isItemVisible(const KrViewItem *item) { return _itemView->viewport()->rect().contains(item->itemRect()); } void KrInterView::setCurrentItem(const QString& name, const QModelIndex &fallbackToIndex) { // find index by given name and set it as current QModelIndex ndx = _model->nameIndex(name); if (ndx.isValid()) { // also sets the scrolling position _itemView->setCurrentIndex(ndx); } else if (fallbackToIndex.isValid()) { // set fallback index as current index // when fallback index is too big, set the last item as current if (fallbackToIndex.row() >= _itemView->model()->rowCount()) { setCurrentKrViewItem(getLast()); } else { _itemView->setCurrentIndex(fallbackToIndex); } } else { // when given parameters fail, set the first item as current setCurrentKrViewItem(getFirst()); } } void KrInterView::setCurrentKrViewItem(KrViewItem *item) { if (item == 0) { _itemView->setCurrentIndex(QModelIndex()); return; } - vfile* vf = (vfile *)item->getVfile(); - QModelIndex ndx = _model->vfileIndex(vf); + FileItem* fileitem = (FileItem *)item->getFileItem(); + QModelIndex ndx = _model->fileItemIndex(fileitem); if (ndx.isValid() && ndx.row() != _itemView->currentIndex().row()) { _mouseHandler->cancelTwoClickRename(); _itemView->setCurrentIndex(ndx); } } void KrInterView::sort() { _model->sort(); } void KrInterView::clear() { _selection.clear(); _itemView->clearSelection(); _itemView->setCurrentIndex(QModelIndex()); _model->clear(); - QHashIterator< vfile *, KrViewItem *> it(_itemHash); + QHashIterator< FileItem *, KrViewItem *> it(_itemHash); while (it.hasNext()) delete it.next().value(); _itemHash.clear(); KrView::clear(); } -void KrInterView::populate(const QList &vfiles, vfile *dummy) +void KrInterView::populate(const QList &fileItems, FileItem *dummy) { - _model->populate(vfiles, dummy); + _model->populate(fileItems, dummy); } -KrViewItem* KrInterView::preAddItem(vfile *vf) +KrViewItem* KrInterView::preAddItem(FileItem *fileitem) { - QModelIndex idx = _model->addItem(vf); + QModelIndex idx = _model->addItem(fileitem); if(_model->rowCount() == 1) // if this is the fist item to be added, make it current _itemView->setCurrentIndex(idx); return getKrViewItem(idx); } void KrInterView::preDelItem(KrViewItem *item) { - setSelected(item->getVfile(), false); - QModelIndex ndx = _model->removeItem((vfile *)item->getVfile()); + setSelected(item->getFileItem(), false); + QModelIndex ndx = _model->removeItem((FileItem *)item->getFileItem()); if (ndx.isValid()) _itemView->setCurrentIndex(ndx); - _itemHash.remove((vfile *)item->getVfile()); + _itemHash.remove((FileItem *)item->getFileItem()); } -void KrInterView::preUpdateItem(vfile *vf) +void KrInterView::preUpdateItem(FileItem *fileitem) { - _model->updateItem(vf); + _model->updateItem(fileitem); } void KrInterView::prepareForActive() { _focused = true; _itemView->setFocus(); } void KrInterView::prepareForPassive() { _focused = false; _mouseHandler->cancelTwoClickRename(); //if ( renameLineEdit() ->isVisible() ) //renameLineEdit() ->clearFocus(); } void KrInterView::redraw() { _itemView->viewport()->update(); } void KrInterView::refreshColors() { QPalette p(_itemView->palette()); KrColorGroup cg; KrColorCache::getColorCache().getColors(cg, KrColorItemType(KrColorItemType::File, false, _focused, false, false)); p.setColor(QPalette::Text, cg.text()); p.setColor(QPalette::Base, cg.background()); _itemView->setPalette(p); redraw(); } void KrInterView::showContextMenu(const QPoint &point) { showContextMenu(_itemView->viewport()->mapToGlobal(point)); } void KrInterView::sortModeUpdated(int column, Qt::SortOrder order) { KrView::sortModeUpdated(static_cast(column), order == Qt::DescendingOrder); } KIO::filesize_t KrInterView::calcSize() { KIO::filesize_t size = 0; - foreach(vfile *vf, _model->vfiles()) { - size += vf->vfile_getSize(); + foreach(FileItem *fileitem, _model->fileItems()) { + size += fileitem->getSize(); } return size; } KIO::filesize_t KrInterView::calcSelectedSize() { KIO::filesize_t size = 0; - foreach(const vfile *vf, _selection) { - size += vf->vfile_getSize(); + foreach(const FileItem *fileitem, _selection) { + size += fileitem->getSize(); } return size; } QList KrInterView::selectedUrls() { QList list; - foreach(const vfile *vf, _selection) { - list << vf->vfile_getUrl(); + foreach(const FileItem *fileitem, _selection) { + list << fileitem->getUrl(); } return list; } void KrInterView::setSelectionUrls(const QList urls) { op()->setMassSelectionUpdate(true); _selection.clear(); foreach(const QUrl &url, urls) { const QModelIndex idx = _model->indexFromUrl(url); if(idx.isValid()) - setSelected(_model->vfileAt(idx), true); + setSelected(_model->fileItemAt(idx), true); } op()->setMassSelectionUpdate(false); } diff --git a/krusader/Panel/krinterview.h b/krusader/Panel/krinterview.h index 12b06110..067837d5 100644 --- a/krusader/Panel/krinterview.h +++ b/krusader/Panel/krinterview.h @@ -1,118 +1,118 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * Copyright (C) 2010 Jan Lepper * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #ifndef KRINTERVIEW_H #define KRINTERVIEW_H // QtCore #include // QtWidgets #include #include "krview.h" class KrVfsModel; class KrMouseHandler; class KrViewItem; /** * @brief Abstract intermediate class between KrView and full view implementations. * * It contains the methods common to all implementing subclasses of KrView. */ class KrInterView : public KrView { friend class KrViewItem; public: KrInterView(KrViewInstance &instance, KConfig *cfg, QAbstractItemView *itemView); virtual ~KrInterView(); QModelIndex getCurrentIndex() Q_DECL_OVERRIDE { return _itemView->currentIndex(); } bool isSelected(const QModelIndex &ndx) Q_DECL_OVERRIDE; uint numSelected() const Q_DECL_OVERRIDE { return _selection.count(); } QList selectedUrls() Q_DECL_OVERRIDE; void setSelectionUrls(const QList urls) Q_DECL_OVERRIDE; KrViewItem* getFirst() Q_DECL_OVERRIDE; KrViewItem* getLast() Q_DECL_OVERRIDE; KrViewItem* getNext(KrViewItem *current) Q_DECL_OVERRIDE; KrViewItem* getPrev(KrViewItem *current) Q_DECL_OVERRIDE; KrViewItem* getCurrentKrViewItem() Q_DECL_OVERRIDE; KrViewItem* findItemByName(const QString &name) Q_DECL_OVERRIDE; - KrViewItem *findItemByVfile(vfile *vf) Q_DECL_OVERRIDE; + KrViewItem *findItemByFileItem(FileItem *fileitem) Q_DECL_OVERRIDE; QString getCurrentItem() const Q_DECL_OVERRIDE; KrViewItem* getKrViewItemAt(const QPoint &vp) Q_DECL_OVERRIDE; void setCurrentItem(const QString& name, const QModelIndex &fallbackToIndex=QModelIndex()) Q_DECL_OVERRIDE; void setCurrentKrViewItem(KrViewItem *item) Q_DECL_OVERRIDE; void makeItemVisible(const KrViewItem *item) Q_DECL_OVERRIDE; bool isItemVisible(const KrViewItem *item) Q_DECL_OVERRIDE; void clear() Q_DECL_OVERRIDE; void sort() Q_DECL_OVERRIDE; void refreshColors() Q_DECL_OVERRIDE; void redraw() Q_DECL_OVERRIDE; void prepareForActive() Q_DECL_OVERRIDE; void prepareForPassive() Q_DECL_OVERRIDE; void showContextMenu(const QPoint & point = QPoint(0,0)) Q_DECL_OVERRIDE; void selectRegion(KrViewItem *i1, KrViewItem *i2, bool select) Q_DECL_OVERRIDE; void sortModeUpdated(int column, Qt::SortOrder order); - void redrawItem(vfile *vf) { - _itemView->viewport()->update(itemRect(vf)); + void redrawItem(FileItem *fileitem) { + _itemView->viewport()->update(itemRect(fileitem)); } protected: class DummySelectionModel : public QItemSelectionModel { public: DummySelectionModel(QAbstractItemModel *model, QObject *parent) : QItemSelectionModel(model, parent) {} // do nothing - selection is managed by KrInterView void select(const QModelIndex &, QItemSelectionModel::SelectionFlags) Q_DECL_OVERRIDE {} void select(const QItemSelection &, QItemSelectionModel::SelectionFlags) Q_DECL_OVERRIDE {} }; KIO::filesize_t calcSize() Q_DECL_OVERRIDE; KIO::filesize_t calcSelectedSize() Q_DECL_OVERRIDE; - void populate(const QList &vfiles, vfile *dummy) Q_DECL_OVERRIDE; - KrViewItem* preAddItem(vfile *vf) Q_DECL_OVERRIDE; + void populate(const QList &fileItems, FileItem *dummy) Q_DECL_OVERRIDE; + KrViewItem* preAddItem(FileItem *fileitem) Q_DECL_OVERRIDE; void preDelItem(KrViewItem *item) Q_DECL_OVERRIDE; - void preUpdateItem(vfile *vf) Q_DECL_OVERRIDE; - void intSetSelected(const vfile* vf, bool select) Q_DECL_OVERRIDE; + void preUpdateItem(FileItem *fileitem) Q_DECL_OVERRIDE; + void intSetSelected(const FileItem* fileitem, bool select) Q_DECL_OVERRIDE; - virtual QRect itemRect(const vfile *vf) = 0; + virtual QRect itemRect(const FileItem *fileitem) = 0; - KrViewItem * getKrViewItem(vfile *vf); + KrViewItem * getKrViewItem(FileItem *fileitem); KrViewItem * getKrViewItem(const QModelIndex &); - bool isSelected(const vfile *vf) const { - return _selection.contains(vf); + bool isSelected(const FileItem *fileitem) const { + return _selection.contains(fileitem); } void makeCurrentVisible(); KrVfsModel *_model; QAbstractItemView *_itemView; KrMouseHandler *_mouseHandler; - QHash _itemHash; - QSet _selection; + QHash _itemHash; + QSet _selection; }; #endif diff --git a/krusader/Panel/krpopupmenu.cpp b/krusader/Panel/krpopupmenu.cpp index 47354ef8..c5323d83 100644 --- a/krusader/Panel/krpopupmenu.cpp +++ b/krusader/Panel/krpopupmenu.cpp @@ -1,428 +1,428 @@ /***************************************************************************** * Copyright (C) 2003 Shie Erlich * * Copyright (C) 2003 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "krpopupmenu.h" // QtGui #include #include #include #include #include #include #include #include #include #include #include #include #include "listpanel.h" #include "krview.h" #include "krviewitem.h" #include "panelfunc.h" #include "listpanelactions.h" #include "../krservices.h" #include "../defaults.h" #include "../MountMan/kmountman.h" #include "../krusader.h" #include "../krslots.h" #include "../krusaderview.h" #include "../panelmanager.h" #include "../UserAction/useractionpopupmenu.h" #include "../Archive/krarchandler.h" -#include "../VFS/krtrashhandler.h" +#include "../FileSystem/krtrashhandler.h" void KrPopupMenu::run(const QPoint &pos, KrPanel *panel) { KrPopupMenu menu(panel); QAction * res = menu.exec(pos); int result = -1; if (res && res->data().canConvert()) result = res->data().toInt(); menu.performAction(result); } /** * Copied from dolphin/src/dolphincontextmenu.cpp and modified to add only compress and extract submenus. */ void KrPopupMenu::addCompressAndExtractPluginActions() { KFileItemListProperties props(_items); QVector jsonPlugins = KPluginLoader::findPlugins("kf5/kfileitemaction", [=](const KPluginMetaData& metaData) { return metaData.pluginId() == "compressfileitemaction" || metaData.pluginId() == "extractfileitemaction"; }); foreach (const KPluginMetaData &jsonMetadata, jsonPlugins) { KAbstractFileItemActionPlugin* abstractPlugin = KPluginLoader(jsonMetadata.fileName()) .factory()->create(); if (abstractPlugin) { abstractPlugin->setParent(this); addActions(abstractPlugin->actions(props, this)); } } } KrPopupMenu::KrPopupMenu(KrPanel *thePanel, QWidget *parent) : QMenu(parent), panel(thePanel), empty(false), multipleSelections(false) { // selected file names const QStringList fileNames = panel->gui->getSelectedNames(); - // vfiles - QList files; + // file items + QList files; for (const QString fileName : fileNames) { - files.append(panel->func->files()->getVfile(fileName)); + files.append(panel->func->files()->getFileItem(fileName)); } // KFileItems - for (vfile *file : files) { - _items.append(KFileItem(file->vfile_getUrl(), file->vfile_getMime(), - file->vfile_getMode())); + for (FileItem *file : files) { + _items.append(KFileItem(file->getUrl(), file->getMime(), + file->getMode())); } if (files.empty()) { addCreateNewMenu(); addSeparator(); addEmptyMenuEntries(); return; } else if (files.size() > 1) { multipleSelections = true; } QSet protocols; - for (vfile *file : files) { - protocols.insert(file->vfile_getUrl().scheme()); + for (FileItem *file : files) { + protocols.insert(file->getUrl().scheme()); } const bool inTrash = protocols.contains("trash"); const bool trashOnly = inTrash && protocols.count() == 1; - vfile *file = files.first(); + FileItem *file = files.first(); // ------------ the OPEN/BROWSE option - open preferred service QAction * openAct = addAction(i18n("Open/Run")); openAct->setData(QVariant(OPEN_ID)); if (!multipleSelections) { // meaningful only if one file is selected KrViewItemList viewItems; panel->view->getSelectedKrViewItems(&viewItems); openAct->setIcon(viewItems.first()->icon()); - openAct->setText(file->vfile_isExecutable() && !file->vfile_isDir() ? + openAct->setText(file->isExecutable() && !file->isDir() ? i18n("Run") : i18n("Open")); // open in a new tab (if folder) - if (file->vfile_isDir()) { + if (file->isDir()) { QAction * openTab = addAction(i18n("Open in New Tab")); openTab->setData(QVariant(OPEN_TAB_ID)); openTab->setIcon(krLoader->loadIcon("tab-new", KIconLoader::Panel)); openTab->setText(i18n("Open in New Tab")); } // if the file can be browsed as archive... - if (!panel->func->browsableArchivePath(file->vfile_getName()).isEmpty() + if (!panel->func->browsableArchivePath(file->getName()).isEmpty() // ...but user disabled archive browsing... && (!KConfigGroup(krConfig, "Archives") .readEntry("ArchivesAsDirectories", _ArchivesAsDirectories) // ...or the file is not a standard archive (e.g. odt, docx, etc.)... - || !KRarcHandler::arcSupported(file->vfile_getMime()))) { + || !KRarcHandler::arcSupported(file->getMime()))) { // ...it will not be browsed as a directory by default, but add an option for it QAction *browseAct = addAction(i18n("Browse")); browseAct->setData(QVariant(BROWSE_ID)); browseAct->setIcon(krLoader->loadIcon("", KIconLoader::Panel)); browseAct->setText(i18n("Browse Archive")); } addSeparator(); } - // ------------- Preview - local vfs only ? + // ------------- Preview - local filesystem only ? if (panel->func->files()->isLocal()) { // create the preview popup preview.setUrls(panel->func->files()->getUrls(fileNames)); QAction *pAct = addMenu(&preview); pAct->setData(QVariant(PREVIEW_ID)); pAct->setText(i18n("Preview")); } // -------------- Open with: try to find-out which apps can open the file QSet uniqueMimeTypes; - for (vfile *file : files) - uniqueMimeTypes.insert(file->vfile_getMime()); + for (FileItem *file : files) + uniqueMimeTypes.insert(file->getMime()); const QStringList mimeTypes = uniqueMimeTypes.toList(); offers = mimeTypes.count() == 1 ? KMimeTypeTrader::self()->query(mimeTypes.first()) : KFileItemActions::associatedApplications(mimeTypes, QString()); if (!offers.isEmpty()) { for (int i = 0; i < offers.count(); ++i) { QExplicitlySharedDataPointer service = offers[i]; if (service->isValid() && service->isApplication()) { openWith.addAction(krLoader->loadIcon(service->icon(), KIconLoader::Small), service->name())->setData(QVariant(SERVICE_LIST_ID + i)); } } openWith.addSeparator(); - if (!multipleSelections && file->vfile_isDir()) + if (!multipleSelections && file->isDir()) openWith.addAction(krLoader->loadIcon("utilities-terminal", KIconLoader::Small), i18n("Terminal"))->setData(QVariant(OPEN_TERM_ID)); openWith.addAction(i18n("Other..."))->setData(QVariant(CHOOSE_ID)); QAction *owAct = addMenu(&openWith); owAct->setData(QVariant(OPEN_WITH_ID)); owAct->setText(i18n("Open With")); addSeparator(); } // --------------- user actions - QAction *userAction = new UserActionPopupMenu(file->vfile_getUrl()); + QAction *userAction = new UserActionPopupMenu(file->getUrl()); userAction->setText(i18n("User Actions")); addAction(userAction); // workaround for Bug 372999: application freezes very long time if many files are selected if (_items.length() < 1000) // add compress and extract plugins (if available) addCompressAndExtractPluginActions(); // NOTE: design and usability problem here. Services disabled in kservicemenurc settings won't // be added to the menu. But Krusader does not provide a way do change these settings (only // Dolphin does). fileItemActions.setItemListProperties(KFileItemListProperties(_items)); fileItemActions.addServiceActionsTo(this); addSeparator(); // ------------- 'create new' submenu addCreateNewMenu(); addSeparator(); // ---------- COPY addAction(i18n("Copy..."))->setData(QVariant(COPY_ID)); // ------- MOVE addAction(i18n("Move..."))->setData(QVariant(MOVE_ID)); // ------- RENAME - only one file if (!multipleSelections && !inTrash) addAction(i18n("Rename"))->setData(QVariant(RENAME_ID)); // -------- MOVE TO TRASH if (KConfigGroup(krConfig, "General").readEntry("Move To Trash", _MoveToTrash) && panel->func->files()->canMoveToTrash(fileNames)) addAction(i18n("Move to Trash"))->setData(QVariant(TRASH_ID)); // -------- DELETE addAction(i18n("Delete"))->setData(QVariant(DELETE_ID)); // -------- SHRED - only one file - /* if ( panel->func->files() ->vfs_getType() == vfs::VFS_NORMAL && - !vf->vfile_isDir() && !multipleSelections ) + /* if ( panel->func->files() ->getType() == filesystem:fileSystemM_NORMAL && + !fileitem->isDir() && !multipleSelections ) addAction( i18n( "Shred" ) )->setData( QVariant( SHRED_ID ) );*/ // ---------- link handling // create new shortcut or redirect links - only on local directories: if (panel->func->files()->isLocal()) { addSeparator(); linkPopup.addAction(i18n("New Symlink..."))->setData(QVariant(NEW_SYMLINK_ID)); linkPopup.addAction(i18n("New Hardlink..."))->setData(QVariant(NEW_LINK_ID)); - if (file->vfile_isSymLink()) + if (file->isSymLink()) linkPopup.addAction(i18n("Redirect Link..."))->setData(QVariant(REDIRECT_LINK_ID)); QAction *linkAct = addMenu(&linkPopup); linkAct->setData(QVariant(LINK_HANDLING_ID)); linkAct->setText(i18n("Link Handling")); } addSeparator(); // ---------- calculate space - if (panel->func->files()->isLocal() && (file->vfile_isDir() || multipleSelections)) + if (panel->func->files()->isLocal() && (file->isDir() || multipleSelections)) addAction(panel->gui->actions()->actCalculate); // ---------- mount/umount/eject - if (panel->func->files()->isLocal() && file->vfile_isDir() && !multipleSelections) { - const QString selectedDirectoryPath = file->vfile_getUrl().path(); + if (panel->func->files()->isLocal() && file->isDir() && !multipleSelections) { + const QString selectedDirectoryPath = file->getUrl().path(); if (krMtMan.getStatus(selectedDirectoryPath) == KMountMan::MOUNTED) addAction(i18n("Unmount"))->setData(QVariant(UNMOUNT_ID)); else if (krMtMan.getStatus(selectedDirectoryPath) == KMountMan::NOT_MOUNTED) addAction(i18n("Mount"))->setData(QVariant(MOUNT_ID)); if (krMtMan.ejectable(selectedDirectoryPath)) addAction(i18n("Eject"))->setData(QVariant(EJECT_ID)); } // --------- send by mail - if (KrServices::supportedTools().contains("MAIL") && !file->vfile_isDir()) { + if (KrServices::supportedTools().contains("MAIL") && !file->isDir()) { addAction(i18n("Send by Email"))->setData(QVariant(SEND_BY_EMAIL_ID)); } // --------- empty trash if (trashOnly) { addAction(i18n("Restore"))->setData(QVariant(RESTORE_TRASHED_FILE_ID)); addAction(i18n("Empty Trash"))->setData(QVariant(EMPTY_TRASH_ID)); } #ifdef SYNCHRONIZER_ENABLED // --------- synchronize if (panel->view->numSelected()) { addAction(i18n("Synchronize Selected Files..."))->setData(QVariant(SYNC_SELECTED_ID)); } #endif // --------- copy/paste addSeparator(); addAction(i18n("Copy to Clipboard"))->setData(QVariant(COPY_CLIP_ID)); addAction(i18n("Cut to Clipboard"))->setData(QVariant(MOVE_CLIP_ID)); addAction(i18n("Paste from Clipboard"))->setData(QVariant(PASTE_CLIP_ID)); addSeparator(); // --------- properties addAction(panel->gui->actions()->actProperties); } void KrPopupMenu::addEmptyMenuEntries() { addAction(i18n("Paste from Clipboard"))->setData(QVariant(PASTE_CLIP_ID)); } void KrPopupMenu::addCreateNewMenu() { createNewPopup.addAction(krLoader->loadIcon("folder", KIconLoader::Small), i18n("Folder..."))->setData(QVariant(MKDIR_ID)); createNewPopup.addAction(krLoader->loadIcon("text-plain", KIconLoader::Small), i18n("Text File..."))->setData(QVariant(NEW_TEXT_FILE_ID)); QAction *newAct = addMenu(&createNewPopup); newAct->setData(QVariant(CREATE_NEW_ID)); newAct->setText(i18n("Create New")); } void KrPopupMenu::performAction(int id) { if (_items.isEmpty()) return; // sanity check, empty file list KFileItem *item = &_items.first(); switch (id) { case - 1 : // the user clicked outside of the menu return ; case OPEN_TAB_ID : // assuming only 1 file is selected (otherwise we won't get here) panel->manager()->newTab(item->url(), panel); break; case OPEN_ID : foreach(KFileItem fi, _items) panel->func->execute(fi.name()); break; case BROWSE_ID : panel->func->goInside(item->url().fileName()); break; case COPY_ID : panel->func->copyFiles(); break; case MOVE_ID : panel->func->moveFiles(); break; case RENAME_ID : panel->func->rename(); break; case TRASH_ID : panel->func->deleteFiles(false); break; case DELETE_ID : panel->func->deleteFiles(true); break; case EJECT_ID : krMtMan.eject(item->url().adjusted(QUrl::StripTrailingSlash).path()); break; /* case SHRED_ID : if ( KMessageBox::warningContinueCancel( krApp, i18n("Do you really want to shred %1? Once shred, the file is gone forever.", item->name()), QString(), KStandardGuiItem::cont(), KStandardGuiItem::cancel(), "Shred" ) == KMessageBox::Continue ) - KShred::shred( panel->func->files() ->vfs_getFile( item->name() ).adjusted(QUrl::RemoveTrailingSlash).path() ); + KShred::shred( panel->func->files() ->getFile( item->name() ).adjusted(QUrl::RemoveTrailingSlash).path() ); break;*/ case OPEN_KONQ_ID : KToolInvocation::startServiceByDesktopName("konqueror", item->url().toDisplayString(QUrl::PreferLocalFile)); break; case CHOOSE_ID : // open-with dialog panel->func->displayOpenWithDialog(_items.urlList()); break; case MOUNT_ID : krMtMan.mount(item->url().adjusted(QUrl::StripTrailingSlash).path()); break; case NEW_LINK_ID : panel->func->krlink(false); break; case NEW_SYMLINK_ID : panel->func->krlink(true); break; case REDIRECT_LINK_ID : panel->func->redirectLink(); break; case EMPTY_TRASH_ID : KrTrashHandler::emptyTrash(); break; case RESTORE_TRASHED_FILE_ID : KrTrashHandler::restoreTrashedFiles(_items.urlList()); break; case UNMOUNT_ID : krMtMan.unmount(item->url().adjusted(QUrl::StripTrailingSlash).path()); break; case COPY_CLIP_ID : panel->func->copyToClipboard(); break; case MOVE_CLIP_ID : panel->func->copyToClipboard(true); break; case PASTE_CLIP_ID : panel->func->pasteFromClipboard(); break; case SEND_BY_EMAIL_ID : { SLOTS->sendFileByEmail(_items.urlList()); break; } case MKDIR_ID : panel->func->mkdir(); break; case NEW_TEXT_FILE_ID: panel->func->editNew(); break; #ifdef SYNCHRONIZER_ENABLED case SYNC_SELECTED_ID : { QStringList selectedNames; foreach(KFileItem item, _items) selectedNames << item.name(); if (panel->otherPanel()->view->numSelected()) { KrViewItemList otherItems; panel->otherPanel()->view->getSelectedKrViewItems(&otherItems); for (KrViewItemList::Iterator it2 = otherItems.begin(); it2 != otherItems.end(); ++it2) { QString name = (*it2) ->name(); if (!selectedNames.contains(name)) selectedNames.append(name); } } SLOTS->slotSynchronizeDirs(selectedNames); } break; #endif case OPEN_TERM_ID : SLOTS->runTerminal(item->url().path()); break; } // check if something from the open-with-offered-services was selected if (id >= SERVICE_LIST_ID) { const QStringList names = panel->gui->getSelectedNames(); panel->func->runService(*(offers[ id - SERVICE_LIST_ID ]), panel->func->files()->getUrls(names)); } } diff --git a/krusader/Panel/krpreviewjob.cpp b/krusader/Panel/krpreviewjob.cpp index 93b773d3..22affefe 100644 --- a/krusader/Panel/krpreviewjob.cpp +++ b/krusader/Panel/krpreviewjob.cpp @@ -1,171 +1,171 @@ /*************************************************************************** krpreviewjob.cpp ------------------- copyright : (C) 2009 by Jan Lepper e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "krpreviewjob.h" #include "krview.h" #include "krviewitem.h" -#include "../VFS/vfile.h" +#include "../FileSystem/fileitem.h" #include "../defaults.h" #include // QtWidgets #include #define ASSERT(what) if(!what) abort(); // how much items to process by a single job // view becomes unresponsive during load if set too high #define MAX_CHUNK_SIZE 50 KrPreviewJob::KrPreviewJob(KrPreviews *parent) : _job(0), _parent(parent) { _timer.setSingleShot(true); _timer.setInterval(0); connect(&_timer, SIGNAL(timeout()), SLOT(slotStartJob())); } KrPreviewJob::~KrPreviewJob() { doKill(); } void KrPreviewJob::scheduleItem(KrViewItem *item) { if(!_scheduled.contains(item)) { _scheduled.append(item); setTotalAmount(KJob::Files, totalAmount(KJob::Files) + 1); } if(!_job) _timer.start(); } void KrPreviewJob::removeItem(KrViewItem *item) { setTotalAmount(KJob::Files, totalAmount(KJob::Files) - _scheduled.removeAll(item)); if(_job) { doKill(); if(!_scheduled.isEmpty()) _timer.start(); } if(_scheduled.isEmpty()) emitResult(); } void KrPreviewJob::slotFailed(const KFileItem & item) { slotGotPreview(item, QPixmap()); } void KrPreviewJob::slotGotPreview(const KFileItem & item, const QPixmap & preview) { KrViewItem *vi = _hash[item]; ASSERT(vi); _scheduled.removeOne(vi); - const vfile *file = vi->getVfile(); + const FileItem *file = vi->getFileItem(); _parent->addPreview(file, preview); vi->redraw(); setProcessedAmount(KJob::Files, processedAmount(KJob::Files) + 1); emitPercent(processedAmount(KJob::Files), totalAmount(KJob::Files)); } void KrPreviewJob::slotStartJob() { ASSERT(_job == 0); ASSERT(!_scheduled.isEmpty()); _hash.clear(); sort(); int size = _parent->_view->fileIconSize(); KFileItemList list; for(int i = 0; i < _scheduled.count() && i < MAX_CHUNK_SIZE; i++) { - KFileItem fi(_scheduled[i]->getVfile()->vfile_getUrl(), 0, 0); + KFileItem fi(_scheduled[i]->getFileItem()->getUrl(), 0, 0); list.append(fi); _hash.insert(fi, _scheduled[i]); } QStringList allPlugins = KIO::PreviewJob::availablePlugins(); _job = new KIO::PreviewJob(list, QSize(size, size), &allPlugins); _job->setOverlayIconAlpha(0); _job->setOverlayIconSize(0); _job->setScaleType(KIO::PreviewJob::ScaledAndCached); connect(_job, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)), SLOT(slotGotPreview(const KFileItem&, const QPixmap&))); connect(_job, SIGNAL(failed(const KFileItem&)), SLOT(slotFailed(const KFileItem&))); connect(_job, SIGNAL(result(KJob*)), SLOT(slotJobResult(KJob*))); } void KrPreviewJob::slotJobResult(KJob *job) { (void) job; if(!disconnect(_job, 0, this, 0)) abort(); _job = 0; _hash.clear(); if(_scheduled.isEmpty()) emitResult(); else _timer.start(); } // move currently visible items to beginning of the list void KrPreviewJob::sort() { for(int i = 0, visible_end = 0; i < _scheduled.count(); i++) { KrViewItem *item = _scheduled[i]; if(_parent->_view->widget()->rect().intersects(item->itemRect())) { if(i != visible_end) _scheduled.move(i, visible_end); visible_end++; } } } bool KrPreviewJob::doKill() { _timer.stop(); if(_job) { if(!disconnect(_job, 0, this, 0)) abort(); if(!_job->kill()) abort(); _job = 0; } _hash.clear(); return true; } diff --git a/krusader/Panel/krpreviews.cpp b/krusader/Panel/krpreviews.cpp index 7e8e38c3..391a2384 100644 --- a/krusader/Panel/krpreviews.cpp +++ b/krusader/Panel/krpreviews.cpp @@ -1,140 +1,140 @@ /*************************************************************************** krpreviews.cpp ------------------- copyright : (C) 2009 by Jan Lepper e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "krpreviews.h" #include "krpreviewjob.h" #include "krcolorcache.h" #include "krview.h" #include "krviewitem.h" -#include "../VFS/vfile.h" +#include "../FileSystem/fileitem.h" #include "../defaults.h" #include #define ASSERT(what) if(!what) abort(); KrPreviews::KrPreviews(KrView *view) : _job(0), _view(view) { _dim = KrColorCache::getColorCache().getDimSettings(_dimColor, _dimFactor); connect(&KrColorCache::getColorCache(), SIGNAL(colorsRefreshed()), SLOT(slotRefreshColors())); } KrPreviews::~KrPreviews() { clear(); } void KrPreviews::clear() { if(_job) { _job->kill(KJob::EmitResult); _job = 0; } _previews.clear(); _previewsInactive.clear(); } void KrPreviews::update() { if(_job) return; for (KrViewItem *it = _view->getFirst(); it != 0; it = _view->getNext(it)) { - if(!_previews.contains(it->getVfile())) + if(!_previews.contains(it->getFileItem())) updatePreview(it); } } void KrPreviews::deletePreview(KrViewItem *item) { if(_job) { _job->removeItem(item); } - removePreview(item->getVfile()); + removePreview(item->getFileItem()); } void KrPreviews::updatePreview(KrViewItem *item) { if(!_job) { _job = new KrPreviewJob(this); connect(_job, SIGNAL(result(KJob*)), SLOT(slotJobResult(KJob*))); _view->op()->emitPreviewJobStarted(_job); } _job->scheduleItem(item); } -bool KrPreviews::getPreview(const vfile* file, QPixmap &pixmap, bool active) +bool KrPreviews::getPreview(const FileItem *file, QPixmap &pixmap, bool active) { if(active || !_dim) pixmap = _previews.value(file); else pixmap = _previewsInactive.value(file); return !pixmap.isNull(); } void KrPreviews::slotJobResult(KJob *job) { (void) job; _job = 0; } void KrPreviews::slotRefreshColors() { clear(); _dim = KrColorCache::getColorCache().getDimSettings(_dimColor, _dimFactor); update(); } -void KrPreviews::addPreview(const vfile *file, const QPixmap &preview) +void KrPreviews::addPreview(const FileItem *file, const QPixmap &preview) { QPixmap active, inactive; if(preview.isNull()) { - active = KrView::getIcon((vfile*)file, true, _view->fileIconSize()); + active = KrView::getIcon((FileItem *)file, true, _view->fileIconSize()); if(_dim) - inactive = KrView::getIcon((vfile*)file, false, _view->fileIconSize()); + inactive = KrView::getIcon((FileItem *)file, false, _view->fileIconSize()); } else { - active = KrView::processIcon(preview, false, _dimColor, _dimFactor, file->vfile_isSymLink()); + active = KrView::processIcon(preview, false, _dimColor, _dimFactor, file->isSymLink()); if(_dim) - inactive = KrView::processIcon(preview, true, _dimColor, _dimFactor, file->vfile_isSymLink()); + inactive = KrView::processIcon(preview, true, _dimColor, _dimFactor, file->isSymLink()); } _previews.insert(file, active); if(_dim) _previewsInactive.insert(file, inactive); } -void KrPreviews::removePreview(const vfile* file) +void KrPreviews::removePreview(const FileItem *file) { _previews.remove(file); _previewsInactive.remove(file); } diff --git a/krusader/Panel/krpreviews.h b/krusader/Panel/krpreviews.h index 34d4b4a2..307a8922 100644 --- a/krusader/Panel/krpreviews.h +++ b/krusader/Panel/krpreviews.h @@ -1,79 +1,79 @@ /*************************************************************************** krpreviews.h ------------------- copyright : (C) 2009 by Jan Lepper e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KRPREVIEWS_H #define KRPREVIEWS_H // QtCore #include #include // QtGui #include #include class KJob; class KrView; class KrViewItem; class KrPreviewJob; -class vfile; +class FileItem; class KrPreviews: public QObject { friend class KrPreviewJob; Q_OBJECT public: KrPreviews(KrView *view); ~KrPreviews(); - bool getPreview(const vfile* file, QPixmap &pixmap, bool active); + bool getPreview(const FileItem* file, QPixmap &pixmap, bool active); void updatePreview(KrViewItem *item); void deletePreview(KrViewItem *item); //updates all items for which no preview has been loaded yet void update(); void clear(); protected slots: void slotRefreshColors(); void slotJobResult(KJob *job); protected: - void addPreview(const vfile *file, const QPixmap &preview); - void removePreview(const vfile* file); + void addPreview(const FileItem *file, const QPixmap &preview); + void removePreview(const FileItem* file); KrPreviewJob *_job; bool _dim; QColor _dimColor; int _dimFactor; - QHash _previews; - QHash _previewsInactive; + QHash _previews; + QHash _previewsInactive; KrView *_view; }; #endif // __krpreviews__ diff --git a/krusader/Panel/krsearchbar.cpp b/krusader/Panel/krsearchbar.cpp index 034a02fe..a9ce120e 100644 --- a/krusader/Panel/krsearchbar.cpp +++ b/krusader/Panel/krsearchbar.cpp @@ -1,393 +1,393 @@ /***************************************************************************** * Copyright (C) 2010 Jan Lepper * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "krsearchbar.h" #include "../defaults.h" #include "../krglobal.h" -#include "../VFS/vfilecontainer.h" +#include "../FileSystem/dirlisterinterface.h" #include "krview.h" #include "krviewitem.h" #include #include #include #include #include #include #include #include #include KrSearchBar::KrSearchBar(KrView *view, QWidget *parent) : QWidget(parent), _view(0) { // close button QToolButton *closeButton = new QToolButton(this); closeButton->setAutoRaise(true); closeButton->setIcon(QIcon::fromTheme(QStringLiteral("dialog-close"))); closeButton->setToolTip(i18n("Close the search bar")); connect(closeButton, SIGNAL(clicked()), SLOT(hideBar())); // combo box for changing search mode _modeBox = new QComboBox(this); _modeBox->addItems(QStringList() << i18n("Search") << i18n("Select") << i18n("Filter")); int defaultIndex = KConfigGroup (krConfig, "Look&Feel") .readEntry("Default Search Mode", QString::number(KrSearchBar::MODE_SEARCH)).toInt(); _modeBox->setCurrentIndex(defaultIndex); _modeBox->setToolTip(i18n("Change the search mode")); connect(_modeBox, SIGNAL(currentIndexChanged(int)), SLOT(onModeChange())); _currentMode = static_cast(_modeBox->currentIndex()); // combo box for entering search string _textBox = new KComboBox(this); _textBox->setEditable(true); _modeBox->setToolTip(i18n("Enter or select search string")); QStringList savedSearches = KConfigGroup(krConfig, "Private") .readEntry("Predefined Selections", QStringList()); if (savedSearches.count() > 0) _textBox->addItems(savedSearches); _textBox->setCurrentText(""); _textBox->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred)); connect(_textBox, SIGNAL(currentTextChanged(QString)), SLOT(onSearchChange())); QToolButton *saveSearchBtn = new QToolButton(this); saveSearchBtn->setIcon(krLoader->loadIcon("document-save", KIconLoader::Toolbar, 16)); saveSearchBtn->setFixedSize(20, 20); saveSearchBtn->setToolTip(i18n("Save the current search string")); connect(saveSearchBtn, SIGNAL(clicked()), this, SLOT(saveSearchString())); _openSelectDialogBtn = new QToolButton(this); _openSelectDialogBtn->setIcon(krLoader->loadIcon("configure", KIconLoader::Toolbar, 16)); _openSelectDialogBtn->setFixedSize(20, 20); _openSelectDialogBtn->setToolTip(i18n("Open selection dialog")); QHBoxLayout *layout = new QHBoxLayout(this); layout->setMargin(0); layout->addWidget(closeButton); layout->addWidget(_modeBox); layout->addWidget(_textBox); layout->addWidget(saveSearchBtn); layout->addWidget(_openSelectDialogBtn); _textBox->installEventFilter(this); setView(view); } void KrSearchBar::setView(KrView *view) { if (_view) { _view->widget()->removeEventFilter(this); disconnect(_openSelectDialogBtn, 0, 0, 0); } _view = view; connect(_openSelectDialogBtn, &QToolButton::clicked, [this](){ _view->customSelection(true); }); _view->widget()->installEventFilter(this); } // #### public slots void KrSearchBar::showBar(SearchMode mode) { if (mode != MODE_LAST) { _modeBox->setCurrentIndex(mode); } show(); _textBox->setFocus(); } void KrSearchBar::hideBar() { resetSearch(); if (_textBox->hasFocus()) _view->widget()->setFocus(); hide(); } void KrSearchBar::resetSearch() { _textBox->clearEditText(); indicateMatch(true); } // #### protected slots void KrSearchBar::onModeChange() { if (_currentMode == MODE_FILTER) { _view->op()->filterSearch(QString(), true); // reset filter } _currentMode = static_cast(_modeBox->currentIndex()); onSearchChange(); } void KrSearchBar::onSearchChange() { const QString text = _textBox->currentText(); switch(_currentMode) { case MODE_SEARCH: { const bool anyMatch = _view->op()->searchItem(text, caseSensitive()); indicateMatch(anyMatch); break; } case MODE_SELECT: { _view->unselectAll(); if (!text.isEmpty()) { const bool anyMatch = _view->changeSelection(KRQuery(text, caseSensitive()), true); indicateMatch(anyMatch); } break; } case MODE_FILTER: { const bool anyMatch =_view->op()->filterSearch(text, caseSensitive()); indicateMatch(anyMatch); break; } default: krOut << "unexpected search mode: " << _currentMode; } _textBox->setFocus(); } void KrSearchBar::saveSearchString() { KConfigGroup group(krConfig, "Private"); QStringList lst = group.readEntry("Predefined Selections", QStringList()); QString searchString = _textBox->currentText(); if (lst.indexOf(searchString) != -1) { // already saved return; } lst.append(searchString); group.writeEntry("Predefined Selections", lst); _textBox->addItem(searchString); QToolTip::showText(QCursor::pos(), i18n("Saved search text to history")); } // #### protected void KrSearchBar::keyPressEvent(QKeyEvent *event) { const bool handled = handleKeyPressEvent(static_cast(event)); if (handled) { return; } QWidget::keyPressEvent(event); } bool KrSearchBar::eventFilter(QObject *watched, QEvent *event) { if (event->type() != QEvent::ShortcutOverride && watched == _view->widget()) { QKeyEvent *ke = static_cast(event); // overwrite "escape" shortcut if bar is shown if ((ke->key() == Qt::Key_Escape) && (ke->modifiers() == Qt::NoModifier) && !isHidden()) { ke->accept(); handleKeyPressEvent(ke); return true; } } if (event->type() != QEvent::KeyPress) { return false; } QKeyEvent *ke = static_cast(event); if (watched == _view->widget()) { KConfigGroup grpSv(krConfig, "Look&Feel"); const bool autoShow = grpSv.readEntry("New Style Quicksearch", _NewStyleQuicksearch); if (isHidden() && !autoShow) { return false; } if (!isHidden()) { const bool handled = handleKeyPressEvent(ke); if (handled) { return true; } } if (isHidden() || // view can handle its own event if user does not want to remove text or... !((ke->key() == Qt::Key_Backspace && !_textBox->currentText().isEmpty()) || // ...insert space in search bar (even if not focused) (ke->key() == Qt::Key_Space && _currentMode == KrSearchBar::MODE_SEARCH))) { const bool handled = _view->handleKeyEvent(ke); if (handled) { return true; } } if (ke->text().isEmpty() || (ke->modifiers() != Qt::NoModifier && ke->modifiers() != Qt::ShiftModifier)) { return false; } // start searching if bar is hidden? if (isHidden()) { if (autoShow) { showBar(); } else { return false; } } // bar is visible and gets the key input _textBox->setFocus(); if (ke->key() == Qt::Key_Backspace) { _textBox->lineEdit()->backspace(); } else { _textBox->setEditText(_textBox->currentText().append(ke->text())); } return true; } else if (watched == _textBox) { // allow the view to handle (most) key events from the text box if (ke->modifiers() == Qt::NoModifier && ke->key() != Qt::Key_Space && ke->key() != Qt::Key_Backspace && ke->key() != Qt::Key_Left && ke->key() != Qt::Key_Right) { bool handled = _view->handleKeyEvent(ke); if (handled) { _view->widget()->setFocus(); return true; } } } return false; } // #### private bool KrSearchBar::handleKeyPressEvent(QKeyEvent *ke) { if (ke->modifiers() != Qt::NoModifier) { return false; } switch (ke->key()) { case Qt::Key_Escape: { hideBar(); return true; } case Qt::Key_Up: return handleUpDownKeyPress(true); case Qt::Key_Down: return handleUpDownKeyPress(false); case Qt::Key_Insert: { // select current item and jump to next search result KrViewItem * item = _view->getCurrentKrViewItem(); if (item) { item->setSelected(!item->isSelected()); _view->op()->searchItem(_textBox->currentText(), caseSensitive(), 1); } return true; } case Qt::Key_Home: { // jump to first search result KrViewItem * item = _view->getLast(); if (item) { _view->setCurrentKrViewItem(_view->getLast()); _view->op()->searchItem(_textBox->currentText(), caseSensitive(), 1); } return true; } case Qt::Key_End: { // jump to last search result KrViewItem * item = _view->getFirst(); if (item) { _view->setCurrentKrViewItem(_view->getFirst()); _view->op()->searchItem(_textBox->currentText(), caseSensitive(), -1); } return true; } } return false; } bool KrSearchBar::handleUpDownKeyPress(bool up) { if (_currentMode != MODE_SEARCH) { return false; } const bool updownCancel = KConfigGroup(krConfig, "Look&Feel") .readEntry("Up/Down Cancels Quicksearch", false); if (updownCancel) { hideBar(); return false; } const bool anyMatch = _view->op()->searchItem(_textBox->currentText(), caseSensitive(), up ? -1 : 1); indicateMatch(anyMatch); return true; } void KrSearchBar::indicateMatch(bool anyMatch) { KConfigGroup gc(krConfig, "Colors"); QPalette p = QGuiApplication::palette(); QString foreground, background; if (anyMatch) { foreground = "Quicksearch Match Foreground"; background = "Quicksearch Match Background"; } else { foreground = "Quicksearch Non-match Foreground"; background = "Quicksearch Non-match Background"; } QColor fore = Qt::black; QString foreSetting = gc.readEntry(foreground, QString()); if (foreSetting == "KDE default") { fore = p.color(QPalette::Active, QPalette::Text); } else if (!foreSetting.isEmpty()) { fore = gc.readEntry(foreground, fore); } QColor back = anyMatch ? QColor(192, 255, 192) : QColor(255, 192, 192); QString backSetting = gc.readEntry(background, QString()); if (backSetting == "KDE default") { back = p.color(QPalette::Active, QPalette::Base); } else if (!backSetting.isEmpty()) { back = gc.readEntry(background, back); } QPalette pal = palette(); pal.setColor(QPalette::Base, back); pal.setColor(QPalette::Text, fore); _textBox->lineEdit()->setPalette(pal); } bool KrSearchBar::caseSensitive() { KConfigGroup grpSvr(krConfig, "Look&Feel"); return grpSvr.readEntry("Case Sensitive Quicksearch", _CaseSensitiveQuicksearch); } diff --git a/krusader/Panel/krsort.cpp b/krusader/Panel/krsort.cpp index 14c7732b..d5001ca4 100644 --- a/krusader/Panel/krsort.cpp +++ b/krusader/Panel/krsort.cpp @@ -1,349 +1,349 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "krsort.h" // QtCore #include #include -#include "../VFS/krpermhandler.h" +#include "../FileSystem/krpermhandler.h" namespace KrSort { -void SortProps::init(vfile *vf, int col, const KrViewProperties * props, bool isDummy, bool asc, int origNdx, QVariant customData) { +void SortProps::init(FileItem *fileitem, int col, const KrViewProperties * props, bool isDummy, bool asc, int origNdx, QVariant customData) { _col = col; _prop = props; _isdummy = isDummy; _ascending = asc; - _vfile = vf; + _fileItem = fileitem; _index = origNdx; - _name = vf->vfile_getName(); + _name = fileitem->getName(); _customData = customData; if(_prop->sortOptions & KrViewProperties::IgnoreCase) _name = _name.toLower(); switch (_col) { case KrViewProperties::Ext: { - if (vf->vfile_isDir()) { + if (fileitem->isDir()) { _ext = ""; } else { // check if the file has an extension - const QString& vfName = vf->vfile_getName(); - int loc = vfName.lastIndexOf('.'); + const QString& fileitemName = fileitem->getName(); + int loc = fileitemName.lastIndexOf('.'); if (loc > 0) { // avoid mishandling of .bashrc and friend // check if it has one of the predefined 'atomic extensions' for (QStringList::const_iterator i = props->atomicExtensions.begin(); i != props->atomicExtensions.end(); ++i) { - if (vfName.endsWith(*i) && vfName != *i) { - loc = vfName.length() - (*i).length(); + if (fileitemName.endsWith(*i) && fileitemName != *i) { + loc = fileitemName.length() - (*i).length(); break; } } _ext = _name.mid(loc); } else _ext = ""; } break; } case KrViewProperties::Type: { if (isDummy) _data = ""; else { QMimeDatabase db; - QMimeType mt = db.mimeTypeForName(vf->vfile_getMime()); + QMimeType mt = db.mimeTypeForName(fileitem->getMime()); if (mt.isValid()) _data = mt.comment(); } break; } case KrViewProperties::Permissions: { if (isDummy) _data = ""; else { if (properties()->numericPermissions) { QString perm; - _data = perm.sprintf("%.4o", vf->vfile_getMode() & PERM_BITMASK); + _data = perm.sprintf("%.4o", fileitem->getMode() & PERM_BITMASK); } else - _data = vf->vfile_getPerm(); + _data = fileitem->getPerm(); } break; } case KrViewProperties::KrPermissions: { if (isDummy) _data = ""; else { - _data = KrView::krPermissionString(vf); + _data = KrView::krPermissionString(fileitem); } break; } case KrViewProperties::Owner: { if (isDummy) _data = ""; else - _data = vf->vfile_getOwner(); + _data = fileitem->getOwner(); } case KrViewProperties::Group: { if (isDummy) _data = ""; else - _data = vf->vfile_getGroup(); + _data = fileitem->getGroup(); } default: break; } } // compares numbers within two strings int compareNumbers(QString& aS1, int& aPos1, QString& aS2, int& aPos2) { int res = 0; int start1 = aPos1; int start2 = aPos2; while (aPos1 < aS1.length() && aS1.at(aPos1).isDigit()) aPos1++; while (aPos2 < aS2.length() && aS2.at(aPos2).isDigit()) aPos2++; // the left-most difference determines what's bigger int i1 = aPos1 - 1; int i2 = aPos2 - 1; for (; i1 >= start1 || i2 >= start2; i1--, i2--) { int c1 = 0; int c2 = 0; if (i1 >= start1) c1 = aS1.at(i1).digitValue(); if (i2 >= start2) c2 = aS2.at(i2).digitValue(); if (c1 < c2) res = -1; else if (c1 > c2) res = 1; } return res; } bool compareTextsAlphabetical(QString& aS1, QString& aS2, const KrViewProperties * _viewProperties, bool aNumbers) { int lPositionS1 = 0; int lPositionS2 = 0; // sometimes, localeAwareCompare is not case sensitive. in that case, we need to fallback to a simple string compare (KDE bug #40131) bool lUseLocaleAware = ((_viewProperties->sortOptions & KrViewProperties::IgnoreCase) || _viewProperties->localeAwareCompareIsCaseSensitive) && (_viewProperties->sortOptions & KrViewProperties::LocaleAwareSort); int j = 0; QChar lchar1; QChar lchar2; while (true) { lchar1 = aS1[lPositionS1]; lchar2 = aS2[lPositionS2]; // detect numbers if (aNumbers && lchar1.isDigit() && lchar2.isDigit()) { int j = compareNumbers(aS1, lPositionS1, aS2, lPositionS2); if (j != 0) return j < 0; } else if (lUseLocaleAware && ((lchar1 >= 128 && ((lchar2 >= 'A' && lchar2 <= 'Z') || (lchar2 >= 'a' && lchar2 <= 'z') || lchar2 >= 128)) || (lchar2 >= 128 && ((lchar1 >= 'A' && lchar1 <= 'Z') || (lchar1 >= 'a' && lchar1 <= 'z') || lchar1 >= 128)) ) ) { // use localeAwareCompare when a unicode character is encountered j = QString::localeAwareCompare(lchar1, lchar2); if (j != 0) return j < 0; lPositionS1++; lPositionS2++; } else { // if characters are latin or localeAwareCompare is not case sensitive then use simple characters compare is enough if (lchar1 < lchar2) return true; if (lchar1 > lchar2) return false; lPositionS1++; lPositionS2++; } // at this point strings are equal, check if ends of strings are reached if (lPositionS1 == aS1.length() && lPositionS2 == aS2.length()) return false; if (lPositionS1 == aS1.length() && lPositionS2 < aS2.length()) return true; if (lPositionS1 < aS1.length() && lPositionS2 == aS2.length()) return false; } } bool compareTextsCharacterCode(QString& aS1, QString& aS2, const KrViewProperties * _viewProperties, bool aNumbers) { Q_UNUSED(_viewProperties); int lPositionS1 = 0; int lPositionS2 = 0; while (true) { // detect numbers if (aNumbers && aS1[lPositionS1].isDigit() && aS2[lPositionS2].isDigit()) { int j = compareNumbers(aS1, lPositionS1, aS2, lPositionS2); if (j != 0) return j < 0; } else { if (aS1[lPositionS1] < aS2[lPositionS2]) return true; if (aS1[lPositionS1] > aS2[lPositionS2]) return false; lPositionS1++; lPositionS2++; } // at this point strings are equal, check if ends of strings are reached if (lPositionS1 == aS1.length() && lPositionS2 == aS2.length()) return false; if (lPositionS1 == aS1.length() && lPositionS2 < aS2.length()) return true; if (lPositionS1 < aS1.length() && lPositionS2 == aS2.length()) return false; } } bool compareTextsKrusader(const QString &aS1, const QString &aS2, const KrViewProperties *_viewProperties) { // sometimes, localeAwareCompare is not case sensitive. in that case, we need to fallback to a simple string compare (KDE bug #40131) if (((_viewProperties->sortOptions & KrViewProperties::IgnoreCase) || _viewProperties->localeAwareCompareIsCaseSensitive) && (_viewProperties->sortOptions & KrViewProperties::LocaleAwareSort)) return QString::localeAwareCompare(aS1, aS2) < 0; else // if localeAwareCompare is not case sensitive then use simple compare is enough return QString::compare(aS1, aS2) < 0; } bool compareTexts(QString aS1, QString aS2, const KrViewProperties * _viewProperties, bool asc, bool isName) { //check empty strings if (aS1.length() == 0 && aS2.length() == 0) { return false; } else if (aS1.length() == 0) { return true; } else if (aS2.length() == 0) { return false; } if (isName) { if (aS1 == "..") { return !asc; } else { if (aS2 == "..") return asc; } } switch (_viewProperties->sortMethod) { case KrViewProperties::Alphabetical: return compareTextsAlphabetical(aS1, aS2, _viewProperties, false); case KrViewProperties::AlphabeticalNumbers: return compareTextsAlphabetical(aS1, aS2, _viewProperties, true); case KrViewProperties::CharacterCode: return compareTextsCharacterCode(aS1, aS2, _viewProperties, false); case KrViewProperties::CharacterCodeNumbers: return compareTextsCharacterCode(aS1, aS2, _viewProperties, true); case KrViewProperties::Krusader: default: return compareTextsKrusader(aS1, aS2, _viewProperties); } } bool itemLessThan(SortProps *sp, SortProps *sp2) { - vfile * file1 = sp->vf(); - vfile * file2 = sp2->vf(); - bool isdir1 = file1->vfile_isDir(); - bool isdir2 = file2->vfile_isDir(); + FileItem * file1 = sp->fileitem(); + FileItem * file2 = sp2->fileitem(); + bool isdir1 = file1->isDir(); + bool isdir2 = file2->isDir(); bool dirsFirst = sp->properties()->sortOptions & KrViewProperties::DirsFirst; bool alwaysSortDirsByName = sp->properties()->sortOptions & KrViewProperties::AlwaysSortDirsByName && dirsFirst && isdir1 && isdir2; if(dirsFirst) { if (isdir1 && !isdir2) return sp->isAscending(); if (isdir2 && !isdir1) return !sp->isAscending(); } if (sp->isDummy()) return sp->isAscending(); if (sp2->isDummy()) return !sp->isAscending(); int column = sp->column(); if (dirsFirst && isdir1 && isdir2 && alwaysSortDirsByName) { alwaysSortDirsByName = !sp->isAscending(); column = KrViewProperties::Name; } switch (column) { case KrViewProperties::Name: return compareTexts(sp->name(), sp2->name(), sp->properties(), sp->isAscending(), true) ^ alwaysSortDirsByName; case KrViewProperties::Ext: if (sp->extension() == sp2->extension()) return compareTexts(sp->name(), sp2->name(), sp->properties(), sp->isAscending(), true); return compareTexts(sp->extension(), sp2->extension(), sp->properties(), sp->isAscending(), true); case KrViewProperties::Size: - if (file1->vfile_getSize() == file2->vfile_getSize()) + if (file1->getSize() == file2->getSize()) return compareTexts(sp->name(), sp2->name(), sp->properties(), sp->isAscending(), true); - return file1->vfile_getSize() < file2->vfile_getSize(); + return file1->getSize() < file2->getSize(); case KrViewProperties::Modified: - if (file1->vfile_getTime_t() == file2->vfile_getTime_t()) + if (file1->getTime_t() == file2->getTime_t()) return compareTexts(sp->name(), sp2->name(), sp->properties(), sp->isAscending(), true); - return file1->vfile_getTime_t() < file2->vfile_getTime_t(); + return file1->getTime_t() < file2->getTime_t(); case KrViewProperties::Type: case KrViewProperties::Permissions: case KrViewProperties::KrPermissions: case KrViewProperties::Owner: case KrViewProperties::Group: if (sp->data() == sp2->data()) return compareTexts(sp->name(), sp2->name(), sp->properties(), sp->isAscending(), true); return compareTexts(sp->data(), sp2->data(), sp->properties(), sp->isAscending(), true); } return sp->name() < sp2->name(); } bool itemGreaterThan(SortProps *sp, SortProps *sp2) { return !itemLessThan(sp, sp2); } Sorter::Sorter(int reserveItems, const KrViewProperties *viewProperties, LessThanFunc lessThanFunc, LessThanFunc greaterThanFunc) : _viewProperties(viewProperties), _lessThanFunc(lessThanFunc), _greaterThanFunc(greaterThanFunc) { _items.reserve(reserveItems); _itemStore.reserve(reserveItems); } -void Sorter::addItem(vfile *vf, bool isDummy, int idx, QVariant customData) +void Sorter::addItem(FileItem *fileitem, bool isDummy, int idx, QVariant customData) { - _itemStore << SortProps(vf, _viewProperties->sortColumn, _viewProperties, isDummy, !descending(), idx, customData); + _itemStore << SortProps(fileitem, _viewProperties->sortColumn, _viewProperties, isDummy, !descending(), idx, customData); _items << &_itemStore.last(); } void Sorter::sort() { qStableSort(_items.begin(), _items.end(), descending() ? _greaterThanFunc : _lessThanFunc); } -int Sorter::insertIndex(vfile *vf, bool isDummy, QVariant customData) +int Sorter::insertIndex(FileItem *fileitem, bool isDummy, QVariant customData) { - SortProps props(vf, _viewProperties->sortColumn, _viewProperties, isDummy, !descending(), -1, customData); + SortProps props(fileitem, _viewProperties->sortColumn, _viewProperties, isDummy, !descending(), -1, customData); const QVector::iterator it = qLowerBound(_items.begin(), _items.end(), &props, descending() ? _greaterThanFunc : _lessThanFunc); if(it != _items.end()) return _items.indexOf((*it)); else return _items.count(); } } // namespace KrSort diff --git a/krusader/Panel/krsort.h b/krusader/Panel/krsort.h index 46382ffb..5f59bd46 100644 --- a/krusader/Panel/krsort.h +++ b/krusader/Panel/krsort.h @@ -1,127 +1,127 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #ifndef KRSORT_H #define KRSORT_H #include "krview.h" -#include "../VFS/vfile.h" +#include "../FileSystem/fileitem.h" // QtCore #include #include #include #define PERM_BITMASK (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO) namespace KrSort { class SortProps { public: SortProps() {} SortProps(const SortProps& other) { - init(other.vf(), other.column(), other.properties(), other.isDummy(), + init(other.fileitem(), other.column(), other.properties(), other.isDummy(), other.isAscending(), other.originalIndex(), other.customData()); } - SortProps(vfile *vf, int col, const KrViewProperties * props, bool isDummy, bool asc, int origNdx, QVariant customData) { - init(vf, col, props, isDummy, asc, origNdx, customData); + SortProps(FileItem *fileitem, int col, const KrViewProperties * props, bool isDummy, bool asc, int origNdx, QVariant customData) { + init(fileitem, col, props, isDummy, asc, origNdx, customData); } inline int column() const { return _col; } inline const KrViewProperties * properties() const { return _prop; } inline bool isDummy() const { return _isdummy; } inline bool isAscending() const { return _ascending; } inline QString name() const { return _name; } inline QString extension() const { return _ext; } - inline vfile * vf() const { - return _vfile; + inline FileItem * fileitem() const { + return _fileItem; } inline int originalIndex() const { return _index; } inline QString data() const { return _data; } inline const QVariant& customData() const { return _customData; } private: - void init(vfile *vf, int col, const KrViewProperties * props, bool isDummy, bool asc, int origNdx, QVariant customData); + void init(FileItem *fileitem, int col, const KrViewProperties * props, bool isDummy, bool asc, int origNdx, QVariant customData); int _col; const KrViewProperties * _prop; bool _isdummy; - vfile * _vfile; + FileItem * _fileItem; bool _ascending; QString _name; QString _ext; int _index; QString _data; QVariant _customData; }; bool compareTexts(QString aS1, QString aS2, const KrViewProperties * _viewProperties, bool asc, bool isName); bool itemLessThan(SortProps *sp, SortProps *sp2); bool itemGreaterThan(SortProps *sp, SortProps *sp2); typedef bool(*LessThanFunc)(SortProps*, SortProps*); class Sorter { public: Sorter(int reserveItems, const KrViewProperties *viewProperties, LessThanFunc lessThanFunc, LessThanFunc greaterThanFunc); Sorter(const Sorter &other); const QVector &items() const { return _items; } void sort(); - void addItem(vfile *vf, bool isDummy, int idx, QVariant customData); - int insertIndex(vfile *vf, bool isDummy, QVariant customData); + void addItem(FileItem *fileitem, bool isDummy, int idx, QVariant customData); + int insertIndex(FileItem *fileitem, bool isDummy, QVariant customData); private: bool descending() const { return _viewProperties->sortOptions & KrViewProperties::Descending; } const KrViewProperties *_viewProperties; QVector _items; QVector _itemStore; LessThanFunc _lessThanFunc, _greaterThanFunc; }; } // namespace KrSort #endif // KRSORT_H diff --git a/krusader/Panel/krvfsmodel.cpp b/krusader/Panel/krvfsmodel.cpp index 7527891a..ffc1c6a6 100644 --- a/krusader/Panel/krvfsmodel.cpp +++ b/krusader/Panel/krvfsmodel.cpp @@ -1,563 +1,563 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "krvfsmodel.h" -#include "../VFS/vfile.h" -#include "../VFS/krpermhandler.h" +#include "../FileSystem/fileitem.h" +#include "../FileSystem/krpermhandler.h" #include "../defaults.h" #include "../krglobal.h" // QtCore #include #include #include #include #include #include #include "krpanel.h" #include "krcolorcache.h" KrVfsModel::KrVfsModel(KrInterView * view): QAbstractListModel(0), _extensionEnabled(true), _view(view), - _dummyVfile(0), _ready(false), _justForSizeHint(false), + _dummyFileItem(0), _ready(false), _justForSizeHint(false), _alternatingTable(false) { KConfigGroup grpSvr(krConfig, "Look&Feel"); _defaultFont = grpSvr.readEntry("Filelist Font", _FilelistFont); } -void KrVfsModel::populate(const QList &files, vfile *dummy) +void KrVfsModel::populate(const QList &files, FileItem *dummy) { - _vfiles = files; - _dummyVfile = dummy; + _fileItems = files; + _dummyFileItem = dummy; _ready = true; if(lastSortOrder() != KrViewProperties::NoColumn) sort(); else { emit layoutAboutToBeChanged(); - for(int i = 0; i < _vfiles.count(); i++) { - updateIndices(_vfiles[i], i); + for(int i = 0; i < _fileItems.count(); i++) { + updateIndices(_fileItems[i], i); } emit layoutChanged(); } } KrVfsModel::~KrVfsModel() { } void KrVfsModel::clear() { - if(!_vfiles.count()) + if(!_fileItems.count()) return; emit layoutAboutToBeChanged(); // clear persistent indexes QModelIndexList oldPersistentList = persistentIndexList(); QModelIndexList newPersistentList; #if QT_VERSION >= 0x040700 newPersistentList.reserve(oldPersistentList.size()); #endif for (int i=0; i< oldPersistentList.size(); ++i) newPersistentList.append(QModelIndex()); changePersistentIndexList(oldPersistentList, newPersistentList); - _vfiles.clear(); - _vfileNdx.clear(); + _fileItems.clear(); + _fileItemNdx.clear(); _nameNdx.clear(); _urlNdx.clear(); - _dummyVfile = 0; + _dummyFileItem = 0; emit layoutChanged(); } int KrVfsModel::rowCount(const QModelIndex& /*parent*/) const { - return _vfiles.count(); + return _fileItems.count(); } int KrVfsModel::columnCount(const QModelIndex& /*parent*/) const { return KrViewProperties::MAX_COLUMNS; } QVariant KrVfsModel::data(const QModelIndex& index, int role) const { if (!index.isValid() || index.row() >= rowCount()) return QVariant(); - vfile *vf = _vfiles.at(index.row()); - if (vf == 0) + FileItem *fileitem = _fileItems.at(index.row()); + if (fileitem == 0) return QVariant(); switch (role) { case Qt::FontRole: return _defaultFont; case Qt::EditRole: { if (index.column() == 0) { - return vf->vfile_getName(); + return fileitem->getName(); } return QVariant(); } case Qt::UserRole: { if (index.column() == 0) { - return nameWithoutExtension(vf, false); + return nameWithoutExtension(fileitem, false); } return QVariant(); } case Qt::ToolTipRole: case Qt::DisplayRole: { switch (index.column()) { case KrViewProperties::Name: { - return nameWithoutExtension(vf); + return nameWithoutExtension(fileitem); } case KrViewProperties::Ext: { - QString nameOnly = nameWithoutExtension(vf); - const QString& vfName = vf->vfile_getName(); - return vfName.mid(nameOnly.length() + 1); + QString nameOnly = nameWithoutExtension(fileitem); + const QString& fileitemName = fileitem->getName(); + return fileitemName.mid(nameOnly.length() + 1); } case KrViewProperties::Size: { - if (vf->vfile_isDir() && vf->vfile_getSize() <= 0) { + if (fileitem->isDir() && fileitem->getSize() <= 0) { //HACK add <> brackets AFTER translating - otherwise KUIT thinks it's a tag static QString label = QString("<") + i18nc("Show the string 'DIR' instead of file size in detailed view (for folders)", "DIR") + ">"; return label; } else return (properties()->humanReadableSize) ? - KIO::convertSize(vf->vfile_getSize()) + " " : - KRpermHandler::parseSize(vf->vfile_getSize()) + ' '; + KIO::convertSize(fileitem->getSize()) + " " : + KRpermHandler::parseSize(fileitem->getSize()) + ' '; } case KrViewProperties::Type: { - if (vf == _dummyVfile) + if (fileitem == _dummyFileItem) return QVariant(); QMimeDatabase db; - QMimeType mt = db.mimeTypeForName(vf->vfile_getMime()); + QMimeType mt = db.mimeTypeForName(fileitem->getMime()); if (mt.isValid()) return mt.comment(); return QVariant(); } case KrViewProperties::Modified: { - if (vf == _dummyVfile) + if (fileitem == _dummyFileItem) return QVariant(); - time_t time = vf->vfile_getTime_t(); + time_t time = fileitem->getTime_t(); struct tm* t = localtime((time_t *) & time); QDateTime tmp(QDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday), QTime(t->tm_hour, t->tm_min)); return QLocale().toString(tmp, QLocale::ShortFormat); } case KrViewProperties::Permissions: { - if (vf == _dummyVfile) + if (fileitem == _dummyFileItem) return QVariant(); if (properties()->numericPermissions) { QString perm; - return perm.sprintf("%.4o", vf->vfile_getMode() & PERM_BITMASK); + return perm.sprintf("%.4o", fileitem->getMode() & PERM_BITMASK); } - return vf->vfile_getPerm(); + return fileitem->getPerm(); } case KrViewProperties::KrPermissions: { - if (vf == _dummyVfile) + if (fileitem == _dummyFileItem) return QVariant(); - return KrView::krPermissionString(vf); + return KrView::krPermissionString(fileitem); } case KrViewProperties::Owner: { - if (vf == _dummyVfile) + if (fileitem == _dummyFileItem) return QVariant(); - return vf->vfile_getOwner(); + return fileitem->getOwner(); } case KrViewProperties::Group: { - if (vf == _dummyVfile) + if (fileitem == _dummyFileItem) return QVariant(); - return vf->vfile_getGroup(); + return fileitem->getGroup(); } default: return QString(); } return QVariant(); } case Qt::DecorationRole: { switch (index.column()) { case KrViewProperties::Name: { if (properties()->displayIcons) { if (_justForSizeHint) return QPixmap(_view->fileIconSize(), _view->fileIconSize()); - return _view->getIcon(vf); + return _view->getIcon(fileitem); } break; } default: break; } return QVariant(); } case Qt::TextAlignmentRole: { switch (index.column()) { case KrViewProperties::Size: return QVariant(Qt::AlignRight | Qt::AlignVCenter); default: return QVariant(Qt::AlignLeft | Qt::AlignVCenter); } return QVariant(); } case Qt::BackgroundRole: case Qt::ForegroundRole: { KrColorItemType colorItemType; colorItemType.m_activePanel = _view->isFocused(); int actRow = index.row(); if (_alternatingTable) { int itemNum = _view->itemsPerPage(); if (itemNum == 0) itemNum++; if ((itemNum & 1) == 0) actRow += (actRow / itemNum); } colorItemType.m_alternateBackgroundColor = (actRow & 1); colorItemType.m_currentItem = _view->getCurrentIndex().row() == index.row(); colorItemType.m_selectedItem = _view->isSelected(index); - if (vf->vfile_isSymLink()) { - if (vf->vfile_isBrokenLink()) + if (fileitem->isSymLink()) { + if (fileitem->isBrokenLink()) colorItemType.m_fileType = KrColorItemType::InvalidSymlink; else colorItemType.m_fileType = KrColorItemType::Symlink; - } else if (vf->vfile_isDir()) + } else if (fileitem->isDir()) colorItemType.m_fileType = KrColorItemType::Directory; - else if (vf->vfile_isExecutable()) + else if (fileitem->isExecutable()) colorItemType.m_fileType = KrColorItemType::Executable; else colorItemType.m_fileType = KrColorItemType::File; KrColorGroup cols; KrColorCache::getColorCache().getColors(cols, colorItemType); if (colorItemType.m_selectedItem) { if (role == Qt::ForegroundRole) return cols.highlightedText(); else return cols.highlight(); } if (role == Qt::ForegroundRole) return cols.text(); else return cols.background(); } default: return QVariant(); } } bool KrVfsModel::setData(const QModelIndex & index, const QVariant & value, int role) { if (role == Qt::EditRole && index.isValid()) { if (index.row() < rowCount() && index.row() >= 0) { - vfile *vf = _vfiles.at(index.row()); - if (vf == 0) + FileItem *fileitem = _fileItems.at(index.row()); + if (fileitem == 0) return false; - _view->op()->emitRenameItem(vf->vfile_getName(), value.toString()); + _view->op()->emitRenameItem(fileitem->getName(), value.toString()); } } if (role == Qt::UserRole && index.isValid()) { _justForSizeHint = value.toBool(); } return QAbstractListModel::setData(index, value, role); } void KrVfsModel::sort(int column, Qt::SortOrder order) { _view->sortModeUpdated(column, order); if(lastSortOrder() == KrViewProperties::NoColumn) return; emit layoutAboutToBeChanged(); QModelIndexList oldPersistentList = persistentIndexList(); KrSort::Sorter sorter(createSorter()); sorter.sort(); - _vfiles.clear(); - _vfileNdx.clear(); + _fileItems.clear(); + _fileItemNdx.clear(); _nameNdx.clear(); _urlNdx.clear(); bool sortOrderChanged = false; QHash changeMap; for (int i = 0; i < sorter.items().count(); ++i) { const KrSort::SortProps *props = sorter.items()[i]; - _vfiles.append(props->vf()); + _fileItems.append(props->fileitem()); changeMap[ props->originalIndex() ] = i; if (i != props->originalIndex()) sortOrderChanged = true; - updateIndices(props->vf(), i); + updateIndices(props->fileitem(), i); } QModelIndexList newPersistentList; foreach(const QModelIndex &mndx, oldPersistentList) newPersistentList << index(changeMap[ mndx.row()], mndx.column()); changePersistentIndexList(oldPersistentList, newPersistentList); emit layoutChanged(); if (sortOrderChanged) _view->makeItemVisible(_view->getCurrentKrViewItem()); } -QModelIndex KrVfsModel::addItem(vfile * vf) +QModelIndex KrVfsModel::addItem(FileItem *fileitem) { emit layoutAboutToBeChanged(); if(lastSortOrder() == KrViewProperties::NoColumn) { - int idx = _vfiles.count(); - _vfiles.append(vf); - updateIndices(vf, idx); + int idx = _fileItems.count(); + _fileItems.append(fileitem); + updateIndices(fileitem, idx); emit layoutChanged(); return index(idx, 0); } QModelIndexList oldPersistentList = persistentIndexList(); KrSort::Sorter sorter(createSorter()); - int insertIndex = sorter.insertIndex(vf, vf == _dummyVfile, customSortData(vf)); - if (insertIndex != _vfiles.count()) - _vfiles.insert(insertIndex, vf); + int insertIndex = sorter.insertIndex(fileitem, fileitem == _dummyFileItem, customSortData(fileitem)); + if (insertIndex != _fileItems.count()) + _fileItems.insert(insertIndex, fileitem); else - _vfiles.append(vf); + _fileItems.append(fileitem); - for (int i = insertIndex; i < _vfiles.count(); ++i) { - updateIndices(_vfiles[i], i); + for (int i = insertIndex; i < _fileItems.count(); ++i) { + updateIndices(_fileItems[i], i); } QModelIndexList newPersistentList; foreach(const QModelIndex &mndx, oldPersistentList) { int newRow = mndx.row(); if (newRow >= insertIndex) newRow++; newPersistentList << index(newRow, mndx.column()); } changePersistentIndexList(oldPersistentList, newPersistentList); emit layoutChanged(); _view->makeItemVisible(_view->getCurrentKrViewItem()); return index(insertIndex, 0); } -QModelIndex KrVfsModel::removeItem(vfile * vf) +QModelIndex KrVfsModel::removeItem(FileItem *fileitem) { QModelIndex currIndex = _view->getCurrentIndex(); - int removeIdx = _vfiles.indexOf(vf); + int removeIdx = _fileItems.indexOf(fileitem); if(removeIdx < 0) return currIndex; emit layoutAboutToBeChanged(); QModelIndexList oldPersistentList = persistentIndexList(); QModelIndexList newPersistentList; - _vfiles.removeAt(removeIdx); + _fileItems.removeAt(removeIdx); if (currIndex.row() == removeIdx) { - if (_vfiles.count() == 0) + if (_fileItems.count() == 0) currIndex = QModelIndex(); - else if (removeIdx >= _vfiles.count()) - currIndex = index(_vfiles.count() - 1, 0); + else if (removeIdx >= _fileItems.count()) + currIndex = index(_fileItems.count() - 1, 0); else currIndex = index(removeIdx, 0); } else if (currIndex.row() > removeIdx) { currIndex = index(currIndex.row() - 1, 0); } - _vfileNdx.remove(vf); - _nameNdx.remove(vf->vfile_getName()); - _urlNdx.remove(vf->vfile_getUrl()); - // update indices for vfiles following vf - for (int i = removeIdx; i < _vfiles.count(); i++) { - updateIndices(_vfiles[i], i); + _fileItemNdx.remove(fileitem); + _nameNdx.remove(fileitem->getName()); + _urlNdx.remove(fileitem->getUrl()); + // update indices for fileItems following fileitem + for (int i = removeIdx; i < _fileItems.count(); i++) { + updateIndices(_fileItems[i], i); } foreach(const QModelIndex &mndx, oldPersistentList) { int newRow = mndx.row(); if (newRow > removeIdx) newRow--; if (newRow != removeIdx) newPersistentList << index(newRow, mndx.column()); else newPersistentList << QModelIndex(); } changePersistentIndexList(oldPersistentList, newPersistentList); emit layoutChanged(); _view->makeItemVisible(_view->getCurrentKrViewItem()); return currIndex; } -void KrVfsModel::updateItem(vfile * vf) +void KrVfsModel::updateItem(FileItem *fileitem) { - QModelIndex oldModelIndex = vfileIndex(vf); + QModelIndex oldModelIndex = fileItemIndex(fileitem); if (!oldModelIndex.isValid()) { - addItem(vf); + addItem(fileitem); return; } if(lastSortOrder() == KrViewProperties::NoColumn) { - _view->redrawItem(vf); + _view->redrawItem(fileitem); return; } int oldIndex = oldModelIndex.row(); emit layoutAboutToBeChanged(); - _vfiles.removeAt(oldIndex); + _fileItems.removeAt(oldIndex); KrSort::Sorter sorter(createSorter()); QModelIndexList oldPersistentList = persistentIndexList(); - int newIndex = sorter.insertIndex(vf, vf == _dummyVfile, customSortData(vf)); - if (newIndex != _vfiles.count()) { + int newIndex = sorter.insertIndex(fileitem, fileitem == _dummyFileItem, customSortData(fileitem)); + if (newIndex != _fileItems.count()) { if (newIndex > oldIndex) newIndex--; - _vfiles.insert(newIndex, vf); + _fileItems.insert(newIndex, fileitem); } else - _vfiles.append(vf); + _fileItems.append(fileitem); int i = newIndex; if (oldIndex < i) i = oldIndex; - for (; i < _vfiles.count(); ++i) { - updateIndices(_vfiles[i], i); + for (; i < _fileItems.count(); ++i) { + updateIndices(_fileItems[i], i); } QModelIndexList newPersistentList; foreach(const QModelIndex &mndx, oldPersistentList) { int newRow = mndx.row(); if (newRow == oldIndex) newRow = newIndex; else { if (newRow >= oldIndex) newRow--; if (mndx.row() > newIndex) newRow++; } newPersistentList << index(newRow, mndx.column()); } changePersistentIndexList(oldPersistentList, newPersistentList); emit layoutChanged(); if (newIndex != oldIndex) _view->makeItemVisible(_view->getCurrentKrViewItem()); } QVariant KrVfsModel::headerData(int section, Qt::Orientation orientation, int role) const { // ignore anything that's not display, and not horizontal if (role != Qt::DisplayRole || orientation != Qt::Horizontal) return QVariant(); switch (section) { case KrViewProperties::Name: return i18nc("File property", "Name"); case KrViewProperties::Ext: return i18nc("File property", "Ext"); case KrViewProperties::Size: return i18nc("File property", "Size"); case KrViewProperties::Type: return i18nc("File property", "Type"); case KrViewProperties::Modified: return i18nc("File property", "Modified"); case KrViewProperties::Permissions: return i18nc("File property", "Perms"); case KrViewProperties::KrPermissions: return i18nc("File property", "rwx"); case KrViewProperties::Owner: return i18nc("File property", "Owner"); case KrViewProperties::Group: return i18nc("File property", "Group"); } return QString(); } -vfile * KrVfsModel::vfileAt(const QModelIndex &index) +FileItem *KrVfsModel::fileItemAt(const QModelIndex &index) { - if (!index.isValid() || index.row() < 0 || index.row() >= _vfiles.count()) + if (!index.isValid() || index.row() < 0 || index.row() >= _fileItems.count()) return 0; - return _vfiles[ index.row()]; + return _fileItems[ index.row()]; } -const QModelIndex & KrVfsModel::vfileIndex(const vfile * vf) +const QModelIndex & KrVfsModel::fileItemIndex(const FileItem *fileitem) { - return _vfileNdx[ (vfile*) vf ]; + return _fileItemNdx[ (FileItem *) fileitem ]; } const QModelIndex & KrVfsModel::nameIndex(const QString & st) { return _nameNdx[ st ]; } Qt::ItemFlags KrVfsModel::flags(const QModelIndex & index) const { Qt::ItemFlags flags = QAbstractListModel::flags(index); if (!index.isValid()) return flags; if (index.row() >= rowCount()) return flags; - vfile *vf = _vfiles.at(index.row()); - if (vf == _dummyVfile) { + FileItem *fileitem = _fileItems.at(index.row()); + if (fileitem == _dummyFileItem) { flags = (flags & (~Qt::ItemIsSelectable)) | Qt::ItemIsDropEnabled; } else flags = flags | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; return flags; } -QString KrVfsModel::nameWithoutExtension(const vfile * vf, bool checkEnabled) const +QString KrVfsModel::nameWithoutExtension(const FileItem *fileItem, bool checkEnabled) const { - if ((checkEnabled && !_extensionEnabled) || vf->vfile_isDir()) - return vf->vfile_getName(); + if ((checkEnabled && !_extensionEnabled) || fileItem->isDir()) + return fileItem->getName(); // check if the file has an extension - const QString& vfName = vf->vfile_getName(); - int loc = vfName.lastIndexOf('.'); + const QString& fileItemName = fileItem->getName(); + int loc = fileItemName.lastIndexOf('.'); // avoid mishandling of .bashrc and friend // and virtfs / search result names like "/dir/.file" which whould become "/dir/" - if (loc > 0 && vfName.lastIndexOf('/') < loc) { + if (loc > 0 && fileItemName.lastIndexOf('/') < loc) { // check if it has one of the predefined 'atomic extensions' for (QStringList::const_iterator i = properties()->atomicExtensions.begin(); i != properties()->atomicExtensions.end(); ++i) { - if (vfName.endsWith(*i) && vfName != *i) { - loc = vfName.length() - (*i).length(); + if (fileItemName.endsWith(*i) && fileItemName != *i) { + loc = fileItemName.length() - (*i).length(); break; } } } else - return vfName; - return vfName.left(loc); + return fileItemName; + return fileItemName.left(loc); } const QModelIndex &KrVfsModel::indexFromUrl(const QUrl &url) { return _urlNdx[url]; } KrSort::Sorter KrVfsModel::createSorter() { - KrSort::Sorter sorter(_vfiles.count(), properties(), lessThanFunc(), greaterThanFunc()); - for(int i = 0; i < _vfiles.count(); i++) - sorter.addItem(_vfiles[i], _vfiles[i] == _dummyVfile, i, customSortData(_vfiles[i])); + KrSort::Sorter sorter(_fileItems.count(), properties(), lessThanFunc(), greaterThanFunc()); + for(int i = 0; i < _fileItems.count(); i++) + sorter.addItem(_fileItems[i], _fileItems[i] == _dummyFileItem, i, customSortData(_fileItems[i])); return sorter; } -void KrVfsModel::updateIndices(vfile *file, int i) +void KrVfsModel::updateIndices(FileItem *file, int i) { - _vfileNdx[file] = index(i, 0); - _nameNdx[file->vfile_getName()] = index(i, 0); - _urlNdx[file->vfile_getUrl()] = index(i, 0); + _fileItemNdx[file] = index(i, 0); + _nameNdx[file->getName()] = index(i, 0); + _urlNdx[file->getUrl()] = index(i, 0); } diff --git a/krusader/Panel/krvfsmodel.h b/krusader/Panel/krvfsmodel.h index 3385cf7b..5d6ee6c0 100644 --- a/krusader/Panel/krvfsmodel.h +++ b/krusader/Panel/krvfsmodel.h @@ -1,122 +1,122 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #ifndef KRVFSMODEL_H #define KRVFSMODEL_H // QtCore #include // QtGui #include #include "krinterview.h" #include "krsort.h" -class vfile; +class FileItem; class KrViewProperties; class KrVfsModel: public QAbstractListModel { Q_OBJECT public: KrVfsModel(KrInterView *); virtual ~KrVfsModel(); inline bool ready() const { return _ready; } - void populate(const QList &files, vfile *dummy); - QModelIndex addItem(vfile *); - QModelIndex removeItem(vfile *); - void updateItem(vfile *vf); + void populate(const QList &files, FileItem *dummy); + QModelIndex addItem(FileItem *); + QModelIndex removeItem(FileItem *); + void updateItem(FileItem *fileitem); int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE; bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) Q_DECL_OVERRIDE; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; void setExtensionEnabled(bool exten) { _extensionEnabled = exten; } inline const KrViewProperties * properties() const { return _view->properties(); } void sort() { sort(lastSortOrder(), lastSortDir()); } void clear(); - QList vfiles() { - return _vfiles; + QList fileItems() { + return _fileItems; } - vfile * vfileAt(const QModelIndex &index); - vfile *dummyVfile() const { - return _dummyVfile; + FileItem * fileItemAt(const QModelIndex &index); + FileItem *dummyFileItem() const { + return _dummyFileItem; } - const QModelIndex & vfileIndex(const vfile *); + const QModelIndex & fileItemIndex(const FileItem *); const QModelIndex & nameIndex(const QString &); const QModelIndex & indexFromUrl(const QUrl &url); virtual Qt::ItemFlags flags(const QModelIndex & index) const Q_DECL_OVERRIDE; void emitChanged() { emit layoutChanged(); } Qt::SortOrder lastSortDir() const { return (properties()->sortOptions & KrViewProperties::Descending) ? Qt::DescendingOrder : Qt::AscendingOrder; } int lastSortOrder() const { return properties()->sortColumn; } void setAlternatingTable(bool altTable) { _alternatingTable = altTable; } public slots: virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) Q_DECL_OVERRIDE; protected: KrSort::LessThanFunc lessThanFunc() { return KrSort::itemLessThan; } KrSort::LessThanFunc greaterThanFunc() const { return KrSort::itemGreaterThan; } - QVariant customSortData(vfile *) const { + QVariant customSortData(FileItem *) const { return QVariant(); } KrSort::Sorter createSorter(); - QString nameWithoutExtension(const vfile * vf, bool checkEnabled = true) const; + QString nameWithoutExtension(const FileItem * fileitem, bool checkEnabled = true) const; private: - void updateIndices(vfile *file, int index); + void updateIndices(FileItem *file, int index); - QList _vfiles; - QHash _vfileNdx; + QList _fileItems; + QHash _fileItemNdx; QHash _nameNdx; QHash _urlNdx; bool _extensionEnabled; KrInterView * _view; - vfile * _dummyVfile; + FileItem * _dummyFileItem; bool _ready; QFont _defaultFont; bool _justForSizeHint; bool _alternatingTable; }; #endif // __krvfsmodel__ diff --git a/krusader/Panel/krview.cpp b/krusader/Panel/krview.cpp index e3d53f9d..fe00ceb1 100644 --- a/krusader/Panel/krview.cpp +++ b/krusader/Panel/krview.cpp @@ -1,1161 +1,1161 @@ /*************************************************************************** krview.cpp ------------------- copyright : (C) 2000-2002 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "krview.h" #include "viewactions.h" #include "krviewfactory.h" #include "krviewitem.h" #include "krselectionmode.h" #include "krcolorcache.h" #include "krpreviews.h" #include "../kicons.h" #include "../krglobal.h" #include "../defaults.h" -#include "../VFS/krpermhandler.h" -#include "../VFS/vfilecontainer.h" +#include "../FileSystem/krpermhandler.h" +#include "../FileSystem/dirlisterinterface.h" #include "../Filter/filterdialog.h" // QtCore #include // QtGui #include #include #include #include // QtWidgets #include #include #include #include #include #include -#define VF getVfile() +#define FILEITEM getFileItem() KrView *KrViewOperator::_changedView = 0; KrViewProperties::PropertyType KrViewOperator::_changedProperties = KrViewProperties::NoProperty; // ----------------------------- operator KrViewOperator::KrViewOperator(KrView *view, QWidget *widget) : _view(view), _widget(widget), _massSelectionUpdate(false) { _saveDefaultSettingsTimer.setSingleShot(true); connect(&_saveDefaultSettingsTimer, SIGNAL(timeout()), SLOT(saveDefaultSettings())); } KrViewOperator::~KrViewOperator() { if(_changedView == _view) saveDefaultSettings(); } void KrViewOperator::startUpdate() { _view->refresh(); } void KrViewOperator::cleared() { _view->clear(); } -void KrViewOperator::fileAdded(vfile *vf) +void KrViewOperator::fileAdded(FileItem *fileitem) { - _view->addItem(vf); + _view->addItem(fileitem); } -void KrViewOperator::fileUpdated(vfile *vf) +void KrViewOperator::fileUpdated(FileItem *fileitem) { - _view->updateItem(vf); + _view->updateItem(fileitem); } void KrViewOperator::startDrag() { QStringList items; _view->getSelectedItems(&items); if (items.empty()) return ; // don't drag an empty thing QPixmap px; if (items.count() > 1 || _view->getCurrentKrViewItem() == 0) px = FL_LOADICON("queue"); // how much are we dragging else px = _view->getCurrentKrViewItem() ->icon(); emit letsDrag(items, px); } bool KrViewOperator::searchItem(const QString &text, bool caseSensitive, int direction) { KrViewItem * item = _view->getCurrentKrViewItem(); if (!item) { return false; } QRegExp rx(text, caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::Wildcard); if (!direction) { if (rx.indexIn(item->name()) == 0) { return true; } direction = 1; } KrViewItem * startItem = item; while (true) { item = (direction > 0) ? _view->getNext(item) : _view->getPrev(item); if (!item) item = (direction > 0) ? _view->getFirst() : _view->getLast(); if (item == startItem) { return false; } if (rx.indexIn(item->name()) == 0) { _view->setCurrentKrViewItem(item); _view->makeItemVisible(item); return true; } } } bool KrViewOperator::filterSearch(const QString &text, bool caseSensitive) { _view->_quickFilterMask = QRegExp(text, caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::Wildcard); _view->refresh(); - return _view->_count || !_view->_files->numVfiles(); + return _view->_count || !_view->_files->numFileItems(); } void KrViewOperator::setMassSelectionUpdate(bool upd) { _massSelectionUpdate = upd; if (!upd) { emit selectionChanged(); _view->redraw(); } } void KrViewOperator::settingsChanged(KrViewProperties::PropertyType properties) { if(!_view->_updateDefaultSettings || _view->_ignoreSettingsChange) return; if(_changedView != _view) saveDefaultSettings(); _changedView = _view; _changedProperties = static_cast(_changedProperties | properties); _saveDefaultSettingsTimer.start(100); } void KrViewOperator::saveDefaultSettings() { _saveDefaultSettingsTimer.stop(); if(_changedView) _changedView->saveDefaultSettings(_changedProperties); _changedProperties = KrViewProperties::NoProperty; _changedView = 0; } // ----------------------------- krview const KrView::IconSizes KrView::iconSizes; KrView::KrView(KrViewInstance &instance, KConfig *cfg) : _config(cfg), _properties(0), _focused(false), _fileIconSize(0), _instance(instance), _files(0), _mainWindow(0), _widget(0), _nameToMakeCurrent(QString()), _previews(0), _updateDefaultSettings(false), _ignoreSettingsChange(false), _count(0), - _numDirs(0), _dummyVfile(0) + _numDirs(0), _dummyFileItem(0) { } KrView::~KrView() { _instance.m_objects.removeOne(this); delete _previews; _previews = 0; - delete _dummyVfile; - _dummyVfile = 0; + delete _dummyFileItem; + _dummyFileItem = 0; if (_properties) qFatal("A class inheriting KrView didn't delete _properties!"); if (_operator) qFatal("A class inheriting KrView didn't delete _operator!"); } void KrView::init(bool enableUpdateDefaultSettings) { // sanity checks: if (!_widget) qFatal("_widget must be set during construction of KrView inheritors"); // ok, continue initProperties(); _operator = createOperator(); setup(); restoreDefaultSettings(); _updateDefaultSettings = enableUpdateDefaultSettings && KConfigGroup(_config, "Startup").readEntry("Update Default Panel Settings", _RememberPos); _instance.m_objects.append(this); } void KrView::initProperties() { _properties = createViewProperties(); KConfigGroup grpSvr(_config, "Look&Feel"); KConfigGroup grpInstance(_config, _instance.name()); _properties->displayIcons = grpInstance.readEntry("With Icons", _WithIcons); _properties->numericPermissions = grpSvr.readEntry("Numeric permissions", _NumericPermissions); int sortOptions = _properties->sortOptions; if (grpSvr.readEntry("Show Directories First", true)) sortOptions |= KrViewProperties::DirsFirst; if(grpSvr.readEntry("Always sort dirs by name", false)) sortOptions |= KrViewProperties::AlwaysSortDirsByName; if (!grpSvr.readEntry("Case Sensative Sort", _CaseSensativeSort)) sortOptions |= KrViewProperties::IgnoreCase; if (grpSvr.readEntry("Locale Aware Sort", true)) sortOptions |= KrViewProperties::LocaleAwareSort; _properties->sortOptions = static_cast(sortOptions); _properties->sortMethod = static_cast( grpSvr.readEntry("Sort method", (int) _DefaultSortMethod)); _properties->humanReadableSize = grpSvr.readEntry("Human Readable Size", _HumanReadableSize); _properties->localeAwareCompareIsCaseSensitive = QString("a").localeAwareCompare("B") > 0; // see KDE bug #40131 QStringList defaultAtomicExtensions; defaultAtomicExtensions += ".tar.gz"; defaultAtomicExtensions += ".tar.bz2"; defaultAtomicExtensions += ".tar.lzma"; defaultAtomicExtensions += ".tar.xz"; defaultAtomicExtensions += ".moc.cpp"; QStringList atomicExtensions = grpSvr.readEntry("Atomic Extensions", defaultAtomicExtensions); for (QStringList::iterator i = atomicExtensions.begin(); i != atomicExtensions.end();) { QString & ext = *i; ext = ext.trimmed(); if (!ext.length()) { i = atomicExtensions.erase(i); continue; } if (!ext.startsWith('.')) ext.insert(0, '.'); ++i; } _properties->atomicExtensions = atomicExtensions; } void KrView::showPreviews(bool show) { if(show) { if(!_previews) { _previews = new KrPreviews(this); _previews->update(); } } else { delete _previews; _previews = 0; } redraw(); // op()->settingsChanged(KrViewProperties::PropShowPreviews); op()->emitRefreshActions(); } void KrView::updatePreviews() { if(_previews) _previews->update(); } QPixmap KrView::processIcon(const QPixmap &icon, bool dim, const QColor & dimColor, int dimFactor, bool symlink) { QPixmap pixmap = icon; if (symlink) { const QStringList overlays = QStringList() << QString() << "emblem-symbolic-link"; KIconLoader::global()->drawOverlays(overlays, pixmap, KIconLoader::Desktop); } if(!dim) return pixmap; QImage dimmed = pixmap.toImage(); QPainter p(&dimmed); p.setCompositionMode(QPainter::CompositionMode_SourceIn); p.fillRect(0, 0, icon.width(), icon.height(), dimColor); p.setCompositionMode(QPainter::CompositionMode_SourceOver); p.setOpacity((qreal)dimFactor / (qreal)100); p.drawPixmap(0, 0, icon.width(), icon.height(), pixmap); return QPixmap::fromImage(dimmed, Qt::ColorOnly | Qt::ThresholdDither | Qt::ThresholdAlphaDither | Qt::NoOpaqueDetection ); } -QPixmap KrView::getIcon(vfile *vf, bool active, int size/*, KRListItem::cmpColor color*/) +QPixmap KrView::getIcon(FileItem *fileitem, bool active, int size/*, KRListItem::cmpColor color*/) { // KConfigGroup ag( krConfig, "Advanced"); ////////////////////////////// QPixmap icon; - QString icon_name = vf->vfile_getIcon(); + QString icon_name = fileitem->getIcon(); QString cacheName; if(!size) size = _FilelistIconSize.toInt(); QColor dimColor; int dimFactor; bool dim = !active && KrColorCache::getColorCache().getDimSettings(dimColor, dimFactor); if (icon_name.isNull()) icon_name = ""; cacheName.append(QString::number(size)); - if(vf->vfile_isSymLink()) + if(fileitem->isSymLink()) cacheName.append("LINK_"); if(dim) cacheName.append("DIM_"); cacheName.append(icon_name); //QPixmapCache::setCacheLimit( ag.readEntry("Icon Cache Size",_IconCacheSize) ); // first try the cache if (!QPixmapCache::find(cacheName, icon)) { icon = processIcon(krLoader->loadIcon(icon_name, KIconLoader::Desktop, size), - dim, dimColor, dimFactor, vf->vfile_isSymLink()); + dim, dimColor, dimFactor, fileitem->isSymLink()); // insert it into the cache QPixmapCache::insert(cacheName, icon); } return icon; } -QPixmap KrView::getIcon(vfile *vf) +QPixmap KrView::getIcon(FileItem *fileitem) { if(_previews) { QPixmap icon; - if(_previews->getPreview(vf, icon, _focused)) + if(_previews->getPreview(fileitem, icon, _focused)) return icon; } - return getIcon(vf, _focused, _fileIconSize); + return getIcon(fileitem, _focused, _fileIconSize); } /** * this function ADDs a list of selected item names into 'names'. * it assumes the list is ready and doesn't initialize it, or clears it */ void KrView::getItemsByMask(QString mask, QStringList* names, bool dirs, bool files) { for (KrViewItem * it = getFirst(); it != 0; it = getNext(it)) { if ((it->name() == "..") || !QDir::match(mask, it->name())) continue; // if we got here, than the item fits the mask - if (it->getVfile()->vfile_isDir() && !dirs) continue; // do we need to skip folders? - if (!it->getVfile()->vfile_isDir() && !files) continue; // do we need to skip files + if (it->getFileItem()->isDir() && !dirs) continue; // do we need to skip folders? + if (!it->getFileItem()->isDir() && !files) continue; // do we need to skip files names->append(it->name()); } } /** * this function ADDs a list of selected item names into 'names'. * it assumes the list is ready and doesn't initialize it, or clears it */ void KrView::getSelectedItems(QStringList *names, bool ignoreJustFocused) { for (KrViewItem * it = getFirst(); it != 0; it = getNext(it)) if (it->isSelected() && (it->name() != "..")) names->append(it->name()); // if all else fails, take the current item if (!ignoreJustFocused) { QString item = getCurrentItem(); if (names->empty() && !item.isEmpty() && item != "..") { names->append(item); } } } void KrView::getSelectedKrViewItems(KrViewItemList *items) { for (KrViewItem * it = getFirst(); it != 0; it = getNext(it)) if (it->isSelected() && (it->name() != "..")) items->append(it); // if all else fails, take the current item QString item = getCurrentItem(); if (items->empty() && !item.isEmpty() && item != ".." && getCurrentKrViewItem() != 0) { items->append(getCurrentKrViewItem()); } } QString KrView::statistics() { KIO::filesize_t size = calcSize(); KIO::filesize_t selectedSize = calcSelectedSize(); QString tmp; KConfigGroup grp(_config, "Look&Feel"); if(grp.readEntry("Show Size In Bytes", false)) { tmp = i18nc("%1=number of selected items,%2=total number of items, \ %3=filesize of selected items,%4=filesize in Bytes, \ %5=filesize of all items in folder,%6=filesize in Bytes", "%1 out of %2, %3 (%4) out of %5 (%6)", numSelected(), _count, KIO::convertSize(selectedSize), KRpermHandler::parseSize(selectedSize), KIO::convertSize(size), KRpermHandler::parseSize(size)); } else { tmp = i18nc("%1=number of selected items,%2=total number of items, \ %3=filesize of selected items,%4=filesize of all items in folder", "%1 out of %2, %3 out of %4", numSelected(), _count, KIO::convertSize(selectedSize), KIO::convertSize(size)); } // notify if we're running a filtered view if (filter() != KrViewProperties::All) tmp = ">> [ " + filterMask().nameFilter() + " ] " + tmp; return tmp; } bool KrView::changeSelection(const KRQuery& filter, bool select) { KConfigGroup grpSvr(_config, "Look&Feel"); return changeSelection(filter, select, grpSvr.readEntry("Mark Dirs", _MarkDirs), true); } bool KrView::changeSelection(const KRQuery& filter, bool select, bool includeDirs, bool makeVisible) { if (op()) op()->setMassSelectionUpdate(true); KrViewItem *temp = getCurrentKrViewItem(); KrViewItem *firstMatch = 0; for (KrViewItem * it = getFirst(); it != 0; it = getNext(it)) { if (it->name() == "..") continue; - if (it->getVfile()->vfile_isDir() && !includeDirs) + if (it->getFileItem()->isDir() && !includeDirs) continue; - vfile * file = it->getMutableVfile(); // filter::match calls getMimetype which isn't const + FileItem * file = it->getMutableFileItem(); // filter::match calls getMimetype which isn't const if (file == 0) continue; if (filter.match(file)) { it->setSelected(select); if (!firstMatch) firstMatch = it; } } if (op()) op()->setMassSelectionUpdate(false); updateView(); if (ensureVisibilityAfterSelect() && temp != 0) { makeItemVisible(temp); } else if (makeVisible && firstMatch != 0) { // if no selected item is visible... KrViewItemList selectedItems; getSelectedKrViewItems(&selectedItems); bool anyVisible = false; for (KrViewItem *item : selectedItems) { if (isItemVisible(item)) { anyVisible = true; break; } } if (!anyVisible) { // ...scroll to fist selected item makeItemVisible(firstMatch); } } redraw(); return firstMatch != 0; // return if any file was selected } void KrView::invertSelection() { if (op()) op()->setMassSelectionUpdate(true); KConfigGroup grpSvr(_config, "Look&Feel"); bool markDirs = grpSvr.readEntry("Mark Dirs", _MarkDirs); KrViewItem *temp = getCurrentKrViewItem(); for (KrViewItem * it = getFirst(); it != 0; it = getNext(it)) { if (it->name() == "..") continue; - if (it->getVfile()->vfile_isDir() && !markDirs && !it->isSelected()) + if (it->getFileItem()->isDir() && !markDirs && !it->isSelected()) continue; it->setSelected(!it->isSelected()); } if (op()) op()->setMassSelectionUpdate(false); updateView(); if (ensureVisibilityAfterSelect() && temp != 0) makeItemVisible(temp); } QString KrView::firstUnmarkedBelowCurrent() { if (getCurrentKrViewItem() == 0) return QString(); KrViewItem * iterator = getNext(getCurrentKrViewItem()); while (iterator && iterator->isSelected()) iterator = getNext(iterator); if (!iterator) { iterator = getPrev(getCurrentKrViewItem()); while (iterator && iterator->isSelected()) iterator = getPrev(iterator); } if (!iterator) return QString(); return iterator->name(); } void KrView::delItem(const QString &name) { KrViewItem *it = findItemByName(name); if(!it) return; if(_previews) _previews->deletePreview(it); preDelItem(it); - if (it->VF->vfile_isDir()) { + if (it->FILEITEM->isDir()) { --_numDirs; } --_count; delete it; op()->emitSelectionChanged(); } -void KrView::addItem(vfile *vf) +void KrView::addItem(FileItem *fileitem) { - if (isFiltered(vf)) + if (isFiltered(fileitem)) return; - KrViewItem *item = preAddItem(vf); + KrViewItem *item = preAddItem(fileitem); if (!item) return; // don't add it after all if(_previews) _previews->updatePreview(item); - if (vf->vfile_isDir()) + if (fileitem->isDir()) ++_numDirs; ++_count; if (item->name() == nameToMakeCurrent()) { setCurrentKrViewItem(item); // dictionary based - quick makeItemVisible(item); } op()->emitSelectionChanged(); } -void KrView::updateItem(vfile *vf) +void KrView::updateItem(FileItem *fileitem) { - if (isFiltered(vf)) - delItem(vf->vfile_getName()); + if (isFiltered(fileitem)) + delItem(fileitem->getName()); else { - preUpdateItem(vf); + preUpdateItem(fileitem); if(_previews) - _previews->updatePreview(findItemByVfile(vf)); + _previews->updatePreview(findItemByFileItem(fileitem)); } op()->emitSelectionChanged(); } void KrView::clear() { if(_previews) _previews->clear(); _count = _numDirs = 0; - delete _dummyVfile; - _dummyVfile = 0; + delete _dummyFileItem; + _dummyFileItem = 0; redraw(); } bool KrView::handleKeyEvent(QKeyEvent *e) { switch (e->key()) { case Qt::Key_Enter : case Qt::Key_Return : { if (e->modifiers() & Qt::ControlModifier) // let the panel handle it e->ignore(); else { KrViewItem * i = getCurrentKrViewItem(); if (i == 0) return true; QString tmp = i->name(); op()->emitExecuted(tmp); } return true; } case Qt::Key_QuoteLeft : // Terminal Emulator bugfix if (e->modifiers() == Qt::ControlModifier) { // let the panel handle it e->ignore(); } else { // a normal click - do a lynx-like moving thing op()->emitGoHome(); // ask krusader to move to the home directory } return true; case Qt::Key_Delete : // kill file op()->emitDeleteFiles(e->modifiers() == Qt::ShiftModifier || e->modifiers() == Qt::ControlModifier); return true; case Qt::Key_Insert: { KrViewItem * i = getCurrentKrViewItem(); if (!i) return true; i->setSelected(!i->isSelected()); if (KrSelectionMode::getSelectionHandler()->insertMovesDown()) { KrViewItem * next = getNext(i); if (next) { setCurrentKrViewItem(next); makeItemVisible(next); } } op()->emitSelectionChanged(); return true; } case Qt::Key_Space: { KrViewItem * viewItem = getCurrentKrViewItem(); if (viewItem != 0) { viewItem->setSelected(!viewItem->isSelected()); - if (viewItem->name() != ".." && viewItem->getVfile()->vfile_isDir() && viewItem->getVfile()->vfile_getSize() <= 0 && + if (viewItem->name() != ".." && viewItem->getFileItem()->isDir() && viewItem->getFileItem()->getSize() <= 0 && KrSelectionMode::getSelectionHandler()->spaceCalculatesDiskSpace()) { op()->emitCalcSpace(viewItem); } if (KrSelectionMode::getSelectionHandler()->spaceMovesDown()) { KrViewItem * next = getNext(viewItem); if (next) { setCurrentKrViewItem(next); makeItemVisible(next); } } op()->emitSelectionChanged(); } return true; } case Qt::Key_Backspace : // Terminal Emulator bugfix case Qt::Key_Left : if (e->modifiers() == Qt::ControlModifier || e->modifiers() == Qt::ShiftModifier || e->modifiers() == Qt::AltModifier) { // let the panel handle it e->ignore(); } else { // a normal click - do a lynx-like moving thing op()->emitDirUp(); // ask krusader to move up a directory } return true; // safety case Qt::Key_Right : if (e->modifiers() == Qt::ControlModifier || e->modifiers() == Qt::ShiftModifier || e->modifiers() == Qt::AltModifier) { // let the panel handle it e->ignore(); } else { // just a normal click - do a lynx-like moving thing KrViewItem *i = getCurrentKrViewItem(); if (i) op()->emitGoInside(i->name()); } return true; case Qt::Key_Up : if (e->modifiers() == Qt::ControlModifier) { // let the panel handle it - jump to the Location Bar e->ignore(); } else { KrViewItem *item = getCurrentKrViewItem(); if (item) { if (e->modifiers() == Qt::ShiftModifier) { item->setSelected(!item->isSelected()); op()->emitSelectionChanged(); } item = getPrev(item); if (item) { setCurrentKrViewItem(item); makeItemVisible(item); } } } return true; case Qt::Key_Down : if (e->modifiers() == Qt::ControlModifier || e->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) { // let the panel handle it - jump to command line e->ignore(); } else { KrViewItem *item = getCurrentKrViewItem(); if (item) { if (e->modifiers() == Qt::ShiftModifier) { item->setSelected(!item->isSelected()); op()->emitSelectionChanged(); } item = getNext(item); if (item) { setCurrentKrViewItem(item); makeItemVisible(item); } } } return true; case Qt::Key_Home: { if (e->modifiers() & Qt::ShiftModifier) { /* Shift+Home */ bool select = true; KrViewItem *pos = getCurrentKrViewItem(); if (pos == 0) pos = getLast(); KrViewItem *item = getFirst(); op()->setMassSelectionUpdate(true); while (item) { item->setSelected(select); if (item == pos) select = false; item = getNext(item); } op()->setMassSelectionUpdate(false); } KrViewItem * first = getFirst(); if (first) { setCurrentKrViewItem(first); makeItemVisible(first); } } return true; case Qt::Key_End: if (e->modifiers() & Qt::ShiftModifier) { bool select = false; KrViewItem *pos = getCurrentKrViewItem(); if (pos == 0) pos = getFirst(); op()->setMassSelectionUpdate(true); KrViewItem *item = getFirst(); while (item) { if (item == pos) select = true; item->setSelected(select); item = getNext(item); } op()->setMassSelectionUpdate(false); } else { KrViewItem *last = getLast(); if (last) { setCurrentKrViewItem(last); makeItemVisible(last); } } return true; case Qt::Key_PageDown: { KrViewItem * current = getCurrentKrViewItem(); int downStep = itemsPerPage(); while (downStep != 0 && current) { KrViewItem * newCurrent = getNext(current); if (newCurrent == 0) break; current = newCurrent; downStep--; } if (current) { setCurrentKrViewItem(current); makeItemVisible(current); } return true; } case Qt::Key_PageUp: { KrViewItem * current = getCurrentKrViewItem(); int upStep = itemsPerPage(); while (upStep != 0 && current) { KrViewItem * newCurrent = getPrev(current); if (newCurrent == 0) break; current = newCurrent; upStep--; } if (current) { setCurrentKrViewItem(current); makeItemVisible(current); } return true; } case Qt::Key_Escape: e->ignore(); return true; // otherwise the selection gets lost??!?? // also it is needed by the panel case Qt::Key_A : // mark all if (e->modifiers() == Qt::ControlModifier) { //FIXME: shouldn't there also be a shortcut for unselecting everything ? selectAllIncludingDirs(); return true; } // default continues here !!!!!!!!!!! default: return false; } return false; } void KrView::zoomIn() { int idx = iconSizes.indexOf(_fileIconSize); if(idx >= 0 && (idx+1) < iconSizes.count()) setFileIconSize(iconSizes[idx+1]); } void KrView::zoomOut() { int idx = iconSizes.indexOf(_fileIconSize); if(idx > 0) setFileIconSize(iconSizes[idx-1]); } void KrView::setFileIconSize(int size) { if(iconSizes.indexOf(size) < 0) return; _fileIconSize = size; if(_previews) { _previews->clear(); _previews->update(); } redraw(); op()->emitRefreshActions(); } int KrView::defaultFileIconSize() { KConfigGroup grpSvr(_config, _instance.name()); return grpSvr.readEntry("IconSize", _FilelistIconSize).toInt(); } void KrView::saveDefaultSettings(KrViewProperties::PropertyType properties) { saveSettings(KConfigGroup(_config, _instance.name()), properties); op()->emitRefreshActions(); } void KrView::restoreDefaultSettings() { restoreSettings(KConfigGroup(_config, _instance.name())); } void KrView::saveSettings(KConfigGroup group, KrViewProperties::PropertyType properties) { if(properties & KrViewProperties::PropIconSize) group.writeEntry("IconSize", fileIconSize()); if(properties & KrViewProperties::PropShowPreviews) group.writeEntry("ShowPreviews", previewsShown()); if(properties & KrViewProperties::PropSortMode) saveSortMode(group); if(properties & KrViewProperties::PropFilter) { group.writeEntry("Filter", static_cast(_properties->filter)); group.writeEntry("FilterApplysToDirs", _properties->filterApplysToDirs); if(_properties->filterSettings.isValid()) _properties->filterSettings.save(KConfigGroup(&group, "FilterSettings")); } } void KrView::restoreSettings(KConfigGroup group) { _ignoreSettingsChange = true; doRestoreSettings(group); _ignoreSettingsChange = false; refresh(); } void KrView::doRestoreSettings(KConfigGroup group) { restoreSortMode(group); setFileIconSize(group.readEntry("IconSize", defaultFileIconSize())); showPreviews(group.readEntry("ShowPreviews", false)); _properties->filter = static_cast(group.readEntry("Filter", static_cast(KrViewProperties::All))); _properties->filterApplysToDirs = group.readEntry("FilterApplysToDirs", false); _properties->filterSettings.load(KConfigGroup(&group, "FilterSettings")); _properties->filterMask = _properties->filterSettings.toQuery(); } void KrView::applySettingsToOthers() { for(int i = 0; i < _instance.m_objects.length(); i++) { KrView *view = _instance.m_objects[i]; if(this != view) { view->_ignoreSettingsChange = true; view->copySettingsFrom(this); view->_ignoreSettingsChange = false; } } } void KrView::sortModeUpdated(KrViewProperties::ColumnType sortColumn, bool descending) { if(sortColumn == _properties->sortColumn && descending == (bool) (_properties->sortOptions & KrViewProperties::Descending)) return; int options = _properties->sortOptions; if(descending) options |= KrViewProperties::Descending; else options &= ~KrViewProperties::Descending; _properties->sortColumn = sortColumn; _properties->sortOptions = static_cast(options); // op()->settingsChanged(KrViewProperties::PropSortMode); } void KrView::saveSortMode(KConfigGroup &group) { group.writeEntry("Sort Column", static_cast(_properties->sortColumn)); group.writeEntry("Descending Sort Order", _properties->sortOptions & KrViewProperties::Descending); } void KrView::restoreSortMode(KConfigGroup &group) { int column = group.readEntry("Sort Column", static_cast(KrViewProperties::Name)); bool isDescending = group.readEntry("Descending Sort Order", false); setSortMode(static_cast(column), isDescending); } -QString KrView::krPermissionString(const vfile * vf) +QString KrView::krPermissionString(const FileItem * fileitem) { QString tmp; - switch (vf->vfile_isReadable()) { + switch (fileitem->isReadable()) { case ALLOWED_PERM: tmp+='r'; break; case UNKNOWN_PERM: tmp+='?'; break; case NO_PERM: tmp+='-'; break; } - switch (vf->vfile_isWriteable()) { + switch (fileitem->isWriteable()) { case ALLOWED_PERM: tmp+='w'; break; case UNKNOWN_PERM: tmp+='?'; break; case NO_PERM: tmp+='-'; break; } - switch (vf->vfile_isExecutable()) { + switch (fileitem->isExecutable()) { case ALLOWED_PERM: tmp+='x'; break; case UNKNOWN_PERM: tmp+='?'; break; case NO_PERM: tmp+='-'; break; } return tmp; } -bool KrView::isFiltered(vfile *vf) +bool KrView::isFiltered(FileItem *fileitem) { - if (_quickFilterMask.isValid() && _quickFilterMask.indexIn(vf->vfile_getName()) == -1) + if (_quickFilterMask.isValid() && _quickFilterMask.indexIn(fileitem->getName()) == -1) return true; bool filteredOut = false; - bool isDir = vf->vfile_isDir(); + bool isDir = fileitem->isDir(); if (!isDir || (isDir && properties()->filterApplysToDirs)) { switch (properties()->filter) { case KrViewProperties::All : break; case KrViewProperties::Custom : - if (!properties()->filterMask.match(vf)) + if (!properties()->filterMask.match(fileitem)) filteredOut = true; break; case KrViewProperties::Dirs: if (!isDir) filteredOut = true; break; case KrViewProperties::Files: if (isDir) filteredOut = true; break; default: break; } } return filteredOut; } -void KrView::setFiles(VfileContainer *files) +void KrView::setFiles(DirListerInterface *files) { if(files != _files) { clear(); if(_files) QObject::disconnect(_files, 0, op(), 0); _files = files; } if(!_files) return; QObject::disconnect(_files, 0, op(), 0); QObject::connect(_files, SIGNAL(refreshDone(bool)), op(), SLOT(startUpdate())); QObject::connect(_files, SIGNAL(cleared()), op(), SLOT(cleared())); - QObject::connect(_files, SIGNAL(addedVfile(vfile*)), op(), SLOT(fileAdded(vfile*))); - QObject::connect(_files, SIGNAL(updatedVfile(vfile*)), op(), SLOT(fileUpdated(vfile*))); + QObject::connect(_files, SIGNAL(addedFileItem(FileItem*)), op(), SLOT(fileAdded(FileItem*))); + QObject::connect(_files, SIGNAL(updatedFileItem(FileItem*)), op(), SLOT(fileUpdated(FileItem*))); } void KrView::setFilter(KrViewProperties::FilterSpec filter, FilterSettings customFilter, bool applyToDirs) { _properties->filter = filter; _properties->filterSettings = customFilter; _properties->filterMask = customFilter.toQuery(); _properties->filterApplysToDirs = applyToDirs; refresh(); } void KrView::setFilter(KrViewProperties::FilterSpec filter) { KConfigGroup cfg(_config, "Look&Feel"); bool rememberSettings = cfg.readEntry("FilterDialogRemembersSettings", _FilterDialogRemembersSettings); bool applyToDirs = rememberSettings ? _properties->filterApplysToDirs : false; switch (filter) { case KrViewProperties::All : break; case KrViewProperties::Custom : { FilterDialog dialog(_widget, i18n("Filter Files"), QStringList(i18n("Apply filter to folders")), false); dialog.checkExtraOption(i18n("Apply filter to folders"), applyToDirs); if(rememberSettings) dialog.applySettings(_properties->filterSettings); dialog.exec(); FilterSettings s(dialog.getSettings()); if(!s.isValid()) // if the user canceled - quit return; _properties->filterSettings = s; _properties->filterMask = s.toQuery(); applyToDirs = dialog.isExtraOptionChecked(i18n("Apply filter to folders")); } break; default: return; } _properties->filterApplysToDirs = applyToDirs; _properties->filter = filter; refresh(); } void KrView::customSelection(bool select) { KConfigGroup grpSvr(_config, "Look&Feel"); bool includeDirs = grpSvr.readEntry("Mark Dirs", _MarkDirs); FilterDialog dialog(0, i18n("Select Files"), QStringList(i18n("Apply selection to folders")), false); dialog.checkExtraOption(i18n("Apply selection to folders"), includeDirs); dialog.exec(); KRQuery query = dialog.getQuery(); // if the user canceled - quit if (query.isNull()) return ; includeDirs = dialog.isExtraOptionChecked(i18n("Apply selection to folders")); changeSelection(query, select, includeDirs); } void KrView::refresh() { QString currentItem = getCurrentItem(); QList selection = selectedUrls(); QModelIndex currentIndex = getCurrentIndex(); clear(); if(!_files) return; - QList vfiles; + QList fileItems; // if we are not at the root add the ".." entry if(!_files->isRoot()) { - _dummyVfile = vfile::createDummy(); - vfiles << _dummyVfile; + _dummyFileItem = FileItem::createDummy(); + fileItems << _dummyFileItem; } - foreach(vfile *vf, _files->vfiles()) { - if(!vf || isFiltered(vf)) + foreach(FileItem *fileitem, _files->fileItems()) { + if(!fileitem || isFiltered(fileitem)) continue; - if(vf->vfile_isDir()) + if(fileitem->isDir()) _numDirs++; _count++; - vfiles << vf; + fileItems << fileitem; } - populate(vfiles, _dummyVfile); + populate(fileItems, _dummyFileItem); if(!selection.isEmpty()) setSelectionUrls(selection); if (!nameToMakeCurrent().isEmpty()) { setCurrentItem(nameToMakeCurrent()); setNameToMakeCurrent(""); } else if (!currentItem.isEmpty()) { if (currentItem == ".." && _count > 0 && !_quickFilterMask.isEmpty() && _quickFilterMask.isValid()) { // In a filtered view we should never select the dummy entry if // there are real matches. setCurrentKrViewItem(getNext(getFirst())); } else setCurrentItem(currentItem, currentIndex); } else { setCurrentKrViewItem(getFirst()); } updatePreviews(); redraw(); op()->emitSelectionChanged(); } -void KrView::setSelected(const vfile* vf, bool select) +void KrView::setSelected(const FileItem* fileitem, bool select) { - if(vf == _dummyVfile) + if(fileitem == _dummyFileItem) return; if(select) clearSavedSelection(); - intSetSelected(vf, select); + intSetSelected(fileitem, select); } void KrView::saveSelection() { _savedSelection = selectedUrls(); op()->emitRefreshActions(); } void KrView::restoreSelection() { if(canRestoreSelection()) setSelectionUrls(_savedSelection); } void KrView::clearSavedSelection() { _savedSelection.clear(); op()->emitRefreshActions(); } void KrView::markSameBaseName() { KrViewItem* item = getCurrentKrViewItem(); if (!item) return; KRQuery query(QString("%1.*").arg(item->name(false))); changeSelection(query, true, false); } void KrView::markSameExtension() { KrViewItem* item = getCurrentKrViewItem(); if (!item) return; KRQuery query(QString("*.%1").arg(item->extension())); changeSelection(query, true, false); } diff --git a/krusader/Panel/krview.h b/krusader/Panel/krview.h index 18d7570a..56591ea5 100644 --- a/krusader/Panel/krview.h +++ b/krusader/Panel/krview.h @@ -1,445 +1,445 @@ /*************************************************************************** krview.h ------------------- copyright : (C) 2000-2002 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KRVIEW_H #define KRVIEW_H // QtCore #include #include #include #include #include #include // QtGui #include #include #include "../Filter/filtersettings.h" -#include "../VFS/krquery.h" +#include "../FileSystem/krquery.h" #define MAX_BRIEF_COLS 5 class KrView; class KrViewItem; class KrPreviews; class KrViewInstance; -class VfileContainer; +class DirListerInterface; typedef QList KrViewItemList; // KrViewProperties // This class is an interface class between KrView and KrViewItem // In order for KrViewItem to be as independent as possible, KrView holds // an instance of this class, and fills it with the correct data. A reference // to this should be given to each KrViewItem, which then queries it for // information regarding how things should be displayed in the current view. // // Every property that the item needs to know about the view must be here! class KrViewProperties { public: KrViewProperties() : numericPermissions(false), displayIcons(false), sortColumn(Name), sortOptions(static_cast(0)), sortMethod(Alphabetical), filter(KrViewProperties::All), filterMask(KRQuery("*")), filterApplysToDirs(false), localeAwareCompareIsCaseSensitive(false), humanReadableSize(), numberOfColumns(1) { } enum PropertyType { NoProperty = 0x0, PropIconSize = 0x1, PropShowPreviews = 0x2, PropSortMode = 0x4, PropColumns = 0x8, PropFilter = 0x10, AllProperties = PropIconSize | PropShowPreviews | PropSortMode | PropColumns | PropFilter }; enum ColumnType { NoColumn = -1, Name = 0x0, Ext = 0x1, Size = 0x2, Type = 0x3, Modified = 0x4, Permissions = 0x5, KrPermissions = 0x6, Owner = 0x7, Group = 0x8, MAX_COLUMNS = 0x09 }; enum SortOptions { Descending = 0x200, DirsFirst = 0x400, IgnoreCase = 0x800, AlwaysSortDirsByName = 0x1000, LocaleAwareSort = 0x2000 }; enum SortMethod { Alphabetical = 0x1, AlphabeticalNumbers = 0x2, CharacterCode = 0x4, CharacterCodeNumbers = 0x8, Krusader = 0x10 }; enum FilterSpec { Dirs = 0x1, Files = 0x2, All = 0x3, Custom = 0x4 }; bool numericPermissions; // show full permission column as octal numbers bool displayIcons; // true if icons should be displayed in this view ColumnType sortColumn; SortOptions sortOptions; SortMethod sortMethod; // sort method for names and extensions FilterSpec filter; // what items to show (all, custom, exec) KRQuery filterMask; // what items to show (*.cpp, *.h etc) FilterSettings filterSettings; bool filterApplysToDirs; bool localeAwareCompareIsCaseSensitive; // mostly, it is not! depends on LC_COLLATE bool humanReadableSize; // display size as KB, MB or just as a long number QStringList atomicExtensions; // list of strings, which will be treated as one extension. Must // start with a dot. int numberOfColumns; // the number of columns in the brief view }; // operator can handle two ways of doing things: // 1. if the view is a widget (inherits krview and klistview for example) // 2. if the view HAS A widget (a krview-son has a member of klistview) // this is done by specifying the view and the widget in the constructor, // even if they are actually the same object (specify it twice in that case) class KrViewOperator : public QObject { Q_OBJECT public: KrViewOperator(KrView *view, QWidget *widget); ~KrViewOperator(); KrView *view() const { return _view; } QWidget *widget() const { return _widget; } void startDrag(); void emitGotDrop(QDropEvent *e) { emit gotDrop(e); } void emitLetsDrag(QStringList items, QPixmap icon) { emit letsDrag(items, icon); } void emitItemDescription(const QString &desc) { emit itemDescription(desc); } void emitContextMenu(const QPoint &point) { emit contextMenu(point); } void emitEmptyContextMenu(const QPoint &point) { emit emptyContextMenu(point); } void emitRenameItem(const QString &oldName, const QString &newName) { emit renameItem(oldName, newName); } void emitExecuted(const QString &name) { emit executed(name); } void emitGoInside(const QString &name) { emit goInside(name); } void emitNeedFocus() { emit needFocus(); } void emitMiddleButtonClicked(KrViewItem *item) { emit middleButtonClicked(item); } void emitCurrentChanged(KrViewItem *item) { emit currentChanged(item); } void emitPreviewJobStarted(KJob *job) { emit previewJobStarted(job); } void emitGoHome() { emit goHome(); } void emitDirUp() { emit dirUp(); } void emitDeleteFiles(bool reallyDelete) { emit deleteFiles(reallyDelete); } void emitCalcSpace(KrViewItem *item) { emit calcSpace(item); } void emitRefreshActions() { emit refreshActions(); } void emitGoBack() { emit goBack(); } void emitGoForward() { emit goForward(); } bool searchItem(const QString &, bool, int = 0); // search for item and set cursor bool filterSearch(const QString &, bool); // filter view items void setMassSelectionUpdate(bool upd); bool isMassSelectionUpdate() { return _massSelectionUpdate; } void settingsChanged(KrViewProperties::PropertyType properties); public slots: void emitSelectionChanged() { if (!_massSelectionUpdate) emit selectionChanged(); } signals: void selectionChanged(); void gotDrop(QDropEvent *e); void letsDrag(QStringList items, QPixmap icon); void itemDescription(const QString &desc); void contextMenu(const QPoint &point); void emptyContextMenu(const QPoint &point); void renameItem(const QString &oldName, const QString &newName); void executed(const QString &name); void goInside(const QString &name); void needFocus(); void middleButtonClicked(KrViewItem *item); void currentChanged(KrViewItem *item); void previewJobStarted(KJob *job); void goHome(); void deleteFiles(bool reallyDelete); void dirUp(); void calcSpace(KrViewItem *item); void refreshActions(); void goBack(); void goForward(); protected slots: void saveDefaultSettings(); void startUpdate(); void cleared(); - void fileAdded(vfile *vf); - void fileUpdated(vfile *vf); + void fileAdded(FileItem *fileitem); + void fileUpdated(FileItem *fileitem); protected: // never delete those KrView *_view; QWidget *_widget; private: bool _massSelectionUpdate; QTimer _saveDefaultSettingsTimer; static KrViewProperties::PropertyType _changedProperties; static KrView *_changedView; }; /**************************************************************************** * READ THIS FIRST: Using the view * * You always hold a pointer to KrView, thus you can only use functions declared * in this class. If you need something else, either this class is missing something * or you are ;-) * * The functions you'd usually want: * 1) getSelectedItems - returns all selected items, or (if none) the current item. * it never returns anything which includes the "..", and thus can return an empty list! * 2) getSelectedKrViewItems - the same as (1), but returns a QValueList with KrViewItems * 3) getCurrentItem, setCurrentItem - work with QString * 4) getFirst, getNext, getPrev, getCurrentKrViewItem - all work with KrViewItems, and * used to iterate through a list of items. note that getNext and getPrev accept a pointer * to the current item (used in detailedview for safe iterating), thus your loop should be: * for (KrViewItem *it = view->getFirst(); it!=0; it = view->getNext(it)) { blah; } * 5) nameToMakeCurrent(), setNameToMakeCurrent() - work with QString * * IMPORTANT NOTE: every one who subclasses this must call initProperties() in the constructor !!! */ class KrView { friend class KrViewItem; friend class KrViewOperator; public: class IconSizes : public QVector { public: IconSizes() : QVector() { *this << 12 << 16 << 22 << 32 << 48 << 64 << 128 << 256; } }; // instantiating a new view // 1. new KrView // 2. view->init() // notes: constructor does as little as possible, setup() does the rest. esp, note that // if you need something from operator or properties, move it into setup() void init(bool enableUpdateDefaultSettings = true); KrViewInstance *instance() { return &_instance; } static const IconSizes iconSizes; protected: void initProperties(); KrViewProperties *createViewProperties() { return new KrViewProperties(); } KrViewOperator *createOperator() { return new KrViewOperator(this, _widget); } virtual void setup() = 0; /////////////////////////////////////////////////////// // Every view must implement the following functions // /////////////////////////////////////////////////////// public: // interview related functions virtual QModelIndex getCurrentIndex() = 0; virtual bool isSelected(const QModelIndex &) = 0; virtual bool ensureVisibilityAfterSelect() = 0; virtual void selectRegion(KrViewItem *, KrViewItem *, bool) = 0; virtual uint numSelected() const = 0; virtual QList selectedUrls() = 0; virtual void setSelectionUrls(const QList urls) = 0; virtual KrViewItem *getFirst() = 0; virtual KrViewItem *getLast() = 0; virtual KrViewItem *getNext(KrViewItem *current) = 0; virtual KrViewItem *getPrev(KrViewItem *current) = 0; virtual KrViewItem *getCurrentKrViewItem() = 0; virtual KrViewItem *getKrViewItemAt(const QPoint &vp) = 0; virtual KrViewItem *findItemByName(const QString &name) = 0; - virtual KrViewItem *findItemByVfile(vfile *vf) = 0; + virtual KrViewItem *findItemByFileItem(FileItem *vf) = 0; virtual QString getCurrentItem() const = 0; virtual void setCurrentItem(const QString &name, const QModelIndex &fallbackToIndex = QModelIndex()) = 0; virtual void setCurrentKrViewItem(KrViewItem *item) = 0; virtual void makeItemVisible(const KrViewItem *item) = 0; virtual bool isItemVisible(const KrViewItem *item) = 0; virtual void updateView() = 0; virtual void sort() = 0; virtual void refreshColors() = 0; virtual void redraw() = 0; virtual bool handleKeyEvent(QKeyEvent *e); virtual void prepareForActive() = 0; virtual void prepareForPassive() = 0; virtual void renameCurrentItem() = 0; // Rename current item. returns immediately virtual int itemsPerPage() = 0; virtual void showContextMenu(const QPoint &point = QPoint(0, 0)) = 0; protected: - virtual KrViewItem *preAddItem(vfile *vf) = 0; + virtual KrViewItem *preAddItem(FileItem *fileitem) = 0; virtual void preDelItem(KrViewItem *item) = 0; - virtual void preUpdateItem(vfile *vf) = 0; + virtual void preUpdateItem(FileItem *fileitem) = 0; virtual void copySettingsFrom(KrView *other) = 0; - virtual void populate(const QList &vfiles, vfile *dummy) = 0; - virtual void intSetSelected(const vfile *vf, bool select) = 0; + virtual void populate(const QList &fileItems, FileItem *dummy) = 0; + virtual void intSetSelected(const FileItem *fileitem, bool select) = 0; virtual void clear(); - void addItem(vfile *vf); - void updateItem(vfile *vf); + void addItem(FileItem *fileitem); + void updateItem(FileItem *fileitem); void delItem(const QString &name); public: ////////////////////////////////////////////////////// // the following functions are already implemented, // // and normally - should NOT be re-implemented. // ////////////////////////////////////////////////////// uint numFiles() const { return _count - _numDirs; } uint numDirs() const { return _numDirs; } uint count() const { return _count; } void getSelectedItems(QStringList *names, bool ignoreJustFocused = false); void getItemsByMask(QString mask, QStringList *names, bool dirs = true, bool files = true); void getSelectedKrViewItems(KrViewItemList *items); void selectAllIncludingDirs() { changeSelection(KRQuery("*"), true, true); } void select(const KRQuery &filter = KRQuery("*")) { changeSelection(filter, true); } void unselect(const KRQuery &filter = KRQuery("*")) { changeSelection(filter, false); } void unselectAll() { changeSelection(KRQuery("*"), false, true); } void invertSelection(); QString nameToMakeCurrent() const { return _nameToMakeCurrent; } void setNameToMakeCurrent(const QString name) { _nameToMakeCurrent = name; } QString firstUnmarkedBelowCurrent(); QString statistics(); const KrViewProperties *properties() const { return _properties; } KrViewOperator *op() const { return _operator; } void showPreviews(bool show); bool previewsShown() { return _previews != 0; } void applySettingsToOthers(); - void setFiles(VfileContainer *files); + void setFiles(DirListerInterface *files); void refresh(); bool changeSelection(const KRQuery &filter, bool select); bool changeSelection(const KRQuery &filter, bool select, bool includeDirs, bool makeVisible = false); - bool isFiltered(vfile *vf); - void setSelected(const vfile *vf, bool select); + bool isFiltered(FileItem *fileitem); + void setSelected(const FileItem *fileitem, bool select); ///////////////////////////////////////////////////////////// // the following functions have a default and minimalistic // // implementation, and may be re-implemented if needed // ///////////////////////////////////////////////////////////// virtual void setSortMode(KrViewProperties::ColumnType sortColumn, bool descending) { sortModeUpdated(sortColumn, descending); } const KRQuery &filterMask() const { return _properties->filterMask; } KrViewProperties::FilterSpec filter() const { return _properties->filter; } void setFilter(KrViewProperties::FilterSpec filter); void setFilter(KrViewProperties::FilterSpec filter, FilterSettings customFilter, bool applyToDirs); void customSelection(bool select); int defaultFileIconSize(); virtual void setFileIconSize(int size); void setDefaultFileIconSize() { setFileIconSize(defaultFileIconSize()); } void zoomIn(); void zoomOut(); // save this view's settings to be restored after restart virtual void saveSettings(KConfigGroup grp, KrViewProperties::PropertyType properties = KrViewProperties::AllProperties); inline QWidget *widget() { return _widget; } inline int fileIconSize() const { return _fileIconSize; } inline bool isFocused() const { return _focused; } - QPixmap getIcon(vfile *vf); + QPixmap getIcon(FileItem *fileitem); void setMainWindow(QWidget *mainWindow) { _mainWindow = mainWindow; } // save this view's settings as default for new views of this type void saveDefaultSettings( KrViewProperties::PropertyType properties = KrViewProperties::AllProperties); // restore the default settings for this view type void restoreDefaultSettings(); // call this to restore this view's settings after restart void restoreSettings(KConfigGroup grp); void saveSelection(); void restoreSelection(); bool canRestoreSelection() { return !_savedSelection.isEmpty(); } void clearSavedSelection(); void markSameBaseName(); void markSameExtension(); // todo: what about selection modes ??? virtual ~KrView(); - static QPixmap getIcon(vfile *vf, bool active, int size = 0); + static QPixmap getIcon(FileItem *fileitem, bool active, int size = 0); static QPixmap processIcon(const QPixmap &icon, bool dim, const QColor &dimColor, int dimFactor, bool symlink); - static QString krPermissionString(const vfile *vf); + static QString krPermissionString(const FileItem *fileitem); protected: KrView(KrViewInstance &instance, KConfig *cfg); virtual void doRestoreSettings(KConfigGroup grp); virtual KIO::filesize_t calcSize() = 0; virtual KIO::filesize_t calcSelectedSize() = 0; void sortModeUpdated(KrViewProperties::ColumnType sortColumn, bool descending); inline void setWidget(QWidget *w) { _widget = w; } KConfig *_config; KrViewProperties *_properties; KrViewOperator *_operator; bool _focused; int _fileIconSize; private: void updatePreviews(); void saveSortMode(KConfigGroup &group); void restoreSortMode(KConfigGroup &group); KrViewInstance &_instance; - VfileContainer *_files; + DirListerInterface *_files; QWidget *_mainWindow; QWidget *_widget; QList _savedSelection; QString _nameToMakeCurrent; KrPreviews *_previews; bool _updateDefaultSettings; bool _ignoreSettingsChange; QRegExp _quickFilterMask; uint _count, _numDirs; - vfile *_dummyVfile; + FileItem *_dummyFileItem; }; #endif /* KRVIEW_H */ diff --git a/krusader/Panel/krviewitem.cpp b/krusader/Panel/krviewitem.cpp index fd57e781..23f3a55a 100644 --- a/krusader/Panel/krviewitem.cpp +++ b/krusader/Panel/krviewitem.cpp @@ -1,155 +1,155 @@ /***************************************************************************** * Copyright (C) 2000-2002 Shie Erlich * * Copyright (C) 2000-2002 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "krviewitem.h" #include "krinterview.h" #include "krvfsmodel.h" -#include "../VFS/krpermhandler.h" +#include "../FileSystem/krpermhandler.h" // QtCore #include #include #include // QtGui #include #include #define PROPS static_cast(_viewProperties) -KrViewItem::KrViewItem(vfile *vf, KrInterView *parentView): - _vf(vf), _view(parentView), _viewProperties(parentView->properties()), _hasExtension(false), +KrViewItem::KrViewItem(FileItem *fileitem, KrInterView *parentView): + _fileitem(fileitem), _view(parentView), _viewProperties(parentView->properties()), _hasExtension(false), _hidden(false), _extension("") { - dummyVfile = parentView->_model->dummyVfile() == vf; + dummyFileItem = parentView->_model->dummyFileItem() == fileitem; - if (vf) { + if (fileitem) { // check if the file has an extension - const QString& vfName = vf->vfile_getName(); - int loc = vfName.lastIndexOf('.'); + const QString& fileitemName = fileitem->getName(); + int loc = fileitemName.lastIndexOf('.'); if (loc > 0) { // avoid mishandling of .bashrc and friend // check if it has one of the predefined 'atomic extensions' for (QStringList::const_iterator i = PROPS->atomicExtensions.begin(); i != PROPS->atomicExtensions.end(); ++i) { - if (vfName.endsWith(*i)) { - loc = vfName.length() - (*i).length(); + if (fileitemName.endsWith(*i)) { + loc = fileitemName.length() - (*i).length(); break; } } - _name = vfName.left(loc); - _extension = vfName.mid(loc + 1); + _name = fileitemName.left(loc); + _extension = fileitemName.mid(loc + 1); _hasExtension = true; } - if (vfName.startsWith('.')) + if (fileitemName.startsWith('.')) _hidden = true; } } const QString& KrViewItem::name(bool withExtension) const { if (!withExtension && _hasExtension) return _name; - else return _vf->vfile_getName(); + else return _fileitem->getName(); } QString KrViewItem::description() const { - if (dummyVfile) + if (dummyFileItem) return i18n("Climb up the folder tree"); // else is implied - QString text = _vf->vfile_getName(); + QString text = _fileitem->getName(); QString comment; QMimeDatabase db; - QMimeType mt = db.mimeTypeForName(_vf->vfile_getMime()); + QMimeType mt = db.mimeTypeForName(_fileitem->getMime()); if (mt.isValid()) comment = mt.comment(); - QString myLinkDest = _vf->vfile_getSymDest(); - KIO::filesize_t mySize = _vf->vfile_getSize(); + QString myLinkDest = _fileitem->getSymDest(); + KIO::filesize_t mySize = _fileitem->getSize(); QString text2 = text; - mode_t m_fileMode = _vf->vfile_getMode(); + mode_t m_fileMode = _fileitem->getMode(); - if (_vf->vfile_isSymLink()) { + if (_fileitem->isSymLink()) { QString tmp; - if (_vf->vfile_isBrokenLink()) + if (_fileitem->isBrokenLink()) tmp = i18n("(Broken Link)"); else if (comment.isEmpty()) tmp = i18n("Symbolic Link") ; else tmp = i18n("%1 (Link)", comment); text += "->"; text += myLinkDest; text += " "; text += tmp; } else if (S_ISREG(m_fileMode)) { text = QString("%1").arg(text2) + QString(" (%1)").arg(PROPS->humanReadableSize ? - KRpermHandler::parseSize(_vf->vfile_getSize()) : KIO::convertSize(mySize)); + KRpermHandler::parseSize(_fileitem->getSize()) : KIO::convertSize(mySize)); text += " "; text += comment; } else if (S_ISDIR(m_fileMode)) { text += "/ "; - if (_vf->vfile_getSize() != 0) { + if (_fileitem->getSize() != 0) { text += '(' + - (PROPS->humanReadableSize ? KRpermHandler::parseSize(_vf->vfile_getSize()) : KIO::convertSize(mySize)) + ") "; + (PROPS->humanReadableSize ? KRpermHandler::parseSize(_fileitem->getSize()) : KIO::convertSize(mySize)) + ") "; } text += comment; } else { text += " "; text += comment; } return text; } QPixmap KrViewItem::icon() { #if 0 QPixmap *p; // This is bad - very bad. the function must return a valid reference, // This is an interface flow - shie please fix it with a function that return QPixmap* // this way we can return 0 - and do our error checking... // shie answers: why? what's the difference? if we return an empty pixmap, others can use it as it // is, without worrying or needing to do error checking. empty pixmap displays nothing #endif - if (dummyVfile || !_viewProperties->displayIcons) + if (dummyFileItem || !_viewProperties->displayIcons) return QPixmap(); - else return KrView::getIcon(_vf, true); + else return KrView::getIcon(_fileitem, true); } bool KrViewItem::isSelected() const { - return _view->isSelected(_vf); + return _view->isSelected(_fileitem); } void KrViewItem::setSelected(bool s) { - _view->setSelected(_vf, s); + _view->setSelected(_fileitem, s); if(!_view->op()->isMassSelectionUpdate()) { redraw(); _view->op()->emitSelectionChanged(); } } QRect KrViewItem::itemRect() const { - return _view->itemRect(_vf); + return _view->itemRect(_fileitem); } void KrViewItem::redraw() { _view->_itemView->viewport()->update(itemRect()); } diff --git a/krusader/Panel/krviewitem.h b/krusader/Panel/krviewitem.h index bf46e9fb..3b513d0e 100644 --- a/krusader/Panel/krviewitem.h +++ b/krusader/Panel/krviewitem.h @@ -1,97 +1,97 @@ /***************************************************************************** * Copyright (C) 2000-2002 Shie Erlich * * Copyright (C) 2000-2002 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #ifndef KRVIEWITEM_H #define KRVIEWITEM_H -#include "../VFS/vfile.h" +#include "../FileSystem/fileitem.h" #include "krview.h" // QtCore #include #include // QtGui #include #include class KrInterView; /** * @brief A view item representing a file inside a KrView */ class KrViewItem { friend class KrView; friend class KrCalcSpaceDialog; public: - KrViewItem(vfile *vf, KrInterView *parentView); + KrViewItem(FileItem *fileitem, KrInterView *parentView); virtual ~KrViewItem() {} const QString& name(bool withExtension = true) const; inline bool hasExtension() const { return _hasExtension; } inline const QString& extension() const { return _extension; } QString description() const; QPixmap icon(); bool isSelected() const; void setSelected(bool s); QRect itemRect() const; void redraw(); // DON'T USE THOSE OUTSIDE THE VIEWS!!! - inline const vfile* getVfile() const { - return _vf; + inline const FileItem* getFileItem() const { + return _fileitem; } - inline void setVfile(vfile *vf) { - _vf = vf; + inline void setFileItem(FileItem *fileitem) { + _fileitem = fileitem; } - inline vfile* getMutableVfile() { - return _vf; + inline FileItem* getMutableFileItem() { + return _fileitem; } inline bool isDummy() const { - return dummyVfile; + return dummyFileItem; } inline bool isHidden() const { return _hidden; } // used INTERNALLY when calculation of dir size changes the displayed size of the item inline void setSize(KIO::filesize_t size) { - _vf->vfile_setSize(size); + _fileitem->setSize(size); } protected: - vfile* _vf; // each view item holds a pointer to a corresponding vfile for fast access + FileItem* _fileitem; // each view item holds a pointer to a corresponding file item for fast access KrInterView * _view; // the parent view this item belongs to - bool dummyVfile; // used in case our item represents the ".." (updir) item + bool dummyFileItem; // used in case our item represents the ".." (updir) item const KrViewProperties* _viewProperties; bool _hasExtension; bool _hidden; QString _name; QString _extension; }; #endif diff --git a/krusader/Panel/listpanel.cpp b/krusader/Panel/listpanel.cpp index a178be52..ee6016b7 100644 --- a/krusader/Panel/listpanel.cpp +++ b/krusader/Panel/listpanel.cpp @@ -1,1295 +1,1295 @@ /*************************************************************************** listpanel.cpp ------------------- copyright : (C) 2000 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "listpanel.h" // QtCore #include #include #include #include #include #include #include // QtGui #include #include #include #include #include #include #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../defaults.h" #include "../krusader.h" #include "../krslots.h" #include "../kicons.h" #include "../krusaderview.h" #include "../krservices.h" -#include "../VFS/krpermhandler.h" +#include "../FileSystem/krpermhandler.h" #include "../Archive/krarchandler.h" #include "../MountMan/kmountman.h" #include "../BookMan/krbookmarkbutton.h" #include "../Dialogs/krdialogs.h" #include "../Dialogs/krspwidgets.h" #include "../Dialogs/percentalsplitter.h" #include "../Dialogs/popularurls.h" #include "../GUI/kcmdline.h" #include "../GUI/dirhistorybutton.h" #include "../GUI/mediabutton.h" #include "../GUI/syncbrowsebutton.h" #include "../UserAction/useractionpopupmenu.h" #include "listpanelactions.h" #include "viewactions.h" #include "krpreviewpopup.h" #include "panelpopup.h" #include "panelfunc.h" #include "krpopupmenu.h" #include "krviewfactory.h" #include "krcolorcache.h" #include "krerrordisplay.h" #include "krlayoutfactory.h" #include "krsearchbar.h" #include "dirhistoryqueue.h" class ActionButton : public QToolButton { public: ActionButton(QWidget *parent, ListPanel *panel, QAction *action, QString text = QString()) : QToolButton(parent), panel(panel), action(action) { setText(text); setAutoRaise(true); if(KConfigGroup(krConfig, "ListPanelButtons").readEntry("Icons", false) || text.isEmpty()) setIcon(action->icon()); setToolTip(action->toolTip()); } protected: virtual void mousePressEvent(QMouseEvent *) Q_DECL_OVERRIDE { panel->slotFocusOnMe(); action->trigger(); } ListPanel *panel; QAction *action; }; ///////////////////////////////////////////////////// // The list panel constructor // ///////////////////////////////////////////////////// ListPanel::ListPanel(QWidget *parent, AbstractPanelManager *manager, KConfigGroup cfg) : QWidget(parent), KrPanel(manager), panelType(-1), colorMask(255), compareMode(false), previewJob(0), inlineRefreshJob(0), searchBar(0), cdRootButton(0), cdUpButton(0), - popupBtn(0), popup(0), vfsError(0), _locked(false) + popupBtn(0), popup(0), fileSystemError(0), _locked(false) { if(cfg.isValid()) panelType = cfg.readEntry("Type", -1); if (panelType == -1) panelType = defaultPanelType(); gui = this; func = new ListPanelFunc(this); _actions = krApp->listPanelActions(); setAcceptDrops(true); QHash widgets; #define ADD_WIDGET(widget) widgets.insert(#widget, widget); // media button mediaButton = new MediaButton(this); connect(mediaButton, SIGNAL(aboutToShow()), this, SLOT(slotFocusOnMe())); connect(mediaButton, SIGNAL(openUrl(const QUrl&)), func, SLOT(openUrl(const QUrl&))); connect(mediaButton, SIGNAL(newTab(const QUrl&)), SLOT(newTab(const QUrl&))); ADD_WIDGET(mediaButton); // status bar status = new KrSqueezedTextLabel(this); KConfigGroup group(krConfig, "Look&Feel"); status->setFont(group.readEntry("Filelist Font", _FilelistFont)); status->setAutoFillBackground(false); status->setText(""); // needed for initialization code! status->setWhatsThis(i18n("The statusbar displays information about the filesystem " "which holds your current folder: total size, free space, " "type of filesystem, etc.")); ADD_WIDGET(status); // back button backButton = new ActionButton(this, this, _actions->actHistoryBackward); ADD_WIDGET(backButton); // forward button forwardButton = new ActionButton(this, this, _actions->actHistoryForward); ADD_WIDGET(forwardButton); // ... create the history button historyButton = new DirHistoryButton(func->history, this); connect(historyButton, SIGNAL(aboutToShow()), this, SLOT(slotFocusOnMe())); connect(historyButton, SIGNAL(gotoPos(int)), func, SLOT(historyGotoPos(int))); ADD_WIDGET(historyButton); // bookmarks button bookmarksButton = new KrBookmarkButton(this); connect(bookmarksButton, SIGNAL(aboutToShow()), this, SLOT(slotFocusOnMe())); connect(bookmarksButton, SIGNAL(openUrl(const QUrl&)), func, SLOT(openUrl(const QUrl&))); bookmarksButton->setWhatsThis(i18n("Open menu with bookmarks. You can also add " "current location to the list, edit bookmarks " "or add subfolder to the list.")); ADD_WIDGET(bookmarksButton); // url input field urlNavigator = new KUrlNavigator(new KFilePlacesModel(this), QUrl(), this); urlNavigator->setWhatsThis(i18n("Name of folder where you are. You can also " "enter name of desired location to move there. " "Use of Net protocols like ftp or fish is possible.")); // handle certain key events here in event filter urlNavigator->editor()->installEventFilter(this); urlNavigator->setUrlEditable(isNavigatorEditModeSet()); urlNavigator->setShowFullPath(group.readEntry("Navigator Full Path", false)); connect(urlNavigator, SIGNAL(returnPressed()), this, SLOT(slotFocusOnMe())); connect(urlNavigator, SIGNAL(urlChanged(QUrl)), func, SLOT(navigatorUrlChanged(QUrl))); connect(urlNavigator->editor()->lineEdit(), SIGNAL(editingFinished()), this, SLOT(resetNavigatorMode())); connect(urlNavigator, SIGNAL(tabRequested(QUrl)), this, SLOT(newTab(QUrl))); connect(urlNavigator, SIGNAL(urlsDropped(QUrl, QDropEvent*)), this, SLOT(handleDrop(QUrl, QDropEvent*))); ADD_WIDGET(urlNavigator); // toolbar QWidget * toolbar = new QWidget(this); QHBoxLayout * toolbarLayout = new QHBoxLayout(toolbar); toolbarLayout->setContentsMargins(0, 0, 0, 0); toolbarLayout->setSpacing(0); ADD_WIDGET(toolbar); - vfsError = new KrErrorDisplay(this); - vfsError->setWordWrap(true); - vfsError->hide(); - ADD_WIDGET(vfsError); + fileSystemError = new KrErrorDisplay(this); + fileSystemError->setWordWrap(true); + fileSystemError->hide(); + ADD_WIDGET(fileSystemError); // client area clientArea = new QWidget(this); QVBoxLayout *clientLayout = new QVBoxLayout(clientArea); clientLayout->setSpacing(0); clientLayout->setContentsMargins(0, 0, 0, 0); ADD_WIDGET(clientArea); // totals label totals = new KrSqueezedTextLabel(this); totals->setFont(group.readEntry("Filelist Font", _FilelistFont)); totals->setAutoFillBackground(false); totals->setWhatsThis(i18n("The totals bar shows how many files exist, " "how many selected and the bytes math")); ADD_WIDGET(totals); // free space label freeSpace = new KrSqueezedTextLabel(this); freeSpace->setFont(group.readEntry("Filelist Font", _FilelistFont)); freeSpace->setAutoFillBackground(false); freeSpace->setText(""); freeSpace->setAlignment(Qt::AlignRight | Qt::AlignVCenter); ADD_WIDGET(freeSpace); // progress indicator for the preview job previewProgress = new QProgressBar(this); previewProgress->hide(); ADD_WIDGET(previewProgress); // a cancel button for the inplace refresh mechanism inlineRefreshCancelButton = new QToolButton(this); inlineRefreshCancelButton->hide(); inlineRefreshCancelButton->setIcon(krLoader->loadIcon("dialog-cancel", KIconLoader::Toolbar, 16)); connect(inlineRefreshCancelButton, SIGNAL(clicked()), this, SLOT(inlineRefreshCancel())); ADD_WIDGET(inlineRefreshCancelButton); // button for changing the panel popup position in the panel popupPositionBtn = new QToolButton(this); popupPositionBtn->hide(); popupPositionBtn->setAutoRaise(true); popupPositionBtn->setIcon(krLoader->loadIcon("exchange-positions", KIconLoader::Toolbar, 16)); popupPositionBtn->setToolTip(i18n("Move popup panel clockwise")); connect(popupPositionBtn, &QToolButton::clicked, [this]() { // moving position clockwise setPopupPosition((popupPosition() + 1) % 4); }); ADD_WIDGET(popupPositionBtn); // a quick button to open the popup panel popupBtn = new QToolButton(this); popupBtn->setAutoRaise(true); popupBtn->setIcon(krLoader->loadIcon("arrow-up", KIconLoader::Toolbar, 16)); connect(popupBtn, SIGNAL(clicked()), this, SLOT(togglePanelPopup())); popupBtn->setToolTip(i18n("Open the popup panel")); ADD_WIDGET(popupBtn); #undef ADD_WIDGET // toolbar buttons cdOtherButton = new ActionButton(toolbar, this, _actions->actCdToOther, "="); toolbarLayout->addWidget(cdOtherButton); cdUpButton = new ActionButton(toolbar, this, _actions->actDirUp, ".."); toolbarLayout->addWidget(cdUpButton); cdHomeButton = new ActionButton(toolbar, this, _actions->actHome, "~"); toolbarLayout->addWidget(cdHomeButton); cdRootButton = new ActionButton(toolbar, this, _actions->actRoot, "/"); toolbarLayout->addWidget(cdRootButton); // ... creates the button for sync-browsing syncBrowseButton = new SyncBrowseButton(toolbar); syncBrowseButton->setAutoRaise(true); toolbarLayout->addWidget(syncBrowseButton); setButtons(); // create a splitter to hold the view and the popup splt = new PercentalSplitter(clientArea); splt->setChildrenCollapsible(true); splt->setOrientation(Qt::Vertical); // expand vertical if splitter orientation is horizontal QSizePolicy sizePolicy = splt->sizePolicy(); sizePolicy.setVerticalPolicy(QSizePolicy::Expanding); splt->setSizePolicy(sizePolicy); clientLayout->addWidget(splt); // view createView(); // search (in folder) bar searchBar = new KrSearchBar(view, clientArea); searchBar->hide(); bool top = group.readEntry("Quicksearch Position", "bottom") == "top"; clientLayout->insertWidget(top ? 0 : -1, searchBar); // create the layout KrLayoutFactory fact(this, widgets); QLayout *layout = fact.createLayout(); if(!layout) { // fallback: create a layout by ourself QVBoxLayout *v = new QVBoxLayout; v->setContentsMargins(0, 0, 0, 0); v->setSpacing(0); QHBoxLayout *h = new QHBoxLayout; h->setContentsMargins(0, 0, 0, 0); h->setSpacing(0); h->addWidget(urlNavigator); h->addWidget(toolbar); h->addStretch(); v->addLayout(h); h = new QHBoxLayout; h->setContentsMargins(0, 0, 0, 0); h->setSpacing(0); h->addWidget(mediaButton); h->addWidget(status); h->addWidget(backButton); h->addWidget(forwardButton); h->addWidget(historyButton); h->addWidget(bookmarksButton); v->addLayout(h); - v->addWidget(vfsError); + v->addWidget(fileSystemError); v->addWidget(clientArea); h = new QHBoxLayout; h->setContentsMargins(0, 0, 0, 0); h->setSpacing(0); h->addWidget(totals); h->addWidget(freeSpace); h->addWidget(previewProgress); h->addWidget(inlineRefreshCancelButton); h->addWidget(popupBtn); v->addLayout(h); layout = v; } setLayout(layout); connect(&KrColorCache::getColorCache(), SIGNAL(colorsRefreshed()), this, SLOT(refreshColors())); connect(krApp, SIGNAL(shutdown()), SLOT(inlineRefreshCancel())); } ListPanel::~ListPanel() { inlineRefreshCancel(); delete view; view = 0; delete func; delete status; delete bookmarksButton; delete totals; delete urlNavigator; delete cdRootButton; delete cdHomeButton; delete cdUpButton; delete cdOtherButton; delete syncBrowseButton; // delete layout; } void ListPanel::reparent(QWidget *parent, AbstractPanelManager *manager) { setParent(parent); _manager = manager; } int ListPanel::defaultPanelType() { KConfigGroup group(krConfig, "Look&Feel"); return group.readEntry("Default Panel Type", KrViewFactory::defaultViewId()); } bool ListPanel::isNavigatorEditModeSet() { KConfigGroup group(krConfig, "Look&Feel"); return group.readEntry("Navigator Edit Mode", false); } void ListPanel::createView() { view = KrViewFactory::createView(panelType, splt, krConfig); view->init(); view->setMainWindow(krApp); // KrViewFactory may create a different view type than requested panelType = view->instance()->id(); if(this == ACTIVE_PANEL) view->prepareForActive(); else view->prepareForPassive(); view->refreshColors(); splt->insertWidget(popupPosition() < 2 ? 1 : 0, view->widget()); view->widget()->installEventFilter(this); connect(view->op(), SIGNAL(calcSpace(KrViewItem*)), func, SLOT(calcSpace(KrViewItem*))); connect(view->op(), SIGNAL(goHome()), func, SLOT(home())); connect(view->op(), SIGNAL(dirUp()), func, SLOT(dirUp())); connect(view->op(), SIGNAL(deleteFiles(bool)), func, SLOT(deleteFiles(bool))); connect(view->op(), SIGNAL(middleButtonClicked(KrViewItem *)), SLOT(newTab(KrViewItem *))); connect(view->op(), SIGNAL(currentChanged(KrViewItem *)), SLOT(slotCurrentChanged(KrViewItem*))); connect(view->op(), SIGNAL(renameItem(const QString &, const QString &)), func, SLOT(rename(const QString &, const QString &))); connect(view->op(), SIGNAL(executed(const QString&)), func, SLOT(execute(const QString&))); connect(view->op(), SIGNAL(goInside(const QString&)), func, SLOT(goInside(const QString&))); connect(view->op(), SIGNAL(needFocus()), this, SLOT(slotFocusOnMe())); connect(view->op(), SIGNAL(selectionChanged()), this, SLOT(slotUpdateTotals())); connect(view->op(), SIGNAL(itemDescription(const QString&)), krApp, SLOT(statusBarUpdate(const QString&))); connect(view->op(), SIGNAL(contextMenu(const QPoint &)), this, SLOT(popRightClickMenu(const QPoint &))); connect(view->op(), SIGNAL(emptyContextMenu(const QPoint &)), this, SLOT(popEmptyRightClickMenu(const QPoint &))); connect(view->op(), SIGNAL(letsDrag(QStringList, QPixmap)), this, SLOT(startDragging(QStringList, QPixmap))); connect(view->op(), &KrViewOperator::gotDrop, this, [this](QDropEvent *event) {handleDrop(event, true); }); connect(view->op(), SIGNAL(previewJobStarted(KJob*)), this, SLOT(slotPreviewJobStarted(KJob*))); connect(view->op(), SIGNAL(refreshActions()), krApp->viewActions(), SLOT(refreshActions())); connect(view->op(), SIGNAL(currentChanged(KrViewItem*)), func->history, SLOT(saveCurrentItem())); connect(view->op(), &KrViewOperator::goBack, func, &ListPanelFunc::historyBackward); connect(view->op(), &KrViewOperator::goForward, func, &ListPanelFunc::historyForward); view->setFiles(func->files()); func->refreshActions(); } void ListPanel::changeType(int type) { if (panelType != type) { QString current = view->getCurrentItem(); QList selection = view->selectedUrls(); bool filterApplysToDirs = view->properties()->filterApplysToDirs; KrViewProperties::FilterSpec filter = view->filter(); FilterSettings filterSettings = view->properties()->filterSettings; panelType = type; KrView *oldView = view; createView(); searchBar->setView(view); delete oldView; view->setFilter(filter, filterSettings, filterApplysToDirs); view->setSelectionUrls(selection); view->setCurrentItem(current); view->makeItemVisible(view->getCurrentKrViewItem()); } } int ListPanel::getProperties() { int props = 0; if (syncBrowseButton->state() == SYNCBROWSE_CD) props |= PROP_SYNC_BUTTON_ON; if (_locked) props |= PROP_LOCKED; return props; } void ListPanel::setProperties(int prop) { syncBrowseButton->setChecked(prop & PROP_SYNC_BUTTON_ON); _locked = (prop & PROP_LOCKED); } bool ListPanel::eventFilter(QObject * watched, QEvent * e) { if(view && watched == view->widget()) { if(e->type() == QEvent::FocusIn && this != ACTIVE_PANEL && !isHidden()) slotFocusOnMe(); else if(e->type() == QEvent::ShortcutOverride) { QKeyEvent *ke = static_cast(e); if(ke->key() == Qt::Key_Escape && ke->modifiers() == Qt::NoModifier) { // if the cancel refresh action has no shortcut assigned, // we need this event ourselves to cancel refresh if(_actions->actCancelRefresh->shortcut().isEmpty()) { e->accept(); return true; } } } } // handle URL navigator key events else if(watched == urlNavigator->editor()) { // override default shortcut for panel focus if(e->type() == QEvent::ShortcutOverride) { QKeyEvent *ke = static_cast(e); if ((ke->key() == Qt::Key_Escape) && (ke->modifiers() == Qt::NoModifier)) { e->accept(); // we will get the key press event now return true; } } else if(e->type() == QEvent::KeyPress) { QKeyEvent *ke = static_cast(e); if ((ke->key() == Qt::Key_Down) && (ke->modifiers() == Qt::ControlModifier)) { slotFocusOnMe(); return true; } else if ((ke->key() == Qt::Key_Escape) && (ke->modifiers() == Qt::NoModifier)) { // reset navigator urlNavigator->editor()->setUrl(urlNavigator->locationUrl()); slotFocusOnMe(); return true; } } } return false; } void ListPanel::togglePanelPopup() { if(!popup) { popup = new PanelPopup(splt, isLeft(), krApp); // fix vertical grow of splitter (and entire window) if its content // demands more space QSizePolicy sizePolicy = popup->sizePolicy(); sizePolicy.setVerticalPolicy(QSizePolicy::Ignored); popup->setSizePolicy(sizePolicy); connect(this, SIGNAL(pathChanged(const QUrl&)), popup, SLOT(onPanelPathChange(const QUrl&))); connect(popup, SIGNAL(selection(const QUrl&)), SLOTS, SLOT(refresh(const QUrl&))); connect(popup, SIGNAL(hideMe()), this, SLOT(togglePanelPopup())); } if (popup->isHidden()) { if (popupSizes.count() > 0) { splt->setSizes(popupSizes); } else { // on the first time, resize to 50% QList lst; lst << height() / 2 << height() / 2; splt->setSizes(lst); } popup->show(); popupBtn->setIcon(krLoader->loadIcon("arrow-down", KIconLoader::Toolbar, 16)); popupBtn->setToolTip(i18n("Close the popup panel")); popupPositionBtn->show(); } else { popupSizes.clear(); popupSizes = splt->sizes(); popup->hide(); popupBtn->setIcon(krLoader->loadIcon("arrow-up", KIconLoader::Toolbar, 16)); popupBtn->setToolTip(i18n("Open the popup panel")); popupPositionBtn->hide(); QList lst; lst << height() << 0; splt->setSizes(lst); if (ACTIVE_PANEL) ACTIVE_PANEL->gui->slotFocusOnMe(); } } QString ListPanel::realPath() const { return _realPath.path(); } void ListPanel::setButtons() { KConfigGroup group(krConfig, "Look&Feel"); mediaButton->setVisible(group.readEntry("Media Button Visible", true)); backButton->setVisible(group.readEntry("Back Button Visible", false)); forwardButton->setVisible(group.readEntry("Forward Button Visible", false)); historyButton->setVisible(group.readEntry("History Button Visible", true)); bookmarksButton->setVisible(group.readEntry("Bookmarks Button Visible", true)); if (group.readEntry("Panel Toolbar visible", _PanelToolBar)) { cdRootButton->setVisible(group.readEntry("Root Button Visible", _cdRoot)); cdHomeButton->setVisible(group.readEntry("Home Button Visible", _cdHome)); cdUpButton->setVisible(group.readEntry("Up Button Visible", _cdUp)); cdOtherButton->setVisible(group.readEntry("Equal Button Visible", _cdOther)); syncBrowseButton->setVisible(group.readEntry("SyncBrowse Button Visible", _syncBrowseButton)); } else { cdRootButton->hide(); cdHomeButton->hide(); cdUpButton->hide(); cdOtherButton->hide(); syncBrowseButton->hide(); } } void ListPanel::slotUpdateTotals() { totals->setText(view->statistics()); } void ListPanel::compareDirs(bool otherPanelToo) { // Performs a check in order to avoid that the next code is executed twice if (otherPanelToo == true) { // If both panels are showing the same directory if (_manager->currentPanel()->virtualPath() == otherPanel()->virtualPath()) { if (KMessageBox::warningContinueCancel(this, i18n("Warning: The left and the right side are showing the same folder.")) != KMessageBox::Continue) { return; } } } KConfigGroup pg(krConfig, "Private"); int compareMode = pg.readEntry("Compare Mode", 0); KConfigGroup group(krConfig, "Look&Feel"); bool selectDirs = group.readEntry("Mark Dirs", false); KrViewItem *item, *otherItem; for (item = view->getFirst(); item != 0; item = view->getNext(item)) { if (item->name() == "..") continue; for (otherItem = otherPanel()->view->getFirst(); otherItem != 0 && otherItem->name() != item->name() ; otherItem = otherPanel()->view->getNext(otherItem)); bool isSingle = (otherItem == 0), isDifferent = false, isNewer = false; - if (func->getVFile(item)->vfile_isDir() && !selectDirs) { + if (func->getFileItem(item)->isDir() && !selectDirs) { item->setSelected(false); continue; } if (otherItem) { - if (!func->getVFile(item)->vfile_isDir()) - isDifferent = ITEM2VFILE(otherPanel(), otherItem)->vfile_getSize() != func->getVFile(item)->vfile_getSize(); - isNewer = func->getVFile(item)->vfile_getTime_t() > ITEM2VFILE(otherPanel(), otherItem)->vfile_getTime_t(); + if (!func->getFileItem(item)->isDir()) + isDifferent = ITEM2FILEITEM(otherPanel(), otherItem)->getSize() != func->getFileItem(item)->getSize(); + isNewer = func->getFileItem(item)->getTime_t() > ITEM2FILEITEM(otherPanel(), otherItem)->getTime_t(); } switch (compareMode) { case 0: item->setSelected(isNewer || isSingle); break; case 1: item->setSelected(isNewer); break; case 2: item->setSelected(isSingle); break; case 3: item->setSelected(isDifferent || isSingle); break; case 4: item->setSelected(isDifferent); break; } } view->updateView(); if (otherPanelToo) otherPanel()->gui->compareDirs(false); } void ListPanel::refreshColors() { view->refreshColors(); emit refreshColors(this == ACTIVE_PANEL); } void ListPanel::slotFocusOnMe(bool focus) { if (focus && _manager->currentPanel() != this) { // ignore focus request if this panel is not shown return; } krApp->setUpdatesEnabled(false); if(focus) { emit activate(); _actions->activePanelChanged(); func->refreshActions(); slotCurrentChanged(view->getCurrentKrViewItem()); view->prepareForActive(); otherPanel()->gui->slotFocusOnMe(false); } else { // in case a new url was entered but not refreshed to, // reset url navigator to the current url urlNavigator->setLocationUrl(virtualPath()); view->prepareForPassive(); } urlNavigator->setActive(focus); refreshColors(); emit refreshPathLabel(); krApp->setUpdatesEnabled(true); } // this is used to start the panel ////////////////////////////////////////////////////////////////// void ListPanel::start(QUrl url, bool immediate) { QUrl virt(url); if (!virt.isValid()) virt = QUrl::fromLocalFile(ROOT_DIR); if (virt.isLocalFile()) _realPath = virt; else _realPath = QUrl::fromLocalFile(ROOT_DIR); if (immediate) func->immediateOpenUrl(virt, true); else func->openUrl(virt); setJumpBack(virt); } void ListPanel::slotStartUpdate(bool directoryChange) { if (inlineRefreshJob) inlineRefreshListResult(0); setCursor(Qt::BusyCursor); const QUrl currentUrl = virtualPath(); if (directoryChange) { if (this == ACTIVE_PANEL) { slotFocusOnMe(); } if (func->files()->isLocal()) _realPath = currentUrl; urlNavigator->setLocationUrl(currentUrl); emit pathChanged(currentUrl); krApp->popularUrls()->addUrl(currentUrl); searchBar->hideBar(); } if (compareMode) otherPanel()->view->refresh(); // return cursor to normal arrow setCursor(Qt::ArrowCursor); slotUpdateTotals(); } void ListPanel::updateFilesystemStats(const QString &metaInfo, const QString &fsType, KIO::filesize_t total, KIO::filesize_t free) { QString statusText, mountPoint, freeSpaceText; if (!metaInfo.isEmpty()) { statusText = metaInfo; mountPoint = freeSpaceText = ""; } else { const int perc = total == 0 ? 0 : (int)(((float)free / (float)total) * 100.0); mountPoint = func->files()->mountPoint(); statusText = i18nc("%1=free space,%2=total space,%3=percentage of usage, " "%4=mountpoint,%5=filesystem type", "%1 free out of %2 (%3%) on %4 [(%5)]", KIO::convertSize(free), KIO::convertSize(total), perc, mountPoint, fsType); freeSpaceText = " " + i18n("%1 free", KIO::convertSize(free)); } status->setText(statusText); freeSpace->setText(freeSpaceText); mediaButton->updateIcon(mountPoint); } void ListPanel::handleDrop(QDropEvent *event, bool onView) { // check what was dropped const QList urls = KUrlMimeData::urlsFromMimeData(event->mimeData()); if (urls.isEmpty()) { event->ignore(); // not for us to handle! return; } // find dropping destination QString destinationDir = ""; const bool dragFromThisPanel = event->source() == this; const KrViewItem *item = onView ? view->getKrViewItemAt(event->pos()) : 0; if (item) { - const vfile *file = item->getVfile(); - if (file && !file->vfile_isDir() && dragFromThisPanel) { + const FileItem *file = item->getFileItem(); + if (file && !file->isDir() && dragFromThisPanel) { event->ignore(); // dragging on files in same panel, ignore return ; - } else if (!file || file->vfile_isDir()) { // item is ".." dummy or a directory + } else if (!file || file->isDir()) { // item is ".." dummy or a directory destinationDir = item->name(); } } else if (dragFromThisPanel) { event->ignore(); // dragged from this panel onto an empty spot in this panel, ignore return ; } QUrl destination = QUrl(virtualPath()); destination.setPath(destination.path() + '/' + destinationDir); func->files()->dropFiles(destination, event); if(KConfigGroup(krConfig, "Look&Feel").readEntry("UnselectBeforeOperation", _UnselectBeforeOperation)) { KrPanel *p = dragFromThisPanel ? this : otherPanel(); p->view->saveSelection(); p->view->unselectAll(); } } void ListPanel::handleDrop(const QUrl &destination, QDropEvent *event) { func->files()->dropFiles(destination, event); } void ListPanel::startDragging(QStringList names, QPixmap px) { if (names.isEmpty()) { // avoid dragging empty urls return; } QList urls = func->files()->getUrls(names); QDrag *drag = new QDrag(this); QMimeData *mimeData = new QMimeData; drag->setPixmap(px); mimeData->setUrls(urls); drag->setMimeData(mimeData); drag->start(Qt::MoveAction | Qt::CopyAction | Qt::LinkAction); } // pops a right-click menu for items void ListPanel::popRightClickMenu(const QPoint &loc) { // run it, on the mouse location int j = QFontMetrics(font()).height() * 2; KrPopupMenu::run(QPoint(loc.x() + 5, loc.y() + j), this); } void ListPanel::popEmptyRightClickMenu(const QPoint &loc) { KrPopupMenu::run(loc, this); } QString ListPanel::getCurrentName() { QString name = view->getCurrentItem(); if (name != "..") return name; else return QString(); } void ListPanel::prepareToDelete() { view->setNameToMakeCurrent(view->firstUnmarkedBelowCurrent()); } void ListPanel::keyPressEvent(QKeyEvent *e) { switch (e->key()) { case Qt::Key_Enter : case Qt::Key_Return : if (e->modifiers() & Qt::ControlModifier) { if (e->modifiers() & Qt::AltModifier) { - vfile *vf = func->files()->getVfile(view->getCurrentKrViewItem()->name()); - if (vf && vf->vfile_isDir()) - newTab(vf->vfile_getUrl(), true); + FileItem *fileitem = func->files()->getFileItem(view->getCurrentKrViewItem()->name()); + if (fileitem && fileitem->isDir()) + newTab(fileitem->getUrl(), true); } else { SLOTS->insertFileName((e->modifiers() & Qt::ShiftModifier) != 0); } } else e->ignore(); break; case Qt::Key_Right : case Qt::Key_Left : if (e->modifiers() == Qt::ControlModifier) { // user pressed CTRL+Right/Left - refresh other panel to the selected path if it's a // directory otherwise as this one if ((isLeft() && e->key() == Qt::Key_Right) || (!isLeft() && e->key() == Qt::Key_Left)) { QUrl newPath; KrViewItem *it = view->getCurrentKrViewItem(); if (it->name() == "..") { newPath = KIO::upUrl(func->files()->currentDirectory()); } else { - vfile *v = func->getVFile(it); + FileItem *v = func->getFileItem(it); // If it's a directory different from ".." - if (v && v->vfile_isDir() && v->vfile_getName() != "..") { - newPath = v->vfile_getUrl(); + if (v && v->isDir() && v->getName() != "..") { + newPath = v->getUrl(); } else { // If it's a supported compressed file - if (v && KRarcHandler::arcSupported(v->vfile_getMime())) { - newPath = func->browsableArchivePath(v->vfile_getUrl().fileName()); + if (v && KRarcHandler::arcSupported(v->getMime())) { + newPath = func->browsableArchivePath(v->getUrl().fileName()); } else { newPath = func->files()->currentDirectory(); } } } otherPanel()->func->openUrl(newPath); } else { func->openUrl(otherPanel()->func->files()->currentDirectory()); } return ; } else e->ignore(); break; case Qt::Key_Down : if (e->modifiers() == Qt::ControlModifier) { // give the keyboard focus to the command line if (MAIN_VIEW->cmdLine()->isVisible()) MAIN_VIEW->cmdLineFocus(); else MAIN_VIEW->focusTerminalEmulator(); return ; } else if (e->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) { // give the keyboard focus to TE MAIN_VIEW->focusTerminalEmulator(); } else e->ignore(); break; case Qt::Key_Up : if (e->modifiers() == Qt::ControlModifier) { // give the keyboard focus to the url navigator editLocation(); return ; } else e->ignore(); break; case Qt::Key_Escape: inlineRefreshCancel(); break; default: // if we got this, it means that the view is not doing // the quick search thing, so send the characters to the commandline, if normal key if (e->modifiers() == Qt::NoModifier) MAIN_VIEW->cmdLine()->addText(e->text()); //e->ignore(); } } void ListPanel::showEvent(QShowEvent *e) { panelActive(); QWidget::showEvent(e); } void ListPanel::hideEvent(QHideEvent *e) { panelInactive(); QWidget::hideEvent(e); } void ListPanel::panelActive() { - //func->files()->vfs_enableRefresh(true) + //func->files()->enableRefresh(true) } void ListPanel::panelInactive() { // don't refresh when not active (ie: hidden, application isn't focused ...) // TODO disabled so that the user sees changes in non-focused window; if the performance impact // is too high we need another solution here - //func->files()->vfs_enableRefresh(false); + //func->files()->enableRefresh(false); } void ListPanel::slotPreviewJobStarted(KJob *job) { previewJob = job; previewProgress->setValue(0); previewProgress->setFormat(i18n("loading previews: %p%")); previewProgress->show(); inlineRefreshCancelButton->show(); previewProgress->setMaximumHeight(inlineRefreshCancelButton->height()); connect(job, SIGNAL(percent(KJob*, unsigned long)), SLOT(slotPreviewJobPercent(KJob*, unsigned long))); connect(job, SIGNAL(result(KJob*)), SLOT(slotPreviewJobResult(KJob*))); } void ListPanel::slotPreviewJobPercent(KJob* /*job*/, unsigned long percent) { previewProgress->setValue(percent); } void ListPanel::slotPreviewJobResult(KJob* /*job*/) { previewJob = 0; previewProgress->hide(); if(!inlineRefreshJob) inlineRefreshCancelButton->hide(); } void ListPanel::slotJobStarted(KIO::Job* job) { // disable the parts of the panel we don't want touched status->setEnabled(false); urlNavigator->setEnabled(false); cdRootButton->setEnabled(false); cdHomeButton->setEnabled(false); cdUpButton->setEnabled(false); cdOtherButton->setEnabled(false); popupBtn->setEnabled(false); if(popup) popup->setEnabled(false); bookmarksButton->setEnabled(false); historyButton->setEnabled(false); syncBrowseButton->setEnabled(false); // connect to the job interface to provide in-panel refresh notification connect(job, SIGNAL(infoMessage(KJob*, const QString &)), SLOT(inlineRefreshInfoMessage(KJob*, const QString &))); connect(job, SIGNAL(percent(KJob*, unsigned long)), SLOT(inlineRefreshPercent(KJob*, unsigned long))); connect(job, SIGNAL(result(KJob*)), this, SLOT(inlineRefreshListResult(KJob*))); inlineRefreshJob = job; totals->setText(i18n(">> Reading...")); inlineRefreshCancelButton->show(); } void ListPanel::inlineRefreshCancel() { if (inlineRefreshJob) { disconnect(inlineRefreshJob, 0, this, 0); inlineRefreshJob->kill(KJob::EmitResult); inlineRefreshListResult(0); } if(previewJob) { disconnect(previewJob, 0, this, 0); previewJob->kill(KJob::EmitResult); slotPreviewJobResult(0); } } void ListPanel::inlineRefreshPercent(KJob*, unsigned long perc) { QString msg = i18n(">> Reading: %1 % complete...", perc); totals->setText(msg); } void ListPanel::inlineRefreshInfoMessage(KJob*, const QString &msg) { totals->setText(i18n(">> Reading: %1", msg)); } void ListPanel::inlineRefreshListResult(KJob*) { if(inlineRefreshJob) disconnect(inlineRefreshJob, 0, this, 0); inlineRefreshJob = 0; // reenable everything status->setEnabled(true); urlNavigator->setEnabled(true); cdRootButton->setEnabled(true); cdHomeButton->setEnabled(true); cdUpButton->setEnabled(true); cdOtherButton->setEnabled(true); popupBtn->setEnabled(true); if(popup) popup->setEnabled(true); bookmarksButton->setEnabled(true); historyButton->setEnabled(true); syncBrowseButton->setEnabled(true); if(!previewJob) inlineRefreshCancelButton->hide(); } void ListPanel::jumpBack() { func->openUrl(_jumpBackURL); } void ListPanel::setJumpBack(QUrl url) { _jumpBackURL = url; } -void ListPanel::slotVfsError(QString msg) +void ListPanel::slotFilesystemError(QString msg) { - if (func->ignoreVFSErrors()) + if (func->ignoreFileSystemErrors()) return; refreshColors(); - vfsError->setText(i18n("Error: %1", msg)); - vfsError->show(); + fileSystemError->setText(i18n("Error: %1", msg)); + fileSystemError->show(); } void ListPanel::showButtonMenu(QToolButton *b) { if(this != ACTIVE_PANEL) slotFocusOnMe(); if(b->isHidden()) b->menu()->exec(mapToGlobal(clientArea->pos())); else b->click(); } void ListPanel::openBookmarks() { showButtonMenu(bookmarksButton); } void ListPanel::openHistory() { showButtonMenu(historyButton); } void ListPanel::openMedia() { showButtonMenu(mediaButton); } void ListPanel::rightclickMenu() { if (view->getCurrentKrViewItem()) popRightClickMenu(mapToGlobal(view->getCurrentKrViewItem()->itemRect().topLeft())); } void ListPanel::toggleSyncBrowse() { syncBrowseButton->toggle(); } void ListPanel::editLocation() { urlNavigator->setUrlEditable(true); urlNavigator->setFocus(); urlNavigator->editor()->lineEdit()->selectAll(); } void ListPanel::showSearchBar() { searchBar->showBar(); } void ListPanel::showSearchFilter() { searchBar->showBar(KrSearchBar::MODE_FILTER); } void ListPanel::saveSettings(KConfigGroup cfg, bool saveHistory) { QUrl url = virtualPath(); url.setPassword(QString()); // make sure no password is saved cfg.writeEntry("Url", url.toString()); cfg.writeEntry("Type", getType()); cfg.writeEntry("Properties", getProperties()); if(saveHistory) func->history->save(KConfigGroup(&cfg, "History")); view->saveSettings(KConfigGroup(&cfg, "View")); // splitter/popup state if (popup && !popup->isHidden()) { popup->saveSettings(KConfigGroup(&cfg, "PanelPopup")); cfg.writeEntry("PopupPosition", popupPosition()); cfg.writeEntry("SplitterSizes", splt->saveState()); cfg.writeEntry("PopupPage", popup->currentPage()); } else { cfg.deleteEntry("PopupPosition"); cfg.deleteEntry("SplitterSizes"); cfg.deleteEntry("PopupPage"); } } void ListPanel::restoreSettings(KConfigGroup cfg) { changeType(cfg.readEntry("Type", defaultPanelType())); setProperties(cfg.readEntry("Properties", 0)); view->restoreSettings(KConfigGroup(&cfg, "View")); _realPath = QUrl::fromLocalFile(ROOT_DIR); if(func->history->restore(KConfigGroup(&cfg, "History"))) func->refresh(); else { QUrl url(cfg.readEntry("Url", ROOT_DIR)); if (!url.isValid()) url = QUrl::fromLocalFile(ROOT_DIR); func->openUrl(url); } setJumpBack(func->history->currentUrl()); if (cfg.hasKey("PopupPosition")) { // popup was visible, restore togglePanelPopup(); // create and show popup->restoreSettings(KConfigGroup(&cfg, "PanelPopup")); setPopupPosition(cfg.readEntry("PopupPosition", 42 /* dummy */)); splt->restoreState(cfg.readEntry("SplitterSizes", QByteArray())); popup->setCurrentPage(cfg.readEntry("PopupPage", 0)); } } void ListPanel::slotCurrentChanged(KrViewItem *item) { // update status bar if (item) krApp->statusBarUpdate(item->description()); // update popup panel; which panel to display on? PanelPopup *p; if(popup && !popup->isHidden()) p = popup; else if(otherPanel()->gui->popup && !otherPanel()->gui->popup->isHidden()) p = otherPanel()->gui->popup; else return; - p->update(item ? func->files()->getVfile(item->name()) : 0); + p->update(item ? func->files()->getFileItem(item->name()) : 0); } void ListPanel::otherPanelChanged() { func->syncURL = QUrl(); } void ListPanel::getFocusCandidates(QVector &widgets) { if(urlNavigator->editor()->isVisible()) widgets << urlNavigator->editor(); if(view->widget()->isVisible()) widgets << view->widget(); if(popup && popup->isVisible()) widgets << popup; } void ListPanel::updateButtons() { backButton->setEnabled(func->history->canGoBack()); forwardButton->setEnabled(func->history->canGoForward()); historyButton->setEnabled(func->history->count() > 1); cdRootButton->setEnabled(!virtualPath().matches(QUrl::fromLocalFile(ROOT_DIR), QUrl::StripTrailingSlash)); cdUpButton->setEnabled(!func->files()->isRoot()); cdHomeButton->setEnabled(!func->atHome()); } void ListPanel::newTab(KrViewItem *it) { if (!it) return; else if (it->name() == "..") { newTab(KIO::upUrl(virtualPath()), true); - } else if (ITEM2VFILE(this, it)->vfile_isDir()) { + } else if (ITEM2FILEITEM(this, it)->isDir()) { QUrl url = virtualPath(); url = url.adjusted(QUrl::StripTrailingSlash); url.setPath(url.path() + '/' + (it->name())); newTab(url, true); } } void ListPanel::resetNavigatorMode() { if (isNavigatorEditModeSet()) return; // set to "navigate" mode if url wasn't changed if (urlNavigator->uncommittedUrl().matches(virtualPath(), QUrl::StripTrailingSlash)) { // NOTE: this also sets focus to the navigator urlNavigator->setUrlEditable(false); slotFocusOnMe(); } } int ListPanel::popupPosition() const { int pos = splt->orientation() == Qt::Vertical ? 1 : 0; return pos + (qobject_cast(splt->widget(0)) == NULL ? 2 : 0); } void ListPanel::setPopupPosition(int pos) { splt->setOrientation(pos % 2 == 0 ? Qt::Horizontal : Qt::Vertical); if ((pos < 2) != (qobject_cast(splt->widget(0)) != NULL)) { splt->insertWidget(0, splt->widget(1)); // swapping widgets in splitter } } diff --git a/krusader/Panel/listpanel.h b/krusader/Panel/listpanel.h index 8d3e9f0f..0d3368b9 100644 --- a/krusader/Panel/listpanel.h +++ b/krusader/Panel/listpanel.h @@ -1,254 +1,254 @@ /*************************************************************************** listpanel.h ------------------- begin : Thu May 4 2000 copyright : (C) 2000 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LISTPANEL_H #define LISTPANEL_H // QtCore #include #include #include #include #include #include // QtGui #include #include #include #include #include #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include "krpanel.h" #include "krviewitem.h" #include "../Dialogs/krsqueezedtextlabel.h" #define PROP_SYNC_BUTTON_ON 1 #define PROP_LOCKED 2 class KrView; class KrSearchBar; class DirHistoryButton; class MediaButton; class PanelPopup; class SyncBrowseButton; class KrBookmarkButton; class ListPanelFunc; class QSplitter; class KrErrorDisplay; class ListPanelActions; class ListPanel : public QWidget, public KrPanel { friend class ListPanelFunc; Q_OBJECT public: -#define ITEM2VFILE(PANEL_PTR, KRVIEWITEM) PANEL_PTR->func->files()->getVfile(KRVIEWITEM->name()) -#define NAME2VFILE(PANEL_PTR, STRING_NAME) PANEL_PTR->func->files()->getVfile(STRING_NAME) +#define ITEM2FILEITEM(PANEL_PTR, KRVIEWITEM) PANEL_PTR->func->files()->getFileItem(KRVIEWITEM->name()) +#define NAME2FILEITEM(PANEL_PTR, STRING_NAME) PANEL_PTR->func->files()->getFileItem(STRING_NAME) // constructor create the panel, but DOESN'T fill it with data, use start() ListPanel(QWidget *parent, AbstractPanelManager *manager, KConfigGroup cfg = KConfigGroup()); ~ListPanel(); virtual void otherPanelChanged() Q_DECL_OVERRIDE; void start(QUrl url = QUrl(), bool immediate = false); void reparent(QWidget *parent, AbstractPanelManager *manager); int getType() { return panelType; } void changeType(int); bool isLocked() { return _locked; } void setLocked(bool lck) { _locked = lck; } ListPanelActions *actions() { return _actions; } /// The last shown local path. QString realPath() const; QString getCurrentName(); QStringList getSelectedNames() { QStringList fileNames; view->getSelectedItems(&fileNames); return fileNames; } void setButtons(); void setJumpBack(QUrl url); int getProperties(); void setProperties(int); void getFocusCandidates(QVector &widgets); void saveSettings(KConfigGroup cfg, bool saveHistory); void restoreSettings(KConfigGroup cfg); public slots: void popRightClickMenu(const QPoint&); void popEmptyRightClickMenu(const QPoint &); void compareDirs(bool otherPanelToo = true); void slotFocusOnMe(bool focus = true); void slotUpdateTotals(); - // react to file changes in vfs (path change or refresh) + // react to file changes in filesystem (path change or refresh) void slotStartUpdate(bool directoryChange); void togglePanelPopup(); void panelActive(); // called when the panel becomes active void panelInactive(); // called when panel becomes inactive void refreshColors(); void inlineRefreshCancel(); void openMedia(); void openHistory(); void openBookmarks(); void rightclickMenu(); void toggleSyncBrowse(); void editLocation(); void showSearchBar(); void showSearchFilter(); void jumpBack(); void setJumpBack() { setJumpBack(virtualPath()); } ///////////////////////// service functions - called internally //////////////////////// void prepareToDelete(); // internal use only protected: virtual void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; virtual void mousePressEvent(QMouseEvent*) Q_DECL_OVERRIDE { slotFocusOnMe(); } virtual void showEvent(QShowEvent *) Q_DECL_OVERRIDE; virtual void hideEvent(QHideEvent *) Q_DECL_OVERRIDE; virtual bool eventFilter(QObject * watched, QEvent * e) Q_DECL_OVERRIDE; void showButtonMenu(QToolButton *b); void createView(); void updateButtons(); static int defaultPanelType(); static bool isNavigatorEditModeSet(); // return the navigator edit mode setting protected slots: void slotCurrentChanged(KrViewItem *item); void handleDrop(QDropEvent *event, bool onView = false); // handle drops on frame or view void handleDrop(const QUrl &destination, QDropEvent *event); // handle drops with destination void startDragging(QStringList, QPixmap); void slotPreviewJobStarted(KJob *job); void slotPreviewJobPercent(KJob *job, unsigned long percent); void slotPreviewJobResult(KJob *job); // those handle the in-panel refresh notifications void slotJobStarted(KIO::Job* job); void inlineRefreshInfoMessage(KJob* job, const QString &msg); void inlineRefreshListResult(KJob* job); void inlineRefreshPercent(KJob*, unsigned long); - void slotVfsError(QString msg); + void slotFilesystemError(QString msg); void newTab(KrViewItem *item); void newTab(const QUrl &url, bool nextToThis = false) { _manager->newTab(url, nextToThis ? this : 0); } void resetNavigatorMode(); // set navigator mode after focus was lost // update filesystem meta info, disk-free and mount status void updateFilesystemStats(const QString &metaInfo, const QString &fsType, KIO::filesize_t total, KIO::filesize_t free); signals: void signalStatus(QString msg); // emmited when we need to update the status bar void pathChanged(const QUrl &url); // directory changed or refreshed void activate(); // emitted when the user changes panels void finishedDragging(); // NOTE: currently not used void refreshColors(bool active); // emitted when we have to update the path label width void refreshPathLabel(); protected: int panelType; QUrl _realPath; // named with _ to keep realPath() compatibility QUrl _jumpBackURL; int colorMask; bool compareMode; //FilterSpec filter; KJob *previewJob; KIO::Job *inlineRefreshJob; ListPanelActions *_actions; QPixmap currDragPix; QWidget *clientArea; QSplitter *splt; KUrlNavigator* urlNavigator; KrSearchBar* searchBar; QToolButton *backButton, *forwardButton; QToolButton *cdRootButton; QToolButton *cdHomeButton; QToolButton *cdUpButton; QToolButton *cdOtherButton; QToolButton *popupPositionBtn; QToolButton *popupBtn; PanelPopup *popup; // lazy initialized KrBookmarkButton *bookmarksButton; KrSqueezedTextLabel *status, *totals, *freeSpace; QProgressBar *previewProgress; DirHistoryButton* historyButton; MediaButton *mediaButton; SyncBrowseButton *syncBrowseButton; QToolButton *inlineRefreshCancelButton; - KrErrorDisplay *vfsError; + KrErrorDisplay *fileSystemError; private: bool handleDropInternal(QDropEvent *event, const QString &dir); int popupPosition() const; // 0: West, 1: North, 2: East, 3: South void setPopupPosition(int); private: bool _locked; QList popupSizes; }; #endif diff --git a/krusader/Panel/panelfunc.cpp b/krusader/Panel/panelfunc.cpp index b51af3e6..03ec2a26 100644 --- a/krusader/Panel/panelfunc.cpp +++ b/krusader/Panel/panelfunc.cpp @@ -1,1248 +1,1248 @@ /*************************************************************************** panelfunc.cpp ------------------- copyright : (C) 2000 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "panelfunc.h" // QtCore #include #include #include #include #include #include // QtGui #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dirhistoryqueue.h" #include "krcalcspacedialog.h" #include "listpanel.h" #include "krerrordisplay.h" #include "listpanelactions.h" #include "../krglobal.h" #include "../krslots.h" #include "../kractions.h" #include "../defaults.h" #include "../abstractpanelmanager.h" #include "../krservices.h" #include "../Archive/krarchandler.h" #include "../Archive/packjob.h" -#include "../VFS/vfile.h" -#include "../VFS/virt_vfs.h" -#include "../VFS/krpermhandler.h" -#include "../VFS/krvfshandler.h" +#include "../FileSystem/fileitem.h" +#include "../FileSystem/virtualfilesystem.h" +#include "../FileSystem/krpermhandler.h" +#include "../FileSystem/filesystemprovider.h" #include "../Dialogs/packgui.h" #include "../Dialogs/krdialogs.h" #include "../Dialogs/krpleasewait.h" #include "../Dialogs/krspwidgets.h" #include "../Dialogs/checksumdlg.h" #include "../KViewer/krviewer.h" #include "../GUI/syncbrowsebutton.h" #include "../MountMan/kmountman.h" #include "../JobMan/jobman.h" QPointer ListPanelFunc::copyToClipboardOrigin; ListPanelFunc::ListPanelFunc(ListPanel *parent) : QObject(parent), - panel(parent), vfsP(0), urlManuallyEntered(false), _refreshing(false), _ignoreVFSErrors(false) + panel(parent), fileSystemP(0), urlManuallyEntered(false), _refreshing(false), _ignoreFileSystemErrors(false) { history = new DirHistoryQueue(panel); delayTimer.setSingleShot(true); connect(&delayTimer, SIGNAL(timeout()), this, SLOT(doRefresh())); } ListPanelFunc::~ListPanelFunc() { - if (vfsP) { - vfsP->deleteLater(); + if (fileSystemP) { + fileSystemP->deleteLater(); } delete history; } void ListPanelFunc::navigatorUrlChanged(const QUrl &url) { if (_refreshing) return; if (!ListPanel::isNavigatorEditModeSet()) { panel->urlNavigator->setUrlEditable(false); } openUrl(KrServices::escapeFileUrl(url), QString(), true); } bool ListPanelFunc::isSyncing(const QUrl &url) { if(otherFunc()->otherFunc() == this && panel->otherPanel()->gui->syncBrowseButton->state() == SYNCBROWSE_CD && !otherFunc()->syncURL.isEmpty() && otherFunc()->syncURL == url) return true; return false; } void ListPanelFunc::openFileNameInternal(const QString &name, bool externallyExecutable) { if (name == "..") { dirUp(); return ; } - vfile *vf = files()->getVfile(name); - if (vf == 0) + FileItem *fileitem = files()->getFileItem(name); + if (fileitem == 0) return ; QUrl url = files()->getUrl(name); - if (vf->vfile_isDir()) { + if (fileitem->isDir()) { panel->view->setNameToMakeCurrent(QString()); openUrl(url); return; } - QString mime = vf->vfile_getMime(); + QString mime = fileitem->getMime(); QUrl arcPath = browsableArchivePath(name); if (!arcPath.isEmpty()) { bool browseAsDirectory = !externallyExecutable || (KConfigGroup(krConfig, "Archives").readEntry("ArchivesAsDirectories", _ArchivesAsDirectories) && (KRarcHandler::arcSupported(mime) || KrServices::isoSupported(mime))); if (browseAsDirectory) { openUrl(arcPath); return; } } if (externallyExecutable) { if (KRun::isExecutableFile(url, mime)) { runCommand(KShell::quoteArg(url.path())); return; } KService::Ptr service = KMimeTypeTrader::self()->preferredService(mime); if(service) { runService(*service, QList() << url); return; } displayOpenWithDialog(QList() << url); } } #if 0 //FIXME: see if this is still needed void ListPanelFunc::popErronousUrl() { QUrl current = urlStack.last(); while (urlStack.count() != 0) { QUrl url = urlStack.takeLast(); if (!current.equals(url)) { immediateOpenUrl(url, true); return; } } immediateOpenUrl(QUrl::fromLocalFile(ROOT_DIR), true); } #endif QUrl ListPanelFunc::cleanPath(const QUrl &urlIn) { QUrl url = urlIn; url.setPath(QDir::cleanPath(url.path())); if (!url.isValid() || url.isRelative()) { if (url.url() == "~") url = QUrl::fromLocalFile(QDir::homePath()); else if (!url.url().startsWith('/')) { // possible relative URL - translate to full URL url = files()->currentDirectory(); url.setPath(url.path() + '/' + urlIn.path()); } } url.setPath(QDir::cleanPath(url.path())); return url; } void ListPanelFunc::openUrl(const QUrl &url, const QString& nameToMakeCurrent, bool manuallyEntered) { if (panel->syncBrowseButton->state() == SYNCBROWSE_CD) { //do sync-browse stuff.... if(syncURL.isEmpty()) syncURL = panel->otherPanel()->virtualPath(); QString relative = QDir(panel->virtualPath().path() + '/').relativeFilePath(url.path()); syncURL.setPath(QDir::cleanPath(syncURL.path() + '/' + relative)); panel->otherPanel()->gui->setLocked(false); otherFunc()->openUrlInternal(syncURL, nameToMakeCurrent, false, false, false); } openUrlInternal(url, nameToMakeCurrent, false, false, manuallyEntered); } void ListPanelFunc::immediateOpenUrl(const QUrl &url, bool disableLock) { openUrlInternal(url, QString(), true, disableLock, false); } void ListPanelFunc::openUrlInternal(const QUrl &url, const QString& nameToMakeCurrent, bool immediately, bool disableLock, bool manuallyEntered) { QUrl cleanUrl = cleanPath(url); if (!disableLock && panel->isLocked() && !files()->currentDirectory().matches(cleanUrl, QUrl::StripTrailingSlash)) { panel->_manager->newTab(url); urlManuallyEntered = false; return; } urlManuallyEntered = manuallyEntered; history->add(cleanUrl, nameToMakeCurrent); if(immediately) doRefresh(); else refresh(); } void ListPanelFunc::refresh() { panel->inlineRefreshCancel(); delayTimer.start(0); // to avoid qApp->processEvents() deadlock situaltion } void ListPanelFunc::doRefresh() { _refreshing = true; delayTimer.stop(); QUrl url = history->currentUrl(); if(!url.isValid()) { //FIXME go back in history here ? panel->slotStartUpdate(true); // refresh the panel urlManuallyEntered = false; _refreshing = false; return ; } panel->inlineRefreshCancel(); // if we are not refreshing to current URL bool isEqualUrl = files()->currentDirectory().matches(url, QUrl::StripTrailingSlash); if (!isEqualUrl) { panel->setCursor(Qt::WaitCursor); panel->view->clearSavedSelection(); } - if(panel->vfsError) - panel->vfsError->hide(); + if(panel->fileSystemError) + panel->fileSystemError->hide(); bool refreshFailed = false; while (true) { QUrl url = history->currentUrl(); isEqualUrl = files()->currentDirectory().matches(url, QUrl::StripTrailingSlash); - // may get a new vfs for this url - vfs* vfs = KrVfsHandler::instance().getVfs(url, files()); - vfs->setParentWindow(krMainWindow); - connect(vfs, &vfs::aboutToOpenDir, &krMtMan, &KMountMan::autoMount, Qt::DirectConnection); - if (vfs != vfsP) { + // may get a new filesystem for this url + FileSystem *fileSystem = FileSystemProvider::instance().getFilesystem(url, files()); + fileSystem->setParentWindow(krMainWindow); + connect(fileSystem, &FileSystem::aboutToOpenDir, &krMtMan, &KMountMan::autoMount, Qt::DirectConnection); + if (fileSystem != fileSystemP) { panel->view->setFiles(0); // disconnect older signals - disconnect(vfsP, 0, panel, 0); + disconnect(fileSystemP, 0, panel, 0); - vfsP->deleteLater(); - vfsP = vfs; // v != 0 so this is safe + fileSystemP->deleteLater(); + fileSystemP = fileSystem; // v != 0 so this is safe } else { - if (vfsP->isRefreshing()) { - delayTimer.start(100); /* if vfs is busy try refreshing later */ + if (fileSystemP->isRefreshing()) { + delayTimer.start(100); /* if filesystem is busy try refreshing later */ return; } } - // (re)connect vfs signals + // (re)connect filesystem signals disconnect(files(), 0, panel, 0); connect(files(), SIGNAL(refreshDone(bool)), panel, SLOT(slotStartUpdate(bool))); - connect(files(), &vfs::filesystemInfoChanged, panel, &ListPanel::updateFilesystemStats); + connect(files(), &FileSystem::fileSystemInfoChanged, panel, &ListPanel::updateFilesystemStats); connect(files(), SIGNAL(refreshJobStarted(KIO::Job*)), panel, SLOT(slotJobStarted(KIO::Job*))); connect(files(), SIGNAL(error(QString)), - panel, SLOT(slotVfsError(QString))); + panel, SLOT(slotFilesystemError(QString))); panel->view->setFiles(files()); if(!history->currentItem().isEmpty() && isEqualUrl) { // if the url we're refreshing into is the current one, then the // partial refresh will not generate the needed signals to actually allow the // view to use nameToMakeCurrent. do it here instead (patch by Thomas Jarosch) panel->view->setCurrentItem(history->currentItem()); panel->view->makeItemVisible(panel->view->getCurrentKrViewItem()); } panel->view->setNameToMakeCurrent(history->currentItem()); int savedHistoryState = history->state(); // NOTE: this is blocking. Returns false on error or interruption (cancel requested or panel // was deleted) - const bool refreshed = vfsP->refresh(url); + const bool refreshed = fileSystemP->refresh(url); if (refreshed) { // update the history and address bar, as the actual url might differ from the one requested - history->setCurrentUrl(vfsP->currentDirectory()); - panel->urlNavigator->setLocationUrl(vfsP->currentDirectory()); + history->setCurrentUrl(fileSystemP->currentDirectory()); + panel->urlNavigator->setLocationUrl(fileSystemP->currentDirectory()); break; // we have a valid refreshed URL now } if (!panel || !panel->view) // this panel was deleted while refreshing return; refreshFailed = true; panel->view->setNameToMakeCurrent(QString()); if(history->state() != savedHistoryState) // don't go back if the history was touched break; if(!history->goBack()) { // put the root dir to the beginning of history, if it's not there yet if (!url.matches(QUrl::fromLocalFile(ROOT_DIR), QUrl::StripTrailingSlash)) history->pushBackRoot(); else break; } - _ignoreVFSErrors = true; + _ignoreFileSystemErrors = true; } - _ignoreVFSErrors = false; + _ignoreFileSystemErrors = false; panel->view->setNameToMakeCurrent(QString()); panel->setCursor(Qt::ArrowCursor); // on local file system change the working directory if (files()->isLocal()) QDir::setCurrent(KrServices::urlToLocalPath(files()->currentDirectory())); // see if the open url operation failed, and if so, // put the attempted url in the navigator bar and let the user change it if (refreshFailed) { if(isSyncing(url)) panel->otherPanel()->gui->syncBrowseButton->setChecked(false); else if(urlManuallyEntered) { panel->urlNavigator->setLocationUrl(url); if(panel == ACTIVE_PANEL) panel->editLocation(); } } if(otherFunc()->otherFunc() == this) // not true if our tab is not active otherFunc()->syncURL = QUrl(); urlManuallyEntered = false; refreshActions(); _refreshing = false; } void ListPanelFunc::redirectLink() { if (!files()->isLocal()) { KMessageBox::sorry(krMainWindow, i18n("You can edit links only on local file systems")); return ; } - vfile *vf = files()->getVfile(panel->getCurrentName()); - if (!vf) + FileItem *fileitem = files()->getFileItem(panel->getCurrentName()); + if (!fileitem) return ; - QString file = vf->vfile_getUrl().path(); - QString currentLink = vf->vfile_getSymDest(); + QString file = fileitem->getUrl().path(); + QString currentLink = fileitem->getSymDest(); if (currentLink.isEmpty()) { KMessageBox::sorry(krMainWindow, i18n("The current file is not a link, so it cannot be redirected.")); return ; } // ask the user for a new destination bool ok = false; QString newLink = QInputDialog::getText(krMainWindow, i18n("Link Redirection"), i18n("Please enter the new link destination:"), QLineEdit::Normal, currentLink, &ok); // if the user canceled - quit if (!ok || newLink == currentLink) return ; // delete the current link if (unlink(file.toLocal8Bit()) == -1) { KMessageBox::sorry(krMainWindow, i18n("Cannot remove old link: %1", file)); return ; } // try to create a new symlink if (symlink(newLink.toLocal8Bit(), file.toLocal8Bit()) == -1) { KMessageBox:: /* --=={ Patch by Heiner }==-- */sorry(krMainWindow, i18n("Failed to create a new link: %1", file)); return ; } } void ListPanelFunc::krlink(bool sym) { if (!files()->isLocal()) { KMessageBox::sorry(krMainWindow, i18n("You can create links only on local file systems")); return; } QString name = panel->getCurrentName(); // ask the new link name.. bool ok = false; QString linkName = QInputDialog::getText(krMainWindow, i18n("New Link"), i18n("Create a new link to: %1", name), QLineEdit::Normal, name, &ok); // if the user canceled - quit if (!ok || linkName == name) return; // if the name is already taken - quit - if (files()->getVfile(linkName) != 0) { + if (files()->getFileItem(linkName) != 0) { KMessageBox::sorry(krMainWindow, i18n("A folder or a file with this name already exists.")); return; } // make link name and target absolute path if (linkName.left(1) != "/") linkName = files()->currentDirectory().path() + '/' + linkName; name = files()->getUrl(name).path(); if (sym) { if (symlink(name.toLocal8Bit(), linkName.toLocal8Bit()) == -1) KMessageBox::sorry(krMainWindow, i18n("Failed to create a new symlink '%1' to: '%2'", linkName, name)); } else { if (link(name.toLocal8Bit(), linkName.toLocal8Bit()) == -1) KMessageBox::sorry(krMainWindow, i18n("Failed to create a new link '%1' to '%2'", linkName, name)); } } void ListPanelFunc::view() { QString fileName = panel->getCurrentName(); if (fileName.isNull()) return ; // if we're trying to view a directory, just exit - vfile * vf = files()->getVfile(fileName); - if (!vf || vf->vfile_isDir()) + FileItem *fileitem = files()->getFileItem(fileName); + if (!fileitem || fileitem->isDir()) return ; - if (!vf->vfile_isReadable()) { + if (!fileitem->isReadable()) { KMessageBox::sorry(0, i18n("No permissions to view this file.")); return ; } // call KViewer. KrViewer::view(files()->getUrl(fileName)); // nothing more to it! } void ListPanelFunc::viewDlg() { // ask the user for a url to view QUrl dest = KChooseDir::getFile(i18n("Enter a URL to view:"), panel->virtualPath(), panel->virtualPath()); if (dest.isEmpty()) return ; // the user canceled KrViewer::view(dest); // view the file } void ListPanelFunc::terminal() { SLOTS->runTerminal(panel->realPath()); } void ListPanelFunc::edit() { KFileItem tmp; if (fileToCreate.isEmpty()) { QString name = panel->getCurrentName(); if (name.isNull()) return; fileToCreate = files()->getUrl(name); } tmp = KFileItem(fileToCreate); if (tmp.isDir()) { KMessageBox::sorry(krMainWindow, i18n("You cannot edit a folder")); fileToCreate = QUrl(); return ; } if (!tmp.isReadable()) { KMessageBox::sorry(0, i18n("No permissions to edit this file.")); fileToCreate = QUrl(); return; } KrViewer::edit(fileToCreate); fileToCreate = QUrl(); } void ListPanelFunc::editNew() { if(!fileToCreate.isEmpty()) return; // ask the user for the filename to edit fileToCreate = KChooseDir::getFile(i18n("Enter the filename to edit:"), panel->virtualPath(), panel->virtualPath()); if(fileToCreate.isEmpty()) return ; // the user canceled // if the file exists, edit it instead of creating a new one QFile f(fileToCreate.toLocalFile()); if(f.exists()) { edit(); } else { QTemporaryFile *tempFile = new QTemporaryFile; tempFile->open(); KIO::CopyJob *job = KIO::copy(QUrl::fromLocalFile(tempFile->fileName()), fileToCreate); job->setUiDelegate(0); job->setDefaultPermissions(true); connect(job, SIGNAL(result(KJob*)), SLOT(slotFileCreated(KJob*))); connect(job, SIGNAL(result(KJob*)), tempFile, SLOT(deleteLater())); } } void ListPanelFunc::slotFileCreated(KJob *job) { if(!job->error() || job->error() == KIO::ERR_FILE_ALREADY_EXIST) { KrViewer::edit(fileToCreate); if(KIO::upUrl(fileToCreate).matches(panel->virtualPath(), QUrl::StripTrailingSlash)) refresh(); else if(KIO::upUrl(fileToCreate).matches(panel->otherPanel()->virtualPath(), QUrl::StripTrailingSlash)) otherFunc()->refresh(); } else KMessageBox::sorry(krMainWindow, job->errorString()); fileToCreate = QUrl(); } void ListPanelFunc::moveFilesByQueue() { moveFiles(!krJobMan->isQueueModeEnabled()); } void ListPanelFunc::copyFilesByQueue() { copyFiles(!krJobMan->isQueueModeEnabled()); } void ListPanelFunc::copyFiles(bool reverseQueueMode, bool move) { const QStringList fileNames = panel->getSelectedNames(); if (fileNames.isEmpty()) return ; // safety QUrl destination = panel->otherPanel()->virtualPath(); bool startPaused = false; KConfigGroup group(krConfig, "Advanced"); bool showDialog = move ? group.readEntry("Confirm Move", _ConfirmMove) : group.readEntry("Confirm Copy", _ConfirmCopy); if (showDialog) { QString operationText; if (move) { operationText = fileNames.count() == 1 ? i18n("Move %1 to:", fileNames.first()) : i18np("Move %1 file to:", "Move %1 files to:", fileNames.count()); } else { operationText = fileNames.count() == 1 ? i18n("Copy %1 to:", fileNames.first()) : i18np("Copy %1 file to:", "Copy %1 files to:", fileNames.count()); } // ask the user for the copy/move dest KChooseDir::ChooseResult result = KChooseDir::getCopyDir(operationText, destination, panel->virtualPath()); destination = result.url; if (destination.isEmpty()) return ; // the user canceled reverseQueueMode = result.reverseQueueMode; startPaused = result.startPaused; } const QList fileUrls = files()->getUrls(fileNames); if (move) { // after the delete return the cursor to the first unmarked file above the current item panel->prepareToDelete(); } // make sure the user does not overwrite multiple files by mistake if (fileNames.count() > 1) { - destination = vfs::ensureTrailingSlash(destination); + destination = FileSystem::ensureTrailingSlash(destination); } KIO::CopyJob::CopyMode mode = move ? KIO::CopyJob::Move : KIO::CopyJob::Copy; - KrVfsHandler::instance().startCopyFiles(fileUrls, destination, mode, true, reverseQueueMode, startPaused); + FileSystemProvider::instance().startCopyFiles(fileUrls, destination, mode, true, reverseQueueMode, startPaused); if(KConfigGroup(krConfig, "Look&Feel").readEntry("UnselectBeforeOperation", _UnselectBeforeOperation)) { panel->view->saveSelection(); panel->view->unselectAll(); } } // called from SLOTS to begin the renaming process void ListPanelFunc::rename() { panel->view->renameCurrentItem(); } // called by signal itemRenamed() from the view to complete the renaming process void ListPanelFunc::rename(const QString &oldname, const QString &newname) { if (oldname == newname) return ; // do nothing // set current after rename panel->view->setNameToMakeCurrent(newname); - // as always - the vfs do the job + // as always - the filesystem do the job files()->rename(oldname, newname); } void ListPanelFunc::mkdir() { // ask the new dir name.. // suggested name is the complete name for the directories // while filenames are suggested without their extension QString suggestedName = panel->getCurrentName(); - if (!suggestedName.isEmpty() && !files()->getVfile(suggestedName)->vfile_isDir()) + if (!suggestedName.isEmpty() && !files()->getFileItem(suggestedName)->isDir()) suggestedName = QFileInfo(suggestedName).completeBaseName(); QString dirName = QInputDialog::getText(krMainWindow, i18n("New folder"), i18n("Folder's name:"), QLineEdit::Normal, suggestedName); // if the user canceled - quit if (dirName.isEmpty()) return ; QStringList dirTree = dirName.split('/'); for (QStringList::Iterator it = dirTree.begin(); it != dirTree.end(); ++it) { if (*it == ".") continue; if (*it == "..") { immediateOpenUrl(QUrl::fromUserInput(*it, QString(), QUrl::AssumeLocalFile)); continue; } // check if the name is already taken - if (files()->getVfile(*it)) { + if (files()->getFileItem(*it)) { // if it is the last dir to be created - quit if (*it == dirTree.last()) { KMessageBox::sorry(krMainWindow, i18n("A folder or a file with this name already exists.")); return ; } // else go into this dir else { immediateOpenUrl(QUrl::fromUserInput(*it, QString(), QUrl::AssumeLocalFile)); continue; } } panel->view->setNameToMakeCurrent(*it); - // as always - the vfs does the job + // as always - the filesystem does the job files()->mkDir(*it); if (dirTree.count() > 1) immediateOpenUrl(QUrl::fromUserInput(*it, QString(), QUrl::AssumeLocalFile)); } // for } void ListPanelFunc::deleteFiles(bool reallyDelete) { - if (files()->type() == vfs::VFS_VIRT && files()->isRoot()) { + if (files()->type() == FileSystem::FS_VIRTUAL && files()->isRoot()) { // only virtual deletion possible removeVirtualFiles(); return; } // first get the selected file names list QStringList fileNames = panel->getSelectedNames(); if (fileNames.isEmpty()) return; const KConfigGroup generalGroup(krConfig, "General"); bool moveToTrash = !reallyDelete && generalGroup.readEntry("Move To Trash", _MoveToTrash); // make sure this is possible moveToTrash = moveToTrash && files()->canMoveToTrash(fileNames); // now ask the user if he/she is sure: const KConfigGroup advancedGroup(krConfig, "Advanced"); if (advancedGroup.readEntry("Confirm Delete", _ConfirmDelete)) { QString s; // text KGuiItem b; // continue button if (moveToTrash) { s = i18np("Do you really want to move this item to the trash?", "Do you really want to move these %1 items to the trash?", fileNames.count()); b = KGuiItem(i18n("&Trash")); - } else if (files()->type() == vfs::VFS_VIRT) { + } else if (files()->type() == FileSystem::FS_VIRTUAL) { s = i18np("Do you really want to delete this item physically (not just " "removing it from the virtual items)?", "Do you really want to delete these %1 items physically (not just " "removing them from the virtual items)?", fileNames.count()); b = KStandardGuiItem::del(); } else { s = i18np("Do you really want to delete this item?", "Do you really want to delete these %1 items?", fileNames.count()); b = KStandardGuiItem::del(); } // show message // note: i'm using continue and not yes/no because the yes/no has cancel as default button if (KMessageBox::warningContinueCancelList(krMainWindow, s, fileNames, i18n("Warning"), b) != KMessageBox::Continue) return; } // we want to warn the user about non empty dir bool emptyDirVerify = advancedGroup.readEntry("Confirm Unempty Dir", _ConfirmUnemptyDir); // TODO only local fs supported emptyDirVerify &= files()->isLocal(); if (emptyDirVerify) { for (const QString fileName: fileNames) { - vfile *vfile = files()->getVfile(fileName); - if (vfile && !vfile->vfile_isSymLink() && vfile->vfile_isDir()) { + FileItem *fileItem = files()->getFileItem(fileName); + if (fileItem && !fileItem->isSymLink() && fileItem->isDir()) { // read local dir... - const QDir dir(vfile->vfile_getUrl().path()); + const QDir dir(fileItem->getUrl().path()); if (dir.entryList(QDir::TypeMask | QDir::System | QDir::Hidden).count() > 2) { // ...is not empty, ask user const KMessageBox::ButtonCode result = KMessageBox::warningYesNoCancel( krMainWindow, i18n("

Folder %1 is not empty.

Skip this one " "or delete all?

", fileName), QString(), KGuiItem(i18n("&Skip")), KGuiItem(i18n("&Delete All"))); if (result == KMessageBox::Yes) { fileNames.removeAll(fileName); // skip } else if (result == KMessageBox::No) { break; // accept all remaining } else { return; // cancel } } } } } if (fileNames.count() == 0) return; // nothing to delete // after the delete return the cursor to the first unmarked // file above the current item; panel->prepareToDelete(); - // let the vfs do the job... + // let the filesystem do the job... files()->deleteFiles(fileNames, moveToTrash); } void ListPanelFunc::removeVirtualFiles() { - if (files()->type() != vfs::VFS_VIRT) { + if (files()->type() != FileSystem::FS_VIRTUAL) { krOut << "filesystem not virtual"; return; } const QStringList fileNames = panel->getSelectedNames(); if (fileNames.isEmpty()) return; const QString text = i18np("Do you really want to delete this virtual item (physical files stay untouched)?", "Do you really want to delete these %1 virtual items (physical files stay " "untouched)?", fileNames.count()); if (KMessageBox::warningContinueCancelList(krMainWindow, text, fileNames, i18n("Warning"), KStandardGuiItem::remove()) != KMessageBox::Continue) return; - virt_vfs *vfs = static_cast(files()); - vfs->remove(fileNames); + VirtualFileSystem *fileSystem = static_cast(files()); + fileSystem->remove(fileNames); } void ListPanelFunc::goInside(const QString& name) { openFileNameInternal(name, false); } void ListPanelFunc::runCommand(QString cmd) { krOut << "Run command: " << cmd; const QString workdir = panel->virtualPath().isLocalFile() ? panel->virtualPath().path() : QDir::homePath(); if(!KRun::runCommand(cmd, krMainWindow, workdir)) KMessageBox::error(0, i18n("Could not start %1", cmd)); } void ListPanelFunc::runService(const KService &service, QList urls) { krOut << "Run service: " << service.name(); KIO::DesktopExecParser parser(service, urls); QStringList args = parser.resultingArguments(); if (!args.isEmpty()) runCommand(KShell::joinArgs(args)); else KMessageBox::error(0, i18n("%1 cannot open %2", service.name(), KrServices::toStringList(urls).join(", "))); } void ListPanelFunc::displayOpenWithDialog(QList urls) { // NOTE: we are not using KRun::displayOpenWithDialog() because we want the commands working // directory to be the panel directory KOpenWithDialog dialog(urls, panel); dialog.hideRunInTerminal(); if (dialog.exec()) { KService::Ptr service = dialog.service(); if(!service) service = KService::Ptr(new KService(dialog.text(), dialog.text(), QString())); runService(*service, urls); } } QUrl ListPanelFunc::browsableArchivePath(const QString &filename) { - vfile *vf = files()->getVfile(filename); + FileItem *fileitem = files()->getFileItem(filename); QUrl url = files()->getUrl(filename); - QString mime = vf->vfile_getMime(); + QString mime = fileitem->getMime(); if(url.isLocalFile()) { QString protocol = KrServices::registeredProtocol(mime); if(!protocol.isEmpty()) { url.setScheme(protocol); return url; } } return QUrl(); } // this is done when you double click on a file void ListPanelFunc::execute(const QString& name) { openFileNameInternal(name, true); } void ListPanelFunc::pack() { const QStringList fileNames = panel->getSelectedNames(); if (fileNames.isEmpty()) return ; // safety if (fileNames.count() == 0) return ; // nothing to pack // choose the default name QString defaultName = panel->virtualPath().fileName(); if (defaultName.isEmpty()) defaultName = "pack"; if (fileNames.count() == 1) defaultName = fileNames.first(); // ask the user for archive name and packer new PackGUI(defaultName, panel->otherPanel()->virtualPath().toDisplayString(QUrl::PreferLocalFile | QUrl::StripTrailingSlash), fileNames.count(), fileNames.first()); if (PackGUI::type.isEmpty()) { return ; // the user canceled } // check for partial URLs if (!PackGUI::destination.contains(":/") && !PackGUI::destination.startsWith('/')) { PackGUI::destination = panel->virtualPath().toDisplayString() + '/' + PackGUI::destination; } QString destDir = PackGUI::destination; if (!destDir.endsWith('/')) destDir += '/'; - bool packToOtherPanel = (destDir == vfs::ensureTrailingSlash(panel->otherPanel()->virtualPath()).toDisplayString(QUrl::PreferLocalFile)); + bool packToOtherPanel = (destDir == FileSystem::ensureTrailingSlash(panel->otherPanel()->virtualPath()).toDisplayString(QUrl::PreferLocalFile)); QUrl destURL = QUrl::fromUserInput(destDir + PackGUI::filename + '.' + PackGUI::type, QString(), QUrl::AssumeLocalFile); if (destURL.isLocalFile() && QFile::exists(destURL.path())) { QString msg = i18n("

The archive %1.%2 already exists. Do you want to overwrite it?

All data in the previous archive will be lost.

", PackGUI::filename, PackGUI::type); if (PackGUI::type == "zip") { msg = i18n("

The archive %1.%2 already exists. Do you want to overwrite it?

Zip will replace identically named entries in the zip archive or add entries for new names.

", PackGUI::filename, PackGUI::type); } if (KMessageBox::warningContinueCancel(krMainWindow, msg, QString(), KStandardGuiItem::overwrite()) == KMessageBox::Cancel) return ; // stop operation } else if (destURL.scheme() == QStringLiteral("virt")) { KMessageBox::error(krMainWindow, i18n("Cannot pack files onto a virtual destination.")); return; } PackJob * job = PackJob::createPacker(files()->currentDirectory(), destURL, fileNames, PackGUI::type, PackGUI::extraProps); job->setUiDelegate(new KIO::JobUiDelegate()); KIO::getJobTracker()->registerJob(job); job->ui()->setAutoErrorHandlingEnabled(true); if (packToOtherPanel) connect(job, SIGNAL(result(KJob*)), panel->otherPanel()->func, SLOT(refresh())); } void ListPanelFunc::testArchive() { const QStringList fileNames = panel->getSelectedNames(); if (fileNames.isEmpty()) return ; // safety TestArchiveJob * job = TestArchiveJob::testArchives(files()->currentDirectory(), fileNames); job->setUiDelegate(new KIO::JobUiDelegate()); KIO::getJobTracker()->registerJob(job); job->ui()->setAutoErrorHandlingEnabled(true); } void ListPanelFunc::unpack() { const QStringList fileNames = panel->getSelectedNames(); if (fileNames.isEmpty()) return ; // safety QString s; if (fileNames.count() == 1) s = i18n("Unpack %1 to:", fileNames[0]); else s = i18np("Unpack %1 file to:", "Unpack %1 files to:", fileNames.count()); // ask the user for the copy dest QUrl dest = KChooseDir::getDir(s, panel->otherPanel()->virtualPath(), panel->virtualPath()); if (dest.isEmpty()) return ; // the user canceled bool packToOtherPanel = (dest.matches(panel->otherPanel()->virtualPath(), QUrl::StripTrailingSlash)); UnpackJob * job = UnpackJob::createUnpacker(files()->currentDirectory(), dest, fileNames); job->setUiDelegate(new KIO::JobUiDelegate()); KIO::getJobTracker()->registerJob(job); job->ui()->setAutoErrorHandlingEnabled(true); if (packToOtherPanel) connect(job, SIGNAL(result(KJob*)), panel->otherPanel()->func, SLOT(refresh())); } // a small ugly function, used to prevent duplication of EVERY line of // code (maybe except 3) from createChecksum and matchChecksum static void checksum_wrapper(ListPanel *panel, QStringList& args, bool &folders) { KrViewItemList items; panel->view->getSelectedKrViewItems(&items); if (items.isEmpty()) return ; // nothing to do // determine if we need recursive mode (md5deep) folders = false; for (KrViewItemList::Iterator it = items.begin(); it != items.end(); ++it) { - if (panel->func->getVFile(*it)->vfile_isDir()) { + if (panel->func->getFileItem(*it)->isDir()) { folders = true; args << (*it)->name(); } else args << (*it)->name(); } } void ListPanelFunc::createChecksum() { QStringList args; bool folders; checksum_wrapper(panel, args, folders); CreateChecksumDlg dlg(args, folders, panel->realPath()); } void ListPanelFunc::matchChecksum() { QStringList args; bool folders; checksum_wrapper(panel, args, folders); - QList checksumFiles = - files()->searchVfiles(KRQuery(MatchChecksumDlg::checksumTypesFilter)); + QList checksumFiles = + files()->searchFileItems(KRQuery(MatchChecksumDlg::checksumTypesFilter)); MatchChecksumDlg dlg(args, folders, panel->realPath(), (checksumFiles.size() == 1 - ? checksumFiles[0]->vfile_getUrl().toDisplayString(QUrl::PreferLocalFile) + ? checksumFiles[0]->getUrl().toDisplayString(QUrl::PreferLocalFile) : QString())); } void ListPanelFunc::calcSpace(KrViewItem *item) { QStringList items; if (item) { items << item->name(); } else { panel->view->getSelectedItems(&items); if (items.isEmpty()) { panel->view->selectAllIncludingDirs(); panel->view->getSelectedItems(&items); if (items.isEmpty()) return ; // nothing to do } } QPointer calc = new KrCalcSpaceDialog(krMainWindow, panel, items, item != 0); calc->exec(); panel->slotUpdateTotals(); delete calc; } void ListPanelFunc::FTPDisconnect() { // you can disconnect only if connected! if (files()->isRemote()) { panel->_actions->actFTPDisconnect->setEnabled(false); panel->view->setNameToMakeCurrent(QString()); openUrl(QUrl::fromLocalFile(panel->realPath())); // open the last local URL } } void ListPanelFunc::newFTPconnection() { QUrl url = KRSpWidgets::newFTP(); // if the user canceled - quit if (url.isEmpty()) return ; panel->_actions->actFTPDisconnect->setEnabled(true); openUrl(url); } void ListPanelFunc::properties() { const QStringList names = panel->getSelectedNames(); if (names.isEmpty()) return ; // no names... KFileItemList fi; for (int i = 0 ; i < names.count() ; ++i) { - vfile* vf = files()->getVfile(names[i]); - if (!vf) + FileItem *fileitem = files()->getFileItem(names[i]); + if (!fileitem) continue; QUrl url = files()->getUrl(names[i]); - fi.push_back(KFileItem(vf->vfile_getEntry(), url)); + fi.push_back(KFileItem(fileitem->getEntry(), url)); } if (fi.isEmpty()) return ; // Show the properties dialog KPropertiesDialog *dlg = new KPropertiesDialog(fi, krMainWindow); connect(dlg, SIGNAL(applied()), SLOT(refresh())); dlg->show(); } void ListPanelFunc::refreshActions() { panel->updateButtons(); if(ACTIVE_PANEL != panel) return; QString protocol = files()->currentDirectory().scheme(); krRemoteEncoding->setEnabled(protocol == "ftp" || protocol == "sftp" || protocol == "fish" || protocol == "krarc"); - //krMultiRename->setEnabled( vfsType == vfs::VFS_NORMAL ); // batch rename - //krProperties ->setEnabled( vfsType == vfs::VFS_NORMAL || vfsType == vfs::VFS_FTP ); // file properties + //krMultiRename->setEnabled( fileSystemType == FileSystem::FS_NORMAL ); // batch rename + //krProperties ->setEnabled( fileSystemType == FileSystem::FS_NORMAL || fileSystemType == FileSystem::FS_FTP ); // file properties /* krUnpack->setEnabled(true); // unpack archive krTest->setEnabled(true); // test archive krSelect->setEnabled(true); // select a group by filter krSelectAll->setEnabled(true); // select all files krUnselect->setEnabled(true); // unselect by filter krUnselectAll->setEnabled( true); // remove all selections krInvert->setEnabled(true); // invert the selection krFTPConnect->setEnabled(true); // connect to an ftp krFTPNew->setEnabled(true); // create a new connection krAllFiles->setEnabled(true); // show all files in list krCustomFiles->setEnabled(true); // show a custom set of files krRoot->setEnabled(true); // go all the way up krExecFiles->setEnabled(true); // show only executables */ panel->_actions->setViewActions[panel->panelType]->setChecked(true); panel->_actions->actFTPDisconnect->setEnabled(files()->isRemote()); // allow disconnecting a network session panel->_actions->actCreateChecksum->setEnabled(files()->isLocal()); panel->_actions->actDirUp->setEnabled(!files()->isRoot()); panel->_actions->actRoot->setEnabled(!panel->virtualPath().matches(QUrl::fromLocalFile(ROOT_DIR), QUrl::StripTrailingSlash)); panel->_actions->actHome->setEnabled(!atHome()); panel->_actions->actHistoryBackward->setEnabled(history->canGoBack()); panel->_actions->actHistoryForward->setEnabled(history->canGoForward()); panel->view->op()->emitRefreshActions(); } -vfs* ListPanelFunc::files() +FileSystem* ListPanelFunc::files() { - if (!vfsP) - vfsP = KrVfsHandler::instance().getVfs(QUrl::fromLocalFile("/")); - return vfsP; + if (!fileSystemP) + fileSystemP = FileSystemProvider::instance().getFilesystem(QUrl::fromLocalFile("/")); + return fileSystemP; } void ListPanelFunc::clipboardChanged(QClipboard::Mode mode) { if (mode == QClipboard::Clipboard && this == copyToClipboardOrigin) { disconnect(QApplication::clipboard(), 0, this, 0); copyToClipboardOrigin = 0; } } void ListPanelFunc::copyToClipboard(bool move) { const QStringList fileNames = panel->getSelectedNames(); if (fileNames.isEmpty()) return ; // safety QList fileUrls = files()->getUrls(fileNames); QMimeData *mimeData = new QMimeData; mimeData->setData("application/x-kde-cutselection", move ? "1" : "0"); mimeData->setUrls(fileUrls); if (copyToClipboardOrigin) disconnect(QApplication::clipboard(), 0, copyToClipboardOrigin, 0); copyToClipboardOrigin = this; QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); connect(QApplication::clipboard(), SIGNAL(changed(QClipboard::Mode)), this, SLOT(clipboardChanged(QClipboard::Mode))); } void ListPanelFunc::pasteFromClipboard() { QClipboard * cb = QApplication::clipboard(); ListPanelFunc *origin = 0; if (copyToClipboardOrigin) { disconnect(QApplication::clipboard(), 0, copyToClipboardOrigin, 0); origin = copyToClipboardOrigin; copyToClipboardOrigin = 0; } bool move = false; const QMimeData *data = cb->mimeData(); if (data->hasFormat("application/x-kde-cutselection")) { QByteArray a = data->data("application/x-kde-cutselection"); if (!a.isEmpty()) move = (a.at(0) == '1'); // true if 1 } QList urls = data->urls(); if (urls.isEmpty()) return ; if(origin && KConfigGroup(krConfig, "Look&Feel").readEntry("UnselectBeforeOperation", _UnselectBeforeOperation)) { origin->panel->view->saveSelection(); for(KrViewItem *item = origin->panel->view->getFirst(); item != 0; item = origin->panel->view->getNext(item)) { - if (urls.contains(item->getVfile()->vfile_getUrl())) + if (urls.contains(item->getFileItem()->getUrl())) item->setSelected(false); } } files()->addFiles(urls, move ? KIO::CopyJob::Move : KIO::CopyJob::Copy); } ListPanelFunc* ListPanelFunc::otherFunc() { return panel->otherPanel()->func; } void ListPanelFunc::historyGotoPos(int pos) { if(history->gotoPos(pos)) refresh(); } void ListPanelFunc::historyBackward() { if(history->goBack()) refresh(); } void ListPanelFunc::historyForward() { if(history->goForward()) refresh(); } void ListPanelFunc::dirUp() { openUrl(KIO::upUrl(files()->currentDirectory()), files()->currentDirectory().fileName()); } void ListPanelFunc::home() { openUrl(QUrl::fromLocalFile(QDir::homePath())); } void ListPanelFunc::root() { openUrl(QUrl::fromLocalFile(ROOT_DIR)); } void ListPanelFunc::cdToOtherPanel() { openUrl(panel->otherPanel()->virtualPath()); } void ListPanelFunc::syncOtherPanel() { otherFunc()->openUrl(panel->virtualPath()); } bool ListPanelFunc::atHome() { return QUrl::fromLocalFile(QDir::homePath()).matches(panel->virtualPath(), QUrl::StripTrailingSlash); } diff --git a/krusader/Panel/panelfunc.h b/krusader/Panel/panelfunc.h index 1ebee4e8..67ff99ed 100644 --- a/krusader/Panel/panelfunc.h +++ b/krusader/Panel/panelfunc.h @@ -1,163 +1,163 @@ /*************************************************************************** panelfunc.h ------------------- begin : Thu May 4 2000 copyright : (C) 2000 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PANELFUNC_H #define PANELFUNC_H #include "krviewitem.h" -#include "../VFS/vfs.h" +#include "../FileSystem/filesystem.h" // QtCore #include #include // QtGui #include #include class DirHistoryQueue; class ListPanel; class ListPanelFunc : public QObject { friend class ListPanel; Q_OBJECT public slots: void execute(const QString&); void goInside(const QString&); void navigatorUrlChanged(const QUrl &url); void openUrl(const QUrl &path, const QString& nameToMakeCurrent = QString(), bool manuallyEntered = false); // void popErronousUrl(); void immediateOpenUrl(const QUrl &url, bool disableLock = false); void rename(const QString &oldname, const QString &newname); // actions void historyBackward(); void historyForward(); void dirUp(); void refresh(); void home(); void root(); void cdToOtherPanel(); void FTPDisconnect(); void newFTPconnection(); void terminal(); void view(); void viewDlg(); void edit(); void editNew(); // create a new textfile and edit it void moveFilesByQueue(); // start in queue regardless of _queueMode state void copyFilesByQueue(); // start in queue regardless of _queueMode state void moveFiles(bool reverseQueueMode = false) { copyFiles(reverseQueueMode, true); } void copyFiles(bool reverseQueueMode = false, bool move = false); /*! * asks the user the new directory name */ void mkdir(); void deleteFiles(bool reallyDelete = false); // delete virtual files or directories in virtual filesystem void removeVirtualFiles(); void rename(); void krlink(bool sym = true); void createChecksum(); void matchChecksum(); void pack(); void unpack(); void testArchive(); // Calculate the occupied space of an item or the currently selected item and show it in a dialog void calcSpace(KrViewItem *item = 0); void properties(); void cut() { copyToClipboard(true); } void copyToClipboard(bool move = false); void pasteFromClipboard(); void syncOtherPanel(); public: ListPanelFunc(ListPanel *parent); ~ListPanelFunc(); - vfs* files(); // return a pointer to the vfs + FileSystem* files(); // return a pointer to the filesystem - inline vfile* getVFile(KrViewItem *item) { - return files()->getVfile(item->name()); + inline FileItem* getFileItem(KrViewItem *item) { + return files()->getFileItem(item->name()); } - inline vfile* getVFile(const QString& name) { - return files()->getVfile(name); + inline FileItem* getFileItem(const QString& name) { + return files()->getFileItem(name); } void refreshActions(); void redirectLink(); void runService(const KService &service, QList urls); void displayOpenWithDialog(QList urls); QUrl browsableArchivePath(const QString &); ListPanelFunc* otherFunc(); bool atHome(); - bool ignoreVFSErrors() { return _ignoreVFSErrors; } + bool ignoreFileSystemErrors() { return _ignoreFileSystemErrors; } protected slots: - // Load the current url from history and refresh vfs and panel to it. If this fails, try the + // Load the current url from history and refresh filesystem and panel to it. If this fails, try the // next url in history until success (last try is root) void doRefresh(); void slotFileCreated(KJob *job); // a file has been created by editNewFile() void historyGotoPos(int pos); void clipboardChanged(QClipboard::Mode mode); protected: QUrl cleanPath(const QUrl &url); bool isSyncing(const QUrl &url); // when externallyExecutable == true, the file can be executed or opened with other software void openFileNameInternal(const QString &name, bool externallyExecutable); void openUrlInternal(const QUrl &url, const QString& makeCurrent, bool immediately, bool disableLock, bool manuallyEntered); void runCommand(QString cmd); ListPanel* panel; // our ListPanel DirHistoryQueue* history; - vfs* vfsP; // pointer to vfs. + FileSystem* fileSystemP; // pointer to fileSystem. QTimer delayTimer; QUrl syncURL; QUrl fileToCreate; // file that's to be created by editNewFile() bool urlManuallyEntered; static QPointer copyToClipboardOrigin; private: bool _refreshing; // ignore url changes while refreshing - bool _ignoreVFSErrors; // ignore (repeated) errors emitted by vfs; + bool _ignoreFileSystemErrors; // ignore (repeated) errors emitted by filesystem; }; #endif diff --git a/krusader/Panel/panelpopup.cpp b/krusader/Panel/panelpopup.cpp index 21a95855..2ab200de 100644 --- a/krusader/Panel/panelpopup.cpp +++ b/krusader/Panel/panelpopup.cpp @@ -1,311 +1,311 @@ /***************************************************************************** * Copyright (C) 2003 Shie Erlich * * Copyright (C) 2003 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "panelpopup.h" #include "krfiletreeview.h" #include "krpanel.h" #include "krview.h" #include "krviewitem.h" #include "panelfunc.h" #include "viewactions.h" #include "../kicons.h" #include "../krmainwindow.h" #include "../defaults.h" #include "../Dialogs/krsqueezedtextlabel.h" #include "../KViewer/panelviewer.h" #include "../KViewer/diskusageviewer.h" // QtCore #include #include // QtWidgets #include #include #include #include #include PanelPopup::PanelPopup(QSplitter *parent, bool left, KrMainWindow *mainWindow) : QWidget(parent), _left(left), _hidden(true), _mainWindow(mainWindow), stack(0), viewer(0), pjob(0), splitterSizes() { splitter = parent; QGridLayout * layout = new QGridLayout(this); layout->setContentsMargins(0, 0, 0, 0); splitterSizes << 100 << 100; // create the label+buttons setup dataLine = new KrSqueezedTextLabel(this); KConfigGroup lg(krConfig, "Look&Feel"); dataLine->setFont(lg.readEntry("Filelist Font", _FilelistFont)); // --- hack: setup colors to be the same as an inactive panel dataLine->setBackgroundRole(QPalette::Window); int sheight = QFontMetrics(dataLine->font()).height() + 4; dataLine->setMaximumHeight(sheight); btns = new QButtonGroup(this); btns->setExclusive(true); connect(btns, SIGNAL(buttonClicked(int)), this, SLOT(tabSelected(int))); treeBtn = new QToolButton(this); treeBtn->setToolTip(i18n("Tree Panel: a tree view of the local file system")); treeBtn->setIcon(krLoader->loadIcon("view-list-tree", KIconLoader::Toolbar, 16)); treeBtn->setFixedSize(20, 20); treeBtn->setCheckable(true); btns->addButton(treeBtn, Tree); previewBtn = new QToolButton(this); previewBtn->setToolTip(i18n("Preview Panel: display a preview of the current file")); previewBtn->setIcon(krLoader->loadIcon("view-preview", KIconLoader::Toolbar, 16)); previewBtn->setFixedSize(20, 20); previewBtn->setCheckable(true); btns->addButton(previewBtn, Preview); viewerBtn = new QToolButton(this); viewerBtn->setToolTip(i18n("View Panel: view the current file")); viewerBtn->setIcon(krLoader->loadIcon("zoom-original", KIconLoader::Toolbar, 16)); viewerBtn->setFixedSize(20, 20); viewerBtn->setCheckable(true); btns->addButton(viewerBtn, View); duBtn = new QToolButton(this); duBtn->setToolTip(i18n("Disk Usage Panel: view the usage of a folder")); duBtn->setIcon(krLoader->loadIcon("kr_diskusage", KIconLoader::Toolbar, 16)); duBtn->setFixedSize(20, 20); duBtn->setCheckable(true); btns->addButton(duBtn, DskUsage); layout->addWidget(dataLine, 0, 0); layout->addWidget(treeBtn, 0, 1); layout->addWidget(previewBtn, 0, 2); layout->addWidget(viewerBtn, 0, 3); layout->addWidget(duBtn, 0, 4); // create a widget stack on which to put the parts stack = new QStackedWidget(this); // create the tree part ---------- tree = new KrFileTreeView(stack); tree->setAcceptDrops(true); tree->setDragDropMode(QTreeView::DropOnly); tree->setDropIndicatorShown(true); tree->setBriefMode(true); tree->setProperty("KrusaderWidgetId", QVariant(Tree)); stack->addWidget(tree); tree->setDirOnlyMode(true); // NOTE: the F2 key press event is catched before it gets to the tree tree->setEditTriggers(QAbstractItemView::EditKeyPressed); connect(tree, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(treeSelection())); connect(tree, SIGNAL(activated(const QUrl &)), this, SLOT(treeSelection())); // create the quickview part ------ viewer = new KImageFilePreview(stack); viewer->setProperty("KrusaderWidgetId", QVariant(Preview)); stack->addWidget(viewer); // create the panelview panelviewer = new PanelViewer(stack); panelviewer->setProperty("KrusaderWidgetId", QVariant(View)); stack->addWidget(panelviewer); connect(panelviewer, SIGNAL(openUrlRequest(const QUrl &)), this, SLOT(handleOpenUrlRequest(const QUrl &))); // create the disk usage view diskusage = new DiskUsageViewer(stack); diskusage->setStatusLabel(dataLine, i18n("Disk Usage:")); diskusage->setProperty("KrusaderWidgetId", QVariant(DskUsage)); stack->addWidget(diskusage); connect(diskusage, SIGNAL(openUrlRequest(const QUrl &)), this, SLOT(handleOpenUrlRequest(const QUrl &))); // -------- finish the layout (General one) layout->addWidget(stack, 1, 0, 1, 5); hide(); // for not to open the 3rd hand tool at start (selecting the last used tab) setCurrentPage(0); } PanelPopup::~PanelPopup() {} void PanelPopup::saveSettings(KConfigGroup cfg) const { if (currentPage() == Tree) { cfg.writeEntry("TreeBriefMode", tree->briefMode()); } } void PanelPopup::restoreSettings(KConfigGroup cfg) { tree->setBriefMode(cfg.readEntry("TreeBriefMode", true)); } void PanelPopup::setCurrentPage(int id) { QAbstractButton * curr = btns->button(id); if (curr) { curr->click(); } } void PanelPopup::show() { QWidget::show(); if (_hidden) splitter->setSizes(splitterSizes); _hidden = false; tabSelected(currentPage()); } void PanelPopup::hide() { if (!_hidden) splitterSizes = splitter->sizes(); QWidget::hide(); _hidden = true; if (currentPage() == View) panelviewer->closeUrl(); if (currentPage() == DskUsage) diskusage->closeUrl(); } void PanelPopup::focusInEvent(QFocusEvent*) { switch (currentPage()) { case Preview: if (!isHidden()) viewer->setFocus(); break; case View: if (!isHidden() && panelviewer->part() && panelviewer->part()->widget()) panelviewer->part()->widget()->setFocus(); break; case DskUsage: if (!isHidden() && diskusage->getWidget() && diskusage->getWidget()->currentWidget()) diskusage->getWidget()->currentWidget()->setFocus(); break; case Tree: if (!isHidden()) tree->setFocus(); break; } } void PanelPopup::handleOpenUrlRequest(const QUrl &url) { QMimeDatabase db; QMimeType mime = db.mimeTypeForUrl(url); if (mime.isValid() && mime.name() == "inode/directory") ACTIVE_PANEL->func->openUrl(url); } void PanelPopup::tabSelected(int id) { QUrl url; - const vfile *vf = 0; + const FileItem *fileitem = 0; if (ACTIVE_PANEL && ACTIVE_PANEL->func->files() && ACTIVE_PANEL->view) - vf = ACTIVE_PANEL->func->files()->getVfile(ACTIVE_PANEL->view->getCurrentItem()); - if(vf) - url = vf->vfile_getUrl(); + fileitem = ACTIVE_PANEL->func->files()->getFileItem(ACTIVE_PANEL->view->getCurrentItem()); + if(fileitem) + url = fileitem->getUrl(); // if tab is tree, set something logical in the data line switch (id) { case Tree: stack->setCurrentWidget(tree); dataLine->setText(i18n("Tree:")); if (!isHidden()) tree->setFocus(); if (ACTIVE_PANEL) tree->setCurrentUrl(ACTIVE_PANEL->func->files()->currentDirectory()); break; case Preview: stack->setCurrentWidget(viewer); dataLine->setText(i18n("Preview:")); - update(vf); + update(fileitem); break; case View: stack->setCurrentWidget(panelviewer); dataLine->setText(i18n("View:")); - update(vf); + update(fileitem); if (!isHidden() && panelviewer->part() && panelviewer->part()->widget()) panelviewer->part()->widget()->setFocus(); break; case DskUsage: stack->setCurrentWidget(diskusage); dataLine->setText(i18n("Disk Usage:")); - update(vf); + update(fileitem); if (!isHidden() && diskusage->getWidget() && diskusage->getWidget()->currentWidget()) diskusage->getWidget()->currentWidget()->setFocus(); break; } if (id != View) panelviewer->closeUrl(); } // decide which part to update, if at all -void PanelPopup::update(const vfile *vf) +void PanelPopup::update(const FileItem *fileitem) { if (isHidden()) return; QUrl url; - if(vf) - url = vf->vfile_getUrl(); + if(fileitem) + url = fileitem->getUrl(); switch (currentPage()) { case Preview: viewer->showPreview(url); dataLine->setText(i18n("Preview: %1", url.fileName())); break; case View: - if(vf && !vf->vfile_isDir() && vf->vfile_isReadable()) - panelviewer->openUrl(vf->vfile_getUrl()); + if(fileitem && !fileitem->isDir() && fileitem->isReadable()) + panelviewer->openUrl(fileitem->getUrl()); else panelviewer->closeUrl(); dataLine->setText(i18n("View: %1", url.fileName())); break; case DskUsage: { - if(vf && !vf->vfile_isDir()) + if(fileitem && !fileitem->isDir()) url = KIO::upUrl(url); dataLine->setText(i18n("Disk Usage: %1", url.fileName())); diskusage->openUrl(url); } break; case Tree: // nothing to do break; } } void PanelPopup::onPanelPathChange(const QUrl &url) { switch (currentPage()) { case Tree: if (url.isLocalFile()) { tree->setCurrentUrl(url); // synchronize panel path with tree path } break; } } // ------------------- tree void PanelPopup::treeSelection() { emit selection(tree->currentUrl()); //emit hideMe(); } diff --git a/krusader/Panel/panelpopup.h b/krusader/Panel/panelpopup.h index 6f42556b..9f4a96da 100644 --- a/krusader/Panel/panelpopup.h +++ b/krusader/Panel/panelpopup.h @@ -1,95 +1,95 @@ /***************************************************************************** * Copyright (C) 2003 Shie Erlich * * Copyright (C) 2003 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #ifndef PANELPOPUP_H #define PANELPOPUP_H // QtCore #include // QtGui // QtWidgets #include #include #include #include #include #include #include #include #include class KrSqueezedTextLabel; class PanelViewer; class DiskUsageViewer; class KrFileTreeView; -class vfile; +class FileItem; class KrMainWindow; class PanelPopup: public QWidget { Q_OBJECT enum Parts { Tree, Preview, View, DskUsage, Last = 0xFF }; public: PanelPopup(QSplitter *splitter, bool left, KrMainWindow *mainWindow); ~PanelPopup(); inline int currentPage() const { return stack->currentWidget()->property("KrusaderWidgetId").toInt(); } void saveSettings(KConfigGroup cfg) const; void restoreSettings(KConfigGroup cfg); void setCurrentPage(int); public slots: - void update(const vfile *vf); + void update(const FileItem *fileitem); void onPanelPathChange(const QUrl &url); void show(); void hide(); signals: void selection(const QUrl &url); void hideMe(); protected slots: void tabSelected(int id); void treeSelection(); void handleOpenUrlRequest(const QUrl &url); protected: virtual void focusInEvent(QFocusEvent*) Q_DECL_OVERRIDE; bool _left; bool _hidden; KrMainWindow *_mainWindow; QStackedWidget *stack; KImageFilePreview *viewer; KrSqueezedTextLabel *dataLine; QPointer pjob; KrFileTreeView *tree; QToolButton *treeBtn, *previewBtn, *viewerBtn, *duBtn; QButtonGroup *btns; KComboBox *quickSelectCombo; PanelViewer *panelviewer; DiskUsageViewer *diskusage; QList splitterSizes; QSplitter *splitter; }; #endif diff --git a/krusader/Search/krsearchdialog.cpp b/krusader/Search/krsearchdialog.cpp index a680c10f..6703b2c5 100644 --- a/krusader/Search/krsearchdialog.cpp +++ b/krusader/Search/krsearchdialog.cpp @@ -1,662 +1,662 @@ /*************************************************************************** krsearchdialog.cpp ------------------- copyright : (C) 2001 by Shie Erlich & Rafi Yanai email : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "krsearchdialog.h" // QtCore #include #include // QtGui #include #include #include #include #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include "../krglobal.h" #include "../kractions.h" #include "../krservices.h" #include "../krslots.h" #include "../defaults.h" #include "../panelmanager.h" #include "../kicons.h" #include "../krusaderview.h" #include "../Dialogs/krdialogs.h" #include "../Dialogs/krspecialwidgets.h" #include "../Dialogs/krsqueezedtextlabel.h" -#include "../VFS/virt_vfs.h" -#include "../VFS/krquery.h" +#include "../FileSystem/virtualfilesystem.h" +#include "../FileSystem/krquery.h" #include "../KViewer/krviewer.h" #include "../Panel/krsearchbar.h" #include "../Panel/krview.h" #include "../Panel/krviewfactory.h" #include "../Panel/krpanel.h" #include "../Panel/panelfunc.h" #include "../Filter/filtertabs.h" #include "../Filter/generalfilter.h" #define RESULTVIEW_TYPE 0 -class SearchResultContainer : public VfileContainer +class SearchResultContainer : public DirListerInterface { public: - SearchResultContainer(QObject *parent) : VfileContainer(parent) {} + SearchResultContainer(QObject *parent) : DirListerInterface(parent) {} virtual ~SearchResultContainer() { clear(); } - virtual QList vfiles() Q_DECL_OVERRIDE { - return _vfiles; + virtual QList fileItems() Q_DECL_OVERRIDE { + return _fileItems; } - virtual unsigned long numVfiles() Q_DECL_OVERRIDE { - return _vfiles.count(); + virtual unsigned long numFileItems() Q_DECL_OVERRIDE { + return _fileItems.count(); } virtual bool isRoot() Q_DECL_OVERRIDE { return true; } void clear() { emit cleared(); - foreach(vfile *vf, _vfiles) - delete vf; - _vfiles.clear(); + foreach(FileItem *fileitem, _fileItems) + delete fileitem; + _fileItems.clear(); _foundText.clear(); } - void addItem(const vfile &file, const QString &foundText) + void addItem(const FileItem &file, const QString &foundText) { - const QString path = file.vfile_getUrl().toDisplayString(QUrl::PreferLocalFile); - vfile *vf = vfile::createCopy(file, path); - _vfiles << vf; + const QString path = file.getUrl().toDisplayString(QUrl::PreferLocalFile); + FileItem *fileitem = FileItem::createCopy(file, path); + _fileItems << fileitem; if(!foundText.isEmpty()) - _foundText[vf] = foundText; - emit addedVfile(vf); + _foundText[fileitem] = foundText; + emit addedFileItem(fileitem); } - QString foundText(const vfile *vf) { - return _foundText[vf]; + QString foundText(const FileItem *fileitem) { + return _foundText[fileitem]; } private: - QList _vfiles; - QHash _foundText; + QList _fileItems; + QHash _foundText; }; KrSearchDialog *KrSearchDialog::SearchDialog = 0; QString KrSearchDialog::lastSearchText = "*"; int KrSearchDialog::lastSearchType = 0; bool KrSearchDialog::lastSearchForCase = false; bool KrSearchDialog::lastContainsWholeWord = false; bool KrSearchDialog::lastContainsWithCase = false; bool KrSearchDialog::lastSearchInSubDirs = true; bool KrSearchDialog::lastSearchInArchives = false; bool KrSearchDialog::lastFollowSymLinks = false; bool KrSearchDialog::lastContainsRegExp = false; // class starts here ///////////////////////////////////////// KrSearchDialog::KrSearchDialog(QString profile, QWidget* parent) : QDialog(parent), query(0), searcher(0), isBusy(false), closed(false) { KConfigGroup group(krConfig, "Search"); setWindowTitle(i18n("Krusader::Search")); setWindowIcon(QIcon::fromTheme("system-search")); QGridLayout* searchBaseLayout = new QGridLayout(this); searchBaseLayout->setSpacing(6); searchBaseLayout->setContentsMargins(11, 11, 11, 11); // creating the dialog buttons ( Search, Stop, Close ) QHBoxLayout* buttonsLayout = new QHBoxLayout(); buttonsLayout->setSpacing(6); buttonsLayout->setContentsMargins(0, 0, 0, 0); profileManager = new ProfileManager("SearcherProfile", this); buttonsLayout->addWidget(profileManager); QSpacerItem* spacer = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); buttonsLayout->addItem(spacer); mainFeedToListBoxBtn = new QPushButton(this); mainFeedToListBoxBtn->setText(i18n("Feed to listbox")); mainFeedToListBoxBtn->setIcon(QIcon::fromTheme("list-add")); mainFeedToListBoxBtn->setEnabled(false); buttonsLayout->addWidget(mainFeedToListBoxBtn); mainSearchBtn = new QPushButton(this); mainSearchBtn->setText(i18n("Search")); mainSearchBtn->setIcon(QIcon::fromTheme("edit-find")); mainSearchBtn->setDefault(true); buttonsLayout->addWidget(mainSearchBtn); mainStopBtn = new QPushButton(this); mainStopBtn->setEnabled(false); mainStopBtn->setText(i18n("Stop")); mainStopBtn->setIcon(QIcon::fromTheme("process-stop")); buttonsLayout->addWidget(mainStopBtn); mainCloseBtn = new QPushButton(this); mainCloseBtn->setText(i18n("Close")); mainCloseBtn->setIcon(QIcon::fromTheme("dialog-close")); buttonsLayout->addWidget(mainCloseBtn); searchBaseLayout->addLayout(buttonsLayout, 1, 0); // creating the searcher tabs searcherTabs = new QTabWidget(this); filterTabs = FilterTabs::addTo(searcherTabs, FilterTabs::Default); generalFilter = (GeneralFilter *)filterTabs->get("GeneralFilter"); QWidget* resultTab = new QWidget(searcherTabs); QGridLayout* resultLayout = new QGridLayout(resultTab); resultLayout->setSpacing(6); resultLayout->setContentsMargins(6, 6, 6, 6); // creating the result tab QHBoxLayout* resultLabelLayout = new QHBoxLayout(); resultLabelLayout->setSpacing(6); resultLabelLayout->setContentsMargins(0, 0, 0, 0); foundLabel = new QLabel(resultTab); QSizePolicy foundpolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); foundpolicy.setHeightForWidth(foundLabel->sizePolicy().hasHeightForWidth()); foundLabel->setSizePolicy(foundpolicy); foundLabel->setFrameShape(QLabel::StyledPanel); foundLabel->setFrameShadow(QLabel::Sunken); foundLabel->setText(i18n("Found 0 matches.")); resultLabelLayout->addWidget(foundLabel); searchingLabel = new KSqueezedTextLabel(resultTab); searchingLabel->setFrameShape(QLabel::StyledPanel); searchingLabel->setFrameShadow(QLabel::Sunken); searchingLabel->setText(""); resultLabelLayout->addWidget(searchingLabel); resultLayout->addLayout(resultLabelLayout, 2, 0); // creating the result list view result = new SearchResultContainer(this); // the view resultView = KrViewFactory::createView(RESULTVIEW_TYPE, resultTab, krConfig); resultView->init(false); resultView->restoreSettings(KConfigGroup(&group, "ResultView")); resultView->setMainWindow(this); resultView->prepareForActive(); resultView->refreshColors(); resultView->setFiles(result); resultView->refresh(); resultLayout->addWidget(resultView->widget(), 0, 0); // search bar searchBar = new KrSearchBar(resultView, this); searchBar->hide(); resultLayout->addWidget(searchBar, 1, 0); QHBoxLayout* foundTextLayout = new QHBoxLayout(); foundTextLayout->setSpacing(6); foundTextLayout->setContentsMargins(0, 0, 0, 0); QLabel *l1 = new QLabel(resultTab); QSizePolicy l1policy(QSizePolicy::Minimum, QSizePolicy::Minimum); l1policy.setHeightForWidth(l1->sizePolicy().hasHeightForWidth()); l1->setSizePolicy(l1policy); l1->setFrameShape(QLabel::StyledPanel); l1->setFrameShadow(QLabel::Sunken); l1->setText(i18n("Text found:")); foundTextLayout->addWidget(l1); foundTextLabel = new KrSqueezedTextLabel(resultTab); foundTextLabel->setFrameShape(QLabel::StyledPanel); foundTextLabel->setFrameShadow(QLabel::Sunken); foundTextLabel->setText(""); foundTextLayout->addWidget(foundTextLabel); resultLayout->addLayout(foundTextLayout, 3, 0); searcherTabs->addTab(resultTab, i18n("&Results")); searchBaseLayout->addWidget(searcherTabs, 0, 0); // signals and slots connections connect(mainSearchBtn, SIGNAL(clicked()), this, SLOT(startSearch())); connect(mainStopBtn, SIGNAL(clicked()), this, SLOT(stopSearch())); connect(mainCloseBtn, SIGNAL(clicked()), this, SLOT(closeDialog())); connect(mainFeedToListBoxBtn, SIGNAL(clicked()), this, SLOT(feedToListBox())); connect(profileManager, SIGNAL(loadFromProfile(QString)), filterTabs, SLOT(loadFromProfile(QString))); connect(profileManager, SIGNAL(saveToProfile(QString)), filterTabs, SLOT(saveToProfile(QString))); connect(resultView->op(), SIGNAL(currentChanged(KrViewItem*)), SLOT(currentChanged(KrViewItem*))); connect(resultView->op(), SIGNAL(executed(const QString&)), SLOT(executed(const QString&))); connect(resultView->op(), SIGNAL(contextMenu(const QPoint&)), SLOT(contextMenu(const QPoint &))); // tab order setTabOrder(mainSearchBtn, mainCloseBtn); setTabOrder(mainCloseBtn, mainStopBtn); setTabOrder(mainStopBtn, searcherTabs); setTabOrder(searcherTabs, resultView->widget()); sizeX = group.readEntry("Window Width", -1); sizeY = group.readEntry("Window Height", -1); if (sizeX != -1 && sizeY != -1) resize(sizeX, sizeY); if (group.readEntry("Window Maximized", false)) showMaximized(); else show(); generalFilter->searchFor->setFocus(); // finaly, load a profile of apply defaults: if (profile.isEmpty()) { // load the last used values generalFilter->searchFor->setEditText(lastSearchText); generalFilter->searchFor->lineEdit()->selectAll(); generalFilter->ofType->setCurrentIndex(lastSearchType); generalFilter->searchForCase->setChecked(lastSearchForCase); generalFilter->containsWholeWord->setChecked(lastContainsWholeWord); generalFilter->containsTextCase->setChecked(lastContainsWithCase); generalFilter->containsRegExp->setChecked(lastContainsRegExp); generalFilter->searchInDirs->setChecked(lastSearchInSubDirs); generalFilter->searchInArchives->setChecked(lastSearchInArchives); generalFilter->followLinks->setChecked(lastFollowSymLinks); // the path in the active panel should be the default search location generalFilter->searchIn->lineEdit()->setText(ACTIVE_PANEL->virtualPath().toDisplayString(QUrl::PreferLocalFile)); } else profileManager->loadProfile(profile); // important: call this _after_ you've connected profileManager ot the loadFromProfile!! } KrSearchDialog::~KrSearchDialog() { delete query; query = 0; delete resultView; resultView = 0; } void KrSearchDialog::closeDialog(bool isAccept) { if(isBusy) { closed = true; return; } // stop the search if it's on-going if (searcher != 0) { delete searcher; searcher = 0; } // saving the searcher state KConfigGroup group(krConfig, "Search"); group.writeEntry("Window Width", sizeX); group.writeEntry("Window Height", sizeY); group.writeEntry("Window Maximized", isMaximized()); resultView->saveSettings(KConfigGroup(&group, "ResultView")); lastSearchText = generalFilter->searchFor->currentText(); lastSearchType = generalFilter->ofType->currentIndex(); lastSearchForCase = generalFilter->searchForCase->isChecked(); lastContainsWholeWord = generalFilter->containsWholeWord->isChecked(); lastContainsWithCase = generalFilter->containsTextCase->isChecked(); lastContainsRegExp = generalFilter->containsRegExp->isChecked(); lastSearchInSubDirs = generalFilter->searchInDirs->isChecked(); lastSearchInArchives = generalFilter->searchInArchives->isChecked(); lastFollowSymLinks = generalFilter->followLinks->isChecked(); hide(); SearchDialog = 0; if (isAccept) QDialog::accept(); else QDialog::reject(); this->deleteLater(); } void KrSearchDialog::reject() { closeDialog(false); } void KrSearchDialog::resizeEvent(QResizeEvent *e) { if (!isMaximized()) { sizeX = e->size().width(); sizeY = e->size().height(); } } -void KrSearchDialog::slotFound(const vfile &file, const QString &foundText) +void KrSearchDialog::slotFound(const FileItem &file, const QString &foundText) { result->addItem(file, foundText); - foundLabel->setText(i18np("Found %1 match.", "Found %1 matches.", result->numVfiles())); + foundLabel->setText(i18np("Found %1 match.", "Found %1 matches.", result->numFileItems())); } bool KrSearchDialog::gui2query() { // prepare the query ... /////////////////// names, locations and greps if (query != 0) { delete query; query = 0; } query = new KRQuery(); return filterTabs->fillQuery(query); } void KrSearchDialog::startSearch() { if(isBusy) return; // prepare the query ///////////////////////////////////////////// if (!gui2query()) return; // first, informative messages if (query->searchInArchives()) { KMessageBox::information(this, i18n("Since you chose to also search in archives, " "note the following limitations:\n" "You cannot search for text (grep) while doing" " a search that includes archives."), 0, "searchInArchives"); } // prepare the gui /////////////////////////////////////////////// mainSearchBtn->setEnabled(false); mainCloseBtn->setEnabled(false); mainStopBtn->setEnabled(true); mainFeedToListBoxBtn->setEnabled(false); result->clear(); resultView->setSortMode(KrViewProperties::NoColumn, 0); searchingLabel->setText(""); foundLabel->setText(i18n("Found 0 matches.")); searcherTabs->setCurrentIndex(2); // show the results page foundTextLabel->setText(""); isBusy = true; qApp->processEvents(); // start the search. if (searcher != 0) abort(); searcher = new KRSearchMod(query); connect(searcher, SIGNAL(searching(const QString&)), searchingLabel, SLOT(setText(const QString&))); connect(searcher, &KRSearchMod::found, this, &KrSearchDialog::slotFound); connect(searcher, SIGNAL(finished()), this, SLOT(stopSearch())); searcher->start(); isBusy = false; delete searcher; searcher = 0; // gui stuff mainSearchBtn->setEnabled(true); mainCloseBtn->setEnabled(true); mainStopBtn->setEnabled(false); - if (result->numVfiles()) + if (result->numFileItems()) mainFeedToListBoxBtn->setEnabled(true); searchingLabel->setText(i18n("Finished searching.")); if (closed) closeDialog(); } void KrSearchDialog::stopSearch() { if (searcher != 0) { searcher->stop(); disconnect(searcher, 0, 0, 0); } } void KrSearchDialog::executed(const QString &name) { // 'name' is (local) file path or complete URL QString path = name; QString fileName; if(!name.endsWith('/')) { // not a directory, split filename and path int idx = name.lastIndexOf("/"); fileName = name.mid(idx+1); path = name.left(idx); } QUrl url(path); if (url.scheme().isEmpty()) url.setScheme("file"); ACTIVE_FUNC->openUrl(url, fileName); showMinimized(); } void KrSearchDialog::currentChanged(KrViewItem *item) { if(!item) return; - QString text = result->foundText(item->getVfile()); + QString text = result->foundText(item->getFileItem()); if(!text.isEmpty()) { // ugly hack: find the and in the text, then // use it to set the are which we don't want squeezed int idx = text.indexOf("") - 4; // take "" into account int length = text.indexOf("") - idx + 4; foundTextLabel->setText(text, idx, length); } } void KrSearchDialog::closeEvent(QCloseEvent *e) { /* if searching is in progress we must not close the window */ if (isBusy) /* because qApp->processEvents() is called by the searcher and */ { /* at window desruction, the searcher object will be deleted */ stopSearch(); /* instead we stop searching */ closed = true; /* and after stopping: startSearch can close the window */ e->ignore(); /* ignoring the close event */ } else QDialog::closeEvent(e); /* if no searching, let QDialog handle the event */ } void KrSearchDialog::keyPressEvent(QKeyEvent *e) { // TODO: don't use hardcoded shortcuts if (isBusy && e->key() == Qt::Key_Escape) { /* at searching we must not close the window */ stopSearch(); /* so we simply stop searching */ return; } if (resultView->widget()->hasFocus()) { if ((e->key() | e->modifiers()) == (Qt::CTRL | Qt::Key_I)) { searchBar->showBar(KrSearchBar::MODE_FILTER); } else if (e->key() == Qt::Key_F4) { if (!generalFilter->containsText->currentText().isEmpty() && QApplication::clipboard()->text() != generalFilter->containsText->currentText()) QApplication::clipboard()->setText(generalFilter->containsText->currentText()); editCurrent(); return; } else if (e->key() == Qt::Key_F3) { if (!generalFilter->containsText->currentText().isEmpty() && QApplication::clipboard()->text() != generalFilter->containsText->currentText()) QApplication::clipboard()->setText(generalFilter->containsText->currentText()); viewCurrent(); return; } else if (e->key() == Qt::Key_F10) { compareByContent(); return; } else if (KrGlobal::copyShortcut == QKeySequence(e->key() | e->modifiers())) { copyToClipBoard(); return; } } QDialog::keyPressEvent(e); } void KrSearchDialog::editCurrent() { KrViewItem *current = resultView->getCurrentKrViewItem(); if (current) - KrViewer::edit(current->getVfile()->vfile_getUrl(), this); + KrViewer::edit(current->getFileItem()->getUrl(), this); } void KrSearchDialog::viewCurrent() { KrViewItem *current = resultView->getCurrentKrViewItem(); if (current) - KrViewer::view(current->getVfile()->vfile_getUrl(), this); + KrViewer::view(current->getFileItem()->getUrl(), this); } void KrSearchDialog::compareByContent() { KrViewItemList list; resultView->getSelectedKrViewItems(&list); if (list.count() != 2) return; - SLOTS->compareContent(list[0]->getVfile()->vfile_getUrl(), list[1]->getVfile()->vfile_getUrl()); + SLOTS->compareContent(list[0]->getFileItem()->getUrl(), list[1]->getFileItem()->getUrl()); } void KrSearchDialog::contextMenu(const QPoint &pos) { // create the menu QMenu popup; popup.setTitle(i18n("Krusader Search")); QAction *actView = popup.addAction(i18n("View File (F3)")); QAction *actEdit = popup.addAction(i18n("Edit File (F4)")); QAction *actComp = popup.addAction(i18n("Compare by content (F10)")); if(resultView->numSelected() != 2) actComp->setEnabled(false); QAction *actClip = popup.addAction(i18n("Copy selected to clipboard")); QAction *result = popup.exec(pos); // check out the user's option if (result == actView) viewCurrent(); else if (result == actEdit) editCurrent(); else if (result == actClip) copyToClipBoard(); else if (result == actComp) compareByContent(); } void KrSearchDialog::feedToListBox() { - virt_vfs virtVfs; - virtVfs.refresh(QUrl::fromLocalFile("/")); + VirtualFileSystem virtFilesystem; + virtFilesystem.refresh(QUrl::fromLocalFile("/")); KConfigGroup group(krConfig, "Search"); int listBoxNum = group.readEntry("Feed To Listbox Counter", 1); QString queryName; if(query) { QString where = KrServices::toStringList(query->searchInDirs()).join(", "); if(query->content().isEmpty()) queryName = i18n("Search results for \"%1\" in %2", query->nameFilter(), where); else queryName = i18n("Search results for \"%1\" containing \"%2\" in %3", query->nameFilter(), query->content(), where); } - QString vfsName; + QString fileSystemName; do { - vfsName = i18n("Search results") + QString(" %1").arg(listBoxNum++); - } while (virtVfs.getVfile(vfsName) != 0); + fileSystemName = i18n("Search results") + QString(" %1").arg(listBoxNum++); + } while (virtFilesystem.getFileItem(fileSystemName) != 0); group.writeEntry("Feed To Listbox Counter", listBoxNum); KConfigGroup ga(krConfig, "Advanced"); if (ga.readEntry("Confirm Feed to Listbox", _ConfirmFeedToListbox)) { bool ok; - vfsName = QInputDialog::getText(this, i18n("Query name"), i18n("Here you can name the file collection"), - QLineEdit::Normal, vfsName, &ok); + fileSystemName = QInputDialog::getText(this, i18n("Query name"), i18n("Here you can name the file collection"), + QLineEdit::Normal, fileSystemName, &ok); if (! ok) return; } QList urlList; - foreach(vfile *vf, result->vfiles()) - urlList.push_back(vf->vfile_getUrl()); + foreach(FileItem *fileitem, result->fileItems()) + urlList.push_back(fileitem->getUrl()); mainSearchBtn->setEnabled(false); mainCloseBtn->setEnabled(false); mainFeedToListBoxBtn->setEnabled(false); isBusy = true; - QUrl url = QUrl(QString("virt:/") + vfsName); - virtVfs.refresh(url); - virtVfs.addFiles(urlList); - virtVfs.setMetaInformation(queryName); + QUrl url = QUrl(QString("virt:/") + fileSystemName); + virtFilesystem.refresh(url); + virtFilesystem.addFiles(urlList); + virtFilesystem.setMetaInformation(queryName); //ACTIVE_FUNC->openUrl(url); ACTIVE_MNG->slotNewTab(url); isBusy = false; closeDialog(); } void KrSearchDialog::copyToClipBoard() { QList urls; - foreach(vfile *vf, result->vfiles()) - urls.push_back(vf->vfile_getUrl()); + foreach(FileItem *fileitem, result->fileItems()) + urls.push_back(fileitem->getUrl()); if (urls.count() == 0) return; QMimeData *mimeData = new QMimeData; mimeData->setImageData(FL_LOADICON("file")); mimeData->setUrls(urls); QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); } diff --git a/krusader/Search/krsearchdialog.h b/krusader/Search/krsearchdialog.h index 6fab9c47..612ef426 100644 --- a/krusader/Search/krsearchdialog.h +++ b/krusader/Search/krsearchdialog.h @@ -1,129 +1,129 @@ /*************************************************************************** krsearchdialog.h ------------------- copyright : (C) 2001 by Shie Erlich & Rafi Yanai email : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KRSEARCHDIALOG_H #define KRSEARCHDIALOG_H // QtCore #include #include // QtWidgets #include #include "krsearchmod.h" class QLabel; class SearchResultContainer; class KrView; class KrViewItem; class ProfileManager; class FilterTabs; class GeneralFilter; class QTabWidget; class KSqueezedTextLabel; class KrSqueezedTextLabel; class KrSearchBar; class KrSearchDialog : public QDialog { Q_OBJECT public: KrSearchDialog(QString profile = QString(), QWidget* parent = 0); ~KrSearchDialog(); void prepareGUI(); static KrSearchDialog *SearchDialog; public slots: void startSearch(); void stopSearch(); void feedToListBox(); void copyToClipBoard(); - void slotFound(const vfile &file, const QString &foundText); + void slotFound(const FileItem &file, const QString &foundText); void closeDialog(bool isAccept = true); void executed(const QString &name); void currentChanged(KrViewItem *item); void contextMenu(const QPoint &); virtual void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; virtual void closeEvent(QCloseEvent *e) Q_DECL_OVERRIDE; virtual void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE; protected slots: void reject(); private: bool gui2query(); void editCurrent(); void viewCurrent(); void compareByContent(); private: ProfileManager *profileManager; FilterTabs * filterTabs; GeneralFilter * generalFilter; QPushButton* mainSearchBtn; QPushButton* mainStopBtn; QPushButton* mainCloseBtn; QPushButton* mainFeedToListBoxBtn; QTabWidget* searcherTabs; QLabel* foundLabel; KrSqueezedTextLabel *foundTextLabel; KSqueezedTextLabel *searchingLabel; SearchResultContainer *result; KrView *resultView; KrSearchBar *searchBar; KRQuery *query; KRSearchMod *searcher; bool isBusy; bool closed; static QString lastSearchText; static int lastSearchType; static bool lastSearchForCase; static bool lastContainsWholeWord; static bool lastContainsWithCase; static bool lastSearchInSubDirs; static bool lastSearchInArchives; static bool lastFollowSymLinks; static bool lastContainsRegExp; int sizeX; int sizeY; }; #endif diff --git a/krusader/Search/krsearchmod.cpp b/krusader/Search/krsearchmod.cpp index 8bee1b39..b569b0d3 100644 --- a/krusader/Search/krsearchmod.cpp +++ b/krusader/Search/krsearchmod.cpp @@ -1,236 +1,236 @@ /*************************************************************************** krsearchmod.cpp ------------------- copyright : (C) 2001 by Shie Erlich & Rafi Yanai email : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "krsearchmod.h" // QtCore #include #include #include #include // QtWidgets #include #include #include -#include "../VFS/krquery.h" -#include "../VFS/vfile.h" -#include "../VFS/krpermhandler.h" +#include "../FileSystem/krquery.h" +#include "../FileSystem/fileitem.h" +#include "../FileSystem/krpermhandler.h" #include "../Archive/krarchandler.h" #define EVENT_PROCESS_DELAY 250 extern KRarcHandler arcHandler; KRSearchMod::KRSearchMod(const KRQuery* q) { stopSearch = false; /// ===> added query = new KRQuery(*q); connect(query, SIGNAL(status(const QString &)), this, SIGNAL(searching(const QString&))); connect(query, SIGNAL(processEvents(bool &)), this, SLOT(slotProcessEvents(bool &))); - remote_vfs = 0; - virtual_vfs = 0; + remote_fileSystem = 0; + virtual_fileSystem = 0; } KRSearchMod::~KRSearchMod() { delete query; - if (remote_vfs) - delete remote_vfs; - if (virtual_vfs) - delete virtual_vfs; + if (remote_fileSystem) + delete remote_fileSystem; + if (virtual_fileSystem) + delete virtual_fileSystem; } void KRSearchMod::start() { unScannedUrls.clear(); scannedUrls.clear(); timer.start(); QList whereToSearch = query->searchInDirs(); // search every dir that needs to be searched for (int i = 0; i < whereToSearch.count(); ++i) scanURL(whereToSearch [ i ]); emit finished(); } void KRSearchMod::stop() { stopSearch = true; } void KRSearchMod::scanURL(QUrl url) { if (stopSearch) return; unScannedUrls.push(url); while (!unScannedUrls.isEmpty()) { QUrl urlToCheck = unScannedUrls.pop(); if (stopSearch) return; if (query->isExcluded(urlToCheck)) { if (!query->searchInDirs().contains(urlToCheck)) continue; } if (scannedUrls.contains(urlToCheck)) continue; scannedUrls.push(urlToCheck); emit searching(urlToCheck.toDisplayString(QUrl::PreferLocalFile)); if (urlToCheck.isLocalFile()) scanLocalDir(urlToCheck); else scanRemoteDir(urlToCheck); } } void KRSearchMod::scanLocalDir(const QUrl &url) { - const QString dir = vfs::ensureTrailingSlash(url).path(); + const QString dir = FileSystem::ensureTrailingSlash(url).path(); QT_DIR *qdir = QT_OPENDIR(dir.toLocal8Bit()); if (!qdir) return; QT_DIRENT *dirEnt; while ((dirEnt = QT_READDIR(qdir)) != NULL) { const QString name = QString::fromLocal8Bit(dirEnt->d_name); // we don't scan the ".",".." enteries if (name == "." || name == "..") continue; const QString fullName = dir + name; const QUrl fileUrl = QUrl::fromLocalFile(fullName); QT_STATBUF stat_p; QT_LSTAT(fullName.toLocal8Bit(), &stat_p); if (query->isRecursive()) { if (S_ISLNK(stat_p.st_mode) && query->followLinks()) unScannedUrls.push(QUrl::fromLocalFile(QDir(fullName).canonicalPath())); else if (S_ISDIR(stat_p.st_mode)) unScannedUrls.push(fileUrl); } - // creating a vfile object for matching with krquery - vfile *vf = vfs::createLocalVFile(name, dir); + // creating a file item object for matching with krquery + FileItem *fileitem = FileSystem::createLocalFileItem(name, dir); if (query->searchInArchives()) { - const QString mime = vf->vfile_getMime(); + const QString mime = fileitem->getMime(); if (KRarcHandler::arcSupported(mime)) { QUrl archiveURL = fileUrl; bool encrypted; const QString realType = arcHandler.getType(encrypted, fileUrl.path(), mime); if (!encrypted) { if (realType == "tbz" || realType == "tgz" || realType == "tarz" || realType == "tar" || realType == "tlz") archiveURL.setScheme("tar"); else archiveURL.setScheme("krarc"); unScannedUrls.push(archiveURL); } } } - if (query->match(vf)) { + if (query->match(fileitem)) { // if we got here - we got a winner results.append(fullName); - emit found(*vf, query->foundText()); // emitting copy of vfile + emit found(*fileitem, query->foundText()); // emitting copy of file item } - delete vf; + delete fileitem; if (timer.elapsed() >= EVENT_PROCESS_DELAY) { qApp->processEvents(); timer.start(); if (stopSearch) return; } } // clean up QT_CLOSEDIR(qdir); } void KRSearchMod::scanRemoteDir(QUrl url) { - vfs * vfs_; + FileSystem * fileSystem_; if (url.scheme() == QStringLiteral("virt")) { - if (virtual_vfs == 0) - virtual_vfs = new virt_vfs(); - vfs_ = virtual_vfs; + if (virtual_fileSystem == 0) + virtual_fileSystem = new VirtualFileSystem(); + fileSystem_ = virtual_fileSystem; } else { - if (remote_vfs == 0) - remote_vfs = new default_vfs(); - vfs_ = remote_vfs; + if (remote_fileSystem == 0) + remote_fileSystem = new DefaultFileSystem(); + fileSystem_ = remote_fileSystem; } - if (!vfs_->refresh(url)) return ; + if (!fileSystem_->refresh(url)) return ; - for (vfile *vf : vfs_->vfiles()) { - QUrl fileURL = vf->vfile_getUrl(); + for (FileItem *fileitem : fileSystem_->fileItems()) { + QUrl fileURL = fileitem->getUrl(); - if (query->isRecursive() && ((vf->vfile_isSymLink() && query->followLinks()) || vf->vfile_isDir())) + if (query->isRecursive() && ((fileitem->isSymLink() && query->followLinks()) || fileitem->isDir())) unScannedUrls.push(fileURL); - if (query->match(vf)) { + if (query->match(fileitem)) { // if we got here - we got a winner results.append(fileURL.toDisplayString(QUrl::PreferLocalFile)); - emit found(*vf, query->foundText()); // emitting copy of vfile + emit found(*fileitem, query->foundText()); // emitting copy of file item } if (timer.elapsed() >= EVENT_PROCESS_DELAY) { qApp->processEvents(); timer.start(); if (stopSearch) return; } } } void KRSearchMod::slotProcessEvents(bool & stopped) { qApp->processEvents(); stopped = stopSearch; } diff --git a/krusader/Search/krsearchmod.h b/krusader/Search/krsearchmod.h index 4b64a86d..29322ed2 100644 --- a/krusader/Search/krsearchmod.h +++ b/krusader/Search/krsearchmod.h @@ -1,88 +1,88 @@ /*************************************************************************** krsearchmod.h ------------------- copyright : (C) 2001 by Shie Erlich & Rafi Yanai email : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KRSEARCHMOD_H #define KRSEARCHMOD_H // QtCore #include #include #include #include #include #include -#include "../VFS/default_vfs.h" -#include "../VFS/virt_vfs.h" +#include "../FileSystem/defaultfilesystem.h" +#include "../FileSystem/virtualfilesystem.h" class KRQuery; -class ftp_vfs; +class ftp_fileSystem; class KRSearchMod : public QObject { Q_OBJECT public: KRSearchMod(const KRQuery *q); ~KRSearchMod(); void scanURL(QUrl url); void start(); void stop(); private: void scanLocalDir(const QUrl &url); void scanRemoteDir(QUrl url); signals: void finished(); void searching(const QString&); - void found(const vfile &file, const QString &foundText); + void found(const FileItem &file, const QString &foundText); private slots: void slotProcessEvents(bool & stopped); private: bool stopSearch; QStack scannedUrls; QStack unScannedUrls; KRQuery *query; QStringList results; - default_vfs *remote_vfs; - virt_vfs *virtual_vfs; + DefaultFileSystem *remote_fileSystem; + VirtualFileSystem *virtual_fileSystem; QTime timer; }; #endif diff --git a/krusader/Splitter/combiner.cpp b/krusader/Splitter/combiner.cpp index 6755ed57..74828411 100644 --- a/krusader/Splitter/combiner.cpp +++ b/krusader/Splitter/combiner.cpp @@ -1,358 +1,358 @@ /*************************************************************************** combiner.cpp - description ------------------- copyright : (C) 2003 by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "combiner.h" -#include "../VFS/vfs.h" +#include "../FileSystem/filesystem.h" // QtCore #include #include #include #include #include #include //TODO: delete destination file on error //TODO: cache more than one byte array of data Combiner::Combiner(QWidget* parent, QUrl baseURLIn, QUrl destinationURLIn, bool unixNamingIn) : QProgressDialog(parent, 0), baseURL(baseURLIn), destinationURL(destinationURLIn), hasValidSplitFile(false), fileCounter(0), permissions(-1), receivedSize(0), statJob(0), combineReadJob(0), combineWriteJob(0), unixNaming(unixNamingIn) { crcContext = new CRC32(); splitFile = ""; setMaximum(100); setAutoClose(false); /* don't close or reset the dialog automatically */ setAutoReset(false); setLabelText("Krusader::Combiner"); setWindowModality(Qt::WindowModal); firstFileIs000 = true; //start with this assumption, will set it to false as soon as .000 isn't found } Combiner::~Combiner() { combineAbortJobs(); delete crcContext; } void Combiner::combine() { setWindowTitle(i18n("Krusader::Combining...")); setLabelText(i18n("Combining the file %1...", baseURL.toDisplayString(QUrl::PreferLocalFile))); /* check whether the .crc file exists */ splURL = baseURL.adjusted(QUrl::RemoveFilename); splURL.setPath(splURL.path() + baseURL.fileName() + ".crc"); KFileItem file(splURL); //FIXME: works only for local files - use KIO::stat() instead file.refresh(); if (!file.isReadable()) { int ret = KMessageBox::questionYesNo(0, i18n("The CRC information file (%1) is missing.\n" "Validity checking is impossible without it. Continue combining?", splURL.toDisplayString(QUrl::PreferLocalFile))); if (ret == KMessageBox::No) { emit reject(); return; } statDest(); } else { permissions = file.permissions() | QFile::WriteUser; combineReadJob = KIO::get(splURL, KIO::NoReload, KIO::HideProgressInfo); connect(combineReadJob, SIGNAL(data(KIO::Job *, const QByteArray &)), this, SLOT(combineSplitFileDataReceived(KIO::Job *, const QByteArray &))); connect(combineReadJob, SIGNAL(result(KJob*)), this, SLOT(combineSplitFileFinished(KJob *))); } exec(); } void Combiner::combineSplitFileDataReceived(KIO::Job *, const QByteArray &byteArray) { splitFile += QString(byteArray); } void Combiner::combineSplitFileFinished(KJob *job) { combineReadJob = 0; QString error; if (job->error()) error = i18n("Error at reading the CRC file (%1).", splURL.toDisplayString(QUrl::PreferLocalFile)); else { splitFile.remove('\r'); // Windows compatibility QStringList splitFileContent = splitFile.split('\n'); bool hasFileName = false, hasSize = false, hasCrc = false; for (int i = 0; i != splitFileContent.count(); i++) { int ndx = splitFileContent[i].indexOf('='); if (ndx == -1) continue; QString token = splitFileContent[i].left(ndx).trimmed(); QString value = splitFileContent[i].mid(ndx + 1); if (token == "filename") { expectedFileName = value; hasFileName = true; } else if (token == "size") { //FIXME - don't use c functions !!! sscanf(value.trimmed().toLocal8Bit(), "%llu", &expectedSize); hasSize = true; } if (token == "crc32") { expectedCrcSum = value.trimmed().rightJustified(8, '0'); hasCrc = true; } } if (!hasFileName || !hasSize || !hasCrc) error = i18n("Not a valid CRC file."); else hasValidSplitFile = true; } if (!error.isEmpty()) { int ret = KMessageBox::questionYesNo(0, error + i18n("\nValidity checking is impossible without a good CRC file. Continue combining?")); if (ret == KMessageBox::No) { emit reject(); return; } } statDest(); } void Combiner::statDest() { if (writeURL.isEmpty()) { - writeURL = vfs::ensureTrailingSlash(destinationURL); + writeURL = FileSystem::ensureTrailingSlash(destinationURL); if (hasValidSplitFile) writeURL.setPath(writeURL.path() + expectedFileName); else if (unixNaming) writeURL.setPath(writeURL.path() + baseURL.fileName() + ".out"); else writeURL.setPath(writeURL.path() + baseURL.fileName()); } statJob = KIO::stat(writeURL, KIO::StatJob::DestinationSide, 0, KIO::HideProgressInfo); connect(statJob, SIGNAL(result(KJob*)), SLOT(statDestResult(KJob*))); } void Combiner::statDestResult(KJob* job) { statJob = 0; if (job->error()) { if (job->error() == KIO::ERR_DOES_NOT_EXIST) { openNextFile(); } else { static_cast(job)->ui()->showErrorMessage(); emit reject(); } } else { // destination already exists KIO::RenameDialog_Options mode = static_cast(job)->statResult().isDir() ? KIO::RenameDialog_IsDirectory : KIO::RenameDialog_Overwrite; KIO::RenameDialog dlg(this, i18n("File Already Exists"), QUrl(), writeURL, mode); switch (dlg.exec()) { case KIO::R_OVERWRITE: openNextFile(); break; case KIO::R_RENAME: { writeURL = dlg.newDestUrl(); statDest(); break; } default: emit reject(); } } } void Combiner::openNextFile() { if (unixNaming) { if (readURL.isEmpty()) readURL = baseURL; else { QString name = readURL.fileName(); int pos = name.length() - 1; QChar ch; do { ch = name.at(pos).toLatin1() + 1; if (ch == QChar('Z' + 1)) ch = 'A'; if (ch == QChar('z' + 1)) ch = 'a'; name[ pos ] = ch; pos--; } while (pos >= 0 && ch.toUpper() == QChar('A')); readURL = readURL.adjusted(QUrl::RemoveFilename); readURL.setPath(readURL.path() + name); } } else { QString index("%1"); /* determining the filename */ index = index.arg(fileCounter++).rightJustified(3, '0'); readURL = baseURL.adjusted(QUrl::RemoveFilename); readURL.setPath(readURL.path() + baseURL.fileName() + '.' + index); } /* creating a read job */ combineReadJob = KIO::get(readURL, KIO::NoReload, KIO::HideProgressInfo); connect(combineReadJob, SIGNAL(data(KIO::Job *, const QByteArray &)), this, SLOT(combineDataReceived(KIO::Job *, const QByteArray &))); connect(combineReadJob, SIGNAL(result(KJob*)), this, SLOT(combineReceiveFinished(KJob *))); if (hasValidSplitFile) connect(combineReadJob, SIGNAL(percent(KJob *, unsigned long)), this, SLOT(combineWritePercent(KJob *, unsigned long))); } void Combiner::combineDataReceived(KIO::Job *, const QByteArray &byteArray) { if (byteArray.size() == 0) return; crcContext->update((unsigned char *)byteArray.data(), byteArray.size()); transferArray = QByteArray(byteArray.data(), byteArray.length()); receivedSize += byteArray.size(); if (combineWriteJob == 0) { combineWriteJob = KIO::put(writeURL, permissions, KIO::HideProgressInfo | KIO::Overwrite); connect(combineWriteJob, SIGNAL(dataReq(KIO::Job *, QByteArray &)), this, SLOT(combineDataSend(KIO::Job *, QByteArray &))); connect(combineWriteJob, SIGNAL(result(KJob*)), this, SLOT(combineSendFinished(KJob *))); } // continue writing and suspend read job until received data is handed over to the write job combineReadJob->suspend(); combineWriteJob->resume(); } void Combiner::combineReceiveFinished(KJob *job) { combineReadJob = 0; /* KIO automatically deletes the object after Finished signal */ if (job->error()) { if (job->error() == KIO::ERR_DOES_NOT_EXIST) { if (fileCounter == 1) { // .000 file doesn't exist but .001 is still a valid first file firstFileIs000 = false; openNextFile(); } else if (!firstFileIs000 && fileCounter == 2) { // neither .000 nor .001 exist combineAbortJobs(); KMessageBox::error(0, i18n("Cannot open the first split file of %1.", baseURL.toDisplayString(QUrl::PreferLocalFile))); emit reject(); } else { // we've received the last file // write out the remaining part of the file combineWriteJob->resume(); if (hasValidSplitFile) { QString crcResult = QString("%1").arg(crcContext->result(), 0, 16).toUpper().trimmed() .rightJustified(8, '0'); if (receivedSize != expectedSize) error = i18n("Incorrect filesize, the file might have been corrupted."); else if (crcResult != expectedCrcSum.toUpper().trimmed()) error = i18n("Incorrect CRC checksum, the file might have been corrupted."); } } } else { combineAbortJobs(); static_cast(job)->ui()->showErrorMessage(); emit reject(); } } else openNextFile(); } void Combiner::combineDataSend(KIO::Job *, QByteArray &byteArray) { byteArray = transferArray; transferArray = QByteArray(); if (combineReadJob) { // continue reading and suspend write job until data is available combineReadJob->resume(); combineWriteJob->suspend(); } } void Combiner::combineSendFinished(KJob *job) { combineWriteJob = 0; /* KIO automatically deletes the object after Finished signal */ if (job->error()) { /* any error occurred? */ combineAbortJobs(); static_cast(job)->ui()->showErrorMessage(); emit reject(); } else if (!error.isEmpty()) { /* was any error message at reading ? */ combineAbortJobs(); /* we cannot write out it in combineReceiveFinished */ KMessageBox::error(0, error); /* because emit accept closes it in this function */ emit reject(); } else emit accept(); } void Combiner::combineAbortJobs() { if (statJob) statJob->kill(KJob::Quietly); if (combineReadJob) combineReadJob->kill(KJob::Quietly); if (combineWriteJob) combineWriteJob->kill(KJob::Quietly); statJob = combineReadJob = combineWriteJob = 0; } void Combiner::combineWritePercent(KJob *, unsigned long) { int percent = (int)((((double)receivedSize / expectedSize) * 100.) + 0.5); setValue(percent); } diff --git a/krusader/Splitter/splitter.cpp b/krusader/Splitter/splitter.cpp index d2f0df37..20c9b777 100644 --- a/krusader/Splitter/splitter.cpp +++ b/krusader/Splitter/splitter.cpp @@ -1,310 +1,310 @@ /*************************************************************************** splitter.cpp - description ------------------- copyright : (C) 2003 by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "splitter.h" -#include "../VFS/vfs.h" +#include "../FileSystem/filesystem.h" // QtCore #include // QtWidgets #include #include #include #include #include #include Splitter::Splitter(QWidget* parent, QUrl fileNameIn, QUrl destinationDirIn, bool overWriteIn) : QProgressDialog(parent, 0), fileName(fileNameIn), destinationDir(destinationDirIn), splitSize(0), permissions(0), overwrite(overWriteIn), fileNumber(0), outputFileRemaining(0), receivedSize(0), crcContext(new CRC32()), statJob(0), splitReadJob(0), splitWriteJob(0) { setMaximum(100); setAutoClose(false); /* don't close or reset the dialog automatically */ setAutoReset(false); setLabelText("Krusader::Splitter"); setWindowModality(Qt::WindowModal); } Splitter::~Splitter() { splitAbortJobs(); delete crcContext; } void Splitter::split(KIO::filesize_t splitSizeIn) { Q_ASSERT(!splitReadJob); Q_ASSERT(!splitWriteJob); Q_ASSERT(!fileNumber); Q_ASSERT(!receivedSize); Q_ASSERT(!outputFileRemaining); splitReadJob = splitWriteJob = 0; fileNumber = receivedSize = outputFileRemaining = 0; splitSize = splitSizeIn; KFileItem file(fileName); file.refresh(); //FIXME: works only for local files - use KIO::stat() instead permissions = file.permissions() | QFile::WriteUser; setWindowTitle(i18n("Krusader::Splitting...")); setLabelText(i18n("Splitting the file %1...", fileName.toDisplayString(QUrl::PreferLocalFile))); if (file.isDir()) { KMessageBox::error(0, i18n("Cannot split a folder.")); return; } splitReadJob = KIO::get(fileName, KIO::NoReload, KIO::HideProgressInfo); connect(splitReadJob, SIGNAL(data(KIO::Job *, const QByteArray &)), this, SLOT(splitDataReceived(KIO::Job *, const QByteArray &))); connect(splitReadJob, SIGNAL(result(KJob*)), this, SLOT(splitReceiveFinished(KJob *))); connect(splitReadJob, SIGNAL(percent(KJob *, unsigned long)), this, SLOT(splitReceivePercent(KJob *, unsigned long))); exec(); } void Splitter::splitDataReceived(KIO::Job *, const QByteArray &byteArray) { Q_ASSERT(!transferArray.length()); // transfer buffer must be empty if (byteArray.size() == 0) return; crcContext->update((unsigned char *)byteArray.data(), byteArray.size()); receivedSize += byteArray.size(); if (!splitWriteJob) nextOutputFile(); transferArray = QByteArray(byteArray.data(), byteArray.length()); // suspend read job until transfer buffer is handed to the write job splitReadJob->suspend(); if (splitWriteJob) splitWriteJob->resume(); } void Splitter::splitReceiveFinished(KJob *job) { splitReadJob = 0; /* KIO automatically deletes the object after Finished signal */ if (splitWriteJob) splitWriteJob->resume(); // finish writing the output if (job->error()) { /* any error occurred? */ splitAbortJobs(); KMessageBox::error(0, i18n("Error reading file %1: %2", fileName.toDisplayString(QUrl::PreferLocalFile), job->errorString())); emit reject(); return; } QString crcResult = QString("%1").arg(crcContext->result(), 0, 16).toUpper().trimmed() .rightJustified(8, '0'); splitInfoFileContent = QString("filename=%1\n").arg(fileName.fileName()) + QString("size=%1\n") .arg(KIO::number(receivedSize)) + QString("crc32=%1\n") .arg(crcResult); } void Splitter::splitReceivePercent(KJob *, unsigned long percent) { setValue(percent); } void Splitter::nextOutputFile() { Q_ASSERT(!outputFileRemaining); fileNumber++; outputFileRemaining = splitSize; QString index("%1"); /* making the split filename */ index = index.arg(fileNumber).rightJustified(3, '0'); QString outFileName = fileName.fileName() + '.' + index; writeURL = destinationDir; writeURL = writeURL.adjusted(QUrl::StripTrailingSlash); writeURL.setPath(writeURL.path() + '/' + (outFileName)); if (overwrite) openOutputFile(); else { statJob = KIO::stat(writeURL, KIO::StatJob::DestinationSide, 0, KIO::HideProgressInfo); connect(statJob, SIGNAL(result(KJob*)), SLOT(statOutputFileResult(KJob*))); } } void Splitter::statOutputFileResult(KJob* job) { statJob = 0; if (job->error()) { if (job->error() == KIO::ERR_DOES_NOT_EXIST) openOutputFile(); else { static_cast(job)->ui()->showErrorMessage(); emit reject(); } } else { // destination already exists KIO::RenameDialog dlg(this, i18n("File Already Exists"), QUrl(), writeURL, static_cast(KIO::M_MULTI | KIO::M_OVERWRITE | KIO::M_NORENAME)); switch (dlg.exec()) { case KIO::R_OVERWRITE: openOutputFile(); break; case KIO::R_OVERWRITE_ALL: overwrite = true; openOutputFile(); break; default: emit reject(); } } } void Splitter::openOutputFile() { // create write job splitWriteJob = KIO::put(writeURL, permissions, KIO::HideProgressInfo | KIO::Overwrite); connect(splitWriteJob, SIGNAL(dataReq(KIO::Job *, QByteArray &)), this, SLOT(splitDataSend(KIO::Job *, QByteArray &))); connect(splitWriteJob, SIGNAL(result(KJob*)), this, SLOT(splitSendFinished(KJob *))); } void Splitter::splitDataSend(KIO::Job *, QByteArray &byteArray) { KIO::filesize_t bufferLen = transferArray.size(); if (!outputFileRemaining) { // current output file needs to be closed ? byteArray = QByteArray(); // giving empty buffer which indicates closing } else if (bufferLen > outputFileRemaining) { // maximum length reached ? byteArray = QByteArray(transferArray.data(), outputFileRemaining); transferArray = QByteArray(transferArray.data() + outputFileRemaining, bufferLen - outputFileRemaining); outputFileRemaining = 0; } else { outputFileRemaining -= bufferLen; // write the whole buffer to the output file byteArray = transferArray; transferArray = QByteArray(); if (splitReadJob) { // suspend write job until transfer buffer is filled or the read job is finished splitWriteJob->suspend(); splitReadJob->resume(); } // else: write job continues until transfer buffer is empty } } void Splitter::splitSendFinished(KJob *job) { splitWriteJob = 0; /* KIO automatically deletes the object after Finished signal */ if (job->error()) { /* any error occurred? */ splitAbortJobs(); KMessageBox::error(0, i18n("Error writing file %1: %2", writeURL.toDisplayString(QUrl::PreferLocalFile), job->errorString())); emit reject(); return; } if (transferArray.size()) /* any data remained in the transfer buffer? */ nextOutputFile(); else if (splitReadJob) splitReadJob->resume(); else { // read job is finished and transfer buffer is empty -> splitting is finished /* writing the split information file out */ writeURL = destinationDir; writeURL = writeURL.adjusted(QUrl::StripTrailingSlash); writeURL.setPath(writeURL.path() + '/' + (fileName.fileName() + ".crc")); splitWriteJob = KIO::put(writeURL, permissions, KIO::HideProgressInfo | KIO::Overwrite); connect(splitWriteJob, SIGNAL(dataReq(KIO::Job *, QByteArray &)), this, SLOT(splitFileSend(KIO::Job *, QByteArray &))); connect(splitWriteJob, SIGNAL(result(KJob*)), this, SLOT(splitFileFinished(KJob *))); } } void Splitter::splitAbortJobs() { if (statJob) statJob->kill(KJob::Quietly); if (splitReadJob) splitReadJob->kill(KJob::Quietly); if (splitWriteJob) splitWriteJob->kill(KJob::Quietly); splitReadJob = splitWriteJob = 0; } void Splitter::splitFileSend(KIO::Job *, QByteArray &byteArray) { byteArray = splitInfoFileContent.toLocal8Bit(); splitInfoFileContent = ""; } void Splitter::splitFileFinished(KJob *job) { splitWriteJob = 0; /* KIO automatically deletes the object after Finished signal */ if (job->error()) { /* any error occurred? */ KMessageBox::error(0, i18n("Error writing file %1: %2", writeURL.toDisplayString(QUrl::PreferLocalFile), job->errorString())); emit reject(); return; } emit accept(); } diff --git a/krusader/Splitter/splittergui.cpp b/krusader/Splitter/splittergui.cpp index a3d15fee..d8902530 100644 --- a/krusader/Splitter/splittergui.cpp +++ b/krusader/Splitter/splittergui.cpp @@ -1,275 +1,275 @@ /*************************************************************************** splittergui.cpp - description ------------------- copyright : (C) 2003 by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "splittergui.h" -#include "../VFS/vfs.h" +#include "../FileSystem/filesystem.h" // QtCore #include // QtGui #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct SplitterGUI::PredefinedDevice { PredefinedDevice(QString name, KIO::filesize_t capacity) : name(name), capacity(capacity) {} PredefinedDevice(const PredefinedDevice &other) : name(other.name), capacity(other.capacity) {} PredefinedDevice &operator=(const PredefinedDevice &other); QString name; KIO::filesize_t capacity; }; const QList &SplitterGUI::predefinedDevices() { static QList list; if(!list.count()) { list << PredefinedDevice(i18n("1.44 MB (3.5\")"), 1457664); list << PredefinedDevice(i18n("1.2 MB (5.25\")"), 1213952); list << PredefinedDevice(i18n("720 kB (3.5\")"), 730112); list << PredefinedDevice(i18n("360 kB (5.25\")"), 362496); list << PredefinedDevice(i18n("100 MB (ZIP)"), 100431872); list << PredefinedDevice(i18n("250 MB (ZIP)"), 250331136); list << PredefinedDevice(i18n("650 MB (CD-R)"), 650*0x100000); list << PredefinedDevice(i18n("700 MB (CD-R)"), 700*0x100000); } return list; }; SplitterGUI::SplitterGUI(QWidget* parent, QUrl fileURL, QUrl defaultDir) : QDialog(parent), userDefinedSize(0x100000), lastSelectedDevice(-1), division(1) { setModal(true); QGridLayout *grid = new QGridLayout(this); grid->setSpacing(6); grid->setContentsMargins(11, 11, 11, 11); QLabel *splitterLabel = new QLabel(this); splitterLabel->setText(i18n("Split the file %1 to folder:", fileURL.toDisplayString(QUrl::PreferLocalFile))); splitterLabel->setMinimumWidth(400); grid->addWidget(splitterLabel, 0 , 0); urlReq = new KUrlRequester(this); urlReq->setUrl(defaultDir); urlReq->setMode(KFile::Directory); grid->addWidget(urlReq, 1 , 0); QWidget *splitSizeLine = new QWidget(this); QHBoxLayout * splitSizeLineLayout = new QHBoxLayout; splitSizeLineLayout->setContentsMargins(0, 0, 0, 0); splitSizeLine->setLayout(splitSizeLineLayout); deviceCombo = new QComboBox(splitSizeLine); for (int i = 0; i != predefinedDevices().count(); i++) deviceCombo->addItem(predefinedDevices()[i].name); deviceCombo->addItem(i18n("User Defined")); splitSizeLineLayout->addWidget(deviceCombo); QLabel *spacer = new QLabel(splitSizeLine); spacer->setText(" "); spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); splitSizeLineLayout->addWidget(spacer); QLabel *bytesPerFile = new QLabel(splitSizeLine); bytesPerFile->setText(i18n("Max file size:")); splitSizeLineLayout->addWidget(bytesPerFile); spinBox = new QDoubleSpinBox(splitSizeLine); spinBox->setMaximum(9999999999.0); spinBox->setMinimumWidth(85); spinBox->setEnabled(false); splitSizeLineLayout->addWidget(spinBox); sizeCombo = new QComboBox(splitSizeLine); sizeCombo->addItem(i18n("Byte")); sizeCombo->addItem(i18n("kByte")); sizeCombo->addItem(i18n("MByte")); sizeCombo->addItem(i18n("GByte")); splitSizeLineLayout->addWidget(sizeCombo); grid->addWidget(splitSizeLine, 2 , 0); overwriteCb = new QCheckBox(i18n("Overwrite files without confirmation"), this); grid->addWidget(overwriteCb, 3, 0); QFrame *separator = new QFrame(this); separator->setFrameStyle(QFrame::HLine | QFrame::Sunken); separator->setFixedHeight(separator->sizeHint().height()); grid->addWidget(separator, 4 , 0); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); buttonBox->button(QDialogButtonBox::Ok)->setText(i18n("&Split")); grid->addWidget(buttonBox, 5 , 0); setWindowTitle(i18n("Krusader::Splitter")); KConfigGroup cfg(KSharedConfig::openConfig(), QStringLiteral("Splitter")); overwriteCb->setChecked(cfg.readEntry("OverWriteFiles", false)); connect(sizeCombo, SIGNAL(activated(int)), this, SLOT(sizeComboActivated(int))); connect(deviceCombo, SIGNAL(activated(int)), this, SLOT(predefinedComboActivated(int))); connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); connect(buttonBox , SIGNAL(accepted()), this, SLOT(splitPressed())); predefinedComboActivated(0); } SplitterGUI::~SplitterGUI() { KConfigGroup cfg(KSharedConfig::openConfig(), QStringLiteral("Splitter")); cfg.writeEntry("OverWriteFiles", overwriteCb->isChecked()); } KIO::filesize_t SplitterGUI::getSplitSize() { if(deviceCombo->currentIndex() < predefinedDevices().count()) // predefined size selected return predefinedDevices()[deviceCombo->currentIndex()].capacity; // user defined size selected return spinBox->value() * division; } bool SplitterGUI::overWriteFiles() { return overwriteCb->isChecked(); } void SplitterGUI::sizeComboActivated(int item) { KIO::filesize_t prevDivision = division; switch (item) { case 0: division = 1; /* byte */ break; case 1: division = 0x400; /* kbyte */ break; case 2: division = 0x100000; /* Mbyte */ break; case 3: division = 0x40000000; /* Gbyte */ break; } double value; if(deviceCombo->currentIndex() < predefinedDevices().count()) // predefined size selected value = (double)predefinedDevices()[deviceCombo->currentIndex()].capacity / division; else { // use defined size selected value = (double)(spinBox->value() * prevDivision) / division; if(value < 1) value = 1; } spinBox->setValue(value); } void SplitterGUI::predefinedComboActivated(int item) { if(item == lastSelectedDevice) return; KIO::filesize_t capacity = userDefinedSize; if (lastSelectedDevice == predefinedDevices().count()) // user defined was selected previously userDefinedSize = spinBox->value() * division; // remember user defined size if(item < predefinedDevices().count()) { // predefined size selected capacity = predefinedDevices()[item].capacity; spinBox->setEnabled(false); } else // user defined size selected spinBox->setEnabled(true); //qDebug() << capacity; if (capacity >= 0x40000000) { /* Gbyte */ sizeCombo->setCurrentIndex(3); division = 0x40000000; } else if (capacity >= 0x100000) { /* Mbyte */ sizeCombo->setCurrentIndex(2); division = 0x100000; } else if (capacity >= 0x400) { /* kbyte */ sizeCombo->setCurrentIndex(1); division = 0x400; } else { sizeCombo->setCurrentIndex(0); /* byte */ division = 1; } spinBox->setValue((double)capacity / division); lastSelectedDevice = item; } void SplitterGUI::splitPressed() { if (!urlReq->url().isValid()) { KMessageBox::error(this, i18n("The folder path URL is malformed.")); return; } if(getSplitSize() > 0) emit accept(); } void SplitterGUI::keyPressEvent(QKeyEvent *e) { switch (e->key()) { case Qt::Key_Enter : case Qt::Key_Return : emit splitPressed(); return; default: QDialog::keyPressEvent(e); } } diff --git a/krusader/Synchronizer/feedtolistboxdialog.cpp b/krusader/Synchronizer/feedtolistboxdialog.cpp index e2736a07..939c0ecd 100644 --- a/krusader/Synchronizer/feedtolistboxdialog.cpp +++ b/krusader/Synchronizer/feedtolistboxdialog.cpp @@ -1,216 +1,216 @@ /*************************************************************************** feedtolistboxdialog.cpp - description ------------------- copyright : (C) 2006 + by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "feedtolistboxdialog.h" #include "synchronizer.h" #include "synchronizergui.h" -#include "../VFS/vfs.h" -#include "../VFS/virt_vfs.h" +#include "../FileSystem/filesystem.h" +#include "../FileSystem/virtualfilesystem.h" #include "../krglobal.h" #include "../krusaderview.h" #include "../panelmanager.h" // QtWidgets #include #include #include #include #include #include #include #include #include #define S_LEFT 0 #define S_RIGHT 1 #define S_BOTH 2 FeedToListBoxDialog::FeedToListBoxDialog(QWidget *parent, Synchronizer *sync, QTreeWidget *syncL, bool equOK) : QDialog(parent), synchronizer(sync), syncList(syncL), equalAllowed(equOK), accepted(false) { setWindowTitle(i18n("Krusader::Feed to listbox")); setWindowModality(Qt::WindowModal); QVBoxLayout *mainLayout = new QVBoxLayout; setLayout(mainLayout); // autodetecting the parameters int selectedNum = 0; int itemNum = 0; int leftExistingNum = 0; int rightExistingNum = 0; QTreeWidgetItemIterator it(syncList); while (*it) { SynchronizerGUI::SyncViewItem *item = (SynchronizerGUI::SyncViewItem *) * it; SynchronizerFileItem *syncItem = item->synchronizerItemRef(); if (syncItem && syncItem->isMarked()) { if (item->isSelected() || syncItem->task() != TT_EQUALS || equalAllowed) { itemNum++; if (item->isSelected()) selectedNum++; if (syncItem->existsInLeft()) leftExistingNum++; if (syncItem->existsInRight()) rightExistingNum++; } } it++; } if (itemNum == 0) { hide(); KMessageBox::error(parent, i18n("No elements to feed.")); return; } // guessing the collection name - virt_vfs virtVfs; - if (!virtVfs.refresh(QUrl("virt:/"))) + VirtualFileSystem virtFilesystem; + if (!virtFilesystem.refresh(QUrl("virt:/"))) return; KConfigGroup group(krConfig, "Synchronize"); int listBoxNum = group.readEntry("Feed To Listbox Counter", 1); QString queryName; do { queryName = i18n("Synchronize results") + QString(" %1").arg(listBoxNum++); - } while (virtVfs.getVfile(queryName) != 0); + } while (virtFilesystem.getFileItem(queryName) != 0); group.writeEntry("Feed To Listbox Counter", listBoxNum); // creating the widget QLabel *label = new QLabel(i18n("Here you can name the file collection"), this); mainLayout->addWidget(label); lineEdit = new QLineEdit(this); lineEdit->setText(queryName); lineEdit->setClearButtonEnabled(true); lineEdit->selectAll(); mainLayout->addWidget(lineEdit); QHBoxLayout * hbox = new QHBoxLayout; QLabel *label2 = new QLabel(i18n("Side to feed:"), this); label2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); hbox->addWidget(label2); sideCombo = new QComboBox(this); sideCombo->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); sideCombo->addItem(i18n("Left")); sideCombo->addItem(i18n("Right")); sideCombo->addItem(i18n("Both")); hbox->addWidget(sideCombo); if (leftExistingNum == 0) { sideCombo->setCurrentIndex(1); sideCombo->setEnabled(false); } else if (rightExistingNum == 0) { sideCombo->setCurrentIndex(0); sideCombo->setEnabled(false); } else sideCombo->setCurrentIndex(2); QFrame *line = new QFrame(this); line->setFrameStyle(QFrame::VLine | QFrame::Sunken); line->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); hbox->addWidget(line); cbSelected = new QCheckBox(i18n("Selected files only"), this); cbSelected->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); cbSelected->setEnabled(selectedNum != 0); cbSelected->setChecked(selectedNum != 0); hbox->addWidget(cbSelected); mainLayout->addLayout(hbox); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); mainLayout->addWidget(buttonBox); QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); okButton->setDefault(true); okButton->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox, SIGNAL(accepted()), SLOT(slotOk())); connect(buttonBox, SIGNAL(rejected()), SLOT(reject())); exec(); } void FeedToListBoxDialog::slotOk() { int side = sideCombo->currentIndex(); bool selected = cbSelected->isChecked(); QString name = lineEdit->text(); QList urlList; QTreeWidgetItemIterator it(syncList); for (;*it; it++) { SynchronizerGUI::SyncViewItem *item = (SynchronizerGUI::SyncViewItem *) * it; SynchronizerFileItem *syncItem = item->synchronizerItemRef(); if (!syncItem || !syncItem->isMarked()) continue; if (selected && !item->isSelected()) continue; if (!equalAllowed && syncItem->task() == TT_EQUALS && (!selected || !item->isSelected())) continue; if ((side == S_BOTH || side == S_LEFT) && syncItem->existsInLeft()) { QString leftDirName = syncItem->leftDirectory().isEmpty() ? "" : syncItem->leftDirectory() + '/'; QUrl leftURL = Synchronizer::fsUrl(synchronizer->leftBaseDirectory() + leftDirName + syncItem->leftName()); urlList.push_back(leftURL); } if ((side == S_BOTH || side == S_RIGHT) && syncItem->existsInRight()) { QString rightDirName = syncItem->rightDirectory().isEmpty() ? "" : syncItem->rightDirectory() + '/'; QUrl leftURL = Synchronizer::fsUrl(synchronizer->rightBaseDirectory() + rightDirName + syncItem->rightName()); urlList.push_back(leftURL); } } QUrl url = QUrl(QString("virt:/") + name); - virt_vfs virtVfs; - if (!virtVfs.refresh(url)) { + VirtualFileSystem virtFilesystem; + if (!virtFilesystem.refresh(url)) { KMessageBox::error(parentWidget(), i18n("Cannot open %1.", url.toDisplayString())); return; } - virtVfs.addFiles(urlList); + virtFilesystem.addFiles(urlList); ACTIVE_MNG->slotNewTab(url); accepted = true; accept(); } diff --git a/krusader/Synchronizer/synchronizedialog.cpp b/krusader/Synchronizer/synchronizedialog.cpp index fbcfbf22..ed9f0c4b 100644 --- a/krusader/Synchronizer/synchronizedialog.cpp +++ b/krusader/Synchronizer/synchronizedialog.cpp @@ -1,213 +1,213 @@ /*************************************************************************** synchronizedialog.cpp - description ------------------- copyright : (C) 2003 + by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "synchronizedialog.h" -#include "../VFS/krpermhandler.h" +#include "../FileSystem/krpermhandler.h" #include "../krglobal.h" #include "../defaults.h" // QtWidgets #include #include #include #include #include SynchronizeDialog::SynchronizeDialog(QWidget* parent, Synchronizer *sync, int pleftCopyNr, KIO::filesize_t pleftCopySize, int prightCopyNr, KIO::filesize_t prightCopySize, int pdeleteNr, KIO::filesize_t pdeleteSize, int parThreads) : QDialog(parent), synchronizer(sync), leftCopyNr(pleftCopyNr), leftCopySize(pleftCopySize), rightCopyNr(prightCopyNr), rightCopySize(prightCopySize), deleteNr(pdeleteNr), deleteSize(pdeleteSize), parallelThreads(parThreads), isPause(true), syncStarted(false) { setWindowTitle(i18n("Krusader::Synchronize")); setModal(true); QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(11, 11, 11, 11); layout->setSpacing(6); cbRightToLeft = new QCheckBox(i18np("Right to left: Copy 1 file", "Right to left: Copy %1 files", leftCopyNr) + ' ' + i18np("(1 byte)", "(%1 bytes)", KRpermHandler::parseSize(leftCopySize).trimmed().toInt()), this); cbRightToLeft->setChecked(leftCopyNr != 0); cbRightToLeft->setEnabled(leftCopyNr != 0); layout->addWidget(cbRightToLeft); lbRightToLeft = new QLabel(i18np("\tReady: %2/1 file, %3/%4", "\tReady: %2/%1 files, %3/%4", leftCopyNr, 0, 0, KRpermHandler::parseSize(leftCopySize).trimmed()), this); lbRightToLeft->setEnabled(leftCopyNr != 0); layout->addWidget(lbRightToLeft); cbLeftToRight = new QCheckBox(i18np("Left to right: Copy 1 file", "Left to right: Copy %1 files", rightCopyNr) + ' ' + i18np("(1 byte)", "(%1 bytes)", KRpermHandler::parseSize(rightCopySize).trimmed().toInt()), this); cbLeftToRight->setChecked(rightCopyNr != 0); cbLeftToRight->setEnabled(rightCopyNr != 0); layout->addWidget(cbLeftToRight); lbLeftToRight = new QLabel(i18np("\tReady: %2/1 file, %3/%4", "\tReady: %2/%1 files, %3/%4", rightCopyNr, 0, 0, KRpermHandler::parseSize(rightCopySize).trimmed()), this); lbLeftToRight->setEnabled(rightCopyNr != 0); layout->addWidget(lbLeftToRight); cbDeletable = new QCheckBox(i18np("Left: Delete 1 file", "Left: Delete %1 files", deleteNr) + ' ' + i18np("(1 byte)", "(%1 bytes)", KRpermHandler::parseSize(deleteSize).trimmed().toInt()), this); cbDeletable->setChecked(deleteNr != 0); cbDeletable->setEnabled(deleteNr != 0); layout->addWidget(cbDeletable); lbDeletable = new QLabel(i18np("\tReady: %2/1 file, %3/%4", "\tReady: %2/%1 files, %3/%4", deleteNr, 0, 0, KRpermHandler::parseSize(deleteSize).trimmed()), this); lbDeletable->setEnabled(deleteNr != 0); layout->addWidget(lbDeletable); progress = new QProgressBar(this); progress->setMaximum(1000); progress->setMinimum(0); progress->setValue(0); progress->setMinimumWidth(400); layout->addWidget(progress); QWidget *hboxWidget = new QWidget(this); QHBoxLayout * hbox = new QHBoxLayout(hboxWidget); hbox->setSpacing(6); cbOverwrite = new QCheckBox(i18n("Confirm overwrites"), this); KConfigGroup group(krConfig, "Synchronize"); cbOverwrite->setChecked(group.readEntry("Confirm overwrites", _ConfirmOverWrites)); layout->addWidget(cbOverwrite); QSpacerItem* spacer = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); hbox->addItem(spacer); btnStart = new QPushButton(hboxWidget); btnStart->setText(i18n("&Start")); btnStart->setIcon(QIcon::fromTheme("media-playback-start")); hbox->addWidget(btnStart); btnPause = new QPushButton(hboxWidget); btnPause->setEnabled(false); btnPause->setText(i18n("&Pause")); btnPause->setIcon(QIcon::fromTheme("media-playback-pause")); hbox->addWidget(btnPause); QPushButton *btnClose = new QPushButton(hboxWidget); btnClose->setText(i18n("&Close")); btnClose->setIcon(QIcon::fromTheme("dialog-close")); hbox->addWidget(btnClose); layout->addWidget(hboxWidget); connect(btnStart, SIGNAL(clicked()), this, SLOT(startSynchronization())); connect(btnPause, SIGNAL(clicked()), this, SLOT(pauseOrResume())); connect(btnClose, SIGNAL(clicked()), this, SLOT(reject())); exec(); } SynchronizeDialog::~SynchronizeDialog() { KConfigGroup group(krConfig, "Synchronize"); group.writeEntry("Confirm overwrites", cbOverwrite->isChecked()); } void SynchronizeDialog::startSynchronization() { btnStart->setEnabled(false); btnPause->setEnabled(syncStarted = true); connect(synchronizer, SIGNAL(synchronizationFinished()), this, SLOT(synchronizationFinished())); connect(synchronizer, SIGNAL(processedSizes(int, KIO::filesize_t, int, KIO::filesize_t, int, KIO::filesize_t)), this, SLOT(processedSizes(int, KIO::filesize_t, int, KIO::filesize_t, int, KIO::filesize_t))); connect(synchronizer, SIGNAL(pauseAccepted()), this, SLOT(pauseAccepted())); if (!cbRightToLeft->isChecked()) leftCopySize = 0; if (!cbLeftToRight->isChecked()) rightCopySize = 0; if (!cbDeletable->isChecked()) deleteSize = 0; synchronizer->synchronize(this, cbRightToLeft->isChecked(), cbLeftToRight->isChecked(), cbDeletable->isChecked(), !cbOverwrite->isChecked(), parallelThreads); } void SynchronizeDialog::synchronizationFinished() { QDialog::reject(); } void SynchronizeDialog::processedSizes(int leftNr, KIO::filesize_t leftSize, int rightNr, KIO::filesize_t rightSize, int delNr, KIO::filesize_t delSize) { lbRightToLeft->setText(i18np("\tReady: %2/1 file, %3/%4", "\tReady: %2/%1 files, %3/%4", leftCopyNr, leftNr, KRpermHandler::parseSize(leftSize).trimmed(), KRpermHandler::parseSize(leftCopySize).trimmed())); lbLeftToRight->setText(i18np("\tReady: %2/1 file, %3/%4", "\tReady: %2/%1 files, %3/%4", rightCopyNr, rightNr, KRpermHandler::parseSize(rightSize).trimmed(), KRpermHandler::parseSize(rightCopySize).trimmed())); lbDeletable->setText(i18np("\tReady: %2/1 file, %3/%4", "\tReady: %2/%1 files, %3/%4", deleteNr, delNr, KRpermHandler::parseSize(delSize).trimmed(), KRpermHandler::parseSize(deleteSize).trimmed())); KIO::filesize_t totalSum = leftCopySize + rightCopySize + deleteSize; KIO::filesize_t processedSum = leftSize + rightSize + delSize; if (totalSum == 0) totalSum++; progress->setValue((int)(((double)processedSum / (double)totalSum)*1000)); } void SynchronizeDialog::pauseOrResume() { if (isPause) { btnPause->setEnabled(false); synchronizer->pause(); } else { btnPause->setText(i18n("Pause")); synchronizer->resume(); isPause = true; } } void SynchronizeDialog::pauseAccepted() { btnPause->setText(i18n("Resume")); btnPause->setEnabled(true); isPause = false; } diff --git a/krusader/Synchronizer/synchronizer.cpp b/krusader/Synchronizer/synchronizer.cpp index 2ccc0244..9c957eb9 100644 --- a/krusader/Synchronizer/synchronizer.cpp +++ b/krusader/Synchronizer/synchronizer.cpp @@ -1,1445 +1,1445 @@ /*************************************************************************** synchronizer.cpp - description ------------------- copyright : (C) 2003 + by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "synchronizer.h" #include "synchronizerdirlist.h" #include "../krglobal.h" #include "../krservices.h" -#include "../VFS/vfs.h" -#include "../VFS/krquery.h" +#include "../FileSystem/filesystem.h" +#include "../FileSystem/krquery.h" #include // QtCore #include #include #include #include #include #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_POSIX_ACL #include #ifdef HAVE_NON_POSIX_ACL_EXTENSIONS #include #endif #endif #define DISPLAY_UPDATE_PERIOD 2 Synchronizer::Synchronizer() : displayUpdateCount(0), markEquals(true), markDiffers(true), markCopyToLeft(true), markCopyToRight(true), markDeletable(true), stack(), jobMap(), receivedMap(), parentWidget(0), resultListIt(resultList) { } Synchronizer::~Synchronizer() { clearLists(); } QUrl Synchronizer::fsUrl(QString strUrl) { QUrl result = QUrl::fromUserInput(strUrl, QString(), QUrl::AssumeLocalFile); return KrServices::escapeFileUrl(result); } void Synchronizer::clearLists() { QListIterator i1(resultList); while (i1.hasNext()) delete i1.next(); resultList.clear(); QListIterator i2(stack); while (i2.hasNext()) delete i2.next(); stack.clear(); temporaryList.clear(); } void Synchronizer::reset() { displayUpdateCount = 0; markEquals = markDiffers = markCopyToLeft = markCopyToRight = markDeletable = true; stopped = false; recurseSubDirs = followSymLinks = ignoreDate = asymmetric = cmpByContent = ignoreCase = autoScroll = false; markEquals = markDiffers = markCopyToLeft = markCopyToRight = markDeletable = markDuplicates = markSingles = false; leftCopyEnabled = rightCopyEnabled = deleteEnabled = overWrite = autoSkip = paused = false; leftCopyNr = rightCopyNr = deleteNr = 0; leftCopySize = rightCopySize = deleteSize = 0; comparedDirs = fileCount = 0; leftBaseDir.clear(); rightBaseDir.clear(); clearLists(); } int Synchronizer::compare(QString leftURL, QString rightURL, KRQuery *query, bool subDirs, bool symLinks, bool igDate, bool asymm, bool cmpByCnt, bool igCase, bool autoSc, QStringList &selFiles, int equThres, int timeOffs, int parThreads, bool hiddenFiles) { clearLists(); recurseSubDirs = subDirs; followSymLinks = symLinks; ignoreDate = igDate; asymmetric = asymm; cmpByContent = cmpByCnt; autoScroll = autoSc; ignoreCase = igCase; selectedFiles = selFiles; equalsThreshold = equThres; timeOffset = timeOffs; parallelThreads = parThreads; ignoreHidden = hiddenFiles; stopped = false; this->query = query; leftURL = KUrlCompletion::replacedPath(leftURL, true, true); rightURL = KUrlCompletion::replacedPath(rightURL, true, true); if (!leftURL.endsWith('/')) leftURL += '/'; if (!rightURL.endsWith('/')) rightURL += '/'; excludedPaths = KrServices::toStringList(query->dontSearchInDirs()); for (int i = 0; i != excludedPaths.count(); i++) if (excludedPaths[ i ].endsWith('/')) excludedPaths[ i ].truncate(excludedPaths[ i ].length() - 1); comparedDirs = fileCount = 0; stack.append(new CompareTask(0, leftBaseDir = leftURL, rightBaseDir = rightURL, "", "", ignoreHidden)); compareLoop(); QListIterator it(temporaryList); while (it.hasNext()) { SynchronizerFileItem * item = it.next(); if (item->isTemporary()) delete item; } temporaryList.clear(); if (!autoScroll) refresh(true); emit statusInfo(i18n("Number of files: %1", fileCount)); return fileCount; } void Synchronizer::compareLoop() { while (!stopped && !stack.isEmpty()) { for (int thread = 0; thread < (int)stack.count() && thread < parallelThreads; thread++) { SynchronizerTask * entry = stack.at(thread); if (entry->state() == ST_STATE_NEW) entry->start(parentWidget); if (entry->inherits("CompareTask")) { if (entry->state() == ST_STATE_READY) { CompareTask *ctentry = (CompareTask *) entry; if (ctentry->isDuplicate()) compareDirectory(ctentry->parent(), ctentry->leftDirList(), ctentry->rightDirList(), ctentry->leftDir(), ctentry->rightDir()); else addSingleDirectory(ctentry->parent(), ctentry->dirList(), ctentry->dir(), ctentry->isLeft()); } if (entry->state() == ST_STATE_READY || entry->state() == ST_STATE_ERROR) comparedDirs++; } switch (entry->state()) { case ST_STATE_STATUS: emit statusInfo(entry->status()); break; case ST_STATE_READY: case ST_STATE_ERROR: emit statusInfo(i18n("Number of compared folders: %1", comparedDirs)); stack.removeAll(entry); delete entry; continue; default: break; } } if (!stack.isEmpty()) qApp->processEvents(); } QListIterator it(stack); while (it.hasNext()) delete it.next(); stack.clear(); } void Synchronizer::compareDirectory(SynchronizerFileItem *parent, SynchronizerDirList * left_directory, SynchronizerDirList * right_directory, const QString &leftDir, const QString &rightDir) { const QString &leftURL = left_directory->url(); const QString &rightURL = right_directory->url(); - vfile * left_file; - vfile * right_file; + FileItem *left_file; + FileItem *right_file; QString file_name; bool checkIfSelected = false; if (leftDir.isEmpty() && rightDir.isEmpty() && selectedFiles.count()) checkIfSelected = true; /* walking through in the left directory */ for (left_file = left_directory->first(); left_file != 0 && !stopped ; left_file = left_directory->next()) { if (isDir(left_file)) continue; - file_name = left_file->vfile_getName(); + file_name = left_file->getName(); if (checkIfSelected && !selectedFiles.contains(file_name)) continue; if (!query->match(left_file)) continue; if ((right_file = right_directory->search(file_name, ignoreCase)) == 0) - addLeftOnlyItem(parent, file_name, leftDir, left_file->vfile_getSize(), left_file->vfile_getTime_t(), - readLink(left_file), left_file->vfile_getOwner(), left_file->vfile_getGroup(), - left_file->vfile_getMode(), left_file->vfile_getACL()); + addLeftOnlyItem(parent, file_name, leftDir, left_file->getSize(), left_file->getTime_t(), + readLink(left_file), left_file->getOwner(), left_file->getGroup(), + left_file->getMode(), left_file->getACL()); else { if (isDir(right_file)) continue; - addDuplicateItem(parent, file_name, right_file->vfile_getName(), leftDir, rightDir, left_file->vfile_getSize(), right_file->vfile_getSize(), - left_file->vfile_getTime_t(), right_file->vfile_getTime_t(), readLink(left_file), - readLink(right_file), left_file->vfile_getOwner(), right_file->vfile_getOwner(), - left_file->vfile_getGroup(), right_file->vfile_getGroup(), - left_file->vfile_getMode(), right_file->vfile_getMode(), - left_file->vfile_getACL(), right_file->vfile_getACL()); + addDuplicateItem(parent, file_name, right_file->getName(), leftDir, rightDir, left_file->getSize(), right_file->getSize(), + left_file->getTime_t(), right_file->getTime_t(), readLink(left_file), + readLink(right_file), left_file->getOwner(), right_file->getOwner(), + left_file->getGroup(), right_file->getGroup(), + left_file->getMode(), right_file->getMode(), + left_file->getACL(), right_file->getACL()); } } /* walking through in the right directory */ for (right_file = right_directory->first(); right_file != 0 && !stopped ; right_file = right_directory->next()) { if (isDir(right_file)) continue; - file_name = right_file->vfile_getName(); + file_name = right_file->getName(); if (checkIfSelected && !selectedFiles.contains(file_name)) continue; if (!query->match(right_file)) continue; if (left_directory->search(file_name, ignoreCase) == 0) - addRightOnlyItem(parent, file_name, rightDir, right_file->vfile_getSize(), right_file->vfile_getTime_t(), - readLink(right_file), right_file->vfile_getOwner(), right_file->vfile_getGroup(), - right_file->vfile_getMode(), right_file->vfile_getACL()); + addRightOnlyItem(parent, file_name, rightDir, right_file->getSize(), right_file->getTime_t(), + readLink(right_file), right_file->getOwner(), right_file->getGroup(), + right_file->getMode(), right_file->getACL()); } /* walking through the subdirectories */ if (recurseSubDirs) { for (left_file = left_directory->first(); left_file != 0 && !stopped ; left_file = left_directory->next()) { - if (left_file->vfile_isDir() && (followSymLinks || !left_file->vfile_isSymLink())) { - QString left_file_name = left_file->vfile_getName(); + if (left_file->isDir() && (followSymLinks || !left_file->isSymLink())) { + QString left_file_name = left_file->getName(); if (checkIfSelected && !selectedFiles.contains(left_file_name)) continue; if (excludedPaths.contains(leftDir.isEmpty() ? left_file_name : leftDir + '/' + left_file_name)) continue; if (!query->matchDirName(left_file_name)) continue; if ((right_file = right_directory->search(left_file_name, ignoreCase)) == 0) { SynchronizerFileItem *me = addLeftOnlyItem(parent, left_file_name, leftDir, 0, - left_file->vfile_getTime_t(), readLink(left_file), - left_file->vfile_getOwner(), left_file->vfile_getGroup(), - left_file->vfile_getMode(), left_file->vfile_getACL(), + left_file->getTime_t(), readLink(left_file), + left_file->getOwner(), left_file->getGroup(), + left_file->getMode(), left_file->getACL(), true, !query->match(left_file)); stack.append(new CompareTask(me, leftURL + left_file_name + '/', leftDir.isEmpty() ? left_file_name : leftDir + '/' + left_file_name, true, ignoreHidden)); } else { - QString right_file_name = right_file->vfile_getName(); + QString right_file_name = right_file->getName(); SynchronizerFileItem *me = addDuplicateItem(parent, left_file_name, right_file_name, leftDir, rightDir, 0, 0, - left_file->vfile_getTime_t(), right_file->vfile_getTime_t(), + left_file->getTime_t(), right_file->getTime_t(), readLink(left_file), readLink(right_file), - left_file->vfile_getOwner(), right_file->vfile_getOwner(), - left_file->vfile_getGroup(), right_file->vfile_getGroup(), - left_file->vfile_getMode(), right_file->vfile_getMode(), - left_file->vfile_getACL(), right_file->vfile_getACL(), + left_file->getOwner(), right_file->getOwner(), + left_file->getGroup(), right_file->getGroup(), + left_file->getMode(), right_file->getMode(), + left_file->getACL(), right_file->getACL(), true, !query->match(left_file)); stack.append(new CompareTask(me, leftURL + left_file_name + '/', rightURL + right_file_name + '/', leftDir.isEmpty() ? left_file_name : leftDir + '/' + left_file_name, rightDir.isEmpty() ? right_file_name : rightDir + '/' + right_file_name, ignoreHidden)); } } } /* walking through the right side subdirectories */ for (right_file = right_directory->first(); right_file != 0 && !stopped ; right_file = right_directory->next()) { - if (right_file->vfile_isDir() && (followSymLinks || !right_file->vfile_isSymLink())) { - file_name = right_file->vfile_getName(); + if (right_file->isDir() && (followSymLinks || !right_file->isSymLink())) { + file_name = right_file->getName(); if (checkIfSelected && !selectedFiles.contains(file_name)) continue; if (excludedPaths.contains(rightDir.isEmpty() ? file_name : rightDir + '/' + file_name)) continue; if (!query->matchDirName(file_name)) continue; if (left_directory->search(file_name, ignoreCase) == 0) { SynchronizerFileItem *me = addRightOnlyItem(parent, file_name, rightDir, 0, - right_file->vfile_getTime_t(), readLink(right_file), - right_file->vfile_getOwner(), right_file->vfile_getGroup(), - right_file->vfile_getMode(), right_file->vfile_getACL(), + right_file->getTime_t(), readLink(right_file), + right_file->getOwner(), right_file->getGroup(), + right_file->getMode(), right_file->getACL(), true, !query->match(right_file)); stack.append(new CompareTask(me, rightURL + file_name + '/', rightDir.isEmpty() ? file_name : rightDir + '/' + file_name, false, ignoreHidden)); } } } } } QString Synchronizer::getTaskTypeName(TaskType taskType) { static QString names[] = {"=", "!=", "<-", "->", "DEL", "?", "?", "?", "?", "?"}; return names[taskType]; } SynchronizerFileItem * Synchronizer::addItem(SynchronizerFileItem *parent, const QString &leftFile, const QString &rightFile, const QString &leftDir, const QString &rightDir, bool existsLeft, bool existsRight, KIO::filesize_t leftSize, KIO::filesize_t rightSize, time_t leftDate, time_t rightDate, const QString &leftLink, const QString &rightLink, const QString &leftOwner, const QString &rightOwner, const QString &leftGroup, const QString &rightGroup, mode_t leftMode, mode_t rightMode, const QString &leftACL, const QString &rightACL, TaskType tsk, bool isDir, bool isTemp) { bool marked = autoScroll ? !isTemp && isMarked(tsk, existsLeft && existsRight) : false; SynchronizerFileItem *item = new SynchronizerFileItem(leftFile, rightFile, leftDir, rightDir, marked, existsLeft, existsRight, leftSize, rightSize, leftDate, rightDate, leftLink, rightLink, leftOwner, rightOwner, leftGroup, rightGroup, leftMode, rightMode, leftACL, rightACL, tsk, isDir, isTemp, parent); if (!isTemp) { while (parent && parent->isTemporary()) setPermanent(parent); bool doRefresh = false; if (marked) { fileCount++; if (autoScroll && markParentDirectories(item)) doRefresh = true; } resultList.append(item); emit comparedFileData(item); if (doRefresh) refresh(true); if (marked && (displayUpdateCount++ % DISPLAY_UPDATE_PERIOD == (DISPLAY_UPDATE_PERIOD - 1))) qApp->processEvents(); } else temporaryList.append(item); return item; } void Synchronizer::compareContentResult(SynchronizerFileItem * item, bool res) { item->compareContentResult(res); bool marked = autoScroll ? isMarked(item->task(), item->existsInLeft() && item->existsInRight()) : false; item->setMarked(marked); if (marked) { markParentDirectories(item); fileCount++; emit markChanged(item, true); } } void Synchronizer::setPermanent(SynchronizerFileItem *item) { if (item->parent() && item->parent()->isTemporary()) setPermanent(item->parent()); item->setPermanent(); resultList.append(item); emit comparedFileData(item); } SynchronizerFileItem * Synchronizer::addLeftOnlyItem(SynchronizerFileItem *parent, const QString &file_name, const QString &dir, KIO::filesize_t size, time_t date, const QString &link, const QString &owner, const QString &group, mode_t mode, const QString &acl, bool isDir, bool isTemp) { return addItem(parent, file_name, file_name, dir, dir, true, false, size, 0, date, 0, link, QString(), owner, QString(), group, QString(), mode, (mode_t) - 1, acl, QString(), asymmetric ? TT_DELETE : TT_COPY_TO_RIGHT, isDir, isTemp); } SynchronizerFileItem * Synchronizer::addRightOnlyItem(SynchronizerFileItem *parent, const QString &file_name, const QString &dir, KIO::filesize_t size, time_t date, const QString &link, const QString &owner, const QString &group, mode_t mode, const QString &acl, bool isDir, bool isTemp) { return addItem(parent, file_name, file_name, dir, dir, false, true, 0, size, 0, date, QString(), link, QString(), owner, QString(), group, (mode_t) - 1, mode, QString(), acl, TT_COPY_TO_LEFT, isDir, isTemp); } SynchronizerFileItem * Synchronizer::addDuplicateItem(SynchronizerFileItem *parent, const QString &leftName, const QString &rightName, const QString &leftDir, const QString &rightDir, KIO::filesize_t leftSize, KIO::filesize_t rightSize, time_t leftDate, time_t rightDate, const QString &leftLink, const QString &rightLink, const QString &leftOwner, const QString &rightOwner, const QString &leftGroup, const QString &rightGroup, mode_t leftMode, mode_t rightMode, const QString &leftACL, const QString &rightACL, bool isDir, bool isTemp) { TaskType task; int checkedRightDate = rightDate - timeOffset; int uncertain = 0; do { if (isDir) { task = TT_EQUALS; break; } if (leftSize == rightSize) { if (!leftLink.isNull() || !rightLink.isNull()) { if (leftLink == rightLink) { task = TT_EQUALS; break; } } else if (cmpByContent) uncertain = TT_UNKNOWN; else { if (ignoreDate || leftDate == checkedRightDate) { task = TT_EQUALS; break; } time_t diff = (leftDate > checkedRightDate) ? leftDate - checkedRightDate : checkedRightDate - leftDate; if (diff <= equalsThreshold) { task = TT_EQUALS; break; } } } if (asymmetric) task = TT_COPY_TO_LEFT; else if (ignoreDate) task = TT_DIFFERS; else if (leftDate > checkedRightDate) task = TT_COPY_TO_RIGHT; else if (leftDate < checkedRightDate) task = TT_COPY_TO_LEFT; else task = TT_DIFFERS; } while (false); SynchronizerFileItem * item = addItem(parent, leftName, rightName, leftDir, rightDir, true, true, leftSize, rightSize, leftDate, rightDate, leftLink, rightLink, leftOwner, rightOwner, leftGroup, rightGroup, leftMode, rightMode, leftACL, rightACL, (TaskType)(task + uncertain), isDir, isTemp); if (uncertain == TT_UNKNOWN) { QUrl leftURL = Synchronizer::fsUrl(leftDir.isEmpty() ? leftBaseDir + leftName : leftBaseDir + leftDir + '/' + leftName); QUrl rightURL = Synchronizer::fsUrl(rightDir.isEmpty() ? rightBaseDir + rightName : rightBaseDir + rightDir + '/' + rightName); stack.append(new CompareContentTask(this, item, leftURL, rightURL, leftSize)); } return item; } void Synchronizer::addSingleDirectory(SynchronizerFileItem *parent, SynchronizerDirList *directory, const QString &dirName, bool isLeft) { const QString &url = directory->url(); - vfile * file; + FileItem *file; QString file_name; /* walking through the directory files */ for (file = directory->first(); file != 0 && !stopped; file = directory->next()) { if (isDir(file)) continue; - file_name = file->vfile_getName(); + file_name = file->getName(); if (!query->match(file)) continue; if (isLeft) - addLeftOnlyItem(parent, file_name, dirName, file->vfile_getSize(), file->vfile_getTime_t(), readLink(file), - file->vfile_getOwner(), file->vfile_getGroup(), file->vfile_getMode(), file->vfile_getACL()); + addLeftOnlyItem(parent, file_name, dirName, file->getSize(), file->getTime_t(), readLink(file), + file->getOwner(), file->getGroup(), file->getMode(), file->getACL()); else - addRightOnlyItem(parent, file_name, dirName, file->vfile_getSize(), file->vfile_getTime_t(), readLink(file), - file->vfile_getOwner(), file->vfile_getGroup(), file->vfile_getMode(), file->vfile_getACL()); + addRightOnlyItem(parent, file_name, dirName, file->getSize(), file->getTime_t(), readLink(file), + file->getOwner(), file->getGroup(), file->getMode(), file->getACL()); } /* walking through the subdirectories */ for (file = directory->first(); file != 0 && !stopped; file = directory->next()) { - if (file->vfile_isDir() && (followSymLinks || !file->vfile_isSymLink())) { - file_name = file->vfile_getName(); + if (file->isDir() && (followSymLinks || !file->isSymLink())) { + file_name = file->getName(); if (excludedPaths.contains(dirName.isEmpty() ? file_name : dirName + '/' + file_name)) continue; if (!query->matchDirName(file_name)) continue; SynchronizerFileItem *me; if (isLeft) - me = addLeftOnlyItem(parent, file_name, dirName, 0, file->vfile_getTime_t(), readLink(file), - file->vfile_getOwner(), file->vfile_getGroup(), file->vfile_getMode(), - file->vfile_getACL(), true, !query->match(file)); + me = addLeftOnlyItem(parent, file_name, dirName, 0, file->getTime_t(), readLink(file), + file->getOwner(), file->getGroup(), file->getMode(), + file->getACL(), true, !query->match(file)); else - me = addRightOnlyItem(parent, file_name, dirName, 0, file->vfile_getTime_t(), readLink(file), - file->vfile_getOwner(), file->vfile_getGroup(), file->vfile_getMode(), - file->vfile_getACL(), true, !query->match(file)); + me = addRightOnlyItem(parent, file_name, dirName, 0, file->getTime_t(), readLink(file), + file->getOwner(), file->getGroup(), file->getMode(), + file->getACL(), true, !query->match(file)); stack.append(new CompareTask(me, url + file_name + '/', dirName.isEmpty() ? file_name : dirName + '/' + file_name, isLeft, ignoreHidden)); } } } void Synchronizer::setMarkFlags(bool left, bool equal, bool differs, bool right, bool dup, bool sing, bool del) { markEquals = equal; markDiffers = differs; markCopyToLeft = left; markCopyToRight = right; markDeletable = del; markDuplicates = dup; markSingles = sing; } bool Synchronizer::isMarked(TaskType task, bool isDuplicate) { if ((isDuplicate && !markDuplicates) || (!isDuplicate && !markSingles)) return false; switch (task) { case TT_EQUALS: return markEquals; case TT_DIFFERS: return markDiffers; case TT_COPY_TO_LEFT: return markCopyToLeft; case TT_COPY_TO_RIGHT: return markCopyToRight; case TT_DELETE: return markDeletable; default: return false; } } bool Synchronizer::markParentDirectories(SynchronizerFileItem *item) { if (item->parent() == 0 || item->parent()->isMarked()) return false; markParentDirectories(item->parent()); item->parent()->setMarked(true); fileCount++; emit markChanged(item->parent(), false); return true; } int Synchronizer::refresh(bool nostatus) { fileCount = 0; QListIterator it(resultList); while (it.hasNext()) { SynchronizerFileItem * item = it.next(); bool marked = isMarked(item->task(), item->existsInLeft() && item->existsInRight()); item->setMarked(marked); if (marked) { markParentDirectories(item); fileCount++; } } it.toFront(); while (it.hasNext()) { SynchronizerFileItem * item = it.next(); emit markChanged(item, false); } if (!nostatus) emit statusInfo(i18n("Number of files: %1", fileCount)); return fileCount; } void Synchronizer::operate(SynchronizerFileItem *item, void (*executeOperation)(SynchronizerFileItem *)) { executeOperation(item); if (item->isDir()) { QString leftDirName = (item->leftDirectory().isEmpty()) ? item->leftName() : item->leftDirectory() + '/' + item->leftName() ; QString rightDirName = (item->rightDirectory().isEmpty()) ? item->rightName() : item->rightDirectory() + '/' + item->rightName() ; QListIterator it(resultList); while (it.hasNext()) { SynchronizerFileItem * item = it.next(); if (item->leftDirectory() == leftDirName || item->leftDirectory().startsWith(leftDirName + '/') || item->rightDirectory() == rightDirName || item->rightDirectory().startsWith(rightDirName + '/')) executeOperation(item); } } } void Synchronizer::excludeOperation(SynchronizerFileItem *item) { item->setTask(TT_DIFFERS); } void Synchronizer::exclude(SynchronizerFileItem *item) { if (!item->parent() || item->parent()->task() != TT_DELETE) operate(item, excludeOperation); /* exclude only if the parent task is not DEL */ } void Synchronizer::restoreOperation(SynchronizerFileItem *item) { item->restoreOriginalTask(); } void Synchronizer::restore(SynchronizerFileItem *item) { operate(item, restoreOperation); while ((item = item->parent()) != 0) /* in case of restore, the parent directories */ { /* must be changed for being consistent */ if (item->task() != TT_DIFFERS) break; if (item->originalTask() == TT_DELETE) /* if the parent original task is delete */ break; /* don't touch it */ item->restoreOriginalTask(); /* restore */ } } void Synchronizer::reverseDirectionOperation(SynchronizerFileItem *item) { if (item->existsInRight() && item->existsInLeft()) { if (item->task() == TT_COPY_TO_LEFT) item->setTask(TT_COPY_TO_RIGHT); else if (item->task() == TT_COPY_TO_RIGHT) item->setTask(TT_COPY_TO_LEFT); } } void Synchronizer::reverseDirection(SynchronizerFileItem *item) { operate(item, reverseDirectionOperation); } void Synchronizer::deleteLeftOperation(SynchronizerFileItem *item) { if (!item->existsInRight() && item->existsInLeft()) item->setTask(TT_DELETE); } void Synchronizer::deleteLeft(SynchronizerFileItem *item) { operate(item, deleteLeftOperation); } void Synchronizer::copyToLeftOperation(SynchronizerFileItem *item) { if (item->existsInRight()) { if (!item->isDir()) item->setTask(TT_COPY_TO_LEFT); else { if (item->existsInLeft() && item->existsInRight()) item->setTask(TT_EQUALS); else if (!item->existsInLeft() && item->existsInRight()) item->setTask(TT_COPY_TO_LEFT); } } } void Synchronizer::copyToLeft(SynchronizerFileItem *item) { operate(item, copyToLeftOperation); while ((item = item->parent()) != 0) { if (item->task() != TT_DIFFERS) break; if (item->existsInLeft() && item->existsInRight()) item->setTask(TT_EQUALS); else if (!item->existsInLeft() && item->existsInRight()) item->setTask(TT_COPY_TO_LEFT); } } void Synchronizer::copyToRightOperation(SynchronizerFileItem *item) { if (item->existsInLeft()) { if (!item->isDir()) item->setTask(TT_COPY_TO_RIGHT); else { if (item->existsInLeft() && item->existsInRight()) item->setTask(TT_EQUALS); else if (item->existsInLeft() && !item->existsInRight()) item->setTask(TT_COPY_TO_RIGHT); } } } void Synchronizer::copyToRight(SynchronizerFileItem *item) { operate(item, copyToRightOperation); while ((item = item->parent()) != 0) { if (item->task() != TT_DIFFERS && item->task() != TT_DELETE) break; if (item->existsInLeft() && item->existsInRight()) item->setTask(TT_EQUALS); else if (item->existsInLeft() && !item->existsInRight()) item->setTask(TT_COPY_TO_RIGHT); } } bool Synchronizer::totalSizes(int * leftCopyNr, KIO::filesize_t *leftCopySize, int * rightCopyNr, KIO::filesize_t *rightCopySize, int *deleteNr, KIO::filesize_t *deletableSize) { bool hasAnythingToDo = false; *leftCopySize = *rightCopySize = *deletableSize = 0; *leftCopyNr = *rightCopyNr = *deleteNr = 0; QListIterator it(resultList); while (it.hasNext()) { SynchronizerFileItem * item = it.next(); if (item->isMarked()) { switch (item->task()) { case TT_COPY_TO_LEFT: *leftCopySize += item->rightSize(); (*leftCopyNr)++; hasAnythingToDo = true; break; case TT_COPY_TO_RIGHT: *rightCopySize += item->leftSize(); (*rightCopyNr)++; hasAnythingToDo = true; break; case TT_DELETE: *deletableSize += item->leftSize(); (*deleteNr)++; hasAnythingToDo = true; break; default: break; } } } return hasAnythingToDo; } void Synchronizer::swapSides() { QString leftTmp = leftBaseDir; leftBaseDir = rightBaseDir; rightBaseDir = leftTmp; QListIterator it(resultList); while (it.hasNext()) { SynchronizerFileItem * item = it.next(); item->swap(asymmetric); } } void Synchronizer::setScrolling(bool scroll) { autoScroll = scroll; if (autoScroll) { int oldFileCount = fileCount; refresh(true); fileCount = oldFileCount; } } void Synchronizer::synchronize(QWidget *syncWdg, bool leftCopyEnabled, bool rightCopyEnabled, bool deleteEnabled, bool overWrite, int parThreads) { this->leftCopyEnabled = leftCopyEnabled; this->rightCopyEnabled = rightCopyEnabled; this->deleteEnabled = deleteEnabled; this->overWrite = overWrite; this->parallelThreads = parThreads; this->syncDlgWidget = syncWdg; autoSkip = paused = disableNewTasks = false; leftCopyNr = rightCopyNr = deleteNr = 0; leftCopySize = rightCopySize = deleteSize = 0; inTaskFinished = 0; lastTask = 0; jobMap.clear(); receivedMap.clear(); resultListIt = resultList; synchronizeLoop(); } void Synchronizer::synchronizeLoop() { if (disableNewTasks) { if (!resultListIt.hasNext() && jobMap.count() == 0) emit synchronizationFinished(); return; } while ((int)jobMap.count() < parallelThreads) { SynchronizerFileItem *task = getNextTask(); if (task == 0) { if (jobMap.count() == 0) emit synchronizationFinished(); return; } executeTask(task); if (disableNewTasks) break; } } SynchronizerFileItem * Synchronizer::getNextTask() { TaskType task; SynchronizerFileItem * currentTask; do { if (!resultListIt.hasNext()) return 0; currentTask = resultListIt.next(); if (currentTask->isMarked()) { task = currentTask->task(); if (leftCopyEnabled && task == TT_COPY_TO_LEFT) break; else if (rightCopyEnabled && task == TT_COPY_TO_RIGHT) break; else if (deleteEnabled && task == TT_DELETE) break; } } while (true); return lastTask = currentTask; } void Synchronizer::executeTask(SynchronizerFileItem * task) { QString leftDirName = task->leftDirectory(); if (!leftDirName.isEmpty()) leftDirName += '/'; QString rightDirName = task->rightDirectory(); if (!rightDirName.isEmpty()) rightDirName += '/'; QUrl leftURL = Synchronizer::fsUrl(leftBaseDir + leftDirName + task->leftName()); QUrl rightURL = Synchronizer::fsUrl(rightBaseDir + rightDirName + task->rightName()); switch (task->task()) { case TT_COPY_TO_LEFT: if (task->isDir()) { KIO::SimpleJob *job = KIO::mkdir(leftURL); connect(job, SIGNAL(result(KJob*)), this, SLOT(slotTaskFinished(KJob*))); jobMap[ job ] = task; disableNewTasks = true; } else { QUrl destURL(leftURL); if (!task->destination().isNull()) destURL = Synchronizer::fsUrl(task->destination()); if (task->rightLink().isNull()) { KIO::FileCopyJob *job = KIO::file_copy(rightURL, destURL, -1, ((overWrite || task->overWrite()) ? KIO::Overwrite : KIO::DefaultFlags) | KIO::HideProgressInfo); connect(job, SIGNAL(processedSize(KJob *, qulonglong)), this, SLOT(slotProcessedSize(KJob *, qulonglong))); connect(job, SIGNAL(result(KJob*)), this, SLOT(slotTaskFinished(KJob*))); jobMap[ job ] = task; } else { KIO::SimpleJob *job = KIO::symlink(task->rightLink(), destURL, ((overWrite || task->overWrite()) ? KIO::Overwrite : KIO::DefaultFlags) | KIO::HideProgressInfo); connect(job, SIGNAL(result(KJob*)), this, SLOT(slotTaskFinished(KJob*))); jobMap[ job ] = task; } } break; case TT_COPY_TO_RIGHT: if (task->isDir()) { KIO::SimpleJob *job = KIO::mkdir(rightURL); connect(job, SIGNAL(result(KJob*)), this, SLOT(slotTaskFinished(KJob*))); jobMap[ job ] = task; disableNewTasks = true; } else { QUrl destURL(rightURL); if (!task->destination().isNull()) destURL = Synchronizer::fsUrl(task->destination()); if (task->leftLink().isNull()) { KIO::FileCopyJob *job = KIO::file_copy(leftURL, destURL, -1, ((overWrite || task->overWrite()) ? KIO::Overwrite : KIO::DefaultFlags) | KIO::HideProgressInfo); connect(job, SIGNAL(processedSize(KJob *, qulonglong)), this, SLOT(slotProcessedSize(KJob *, qulonglong))); connect(job, SIGNAL(result(KJob*)), this, SLOT(slotTaskFinished(KJob*))); jobMap[ job ] = task; } else { KIO::SimpleJob *job = KIO::symlink(task->leftLink(), destURL, ((overWrite || task->overWrite()) ? KIO::Overwrite : KIO::DefaultFlags) | KIO::HideProgressInfo); connect(job, SIGNAL(result(KJob*)), this, SLOT(slotTaskFinished(KJob*))); jobMap[ job ] = task; } } break; case TT_DELETE: { KIO::DeleteJob *job = KIO::del(leftURL, KIO::DefaultFlags); connect(job, SIGNAL(result(KJob*)), this, SLOT(slotTaskFinished(KJob*))); jobMap[ job ] = task; } break; default: break; } } void Synchronizer::slotTaskFinished(KJob *job) { inTaskFinished++; SynchronizerFileItem * item = jobMap[ job ]; jobMap.remove(job); KIO::filesize_t receivedSize = 0; if (receivedMap.contains(job)) { receivedSize = receivedMap[ job ]; receivedMap.remove(job); } if (disableNewTasks && item == lastTask) disableNewTasks = false; // the blocker task finished QString leftDirName = item->leftDirectory().isEmpty() ? "" : item->leftDirectory() + '/'; QString rightDirName = item->rightDirectory().isEmpty() ? "" : item->rightDirectory() + '/'; QUrl leftURL = Synchronizer::fsUrl(leftBaseDir + leftDirName + item->leftName()); QUrl rightURL = Synchronizer::fsUrl(rightBaseDir + rightDirName + item->rightName()); do { if (!job->error()) { switch (item->task()) { case TT_COPY_TO_LEFT: if (leftURL.isLocalFile()) { struct utimbuf timestamp; timestamp.actime = time(0); timestamp.modtime = item->rightDate() - timeOffset; utime((const char *)(leftURL.adjusted(QUrl::StripTrailingSlash).path().toLocal8Bit()), ×tamp); uid_t newOwnerID = (uid_t) - 1; // chown(2) : -1 means no change if (!item->rightOwner().isEmpty()) { struct passwd* pw = getpwnam(QFile::encodeName(item->rightOwner())); if (pw != 0L) newOwnerID = pw->pw_uid; } gid_t newGroupID = (gid_t) - 1; // chown(2) : -1 means no change if (!item->rightGroup().isEmpty()) { struct group* g = getgrnam(QFile::encodeName(item->rightGroup())); if (g != 0L) newGroupID = g->gr_gid; } chown((const char *)(leftURL.adjusted(QUrl::StripTrailingSlash).path().toLocal8Bit()), newOwnerID, (gid_t) - 1); chown((const char *)(leftURL.adjusted(QUrl::StripTrailingSlash).path().toLocal8Bit()), (uid_t) - 1, newGroupID); chmod((const char *)(leftURL.adjusted(QUrl::StripTrailingSlash).path().toLocal8Bit()), item->rightMode() & 07777); #ifdef HAVE_POSIX_ACL if (!item->rightACL().isNull()) { acl_t acl = acl_from_text(item->rightACL().toLatin1()); if (acl && !acl_valid(acl)) acl_set_file(leftURL.adjusted(QUrl::StripTrailingSlash).path().toLocal8Bit(), ACL_TYPE_ACCESS, acl); if (acl) acl_free(acl); } #endif } break; case TT_COPY_TO_RIGHT: if (rightURL.isLocalFile()) { struct utimbuf timestamp; timestamp.actime = time(0); timestamp.modtime = item->leftDate() + timeOffset; utime((const char *)(rightURL.adjusted(QUrl::StripTrailingSlash).path().toLocal8Bit()), ×tamp); uid_t newOwnerID = (uid_t) - 1; // chown(2) : -1 means no change if (!item->leftOwner().isEmpty()) { struct passwd* pw = getpwnam(QFile::encodeName(item->leftOwner())); if (pw != 0L) newOwnerID = pw->pw_uid; } gid_t newGroupID = (gid_t) - 1; // chown(2) : -1 means no change if (!item->leftGroup().isEmpty()) { struct group* g = getgrnam(QFile::encodeName(item->leftGroup())); if (g != 0L) newGroupID = g->gr_gid; } chown((const char *)(rightURL.adjusted(QUrl::StripTrailingSlash).path().toLocal8Bit()), newOwnerID, (uid_t) - 1); chown((const char *)(rightURL.adjusted(QUrl::StripTrailingSlash).path().toLocal8Bit()), (uid_t) - 1, newGroupID); chmod((const char *)(rightURL.adjusted(QUrl::StripTrailingSlash).path().toLocal8Bit()), item->leftMode() & 07777); #ifdef HAVE_POSIX_ACL if (!item->leftACL().isNull()) { acl_t acl = acl_from_text(item->leftACL().toLatin1()); if (acl && !acl_valid(acl)) acl_set_file(rightURL.adjusted(QUrl::StripTrailingSlash).path().toLocal8Bit(), ACL_TYPE_ACCESS, acl); if (acl) acl_free(acl); } #endif } break; default: break; } } else { if (job->error() == KIO::ERR_FILE_ALREADY_EXIST && item->task() != TT_DELETE) { KIO::RenameDialog_Result result; QString newDest; if (autoSkip) break; KIO::JobUiDelegate *ui = static_cast(job->uiDelegate()); ui->setWindow(syncDlgWidget); if (item->task() == TT_COPY_TO_LEFT) { result = ui->askFileRename(job, i18n("File Already Exists"), rightURL, leftURL, (KIO::RenameDialog_Mode)(KIO::M_OVERWRITE | KIO::M_SKIP | KIO::M_MULTI), newDest, item->rightSize(), item->leftSize(), QDateTime(), QDateTime(), QDateTime::fromTime_t(item->rightDate()), QDateTime::fromTime_t(item->leftDate())); } else { result = ui->askFileRename(job, i18n("File Already Exists"), leftURL, rightURL, (KIO::RenameDialog_Mode)(KIO::M_OVERWRITE | KIO::M_SKIP | KIO::M_MULTI), newDest, item->leftSize(), item->rightSize(), QDateTime(), QDateTime(), QDateTime::fromTime_t(item->leftDate()), QDateTime::fromTime_t(item->rightDate())); } switch (result) { case KIO::R_RENAME: item->setDestination(newDest); executeTask(item); inTaskFinished--; return; case KIO::R_OVERWRITE: item->setOverWrite(); executeTask(item); inTaskFinished--; return; case KIO::R_OVERWRITE_ALL: overWrite = true; executeTask(item); inTaskFinished--; return; case KIO::R_AUTO_SKIP: autoSkip = true; case KIO::R_SKIP: default: break; } break; } if (job->error() != KIO::ERR_DOES_NOT_EXIST || item->task() != TT_DELETE) { if (autoSkip) break; QString error; switch (item->task()) { case TT_COPY_TO_LEFT: error = i18n("Error at copying file %1 to %2.", rightURL.toDisplayString(QUrl::PreferLocalFile), leftURL.toDisplayString(QUrl::PreferLocalFile)); break; case TT_COPY_TO_RIGHT: error = i18n("Error at copying file %1 to %2.", leftURL.toDisplayString(QUrl::PreferLocalFile), rightURL.toDisplayString(QUrl::PreferLocalFile)); break; case TT_DELETE: error = i18n("Error at deleting file %1.", leftURL.toDisplayString(QUrl::PreferLocalFile)); break; default: break; } KIO::JobUiDelegate *ui = static_cast(job->uiDelegate()); ui->setWindow(syncDlgWidget); KIO::SkipDialog_Result result = ui->askSkip(job, KIO::SkipDialog_MultipleItems, error); switch (result) { case KIO::S_CANCEL: executeTask(item); /* simply retry */ inTaskFinished--; return; case KIO::S_AUTO_SKIP: autoSkip = true; default: break; } } } } while (false); switch (item->task()) { case TT_COPY_TO_LEFT: leftCopyNr++; leftCopySize += item->rightSize() - receivedSize; break; case TT_COPY_TO_RIGHT: rightCopyNr++; rightCopySize += item->leftSize() - receivedSize; break; case TT_DELETE: deleteNr++; deleteSize += item->leftSize() - receivedSize; break; default: break; } emit processedSizes(leftCopyNr, leftCopySize, rightCopyNr, rightCopySize, deleteNr, deleteSize); if (--inTaskFinished == 0) { if (paused) emit pauseAccepted(); else synchronizeLoop(); } } void Synchronizer::slotProcessedSize(KJob * job , qulonglong size) { KIO::filesize_t dl = 0, dr = 0, dd = 0; SynchronizerFileItem * item = jobMap[ job ]; KIO::filesize_t lastProcessedSize = 0; if (receivedMap.contains(job)) lastProcessedSize = receivedMap[ job ]; receivedMap[ job ] = size; switch (item->task()) { case TT_COPY_TO_LEFT: dl = size - lastProcessedSize; break; case TT_COPY_TO_RIGHT: dr = size - lastProcessedSize; break; case TT_DELETE: dd = size - lastProcessedSize; break; default: break; } emit processedSizes(leftCopyNr, leftCopySize += dl, rightCopyNr, rightCopySize += dr, deleteNr, deleteSize += dd); } void Synchronizer::pause() { paused = true; } void Synchronizer::resume() { paused = false; synchronizeLoop(); } QString Synchronizer::leftBaseDirectory() { return leftBaseDir; } QString Synchronizer::rightBaseDirectory() { return rightBaseDir; } KgetProgressDialog::KgetProgressDialog(QWidget *parent, const QString &caption, const QString &text, bool modal) : QDialog(parent) { if (caption.isEmpty()) setWindowTitle(caption); setModal(modal); QVBoxLayout *mainLayout = new QVBoxLayout; setLayout(mainLayout); mainLayout->addWidget(new QLabel(text)); mProgressBar = new QProgressBar; mainLayout->addWidget(mProgressBar); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel); mainLayout->addWidget(buttonBox); mPauseButton = new QPushButton(i18n("Pause")); buttonBox->addButton(mPauseButton, QDialogButtonBox::ActionRole); buttonBox->button(QDialogButtonBox::Cancel)->setDefault(true); connect(mPauseButton, SIGNAL(clicked()), SLOT(slotPause())); connect(buttonBox, SIGNAL(rejected()), this, SLOT(slotCancel())); mCancelled = mPaused = false; } void KgetProgressDialog::slotPause() { if ((mPaused = !mPaused) == false) mPauseButton->setText(i18n("Pause")); else mPauseButton->setText(i18n("Resume")); } void KgetProgressDialog::slotCancel() { mCancelled = true; reject(); } void Synchronizer::synchronizeWithKGet() { bool isLeftLocal = QUrl::fromUserInput(leftBaseDirectory(), QString(), QUrl::AssumeLocalFile).isLocalFile(); KgetProgressDialog *progDlg = 0; int processedCount = 0, totalCount = 0; QListIterator it(resultList); while (it.hasNext()) if (it.next()->isMarked()) totalCount++; it.toFront(); while (it.hasNext()) { SynchronizerFileItem * item = it.next(); if (item->isMarked()) { QUrl downloadURL; QUrl destURL; QString destDir; QString leftDirName = item->leftDirectory().isEmpty() ? "" : item->leftDirectory() + '/'; QString rightDirName = item->rightDirectory().isEmpty() ? "" : item->rightDirectory() + '/'; if (progDlg == 0) { progDlg = new KgetProgressDialog(krMainWindow, i18n("Krusader::Synchronizer"), i18n("Feeding the URLs to KGet"), true); progDlg->progressBar()->setMaximum(totalCount); progDlg->show(); qApp->processEvents(); } if (item->task() == TT_COPY_TO_RIGHT && !isLeftLocal) { downloadURL = Synchronizer::fsUrl(leftBaseDirectory() + leftDirName + item->leftName()); destDir = rightBaseDirectory() + rightDirName; destURL = Synchronizer::fsUrl(destDir + item->rightName()); if (item->isDir()) destDir += item->leftName(); } if (item->task() == TT_COPY_TO_LEFT && isLeftLocal) { downloadURL = Synchronizer::fsUrl(rightBaseDirectory() + rightDirName + item->rightName()); destDir = leftBaseDirectory() + leftDirName; destURL = Synchronizer::fsUrl(destDir + item->leftName()); if (item->isDir()) destDir += item->rightName(); } // creating the directory system for (int i = 0; i >= 0 ; i = destDir.indexOf('/', i + 1)) if (!QDir(destDir.left(i)).exists()) QDir().mkdir(destDir.left(i)); if (!item->isDir() && !downloadURL.isEmpty()) { if (QFile(destURL.path()).exists()) QFile(destURL.path()).remove(); QString source = downloadURL.toDisplayString(); if (source.indexOf('@') >= 2) { /* is this an ftp proxy URL? */ int lastAt = source.lastIndexOf('@'); QString startString = source.left(lastAt); QString endString = source.mid(lastAt); startString.replace('@', "%40"); source = startString + endString; } KProcess p; p << KrServices::fullPathName("kget") << source << destURL.path(); if (!p.startDetached()) KMessageBox::error(parentWidget, i18n("Error executing %1.", KrServices::fullPathName("kget"))); } progDlg->progressBar()->setValue(++processedCount); QTime t; t.start(); bool canExit = false; do { qApp->processEvents(); if (progDlg->wasCancelled()) break; canExit = (t.elapsed() > 100); if (progDlg->isPaused() || !canExit) usleep(10000); } while (progDlg->isPaused() || !canExit); if (progDlg->wasCancelled()) break; } } if (progDlg) delete progDlg; } -bool Synchronizer::isDir(const vfile * file) +bool Synchronizer::isDir(const FileItem *file) { if (followSymLinks) { - return file->vfile_isDir(); + return file->isDir(); } else { - return file->vfile_isDir() && !file->vfile_isSymLink(); + return file->isDir() && !file->isSymLink(); } } -QString Synchronizer::readLink(const vfile * file) +QString Synchronizer::readLink(const FileItem *file) { - if (file->vfile_isSymLink()) - return file->vfile_getSymDest(); + if (file->isSymLink()) + return file->getSymDest(); else return QString(); } SynchronizerFileItem *Synchronizer::getItemAt(unsigned ndx) { if (ndx < (unsigned)resultList.count()) return resultList.at(ndx); else return 0; } diff --git a/krusader/Synchronizer/synchronizer.h b/krusader/Synchronizer/synchronizer.h index 97dc19eb..fcbd18b2 100644 --- a/krusader/Synchronizer/synchronizer.h +++ b/krusader/Synchronizer/synchronizer.h @@ -1,243 +1,243 @@ /*************************************************************************** synchronizer.h - description ------------------- copyright : (C) 2003 + by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SYNCHRONIZER_H #define SYNCHRONIZER_H // QtCore #include #include #include // QtGui #include // QtWidgets #include #include # include "synchronizertask.h" #include "synchronizerfileitem.h" class KRQuery; -class vfile; +class FileItem; class Synchronizer : public QObject { Q_OBJECT private: int displayUpdateCount; // the display is refreshed after every x-th change public: Synchronizer(); ~Synchronizer(); int compare(QString leftURL, QString rightURL, KRQuery *query, bool subDirs, bool symLinks, bool igDate, bool asymm, bool cmpByCnt, bool igCase, bool autoSc, QStringList &selFiles, int equThres, int timeOffs, int parThreads, bool hiddenFiles); void stop() { stopped = true; } void setMarkFlags(bool left, bool equal, bool differs, bool right, bool dup, bool sing, bool del); int refresh(bool nostatus = false); bool totalSizes(int *, KIO::filesize_t *, int *, KIO::filesize_t *, int *, KIO::filesize_t *); void synchronize(QWidget *, bool leftCopyEnabled, bool rightCopyEnabled, bool deleteEnabled, bool overWrite, int parThreads); void synchronizeWithKGet(); void setScrolling(bool scroll); void pause(); void resume(); void swapSides(); void reset(); void clearLists(); void exclude(SynchronizerFileItem *); void restore(SynchronizerFileItem *); void reverseDirection(SynchronizerFileItem *); void copyToLeft(SynchronizerFileItem *); void copyToRight(SynchronizerFileItem *); void deleteLeft(SynchronizerFileItem *); QString leftBaseDirectory(); QString rightBaseDirectory(); static QString getTaskTypeName(TaskType taskType); static QUrl fsUrl(QString strUrl); SynchronizerFileItem *getItemAt(unsigned ndx); void setParentWidget(QWidget * widget) { parentWidget = widget; } void compareContentResult(SynchronizerFileItem * item, bool result); signals: void comparedFileData(SynchronizerFileItem *); void markChanged(SynchronizerFileItem *, bool); void synchronizationFinished(); void processedSizes(int, KIO::filesize_t, int, KIO::filesize_t, int, KIO::filesize_t); void pauseAccepted(); void statusInfo(QString); public slots: void slotTaskFinished(KJob*); void slotProcessedSize(KJob * , qulonglong); private: - bool isDir(const vfile * file); - QString readLink(const vfile * file); + bool isDir(const FileItem * file); + QString readLink(const FileItem * file); void compareDirectory(SynchronizerFileItem *, SynchronizerDirList *, SynchronizerDirList *, const QString &leftDir, const QString &rightDir); void addSingleDirectory(SynchronizerFileItem *, SynchronizerDirList *, const QString &, bool); SynchronizerFileItem * addItem(SynchronizerFileItem *, const QString &, const QString &, const QString &, const QString &, bool, bool, KIO::filesize_t, KIO::filesize_t, time_t, time_t, const QString &, const QString &, const QString &, const QString &, const QString &, const QString &, mode_t, mode_t, const QString &, const QString &, TaskType, bool, bool); SynchronizerFileItem * addLeftOnlyItem(SynchronizerFileItem *, const QString &, const QString &, KIO::filesize_t, time_t, const QString &, const QString &, const QString &, mode_t, const QString &, bool isDir = false, bool isTemp = false); SynchronizerFileItem * addRightOnlyItem(SynchronizerFileItem *, const QString &, const QString &, KIO::filesize_t, time_t, const QString &, const QString &, const QString &, mode_t, const QString &, bool isDir = false, bool isTemp = false); SynchronizerFileItem * addDuplicateItem(SynchronizerFileItem *, const QString &, const QString &, const QString &, const QString &, KIO::filesize_t, KIO::filesize_t, time_t, time_t, const QString &, const QString &, const QString &, const QString &, const QString &, const QString &, mode_t, mode_t, const QString &, const QString &, bool isDir = false, bool isTemp = false); bool isMarked(TaskType task, bool dupl); bool markParentDirectories(SynchronizerFileItem *); void synchronizeLoop(); SynchronizerFileItem * getNextTask(); void executeTask(SynchronizerFileItem * task); void setPermanent(SynchronizerFileItem *); void operate(SynchronizerFileItem *item, void (*)(SynchronizerFileItem *)); void compareLoop(); static void excludeOperation(SynchronizerFileItem *item); static void restoreOperation(SynchronizerFileItem *item); static void reverseDirectionOperation(SynchronizerFileItem *item); static void copyToLeftOperation(SynchronizerFileItem *item); static void copyToRightOperation(SynchronizerFileItem *item); static void deleteLeftOperation(SynchronizerFileItem *item); protected: bool recurseSubDirs; // walk through subdirectories also bool followSymLinks; // follow the symbolic links bool ignoreDate; // don't use date info at comparing bool asymmetric; // asymmetric directory update bool cmpByContent; // compare the files by content bool ignoreCase; // case insensitive synchronization for Windows fs bool autoScroll; // automatic update of the directory QList resultList; // the found files QList temporaryList; // temporary files QString leftBaseDir; // the left-side base directory QString rightBaseDir; // the right-side base directory QStringList excludedPaths; // list of the excluded paths KRQuery *query; // the filter used for the query bool stopped; // 'Stop' button was pressed int equalsThreshold;// threshold to treat files equal int timeOffset; // time offset between the left and right sides bool ignoreHidden; // ignores the hidden files bool markEquals; // show the equal files bool markDiffers; // show the different files bool markCopyToLeft; // show the files to copy from right to left bool markCopyToRight;// show the files to copy from left to right bool markDeletable; // show the files to be deleted bool markDuplicates; // show the duplicated items bool markSingles; // show the single items bool leftCopyEnabled;// copy to left is enabled at synchronize bool rightCopyEnabled;// copy to right is enabled at synchronize bool deleteEnabled; // delete is enabled at synchronize bool overWrite; // overwrite or query each modification bool autoSkip; // automatic skipping bool paused; // pause flag bool disableNewTasks;// at mkdir the further task creation is disabled int leftCopyNr; // the file number copied to left int rightCopyNr; // the file number copied to right int deleteNr; // the number of the deleted files int parallelThreads;// the number of the parallel procesing threads KIO::filesize_t leftCopySize; // the total size copied to left KIO::filesize_t rightCopySize; // the total size copied to right KIO::filesize_t deleteSize; // the size of the deleted files int comparedDirs; // the number of the compared directories int fileCount; // the number of counted files private: QList stack; // stack for comparing QMap jobMap; // job maps QMap receivedMap; // the received file size SynchronizerFileItem *lastTask; // reference to the last stack int inTaskFinished; // counter of quasy 'threads' in slotTaskFinished QStringList selectedFiles; // the selected files to compare QWidget *parentWidget; // the parent widget QWidget *syncDlgWidget; // the synchronizer dialog widget QListIterator resultListIt; // iterator for result list }; class QProgressBar; class KgetProgressDialog : public QDialog { Q_OBJECT public: KgetProgressDialog(QWidget *parent = 0, const QString &caption = QString(), const QString &text = QString(), bool modal = false); QProgressBar *progressBar() { return mProgressBar; } public slots: void slotPause(); void slotCancel(); bool wasCancelled() { return mCancelled; } bool isPaused() { return mPaused; } private: QProgressBar *mProgressBar; QPushButton *mPauseButton; bool mCancelled; bool mPaused; }; #endif /* __SYNCHRONIZER_H__ */ diff --git a/krusader/Synchronizer/synchronizerdirlist.cpp b/krusader/Synchronizer/synchronizerdirlist.cpp index c6dcb858..8570e9e2 100644 --- a/krusader/Synchronizer/synchronizerdirlist.cpp +++ b/krusader/Synchronizer/synchronizerdirlist.cpp @@ -1,193 +1,193 @@ /*************************************************************************** synchronizerdirlist.cpp - description ------------------- copyright : (C) 2006 + by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "synchronizerdirlist.h" #ifdef HAVE_POSIX_ACL #include #ifdef HAVE_NON_POSIX_ACL_EXTENSIONS #include #endif #endif #include // QtCore #include // QtWidgets #include #include #include #include #include -#include "../VFS/vfs.h" -#include "../VFS/krpermhandler.h" +#include "../FileSystem/filesystem.h" +#include "../FileSystem/krpermhandler.h" #include "../krservices.h" -SynchronizerDirList::SynchronizerDirList(QWidget *w, bool hidden) : QObject(), QHash(), fileIterator(0), +SynchronizerDirList::SynchronizerDirList(QWidget *w, bool hidden) : QObject(), QHash(), fileIterator(0), parentWidget(w), busy(false), result(false), ignoreHidden(hidden), currentUrl() { } SynchronizerDirList::~SynchronizerDirList() { if (fileIterator) delete fileIterator; - QHashIterator< QString, vfile *> lit(*this); + QHashIterator< QString, FileItem *> lit(*this); while (lit.hasNext()) delete lit.next().value(); } -vfile * SynchronizerDirList::search(const QString &name, bool ignoreCase) +FileItem *SynchronizerDirList::search(const QString &name, bool ignoreCase) { if (!ignoreCase) { if (!contains(name)) return 0; return (*this)[ name ]; } - QHashIterator iter(*this); + QHashIterator iter(*this); iter.toFront(); QString file = name.toLower(); while (iter.hasNext()) { - vfile * item = iter.next().value(); - if (file == item->vfile_getName().toLower()) + FileItem *item = iter.next().value(); + if (file == item->getName().toLower()) return item; } return 0; } -vfile * SynchronizerDirList::first() +FileItem *SynchronizerDirList::first() { if (fileIterator == 0) - fileIterator = new QHashIterator (*this); + fileIterator = new QHashIterator (*this); fileIterator->toFront(); if (fileIterator->hasNext()) return fileIterator->next().value(); return 0; } -vfile * SynchronizerDirList::next() +FileItem *SynchronizerDirList::next() { if (fileIterator == 0) - fileIterator = new QHashIterator (*this); + fileIterator = new QHashIterator (*this); if (fileIterator->hasNext()) return fileIterator->next().value(); return 0; } bool SynchronizerDirList::load(const QString &urlIn, bool wait) { if (busy) return false; currentUrl = urlIn; const QUrl url = QUrl::fromUserInput(urlIn, QString(), QUrl::AssumeLocalFile); - QHashIterator< QString, vfile *> lit(*this); + QHashIterator< QString, FileItem *> lit(*this); while (lit.hasNext()) delete lit.next().value(); clear(); if (fileIterator) { delete fileIterator; fileIterator = 0; } if (url.isLocalFile()) { - const QString dir = vfs::ensureTrailingSlash(url).path(); + const QString dir = FileSystem::ensureTrailingSlash(url).path(); QT_DIR* qdir = QT_OPENDIR(dir.toLocal8Bit()); if (!qdir) { KMessageBox::error(parentWidget, i18n("Cannot open the folder %1.", dir), i18n("Error")); emit finished(result = false); return false; } QT_DIRENT* dirEnt; while ((dirEnt = QT_READDIR(qdir)) != NULL) { const QString name = QString::fromLocal8Bit(dirEnt->d_name); if (name == "." || name == "..") continue; if (ignoreHidden && name.startsWith('.')) continue; - vfile *item = vfs::createLocalVFile(name, dir); + FileItem *item = FileSystem::createLocalFileItem(name, dir); insert(name, item); } QT_CLOSEDIR(qdir); emit finished(result = true); return true; } else { KIO::Job *job = KIO::listDir(KrServices::escapeFileUrl(url), KIO::HideProgressInfo, true); connect(job, SIGNAL(entries(KIO::Job*, const KIO::UDSEntryList&)), this, SLOT(slotEntries(KIO::Job*, const KIO::UDSEntryList&))); connect(job, SIGNAL(result(KJob*)), this, SLOT(slotListResult(KJob*))); busy = true; if (!wait) return true; while (busy) qApp->processEvents(); return result; } } void SynchronizerDirList::slotEntries(KIO::Job *job, const KIO::UDSEntryList& entries) { KIO::ListJob *listJob = static_cast(job); for (const KIO::UDSEntry entry : entries) { - vfile *item = vfs::createVFileFromKIO(entry, listJob->url()); + FileItem *item = FileSystem::createFileItemFromKIO(entry, listJob->url()); if (item) { - insert(item->vfile_getName(), item); + insert(item->getName(), item); } } } void SynchronizerDirList::slotListResult(KJob *job) { busy = false; if (job && job->error()) { job->uiDelegate()->showErrorMessage(); emit finished(result = false); return; } emit finished(result = true); } diff --git a/krusader/Synchronizer/synchronizerdirlist.h b/krusader/Synchronizer/synchronizerdirlist.h index b110f60b..bb32a113 100644 --- a/krusader/Synchronizer/synchronizerdirlist.h +++ b/krusader/Synchronizer/synchronizerdirlist.h @@ -1,76 +1,76 @@ /*************************************************************************** synchronizerdirlist.h - description ------------------- copyright : (C) 2006 + by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SYNCHRONIZERDIRLIST_H #define SYNCHRONIZERDIRLIST_H // QtCore #include #include #include -#include "../VFS/vfile.h" +#include "../FileSystem/fileitem.h" -class SynchronizerDirList : public QObject, public QHash +class SynchronizerDirList : public QObject, public QHash { Q_OBJECT public: SynchronizerDirList(QWidget *w, bool ignoreHidden); ~SynchronizerDirList(); - vfile * search(const QString &name, bool ignoreCase = false); - vfile * first(); - vfile * next(); + FileItem *search(const QString &name, bool ignoreCase = false); + FileItem *first(); + FileItem *next(); inline const QString & url() { return currentUrl; } bool load(const QString &urlIn, bool wait = false); public slots: void slotEntries(KIO::Job * job, const KIO::UDSEntryList& entries); void slotListResult(KJob *job); signals: void finished(bool err); private: - QHashIterator *fileIterator; //< Point to a dictionary of virtual files (vfile). + QHashIterator *fileIterator; //< Point to a dictionary of file items QWidget *parentWidget; bool busy; bool result; bool ignoreHidden; QString currentUrl; }; #endif /* __SYNCHRONIZER_DIR_LIST_H__ */ diff --git a/krusader/Synchronizer/synchronizergui.cpp b/krusader/Synchronizer/synchronizergui.cpp index 6a449e79..9c72fecb 100644 --- a/krusader/Synchronizer/synchronizergui.cpp +++ b/krusader/Synchronizer/synchronizergui.cpp @@ -1,2609 +1,2609 @@ /*************************************************************************** synchronizergui.cpp - description ------------------- copyright : (C) 2003 + by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "synchronizergui.h" #include "../krglobal.h" #include "../defaults.h" #include "../krusaderview.h" #include "../Panel/listpanel.h" #include "../Panel/panelfunc.h" -#include "../VFS/krpermhandler.h" +#include "../FileSystem/krpermhandler.h" #include "../KViewer/krviewer.h" #include "../Dialogs/krspwidgets.h" -#include "../VFS/krquery.h" +#include "../FileSystem/krquery.h" #include "../krservices.h" #include "../krslots.h" #include "../kicons.h" #include "synchronizedialog.h" #include "feedtolistboxdialog.h" #include "synchronizercolors.h" // QtCore #include #include #include #include // QtGui #include #include #include #include #include #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static const char * const right_arrow_button_data[] = { "18 18 97 2", " c None", ". c #000000", "+ c #030D03", "@ c #184F16", "# c #5DB45A", "$ c #2E6C2A", "% c #90D28D", "& c #9CD59A", "* c #32732E", "= c #92CF8F", "- c #BDE9BB", "; c #C4E5C3", "> c #447F41", ", c #108F08", "' c #0F8E08", ") c #108E08", "! c #14970B", "~ c #8DD289", "{ c #87DF7F", "] c #D6F1D3", "^ c #C3E1C1", "/ c #488844", "( c #73D56C", "_ c #D1F4D0", ": c #F3FCF3", "< c #F7FEF7", "[ c #EFFCEF", "} c #DCF6DB", "| c #B4EAB0", "1 c #70D965", "2 c #2AC71B", "3 c #68D85D", "4 c #CFF1CB", "5 c #DCEFDB", "6 c #589955", "7 c #74D46D", "8 c #9DDF98", "9 c #ABE8A5", "0 c #B8EEB4", "a c #9EE797", "b c #74DD6A", "c c #62D758", "d c #23C512", "e c #15BC07", "f c #27C519", "g c #73DC69", "h c #BAEDB6", "i c #B8E7B6", "j c #499145", "k c #77D671", "l c #7BD874", "m c #3AC72C", "n c #42C437", "o c #34C526", "p c #1FC40F", "q c #24C516", "r c #1AB70E", "s c #1ABC0D", "t c #20C411", "u c #5AD94B", "v c #5DE24A", "w c #36C229", "x c #177B11", "y c #7DDA75", "z c #84E07B", "A c #2BC519", "B c #2FBF1F", "C c #33C623", "D c #28C716", "E c #22CC11", "F c #20C511", "G c #23CC13", "H c #31D81C", "I c #4FE03B", "J c #34C725", "K c #137F0D", "L c #157C0E", "M c #126B0F", "N c #126A0E", "O c #116C0C", "P c #13760E", "Q c #179A0E", "R c #37DC22", "S c #4DDF38", "T c #2AB71D", "U c #12720D", "V c #010C00", "W c #28C715", "X c #47DF32", "Y c #2DBD1F", "Z c #116B0D", "` c #2CB122", " . c #23AD18", ".. c #10620C", "+. c #289023", "@. c #125B0E", "#. c #094706", " ", " . + ", " . @ . ", " . # $ . ", " . % & * . ", " . . . . . . . . = - ; > . ", " . , ' ' ' ) , ! ~ { ] ^ / . ", " . ( _ : < [ } | 1 2 3 4 5 6 . ", " . 7 8 9 0 a b c d e f g h i j . ", " . k l m n o p q r s t u v w x . ", " . y z A B C D E F G H I J K . ", " . L M N M O P Q p R S T U . ", " V . . . . . . . W X Y Z . ", " . ` .... ", " . +.@.. ", " . #.. ", " . . ", " " }; static const char * const equals_button_data[] = { "18 18 5 1", " c None", ". c #414100", "+ c #E0E0E0", "@ c #A8A8A8", "# c #808080", " ", " ", " ", " .............. ", " .++++++++++++. ", " .@@@@@@@@@@@@. ", " .############. ", " .............. ", " ", " .............. ", " .++++++++++++. ", " .@@@@@@@@@@@@. ", " .############. ", " .............. ", " ", " ", " ", " " }; static const char * const differents_button_data[] = { "18 18 5 1", " c None", ". c #FF0000", "+ c #FFC0C0", "@ c #FF8080", "# c #FF4040", " ", " ... ", " ... ", " .............. ", " .+++++++...++. ", " .@@@@@@...@@@. ", " .######...###. ", " .............. ", " ... ", " .............. ", " .++++...+++++. ", " .@@@...@@@@@@. ", " .###...######. ", " .............. ", " ... ", " ... ", " ... ", " " }; static const char * const left_arrow_button_data[] = { "18 18 137 2", " c None", ". c #03090E", "+ c #0D3A57", "@ c #041F2B", "# c #073347", "$ c #0D3C5A", "% c #051C26", "& c #0F455C", "* c #237191", "= c #104363", "- c #04121A", "; c #0C4A62", "> c #198AAD", ", c #2291B2", "' c #104564", ") c #062332", "! c #0D506B", "~ c #209FBD", "{ c #33CBDF", "] c #16ACC8", "^ c #0C4968", "/ c #061F2D", "( c #031721", "_ c #041621", ": c #051721", "< c #021621", "[ c #031B27", "} c #01090D", "| c #04151E", "1 c #0D5672", "2 c #1E99B8", "3 c #39CEDF", "4 c #22C5DC", "5 c #10A1C4", "6 c #0E799B", "7 c #0E5976", "8 c #0D516D", "9 c #0F4E6B", "0 c #0F4D6A", "a c #0F607D", "b c #031D25", "c c #052837", "d c #0D617F", "e c #25ABC7", "f c #3BD0E1", "g c #1DC0D9", "h c #14A8CC", "i c #11A3C5", "j c #11ABCC", "k c #17AAC8", "l c #23ACC6", "m c #1FA8C0", "n c #1AAAC5", "o c #7CCDE1", "p c #76C4DB", "q c #032832", "r c #061D28", "s c #125F7C", "t c #29A6C3", "u c #4BD4E3", "v c #4BC5DA", "w c #129FC4", "x c #0D95BC", "y c #0F90B7", "z c #16A2C5", "A c #0FA3C4", "B c #26A8C5", "C c #37A8C4", "D c #2DA9C7", "E c #75C1D9", "F c #71BED6", "G c #0A212C", "H c #467B92", "I c #B6D9E8", "J c #B6E2ED", "K c #69C7DC", "L c #19A2C5", "M c #0796BC", "N c #13A5C5", "O c #59BBD7", "P c #6BC5DD", "Q c #98D8E8", "R c #B4E2EE", "S c #A6DCE9", "T c #98CFDF", "U c #6DBCD4", "V c #143341", "W c #56859A", "X c #DCEAF0", "Y c #CCEAF2", "Z c #5EC2D9", "` c #1BA7C8", " . c #66C4DA", ".. c #B1DBEB", "+. c #DBEEF6", "@. c #EFF6FC", "#. c #F7FAFE", "$. c #F3F8FC", "%. c #D0EAF4", "&. c #6CBCD5", "*. c #091A21", "=. c #457589", "-. c #C2D8E2", ";. c #D4ECF2", ">. c #80CCDF", ",. c #8ABFD3", "'. c #0C7497", "). c #086E90", "!. c #086C8E", "~. c #086B8E", "{. c #086D90", "]. c #021E27", "^. c #0D2B38", "/. c #426D80", "(. c #C3DAE5", "_. c #BCDCEA", ":. c #90BDD0", "<. c #144361", "[. c #002745", "}. c #00213F", "|. c #001F3E", "1. c #00203F", "2. c #002643", "3. c #000B13", "4. c #03161D", "5. c #2F5F73", "6. c #9AC3D5", "7. c #8EBED3", "8. c #1A4A68", "9. c #0C222B", "0. c #2B5A6D", "a. c #5A98B4", "b. c #164867", "c. c #0F2731", "d. c #163E50", "e. c #0E3E5C", "f. c #0C3652", " ", " . f. ", " c.d.e. ", " 9.0.a.b. ", " 4.5.6.7.8. ", " ^./.(._.:.<.[.}.|.|.1.2.3. ", " *.=.-.;.>.,.'.).!.~.~.~.{.]. ", " V W X Y Z ` ...+.@.#.$.%.&.q ", " G H I J K L M N O P Q R S T U q ", " r s t u v w x y z A B C D E F q ", " c d e f g h i j k l m n o p q ", " | 1 2 3 4 5 6 7 8 9 0 9 a b ", " ) ! ~ { ] ^ / ( _ : < [ } ", " - ; > , ' ", " % & * = ", " @ # $ ", " . + ", " " }; static const char * const trash_button_data[] = { "18 18 140 2", " c None", ". c #BFBFBF", "+ c #BABAB9", "@ c #AEAEAE", "# c #A2A2A3", "$ c #959595", "% c #8B8B8C", "& c #868687", "* c #D3D5D5", "= c #E1E1E1", "- c #CCCCCD", "; c #BDBEBD", "> c #B1B2B1", ", c #A3A2A2", "' c #959597", ") c #8E8E8F", "! c #818282", "~ c #727171", "{ c #838384", "] c #D1D1D1", "^ c #F3F3F3", "/ c #C6C7C6", "( c #B8B9B9", "_ c #ABABAB", ": c #9F9FA0", "< c #949394", "[ c #8E8E8E", "} c #7E8080", "| c #717071", "1 c #5C5C5B", "2 c #555556", "3 c #A7A7A7", "4 c #FAFAFA", "5 c #CACACA", "6 c #BABBBB", "7 c #B5B6B6", "8 c #A9A9AA", "9 c #9E9E9D", "0 c #929293", "a c #8E8C8D", "b c #7F7F7F", "c c #6F6F70", "d c #525151", "e c #414141", "f c #A1A2A2", "g c #C3C3C2", "h c #D5D4D4", "i c #ECECEC", "j c #E7E7E7", "k c #D6D6D6", "l c #C5C5C6", "m c #B0B0B0", "n c #AAAAAA", "o c #989898", "p c #6D6D6E", "q c #494949", "r c #9E9E9E", "s c #C0C1C1", "t c #BABABA", "u c #B2B2B2", "v c #AEAEAD", "w c #A4A4A4", "x c #9B9B9B", "y c #8E8F8F", "z c #888888", "A c #767676", "B c #616161", "C c #B3B3B3", "D c #B9B9BA", "E c #A4A5A4", "F c #979797", "G c #888788", "H c #6D6D6D", "I c #4D4D4D", "J c #4B4A4B", "K c #F6F6F6", "L c #B1B1B1", "M c #A7A8A7", "N c #939394", "O c #8D8D8E", "P c #727272", "Q c #505050", "R c #484848", "S c #EEEEEE", "T c #EBEBEB", "U c #9D9D9C", "V c #919292", "W c #8C8C8C", "X c #808080", "Y c #6C6B6C", "Z c #E5E5E5", "` c #AFAFAF", " . c #A6A6A6", ".. c #8F908F", "+. c #888989", "@. c #7B7B7B", "#. c #676667", "$. c #4F4F4F", "%. c #AFB0AF", "&. c #D8D8D8", "*. c #D4D4D4", "=. c #A5A5A4", "-. c #9A9A9A", ";. c #8D8D8D", ">. c #777777", ",. c #5F5F5F", "'. c #4B4B4B", "). c #B0AFAF", "!. c #D3D2D2", "~. c #CDCDCD", "{. c #A4A5A5", "]. c #8D8D8B", "^. c #868685", "/. c #747474", "(. c #5D5D5D", "_. c #AEAFAE", ":. c #C4C4C4", "<. c #BEBEBE", "[. c #A3A4A3", "}. c #8B8A8A", "|. c #838282", "1. c #707070", "2. c #565656", "3. c #444444", "4. c #000000", "5. c #B2B1B1", "6. c #ADADAD", "7. c #A3A3A3", "8. c #979697", "9. c #6C6C6C", "0. c #403F3F", "a. c #B1B2B2", "b. c #9F9F9F", "c. c #A6A6A7", "d. c #9E9F9F", "e. c #949494", "f. c #828282", "g. c #787979", "h. c #3D3D3C", "i. c #2F2F2F", " ", " . + @ # $ % & % ", " * = - ; > , ' ) ! ~ { ", " ] ^ / ; ( _ : < [ } | 1 2 ", " 3 4 5 6 7 8 9 0 a b c d e ", " f g h i j k l m n o p q e ", " r s t u v w x y z A B e 2 ", " [ C D C E F G b H I J ", " C K ^ L M r N O P Q R ", " L S T m 3 U V W X Y R ", " m Z = ` .x ..+.@.#.$. ", " %.&.*.@ =.-.;.& >.,.'. ", " ).!.~.@ {.-.].^./.(.R ", " _.:.<.@ [.o }.|.1.2.3.4.4.4. ", " @ D 5.6.7.8.z b 9.Q 0.4.4.4.4. ", " a.b.c.3 d.e.f.g.(.h.i.4.4.4.4. ", " 4.4.4.4.4.4.4.4. ", " " }; static const char * const file_data[] = { "16 16 42 1", " c None", ". c #D0D0DF", "+ c #9C9CB6", "@ c #FFFFFF", "# c #F9F9FE", "$ c #F5F5FC", "% c #E9E9F2", "& c #EBEBF4", "* c #FCFCFF", "= c #F8F8FE", "- c #ECECF4", "; c #D3D3E1", "> c #EFEFF6", ", c #FDFDFF", "' c #F1F1F8", ") c #E6E6F0", "! c #D7D7E5", "~ c #C9C9DA", "{ c #FEFEFF", "] c #F2F2F9", "^ c #EEEEF5", "/ c #DADAE7", "( c #CECEDD", "_ c #CCCCDB", ": c #F3F3F9", "< c #D5D5E4", "[ c #D2D2E0", "} c #E7E7F0", "| c #E0E0EC", "1 c #DCDCE9", "2 c #DBDBE8", "3 c #D8D8E6", "4 c #F6F6FD", "5 c #E5E5EF", "6 c #DEDEEB", "7 c #F0F0F7", "8 c #EAEAF3", "9 c #E8E8F1", "0 c #E1E1ED", "a c #F4F4FA", "b c #E4E4EE", "c c #FAFAFF", " ........+ ", " .@@@#$%&.+ ", " .@@@*=-&.;+ ", " .@@@*#>&++++ ", " .@@@,#'&)!~+ ", " .@@@{*]^/(_+ ", " .@@@@*:&<[.+ ", " .@@{#$}|123+ ", " .@{,4^)5|61+ ", " .@@#7^8950|+ ", " .@,a'>&8)b|+ ", " .@c:'>&8}50+ ", " .@$:'7^8}50+ ", " .@:]7>-8)50+ ", " .*::'>&8}50+ ", " ++++++++++++ " }; static const char * const folder_data[] = { "16 16 132 2", " c None", ". c #2C87EF", "+ c #64A6F7", "@ c #357CE3", "# c #D9E1F8", "$ c #B1BADE", "% c #8BA2D9", "& c #4392E3", "* c #B8D9F8", "= c #4F9BED", "- c #126EE0", "; c #0A43A8", "> c #C6CBDA", ", c #FFFFFF", "' c #F1F0F6", ") c #80ADE2", "! c #4F95E4", "~ c #1876DF", "{ c #0C6ADF", "] c #0C4CB9", "^ c #CCCFDA", "/ c #F8F4F7", "( c #89B7E7", "_ c #78ACE4", ": c #B4D8F8", "< c #97CAFF", "[ c #6FAEFC", "} c #3175D8", "| c #0E51B4", "1 c #002374", "2 c #D0D0D7", "3 c #8EC1F0", "4 c #85BBED", "5 c #DAF0F9", "6 c #BDE2FB", "7 c #9CCCF8", "8 c #84BBF8", "9 c #6FAAF4", "0 c #4780D4", "a c #0851AA", "b c #0035A9", "c c #CFD0D4", "d c #51A2E9", "e c #FFFFFE", "f c #EEFCFD", "g c #CEECFB", "h c #B1D9F9", "i c #9AC9F9", "j c #7EB3F2", "k c #568CDA", "l c #1156BA", "m c #004595", "n c #003293", "o c #EFEFEE", "p c #84BCEE", "q c #E2F8FC", "r c #C9E8FB", "s c #B0D8FA", "t c #90C0F3", "u c #6B9FE5", "v c #3375CC", "w c #2A71C7", "x c #003B96", "y c #0651AE", "z c #0E3DAC", "A c #E5E3E0", "B c #DFD8D5", "C c #FFF7F2", "D c #DEEFFE", "E c #BEDCF6", "F c #E5FCFD", "G c #C4E6FB", "H c #A8D4F8", "I c #85B6EC", "J c #437DCE", "K c #2170C9", "L c #397CC8", "M c #A3B6D4", "N c #E3D3D2", "O c #295BC3", "P c #4AACFF", "Q c #74A7D5", "R c #CBC7CE", "S c #7EB0E7", "T c #F5FFFF", "U c #C1E7FE", "V c #9AC8F3", "W c #4B84D3", "X c #5490D9", "Y c #B3C7E3", "Z c #E9DFDF", "` c #D3CED8", " . c #D7CFD3", ".. c #7488C1", "+. c #002A95", "@. c #6FCDFF", "#. c #CBEAFF", "$. c #D9F9FF", "%. c #70AAE1", "&. c #C7E0EE", "*. c #9DCBF1", "=. c #84AEE4", "-. c #D0E1F4", ";. c #FFF9F4", ">. c #EEE9EB", ",. c #E6E2E5", "'. c #D9D1D6", "). c #637DC0", "!. c #2D63D3", "~. c #001251", "{. c #439FF0", "]. c #B4DBF9", "^. c #D6F8FF", "/. c #75ACE3", "(. c #F0FAFF", "_. c #FCF9F8", ":. c #91A5D4", "<. c #2A5FCE", "[. c #002B91", "}. c #3E9DEF", "|. c #A4CEF4", "1. c #77AFE8", "2. c #E1EBFC", "3. c #3F73D7", "4. c #043BAE", "5. c #3188DE", "6. c #75A9E3", "7. c #A8C6EC", "8. c #6195E7", "9. c #1450C5", "0. c #7AB0FB", "a. c #155ED2", " ", " . + @ ", " # $ % & * = - ; ", " > , , ' ) ! ~ { ] ", " ^ , / ( _ : < [ } | 1 ", " 2 , 3 4 5 6 7 8 9 0 a b ", " c , d e f g h i j k l m n ", "o , , p , q r s t u v w x y z ", "A B C D E F G H I J K L M N O ", " P Q R S T U V W X Y Z ` ...+.", " @.#.$.%.&.*.=.-.;.>.,.'.).!.~.", " {.].^./.(., , _.C :.<.[. ", " }.|.1., , , 2.3.4. ", " 5.6.7., 8.9. ", " 0.a. ", " " }; static const char * const swap_sides_data[] = { "27 20 228 2", " c None", ". c #03090E", "+ c #0C3652", "@ c #000000", "# c #030D03", "$ c #0F2731", "% c #163E50", "& c #0E3E5C", "* c #184F16", "= c #0C222B", "- c #2B5A6D", "; c #5A98B4", "> c #164867", ", c #5DB45A", "' c #2E6C2A", ") c #03161D", "! c #2F5F73", "~ c #9AC3D5", "{ c #8EBED3", "] c #1A4A68", "^ c #90D28D", "/ c #9CD59A", "( c #32732E", "_ c #0D2B38", ": c #426D80", "< c #C3DAE5", "[ c #BCDCEA", "} c #90BDD0", "| c #144361", "1 c #002745", "2 c #00213F", "3 c #001F3E", "4 c #00203F", "5 c #002643", "6 c #92CF8F", "7 c #BDE9BB", "8 c #C4E5C3", "9 c #447F41", "0 c #091A21", "a c #457589", "b c #C2D8E2", "c c #D4ECF2", "d c #80CCDF", "e c #8ABFD3", "f c #0C7497", "g c #086E90", "h c #086C8E", "i c #086B8E", "j c #086D90", "k c #108F08", "l c #0F8E08", "m c #108E08", "n c #14970B", "o c #8DD289", "p c #87DF7F", "q c #D6F1D3", "r c #C3E1C1", "s c #488844", "t c #143341", "u c #56859A", "v c #DCEAF0", "w c #CCEAF2", "x c #5EC2D9", "y c #1BA7C8", "z c #66C4DA", "A c #B1DBEB", "B c #DBEEF6", "C c #EFF6FC", "D c #F7FAFE", "E c #F3F8FC", "F c #D0EAF4", "G c #6CBCD5", "H c #73D56C", "I c #D1F4D0", "J c #F3FCF3", "K c #F7FEF7", "L c #EFFCEF", "M c #DCF6DB", "N c #B4EAB0", "O c #70D965", "P c #2AC71B", "Q c #68D85D", "R c #CFF1CB", "S c #DCEFDB", "T c #589955", "U c #0A212C", "V c #467B92", "W c #B6D9E8", "X c #B6E2ED", "Y c #69C7DC", "Z c #19A2C5", "` c #0796BC", " . c #13A5C5", ".. c #59BBD7", "+. c #6BC5DD", "@. c #98D8E8", "#. c #B4E2EE", "$. c #A6DCE9", "%. c #98CFDF", "&. c #6DBCD4", "*. c #74D46D", "=. c #9DDF98", "-. c #ABE8A5", ";. c #B8EEB4", ">. c #9EE797", ",. c #74DD6A", "'. c #62D758", "). c #23C512", "!. c #15BC07", "~. c #27C519", "{. c #73DC69", "]. c #BAEDB6", "^. c #B8E7B6", "/. c #499145", "(. c #061D28", "_. c #125F7C", ":. c #29A6C3", "<. c #4BD4E3", "[. c #4BC5DA", "}. c #129FC4", "|. c #0D95BC", "1. c #0F90B7", "2. c #16A2C5", "3. c #0FA3C4", "4. c #26A8C5", "5. c #37A8C4", "6. c #2DA9C7", "7. c #75C1D9", "8. c #71BED6", "9. c #77D671", "0. c #7BD874", "a. c #3AC72C", "b. c #42C437", "c. c #34C526", "d. c #1FC40F", "e. c #24C516", "f. c #1AB70E", "g. c #1ABC0D", "h. c #20C411", "i. c #5AD94B", "j. c #5DE24A", "k. c #36C229", "l. c #177B11", "m. c #052837", "n. c #0D617F", "o. c #25ABC7", "p. c #3BD0E1", "q. c #1DC0D9", "r. c #14A8CC", "s. c #11A3C5", "t. c #11ABCC", "u. c #17AAC8", "v. c #23ACC6", "w. c #1FA8C0", "x. c #1AAAC5", "y. c #7CCDE1", "z. c #76C4DB", "A. c #7DDA75", "B. c #84E07B", "C. c #2BC519", "D. c #2FBF1F", "E. c #33C623", "F. c #28C716", "G. c #22CC11", "H. c #20C511", "I. c #23CC13", "J. c #31D81C", "K. c #4FE03B", "L. c #34C725", "M. c #137F0D", "N. c #04151E", "O. c #0D5672", "P. c #1E99B8", "Q. c #39CEDF", "R. c #22C5DC", "S. c #10A1C4", "T. c #0E799B", "U. c #0E5976", "V. c #0D516D", "W. c #0F4E6B", "X. c #0F4D6A", "Y. c #0F607D", "Z. c #157C0E", "`. c #126B0F", " + c #126A0E", ".+ c #116C0C", "++ c #13760E", "@+ c #179A0E", "#+ c #37DC22", "$+ c #4DDF38", "%+ c #2AB71D", "&+ c #12720D", "*+ c #062332", "=+ c #0D506B", "-+ c #209FBD", ";+ c #33CBDF", ">+ c #16ACC8", ",+ c #0C4968", "'+ c #061F2D", ")+ c #031721", "!+ c #041621", "~+ c #051721", "{+ c #021621", "]+ c #031B27", "^+ c #010C00", "/+ c #28C715", "(+ c #47DF32", "_+ c #2DBD1F", ":+ c #116B0D", "<+ c #04121A", "[+ c #0C4A62", "}+ c #198AAD", "|+ c #2291B2", "1+ c #104564", "2+ c #2CB122", "3+ c #23AD18", "4+ c #10620C", "5+ c #051C26", "6+ c #0F455C", "7+ c #237191", "8+ c #104363", "9+ c #289023", "0+ c #125B0E", "a+ c #041F2B", "b+ c #073347", "c+ c #0D3C5A", "d+ c #094706", "e+ c #0D3A57", " ", " ", " . + @ # ", " $ % & @ * @ ", " = - ; > @ , ' @ ", " ) ! ~ { ] @ ^ / ( @ ", " _ : < [ } | 1 3 4 5 @ @ @ @ @ @ 6 7 8 9 @ ", " 0 a b c d e f g i i j @ k l l k n o p q r s @ ", " t u v w x y z A B E F G @ H I K M N O P Q R S T @ ", "U V W X Y Z ` ...+.$.%.&.@ *.=.;.,.'.).!.~.{.].^./.@ ", "(._.:.<.[.}.|.1.2.3.6.7.8.@ 9.0.b.d.e.f.g.h.i.j.k.l.@ ", " m.n.o.p.q.r.s.t.u.x.y.z.@ A.B.D.F.G.H.I.J.K.L.M.@ ", " N.O.P.Q.R.S.T.U.X.W.Y.@ Z.`.`.++@+d.#+$+%+&+@ ", " *+=+-+;+>+,+'+~+{+]+^+@ @ @ @ @ /+(+_+:+@ ", " <+[+}+|+1+ @ 2+3+4+@ ", " 5+6+7+8+ @ 9+0+@ ", " a+b+c+ @ d+@ ", " . e+ @ @ ", " ", " " }; class SynchronizerListView : public KrTreeWidget { private: Synchronizer *synchronizer; bool isLeft; public: SynchronizerListView(Synchronizer * sync, QWidget * parent) : KrTreeWidget(parent), synchronizer(sync) { } void mouseMoveEvent(QMouseEvent * e) { isLeft = ((e->modifiers() & Qt::ShiftModifier) == 0); KrTreeWidget::mouseMoveEvent(e); } void startDrag(Qt::DropActions /* supportedActs */) { QList urls; unsigned ndx = 0; SynchronizerFileItem *currentItem; while ((currentItem = synchronizer->getItemAt(ndx++)) != 0) { SynchronizerGUI::SyncViewItem *viewItem = (SynchronizerGUI::SyncViewItem *)currentItem->userData(); if (!viewItem || !viewItem->isSelected() || viewItem->isHidden()) continue; SynchronizerFileItem *item = viewItem->synchronizerItemRef(); if (item) { if (isLeft && item->existsInLeft()) { QString leftDirName = item->leftDirectory().isEmpty() ? "" : item->leftDirectory() + '/'; QUrl leftURL = Synchronizer::fsUrl(synchronizer->leftBaseDirectory() + leftDirName + item->leftName()); urls.push_back(leftURL); } else if (!isLeft && item->existsInRight()) { QString rightDirName = item->rightDirectory().isEmpty() ? "" : item->rightDirectory() + '/'; QUrl rightURL = Synchronizer::fsUrl(synchronizer->rightBaseDirectory() + rightDirName + item->rightName()); urls.push_back(rightURL); } } } if (urls.count() == 0) return; QDrag *drag = new QDrag(this); QMimeData *mimeData = new QMimeData; mimeData->setImageData(FL_LOADICON(isLeft ? "arrow-left-double" : "arrow-right-double")); mimeData->setUrls(urls); drag->setMimeData(mimeData); drag->start(); } }; SynchronizerGUI::SynchronizerGUI(QWidget* parent, QUrl leftURL, QUrl rightURL, QStringList selList) : QDialog(parent) { initGUI(parent, QString(), leftURL, rightURL, selList); } SynchronizerGUI::SynchronizerGUI(QWidget* parent, QString profile) : QDialog(parent) { initGUI(parent, profile, QUrl(), QUrl(), QStringList()); } void SynchronizerGUI::initGUI(QWidget* /* parent */, QString profileName, QUrl leftURL, QUrl rightURL, QStringList selList) { selectedFiles = selList; isComparing = wasClosed = wasSync = false; firstResize = true; sizeX = sizeY = -1; bool equalSizes = false; hasSelectedFiles = (selectedFiles.count() != 0); if (leftURL.isEmpty()) leftURL = QUrl::fromLocalFile(ROOT_DIR); if (rightURL.isEmpty()) rightURL = QUrl::fromLocalFile(ROOT_DIR); setWindowTitle(i18n("Krusader::Synchronize Folders")); QGridLayout *synchGrid = new QGridLayout(this); synchGrid->setSpacing(6); synchGrid->setContentsMargins(11, 11, 11, 11); folderIcon = QPixmap((const char**) folder_data); fileIcon = QPixmap((const char**) file_data); synchronizerTabs = new QTabWidget(this); /* ============================== Compare groupbox ============================== */ QWidget *synchronizerTab = new QWidget(this); QGridLayout *synchronizerGrid = new QGridLayout(synchronizerTab); synchronizerGrid->setSpacing(6); synchronizerGrid->setContentsMargins(11, 11, 11, 11); QGroupBox *compareDirs = new QGroupBox(synchronizerTab); compareDirs->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); compareDirs->setTitle(i18n("Folder Comparison")); QGridLayout *grid = new QGridLayout(compareDirs); grid->setSpacing(6); grid->setContentsMargins(11, 11, 11, 11); leftDirLabel = new QLabel(compareDirs); leftDirLabel->setAlignment(Qt::AlignHCenter); grid->addWidget(leftDirLabel, 0 , 0); QLabel *filterLabel = new QLabel(compareDirs); filterLabel->setText(i18n("File &Filter:")); filterLabel->setAlignment(Qt::AlignHCenter); grid->addWidget(filterLabel, 0 , 1); rightDirLabel = new QLabel(compareDirs); rightDirLabel->setAlignment(Qt::AlignHCenter); grid->addWidget(rightDirLabel, 0 , 2); KConfigGroup group(krConfig, "Synchronize"); leftLocation = new KHistoryComboBox(false, compareDirs); leftLocation->setMaxCount(25); // remember 25 items leftLocation->setDuplicatesEnabled(false); leftLocation->setEditable(true); leftLocation->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); QStringList list = group.readEntry("Left Folder History", QStringList()); leftLocation->setHistoryItems(list); KUrlRequester *leftUrlReq = new KUrlRequester(leftLocation, compareDirs); leftUrlReq->setUrl(leftURL); leftUrlReq->setMode(KFile::Directory); leftUrlReq->setMinimumWidth(250); grid->addWidget(leftUrlReq, 1 , 0); leftLocation->setWhatsThis(i18n("The left base folder used during the synchronization process.")); leftUrlReq->setEnabled(!hasSelectedFiles); leftLocation->setEnabled(!hasSelectedFiles); leftDirLabel->setBuddy(leftLocation); fileFilter = new KHistoryComboBox(false, compareDirs); fileFilter->setMaxCount(25); // remember 25 items fileFilter->setDuplicatesEnabled(false); fileFilter->setMinimumWidth(100); fileFilter->setMaximumWidth(100); fileFilter->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); list = group.readEntry("File Filter", QStringList()); fileFilter->setHistoryItems(list); fileFilter->setEditText("*"); grid->addWidget(fileFilter, 1 , 1); filterLabel->setBuddy(fileFilter); QString wtFilter = "

" + i18n("

The filename filtering criteria is defined here.

You can make use of wildcards. Multiple patterns are separated by space (means logical OR) and patterns are excluded from the search using the pipe symbol.

If the pattern is ended with a slash (*pattern*/), that means that pattern relates to recursive search of folders.

  • pattern - means to search those files/folders that name is pattern, recursive search goes through all subfolders independently of the value of pattern
  • pattern/ - means to search all files/folders, but recursive search goes through/excludes the folders that name is pattern

It is allowed to use quotation marks for names that contain space. Filter \"Program Files\" searches out those files/folders that name is Program Files.

Examples:

  • *.o
  • *.h *.c\?\?
  • *.cpp *.h | *.moc.cpp
  • * | .svn/ .git/

Note: the search term 'text' is equivalent to '*text*'.

"); fileFilter->setWhatsThis(wtFilter); filterLabel->setWhatsThis(wtFilter); rightLocation = new KHistoryComboBox(compareDirs); rightLocation->setMaxCount(25); // remember 25 items rightLocation->setDuplicatesEnabled(false); rightLocation->setEditable(true); rightLocation->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); list = group.readEntry("Right Folder History", QStringList()); rightLocation->setHistoryItems(list); KUrlRequester *rightUrlReq = new KUrlRequester(rightLocation, compareDirs); rightUrlReq->setUrl(rightURL); rightUrlReq->setMode(KFile::Directory); rightUrlReq->setMinimumWidth(250); grid->addWidget(rightUrlReq, 1 , 2); rightLocation->setWhatsThis(i18n("The right base folder used during the synchronization process.")); rightUrlReq->setEnabled(!hasSelectedFiles); rightLocation->setEnabled(!hasSelectedFiles); rightDirLabel->setBuddy(rightLocation); QWidget *optionWidget = new QWidget(compareDirs); QHBoxLayout *optionBox = new QHBoxLayout(optionWidget); optionBox->setContentsMargins(0, 0, 0, 0); QWidget *optionGridWidget = new QWidget(optionWidget); QGridLayout *optionGrid = new QGridLayout(optionGridWidget); optionBox->addWidget(optionGridWidget); cbSubdirs = new QCheckBox(i18n("Recurse subfolders"), optionGridWidget); cbSubdirs->setChecked(group.readEntry("Recurse Subdirectories", _RecurseSubdirs)); optionGrid->addWidget(cbSubdirs, 0, 0); cbSubdirs->setWhatsThis(i18n("Compare not only the base folders but their subfolders as well.")); cbSymlinks = new QCheckBox(i18n("Follow symlinks"), optionGridWidget); cbSymlinks->setChecked(group.readEntry("Follow Symlinks", _FollowSymlinks)); cbSymlinks->setEnabled(cbSubdirs->isChecked()); optionGrid->addWidget(cbSymlinks, 0, 1); cbSymlinks->setWhatsThis(i18n("Follow symbolic links during the compare process.")); cbByContent = new QCheckBox(i18n("Compare by content"), optionGridWidget); cbByContent->setChecked(group.readEntry("Compare By Content", _CompareByContent)); optionGrid->addWidget(cbByContent, 0, 2); cbByContent->setWhatsThis(i18n("Compare duplicated files with same size by content.")); cbIgnoreDate = new QCheckBox(i18n("Ignore Date"), optionGridWidget); cbIgnoreDate->setChecked(group.readEntry("Ignore Date", _IgnoreDate)); optionGrid->addWidget(cbIgnoreDate, 1, 0); cbIgnoreDate->setWhatsThis(i18n("

Ignore date information during the compare process.

Note: useful if the files are located on network filesystems or in archives.

")); cbAsymmetric = new QCheckBox(i18n("Asymmetric"), optionGridWidget); cbAsymmetric->setChecked(group.readEntry("Asymmetric", _Asymmetric)); optionGrid->addWidget(cbAsymmetric, 1, 1); cbAsymmetric->setWhatsThis(i18n("

Asymmetric mode

The left side is the destination, the right is the source folder. Files existing only in the left folder will be deleted, the other differing ones will be copied from right to left.

Note: useful when updating a folder from a file server.

")); cbIgnoreCase = new QCheckBox(i18n("Ignore Case"), optionGridWidget); cbIgnoreCase->setChecked(group.readEntry("Ignore Case", _IgnoreCase)); optionGrid->addWidget(cbIgnoreCase, 1, 2); cbIgnoreCase->setWhatsThis(i18n("

Case insensitive filename compare.

Note: useful when synchronizing Windows filesystems.

")); /* =========================== Show options groupbox ============================= */ QGroupBox *showOptions = new QGroupBox(optionWidget); optionBox->addWidget(showOptions); showOptions->setTitle(i18n("S&how options")); showOptions->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); QGridLayout *showOptionsLayout = new QGridLayout(showOptions); showOptionsLayout->setSpacing(4); showOptionsLayout->setContentsMargins(11, 11, 11, 11); QPixmap showLeftToRight((const char**) right_arrow_button_data); QPixmap showEquals((const char**) equals_button_data); QPixmap showDifferents((const char**) differents_button_data); QPixmap showRightToLeft((const char**) left_arrow_button_data); QPixmap showDeletable((const char**) trash_button_data); btnLeftToRight = new QPushButton(showOptions); btnLeftToRight->setText(""); btnLeftToRight->setIcon(QIcon(showLeftToRight)); btnLeftToRight->setCheckable(true); btnLeftToRight->setChecked(group.readEntry("LeftToRight Button", _BtnLeftToRight)); btnLeftToRight->setShortcut(Qt::CTRL + Qt::Key_L); btnLeftToRight->setWhatsThis(i18n("Show files marked to Copy from left to right (Ctrl+L).")); btnLeftToRight->setFixedSize(showLeftToRight.width() + 15, showLeftToRight.height() + 15); showOptionsLayout->addWidget(btnLeftToRight, 0, 0); btnEquals = new QPushButton(showOptions); btnEquals->setText(""); btnEquals->setIcon(QIcon(showEquals)); btnEquals->setCheckable(true); btnEquals->setChecked(group.readEntry("Equals Button", _BtnEquals)); btnEquals->setShortcut(Qt::CTRL + Qt::Key_E); btnEquals->setWhatsThis(i18n("Show files considered to be identical (Ctrl+E).")); btnEquals->setFixedSize(showEquals.width() + 15, showEquals.height() + 15); showOptionsLayout->addWidget(btnEquals, 0, 1); btnDifferents = new QPushButton(showOptions); btnDifferents->setText(""); btnDifferents->setIcon(QIcon(showDifferents)); btnDifferents->setCheckable(true); btnDifferents->setChecked(group.readEntry("Differents Button", _BtnDifferents)); btnDifferents->setShortcut(Qt::CTRL + Qt::Key_D); btnDifferents->setWhatsThis(i18n("Show excluded files (Ctrl+D).")); btnDifferents->setFixedSize(showDifferents.width() + 15, showDifferents.height() + 15); showOptionsLayout->addWidget(btnDifferents, 0, 2); btnRightToLeft = new QPushButton(showOptions); btnRightToLeft->setText(""); btnRightToLeft->setIcon(QIcon(showRightToLeft)); btnRightToLeft->setCheckable(true); btnRightToLeft->setChecked(group.readEntry("RightToLeft Button", _BtnRightToLeft)); btnRightToLeft->setShortcut(Qt::CTRL + Qt::Key_R); btnRightToLeft->setWhatsThis(i18n("Show files marked to Copy from right to left (Ctrl+R).")); btnRightToLeft->setFixedSize(showRightToLeft.width() + 15, showRightToLeft.height() + 15); showOptionsLayout->addWidget(btnRightToLeft, 0, 3); btnDeletable = new QPushButton(showOptions); btnDeletable->setText(""); btnDeletable->setIcon(QIcon(showDeletable)); btnDeletable->setCheckable(true); btnDeletable->setChecked(group.readEntry("Deletable Button", _BtnDeletable)); btnDeletable->setShortcut(Qt::CTRL + Qt::Key_T); btnDeletable->setWhatsThis(i18n("Show files marked to delete (Ctrl+T).")); btnDeletable->setFixedSize(showDeletable.width() + 15, showDeletable.height() + 15); showOptionsLayout->addWidget(btnDeletable, 0, 4); btnDuplicates = new QPushButton(showOptions); btnDuplicates->setText(i18n("Duplicates")); btnDuplicates->setFixedWidth(QFontMetrics(btnDuplicates->font()).width(btnDuplicates->text()) + 15); btnDuplicates->setMinimumHeight(btnLeftToRight->height()); btnDuplicates->setCheckable(true); btnDuplicates->setChecked(group.readEntry("Duplicates Button", _BtnDuplicates)); btnDuplicates->setWhatsThis(i18n("Show files that exist on both sides.")); showOptionsLayout->addWidget(btnDuplicates, 0, 5); btnSingles = new QPushButton(showOptions); btnSingles->setText(i18n("Singles")); btnSingles->setFixedWidth(QFontMetrics(btnSingles->font()).width(btnSingles->text()) + 15); btnSingles->setMinimumHeight(btnLeftToRight->height()); btnSingles->setCheckable(true); btnSingles->setChecked(group.readEntry("Singles Button", _BtnSingles)); btnSingles->setWhatsThis(i18n("Show files that exist on one side only.")); showOptionsLayout->addWidget(btnSingles, 0, 6); grid->addWidget(optionWidget, 2, 0, 1, 3); synchronizerGrid->addWidget(compareDirs, 0, 0); /* ========================= Synchronization list view ========================== */ syncList = new SynchronizerListView(&synchronizer, synchronizerTab); // create the main container syncList->setWhatsThis(i18n("The compare results of the synchronizer (Ctrl+M).")); syncList->setAutoFillBackground(true); syncList->installEventFilter(this); KConfigGroup gl(krConfig, "Look&Feel"); syncList->setFont(gl.readEntry("Filelist Font", _FilelistFont)); syncList->setBackgroundRole(QPalette::Window); syncList->setAutoFillBackground(true); QStringList labels; labels << i18nc("@title:column file name", "Name"); labels << i18nc("@title:column", "Size"); labels << i18nc("@title:column", "Date"); labels << i18n("<=>"); labels << i18nc("@title:column", "Date"); labels << i18nc("@title:column", "Size"); labels << i18nc("@title:column file name", "Name"); syncList->setHeaderLabels(labels); syncList->header()->setSectionResizeMode(QHeaderView::Interactive); if (group.hasKey("State")) syncList->header()->restoreState(group.readEntry("State", QByteArray())); else { int i = QFontMetrics(syncList->font()).width("W"); int j = QFontMetrics(syncList->font()).width("0"); j = (i > j ? i : j); int typeWidth = j * 7 / 2; syncList->setColumnWidth(0, typeWidth * 4); syncList->setColumnWidth(1, typeWidth * 2); syncList->setColumnWidth(2, typeWidth * 3); syncList->setColumnWidth(3, typeWidth * 1); syncList->setColumnWidth(4, typeWidth * 3); syncList->setColumnWidth(5, typeWidth * 2); syncList->setColumnWidth(6, typeWidth * 4); equalSizes = true; } syncList->setAllColumnsShowFocus(true); syncList->setSelectionMode(QAbstractItemView::ExtendedSelection); syncList->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); syncList->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); syncList->header()->setSortIndicatorShown(false); syncList->setSortingEnabled(false); syncList->setRootIsDecorated(true); syncList->setIndentation(10); syncList->setDragEnabled(true); syncList->setAutoFillBackground(true); synchronizerGrid->addWidget(syncList, 1, 0); synchronizerTabs->addTab(synchronizerTab, i18n("&Synchronizer")); synchGrid->addWidget(synchronizerTabs, 0, 0); filterTabs = FilterTabs::addTo(synchronizerTabs, FilterTabs::HasDontSearchIn); generalFilter = (GeneralFilter *)filterTabs->get("GeneralFilter"); generalFilter->searchFor->setEditText(fileFilter->currentText()); generalFilter->searchForCase->setChecked(true); // creating the time shift, equality threshold, hidden files options QGroupBox *optionsGroup = new QGroupBox(generalFilter); optionsGroup->setTitle(i18n("&Options")); QGridLayout *optionsLayout = new QGridLayout(optionsGroup); optionsLayout->setAlignment(Qt::AlignTop); optionsLayout->setSpacing(6); optionsLayout->setContentsMargins(11, 11, 11, 11); QLabel * parallelThreadsLabel = new QLabel(i18n("Parallel threads:"), optionsGroup); optionsLayout->addWidget(parallelThreadsLabel, 0, 0); parallelThreadsSpinBox = new QSpinBox(optionsGroup); parallelThreadsSpinBox->setMinimum(1); parallelThreadsSpinBox->setMaximum(15); int parThreads = group.readEntry("Parallel Threads", 1); parallelThreadsSpinBox->setValue(parThreads); optionsLayout->addWidget(parallelThreadsSpinBox, 0, 1); QLabel * equalityLabel = new QLabel(i18n("Equality threshold:"), optionsGroup); optionsLayout->addWidget(equalityLabel, 1, 0); equalitySpinBox = new QSpinBox(optionsGroup); equalitySpinBox->setMaximum(9999); optionsLayout->addWidget(equalitySpinBox, 1, 1); equalityUnitCombo = new QComboBox(optionsGroup); equalityUnitCombo->addItem(i18n("sec")); equalityUnitCombo->addItem(i18n("min")); equalityUnitCombo->addItem(i18n("hour")); equalityUnitCombo->addItem(i18n("day")); optionsLayout->addWidget(equalityUnitCombo, 1, 2); QLabel * timeShiftLabel = new QLabel(i18n("Time shift (right-left):"), optionsGroup); optionsLayout->addWidget(timeShiftLabel, 2, 0); timeShiftSpinBox = new QSpinBox(optionsGroup); timeShiftSpinBox->setMinimum(-9999); timeShiftSpinBox->setMaximum(9999); optionsLayout->addWidget(timeShiftSpinBox, 2, 1); timeShiftUnitCombo = new QComboBox(optionsGroup); timeShiftUnitCombo->addItem(i18n("sec")); timeShiftUnitCombo->addItem(i18n("min")); timeShiftUnitCombo->addItem(i18n("hour")); timeShiftUnitCombo->addItem(i18n("day")); optionsLayout->addWidget(timeShiftUnitCombo, 2, 2); QFrame *line = new QFrame(optionsGroup); line->setFrameStyle(QFrame::HLine | QFrame::Sunken); optionsLayout->addWidget(line, 3, 0, 1, 3); ignoreHiddenFilesCB = new QCheckBox(i18n("Ignore hidden files"), optionsGroup); optionsLayout->addWidget(ignoreHiddenFilesCB, 4, 0, 1, 3); generalFilter->middleLayout->addWidget(optionsGroup); /* ================================== Buttons =================================== */ QHBoxLayout *buttons = new QHBoxLayout; buttons->setSpacing(6); buttons->setContentsMargins(0, 0, 0, 0); profileManager = new ProfileManager("SynchronizerProfile", this); profileManager->setShortcut(Qt::CTRL + Qt::Key_P); profileManager->setWhatsThis(i18n("Profile manager (Ctrl+P).")); buttons->addWidget(profileManager); QPixmap swapSides((const char**) swap_sides_data); btnSwapSides = new QPushButton(this); btnSwapSides->setIcon(QIcon(swapSides)); btnSwapSides->setShortcut(Qt::CTRL + Qt::Key_S); btnSwapSides->setWhatsThis(i18n("Swap sides (Ctrl+S).")); btnSwapSides->setFixedWidth(swapSides.width() + 15); buttons->addWidget(btnSwapSides); statusLabel = new QLabel(this); buttons->addWidget(statusLabel); QSpacerItem* spacer = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); buttons->addItem(spacer); btnCompareDirs = new QPushButton(this); btnCompareDirs->setText(i18n("Compare")); btnCompareDirs->setDefault(true); buttons->addWidget(btnCompareDirs); btnScrollResults = new QPushButton(this); btnScrollResults->setCheckable(true); btnScrollResults->setChecked(group.readEntry("Scroll Results", _ScrollResults)); btnScrollResults->hide(); if (btnScrollResults->isChecked()) btnScrollResults->setText(i18n("Quiet")); else btnScrollResults->setText(i18n("Scroll Results")); buttons->addWidget(btnScrollResults); btnStopComparing = new QPushButton(this); btnStopComparing->setText(i18n("Stop")); btnStopComparing->setIcon(QIcon::fromTheme("process-stop")); btnStopComparing->setEnabled(false); buttons->addWidget(btnStopComparing); btnFeedToListBox = new QPushButton(this); btnFeedToListBox->setText(i18n("Feed to listbox")); btnFeedToListBox->setIcon(QIcon::fromTheme("list-add")); btnFeedToListBox->setEnabled(false); btnFeedToListBox->hide(); buttons->addWidget(btnFeedToListBox); btnSynchronize = new QPushButton(this); btnSynchronize->setText(i18n("Synchronize")); btnSynchronize->setIcon(QIcon::fromTheme("folder-sync")); btnSynchronize->setEnabled(false); buttons->addWidget(btnSynchronize); QPushButton *btnCloseSync = new QPushButton(this); btnCloseSync->setText(i18n("Close")); btnCloseSync->setIcon(QIcon::fromTheme("dialog-close")); buttons->addWidget(btnCloseSync); synchGrid->addLayout(buttons, 1, 0); /* =============================== Connect table ================================ */ connect(syncList, SIGNAL(itemRightClicked(QTreeWidgetItem *, const QPoint &, int)), this, SLOT(rightMouseClicked(QTreeWidgetItem *, const QPoint &))); connect(syncList, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, SLOT(doubleClicked(QTreeWidgetItem *))); connect(profileManager, SIGNAL(loadFromProfile(QString)), this, SLOT(loadFromProfile(QString))); connect(profileManager, SIGNAL(saveToProfile(QString)), this, SLOT(saveToProfile(QString))); connect(btnSwapSides, SIGNAL(clicked()), this, SLOT(swapSides())); connect(btnCompareDirs, SIGNAL(clicked()), this, SLOT(compare())); connect(btnStopComparing, SIGNAL(clicked()), this, SLOT(stop())); connect(btnFeedToListBox, SIGNAL(clicked()), this, SLOT(feedToListBox())); connect(btnSynchronize, SIGNAL(clicked()), this, SLOT(synchronize())); connect(btnScrollResults, SIGNAL(toggled(bool)), this, SLOT(setScrolling(bool))); connect(btnCloseSync, SIGNAL(clicked()), this, SLOT(closeDialog())); connect(cbSubdirs, SIGNAL(toggled(bool)), this, SLOT(subdirsChecked(bool))); connect(cbAsymmetric, SIGNAL(toggled(bool)), this, SLOT(setPanelLabels())); connect(&synchronizer, SIGNAL(comparedFileData(SynchronizerFileItem *)), this, SLOT(addFile(SynchronizerFileItem *))); connect(&synchronizer, SIGNAL(markChanged(SynchronizerFileItem *, bool)), this, SLOT(markChanged(SynchronizerFileItem *, bool))); connect(&synchronizer, SIGNAL(statusInfo(QString)), this, SLOT(statusInfo(QString))); connect(btnLeftToRight, SIGNAL(toggled(bool)), this, SLOT(refresh())); connect(btnEquals, SIGNAL(toggled(bool)), this, SLOT(refresh())); connect(btnDifferents, SIGNAL(toggled(bool)), this, SLOT(refresh())); connect(btnRightToLeft, SIGNAL(toggled(bool)), this, SLOT(refresh())); connect(btnDeletable, SIGNAL(toggled(bool)), this, SLOT(refresh())); connect(btnDuplicates, SIGNAL(toggled(bool)), this, SLOT(refresh())); connect(btnSingles, SIGNAL(toggled(bool)), this, SLOT(refresh())); connect(fileFilter, SIGNAL(currentTextChanged(QString)), this, SLOT(connectFilters(QString))); connect(generalFilter->searchFor, SIGNAL(currentTextChanged(QString)), this, SLOT(connectFilters(QString))); connect(generalFilter->searchFor, SIGNAL(currentTextChanged(QString)), this, SLOT(setCompletion())); connect(generalFilter->dontSearchIn, SIGNAL(checkValidity(QString &, QString &)), this, SLOT(checkExcludeURLValidity(QString &, QString &))); connect(profileManager, SIGNAL(loadFromProfile(QString)), filterTabs, SLOT(loadFromProfile(QString))); connect(profileManager, SIGNAL(saveToProfile(QString)), filterTabs, SLOT(saveToProfile(QString))); setPanelLabels(); setCompletion(); /* =============================== Loading the colors ================================ */ KConfigGroup gc(krConfig, "Colors"); QString COLOR_NAMES[] = { "Equals", "Differs", "LeftCopy", "RightCopy", "Delete" }; QPalette defaultPalette = QGuiApplication::palette(); DECLARE_SYNCHRONIZER_BACKGROUND_DEFAULTS; DECLARE_SYNCHRONIZER_FOREGROUND_DEFAULTS; for (int clr = 0; clr != TT_MAX; clr ++) { QString colorName = clr > 4 ? "Equals" : COLOR_NAMES[ clr ]; QColor backgroundDefault = clr > 4 ? defaultPalette.color(QPalette::Active, QPalette::Base) : SYNCHRONIZER_BACKGROUND_DEFAULTS[ clr ]; QColor foregroundDefault = clr > 4 ? defaultPalette.color(QPalette::Active, QPalette::Text) : SYNCHRONIZER_FOREGROUND_DEFAULTS[ clr ]; QString foreEntry = QString("Synchronizer ") + colorName + QString(" Foreground"); QString bckgEntry = QString("Synchronizer ") + colorName + QString(" Background"); if (gc.readEntry(foreEntry, QString()) == "KDE default") foreGrounds[ clr ] = QColor(); else if (gc.readEntry(foreEntry, QString()).isEmpty()) // KDE4 workaround, default color doesn't work foreGrounds[ clr ] = foregroundDefault; else foreGrounds[ clr ] = gc.readEntry(foreEntry, foregroundDefault); if (gc.readEntry(bckgEntry, QString()) == "KDE default") backGrounds[ clr ] = QColor(); else if (gc.readEntry(foreEntry, QString()).isEmpty()) // KDE4 workaround, default color doesn't work backGrounds[ clr ] = backgroundDefault; else backGrounds[ clr ] = gc.readEntry(bckgEntry, backgroundDefault); } if (backGrounds[ TT_EQUALS ].isValid()) { QPalette pal = syncList->palette(); pal.setColor(QPalette::Base, backGrounds[ TT_EQUALS ]); syncList->setPalette(pal); } int sx = group.readEntry("Window Width", -1); int sy = group.readEntry("Window Height", -1); if (sx != -1 && sy != -1) resize(sx, sy); if (group.readEntry("Window Maximized", false)) showMaximized(); else show(); if (equalSizes) { int newSize6 = syncList->header()->sectionSize(6); int newSize0 = syncList->header()->sectionSize(0); int delta = newSize6 - newSize0 + (newSize6 & 1); newSize0 += (delta / 2); if (newSize0 > 20) syncList->header()->resizeSection(0, newSize0); } if (!profileName.isNull()) profileManager->loadProfile(profileName); synchronizer.setParentWidget(this); } SynchronizerGUI::~SynchronizerGUI() { syncList->clear(); // for sanity: deletes the references to the synchronizer list } void SynchronizerGUI::setPanelLabels() { if (hasSelectedFiles && cbAsymmetric->isChecked()) { leftDirLabel->setText(i18n("Selected files from targ&et folder:")); rightDirLabel->setText(i18n("Selected files from sou&rce folder:")); } else if (hasSelectedFiles && !cbAsymmetric->isChecked()) { leftDirLabel->setText(i18n("Selected files from &left folder:")); rightDirLabel->setText(i18n("Selected files from &right folder:")); } else if (cbAsymmetric->isChecked()) { leftDirLabel->setText(i18n("Targ&et folder:")); rightDirLabel->setText(i18n("Sou&rce folder:")); } else { leftDirLabel->setText(i18n("&Left folder:")); rightDirLabel->setText(i18n("&Right folder:")); } } void SynchronizerGUI::setCompletion() { generalFilter->dontSearchIn->setCompletionDir(Synchronizer::fsUrl(rightLocation->currentText())); } void SynchronizerGUI::checkExcludeURLValidity(QString &text, QString &error) { QUrl url = Synchronizer::fsUrl(text); if (url.isRelative()) return; QString leftBase = leftLocation->currentText(); if (!leftBase.endsWith('/')) leftBase += '/'; QUrl leftBaseURL = Synchronizer::fsUrl(leftBase); if (leftBaseURL.isParentOf(url) && !url.isParentOf(leftBaseURL)) { text = QDir(leftBaseURL.path()).relativeFilePath(url.path()); return; } QString rightBase = rightLocation->currentText(); if (!rightBase.endsWith('/')) rightBase += '/'; QUrl rightBaseURL = Synchronizer::fsUrl(rightBase); if (rightBaseURL.isParentOf(url) && !url.isParentOf(rightBaseURL)) { text = QDir(rightBaseURL.path()).relativeFilePath(url.path()); return; } error = i18n("URL must be the descendant of either the left or the right base URL."); } void SynchronizerGUI::doubleClicked(QTreeWidgetItem *itemIn) { if (!itemIn) return; SyncViewItem *syncItem = (SyncViewItem *)itemIn; SynchronizerFileItem *item = syncItem->synchronizerItemRef(); if (item && item->existsInLeft() && item->existsInRight() && !item->isDir()) { QString leftDirName = item->leftDirectory().isEmpty() ? "" : item->leftDirectory() + '/'; QString rightDirName = item->rightDirectory().isEmpty() ? "" : item->rightDirectory() + '/'; QUrl leftURL = Synchronizer::fsUrl(synchronizer.leftBaseDirectory() + leftDirName + item->leftName()); QUrl rightURL = Synchronizer::fsUrl(synchronizer.rightBaseDirectory() + rightDirName + item->rightName()); SLOTS->compareContent(leftURL, rightURL); } else if (item && item->isDir()) { itemIn->setExpanded(!itemIn->isExpanded()); } } void SynchronizerGUI::rightMouseClicked(QTreeWidgetItem *itemIn, const QPoint &pos) { // these are the values that will exist in the menu #define EXCLUDE_ID 90 #define RESTORE_ID 91 #define COPY_TO_LEFT_ID 92 #define COPY_TO_RIGHT_ID 93 #define REVERSE_DIR_ID 94 #define DELETE_ID 95 #define VIEW_LEFT_FILE_ID 96 #define VIEW_RIGHT_FILE_ID 97 #define COMPARE_FILES_ID 98 #define SELECT_ITEMS_ID 99 #define DESELECT_ITEMS_ID 100 #define INVERT_SELECTION_ID 101 #define SYNCH_WITH_KGET_ID 102 #define COPY_CLPBD_LEFT_ID 103 #define COPY_CLPBD_RIGHT_ID 104 ////////////////////////////////////////////////////////// if (!itemIn) return; SyncViewItem *syncItem = (SyncViewItem *)itemIn; if (syncItem == 0) return; SynchronizerFileItem *item = syncItem->synchronizerItemRef(); bool isDuplicate = item->existsInLeft() && item->existsInRight(); bool isDir = item->isDir(); // create the menu QMenu popup; QAction *myact; QHash< QAction *, int > actHash; popup.setTitle(i18n("Synchronize Folders")); myact = popup.addAction(i18n("E&xclude")); actHash[ myact ] = EXCLUDE_ID; myact = popup.addAction(i18n("Restore ori&ginal operation")); actHash[ myact ] = RESTORE_ID; myact = popup.addAction(i18n("Re&verse direction")); actHash[ myact ] = REVERSE_DIR_ID; myact = popup.addAction(i18n("Copy from &right to left")); actHash[ myact ] = COPY_TO_LEFT_ID; myact = popup.addAction(i18n("Copy from &left to right")); actHash[ myact ] = COPY_TO_RIGHT_ID; myact = popup.addAction(i18n("&Delete (left single)")); actHash[ myact ] = DELETE_ID; popup.addSeparator(); myact = popup.addAction(i18n("V&iew left file")); myact->setEnabled(!isDir && item->existsInLeft()); actHash[ myact ] = VIEW_LEFT_FILE_ID; myact = popup.addAction(i18n("Vi&ew right file")); myact->setEnabled(!isDir && item->existsInRight()); actHash[ myact ] = VIEW_RIGHT_FILE_ID; myact = popup.addAction(i18n("&Compare Files")); myact->setEnabled(!isDir && isDuplicate); actHash[ myact ] = COMPARE_FILES_ID; popup.addSeparator(); myact = popup.addAction(i18n("C&opy selected to clipboard (left)")); actHash[ myact ] = COPY_CLPBD_LEFT_ID; myact = popup.addAction(i18n("Co&py selected to clipboard (right)")); actHash[ myact ] = COPY_CLPBD_RIGHT_ID; popup.addSeparator(); myact = popup.addAction(i18n("&Select items")); actHash[ myact ] = SELECT_ITEMS_ID; myact = popup.addAction(i18n("Deselec&t items")); actHash[ myact ] = DESELECT_ITEMS_ID; myact = popup.addAction(i18n("I&nvert selection")); actHash[ myact ] = INVERT_SELECTION_ID; QUrl leftBDir = Synchronizer::fsUrl(synchronizer.leftBaseDirectory()); QUrl rightBDir = Synchronizer::fsUrl(synchronizer.rightBaseDirectory()); if (KrServices::cmdExist("kget") && ((!leftBDir.isLocalFile() && rightBDir.isLocalFile() && btnLeftToRight->isChecked()) || (leftBDir.isLocalFile() && !rightBDir.isLocalFile() && btnRightToLeft->isChecked()))) { popup.addSeparator(); myact = popup.addAction(i18n("Synchronize with &KGet")); actHash[ myact ] = SYNCH_WITH_KGET_ID; } QAction * res = popup.exec(pos); int result = -1; if (actHash.contains(res)) result = actHash[ res ]; if (result != -1) executeOperation(item, result); } void SynchronizerGUI::executeOperation(SynchronizerFileItem *item, int op) { // check out the user's option QString leftDirName = item->leftDirectory().isEmpty() ? "" : item->leftDirectory() + '/'; QString rightDirName = item->rightDirectory().isEmpty() ? "" : item->rightDirectory() + '/'; QUrl leftURL = Synchronizer::fsUrl(synchronizer.leftBaseDirectory() + leftDirName + item->leftName()); QUrl rightURL = Synchronizer::fsUrl(synchronizer.rightBaseDirectory() + rightDirName + item->rightName()); switch (op) { case EXCLUDE_ID: case RESTORE_ID: case COPY_TO_LEFT_ID: case COPY_TO_RIGHT_ID: case REVERSE_DIR_ID: case DELETE_ID: { unsigned ndx = 0; SynchronizerFileItem *currentItem; while ((currentItem = synchronizer.getItemAt(ndx++)) != 0) { SyncViewItem *viewItem = (SyncViewItem *)currentItem->userData(); if (!viewItem || !viewItem->isSelected() || viewItem->isHidden()) continue; switch (op) { case EXCLUDE_ID: synchronizer.exclude(viewItem->synchronizerItemRef()); break; case RESTORE_ID: synchronizer.restore(viewItem->synchronizerItemRef()); break; case REVERSE_DIR_ID: synchronizer.reverseDirection(viewItem->synchronizerItemRef()); break; case COPY_TO_LEFT_ID: synchronizer.copyToLeft(viewItem->synchronizerItemRef()); break; case COPY_TO_RIGHT_ID: synchronizer.copyToRight(viewItem->synchronizerItemRef()); break; case DELETE_ID: synchronizer.deleteLeft(viewItem->synchronizerItemRef()); break; } } refresh(); } break; case VIEW_LEFT_FILE_ID: KrViewer::view(leftURL, this); // view the file break; case VIEW_RIGHT_FILE_ID: KrViewer::view(rightURL, this); // view the file break; case COMPARE_FILES_ID: SLOTS->compareContent(leftURL, rightURL); break; case SELECT_ITEMS_ID: case DESELECT_ITEMS_ID: { KRQuery query = KRSpWidgets::getMask((op == SELECT_ITEMS_ID ? i18n("Select items") : i18n("Deselect items")), true, this); if (query.isNull()) break; unsigned ndx = 0; SynchronizerFileItem *currentItem; while ((currentItem = synchronizer.getItemAt(ndx++)) != 0) { SyncViewItem *viewItem = (SyncViewItem *)currentItem->userData(); if (!viewItem || viewItem->isHidden()) continue; if (query.match(currentItem->leftName()) || query.match(currentItem->rightName())) viewItem->setSelected(op == SELECT_ITEMS_ID); } } break; case INVERT_SELECTION_ID: { unsigned ndx = 0; SynchronizerFileItem *currentItem; while ((currentItem = synchronizer.getItemAt(ndx++)) != 0) { SyncViewItem *viewItem = (SyncViewItem *)currentItem->userData(); if (!viewItem || viewItem->isHidden()) continue; viewItem->setSelected(!viewItem->isSelected()); } } break; case SYNCH_WITH_KGET_ID: synchronizer.synchronizeWithKGet(); closeDialog(); break; case COPY_CLPBD_LEFT_ID: copyToClipboard(true); break; case COPY_CLPBD_RIGHT_ID: copyToClipboard(false); break; case -1 : return; // the user clicked outside of the menu } } void SynchronizerGUI::closeDialog() { if (isComparing) { stop(); wasClosed = true; return; } KConfigGroup group(krConfig, "Synchronize"); QStringList list; foreach(QString item, leftLocation->historyItems()) { QUrl url(item); // make sure no passwords are saved in config url.setPassword(QString()); list << url.toDisplayString(QUrl::PreferLocalFile); } group.writeEntry("Left Folder History", list); list.clear(); foreach(QString item, rightLocation->historyItems()) { QUrl url(item); // make sure no passwords are saved in config url.setPassword(QString()); list << url.toDisplayString(QUrl::PreferLocalFile); } group.writeEntry("Right Folder History", list); list = fileFilter->historyItems(); group.writeEntry("File Filter", list); group.writeEntry("Recurse Subdirectories", cbSubdirs->isChecked()); group.writeEntry("Follow Symlinks", cbSymlinks->isChecked()); group.writeEntry("Compare By Content", cbByContent->isChecked()); group.writeEntry("Ignore Date", cbIgnoreDate->isChecked()); group.writeEntry("Asymmetric", cbAsymmetric->isChecked()); group.writeEntry("Ignore Case", cbIgnoreCase->isChecked()); group.writeEntry("LeftToRight Button", btnLeftToRight->isChecked()); group.writeEntry("Equals Button", btnEquals->isChecked()); group.writeEntry("Differents Button", btnDifferents->isChecked()); group.writeEntry("RightToLeft Button", btnRightToLeft->isChecked()); group.writeEntry("Deletable Button", btnDeletable->isChecked()); group.writeEntry("Duplicates Button", btnDuplicates->isChecked()); group.writeEntry("Singles Button", btnSingles->isChecked()); group.writeEntry("Scroll Results", btnScrollResults->isChecked()); group.writeEntry("Parallel Threads", parallelThreadsSpinBox->value()); group.writeEntry("Window Width", sizeX); group.writeEntry("Window Height", sizeY); group.writeEntry("Window Maximized", isMaximized()); group.writeEntry("State", syncList->header()->saveState()); QDialog::reject(); this->deleteLater(); if (wasSync) { LEFT_PANEL->func->refresh(); RIGHT_PANEL->func->refresh(); ACTIVE_PANEL->gui->slotFocusOnMe(); } } void SynchronizerGUI::compare() { KRQuery query; if (!filterTabs->fillQuery(&query)) return; // perform some previous tests QString leftLocationTrimmed = leftLocation->currentText().trimmed(); QString rightLocationTrimmed = rightLocation->currentText().trimmed(); if (leftLocationTrimmed.isEmpty()) { KMessageBox::error(this, i18n("The target folder must not be empty.")); leftLocation->setFocus(); return; } if (rightLocationTrimmed.isEmpty()) { KMessageBox::error(this, i18n("The source folder must not be empty.")); rightLocation->setFocus(); return; } if (leftLocationTrimmed == rightLocationTrimmed) { if (KMessageBox::warningContinueCancel(this, i18n("Warning: The left and the right side are showing the same folder.")) != KMessageBox::Continue) { return; } } query.setNameFilter(fileFilter->currentText(), query.isCaseSensitive()); synchronizerTabs->setCurrentIndex(0); syncList->clear(); lastItem = 0; leftLocation->addToHistory(leftLocation->currentText()); rightLocation->addToHistory(rightLocation->currentText()); fileFilter->addToHistory(fileFilter->currentText()); setMarkFlags(); btnCompareDirs->setEnabled(false); profileManager->setEnabled(false); btnSwapSides->setEnabled(false); btnStopComparing->setEnabled(isComparing = true); btnStopComparing->show(); btnFeedToListBox->setEnabled(false); btnFeedToListBox->hide(); btnSynchronize->setEnabled(false); btnCompareDirs->hide(); btnScrollResults->show(); disableMarkButtons(); int fileCount = synchronizer.compare(leftLocation->currentText(), rightLocation->currentText(), &query, cbSubdirs->isChecked(), cbSymlinks->isChecked(), cbIgnoreDate->isChecked(), cbAsymmetric->isChecked(), cbByContent->isChecked(), cbIgnoreCase->isChecked(), btnScrollResults->isChecked(), selectedFiles, convertToSeconds(equalitySpinBox->value(), equalityUnitCombo->currentIndex()), convertToSeconds(timeShiftSpinBox->value(), timeShiftUnitCombo->currentIndex()), parallelThreadsSpinBox->value(), ignoreHiddenFilesCB->isChecked()); enableMarkButtons(); btnStopComparing->setEnabled(isComparing = false); btnStopComparing->hide(); btnFeedToListBox->show(); btnCompareDirs->setEnabled(true); profileManager->setEnabled(true); btnSwapSides->setEnabled(true); btnCompareDirs->show(); btnScrollResults->hide(); if (fileCount) { btnSynchronize->setEnabled(true); btnFeedToListBox->setEnabled(true); } syncList->setFocus(); if (wasClosed) closeDialog(); } void SynchronizerGUI::stop() { synchronizer.stop(); } void SynchronizerGUI::feedToListBox() { FeedToListBoxDialog listBox(this, &synchronizer, syncList, btnEquals->isChecked()); if (listBox.isAccepted()) closeDialog(); } void SynchronizerGUI::reject() { closeDialog(); } void SynchronizerGUI::addFile(SynchronizerFileItem *item) { QString leftName = "", rightName = "", leftDate = "", rightDate = "", leftSize = "", rightSize = ""; bool isDir = item->isDir(); QColor textColor = foreGrounds[ item->task()]; QColor baseColor = backGrounds[ item->task()]; if (item->existsInLeft()) { leftName = item->leftName(); leftSize = isDir ? dirLabel() + ' ' : KRpermHandler::parseSize(item->leftSize()); leftDate = SynchronizerGUI::convertTime(item->leftDate()); } if (item->existsInRight()) { rightName = item->rightName(); rightSize = isDir ? dirLabel() + ' ' : KRpermHandler::parseSize(item->rightSize()); rightDate = SynchronizerGUI::convertTime(item->rightDate()); } SyncViewItem *listItem = 0; SyncViewItem *dirItem; if (item->parent() == 0) { listItem = new SyncViewItem(item, textColor, baseColor, syncList, lastItem, leftName, leftSize, leftDate, Synchronizer::getTaskTypeName(item->task()), rightDate, rightSize, rightName); lastItem = listItem; } else { dirItem = (SyncViewItem *)item->parent()->userData(); if (dirItem) { dirItem->setExpanded(true); listItem = new SyncViewItem(item, textColor, baseColor, dirItem, dirItem->lastItem(), leftName, leftSize, leftDate, Synchronizer::getTaskTypeName(item->task()), rightDate, rightSize, rightName); dirItem->setLastItem(listItem); } } if (listItem) { listItem->setIcon(0, isDir ? folderIcon : fileIcon); if (!item->isMarked()) listItem->setHidden(true); else syncList->scrollTo(syncList->indexOf(listItem)); } } void SynchronizerGUI::markChanged(SynchronizerFileItem *item, bool ensureVisible) { SyncViewItem *listItem = (SyncViewItem *)item->userData(); if (listItem) { if (!item->isMarked()) { listItem->setHidden(true); } else { QString leftName = "", rightName = "", leftDate = "", rightDate = "", leftSize = "", rightSize = ""; bool isDir = item->isDir(); if (item->existsInLeft()) { leftName = item->leftName(); leftSize = isDir ? dirLabel() + ' ' : KRpermHandler::parseSize(item->leftSize()); leftDate = SynchronizerGUI::convertTime(item->leftDate()); } if (item->existsInRight()) { rightName = item->rightName(); rightSize = isDir ? dirLabel() + ' ' : KRpermHandler::parseSize(item->rightSize()); rightDate = SynchronizerGUI::convertTime(item->rightDate()); } listItem->setHidden(false); listItem->setText(0, leftName); listItem->setText(1, leftSize); listItem->setText(2, leftDate); listItem->setText(3, Synchronizer::getTaskTypeName(item->task())); listItem->setText(4, rightDate); listItem->setText(5, rightSize); listItem->setText(6, rightName); listItem->setColors(foreGrounds[ item->task()], backGrounds[ item->task()]); if (ensureVisible) syncList->scrollTo(syncList->indexOf(listItem)); } } } void SynchronizerGUI::subdirsChecked(bool isOn) { cbSymlinks->setEnabled(isOn); } void SynchronizerGUI::disableMarkButtons() { btnLeftToRight->setEnabled(false); btnEquals->setEnabled(false); btnDifferents->setEnabled(false); btnRightToLeft->setEnabled(false); btnDeletable->setEnabled(false); btnDuplicates->setEnabled(false); btnSingles->setEnabled(false); } void SynchronizerGUI::enableMarkButtons() { btnLeftToRight->setEnabled(true); btnEquals->setEnabled(true); btnDifferents->setEnabled(true); btnRightToLeft->setEnabled(true); btnDeletable->setEnabled(true); btnDuplicates->setEnabled(true); btnSingles->setEnabled(true); } QString SynchronizerGUI::convertTime(time_t time) const { // convert the time_t to struct tm struct tm* t = localtime((time_t *) & time); QDateTime tmp(QDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday), QTime(t->tm_hour, t->tm_min)); return QLocale().toString(tmp, QLocale::ShortFormat); } void SynchronizerGUI::setMarkFlags() { synchronizer.setMarkFlags(btnRightToLeft->isChecked(), btnEquals->isChecked(), btnDifferents->isChecked(), btnLeftToRight->isChecked(), btnDuplicates->isChecked(), btnSingles->isChecked(), btnDeletable->isChecked()); } void SynchronizerGUI::refresh() { if (!isComparing) { syncList->clearSelection(); setMarkFlags(); btnCompareDirs->setEnabled(false); profileManager->setEnabled(false); btnSwapSides->setEnabled(false); btnSynchronize->setEnabled(false); btnFeedToListBox->setEnabled(false); disableMarkButtons(); int fileCount = synchronizer.refresh(); enableMarkButtons(); btnCompareDirs->setEnabled(true); profileManager->setEnabled(true); btnSwapSides->setEnabled(true); if (fileCount) { btnFeedToListBox->setEnabled(true); btnSynchronize->setEnabled(true); } } } void SynchronizerGUI::synchronize() { int copyToLeftNr, copyToRightNr, deleteNr; KIO::filesize_t copyToLeftSize, copyToRightSize, deleteSize; if (!synchronizer.totalSizes(©ToLeftNr, ©ToLeftSize, ©ToRightNr, ©ToRightSize, &deleteNr, &deleteSize)) { KMessageBox::sorry(parentWidget(), i18n("Synchronizer has nothing to do.")); return; } SynchronizeDialog *sd = new SynchronizeDialog(this, &synchronizer, copyToLeftNr, copyToLeftSize, copyToRightNr, copyToRightSize, deleteNr, deleteSize, parallelThreadsSpinBox->value()); wasSync = sd->wasSyncronizationStarted(); delete sd; if (wasSync) closeDialog(); } void SynchronizerGUI::resizeEvent(QResizeEvent *e) { if (!isMaximized()) { sizeX = e->size().width(); sizeY = e->size().height(); } if (!firstResize) { int delta = e->size().width() - e->oldSize().width() + (e->size().width() & 1); int newSize = syncList->header()->sectionSize(0) + delta / 2; if (newSize > 20) syncList->header()->resizeSection(0, newSize); } firstResize = false; QDialog::resizeEvent(e); } void SynchronizerGUI::statusInfo(QString info) { statusLabel->setText(info); qApp->processEvents(); } void SynchronizerGUI::swapSides() { if (btnCompareDirs->isEnabled()) { QString leftCurrent = leftLocation->currentText(); leftLocation->lineEdit()->setText(rightLocation->currentText()); rightLocation->lineEdit()->setText(leftCurrent); synchronizer.swapSides(); refresh(); } } void SynchronizerGUI::keyPressEvent(QKeyEvent *e) { switch (e->key()) { case Qt::Key_M : { if (e->modifiers() == Qt::ControlModifier) { syncList->setFocus(); e->accept(); } break; } case Qt::Key_F3 : case Qt::Key_F4 : { e->accept(); syncList->setFocus(); QTreeWidgetItem *listItem = syncList->currentItem(); if (listItem == 0) break; bool isedit = e->key() == Qt::Key_F4; SynchronizerFileItem *item = ((SyncViewItem *)listItem)->synchronizerItemRef(); QString leftDirName = item->leftDirectory().isEmpty() ? "" : item->leftDirectory() + '/'; QString rightDirName = item->rightDirectory().isEmpty() ? "" : item->rightDirectory() + '/'; if (item->isDir()) return; if (e->modifiers() == Qt::ShiftModifier && item->existsInRight()) { QUrl rightURL = Synchronizer::fsUrl(synchronizer.rightBaseDirectory() + rightDirName + item->rightName()); if (isedit) KrViewer::edit(rightURL, this); // view the file else KrViewer::view(rightURL, this); // view the file return; } else if (e->modifiers() == 0 && item->existsInLeft()) { QUrl leftURL = Synchronizer::fsUrl(synchronizer.leftBaseDirectory() + leftDirName + item->leftName()); if (isedit) KrViewer::edit(leftURL, this); // view the file else KrViewer::view(leftURL, this); // view the file return; } } break; case Qt::Key_U : if (e->modifiers() != Qt::ControlModifier) break; e->accept(); swapSides(); return; case Qt::Key_Escape: if (!btnStopComparing->isHidden() && btnStopComparing->isEnabled()) { // is it comparing? e->accept(); btnStopComparing->animateClick(); // just click the stop button } else { e->accept(); if (syncList->topLevelItemCount() != 0) { int result = KMessageBox::warningYesNo(this, i18n("The synchronizer window contains data from a previous compare. If you exit, this data will be lost. Do you really want to exit?"), i18n("Krusader::Synchronize Folders"), KStandardGuiItem::yes(), KStandardGuiItem::no(), "syncGUIexit"); if (result != KMessageBox::Yes) return; } QDialog::reject(); } return; } QDialog::keyPressEvent(e); } bool SynchronizerGUI::eventFilter(QObject * /* watched */, QEvent * e) { if (e->type() == QEvent::KeyPress) { QKeyEvent* ke = (QKeyEvent*) e; switch (ke->key()) { case Qt::Key_Down: case Qt::Key_Left: case Qt::Key_Right: case Qt::Key_Up: case Qt::Key_Delete: case Qt::Key_W: { if (ke->key() == Qt::Key_W) { if (ke->modifiers() != Qt::ControlModifier) return false; } else if (ke->modifiers() != Qt::AltModifier) return false; int op = -1; switch (ke->key()) { case Qt::Key_Down: op = EXCLUDE_ID; break; case Qt::Key_Left: op = COPY_TO_LEFT_ID; break; case Qt::Key_Right: op = COPY_TO_RIGHT_ID; break; case Qt::Key_Up: op = RESTORE_ID; break; case Qt::Key_Delete: op = DELETE_ID; break; case Qt::Key_W: op = REVERSE_DIR_ID; break; } ke->accept(); QTreeWidgetItem *listItem = syncList->currentItem(); if (listItem == 0) return true; SynchronizerFileItem *item = ((SyncViewItem *)listItem)->synchronizerItemRef(); bool hasSelected = false; QList selected = syncList->selectedItems(); for (int i = 0; i != selected.count(); i++) if (selected[ i ]->isSelected() && !selected[ i ]->isHidden()) hasSelected = true; if (!hasSelected) listItem->setSelected(true); executeOperation(item, op); return true; } } } return false; } void SynchronizerGUI::loadFromProfile(QString profile) { syncList->clear(); synchronizer.reset(); isComparing = wasClosed = false; btnSynchronize->setEnabled(false); btnFeedToListBox->setEnabled(false); KConfigGroup pg(krConfig, profile); if (!hasSelectedFiles) { leftLocation->lineEdit()->setText(pg.readEntry("Left Location", QString())); rightLocation->lineEdit()->setText(pg.readEntry("Right Location", QString())); } fileFilter->lineEdit()->setText(pg.readEntry("Search For", QString())); cbSubdirs-> setChecked(pg.readEntry("Recurse Subdirectories", true)); cbSymlinks-> setChecked(pg.readEntry("Follow Symlinks", false)); cbByContent-> setChecked(pg.readEntry("Compare By Content", false)); cbIgnoreDate->setChecked(pg.readEntry("Ignore Date", false)); cbAsymmetric->setChecked(pg.readEntry("Asymmetric", false)); cbIgnoreCase->setChecked(pg.readEntry("Ignore Case", false)); btnScrollResults->setChecked(pg.readEntry("Scroll Results", false)); btnLeftToRight->setChecked(pg.readEntry("Show Left To Right", true)); btnEquals ->setChecked(pg.readEntry("Show Equals", true)); btnDifferents ->setChecked(pg.readEntry("Show Differents", true)); btnRightToLeft->setChecked(pg.readEntry("Show Right To Left", true)); btnDeletable ->setChecked(pg.readEntry("Show Deletable", true)); btnDuplicates ->setChecked(pg.readEntry("Show Duplicates", true)); btnSingles ->setChecked(pg.readEntry("Show Singles", true)); int equalityThreshold = pg.readEntry("Equality Threshold", 0); int equalityCombo = 0; convertFromSeconds(equalityThreshold, equalityCombo, equalityThreshold); equalitySpinBox->setValue(equalityThreshold); equalityUnitCombo->setCurrentIndex(equalityCombo); int timeShift = pg.readEntry("Time Shift", 0); int timeShiftCombo = 0; convertFromSeconds(timeShift, timeShiftCombo, timeShift); timeShiftSpinBox->setValue(timeShift); timeShiftUnitCombo->setCurrentIndex(timeShiftCombo); int parallelThreads = pg.readEntry("Parallel Threads", 1); parallelThreadsSpinBox->setValue(parallelThreads); bool ignoreHidden = pg.readEntry("Ignore Hidden Files", false); ignoreHiddenFilesCB->setChecked(ignoreHidden); refresh(); } void SynchronizerGUI::saveToProfile(QString profile) { KConfigGroup group(krConfig, profile); group.writeEntry("Left Location", leftLocation->currentText()); group.writeEntry("Search For", fileFilter->currentText()); group.writeEntry("Right Location", rightLocation->currentText()); group.writeEntry("Recurse Subdirectories", cbSubdirs->isChecked()); group.writeEntry("Follow Symlinks", cbSymlinks->isChecked()); group.writeEntry("Compare By Content", cbByContent->isChecked()); group.writeEntry("Ignore Date", cbIgnoreDate->isChecked()); group.writeEntry("Asymmetric", cbAsymmetric->isChecked()); group.writeEntry("Ignore Case", cbIgnoreCase->isChecked()); group.writeEntry("Scroll Results", btnScrollResults->isChecked()); group.writeEntry("Show Left To Right", btnLeftToRight->isChecked()); group.writeEntry("Show Equals", btnEquals->isChecked()); group.writeEntry("Show Differents", btnDifferents->isChecked()); group.writeEntry("Show Right To Left", btnRightToLeft->isChecked()); group.writeEntry("Show Deletable", btnDeletable->isChecked()); group.writeEntry("Show Duplicates", btnDuplicates->isChecked()); group.writeEntry("Show Singles", btnSingles->isChecked()); group.writeEntry("Equality Threshold", convertToSeconds(equalitySpinBox->value(), equalityUnitCombo->currentIndex())); group.writeEntry("Time Shift", convertToSeconds(timeShiftSpinBox->value(), timeShiftUnitCombo->currentIndex())); group.writeEntry("Parallel Threads", parallelThreadsSpinBox->value()); group.writeEntry("Ignore Hidden Files", ignoreHiddenFilesCB->isChecked()); } void SynchronizerGUI::connectFilters(const QString &newString) { if (synchronizerTabs->currentIndex()) fileFilter->setEditText(newString); else generalFilter->searchFor->setEditText(newString); } void SynchronizerGUI::setScrolling(bool isOn) { if (isOn) btnScrollResults->setText(i18n("Quiet")); else btnScrollResults->setText(i18n("Scroll Results")); synchronizer.setScrolling(isOn); } int SynchronizerGUI::convertToSeconds(int time, int unit) { switch (unit) { case 1: return time * 60; case 2: return time * 3600; case 3: return time * 86400; default: return time; } } void SynchronizerGUI::convertFromSeconds(int &time, int &unit, int second) { unit = 0; time = second; int absTime = (time < 0) ? -time : time; if (absTime >= 86400 && (absTime % 86400) == 0) { time /= 86400; unit = 3; } else if (absTime >= 3600 && (absTime % 3600) == 0) { time /= 3600; unit = 2; } else if (absTime >= 60 && (absTime % 60) == 0) { time /= 60; unit = 1; } } void SynchronizerGUI::copyToClipboard(bool isLeft) { QList urls; unsigned ndx = 0; SynchronizerFileItem *currentItem; while ((currentItem = synchronizer.getItemAt(ndx++)) != 0) { SynchronizerGUI::SyncViewItem *viewItem = (SynchronizerGUI::SyncViewItem *)currentItem->userData(); if (!viewItem || !viewItem->isSelected() || viewItem->isHidden()) continue; SynchronizerFileItem *item = viewItem->synchronizerItemRef(); if (item) { if (isLeft && item->existsInLeft()) { QString leftDirName = item->leftDirectory().isEmpty() ? "" : item->leftDirectory() + '/'; QUrl leftURL = Synchronizer::fsUrl(synchronizer.leftBaseDirectory() + leftDirName + item->leftName()); urls.push_back(leftURL); } else if (!isLeft && item->existsInRight()) { QString rightDirName = item->rightDirectory().isEmpty() ? "" : item->rightDirectory() + '/'; QUrl rightURL = Synchronizer::fsUrl(synchronizer.rightBaseDirectory() + rightDirName + item->rightName()); urls.push_back(rightURL); } } } if (urls.count() == 0) return; QMimeData *mimeData = new QMimeData; mimeData->setImageData(FL_LOADICON(isLeft ? "arrow-left-double" : "arrow-right-double")); mimeData->setUrls(urls); QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); } QString SynchronizerGUI::dirLabel() { //HACK add <> brackets AFTER translating - otherwise KUIT thinks it's a tag static QString label = QString("<") + i18nc("Show the string 'DIR' instead of file size in detailed view (for folders)", "DIR") + ">"; return label; } diff --git a/krusader/Synchronizer/synchronizertask.cpp b/krusader/Synchronizer/synchronizertask.cpp index f067ed92..9c14a480 100644 --- a/krusader/Synchronizer/synchronizertask.cpp +++ b/krusader/Synchronizer/synchronizertask.cpp @@ -1,355 +1,355 @@ /*************************************************************************** synchronizertask.cpp - description ------------------- copyright : (C) 2006 + by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "synchronizertask.h" // QtCore #include #include #include #include #include "synchronizer.h" #include "synchronizerfileitem.h" #include "synchronizerdirlist.h" -#include "../VFS/vfs.h" +#include "../FileSystem/filesystem.h" CompareTask::CompareTask(SynchronizerFileItem *parentIn, const QString &leftURL, const QString &rightURL, const QString &leftDir, const QString &rightDir, bool hidden) : SynchronizerTask(), m_parent(parentIn), m_url(leftURL), m_dir(leftDir), m_otherUrl(rightURL), m_otherDir(rightDir), m_duplicate(true), m_dirList(0), m_otherDirList(0) { ignoreHidden = hidden; } CompareTask::CompareTask(SynchronizerFileItem *parentIn, const QString &urlIn, const QString &dirIn, bool isLeftIn, bool hidden) : SynchronizerTask(), m_parent(parentIn), m_url(urlIn), m_dir(dirIn), m_isLeft(isLeftIn), m_duplicate(false), m_dirList(0), m_otherDirList(0) { ignoreHidden = hidden; } CompareTask::~CompareTask() { if (m_dirList) { delete m_dirList; m_dirList = 0; } if (m_otherDirList) { delete m_otherDirList; m_otherDirList = 0; } } void CompareTask::start() { if (m_state == ST_STATE_NEW) { m_state = ST_STATE_PENDING; m_loadFinished = m_otherLoadFinished = false; m_dirList = new SynchronizerDirList(parentWidget, ignoreHidden); connect(m_dirList, SIGNAL(finished(bool)), this, SLOT(slotFinished(bool))); m_dirList->load(m_url, false); if (m_duplicate) { m_otherDirList = new SynchronizerDirList(parentWidget, ignoreHidden); connect(m_otherDirList, SIGNAL(finished(bool)), this, SLOT(slotOtherFinished(bool))); m_otherDirList->load(m_otherUrl, false); } } } void CompareTask::slotFinished(bool result) { if (!result) { m_state = ST_STATE_ERROR; return; } m_loadFinished = true; if (m_otherLoadFinished || !m_duplicate) m_state = ST_STATE_READY; } void CompareTask::slotOtherFinished(bool result) { if (!result) { m_state = ST_STATE_ERROR; return; } m_otherLoadFinished = true; if (m_loadFinished) m_state = ST_STATE_READY; } CompareContentTask::CompareContentTask(Synchronizer *syn, SynchronizerFileItem *itemIn, const QUrl &leftURLIn, const QUrl &rightURLIn, KIO::filesize_t sizeIn) : SynchronizerTask(), leftURL(leftURLIn), rightURL(rightURLIn), size(sizeIn), errorPrinted(false), leftReadJob(0), rightReadJob(0), compareArray(), owner(-1), item(itemIn), timer(0), leftFile(0), rightFile(0), received(0), sync(syn) { } CompareContentTask::~CompareContentTask() { abortContentComparing(); if (timer) delete timer; if (leftFile) delete leftFile; if (rightFile) delete rightFile; } void CompareContentTask::start() { m_state = ST_STATE_PENDING; if (leftURL.isLocalFile() && rightURL.isLocalFile()) { leftFile = new QFile(leftURL.path()); if (!leftFile->open(QIODevice::ReadOnly)) { KMessageBox::error(parentWidget, i18n("Error at opening %1.", leftURL.path())); m_state = ST_STATE_ERROR; return; } rightFile = new QFile(rightURL.path()); if (!rightFile->open(QIODevice::ReadOnly)) { KMessageBox::error(parentWidget, i18n("Error at opening %1.", rightURL.path())); m_state = ST_STATE_ERROR; return; } timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(sendStatusMessage())); timer->setSingleShot(true); timer->start(1000); localFileCompareCycle(); } else { leftReadJob = KIO::get(leftURL, KIO::NoReload, KIO::HideProgressInfo); rightReadJob = KIO::get(rightURL, KIO::NoReload, KIO::HideProgressInfo); connect(leftReadJob, SIGNAL(data(KIO::Job *, const QByteArray &)), this, SLOT(slotDataReceived(KIO::Job *, const QByteArray &))); connect(rightReadJob, SIGNAL(data(KIO::Job *, const QByteArray &)), this, SLOT(slotDataReceived(KIO::Job *, const QByteArray &))); connect(leftReadJob, SIGNAL(result(KJob*)), this, SLOT(slotFinished(KJob *))); connect(rightReadJob, SIGNAL(result(KJob*)), this, SLOT(slotFinished(KJob *))); rightReadJob->suspend(); timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(sendStatusMessage())); timer->setSingleShot(true); timer->start(1000); } } void CompareContentTask::localFileCompareCycle() { bool different = false; char leftBuffer[ 1440 ]; char rightBuffer[ 1440 ]; QTime timer; timer.start(); int cnt = 0; while (!leftFile->atEnd() && !rightFile->atEnd()) { int leftBytes = leftFile->read(leftBuffer, sizeof(leftBuffer)); int rightBytes = rightFile->read(rightBuffer, sizeof(rightBuffer)); if (leftBytes != rightBytes) { different = true; break; } if (leftBytes <= 0) break; received += leftBytes; if (memcmp(leftBuffer, rightBuffer, leftBytes)) { different = true; break; } if ((++cnt % 16) == 0 && timer.elapsed() >= 250) break; } if (different) { sync->compareContentResult(item, false); m_state = ST_STATE_READY; return; } if (leftFile->atEnd() && rightFile->atEnd()) { sync->compareContentResult(item, true); m_state = ST_STATE_READY; return; } QTimer::singleShot(0, this, SLOT(localFileCompareCycle())); } void CompareContentTask::slotDataReceived(KIO::Job *job, const QByteArray &data) { int jobowner = (job == leftReadJob) ? 1 : 0; int bufferLen = compareArray.size(); int dataLen = data.size(); if (job == leftReadJob) received += dataLen; if (jobowner == owner) { compareArray.append(data); return; } do { if (bufferLen == 0) { compareArray = QByteArray(data.data(), dataLen); owner = jobowner; break; } int minSize = (dataLen < bufferLen) ? dataLen : bufferLen; for (int i = 0; i != minSize; i++) if (data[i] != compareArray[i]) { abortContentComparing(); return; } if (minSize == bufferLen) { compareArray = QByteArray(data.data() + bufferLen, dataLen - bufferLen); if (dataLen == bufferLen) { owner = -1; return; } owner = jobowner; break; } else { compareArray = QByteArray(compareArray.data() + dataLen, bufferLen - dataLen); return; } } while (false); KIO::TransferJob *otherJob = (job == leftReadJob) ? rightReadJob : leftReadJob; if (otherJob == 0) { if (compareArray.size()) abortContentComparing(); } else { if (!((KIO::TransferJob *)job)->isSuspended()) { ((KIO::TransferJob *)job)->suspend(); otherJob->resume(); } } } void CompareContentTask::slotFinished(KJob *job) { KIO::TransferJob *otherJob = (job == leftReadJob) ? rightReadJob : leftReadJob; if (job == leftReadJob) leftReadJob = 0; else rightReadJob = 0; if (otherJob) otherJob->resume(); if (job->error()) { timer->stop(); abortContentComparing(); } if (job->error() && job->error() != KIO::ERR_USER_CANCELED && !errorPrinted) { errorPrinted = true; KMessageBox::error(parentWidget, i18n("I/O error while comparing file %1 with %2.", leftURL.toDisplayString(QUrl::PreferLocalFile), rightURL.toDisplayString(QUrl::PreferLocalFile))); } if (leftReadJob == 0 && rightReadJob == 0) { if (!compareArray.size()) sync->compareContentResult(item, true); else sync->compareContentResult(item, false); m_state = ST_STATE_READY; } } void CompareContentTask::abortContentComparing() { if (timer) timer->stop(); if (leftReadJob) leftReadJob->kill(KJob::EmitResult); if (rightReadJob) rightReadJob->kill(KJob::EmitResult); if (item->task() >= TT_UNKNOWN) sync->compareContentResult(item, false); m_state = ST_STATE_READY; } void CompareContentTask::sendStatusMessage() { double perc = (size == 0) ? 1. : (double)received / (double)size; int percent = (int)(perc * 10000. + 0.5); QString statstr = QString("%1.%2%3").arg(percent / 100).arg((percent / 10) % 10).arg(percent % 10) + '%'; setStatusMessage(i18n("Comparing file %1 (%2)...", leftURL.fileName(), statstr)); timer->setSingleShot(true); timer->start(500); } diff --git a/krusader/UserAction/expander.cpp b/krusader/UserAction/expander.cpp index 3e912b27..84a85eaa 100644 --- a/krusader/UserAction/expander.cpp +++ b/krusader/UserAction/expander.cpp @@ -1,1217 +1,1217 @@ /***************************************************************************** * Copyright (C) 2004 Jonas Bähr * * Copyright (C) 2004 Shie Erlich * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "expander.h" #include "../krusader.h" #include "../krusaderview.h" #include "../panelmanager.h" #include "../Panel/listpanel.h" #include "../Panel/panelfunc.h" #include "../Panel/krview.h" #include "../Search/krsearchdialog.h" #include "../GUI/profilemanager.h" -#include "../VFS/krvfshandler.h" +#include "../FileSystem/filesystemprovider.h" #include "../KViewer/krviewer.h" #include "../krservices.h" #ifdef SYNCHRONIZER_ENABLED #include "../Synchronizer/synchronizergui.h" #endif #ifdef __KJSEMBED__ #include "../KrJS/krjs.h" #endif // QtCore #include #include #include #include #include // QtGui #include // QtWidgets #include #include #include #include #include #include using namespace std; #define NEED_PANEL if (panel==0) { panelMissingError(_expression,exp); return QString(); } inline void exp_placeholder::setError(Expander& exp, const Error& e) { exp.setError(e); } inline QStringList exp_placeholder::splitEach(const TagString& s) { return Expander::splitEach(s); } inline exp_placeholder::exp_placeholder() { } void exp_placeholder::panelMissingError(const QString &s, Expander& exp) { exp.setError(Error(Error::exp_S_FATAL, Error::exp_C_ARGUMENT, i18n("Needed panel specification missing in expander %1", s))); } QStringList exp_placeholder::fileList(const KrPanel* const panel, const QString& type, const QString& mask, const bool omitPath, const bool useUrl, Expander& exp, const QString& error) { QStringList items; if (type.isEmpty() || type == "all") panel->view->getItemsByMask(mask, &items); else if (type == "files") panel->view->getItemsByMask(mask, &items, false, true); else if (type == "dirs") panel->view->getItemsByMask(mask, &items, true, false); else if (type == "selected") panel->view->getSelectedItems(&items); else { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_ARGUMENT, i18n("Expander: Bad argument to %1: %2 is not valid item specifier", error, type))); return QStringList(); } if (!omitPath) { // add the current path - // translate to urls using vfs + // translate to urls using filesystem QList list = panel->func->files()->getUrls(items); items.clear(); // parse everything to a single qstring foreach(const QUrl &url, list) { items.push_back(useUrl ? url.url() : url.path()); } } return items; } namespace { class exp_simpleplaceholder : public exp_placeholder { public: EXP_FUNC; virtual TagString expFunc(const KrPanel*, const QStringList&, const bool&, Expander&) const = 0; }; #define PLACEHOLDER_CLASS(name) \ class name : public exp_placeholder { \ public: \ name(); \ virtual TagString expFunc ( const KrPanel*, const TagStringList&, const bool&, Expander& ) const; \ }; #define SIMPLE_PLACEHOLDER_CLASS(name) \ class name : public exp_simpleplaceholder { \ public: \ using exp_simpleplaceholder::expFunc; \ name(); \ virtual TagString expFunc ( const KrPanel*, const QStringList&, const bool&, Expander& ) const; \ }; /** * expands %_Path% ('_' is replaced by 'a', 'o', 'r' or 'l' to indicate the active, other, right or left panel) with the path of the specified panel */ SIMPLE_PLACEHOLDER_CLASS(exp_Path) /** * expands %_Count% ('_' is replaced by 'a', 'o', 'r' or 'l' to indicate the active, other, right or left panel) with the number of items, which type is specified by the first Parameter */ SIMPLE_PLACEHOLDER_CLASS(exp_Count) /** * expands %_Filter% ('_' is replaced by 'a', 'o', 'r' or 'l' to indicate the active, other, right or left panel) with the correspondend filter (ie: "*.cpp") */ SIMPLE_PLACEHOLDER_CLASS(exp_Filter) /** * expands %_Current% ('_' is replaced by 'a', 'o', 'r' or 'l' to indicate the active, other, right or left panel) with the current item ( != the selected onec) */ SIMPLE_PLACEHOLDER_CLASS(exp_Current); /** * expands %_List% ('_' is replaced by 'a', 'o', 'r' or 'l' to indicate the active, other, right or left panel) with a list of items, which type is specified by the first Parameter */ SIMPLE_PLACEHOLDER_CLASS(exp_List); /** * expands %_ListFile% ('_' is replaced by 'a', 'o', 'r' or 'l' to indicate * the active, other, right or left panel) with the name of a temporary file, * containing a list of items, which type is specified by the first Parameter */ SIMPLE_PLACEHOLDER_CLASS(exp_ListFile); /** * expands %_Ask% ('_' is necessary because there is no panel needed) * with the return of an input-dialog */ SIMPLE_PLACEHOLDER_CLASS(exp_Ask); /** * This copies it's first Parameter to the clipboard */ PLACEHOLDER_CLASS(exp_Clipboard); /** * This selects all items by the mask given with the first Parameter */ SIMPLE_PLACEHOLDER_CLASS(exp_Select); /** * This changes the panel'spath to the value given with the first Parameter. */ SIMPLE_PLACEHOLDER_CLASS(exp_Goto); /** * This is equal to 'cp '. */ PLACEHOLDER_CLASS(exp_Copy); /** * This is equal to 'mv '. */ PLACEHOLDER_CLASS(exp_Move); #ifdef SYNCHRONIZER_ENABLED /** * This opens the synchronizer with a given profile */ SIMPLE_PLACEHOLDER_CLASS(exp_Sync); #endif /** * This opens the searchmodule with a given profile */ SIMPLE_PLACEHOLDER_CLASS(exp_NewSearch); /** * This loads the panel-profile with a given name */ SIMPLE_PLACEHOLDER_CLASS(exp_Profile); /** * This is setting marks in the string where he is later split up for each {all, selected, files, dirs} */ SIMPLE_PLACEHOLDER_CLASS(exp_Each); /** * This sets the sorting on a specific colunm */ SIMPLE_PLACEHOLDER_CLASS(exp_ColSort); /** * This sets relation between the left and right panel */ SIMPLE_PLACEHOLDER_CLASS(exp_PanelSize); #ifdef __KJSEMBED__ /** * This sets relation between the left and right panel */ SIMPLE_PLACEHOLDER_CLASS(exp_Script); #endif /** * This loads a file in the internal viewer */ SIMPLE_PLACEHOLDER_CLASS(exp_View); //////////////////////////////////////////////////////////// //////////////////////// utils //////////////////////// //////////////////////////////////////////////////////////// /** * escapes everything that confuses bash in filenames * @param s String to manipulate * @return escaped string */ QString bashquote(QString s) { /* // we _can_not_ use this function because it _encloses_ the sting in single-quots! // In this case quotes strings could not be concaternated anymore return KrServices::quote(s); */ static const QString evilstuff = "\\\"'`()[]{}!?;$&<>| \t\r\n"; // stuff that should get escaped for (int i = 0; i < evilstuff.length(); ++i) s.replace(evilstuff[ i ], ('\\' + evilstuff[ i ])); return s; } QString separateAndQuote(QStringList list, const QString& separator, const bool quote) { if (quote) transform(list.begin(), list.end(), list.begin(), bashquote); // QLineEdit::text() always escapes special characters, revert this for newline and tab QString decodedSeparator = separator; decodedSeparator.replace("\\n", "\n").replace("\\t", "\t"); return list.join(decodedSeparator); } ///////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////// expander classes //////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////// exp_Path::exp_Path() { _expression = "Path"; _description = i18n("Panel's Path..."); _needPanel = true; addParameter(exp_parameter(i18n("Automatically escape spaces"), "__yes", false)); } TagString exp_Path::expFunc(const KrPanel* panel, const QStringList& parameter, const bool& useUrl, Expander& exp) const { NEED_PANEL QString result; if (useUrl) result = panel->func->files()->currentDirectory().url() + '/'; else result = panel->func->files()->currentDirectory().path() + '/'; if (parameter.count() > 0 && parameter[0].toLower() == "no") // don't escape spaces return TagString(result); else return TagString(bashquote(result)); } exp_Count::exp_Count() { _expression = "Count"; _description = i18n("Number of..."); _needPanel = true; addParameter(exp_parameter(i18n("Count:"), "__choose:All;Files;Dirs;Selected", false)); } TagString exp_Count::expFunc(const KrPanel* panel, const QStringList& parameter, const bool&, Expander& exp) const { NEED_PANEL int n = -1; if (parameter.count() == 0 || parameter[ 0 ].isEmpty() || parameter[ 0 ].toLower() == "all") n = panel->view->numDirs() + panel->view->numFiles(); else if (parameter[ 0 ].toLower() == "files") n = panel->view->numFiles(); else if (parameter[ 0 ].toLower() == "dirs") n = panel->view->numDirs(); else if (parameter[ 0 ].toLower() == "selected") n = panel->view->numSelected(); else { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_ARGUMENT, i18n("Expander: Bad argument to Count: %1 is not valid item specifier", parameter[0]))); return QString(); } return TagString(QString("%1").arg(n)); } exp_Filter::exp_Filter() { _expression = "Filter"; _description = i18n("Filter Mask (*.h, *.cpp, etc.)"); _needPanel = true; } TagString exp_Filter::expFunc(const KrPanel* panel, const QStringList&, const bool&, Expander& exp) const { NEED_PANEL return panel->view->filterMask().nameFilter(); } exp_Current::exp_Current() { _expression = "Current"; _description = i18n("Current File (!= Selected File)..."); _needPanel = true; addParameter(exp_parameter(i18n("Omit the current path (optional)"), "__no", false)); addParameter(exp_parameter(i18n("Automatically escape spaces"), "__yes", false)); } TagString exp_Current::expFunc(const KrPanel* panel, const QStringList& parameter, const bool& useUrl, Expander& exp) const { NEED_PANEL QString item = panel->view->getCurrentItem(); QString result; if (parameter.count() > 0 && parameter[0].toLower() == "yes") // omit the current path result = item; else { QUrl url = panel->func->files()->getUrl(item); if (useUrl) result = url.url(); else result = url.path(); } if (parameter.count() > 1 && parameter[1].toLower() == "no") // don't escape spaces return result; else return bashquote(result); } exp_List::exp_List() { _expression = "List"; _description = i18n("Item List of..."); _needPanel = true; addParameter(exp_parameter(i18n("Which items:"), "__choose:All;Files;Dirs;Selected", false)); addParameter(exp_parameter(i18n("Separator between the items (optional):"), " ", false)); addParameter(exp_parameter(i18n("Omit the current path (optional)"), "__no", false)); addParameter(exp_parameter(i18n("Mask (optional, all but 'Selected'):"), "__select", false)); addParameter(exp_parameter(i18n("Automatically escape spaces"), "__yes", false)); } TagString exp_List::expFunc(const KrPanel* panel, const QStringList& parameter, const bool& useUrl, Expander& exp) const { NEED_PANEL // get selected items from view QStringList items; QString mask; if (parameter.count() <= 3 || parameter[3].isEmpty()) mask = '*'; else mask = parameter[3]; return separateAndQuote( fileList(panel, parameter.isEmpty() ? QString() : parameter[0].toLower(), mask, parameter.count() > 2 ? parameter[2].toLower() == "yes" : false, useUrl, exp, "List"), parameter.count() > 1 ? parameter[1] : " ", parameter.count() > 4 ? parameter[4].toLower() == "yes" : true); } exp_ListFile::exp_ListFile() { _expression = "ListFile"; _description = i18n("Filename of an Item List..."); _needPanel = true; addParameter(exp_parameter(i18n("Which items:"), "__choose:All;Files;Dirs;Selected", false)); addParameter(exp_parameter(i18n("Separator between the items (optional)"), "\n", false)); addParameter(exp_parameter(i18n("Omit the current path (optional)"), "__no", false)); addParameter(exp_parameter(i18n("Mask (optional, all but 'Selected'):"), "__select", false)); addParameter(exp_parameter(i18n("Automatically escape spaces"), "__no", false)); } TagString exp_ListFile::expFunc(const KrPanel* panel, const QStringList& parameter, const bool& useUrl, Expander& exp) const { NEED_PANEL // get selected items from view QStringList items; QString mask; if (parameter.count() <= 3 || parameter[3].isEmpty()) mask = '*'; else mask = parameter[3]; QTemporaryFile tmpFile(QDir::tempPath() + QLatin1String("/krusader_XXXXXX.itemlist")); tmpFile.setAutoRemove(false); if (!tmpFile.open()) { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_WORLD, i18n("Expander: temporary file could not be opened (%1)", tmpFile.errorString()))); return QString(); } QTextStream stream(&tmpFile); stream << separateAndQuote( fileList(panel, parameter.isEmpty() ? QString() : parameter[0].toLower(), mask, parameter.count() > 2 ? parameter[2].toLower() == "yes" : false, useUrl, exp, "ListFile"), parameter.count() > 1 ? parameter[1] : "\n", parameter.count() > 4 ? parameter[4].toLower() == "yes" : true) << "\n"; tmpFile.close(); return tmpFile.fileName(); } exp_Select::exp_Select() { _expression = "Select"; _description = i18n("Manipulate the Selection..."); _needPanel = true; addParameter(exp_parameter(i18n("Selection mask:"), "__select", true)); addParameter(exp_parameter(i18n("Manipulate in which way:"), "__choose:Set;Add;Remove", false)); } TagString exp_Select::expFunc(const KrPanel* panel, const QStringList& parameter, const bool& , Expander& exp) const { NEED_PANEL KRQuery mask; if (parameter.count() <= 0 || parameter[0].isEmpty()) mask = KRQuery("*"); else mask = KRQuery(parameter[0]); if (parameter.count() > 1 && parameter[1].toLower() == "list-add") panel->view->select(mask); else if (parameter.count() > 1 && parameter[1].toLower() == "list-remove") panel->view->unselect(mask); else { // parameter[1].toLower() == "set" or isEmpty() or whatever panel->view->unselect(KRQuery("*")); panel->view->select(mask); } return QString(); // this doesn't return anything, that's normal! } exp_Goto::exp_Goto() { _expression = "Goto"; _description = i18n("Jump to a Location..."); _needPanel = true; addParameter(exp_parameter(i18n("Choose a path:"), "__goto", true)); addParameter(exp_parameter(i18n("Open location in a new tab"), "__no", false)); } TagString exp_Goto::expFunc(const KrPanel* panel, const QStringList& parameter, const bool&, Expander& exp) const { NEED_PANEL bool newTab = false; if (parameter.count() > 1 && parameter[1].toLower() == "yes") newTab = true; if (parameter.count() == 0) { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_ARGUMENT, i18n("Expander: at least 1 parameter is required for Goto."))); return QString(); } QUrl url = QUrl::fromUserInput(parameter[0], QString(), QUrl::AssumeLocalFile); if (newTab) { if (panel == LEFT_PANEL) MAIN_VIEW->leftManager()->slotNewTab(url); else MAIN_VIEW->rightManager()->slotNewTab(url); } else { panel->func->openUrl(url, ""); panel->gui->slotFocusOnMe(); } return QString(); // this doesn't return anything, that's normal! } /* exp_Search::exp_Search() { _expression = "Search"; _description = i18n("Search for files"); _needPanel = true; addParameter( new exp_parameter( i18n("please choose the setting"), "__searchprofile", true ) ); - addParameter( new exp_parameter( i18n("open the search in a new tab"), "__yes", false ) ); //TODO: add this also to panel-dependent as soon as vfs support the display of search-results + addParameter( new exp_parameter( i18n("open the search in a new tab"), "__yes", false ) ); //TODO: add this also to panel-dependent as soon as filesystem support the display of search-results } */ exp_Ask::exp_Ask() { _expression = "Ask"; _description = i18n("Ask Parameter from User..."); _needPanel = false; addParameter(exp_parameter(i18n("Question:"), "Where do you want do go today?", true)); addParameter(exp_parameter(i18n("Preset (optional):"), "", false)); addParameter(exp_parameter(i18n("Caption (optional):"), "", false)); } TagString exp_Ask::expFunc(const KrPanel*, const QStringList& parameter, const bool&, Expander& exp) const { QString caption, preset, result; if (parameter.count() == 0) { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_ARGUMENT, i18n("Expander: at least 1 parameter is required for Ask."))); return QString(); } if (parameter.count() <= 2 || parameter[2].isEmpty()) caption = i18n("User Action"); else caption = parameter[2]; if (parameter.count() <= 1 || parameter[1].isEmpty()) preset.clear(); else preset = parameter[1]; bool ok; result = QInputDialog::getText(krMainWindow, caption, parameter[0], QLineEdit::Normal, preset, &ok); if (ok) return result; else { setError(exp, Error(Error::exp_S_ERROR, Error::exp_C_USER, "User cancelled")); return QString(); } } exp_Clipboard::exp_Clipboard() { _expression = "Clipboard"; _description = i18n("Copy to Clipboard..."); _needPanel = false; addParameter(exp_parameter(i18n("What to copy:"), "__placeholder", true)); addParameter(exp_parameter(i18n("Append to current clipboard content with this separator (optional):"), "", false)); } TagString exp_Clipboard::expFunc(const KrPanel*, const TagStringList& parameter, const bool&, Expander& exp) const { // qDebug() << "Expander::exp_Clipboard, parameter[0]: '" << parameter[0] << "', Clipboard: " << QApplication::clipboard()->text() << endl; if (parameter.count() == 0) { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_ARGUMENT, i18n("Expander: at least 1 parameter is required for Clipboard."))); return QString(); } QStringList lst = splitEach(parameter[0]); if (parameter.count() > 1 && !parameter[1].isSimple()) { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_SYNTAX, i18n("Expander: %Each% may not be in the second argument of %Clipboard%"))); return QString(); } if (parameter.count() <= 1 || parameter[1].string().isEmpty() || QApplication::clipboard()->text().isEmpty()) QApplication::clipboard()->setText(lst.join("\n")); else QApplication::clipboard()->setText(QApplication::clipboard()->text() + parameter[1].string() + lst.join("\n")); return QString(); // this doesn't return anything, that's normal! } exp_Copy::exp_Copy() { _expression = "Copy"; _description = i18n("Copy a File/Folder..."); _needPanel = false; addParameter(exp_parameter(i18n("What to copy:"), "__placeholder", true)); addParameter(exp_parameter(i18n("Where to copy:"), "__placeholder", true)); } TagString exp_Copy::expFunc(const KrPanel*, const TagStringList& parameter, const bool&, Expander& exp) const { if (parameter.count() < 2) { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_ARGUMENT, i18n("Expander: at least 2 parameter is required for Copy."))); return QString(); } // basically the parameter can already be used as URL, but since QUrl has problems with ftp-proxy-urls (like ftp://username@proxyusername@url...) this is neccesary: QStringList lst = splitEach(parameter[0]); if (!parameter[1].isSimple()) { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_SYNTAX, i18n("Expander: %Each% may not be in the second argument of %Copy%"))); return QString(); } QList src; for (QStringList::const_iterator it = lst.constBegin(), end = lst.constEnd();it != end;++it) src.push_back(QUrl::fromUserInput(*it, QString(), QUrl::AssumeLocalFile)); // or transform(...) ? QUrl dest = QUrl::fromUserInput(parameter[1].string(), QString(), QUrl::AssumeLocalFile); if (!dest.isValid() || find_if(src.constBegin(), src.constEnd(), not1(mem_fun_ref(&QUrl::isValid))) != src.constEnd()) { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_ARGUMENT, i18n("Expander: invalid URLs in %_Copy(\"src\", \"dest\")%"))); return QString(); } - KrVfsHandler::instance().startCopyFiles(src, dest); + FileSystemProvider::instance().startCopyFiles(src, dest); return QString(); // this doesn't return everything, that's normal! } exp_Move::exp_Move() { _expression = "Move"; _description = i18n("Move/Rename a File/Folder..."); _needPanel = false; addParameter(exp_parameter(i18n("What to move/rename:"), "__placeholder", true)); addParameter(exp_parameter(i18n("New target/name:"), "__placeholder", true)); } TagString exp_Move::expFunc(const KrPanel*, const TagStringList& parameter, const bool& , Expander& exp) const { if (parameter.count() < 2) { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_ARGUMENT, i18n("Expander: at least 2 parameter is required for Move."))); return QString(); } // basically the parameter can already be used as URL, but since QUrl has problems with ftp-proxy-urls (like ftp://username@proxyusername@url...) this is neccesary: QStringList lst = splitEach(parameter[0]); if (!parameter[1].isSimple()) { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_SYNTAX, i18n("%Each% may not be in the second argument of %Move%"))); return QString(); } QList src; for (QStringList::const_iterator it = lst.constBegin(), end = lst.constEnd();it != end;++it) src.push_back(QUrl::fromUserInput(*it, QString(), QUrl::AssumeLocalFile)); // or transform(...) ? QUrl dest = QUrl::fromUserInput(parameter[1].string(), QString(), QUrl::AssumeLocalFile); if (!dest.isValid() || find_if(src.constBegin(), src.constEnd(), not1(mem_fun_ref(&QUrl::isValid))) != src.constEnd()) { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_ARGUMENT, i18n("Expander: invalid URLs in %_Move(\"src\", \"dest\")%"))); return QString(); } - KrVfsHandler::instance().startCopyFiles(src, dest, KIO::CopyJob::Move); + FileSystemProvider::instance().startCopyFiles(src, dest, KIO::CopyJob::Move); return QString(); // this doesn't return anything, that's normal! } #ifdef SYNCHRONIZER_ENABLED exp_Sync::exp_Sync() { _expression = "Sync"; _description = i18n("Load a Synchronizer Profile..."); _needPanel = false; addParameter(exp_parameter(i18n("Choose a profile:"), "__syncprofile", true)); } TagString exp_Sync::expFunc(const KrPanel*, const QStringList& parameter, const bool&, Expander& exp) const { if (parameter.count() == 0 || parameter[0].isEmpty()) { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_ARGUMENT, i18n("Expander: no profile specified for %_Sync(profile)%"))); return QString(); } new SynchronizerGUI(0, parameter[0]); return QString(); // this doesn't return everything, that's normal! } #endif exp_NewSearch::exp_NewSearch() { _expression = "NewSearch"; _description = i18n("Load a Searchmodule Profile..."); _needPanel = false; addParameter(exp_parameter(i18n("Choose a profile:"), "__searchprofile", true)); } TagString exp_NewSearch::expFunc(const KrPanel*, const QStringList& parameter, const bool&, Expander& exp) const { if (parameter.count() == 0 || parameter[0].isEmpty()) { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_ARGUMENT, i18n("Expander: no profile specified for %_NewSearch(profile)%"))); return QString(); } new KrSearchDialog(parameter[0], krApp); return QString(); // this doesn't return everything, that's normal! } exp_Profile::exp_Profile() { _expression = "Profile"; _description = i18n("Load a Panel Profile..."); _needPanel = false; addParameter(exp_parameter(i18n("Choose a profile:"), "__panelprofile", true)); } TagString exp_Profile::expFunc(const KrPanel*, const QStringList& parameter, const bool&, Expander& exp) const { if (parameter.count() == 0 || parameter[0].isEmpty()) { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_ARGUMENT, i18n("Expander: no profile specified for %_Profile(profile)%; abort..."))); return QString(); } MAIN_VIEW->profiles(parameter[0]); return QString(); // this doesn't return everything, that's normal! } exp_Each::exp_Each() { _expression = "Each"; _description = i18n("Separate Program Call for Each..."); _needPanel = true; addParameter(exp_parameter(i18n("Which items:"), "__choose:All;Files;Dirs;Selected", false)); addParameter(exp_parameter(i18n("Omit the current path (optional)"), "__no", false)); addParameter(exp_parameter(i18n("Mask (optional, all but 'Selected'):"), "__select", false)); addParameter(exp_parameter(i18n("Automatically escape spaces"), "__yes", false)); } TagString exp_Each::expFunc(const KrPanel* panel, const QStringList& parameter, const bool& useUrl, Expander& exp) const { NEED_PANEL QString mask; if (parameter.count() <= 2 || parameter[2].isEmpty()) mask = '*'; else mask = parameter[2]; TagString ret; QStringList l = fileList(panel, parameter.empty() ? QString() : parameter[0].toLower(), mask, parameter.count() > 1 && parameter[1].toLower() == "yes", useUrl, exp, "Each"); if (!(parameter.count() <= 3 || parameter[3].toLower() != "yes")) transform(l.begin(), l.end(), l.begin(), bashquote); ret.insertTag(0, l); return ret; } exp_ColSort::exp_ColSort() { _expression = "ColSort"; _description = i18n("Set Sorting for This Panel..."); _needPanel = true; addParameter(exp_parameter(i18n("Choose a column:"), "__choose:Name;Ext;Type;Size;Modified;Perms;rwx;Owner;Group", true)); addParameter(exp_parameter(i18n("Choose a sort sequence:"), "__choose:Toggle;Asc;Desc", false)); } TagString exp_ColSort::expFunc(const KrPanel* panel, const QStringList& parameter, const bool&, Expander& exp) const { NEED_PANEL if (parameter.count() == 0 || parameter[0].isEmpty()) { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_ARGUMENT, i18n("Expander: no column specified for %_ColSort(column)%"))); return QString(); } KrViewProperties::ColumnType oldColumn = panel->view->properties()->sortColumn; KrViewProperties::ColumnType column = oldColumn; if (parameter[0].toLower() == "name") { column = KrViewProperties::Name; } else if (parameter[0].toLower() == "ext") { column = KrViewProperties::Ext; } else if (parameter[0].toLower() == "type") { column = KrViewProperties::Type; } else if (parameter[0].toLower() == "size") { column = KrViewProperties::Size; } else if (parameter[0].toLower() == "modified") { column = KrViewProperties::Modified; } else if (parameter[0].toLower() == "perms") { column = KrViewProperties::Permissions; } else if (parameter[0].toLower() == "rwx") { column = KrViewProperties::KrPermissions; } else if (parameter[0].toLower() == "owner") { column = KrViewProperties::Owner; } else if (parameter[0].toLower() == "group") { column = KrViewProperties::Group; } else { setError(exp, Error(Error::exp_S_WARNING, Error::exp_C_ARGUMENT, i18n("Expander: unknown column specified for %_ColSort(%1)%", parameter[0]))); return QString(); } bool descending = panel->view->properties()->sortOptions & KrViewProperties::Descending; if (parameter.count() <= 1 || (parameter[1].toLower() != "asc" && parameter[1].toLower() != "desc")) { // no sortdir parameter if(column == oldColumn) // reverse direction if column is unchanged descending = !descending; else // otherwise set to ascending descending = false; } else { // sortdir specified if (parameter[1].toLower() == "asc") descending = false; else // == desc descending = true; } panel->view->setSortMode(column, descending); return QString(); // this doesn't return anything, that's normal! } exp_PanelSize::exp_PanelSize() { _expression = "PanelSize"; _description = i18n("Set Relation Between the Panels..."); _needPanel = true; addParameter(exp_parameter(i18n("Set the new size in percent:"), "__int:0;100;5;50", true)); } TagString exp_PanelSize::expFunc(const KrPanel* panel, const QStringList& parameter, const bool&, Expander& exp) const { NEED_PANEL int newSize; if (parameter.count() == 0 || parameter[0].isEmpty()) newSize = 50; //default is 50% else newSize = parameter[0].toInt(); if (newSize < 0 || newSize > 100) { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_ARGUMENT, i18n("Expander: Value %1 out of range for %_PanelSize(percent)%. The first parameter has to be >0 and <100", newSize))); return QString(); } MAIN_VIEW->setPanelSize(panel->isLeft(), newSize); return QString(); // this doesn't return everything, that's normal! } #ifdef __KJSEMBED__ exp_Script::exp_Script() { _expression = "Script"; _description = i18n("Execute a JavaScript Extension..."); _needPanel = false; addParameter(exp_parameter(i18n("Location of the script"), "", true)); addParameter(exp_parameter(i18n("Set some variables for the execution (optional).\ni.e. \"return=return_var;foo=bar\", consult the handbook for more information"), "", false)); } TagString exp_Script::expFunc(const KrPanel*, const QStringList& parameter, const bool&, Expander& exp) const { if (parameter.count() == 0 || parameter[0].isEmpty()) { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_ARGUMENT, i18n("Expander: no script specified for %_Script(script)%"))); return QString(); } QString filename = parameter[0]; if (filename.find('/') && QUrl::isRelativeUrl(filename)) { // this return the local version of the file if this exists. else the global one is returnd filename = locate("data", "krusader/js/" + filename); } if (! krJS) krJS = new KrJS(); KJS::ExecState *exec = krJS->globalExec(); QString jsReturn; if (parameter[1].toLower() == "yes") // to stay compatible with the old-style parameter jsReturn = "cmd"; else { QStringList jsVariables = parameter[1].split(';'); QString jsVariable, jsValue; for (QStringList::Iterator it = jsVariables.begin(); it != jsVariables.end(); ++it) { jsVariable = (*it).section('=', 0, 0).trimmed(); jsValue = (*it).section('=', 1); if (jsVariable == "return") jsReturn = jsValue.trimmed(); else krJS->putValue(jsVariable, KJSEmbed::convertToValue(exec, jsValue)); } } krJS->runFile(filename); if (! jsReturn.isEmpty()) return krJS->getValue(jsReturn).toString(krJS->globalExec()).qstring(); else return QString(); } #endif exp_View::exp_View() { _expression = "View"; _description = i18n("View File with Krusader's Internal Viewer..."); _needPanel = false; addParameter(exp_parameter(i18n("Which file to view (normally '%aCurrent%'):"), "__placeholder", true)); addParameter(exp_parameter(i18n("Choose a view mode:"), "__choose:generic;text;hex", false)); //addParameter( exp_parameter( i18n("Choose a window-mode"), "__choose:tab;window;panel", false ) ); //TODO: window-mode 'panel' should open the file in the third-hand viewer addParameter(exp_parameter(i18n("Choose a window mode:"), "__choose:tab;window", false)); } TagString exp_View::expFunc(const KrPanel*, const QStringList& parameter, const bool&, Expander& exp) const { if (parameter.count() == 0 || parameter[0].isEmpty()) { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_ARGUMENT, i18n("Expander: no file to view in %_View(filename)%"))); return QString(); } QString viewMode, windowMode; if (parameter.count() <= 1 || parameter[1].isEmpty()) viewMode = "generic"; else viewMode = parameter[1]; if (parameter.count() <= 2 || parameter[2].isEmpty()) windowMode = "tab"; else windowMode = parameter[2]; KrViewer::Mode mode = KrViewer::Generic; if (viewMode == "text") mode = KrViewer::Text; else if (viewMode == "hex") mode = KrViewer::Hex; QUrl url = QUrl::fromUserInput(parameter[0], QString(), QUrl::AssumeLocalFile); KrViewer::view(url, mode, (windowMode == "window")); //TODO: Call the viewer with viewMode and windowMode. Filename is in parameter[0]. // It would be nice if parameter[0] could also be a space-separated filename-list (provided if the first parameter is %aList(selected)%) return QString(); // this doesn't return everything, that's normal! } ///////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////// end of expander classes //////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////// TagString exp_simpleplaceholder::expFunc(const KrPanel* p, const TagStringList& parameter, const bool& useUrl, Expander& exp) const { QStringList lst; for (TagStringList::const_iterator it = parameter.begin(), end = parameter.end();it != end;++it) if ((*it).isSimple()) lst.push_back((*it).string()); else { setError(exp, Error(Error::exp_S_FATAL, Error::exp_C_SYNTAX, i18n("%Each% is not allowed in parameter to %1", description()))); return QString(); } return expFunc(p, lst, useUrl, exp); } } KrPanel* Expander::getPanel(const char panelIndicator, const exp_placeholder* pl, Expander& exp) { switch (panelIndicator) { case 'a': return ACTIVE_PANEL; case 'o': return OTHER_PANEL; case 'l': return LEFT_PANEL; case 'r': return RIGHT_PANEL; case '_': return 0; default: exp.setError(Error(Error::exp_S_FATAL, Error::exp_C_SYNTAX, i18n("Expander: Bad panel specifier %1 in placeholder %2", panelIndicator, pl->description()))); return 0; } } void Expander::expand(const QString& stringToExpand, bool useUrl) { TagString result = expandCurrent(stringToExpand, useUrl); if (error()) return; if (!result.isSimple()) resultList = splitEach(result); else resultList.append(result.string()); // krOut << resultList[0] << endl; } TagString Expander::expandCurrent(const QString& stringToExpand, bool useUrl) { TagString result; QString exp; TagString tmpResult; int begin, end, i; // int brackets = 0; // bool inQuotes = false; int idx = 0; while (idx < stringToExpand.length()) { if ((begin = stringToExpand.indexOf('%', idx)) == -1) break; if ((end = findEnd(stringToExpand, begin)) == -1) { // xgettext:no-c-format setError(Error(Error::exp_S_FATAL, Error::exp_C_SYNTAX, i18n("Error: unterminated % in Expander"))); return QString(); } result += stringToExpand.mid(idx, begin - idx); // copy until the start of %exp% // get the expression, and expand it using the correct expander function exp = stringToExpand.mid(begin + 1, end - begin - 1); // qDebug() << "------------- exp: '" << exp << "'" << endl; if (exp.isEmpty()) result += QString(QChar('%')); else { TagStringList parameter = separateParameter(&exp, useUrl); if (error()) return QString(); char panelIndicator = exp.toLower()[0].toLatin1(); exp.replace(0, 1, ""); for (i = 0; i < placeholderCount(); ++i) if (exp == placeholder(i)->expression()) { // qDebug() << "---------------------------------------" << endl; tmpResult = placeholder(i)->expFunc(getPanel(panelIndicator, placeholder(i), *this), parameter, useUrl, *this); if (error()) { return QString(); } else result += tmpResult; // qDebug() << "---------------------------------------" << endl; break; } if (i == placeholderCount()) { // didn't find an expander setError(Error(Error::exp_S_FATAL, Error::exp_C_SYNTAX, i18n("Error: unrecognized %%%1%2%% in Expander", panelIndicator, exp))); return QString(); } } //else idx = end + 1; } // copy the rest of the string result += stringToExpand.mid(idx); // qDebug() << "============== result '" << result << "'" << endl; return result; } QStringList Expander::splitEach(TagString stringToSplit) { if (stringToSplit.isSimple()) { // krOut << stringToSplit.string() << endl; QStringList l; l << stringToSplit.string(); return l; } pair pl = *stringToSplit.tagsBegin(); stringToSplit.eraseTag(stringToSplit.tagsBegin()); QStringList ret; for (QStringList::const_iterator it = pl.second.constBegin(), end = pl.second.constEnd();it != end;++it) { TagString s = stringToSplit; s.insert(pl.first, *it); ret += splitEach(s); } return ret; // qDebug() << "stringToSplit: " << stringToSplit << endl; } TagStringList Expander::separateParameter(QString* const exp, bool useUrl) { TagStringList parameter; QStringList parameter1; QString result; int begin, end; if ((begin = exp->indexOf('(')) != -1) { if ((end = exp->lastIndexOf(')')) == -1) { setError(Error(Error::exp_S_FATAL, Error::exp_C_SYNTAX, i18n("Error: missing ')' in Expander"))); return TagStringList(); } result = exp->mid(begin + 1, end - begin - 1); *exp = exp->left(begin); bool inQuotes = false; int idx = 0; begin = 0; while (idx < result.length()) { if (result[ idx ].toLatin1() == '\\') { if (result[ idx+1 ].toLatin1() == '"') result.replace(idx, 1, ""); } if (result[ idx ].toLatin1() == '"') inQuotes = !inQuotes; if (result[ idx ].toLatin1() == ',' && !inQuotes) { parameter1.append(result.mid(begin, idx - begin)); begin = idx + 1; // krOut << " ---- parameter: " << parameter.join(";") << endl; } idx++; } parameter1.append(result.mid(begin, idx - begin)); //don't forget the last one for (QStringList::Iterator it = parameter1.begin(); it != parameter1.end(); ++it) { *it = (*it).trimmed(); if ((*it).left(1) == "\"") *it = (*it).mid(1, (*it).length() - 2); parameter.push_back(expandCurrent(*it, useUrl)); if (error()) return TagStringList(); } } // krOut << "------- exp: " << *exp << " ---- parameter: " << parameter.join(";") << endl; return parameter; } int Expander::findEnd(const QString& str, int start) { int end = str.indexOf('%', start + 1); if (end == -1) return end; int bracket = str.indexOf('(', start + 1); if (end < bracket || bracket == -1) return end; int idx = bracket + 1; bool inQuotes = false; int depth = 1; while (idx < str.length()) { switch (str[ idx ].toLatin1()) { case '\\': idx ++; break; case '"': inQuotes = !inQuotes; break; case '(': if (!inQuotes) depth++; break; case ')': if (!inQuotes) --depth; break; case '%': if (depth == 0) return idx; } //switch idx++; } //while // failsafe return -1; } QList& Expander::_placeholder() { static QList ret; if(!ret.count()) { ret << new exp_View; ret << new exp_PanelSize; ret << new exp_ColSort; ret << new exp_Each; ret << new exp_Profile; ret << new exp_NewSearch; #ifdef SYNCHRONIZER_ENABLED ret << new exp_Sync; #endif ret << new exp_Move; ret << new exp_Copy; ret << new exp_Goto; ret << new exp_Select; ret << new exp_Clipboard; ret << new exp_Ask; ret << new exp_ListFile; ret << new exp_List; ret << new exp_Current; ret << new exp_Filter; ret << new exp_Count; ret << new exp_Path; #ifdef __KJSEMBED__ ret << new exp_Script; #endif } return ret; } diff --git a/krusader/VFS/CMakeLists.txt b/krusader/VFS/CMakeLists.txt deleted file mode 100644 index b8eabc1e..00000000 --- a/krusader/VFS/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -include_directories(${KF5_INCLUDES_DIRS} ${QT_INCLUDES}) - -set(VFS_SRCS - vfilecontainer.cpp - krvfshandler.cpp - virt_vfs.cpp - vfs.cpp - vfile.cpp - default_vfs.cpp - krpermhandler.cpp - krquery.cpp - krtrashhandler.cpp - ../../krArc/krlinecountingprocess.cpp -) - -add_library(VFS STATIC ${VFS_SRCS}) - -target_link_libraries(VFS - KF5::I18n - KF5::KIOCore - KF5::KIOWidgets -) - -if(ACL_FOUND) - target_link_libraries(VFS ${ACL_LIBS}) -endif(ACL_FOUND) diff --git a/krusader/krslots.cpp b/krusader/krslots.cpp index 5706d1cf..b1b2d0d3 100644 --- a/krusader/krslots.cpp +++ b/krusader/krslots.cpp @@ -1,738 +1,738 @@ /*************************************************************************** krslots.cpp ------------------- copyright : (C) 2001 by Shie Erlich & Rafi Yanai email : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "krslots.h" // QtCore #include #include #include #include #include #include // QtGui #include #include // QtWidgets #include #include #include #include #include #include #include #ifdef __KJSEMBED__ #include #include "KrJS/krjs.h" #endif #include "KViewer/krviewer.h" #include "Panel/krviewfactory.h" #include "krusader.h" #include "kractions.h" #include "krusaderview.h" #include "Panel/listpanel.h" #include "Panel/krselectionmode.h" #include "Dialogs/krdialogs.h" #include "Dialogs/krspwidgets.h" #include "GUI/krusaderstatus.h" #include "Panel/panelfunc.h" #include "Konfigurator/konfigurator.h" #include "MountMan/kmountman.h" #include "defaults.h" #include "GUI/kfnkeys.h" #include "GUI/kcmdline.h" #include "GUI/terminaldock.h" #include "GUI/syncbrowsebutton.h" #include "GUI/mediabutton.h" #include "GUI/dirhistorybutton.h" -#include "VFS/krquery.h" +#include "FileSystem/krquery.h" #include "Search/krsearchmod.h" #include "Search/krsearchdialog.h" #include "Locate/locate.h" -#include "VFS/vfs.h" -#include "VFS/vfile.h" +#include "FileSystem/filesystem.h" +#include "FileSystem/fileitem.h" #include "panelmanager.h" #include "Splitter/splittergui.h" #include "Splitter/splitter.h" #include "Splitter/combiner.h" #include "ActionMan/actionman.h" #include "Panel/panelpopup.h" #include "Dialogs/krspecialwidgets.h" #include "DiskUsage/diskusagegui.h" #include "krservices.h" #include "Panel/krviewitem.h" #include "krtrashhandler.h" #include "BookMan/krbookmarkhandler.h" #include "BookMan/krbookmarkbutton.h" #ifdef SYNCHRONIZER_ENABLED #include "Synchronizer/synchronizergui.h" #endif #define ACTIVE_VIEW _mainWindow->activeView() KRslots::KRslots(QObject *parent) : QObject(parent), _mainWindow(krApp) { } void KRslots::sendFileByEmail(const QList &urls) { if (urls.count() == 0) { KMessageBox::error(0, i18n("No selected files to send.")); return; } QString mailProg; QStringList lst = KrServices::supportedTools(); if (lst.contains("MAIL")) mailProg = lst[lst.indexOf("MAIL") + 1]; else { KMessageBox::error(0, i18n("Krusader cannot find a supported mail client. Please install one to your path. Hint: Krusader supports KMail.")); return; } QString subject, separator; foreach(const QUrl &url, urls) { subject += separator + url.fileName(); separator = ','; } subject = i18np("Sending file: %2", "Sending files: %2", urls.count(), subject); KProcess proc; QString executable = QUrl::fromLocalFile(mailProg).fileName(); if (executable == QStringLiteral("kmail")) { proc << mailProg << "--subject" << subject; foreach(const QUrl &url2, urls) proc << "--attach" << url2.toDisplayString(); } else if (executable == QStringLiteral("thunderbird")) { QString param = "attachment=\'"; separator = ""; foreach(const QUrl &url2, urls) { param += separator + url2.toDisplayString(); separator = ','; } param += "\',subject=\'" + subject + "\'"; proc << mailProg << "--compose" << param; } else if (executable == QStringLiteral("evolution")) { QString param = "mailto:?cc=&subject=" + subject + "&attach="; separator = ""; foreach(const QUrl &url2, urls) { param += separator + url2.toDisplayString(); separator = "&attach="; } proc << mailProg << param + ""; } if (!proc.startDetached()) KMessageBox::error(0, i18n("Error executing %1.", mailProg)); } void KRslots::compareContent() { const QStringList lstLeft = LEFT_PANEL->getSelectedNames(); const QStringList lstRight = RIGHT_PANEL->getSelectedNames(); const QStringList lstActive = ACTIVE_PANEL->gui->isLeft() ? lstLeft : lstRight; QUrl name1, name2; if (lstLeft.count() == 1 && lstRight.count() == 1) { // first, see if we've got exactly 1 selected file in each panel: name1 = LEFT_PANEL->func->files()->getUrl(lstLeft[0]); name2 = RIGHT_PANEL->func->files()->getUrl(lstRight[0]); } else if (lstActive.count() == 2) { // next try: are in the current panel exacty 2 files selected? name1 = ACTIVE_PANEL->func->files()->getUrl(lstActive[0]); name2 = ACTIVE_PANEL->func->files()->getUrl(lstActive[1]); - } else if (ACTIVE_PANEL->otherPanel()->func->files()->getVfile(ACTIVE_VIEW->getCurrentItem())) { + } else if (ACTIVE_PANEL->otherPanel()->func->files()->getFileItem(ACTIVE_VIEW->getCurrentItem())) { // next try: is in the other panel a file with the same name? name1 = ACTIVE_PANEL->func->files()->getUrl(ACTIVE_VIEW->getCurrentItem()); name2 = ACTIVE_PANEL->otherPanel()->func->files()->getUrl(ACTIVE_VIEW->getCurrentItem()); } else { // if we got here, then we can't be sure what file to diff KMessageBox::detailedError(0, i18n("Do not know which files to compare."), "" + i18n("To compare two files by content, you can either:
  • Select one file in the left panel, and one in the right panel.
  • Select exactly two files in the active panel.
  • Make sure there is a file in the other panel, with the same name as the current file in the active panel.
") + "
"); return; } // else implied: all ok, let's call an external program to compare files // but if any of the files isn't local, download it first compareContent(name1, name2); } bool downloadToTemp(const QUrl &url, QString &dest) { QTemporaryFile tmpFile; tmpFile.setAutoRemove(false); if (tmpFile.open()) { dest = tmpFile.fileName(); KIO::Job* job = KIO::file_copy(url, QUrl::fromLocalFile(dest), -1, KIO::Overwrite | KIO::HideProgressInfo); if(!job->exec()) { KMessageBox::error(krApp, i18n("Krusader is unable to download %1", url.fileName())); return false; } return true; } return false; } void KRslots::compareContent(QUrl url1, QUrl url2) { QString diffProg; QStringList lst = KrServices::supportedTools(); if (lst.contains("DIFF")) diffProg = lst[lst.indexOf("DIFF") + 1]; else { KMessageBox::error(0, i18n("Krusader cannot find any of the supported diff-frontends. Please install one to your path. Hint: Krusader supports Kompare, KDiff3 and Xxdiff.")); return; } QString tmp1; QString tmp2; // kdiff3 sucks with spaces if (QUrl::fromLocalFile(diffProg).fileName() == "kdiff3" && !url1.toDisplayString().contains(" ") && !url2.toDisplayString().contains(" ")) { tmp1 = url1.toDisplayString(); tmp2 = url2.toDisplayString(); } else { if (!url1.isLocalFile()) { if (!downloadToTemp(url1, tmp1)) { return; } } else tmp1 = url1.path(); if (!url2.isLocalFile()) { if (!downloadToTemp(url2, tmp2)) { if (tmp1 != url1.path()) QFile::remove(tmp1); return; } } else tmp2 = url2.path(); } KrProcess *p = new KrProcess(tmp1 != url1.path() ? tmp1 : QString(), tmp2 != url2.path() ? tmp2 : QString()); *p << diffProg << tmp1 << tmp2; p->start(); if (!p->waitForStarted()) KMessageBox::error(0, i18n("Error executing %1.", diffProg)); } // GUI toggle slots void KRslots::toggleFnkeys() { if (MAIN_VIEW->fnKeys()->isVisible()) MAIN_VIEW->fnKeys()->hide(); else MAIN_VIEW->fnKeys()->show(); } void KRslots::toggleCmdline() { if (MAIN_VIEW->cmdLine()->isVisible()) MAIN_VIEW->cmdLine()->hide(); else MAIN_VIEW->cmdLine()->show(); } void KRslots::updateStatusbarVisibility() { krApp->statusBar()->setVisible(KrActions::actShowStatusBar->isChecked()); } void KRslots::toggleTerminal() { MAIN_VIEW->setTerminalEmulator(KrActions::actToggleTerminal->isChecked()); } void KRslots::insertFileName(bool full_path) { QString filename = ACTIVE_VIEW->getCurrentItem(); if (filename.isEmpty()) { return; } if (full_path) { - QString path = vfs::ensureTrailingSlash(ACTIVE_FUNC->files()->currentDirectory()).toDisplayString(QUrl::PreferLocalFile); + QString path = FileSystem::ensureTrailingSlash(ACTIVE_FUNC->files()->currentDirectory()).toDisplayString(QUrl::PreferLocalFile); filename = path + filename; } filename = KrServices::quote(filename); if (MAIN_VIEW->cmdLine()->isVisible() || !MAIN_VIEW->terminalDock()->isTerminalVisible()) { QString current = MAIN_VIEW->cmdLine()->text(); if (current.length() != 0 && !current.endsWith(' ')) current += ' '; MAIN_VIEW->cmdLine()->setText(current + filename); MAIN_VIEW->cmdLine()->setFocus(); } else if (MAIN_VIEW->terminalDock()->isTerminalVisible()) { filename = QChar(' ') + filename + QChar(' '); MAIN_VIEW->terminalDock()->sendInput(filename, false); MAIN_VIEW->terminalDock()->setFocus(); } } void KRslots::refresh(const QUrl &u) { ACTIVE_FUNC->openUrl(u); } void KRslots::runKonfigurator(bool firstTime) { Konfigurator *konfigurator = new Konfigurator(firstTime); connect(konfigurator, SIGNAL(configChanged(bool)), SLOT(configChanged(bool))); //FIXME - no need to exec konfigurator->exec(); delete konfigurator; } void KRslots::configChanged(bool isGUIRestartNeeded) { krConfig->sync(); if (isGUIRestartNeeded) { krApp->setUpdatesEnabled(false); KConfigGroup group(krConfig, "Look&Feel"); - vfile::vfile_loadUserDefinedFolderIcons(group.readEntry("Load User Defined Folder Icons", _UserDefinedFolderIcons)); + FileItem::loadUserDefinedFolderIcons(group.readEntry("Load User Defined Folder Icons", _UserDefinedFolderIcons)); bool leftActive = ACTIVE_PANEL->gui->isLeft(); MAIN_VIEW->leftManager()->slotRecreatePanels(); MAIN_VIEW->rightManager()->slotRecreatePanels(); if(leftActive) LEFT_PANEL->slotFocusOnMe(); else RIGHT_PANEL->slotFocusOnMe(); MAIN_VIEW->fnKeys()->updateShortcuts(); KrSelectionMode::resetSelectionHandler(); krApp->setUpdatesEnabled(true); } // really ugly, but reload the Fn keys just in case - csaba: any better idea? MAIN_VIEW->fnKeys()->updateShortcuts(); bool showHidden = KConfigGroup(krConfig, "Look&Feel").readEntry("Show Hidden", KrActions::actToggleHidden->isChecked()); if (showHidden != KrActions::actToggleHidden->isChecked()) { KrActions::actToggleHidden->setChecked(showHidden); MAIN_VIEW->leftManager()->refreshAllTabs(); MAIN_VIEW->rightManager()->refreshAllTabs(); } } void KRslots::showHiddenFiles(bool show) { KConfigGroup group(krConfig, "Look&Feel"); group.writeEntry("Show Hidden", show); MAIN_VIEW->leftManager()->refreshAllTabs(); MAIN_VIEW->rightManager()->refreshAllTabs(); } void KRslots::swapPanels() { QUrl leftURL = LEFT_PANEL->func->files()->currentDirectory(); QUrl rightURL = RIGHT_PANEL->func->files()->currentDirectory(); LEFT_PANEL->func->openUrl(rightURL); RIGHT_PANEL->func->openUrl(leftURL); } void KRslots::toggleSwapSides() { MAIN_VIEW->swapSides(); } void KRslots::search() { if (KrSearchDialog::SearchDialog != 0) { KConfigGroup group(krConfig, "Search"); if (group.readEntry("Window Maximized", false)) KrSearchDialog::SearchDialog->showMaximized(); else KrSearchDialog::SearchDialog->showNormal(); KrSearchDialog::SearchDialog->raise(); KrSearchDialog::SearchDialog->activateWindow(); } else KrSearchDialog::SearchDialog = new KrSearchDialog(); } void KRslots::locate() { if (!KrServices::cmdExist("locate")) { KMessageBox::error(krApp, i18n("Cannot find the 'locate' command. Please install the " "findutils-locate package of GNU, or set its dependencies in " "Konfigurator")); return; } if (LocateDlg::LocateDialog != 0) { LocateDlg::LocateDialog->showNormal(); LocateDlg::LocateDialog->raise(); LocateDlg::LocateDialog->activateWindow(); LocateDlg::LocateDialog->reset(); } else LocateDlg::LocateDialog = new LocateDlg(); } void KRslots::runTerminal(const QString & dir) { KProcess proc; proc.setWorkingDirectory(dir); KConfigGroup group(krConfig, "General"); QString term = group.readEntry("Terminal", _Terminal); QStringList sepdArgs = KShell::splitArgs(term, KShell::TildeExpand); if (sepdArgs.isEmpty()) { KMessageBox::error(krMainWindow, i18nc("Arg is a string containing the bad quoting.", "Bad quoting in terminal command:\n%1", term)); return; } for (int i = 0; i < sepdArgs.size(); i++) { if (sepdArgs[i] == "%d") { sepdArgs[i] = dir; } } proc << sepdArgs; if (!proc.startDetached()) KMessageBox::sorry(krApp, i18n("Error executing %1.", term)); } void KRslots::homeTerminal() { runTerminal(QDir::homePath()); } void KRslots::multiRename() { QStringList lst = KrServices::supportedTools(); int i = lst.indexOf("RENAME"); if (i == -1) { KMessageBox::sorry(krApp, i18n("Cannot find a batch rename tool.\nYou can get KRename at http://www.krename.net")); return; } QString pathToRename = lst[i+1]; const QStringList names = ACTIVE_PANEL->gui->getSelectedNames(); if (names.isEmpty()) { return; } KProcess proc; proc << pathToRename; for (const QString name: names) { - vfile *file = ACTIVE_FUNC->files()->getVfile(name); + FileItem *file = ACTIVE_FUNC->files()->getFileItem(name); if (!file) continue; - const QUrl url = file->vfile_getUrl(); + const QUrl url = file->getUrl(); // KRename only supports the recursive option combined with a local directory path - if (file->vfile_isDir() && url.scheme() == "file") { + if (file->isDir() && url.scheme() == "file") { proc << "-r" << url.path(); } else { proc << url.toString(); } } if (!proc.startDetached()) KMessageBox::error(0, i18n("Error executing '%1'.", proc.program().join(" "))); } void KRslots::rootKrusader() { if (!KrServices::cmdExist("krusader") || !KrServices::cmdExist("kdesu")) { KMessageBox::sorry(krApp, i18n("Cannot start root mode Krusader, because Krusader or kdesu is missing from the path. Please configure the dependencies in Konfigurator.")); return; } KProcess proc; proc << KrServices::fullPathName("kdesu") << "-c" << KrServices::fullPathName("krusader") + " --left=" + KrServices::quote(LEFT_PANEL->func->files()->currentDirectory().toDisplayString(QUrl::PreferLocalFile)) + " --right=" + KrServices::quote(RIGHT_PANEL->func->files()->currentDirectory().toDisplayString(QUrl::PreferLocalFile)); if (!proc.startDetached()) KMessageBox::error(0, i18n("Error executing %1.", proc.program()[0])); } void KRslots::slotSplit() { const QStringList list = ACTIVE_PANEL->gui->getSelectedNames(); QString name; // first, see if we've got exactly 1 selected file, if not, try the current one if (list.count() == 1) name = list[0]; if (name.isEmpty()) { // if we got here, then one of the panel can't be sure what file to diff KMessageBox::error(0, i18n("Do not know which file to split.")); return; } QUrl fileURL = ACTIVE_FUNC->files()->getUrl(name); if (fileURL.isEmpty()) return; - if (ACTIVE_FUNC->files()->getVfile(name)->vfile_isDir()) { + if (ACTIVE_FUNC->files()->getFileItem(name)->isDir()) { KMessageBox::sorry(krApp, i18n("You cannot split a folder.")); return ; } QUrl destDir = ACTIVE_PANEL->otherPanel()->func->files()->currentDirectory(); SplitterGUI splitterGUI(MAIN_VIEW, fileURL, destDir); if (splitterGUI.exec() == QDialog::Accepted) { bool splitToOtherPanel = splitterGUI.getDestinationDir().matches(ACTIVE_PANEL->otherPanel()->virtualPath(), QUrl::StripTrailingSlash); Splitter split(MAIN_VIEW, fileURL, splitterGUI.getDestinationDir(), splitterGUI.overWriteFiles()); split.split(splitterGUI.getSplitSize()); if (splitToOtherPanel) ACTIVE_PANEL->otherPanel()->func->refresh(); } } void KRslots::slotCombine() { const QStringList list = ACTIVE_PANEL->gui->getSelectedNames(); if (list.isEmpty()) { KMessageBox::error(0, i18n("Do not know which files to combine.")); return; } QUrl baseURL; bool unixStyle = false; bool windowsStyle = false; QString commonName; int commonLength = 0; /* checking splitter names */ for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it) { QUrl url = ACTIVE_FUNC->files()->getUrl(*it); if (url.isEmpty()) return; - if (ACTIVE_FUNC->files()->getVfile(*it)->vfile_isDir()) { + if (ACTIVE_FUNC->files()->getFileItem(*it)->isDir()) { KMessageBox::sorry(krApp, i18n("You cannot combine a folder.")); return ; } if (!unixStyle) { QString name = url.fileName(); int extPos = name.lastIndexOf('.'); QString ext = name.mid(extPos + 1); name.truncate(extPos); url = url.adjusted(QUrl::RemoveFilename); url.setPath(url.path() + name); bool isExtInt; ext.toInt(&isExtInt, 10); if (extPos < 1 || ext.isEmpty() || (ext != "crc" && !isExtInt)) { if (windowsStyle) { KMessageBox::error(0, i18n("Not a split file: %1.", url.toDisplayString(QUrl::PreferLocalFile))); return; } unixStyle = true; } else { if (ext != "crc") windowsStyle = true; if (baseURL.isEmpty()) baseURL = url; else if (baseURL != url) { KMessageBox::error(0, i18n("Select only one split file.")); return; } } } if (unixStyle) { bool error = true; do { QString shortName = *it; QChar lastChar = shortName.at(shortName.length() - 1); if (lastChar.isLetter()) { char fillLetter = (lastChar.toUpper() == lastChar) ? 'A' : 'a'; if (commonName.isNull()) { commonLength = shortName.length(); commonName = shortName; while (commonName.length()) { QString shorter = commonName.left(commonName.length() - 1); QString testFile = shorter.leftJustified(commonLength, fillLetter); - if (ACTIVE_FUNC->files()->getVfile(testFile) == 0) + if (ACTIVE_FUNC->files()->getFileItem(testFile) == 0) break; else { commonName = shorter; baseURL = ACTIVE_FUNC->files()->currentDirectory().adjusted(QUrl::StripTrailingSlash); baseURL.setPath(baseURL.path() + '/' + (testFile)); } } error = (commonName == shortName); } else if (commonLength == shortName.length() && shortName.startsWith(commonName)) error = false; } } while (false); if (error) { KMessageBox::error(0, i18n("Not a split file: %1.", url.toDisplayString(QUrl::PreferLocalFile))); return; } } } // ask the user for the copy dest QUrl dest = KChooseDir::getDir(i18n("Combining %1.* to folder:", baseURL.toDisplayString(QUrl::PreferLocalFile)), ACTIVE_PANEL->otherPanel()->virtualPath(), ACTIVE_PANEL->virtualPath()); if (dest.isEmpty()) return ; // the user canceled bool combineToOtherPanel = (dest.matches(ACTIVE_PANEL->otherPanel()->virtualPath(), QUrl::StripTrailingSlash)); Combiner combine(MAIN_VIEW, baseURL, dest, unixStyle); combine.combine(); if (combineToOtherPanel) ACTIVE_PANEL->otherPanel()->func->refresh(); } void KRslots::manageUseractions() { ActionMan actionMan(MAIN_VIEW); } #ifdef SYNCHRONIZER_ENABLED void KRslots::slotSynchronizeDirs(QStringList selected) { new SynchronizerGUI(0, LEFT_PANEL->func->files()->currentDirectory(), RIGHT_PANEL->func->files()->currentDirectory(), selected); } #endif void KRslots::compareSetup() { for (int i = 0; KrActions::compareArray[i] != 0; i++) if ((*KrActions::compareArray[i])->isChecked()) { KConfigGroup group(krConfig, "Private"); group.writeEntry("Compare Mode", i); break; } } /** called by actions actExec* to choose the built-in command line mode */ void KRslots::execTypeSetup() { for (int i = 0; KrActions::execTypeArray[i] != 0; i++) if ((*KrActions::execTypeArray[i])->isChecked()) { if (*KrActions::execTypeArray[i] == KrActions::actExecTerminalEmbedded) { // if commands are to be executed in the TE, it must be loaded MAIN_VIEW->terminalDock()->initialise(); } KConfigGroup grp(krConfig, "Private"); grp.writeEntry("Command Execution Mode", i); break; } } void KRslots::slotDiskUsage() { DiskUsageGUI du(ACTIVE_FUNC->files()->currentDirectory(), MAIN_VIEW); } void KRslots::applicationStateChanged() { if (MAIN_VIEW == 0) { /* CRASH FIX: it's possible that the method is called after destroying the main view */ return; } if(qApp->applicationState() == Qt::ApplicationActive) { LEFT_PANEL->panelActive(); RIGHT_PANEL->panelActive(); } else { LEFT_PANEL->panelInactive(); RIGHT_PANEL->panelInactive(); } } void KRslots::emptyTrash() { KrTrashHandler::emptyTrash(); } #define OPEN_ID 100001 #define EMPTY_TRASH_ID 100002 void KRslots::trashPopupMenu() { QMenu trashMenu(krApp); QAction * act = trashMenu.addAction(krLoader->loadIcon("document-open", KIconLoader::Panel), i18n("Open trash bin")); act->setData(QVariant(OPEN_ID)); act = trashMenu.addAction(krLoader->loadIcon("trash-empty", KIconLoader::Panel), i18n("Empty trash bin")); act->setData(QVariant(EMPTY_TRASH_ID)); int result = -1; QAction *res = trashMenu.exec(QCursor::pos()); if (res && res->data().canConvert ()) result = res->data().toInt(); if (result == OPEN_ID) { ACTIVE_FUNC->openUrl(QUrl(QStringLiteral("trash:/"))); } else if (result == EMPTY_TRASH_ID) { KrTrashHandler::emptyTrash(); } } //shows the JavaScript-Console void KRslots::jsConsole() { #ifdef __KJSEMBED__ if (! krJS) krJS = new KrJS(); krJS->view()->show(); #endif } void KRslots::addBookmark() { krBookMan->bookmarkCurrent(ACTIVE_PANEL->virtualPath()); } void KRslots::cmdlinePopup() { MAIN_VIEW->cmdLine()->popup(); } diff --git a/krusader/krusader.cpp b/krusader/krusader.cpp index 7b2fd26a..d4e2d787 100644 --- a/krusader/krusader.cpp +++ b/krusader/krusader.cpp @@ -1,673 +1,673 @@ /*************************************************************************** krusader.cpp ------------------- copyright : (C) 2000 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "krusader.h" // QtCore #include #include #include #include // QtGui #include #include // QtWidgets #include #include #include // QtDBus #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "krusaderversion.h" #include "kicons.h" #include "krusaderview.h" #include "defaults.h" #include "krslots.h" #include "krservices.h" // This makes gcc-4.1 happy. Warning about possible problem with KrAction's dtor not called #include "krtrashhandler.h" #include "tabactions.h" #include "krglobal.h" #include "kractions.h" #include "panelmanager.h" #include "Panel/krcolorcache.h" #include "Panel/viewactions.h" #include "Panel/listpanelactions.h" #include "Panel/krpanel.h" #include "Panel/krview.h" #include "Panel/krviewfactory.h" #include "UserAction/kraction.h" #include "UserAction/expander.h" #include "UserAction/useraction.h" #include "Dialogs/popularurls.h" #include "Dialogs/checksumdlg.h" #include "Dialogs/krpleasewait.h" #include "GUI/krremoteencodingmenu.h" #include "GUI/kfnkeys.h" #include "GUI/kcmdline.h" #include "GUI/terminaldock.h" #include "GUI/krusaderstatus.h" -#include "VFS/vfile.h" -#include "VFS/krpermhandler.h" +#include "FileSystem/fileitem.h" +#include "FileSystem/krpermhandler.h" #include "MountMan/kmountman.h" #include "Konfigurator/kgprotocols.h" #include "BookMan/krbookmarkhandler.h" #include "KViewer/krviewer.h" #include "JobMan/jobman.h" #ifdef __KJSEMBED__ #include "KrJS/krjs.h" #endif // define the static members Krusader *Krusader::App = 0; QString Krusader::AppName; // KrBookmarkHandler *Krusader::bookman = 0; //QTextOStream *Krusader::_krOut = QTextOStream(::stdout); #ifdef __KJSEMBED__ KrJS *Krusader::js = 0; QAction *Krusader::actShowJSConsole = 0; #endif // construct the views, statusbar and menu bars and prepare Krusader to start Krusader::Krusader(const QCommandLineParser &parser) : KParts::MainWindow(0, Qt::Window | Qt::WindowTitleHint | Qt::WindowContextHelpButtonHint), _listPanelActions(0), isStarting(true), isExiting(false) { // create the "krusader" App = this; krMainWindow = this; SLOTS = new KRslots(this); setXMLFile("krusaderui.rc"); // kpart-related xml file plzWait = new KRPleaseWaitHandler(this); bool runKonfig = versionControl(); QString message; switch (krConfig->accessMode()) { case KConfigBase::NoAccess : message = "Krusader's configuration file can't be found. Default values will be used."; break; case KConfigBase::ReadOnly : message = "Krusader's configuration file is in READ ONLY mode (why is that!?) Changed values will not be saved"; break; case KConfigBase::ReadWrite : message = ""; break; } if (!message.isEmpty()) { KMessageBox::error(krApp, message); } // create an icon loader krLoader = KIconLoader::global(); // iconLoader->addExtraDesktopThemes(); // create MountMan KrGlobal::mountMan = new KMountMan(this); connect(KrGlobal::mountMan, SIGNAL(refreshPanel(const QUrl &)), SLOTS, SLOT(refresh(const QUrl &))); // create bookman krBookMan = new KrBookmarkHandler(this); // create job manager krJobMan = new JobMan(this); _popularUrls = new PopularUrls(this); // create the main view MAIN_VIEW = new KrusaderView(this); // setup all the krusader's actions setupActions(); // init the permmision handler class KRpermHandler::init(); // init the protocol handler KgProtocols::init(); // init the checksum tools initChecksumModule(); KConfigGroup gl(krConfig, "Look&Feel"); - vfile::vfile_loadUserDefinedFolderIcons(gl.readEntry("Load User Defined Folder Icons", + FileItem::loadUserDefinedFolderIcons(gl.readEntry("Load User Defined Folder Icons", _UserDefinedFolderIcons)); KConfigGroup gs(krConfig, "Startup"); QString startProfile = gs.readEntry("Starter Profile Name", QString()); QList leftTabs; QList rightTabs; // get command-line arguments if (parser.isSet("left")) { leftTabs = KrServices::toUrlList(parser.value("left").split(',')); startProfile.clear(); } if (parser.isSet("right")) { rightTabs = KrServices::toUrlList(parser.value("right").split(',')); startProfile.clear(); } if (parser.isSet("profile")) startProfile = parser.value("profile"); if (!startProfile.isEmpty()) { leftTabs.clear(); rightTabs.clear(); } // starting the panels MAIN_VIEW->start(gs, startProfile.isEmpty(), leftTabs, rightTabs); // create a status bar KrusaderStatus *status = new KrusaderStatus(this); setStatusBar(status); status->setWhatsThis(i18n("Statusbar will show basic information " "about file below mouse pointer.")); // create tray icon (even if not shown) sysTray = new QSystemTrayIcon(this); sysTray->setIcon(krLoader->loadIcon(privIcon(), KIconLoader::Panel, 22)); QMenu *trayMenu = new QMenu(this); trayMenu->addSection(QGuiApplication::applicationDisplayName()); // show "title" QAction *restoreAction = new QAction(i18n("Restore"), this); connect(restoreAction, SIGNAL(triggered()), SLOT(showFromTray())); trayMenu->addAction(restoreAction); trayMenu->addSeparator(); trayMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Quit))); sysTray->setContextMenu(trayMenu); // tray is only visible if main window is hidden, so action is always "show" connect(sysTray, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), SLOT(showFromTray())); setCentralWidget(MAIN_VIEW); // manage our keyboard short-cuts //KAcceleratorManager::manage(this,true); setCursor(Qt::ArrowCursor); if (! startProfile.isEmpty()) MAIN_VIEW->profiles(startProfile); // restore gui settings { // now, check if we need to create a konsole_part // call the XML GUI function to draw the UI createGUI(MAIN_VIEW->terminalDock()->part()); // this needs to be called AFTER createGUI() !!! updateUserActions(); _listPanelActions->guiUpdated(); // not using this. See savePosition() //applyMainWindowSettings(); const KConfigGroup cfgToolbar(krConfig, "Main Toolbar"); toolBar()->applySettings(cfgToolbar); const KConfigGroup cfgJobBar(krConfig, "Job Toolbar"); toolBar("jobToolBar")->applySettings(cfgJobBar); const KConfigGroup cfgActionsBar(krConfig, "Actions Toolbar"); toolBar("actionsToolBar")->applySettings(cfgActionsBar); // restore toolbars position and visibility const KConfigGroup cfgStartup(krConfig->group("Startup")); restoreState(cfgStartup.readEntry("State", QByteArray())); statusBar()->setVisible(cfgStartup.readEntry("Show status bar", _ShowStatusBar)); MAIN_VIEW->updateGUI(cfgStartup); // popular urls _popularUrls->load(); } if (runKonfig) SLOTS->runKonfigurator(true); KConfigGroup viewerModuleGrp(krConfig, "ViewerModule"); if (viewerModuleGrp.readEntry("FirstRun", true)) { KrViewer::configureDeps(); viewerModuleGrp.writeEntry("FirstRun", false); } if (!runKonfig) { KConfigGroup cfg(krConfig, "Private"); move(cfg.readEntry("Start Position", _StartPosition)); resize(cfg.readEntry("Start Size", _StartSize)); } // view initialized; show window or tray if (gs.readEntry("Start To Tray", _StartToTray)) { sysTray->show(); } else { show(); } KrTrashHandler::startWatcher(); isStarting = false; //HACK - used by [ListerTextArea|KrSearchDialog|LocateDlg]:keyPressEvent() KrGlobal::copyShortcut = _listPanelActions->actCopy->shortcut(); //HACK: make sure the active view becomes focused // for some reason sometimes the active view cannot be focused immediately at this point, // so queue it for the main loop QTimer::singleShot(0, ACTIVE_PANEL->view->widget(), SLOT(setFocus())); _openUrlTimer.setSingleShot(true); connect(&_openUrlTimer, SIGNAL(timeout()), SLOT(doOpenUrl())); KStartupInfo *startupInfo = new KStartupInfo(0, this); connect(startupInfo, &KStartupInfo::gotNewStartup, this, &Krusader::slotGotNewStartup); connect(startupInfo, &KStartupInfo::gotRemoveStartup, this, &Krusader::slotGotRemoveStartup); } Krusader::~Krusader() { KrTrashHandler::stopWatcher(); if (!isExiting) // save the settings if it was not saved (SIGTERM) saveSettings(); delete MAIN_VIEW; MAIN_VIEW = 0; App = 0; } bool Krusader::versionControl() { #define FIRST_RUN "First Time" bool retval = false; // create config file krConfig = KSharedConfig::openConfig().data(); KConfigGroup nogroup(krConfig, QString()); bool firstRun = nogroup.readEntry(FIRST_RUN, true); #if 0 QString oldVerText = nogroup.readEntry("Version", "10.0"); oldVerText.truncate(oldVerText.lastIndexOf(".")); // remove the third dot float oldVer = oldVerText.toFloat(); // older icompatible version if (oldVer <= 0.9) { KMessageBox::information(krApp, i18n("A configuration of 1.51 or older was detected. Krusader has to reset your configuration to default values.\nNote: your bookmarks and keybindings will remain intact.\nKrusader will now run Konfigurator.")); /*if ( !QDir::home().remove( ".kde/share/config/krusaderrc" ) ) { KMessageBox::error( krApp, i18n( "Unable to remove your krusaderrc file. Please remove it manually and rerun Krusader." ) ); exit( 1 ); }*/ retval = true; krConfig->reparseConfiguration(); } #endif // first installation of krusader if (firstRun) { KMessageBox::information(krApp, i18n("Welcome to Krusader.

As this is your first run, your machine will now be checked for external applications. Then the Konfigurator will be launched where you can customize Krusader to your needs.

")); retval = true; } nogroup.writeEntry("Version", VERSION); nogroup.writeEntry(FIRST_RUN, false); krConfig->sync(); QDir().mkpath(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/krusader/")); return retval; } void Krusader::statusBarUpdate(const QString& mess) { // change the message on the statusbar for 5 seconds if (statusBar()->isVisible()) statusBar()->showMessage(mess, 5000); } void Krusader::showFromTray() { setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); show(); sysTray->hide(); } void Krusader::changeEvent(QEvent *event) { QMainWindow::changeEvent(event); if (isExiting) return; // toggle tray when minimizing (if enabled) if(event->type() == QEvent::WindowStateChange) { if(isMinimized()) { KConfigGroup group(krConfig, "Look&Feel"); if (group.readEntry("Minimize To Tray", _MinimizeToTray)) { // TODO tray created again to prevent bug in kf5, // remove this if bug 365105 is resolved sysTray->deleteLater(); sysTray = new QSystemTrayIcon(this); sysTray->setIcon(krLoader->loadIcon(privIcon(), KIconLoader::Panel, 22)); QMenu *trayMenu = new QMenu(this); trayMenu->addSection(QGuiApplication::applicationDisplayName()); // show "title" QAction *restoreAction = new QAction(i18n("Restore"), this); connect(restoreAction, SIGNAL(triggered()), SLOT(showFromTray())); trayMenu->addAction(restoreAction); trayMenu->addSeparator(); trayMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Quit))); sysTray->setContextMenu(trayMenu); connect(sysTray, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), SLOT(showFromTray())); sysTray->show(); hide(); } } else if(isVisible()) { sysTray->hide(); } } } bool Krusader::event(QEvent *e) { if(e->type() == QEvent::ApplicationPaletteChange) { KrColorCache::getColorCache().refreshColors(); } return KParts::MainWindow::event(e); } // Moving from Pixmap actions to generic filenames - thanks to Carsten Pfeiffer void Krusader::setupActions() { QAction *bringToTopAct = new QAction(i18n("Bring Main Window to Top"), this); actionCollection()->addAction("bring_main_window_to_top", bringToTopAct); connect(bringToTopAct, SIGNAL(triggered()), SLOT(moveToTop())); KrActions::setupActions(this); _krActions = new KrActions(this); _viewActions = new ViewActions(this, this); _listPanelActions = new ListPanelActions(this, this); _tabActions = new TabActions(this, this); } /////////////////////////////////////////////////////////////////////////// //////////////////// implementation of slots ////////////////////////////// /////////////////////////////////////////////////////////////////////////// void Krusader::savePosition() { KConfigGroup cfg(krConfig, "Private"); cfg.writeEntry("Start Position", pos()); cfg.writeEntry("Start Size", size()); cfg = krConfig->group("Startup"); MAIN_VIEW->saveSettings(cfg); // NOTE: this would save current window state/size, statusbar and settings for each toolbar. // We are not using this and saving everything manually because // - it does not save window position // - window size save/restore does sometimes not work (multi-monitor setup) // - saving the statusbar visibility should be independent from window position and restoring it // does not work properly. //KConfigGroup cfg = KConfigGroup(&cfg, "MainWindowSettings"); //saveMainWindowSettings(cfg); //statusBar()->setVisible(cfg.readEntry("StatusBar", "Enabled") != "Disabled"); krConfig->sync(); } void Krusader::saveSettings() { // workaround: revert terminal fullscreen mode before saving widget and toolbar visibility if (MAIN_VIEW->isTerminalEmulatorFullscreen()) { MAIN_VIEW->setTerminalEmulator(false, true); } // save toolbar settings KConfigGroup cfg(krConfig, "Main Toolbar"); toolBar()->saveSettings(cfg); cfg = krConfig->group("Job Toolbar"); toolBar("jobToolBar")->saveSettings(cfg); cfg = krConfig->group("Actions Toolbar"); toolBar("actionsToolBar")->saveSettings(cfg); cfg = krConfig->group("Startup"); // save toolbar visibility and position cfg.writeEntry("State", saveState()); cfg.writeEntry("Show status bar", statusBar()->isVisible()); // save panel and window settings if (cfg.readEntry("Remember Position", _RememberPos)) savePosition(); // save the gui components visibility if (cfg.readEntry("UI Save Settings", _UiSave)) { cfg.writeEntry("Show FN Keys", KrActions::actToggleFnkeys->isChecked()); cfg.writeEntry("Show Cmd Line", KrActions::actToggleCmdline->isChecked()); cfg.writeEntry("Show Terminal Emulator", KrActions::actToggleTerminal->isChecked()); } // save popular links _popularUrls->save(); krConfig->sync(); } bool Krusader::queryClose() { if (isStarting || isExiting) return false; if (qApp->isSavingSession()) { // KDE is logging out, accept the close acceptClose(); return true; } const KConfigGroup cfg = krConfig->group("Look&Feel"); const bool confirmExit = cfg.readEntry("Warn On Exit", _WarnOnExit); // ask user and wait until all KIO::job operations are terminated. Krusader won't exit before // that anyway if (!krJobMan->waitForJobs(confirmExit)) return false; /* First try to close the child windows, because it's the safer way to avoid crashes, then close the main window. If closing a child is not successful, then we cannot let the main window close. */ for (;;) { QWidgetList list = QApplication::topLevelWidgets(); QWidget *activeModal = QApplication::activeModalWidget(); QWidget *w = list.at(0); if (activeModal && activeModal != this && activeModal != menuBar() && list.contains(activeModal) && !activeModal->isHidden()) { w = activeModal; } else { int i = 1; for (; i < list.count(); ++i) { w = list.at(i); if (!(w && (w == this || w->isHidden() || w == menuBar()))) break; } if (i == list.count()) w = 0; } if (!w) break; if (!w->close()) { if (w->inherits("QDialog")) { fprintf(stderr, "Failed to close: %s\n", w->metaObject()->className()); } return false; } } acceptClose(); return true; } void Krusader::acceptClose() { saveSettings(); emit shutdown(); // Removes the DBUS registration of the application. Single instance mode requires unique appid. // As Krusader is exiting, we release that unique appid, so new Krusader instances // can be started. QDBusConnection dbus = QDBusConnection::sessionBus(); dbus.unregisterObject("/Instances/" + Krusader::AppName); isExiting = true; // this will also kill the pending jobs } // the please wait dialog functions void Krusader::startWaiting(QString msg, int count , bool cancel) { plzWait->startWaiting(msg , count, cancel); } bool Krusader::wasWaitingCancelled() const { return plzWait->wasCancelled(); } void Krusader::stopWait() { plzWait->stopWait(); } void Krusader::updateUserActions() { KActionMenu *userActionMenu = (KActionMenu *) KrActions::actUserMenu; if (userActionMenu) { userActionMenu->menu()->clear(); userActionMenu->addAction(KrActions::actManageUseractions); userActionMenu->addSeparator(); krUserAction->populateMenu(userActionMenu, NULL); } } const char* Krusader::privIcon() { if (geteuid()) return "krusader_user"; else return "krusader_root"; } void Krusader::moveToTop() { if (isHidden()) show(); KWindowSystem::forceActiveWindow(winId()); } bool Krusader::isRunning() { moveToTop(); //FIXME - doesn't belong here return true; } bool Krusader::isLeftActive() { return MAIN_VIEW->isLeftActive(); } bool Krusader::openUrl(QString url) { _urlToOpen = url; _openUrlTimer.start(0); return true; } void Krusader::doOpenUrl() { QUrl url = QUrl::fromUserInput(_urlToOpen, QDir::currentPath(), QUrl::AssumeLocalFile); _urlToOpen.clear(); int tab = ACTIVE_MNG->findTab(url); if(tab >= 0) ACTIVE_MNG->setActiveTab(tab); else if((tab = OTHER_MNG->findTab(url)) >= 0) { OTHER_MNG->setActiveTab(tab); OTHER_MNG->currentPanel()->view->widget()->setFocus(); } else ACTIVE_MNG->slotNewTab(url); } void Krusader::slotGotNewStartup(const KStartupInfoId &id, const KStartupInfoData &data) { Q_UNUSED(id) Q_UNUSED(data) // This is here to show busy mouse cursor when _other_ applications are launched, not for krusader itself. qApp->setOverrideCursor(Qt::BusyCursor); } void Krusader::slotGotRemoveStartup(const KStartupInfoId &id, const KStartupInfoData &data) { Q_UNUSED(id) Q_UNUSED(data) qApp->restoreOverrideCursor(); } KrView *Krusader::activeView() { return ACTIVE_PANEL->view; } AbstractPanelManager *Krusader::activeManager() { return MAIN_VIEW->activeManager(); } AbstractPanelManager *Krusader::leftManager() { return MAIN_VIEW->leftManager(); } AbstractPanelManager *Krusader::rightManager() { return MAIN_VIEW->rightManager(); } diff --git a/krusader/layout.xml b/krusader/layout.xml index 634f1104..9c0328c3 100644 --- a/krusader/layout.xml +++ b/krusader/layout.xml @@ -1,90 +1,90 @@ - + - + - + diff --git a/krusader/panelmanager.cpp b/krusader/panelmanager.cpp index c6f1e15e..1c81161e 100644 --- a/krusader/panelmanager.cpp +++ b/krusader/panelmanager.cpp @@ -1,455 +1,455 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "panelmanager.h" #include "defaults.h" #include "tabactions.h" #include "krusaderview.h" #include "krmainwindow.h" #include "Panel/listpanel.h" #include "Panel/panelfunc.h" #include "Panel/krviewfactory.h" #include // QtGui #include // QtWidgets #include #include #include #include #include #include #define HIDE_ON_SINGLE_TAB false PanelManager::PanelManager(QWidget *parent, KrMainWindow* mainWindow, bool left) : QWidget(parent), _otherManager(0), _actions(mainWindow->tabActions()), _layout(0), _left(left), _self(0) { _layout = new QGridLayout(this); _layout->setContentsMargins(0, 0, 0, 0); _layout->setSpacing(0); _stack = new QStackedWidget(this); // new tab button _newTab = new QToolButton(this); _newTab->setAutoRaise(true); _newTab->setText(i18n("Open a new tab in home")); _newTab->setToolTip(i18n("Open a new tab in home")); _newTab->setIcon(SmallIcon("tab-new")); _newTab->adjustSize(); connect(_newTab, SIGNAL(clicked()), this, SLOT(slotNewTab())); // tab-bar _tabbar = new PanelTabBar(this, _actions); connect(_tabbar, SIGNAL(currentChanged(int)), this, SLOT(slotCurrentTabChanged(int))); connect(_tabbar, SIGNAL(tabCloseRequested(int)), this, SLOT(slotCloseTab(int))); connect(_tabbar, SIGNAL(closeCurrentTab()), this, SLOT(slotCloseTab())); connect(_tabbar, SIGNAL(newTab(const QUrl&)), this, SLOT(slotNewTab(const QUrl&))); connect(_tabbar, SIGNAL(draggingTab(QMouseEvent*)), this, SLOT(slotDraggingTab(QMouseEvent*))); connect(_tabbar, SIGNAL(draggingTabFinished(QMouseEvent*)), this, SLOT(slotDraggingTabFinished(QMouseEvent*))); QHBoxLayout *tabbarLayout = new QHBoxLayout; tabbarLayout->setSpacing(0); tabbarLayout->setContentsMargins(0, 0, 0, 0); tabbarLayout->addWidget(_tabbar); tabbarLayout->addWidget(_newTab); _layout->addWidget(_stack, 0, 0); _layout->addLayout(tabbarLayout, 1, 0); updateTabbarPos(); setLayout(_layout); addPanel(true); tabsCountChanged(); } void PanelManager::tabsCountChanged() { bool showTabbar = true; if (_tabbar->count() <= 1 && HIDE_ON_SINGLE_TAB) showTabbar = false; KConfigGroup cfg(krConfig, "Look&Feel"); bool showButtons = showTabbar && cfg.readEntry("Show Tab Buttons", true); _newTab->setVisible(showButtons); _tabbar->setVisible(showTabbar); // disable close button if only 1 tab is left _tabbar->setTabsClosable(showButtons && _tabbar->count() > 1); _actions->refreshActions(); } void PanelManager::activate() { assert(sender() == (currentPanel()->gui)); emit setActiveManager(this); _actions->refreshActions(); } void PanelManager::slotCurrentTabChanged(int index) // void PanelManager::slotChangePanel(ListPanel *p, bool makeActive) { ListPanel *p = _tabbar->getPanel(index); if (!p || p == _self) return; ListPanel *prev = _self; _self = p; _stack->setCurrentWidget(_self); if(prev) prev->slotFocusOnMe(false); //FIXME - necessary ? _self->slotFocusOnMe(this == ACTIVE_MNG); emit pathChanged(p); if(otherManager()) otherManager()->currentPanel()->otherPanelChanged(); } ListPanel* PanelManager::createPanel(KConfigGroup cfg) { ListPanel * p = new ListPanel(_stack, this, cfg); connectPanel(p); return p; } void PanelManager::connectPanel(ListPanel *p) { connect(p, &ListPanel::activate, this, &PanelManager::activate); connect(p, &ListPanel::pathChanged, this, [=]() { pathChanged(p); }); connect(p, &ListPanel::pathChanged, this, [=]() { _tabbar->updateTab(p); }); } void PanelManager::disconnectPanel(ListPanel *p) { disconnect(p, &ListPanel::activate, this, nullptr); disconnect(p, &ListPanel::pathChanged, this, nullptr); } ListPanel* PanelManager::addPanel(bool setCurrent, KConfigGroup cfg, KrPanel *nextTo) { // create the panel and add it into the widgetstack ListPanel * p = createPanel(cfg); _stack->addWidget(p); // now, create the corresponding tab int index = _tabbar->addPanel(p, setCurrent, nextTo); tabsCountChanged(); if (setCurrent) slotCurrentTabChanged(index); return p; } void PanelManager::saveSettings(KConfigGroup config, bool saveHistory) { config.writeEntry("ActiveTab", activeTab()); KConfigGroup grpTabs(&config, "Tabs"); foreach(QString grpTab, grpTabs.groupList()) grpTabs.deleteGroup(grpTab); for(int i = 0; i < _tabbar->count(); i++) { ListPanel *panel = _tabbar->getPanel(i); KConfigGroup grpTab(&grpTabs, "Tab" + QString::number(i)); panel->saveSettings(grpTab, saveHistory); } } void PanelManager::loadSettings(KConfigGroup config) { KConfigGroup grpTabs(&config, "Tabs"); int numTabsOld = _tabbar->count(); int numTabsNew = grpTabs.groupList().count(); for(int i = 0; i < numTabsNew; i++) { KConfigGroup grpTab(&grpTabs, "Tab" + QString::number(i)); // TODO workaround for bug 371453. Remove this when bug is fixed if (grpTab.keyList().isEmpty()) continue; ListPanel *panel = i < numTabsOld ? _tabbar->getPanel(i) : addPanel(false, grpTab); panel->restoreSettings(grpTab); } for(int i = numTabsOld - 1; i >= numTabsNew && i > 0; i--) slotCloseTab(i); setActiveTab(config.readEntry("ActiveTab", 0)); // this is needed so that all tab labels get updated layoutTabs(); } void PanelManager::layoutTabs() { // delayed url refreshes may be pending - // delay the layout too so it happens after them QTimer::singleShot(0, _tabbar, SLOT(layoutTabs())); } void PanelManager::moveTabToOtherSide() { if(tabCount() < 2) return; ListPanel *p; _tabbar->removeCurrentPanel(p); _stack->removeWidget(p); disconnectPanel(p); p->reparent(_otherManager->_stack, _otherManager); _otherManager->connectPanel(p); _otherManager->_stack->addWidget(p); _otherManager->_tabbar->addPanel(p, true); _otherManager->tabsCountChanged(); tabsCountChanged(); p->slotFocusOnMe(); } void PanelManager::slotNewTab(const QUrl &url, bool setCurrent, KrPanel *nextTo) { ListPanel *p = addPanel(setCurrent, KConfigGroup(), nextTo); if(nextTo && nextTo->gui) { // We duplicate tab settings by writing original settings to a temporary // group and making the new tab read settings from it. Duplicating // settings directly would add too much complexity. QString grpName = "PanelManager_" + QString::number(qApp->applicationPid()); krConfig->deleteGroup(grpName); // make sure the group is empty KConfigGroup cfg(krConfig, grpName); nextTo->gui->saveSettings(cfg, true); p->restoreSettings(cfg); krConfig->deleteGroup(grpName); } else p->start(url); } void PanelManager::slotNewTab() { slotNewTab(QUrl::fromLocalFile(QDir::home().absolutePath())); } void PanelManager::slotCloseTab() { slotCloseTab(_tabbar->currentIndex()); } void PanelManager::slotCloseTab(int index) { if (_tabbar->count() <= 1) /* if this is the last tab don't close it */ return ; ListPanel *oldp; // if (index == _tabbar->currentIndex()) // slotChangePanel(_tabbar->removeCurrentPanel(oldp), false); // else _tabbar->removePanel(index, oldp); //this automatically changes the current panel _stack->removeWidget(oldp); deletePanel(oldp); tabsCountChanged(); } void PanelManager::updateTabbarPos() { KConfigGroup group(krConfig, "Look&Feel"); if(group.readEntry("Tab Bar Position", "bottom") == "top") { _layout->addWidget(_stack, 2, 0); _tabbar->setShape(QTabBar::RoundedNorth); } else { _layout->addWidget(_stack, 0, 0); _tabbar->setShape(QTabBar::RoundedSouth); } } int PanelManager::activeTab() { return _tabbar->currentIndex(); } void PanelManager::setActiveTab(int index) { _tabbar->setCurrentIndex(index); } void PanelManager::slotRecreatePanels() { updateTabbarPos(); for (int i = 0; i != _tabbar->count(); i++) { QString grpName = "PanelManager_" + QString::number(qApp->applicationPid()); krConfig->deleteGroup(grpName); // make sure the group is empty KConfigGroup cfg(krConfig, grpName); ListPanel *oldPanel = _tabbar->getPanel(i); oldPanel->saveSettings(cfg, true); disconnect(oldPanel); ListPanel *newPanel = createPanel(cfg); _stack->insertWidget(i, newPanel); _tabbar->changePanel(i, newPanel); if (_self == oldPanel) { _self = newPanel; _stack->setCurrentWidget(_self); } _stack->removeWidget(oldPanel); deletePanel(oldPanel); newPanel->restoreSettings(cfg); _tabbar->updateTab(newPanel); krConfig->deleteGroup(grpName); } tabsCountChanged(); _self->slotFocusOnMe(this == ACTIVE_MNG); emit pathChanged(_self); } void PanelManager::slotNextTab() { int currTab = _tabbar->currentIndex(); int nextInd = (currTab == _tabbar->count() - 1 ? 0 : currTab + 1); _tabbar->setCurrentIndex(nextInd); } void PanelManager::slotPreviousTab() { int currTab = _tabbar->currentIndex(); int nextInd = (currTab == 0 ? _tabbar->count() - 1 : currTab - 1); _tabbar->setCurrentIndex(nextInd); } void PanelManager::refreshAllTabs() { int i = 0; while (i < _tabbar->count()) { ListPanel *panel = _tabbar->getPanel(i); if (panel && panel->func) { - vfs * vfs = panel->func->files(); - if (vfs) { - vfs->refresh(); + FileSystem *fileSystem = panel->func->files(); + if (fileSystem) { + fileSystem->refresh(); } } ++i; } } void PanelManager::deletePanel(ListPanel * p) { disconnect(p); if (p && p->func && p->func->files()) { p->func->files()->deleteLater(); } delete p; } void PanelManager::slotCloseInactiveTabs() { int i = 0; while (i < _tabbar->count()) { if (i == activeTab()) i++; else slotCloseTab(i); } } void PanelManager::slotCloseDuplicatedTabs() { int i = 0; while (i < _tabbar->count() - 1) { ListPanel * panel1 = _tabbar->getPanel(i); if (panel1 != 0) { for (int j = i + 1; j < _tabbar->count(); j++) { ListPanel * panel2 = _tabbar->getPanel(j); if (panel2 != 0 && panel1->virtualPath().matches(panel2->virtualPath(), QUrl::StripTrailingSlash)) { if (j == activeTab()) { slotCloseTab(i); i--; break; } else { slotCloseTab(j); j--; } } } } i++; } } int PanelManager::findTab(QUrl url) { url.setPath(QDir::cleanPath(url.path())); for(int i = 0; i < _tabbar->count(); i++) { if(_tabbar->getPanel(i)) { QUrl panelUrl = _tabbar->getPanel(i)->virtualPath(); panelUrl.setPath(QDir::cleanPath(panelUrl.path())); if(panelUrl.matches(url, QUrl::StripTrailingSlash)) return i; } } return -1; } void PanelManager::slotLockTab() { currentPanel()->gui->setLocked(!currentPanel()->gui->isLocked()); _actions->refreshActions(); } void PanelManager::newTabs(const QStringList& urls) { for(int i = 0; i < urls.count(); i++) slotNewTab(QUrl::fromUserInput(urls[i], QString(), QUrl::AssumeLocalFile)); } KrPanel *PanelManager::currentPanel() { return _self; }