diff --git a/iso/iso.cpp b/iso/iso.cpp index d166a5d1..39bec5e8 100644 --- a/iso/iso.cpp +++ b/iso/iso.cpp @@ -1,526 +1,526 @@ /***************************************************************************** * Copyright (C) 2000 David Faure * * Copyright (C) 2002 Szombathelyi György * * Copyright (C) 2003 Leo Savernik * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is heavily based on ktar from kdelibs * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "iso.h" #include // QtCore #include #include #include #include #include #include #include #include "libisofs/iso_fs.h" #include "kiso.h" #include "kisofile.h" #include "kisodirectory.h" using namespace KIO; extern "C" { int Q_DECL_EXPORT kdemain(int argc, char **argv) { //qDebug() << "Starting " << getpid() << endl; if (argc != 4) { fprintf(stderr, "Usage: kio_iso protocol domain-socket1 domain-socket2\n"); exit(-1); } kio_isoProtocol slave(argv[2], argv[3]); slave.dispatchLoop(); //qDebug() << "Done" << endl; return 0; } } // extern "C" typedef struct { char magic[8]; char uncompressed_len[4]; unsigned char header_size; unsigned char block_size; char reserved[2]; /* Reserved for future use, MBZ */ } compressed_file_header; static const unsigned char zisofs_magic[8] = { 0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07 }; kio_isoProtocol::kio_isoProtocol(const QByteArray &pool, const QByteArray &app) : SlaveBase("iso", pool, app) { //qDebug() << "kio_isoProtocol::kio_isoProtocol" << endl; - m_isoFile = 0L; + m_isoFile = nullptr; } kio_isoProtocol::~kio_isoProtocol() { delete m_isoFile; } bool kio_isoProtocol::checkNewFile(QString fullPath, QString & path, int startsec) { //qDebug() << "kio_isoProtocol::checkNewFile " << fullPath << " startsec: " << //startsec << endl; // Are we already looking at that file ? if (m_isoFile && startsec == m_isoFile->startSec() && m_isoFile->fileName() == fullPath.left(m_isoFile->fileName().length())) { // Has it changed ? QT_STATBUF statbuf; if (QT_STAT(QFile::encodeName(m_isoFile->fileName()), &statbuf) == 0) { if (m_mtime == statbuf.st_mtime) { path = fullPath.mid(m_isoFile->fileName().length()); //qDebug() << "kio_isoProtocol::checkNewFile returning " << path << endl; if(path.endsWith(DIR_SEPARATOR_CHAR)) { path.chop(1); } if(path.isEmpty()) { path = DIR_SEPARATOR_CHAR; } return true; } } } //qDebug() << "Need to open a new file" << endl; // Close previous file if (m_isoFile) { m_isoFile->close(); delete m_isoFile; - m_isoFile = 0L; + m_isoFile = nullptr; } // Find where the iso file is in the full path int pos = 0; QString isoFile; path.clear(); int len = fullPath.length(); if (len != 0 && fullPath[ len - 1 ] != DIR_SEPARATOR_CHAR) fullPath += DIR_SEPARATOR_CHAR; //qDebug() << "the full path is " << fullPath << endl; while ((pos = fullPath.indexOf(DIR_SEPARATOR_CHAR, pos + 1)) != -1) { QString tryPath = fullPath.left(pos); //qDebug() << fullPath << " trying " << tryPath << endl; QT_STATBUF statbuf; if (QT_LSTAT(QFile::encodeName(tryPath), &statbuf) == 0 && !S_ISDIR(statbuf.st_mode)) { bool isFile = true; if (S_ISLNK(statbuf.st_mode)) { char symDest[256]; memset(symDest, 0, 256); int endOfName = readlink(QFile::encodeName(tryPath), symDest, 256); if (endOfName != -1) { if (QDir(QString::fromLocal8Bit(symDest)).exists()) isFile = false; } } if (isFile) { isoFile = tryPath; m_mtime = statbuf.st_mtime; m_mode = statbuf.st_mode; path = fullPath.mid(pos + 1); //qDebug() << "fullPath=" << fullPath << " path=" << path << endl; if(path.endsWith(DIR_SEPARATOR_CHAR)) { path.chop(1); } if(path.isEmpty()) { path = DIR_SEPARATOR_CHAR; } //qDebug() << "Found. isoFile=" << isoFile << " path=" << path << endl; break; } } } if (isoFile.isEmpty()) { //qDebug() << "kio_isoProtocol::checkNewFile: not found" << endl; return false; } // Open new file //qDebug() << "Opening KIso on " << isoFile << endl; m_isoFile = new KIso(isoFile); m_isoFile->setStartSec(startsec); if (!m_isoFile->open(QIODevice::ReadOnly)) { //qDebug() << "Opening " << isoFile << " failed." << endl; delete m_isoFile; - m_isoFile = 0L; + m_isoFile = nullptr; return false; } return true; } void kio_isoProtocol::createUDSEntry(const KArchiveEntry * isoEntry, UDSEntry & entry) { entry.clear(); entry.insert(UDSEntry::UDS_NAME, isoEntry->name()); entry.insert(UDSEntry::UDS_FILE_TYPE, isoEntry->permissions() & S_IFMT); // keep file type only entry.insert(UDSEntry::UDS_ACCESS, isoEntry->permissions() & 07777); // keep permissions only if (isoEntry->isFile()) { long long si = ((KIsoFile *)isoEntry)->realsize(); if (!si) si = ((KIsoFile *)isoEntry)->size(); entry.insert(UDSEntry::UDS_SIZE, si); } else { entry.insert(UDSEntry::UDS_SIZE, 0L); } entry.insert(UDSEntry::UDS_USER, isoEntry->user()); entry.insert(UDSEntry::UDS_GROUP, isoEntry->group()); entry.insert((uint)UDSEntry::UDS_MODIFICATION_TIME, isoEntry->date().toTime_t()); entry.insert(UDSEntry::UDS_ACCESS_TIME, isoEntry->isFile() ? ((KIsoFile *)isoEntry)->adate() : ((KIsoDirectory *)isoEntry)->adate()); entry.insert(UDSEntry::UDS_CREATION_TIME, isoEntry->isFile() ? ((KIsoFile *)isoEntry)->cdate() : ((KIsoDirectory *)isoEntry)->cdate()); entry.insert(UDSEntry::UDS_LINK_DEST, isoEntry->symLinkTarget()); } void kio_isoProtocol::listDir(const QUrl &url) { //qDebug() << "kio_isoProtocol::listDir " << url.url() << endl; QString path; if (!checkNewFile(getPath(url), path, url.hasFragment() ? url.fragment(QUrl::FullyDecoded).toInt() : -1)) { QByteArray _path(QFile::encodeName(getPath(url))); //qDebug() << "Checking (stat) on " << _path << endl; QT_STATBUF buff; if (QT_STAT(_path.data(), &buff) == -1 || !S_ISDIR(buff.st_mode)) { error(KIO::ERR_DOES_NOT_EXIST, getPath(url)); return; } // It's a real dir -> redirect QUrl redir; redir.setPath(getPath(url)); if (url.hasFragment()) redir.setFragment(url.fragment(QUrl::FullyDecoded)); //qDebug() << "Ok, redirection to " << redir.url() << endl; redir.setScheme("file"); redirection(redir); finished(); // And let go of the iso file - for people who want to unmount a cdrom after that delete m_isoFile; - m_isoFile = 0L; + m_isoFile = nullptr; return; } if (path.isEmpty()) { QUrl redir(QStringLiteral("iso:/")); //qDebug() << "url.path()==" << getPath(url) << endl; if (url.hasFragment()) redir.setFragment(url.fragment(QUrl::FullyDecoded)); redir.setPath(getPath(url) + QString::fromLatin1(DIR_SEPARATOR)); //qDebug() << "kio_isoProtocol::listDir: redirection " << redir.url() << endl; redir.setScheme("file"); redirection(redir); finished(); return; } //qDebug() << "checkNewFile done" << endl; const KArchiveDirectory* root = m_isoFile->directory(); const KArchiveDirectory* dir; if (!path.isEmpty() && path != DIR_SEPARATOR) { //qDebug() << QString("Looking for entry %1").arg(path) << endl; const KArchiveEntry* e = root->entry(path); if (!e) { error(KIO::ERR_DOES_NOT_EXIST, path); return; } if (! e->isDirectory()) { error(KIO::ERR_IS_FILE, path); return; } dir = (KArchiveDirectory*)e; } else { dir = root; } QStringList l = dir->entries(); totalSize(l.count()); UDSEntry entry; QStringList::Iterator it = l.begin(); for (; it != l.end(); ++it) { //qDebug() << (*it) << endl; const KArchiveEntry* isoEntry = dir->entry((*it)); createUDSEntry(isoEntry, entry); listEntry(entry); } finished(); //qDebug() << "kio_isoProtocol::listDir done" << endl; } void kio_isoProtocol::stat(const QUrl &url) { QString path; UDSEntry entry; //qDebug() << "kio_isoProtocol::stat " << url.url() << endl; if (!checkNewFile(getPath(url), path, url.hasFragment() ? url.fragment(QUrl::FullyDecoded).toInt() : -1)) { // We may be looking at a real directory - this happens // when pressing up after being in the root of an archive QByteArray _path(QFile::encodeName(getPath(url))); //qDebug() << "kio_isoProtocol::stat (stat) on " << _path << endl; QT_STATBUF buff; if (QT_STAT(_path.data(), &buff) == -1 || !S_ISDIR(buff.st_mode)) { //qDebug() << "isdir=" << S_ISDIR(buff.st_mode) << " errno=" << strerror(errno) << endl; error(KIO::ERR_DOES_NOT_EXIST, getPath(url)); return; } // Real directory. Return just enough information for KRun to work entry.insert(UDSEntry::UDS_NAME, url.fileName()); //qDebug() << "kio_isoProtocol::stat returning name=" << url.fileName() << endl; entry.insert(UDSEntry::UDS_FILE_TYPE, buff.st_mode & S_IFMT); statEntry(entry); finished(); // And let go of the iso file - for people who want to unmount a cdrom after that delete m_isoFile; - m_isoFile = 0L; + m_isoFile = nullptr; return; } const KArchiveDirectory* root = m_isoFile->directory(); const KArchiveEntry* isoEntry; if (path.isEmpty()) { path = QString::fromLatin1(DIR_SEPARATOR); isoEntry = root; } else { isoEntry = root->entry(path); } if (!isoEntry) { error(KIO::ERR_DOES_NOT_EXIST, path); return; } createUDSEntry(isoEntry, entry); statEntry(entry); finished(); } void kio_isoProtocol::getFile(const KIsoFile *isoFileEntry, const QString &path) { unsigned long long size, pos = 0; bool mime = false, zlib = false; QByteArray fileData, pointer_block, inbuf, outbuf; - char *pptr = 0; + char *pptr = nullptr; compressed_file_header *hdr; int block_shift; unsigned long nblocks; unsigned long fullsize = 0, block_size = 0, block_size2 = 0; size_t ptrblock_bytes; unsigned long cstart, cend, csize; uLong bytes; size = isoFileEntry->realsize(); if (size >= sizeof(compressed_file_header)) zlib = true; if (!size) size = isoFileEntry->size(); totalSize(size); if (!size) mimeType("application/x-zerosize"); if (size && !m_isoFile->device()->isOpen()) { m_isoFile->device()->open(QIODevice::ReadOnly); // seek(0) ensures integrity with the QIODevice's built-in buffer // see bug #372023 for details m_isoFile->device()->seek(0); } if (zlib) { fileData = isoFileEntry->dataAt(0, sizeof(compressed_file_header)); if (fileData.size() == sizeof(compressed_file_header) && !memcmp(fileData.data(), zisofs_magic, sizeof(zisofs_magic))) { hdr = (compressed_file_header*) fileData.data(); block_shift = hdr->block_size; block_size = 1UL << block_shift; block_size2 = block_size << 1; fullsize = isonum_731(hdr->uncompressed_len); nblocks = (fullsize + block_size - 1) >> block_shift; ptrblock_bytes = (nblocks + 1) * 4; pointer_block = isoFileEntry->dataAt(hdr->header_size << 2, ptrblock_bytes); if ((unsigned long)pointer_block.size() == ptrblock_bytes) { inbuf.resize(block_size2); if (inbuf.size()) { outbuf.resize(block_size); if (outbuf.size()) pptr = pointer_block.data(); else { error(KIO::ERR_COULD_NOT_READ, path); return; } } else { error(KIO::ERR_COULD_NOT_READ, path); return; } } else { error(KIO::ERR_COULD_NOT_READ, path); return; } } else { zlib = false; } } while (pos < size) { if (zlib) { cstart = isonum_731(pptr); pptr += 4; cend = isonum_731(pptr); csize = cend - cstart; if (csize == 0) { outbuf.fill(0, -1); } else { if (csize > block_size2) { //err = EX_DATAERR; break; } inbuf = isoFileEntry->dataAt(cstart, csize); if ((unsigned long)inbuf.size() != csize) { break; } bytes = block_size; // Max output buffer size if ((uncompress((Bytef*) outbuf.data(), &bytes, (Bytef*) inbuf.data(), csize)) != Z_OK) { break; } } if (((fullsize > block_size) && (bytes != block_size)) || ((fullsize <= block_size) && (bytes < fullsize))) { break; } if (bytes > fullsize) bytes = fullsize; fileData = outbuf; fileData.resize(bytes); fullsize -= bytes; } else { fileData = isoFileEntry->dataAt(pos, 65536); if (fileData.size() == 0) break; } if (!mime) { QMimeDatabase db; QMimeType mt = db.mimeTypeForFileNameAndData(path, fileData); if (mt.isValid()) { //qDebug() << "Emitting mimetype " << mt.name() << endl; mimeType(mt.name()); mime = true; } } data(fileData); pos += fileData.size(); processedSize(pos); } if (pos != size) { error(KIO::ERR_COULD_NOT_READ, path); return; } fileData.resize(0); data(fileData); processedSize(pos); finished(); } void kio_isoProtocol::get(const QUrl &url) { //qDebug() << "kio_isoProtocol::get" << url.url() << endl; QString path; if (!checkNewFile(getPath(url), path, url.hasFragment() ? url.fragment(QUrl::FullyDecoded).toInt() : -1)) { error(KIO::ERR_DOES_NOT_EXIST, getPath(url)); return; } const KArchiveDirectory* root = m_isoFile->directory(); const KArchiveEntry* isoEntry = root->entry(path); if (!isoEntry) { error(KIO::ERR_DOES_NOT_EXIST, path); return; } if (isoEntry->isDirectory()) { error(KIO::ERR_IS_DIRECTORY, path); return; } - const KIsoFile* isoFileEntry = static_cast(isoEntry); + const auto* isoFileEntry = dynamic_cast(isoEntry); if (!isoEntry->symLinkTarget().isEmpty()) { //qDebug() << "Redirection to " << isoEntry->symLinkTarget() << endl; QUrl realURL = QUrl(url).resolved(QUrl(isoEntry->symLinkTarget())); //qDebug() << "realURL= " << realURL.url() << endl; realURL.setScheme("file"); redirection(realURL); finished(); return; } getFile(isoFileEntry, path); if (m_isoFile->device()->isOpen()) m_isoFile->device()->close(); } QString kio_isoProtocol::getPath(const QUrl &url) { QString path = url.path(); REPLACE_DIR_SEP2(path); #ifdef Q_WS_WIN if (path.startsWith(DIR_SEPARATOR)) { int p = 1; while (p < path.length() && path[ p ] == DIR_SEPARATOR_CHAR) p++; /* /C:/Folder */ if (p + 2 <= path.length() && path[ p ].isLetter() && path[ p + 1 ] == ':') { path = path.mid(p); } } #endif return path; } diff --git a/iso/kiso.cpp b/iso/kiso.cpp index 5c990225..545c7e44 100644 --- a/iso/kiso.cpp +++ b/iso/kiso.cpp @@ -1,521 +1,521 @@ /***************************************************************************** * Copyright (C) 2000 David Faure * * Copyright (C) 2002 Szombathelyi György * * Copyright (C) 2003 Leo Savernik * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is heavily based on ktar from kdelibs * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "kiso.h" // QtCore #include #include #include #include #include #include #include #include #include #include #include "libisofs/isofs.h" #include "qfilehack.h" #ifdef Q_OS_LINUX #undef __STRICT_ANSI__ #include #define __STRICT_ANSI__ #include #include #endif //////////////////////////////////////////////////////////////////////// /////////////////////////// KIso /////////////////////////////////// //////////////////////////////////////////////////////////////////////// /** * puts the track layout of the device 'fname' into 'tracks' * tracks structure: start sector, track number, ... * tracks should be 100*2 entry long (this is the maximum in the CD-ROM standard) * currently it's linux only, porters are welcome */ static int getTracks(const char *fname, int *tracks) { KRFUNC; int ret = 0; memset(tracks, 0, 200*sizeof(int)); #ifdef Q_OS_LINUX int fd, i; struct cdrom_tochdr tochead; struct cdrom_tocentry tocentry; //qDebug() << "getTracks open:" << fname << endl; fd = QT_OPEN(fname, O_RDONLY | O_NONBLOCK); if (fd > 0) { if (ioctl(fd, CDROMREADTOCHDR, &tochead) != -1) { // qDebug() << "getTracks first track:" << tochead.cdth_trk0 // << " last track " << tochead.cdth_trk1 << endl; for (i = tochead.cdth_trk0;i <= tochead.cdth_trk1;++i) { if (ret > 99) break; memset(&tocentry, 0, sizeof(struct cdrom_tocentry)); tocentry.cdte_track = i; tocentry.cdte_format = CDROM_LBA; if (ioctl(fd, CDROMREADTOCENTRY, &tocentry) < 0) break; // qDebug() << "getTracks got track " << i << " starting at: " << // tocentry.cdte_addr.lba << endl; if ((tocentry.cdte_ctrl & 0x4) == 0x4) { tracks[ret<<1] = tocentry.cdte_addr.lba; tracks[(ret<<1)+1] = i; ret++; } } } close(fd); } #endif return ret; } class KIso::KIsoPrivate { public: - KIsoPrivate() {} + KIsoPrivate() = default; QStringList dirList; }; KIso::KIso(const QString& filename, const QString & _mimetype) - : KArchive(0L) + : KArchive(nullptr) { KRFUNC; KRDEBUG("Starting KIso: " << filename << " - type: " << _mimetype); m_startsec = -1; m_filename = filename; d = new KIsoPrivate; QString mimetype(_mimetype); bool forced = true; if (mimetype.isEmpty()) { QMimeDatabase db; QMimeType mt = db.mimeTypeForFile(filename, QMimeDatabase::MatchContent); if (mt.isValid()) mimetype = mt.name(); //qDebug() << "KIso::KIso mimetype=" << mimetype << endl; // Don't move to prepareDevice - the other constructor theoretically allows ANY filter if (mimetype == "application/x-tgz" || mimetype == "application/x-targz" || // the latter is deprecated but might still be around mimetype == "application/x-webarchive") // that's a gzipped tar file, so ask for gzip filter mimetype = "application/x-gzip"; else if (mimetype == "application/x-tbz") // that's a bzipped2 tar file, so ask for bz2 filter mimetype = "application/x-bzip2"; else { // Something else. Check if it's not really gzip though (e.g. for KOffice docs) QFile file(filename); if (file.open(QIODevice::ReadOnly)) { char firstByte; char secondByte; char thirdByte; file.getChar(&firstByte); file.getChar(&secondByte); file.getChar(&thirdByte); if (firstByte == 0037 && secondByte == (char)0213) mimetype = "application/x-gzip"; else if (firstByte == 'B' && secondByte == 'Z' && thirdByte == 'h') mimetype = "application/x-bzip2"; else if (firstByte == 'P' && secondByte == 'K' && thirdByte == 3) { char fourthByte; file.getChar(&fourthByte); if (fourthByte == 4) mimetype = "application/x-zip"; } } } forced = false; } prepareDevice(filename, mimetype, forced); } void KIso::prepareDevice(const QString & filename, const QString & mimetype, bool forced) { KRFUNC; KRDEBUG("Preparing: " << filename << " - type: " << mimetype << " - using the force: " << forced); /* 'hack' for Qt's false assumption that only S_ISREG is seekable */ if ("inode/blockdevice" == mimetype) setDevice(new QFileHack(filename)); else { if ("application/x-gzip" == mimetype || "application/x-bzip2" == mimetype) forced = true; KCompressionDevice *device; if(mimetype.isEmpty()) { device = new KFilterDev(filename); } else { device = new KCompressionDevice(filename, KFilterDev::compressionTypeForMimeType(mimetype)); } if (device->compressionType() == KCompressionDevice::None && forced) { delete device; } else { setDevice(device); } } } KIso::KIso(QIODevice * dev) : KArchive(dev) { d = new KIsoPrivate; } KIso::~KIso() { // mjarrett: Closes to prevent ~KArchive from aborting w/o device if (isOpen()) close(); if (!m_filename.isEmpty()) delete device(); // we created it ourselves delete d; } /* callback function for libisofs */ static int readf(char *buf, unsigned int start, unsigned int len, void *udata) { KRFUNC; QIODevice* dev = (static_cast(udata))->device(); // seek(0) ensures integrity with the QIODevice's built-in buffer // see bug #372023 for details dev->seek(0); if (dev->seek((qint64)start << (qint64)11)) { if ((dev->read(buf, len << 11u)) != -1) return (len); } //qDebug() << "KIso::ReadRequest failed start: " << start << " len: " << len << endl; return -1; } /* callback function for libisofs */ static int mycallb(struct iso_directory_record *idr, void *udata) { KRFUNC; - KIso *iso = static_cast(udata); + auto *iso = static_cast(udata); QString path, user, group, symlink; int i; int access; int time, cdate, adate; rr_entry rr; bool special = false; - KArchiveEntry *entry = NULL, *oldentry = NULL; + KArchiveEntry *entry = nullptr, *oldentry = nullptr; char z_algo[2], z_params[2]; long long z_size = 0; if ((idr->flags[0] & 1) && !iso->showhidden) return 0; if (iso->level) { if (isonum_711(idr->name_len) == 1) { switch (idr->name[0]) { case 0: path += ("."); special = true; break; case 1: path += (".."); special = true; break; } } if (iso->showrr && ParseRR(idr, &rr) > 0) { if (!special) path = rr.name; symlink = rr.sl; access = rr.mode; time = rr.t_mtime; adate = rr.t_atime; cdate = rr.t_ctime; user.setNum(rr.uid); group.setNum(rr.gid); z_algo[0] = rr.z_algo[0];z_algo[1] = rr.z_algo[1]; z_params[0] = rr.z_params[0];z_params[1] = rr.z_params[1]; z_size = rr.z_size; } else { access = iso->dirent->permissions() & ~S_IFMT; adate = cdate = time = isodate_915(idr->date, 0); user = iso->dirent->user(); group = iso->dirent->group(); if (idr->flags[0] & 2) access |= S_IFDIR; else access |= S_IFREG; if (!special) { if (iso->joliet) { for (i = 0;i < (isonum_711(idr->name_len) - 1);i += 2) { void *p = &(idr->name[i]); QChar ch(be2me_16(*(ushort *)p)); if (ch == ';') break; path += ch; } } else { for (i = 0;i < isonum_711(idr->name_len);++i) { if (idr->name[i] == ';') break; if (idr->name[i]) path += (idr->name[i]); } } if (path.endsWith('.')) path.resize(path.length() - 1); } } if (iso->showrr) FreeRR(&rr); if (idr->flags[0] & 2) { entry = new KIsoDirectory(iso, path, access | S_IFDIR, time, adate, cdate, user, group, symlink); } else { entry = new KIsoFile(iso, path, access, time, adate, cdate, user, group, symlink, (long long)(isonum_733(idr->extent)) << (long long)11, isonum_733(idr->size)); - if (z_size)(static_cast (entry))->setZF(z_algo, z_params, z_size); + if (z_size)(dynamic_cast (entry))->setZF(z_algo, z_params, z_size); } iso->dirent->addEntry(entry); } if ((idr->flags[0] & 2) && (iso->level == 0 || !special)) { if (iso->level) { oldentry = iso->dirent; - iso->dirent = static_cast(entry); + iso->dirent = dynamic_cast(entry); } iso->level++; ProcessDir(&readf, isonum_733(idr->extent), isonum_733(idr->size), &mycallb, udata); iso->level--; - if (iso->level) iso->dirent = static_cast(oldentry); + if (iso->level) iso->dirent = dynamic_cast(oldentry); } return 0; } void KIso::addBoot(struct el_torito_boot_descriptor* bootdesc) { KRFUNC; int i; long long size; boot_head boot; boot_entry *be; QString path; KIsoFile *entry; path = "Catalog"; entry = new KIsoFile(this, path, dirent->permissions() & ~S_IFDIR, dirent->date(), dirent->adate(), dirent->cdate(), dirent->user(), dirent->group(), QString(), (long long)isonum_731(bootdesc->boot_catalog) << (long long)11, (long long)2048); dirent->addEntry(entry); if (!ReadBootTable(&readf, isonum_731(bootdesc->boot_catalog), &boot, this)) { i = 1; be = boot.defentry; while (be) { size = BootImageSize(isonum_711(be->data.d_e.media), isonum_721(be->data.d_e.seccount)); path = "Default Image"; if (i > 1) path += " (" + QString::number(i) + ')'; entry = new KIsoFile(this, path, dirent->permissions() & ~S_IFDIR, dirent->date(), dirent->adate(), dirent->cdate(), dirent->user(), dirent->group(), QString(), (long long)isonum_731(be->data.d_e.start) << (long long)11, size << (long long)9); dirent->addEntry(entry); be = be->next; i++; } FreeBootTable(&boot); } } void KIso::readParams() { KRFUNC; KConfig *config; config = new KConfig("kio_isorc"); KConfigGroup group(config, QString()); showhidden = group.readEntry("showhidden", false); showrr = group.readEntry("showrr", true); delete config; } bool KIso::openArchive(QIODevice::OpenMode mode) { KRFUNC; iso_vol_desc *desc; QString path, uid, gid; QT_STATBUF buf; int tracks[2*100], trackno = 0, i, access, c_b, c_i, c_j; KArchiveDirectory *root; struct iso_directory_record* idr; struct el_torito_boot_descriptor* bootdesc; if (mode == QIODevice::WriteOnly) return false; readParams(); d->dirList.clear(); tracks[0] = 0; if (m_startsec > 0) tracks[0] = m_startsec; //qDebug() << " m_startsec: " << m_startsec << endl; /* We'll use the permission and user/group of the 'host' file except * in Rock Ridge, where the permissions are stored on the file system */ if (QT_STAT(m_filename.toLocal8Bit(), &buf) < 0) { /* defaults, if stat fails */ memset(&buf, 0, sizeof(struct stat)); buf.st_mode = 0777; } else { /* If it's a block device, try to query the track layout (for multisession) */ if (m_startsec == -1 && S_ISBLK(buf.st_mode)) trackno = getTracks(m_filename.toLatin1(), (int*) & tracks); } uid.setNum(buf.st_uid); gid.setNum(buf.st_gid); access = buf.st_mode & ~S_IFMT; //qDebug() << "KIso::openArchive number of tracks: " << trackno << endl; if (trackno == 0) trackno = 1; for (i = 0;i < trackno;++i) { c_b = 1;c_i = 1;c_j = 1; root = rootDir(); if (trackno > 1) { path.clear(); QTextStream(&path) << "Track " << tracks[(i<<1)+1]; root = new KIsoDirectory(this, path, access | S_IFDIR, buf.st_mtime, buf.st_atime, buf.st_ctime, uid, gid, QString()); rootDir()->addEntry(root); } desc = ReadISO9660(&readf, tracks[i<<1], this); if (!desc) { //qDebug() << "KIso::openArchive no volume descriptors" << endl; continue; } while (desc) { switch (isonum_711(desc->data.type)) { case ISO_VD_BOOT: bootdesc = (struct el_torito_boot_descriptor*) & (desc->data); if (!memcmp(EL_TORITO_ID, bootdesc->system_id, ISODCL(8, 39))) { path = "El Torito Boot"; if (c_b > 1) path += " (" + QString::number(c_b) + ')'; dirent = new KIsoDirectory(this, path, access | S_IFDIR, buf.st_mtime, buf.st_atime, buf.st_ctime, uid, gid, QString()); root->addEntry(dirent); addBoot(bootdesc); c_b++; } break; case ISO_VD_PRIMARY: case ISO_VD_SUPPLEMENTARY: idr = (struct iso_directory_record*) & (((struct iso_primary_descriptor*) & desc->data)->root_directory_record); joliet = JolietLevel(&desc->data); if (joliet) { QTextStream(&path) << "Joliet level " << joliet; if (c_j > 1) path += " (" + QString::number(c_j) + ')'; } else { path = "ISO9660"; if (c_i > 1) path += " (" + QString::number(c_i) + ')'; } dirent = new KIsoDirectory(this, path, access | S_IFDIR, buf.st_mtime, buf.st_atime, buf.st_ctime, uid, gid, QString()); root->addEntry(dirent); level = 0; mycallb(idr, this); if (joliet) c_j++; else c_i++; break; } desc = desc->next; } free(desc); } device()->close(); return true; } bool KIso::closeArchive() { KRFUNC; d->dirList.clear(); return true; } bool KIso::writeDir(const QString&, const QString&, const QString&, mode_t, time_t, time_t, time_t) { return false; } bool KIso::prepareWriting(const QString&, const QString&, const QString&, qint64, mode_t, time_t, time_t, time_t) { return false; } bool KIso::finishWriting(qint64) { return false; } bool KIso::writeSymLink(const QString &, const QString &, const QString &, const QString &, mode_t, time_t, time_t, time_t) { return false; } bool KIso::doWriteDir(const QString&, const QString&, const QString&, mode_t, const QDateTime&, const QDateTime &, const QDateTime &) { return false; } bool KIso::doWriteSymLink(const QString &, const QString &, const QString &, const QString &, mode_t, const QDateTime&, const QDateTime&, const QDateTime&) { return false; } bool KIso::doPrepareWriting(const QString& , const QString& , const QString& , qint64, mode_t, const QDateTime&, const QDateTime&, const QDateTime&) { return false; } bool KIso::doFinishWriting(qint64) { return false; } void KIso::virtual_hook(int id, void* data) { KArchive::virtual_hook(id, data); } diff --git a/iso/kisodirectory.cpp b/iso/kisodirectory.cpp index 3c26f298..37e5fac9 100644 --- a/iso/kisodirectory.cpp +++ b/iso/kisodirectory.cpp @@ -1,36 +1,35 @@ /***************************************************************************** * Copyright (C) 2002 Szombathelyi György * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "kisodirectory.h" KIsoDirectory::KIsoDirectory(KArchive* archive, const QString& name, int access, int date, int adate, int cdate, const QString& user, const QString& group, const QString& symlink) : KArchiveDirectory(archive, name, access, QDateTime::fromTime_t(date), user, group, symlink) { m_adate = adate; m_cdate = cdate; } KIsoDirectory::~KIsoDirectory() -{ -} += default; diff --git a/iso/kisofile.cpp b/iso/kisofile.cpp index bed5afe2..584ea93d 100644 --- a/iso/kisofile.cpp +++ b/iso/kisofile.cpp @@ -1,61 +1,60 @@ /***************************************************************************** * Copyright (C) 2002 Szombathelyi György * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "kisofile.h" KIsoFile::KIsoFile(KArchive* archive, const QString& name, int access, int date, int adate, int cdate, const QString& user, const QString& group, const QString& symlink, long long pos, long long size) : KArchiveFile(archive, name, access, QDateTime::fromTime_t(date), user, group, symlink, pos, size) { m_adate = adate; m_cdate = cdate; m_algo[0] = 0;m_algo[1] = 0;m_parms[0] = 0;m_parms[1] = 0;m_realsize = 0; } KIsoFile::~KIsoFile() -{ -} += default; void KIsoFile::setZF(char algo[2], char parms[2], long long realsize) { m_algo[0] = algo[0];m_algo[1] = algo[1]; m_parms[0] = parms[0];m_parms[1] = parms[1]; m_realsize = realsize; } QByteArray KIsoFile::dataAt(long long pos, int count) const { QByteArray r; int rlen; if (archive()->device()->seek(position() + pos)) { r.resize(((pos + count) < size()) ? count : size() - pos); if (r.size()) { rlen = archive()->device()->read(r.data(), r.size()); if (rlen == - 1) r.resize(0); else if (rlen != (int)r.size()) r.resize(rlen); } } return r; } diff --git a/iso/qfilehack.cpp b/iso/qfilehack.cpp index 8fcebbd8..1d6b708b 100644 --- a/iso/qfilehack.cpp +++ b/iso/qfilehack.cpp @@ -1,47 +1,45 @@ /***************************************************************************** * Copyright (C) 2002 Szombathelyi György * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "qfilehack.h" QFileHack::QFileHack() -{ -} += default; QFileHack::QFileHack(const QString & name) : QFile(name) { } QFileHack::~QFileHack() -{ -} += default; bool QFileHack::open(QFile::OpenMode m) { bool ret; #ifdef Q_OS_UNIX // m |= IO_Async; // On linux, set O_NONBLOCK, opens CD-ROMs faster #endif ret = QFile::open(m); // if (ret && isSequential() ) { // setOpenMode(m | (QFile::OpenMode)IO_Direct); // } return ret; } diff --git a/krArc/krarc.cpp b/krArc/krarc.cpp index 5846c16d..747dddd4 100644 --- a/krArc/krarc.cpp +++ b/krArc/krarc.cpp @@ -1,1932 +1,1932 @@ /***************************************************************************** * Copyright (C) 2003 Rafi Yanai * * Copyright (C) 2003 Shie Erlich * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "krarc.h" #include "../krusader/defaults.h" // QtCore #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_IPC_SIZE (1024*32) #define TRIES_WITH_PASSWORDS 3 using namespace KIO; extern "C" { #ifdef KRARC_ENABLED /* This codec is for being able to handle files which encoding differs from the current locale. * * Unfortunately QProcess requires QString parameters for arguments which are encoded to Local8Bit * If we want to use unzip with ISO-8852-2 when the current locale is UTF-8, it will cause problems. * * Workaround: * 1. encode the QString to QByteArray ( according to the selected remote encoding, ISO-8852-2 ) * 2. encode QByteArray to QString again * unicode 0xE000-0xF7FF is for private use * the byte array is mapped to 0xE000-0xE0FF unicodes * 3. KrArcCodec maps 0xE000-0xE0FF to 0x0000-0x00FF, while calls the default encoding routine * for other unicodes. */ class KrArcCodec : public QTextCodec { public: KrArcCodec(QTextCodec * codec) : originalCodec(codec) {} - virtual ~KrArcCodec() {} + ~KrArcCodec() override = default; - virtual QByteArray name() const Q_DECL_OVERRIDE { + QByteArray name() const Q_DECL_OVERRIDE { return originalCodec->name(); } - virtual QList aliases() const Q_DECL_OVERRIDE { + QList aliases() const Q_DECL_OVERRIDE { return originalCodec->aliases(); } - virtual int mibEnum() const Q_DECL_OVERRIDE { + int mibEnum() const Q_DECL_OVERRIDE { return originalCodec->mibEnum(); } protected: - virtual QString convertToUnicode(const char *in, int length, ConverterState *state) const Q_DECL_OVERRIDE { + QString convertToUnicode(const char *in, int length, ConverterState *state) const Q_DECL_OVERRIDE { return originalCodec->toUnicode(in, length, state); } - virtual QByteArray convertFromUnicode(const QChar *in, int length, ConverterState *state) const Q_DECL_OVERRIDE { + QByteArray convertFromUnicode(const QChar *in, int length, ConverterState *state) const Q_DECL_OVERRIDE { // the QByteArray is embedded into the unicode charset (QProcess hell) QByteArray result; for (int i = 0; i != length; i++) { if (((in[ i ].unicode()) & 0xFF00) == 0xE000) // map 0xE000-0xE0FF to 0x0000-0x00FF result.append((char)(in[ i ].unicode() & 0xFF)); else result.append(originalCodec->fromUnicode(in + i, 1, state)); } return result; } private: QTextCodec * originalCodec; } *krArcCodec; #define SET_KRCODEC QTextCodec *origCodec = QTextCodec::codecForLocale(); \ QTextCodec::setCodecForLocale( krArcCodec ); #define RESET_KRCODEC QTextCodec::setCodecForLocale( origCodec ); #endif // KRARC_ENABLED class DummySlave : public KIO::SlaveBase { public: DummySlave(const QByteArray &pool_socket, const QByteArray &app_socket) : SlaveBase("kio_krarc", pool_socket, app_socket) { error((int)ERR_SLAVE_DEFINED, QString("krarc is disabled.")); } }; int Q_DECL_EXPORT kdemain(int argc, char **argv) { if (argc != 4) { qWarning() << "Usage: kio_krarc protocol domain-socket1 domain-socket2" << endl; exit(-1); } #ifdef KRARC_ENABLED kio_krarcProtocol slave(argv[2], argv[3]); #else DummySlave slave(argv[2], argv[3]); #endif slave.dispatchLoop(); return 0; } } // extern "C" #ifdef KRARC_ENABLED kio_krarcProtocol::kio_krarcProtocol(const QByteArray &pool_socket, const QByteArray &app_socket) - : SlaveBase("kio_krarc", pool_socket, app_socket), archiveChanged(true), arcFile(0L), extArcReady(false), - password(QString()), krConf("krusaderrc"), codec(0) + : SlaveBase("kio_krarc", pool_socket, app_socket), archiveChanged(true), arcFile(nullptr), extArcReady(false), + password(QString()), krConf("krusaderrc"), codec(nullptr) { KRFUNC; confGrp = KConfigGroup(&krConf, "Dependencies"); KConfigGroup group(&krConf, "General"); QString tmpDirPath = group.readEntry("Temp Directory", _TempDirectory); QDir tmpDir(tmpDirPath); if(!tmpDir.exists()) { for (int i = 1 ; i != -1 ; i = tmpDirPath.indexOf('/', i + 1)) QDir().mkdir(tmpDirPath.left(i)); QDir().mkdir(tmpDirPath); } arcTempDir = tmpDirPath + DIR_SEPARATOR; QString dirName = "krArc" + QDateTime::currentDateTime().toString(Qt::ISODate); dirName.replace(QRegExp(":"), "_"); tmpDir.mkdir(dirName); arcTempDir = arcTempDir + dirName + DIR_SEPARATOR; krArcCodec = new KrArcCodec(QTextCodec::codecForLocale()); } /* ---------------------------------------------------------------------------------- */ kio_krarcProtocol::~kio_krarcProtocol() { KRFUNC; // delete the temp directory KProcess proc; proc << fullPathName("rm") << "-rf" << arcTempDir; proc.start(); proc.waitForFinished(); } /* ---------------------------------------------------------------------------------- */ bool kio_krarcProtocol::checkWriteSupport() { KRFUNC; krConf.reparseConfiguration(); if (KConfigGroup(&krConf, "kio_krarc").readEntry("EnableWrite", false)) return true; else { error(ERR_UNSUPPORTED_ACTION, i18n("krarc: write support is disabled.\n" "You can enable it on the 'Archives' page in Konfigurator.")); return false; } } void kio_krarcProtocol::receivedData(KProcess *, QByteArray &d) { KRFUNC; - QByteArray buf(d); + const QByteArray& buf(d); data(buf); processedSize(d.length()); decompressedLen += d.length(); } void kio_krarcProtocol::mkdir(const QUrl &url, int permissions) { KRFUNC; const QString path = getPath(url); KRDEBUG(path); if (!checkWriteSupport()) return; // In case of KIO::mkpath call there is a mkdir call for every path element. // Therefore the path all the way up to our archive needs to be checked for existence // and reported as success. if (QDir().exists(path)) { finished(); return; } if (!setArcFile(url)) { error(ERR_CANNOT_ENTER_DIRECTORY, path); return; } if (newArchiveURL && !initDirDict(url)) { error(ERR_CANNOT_ENTER_DIRECTORY, path); return; } if (putCmd.isEmpty()) { error(ERR_UNSUPPORTED_ACTION, i18n("Creating directories is not supported with %1 archives", arcType)); return; } const QString arcFilePath = getPath(arcFile->url()); if (arcType == "arj" || arcType == "lha") { QString arcDir = path.mid(arcFilePath.length()); if (arcDir.right(1) != DIR_SEPARATOR) arcDir = arcDir + DIR_SEPARATOR; if (dirDict.find(arcDir) == dirDict.end()) addNewDir(arcDir); finished(); return; } QString arcDir = findArcDirectory(url); QString tempDir = arcDir.mid(1) + path.mid(path.lastIndexOf(DIR_SEPARATOR) + 1); if (tempDir.right(1) != DIR_SEPARATOR) tempDir = tempDir + DIR_SEPARATOR; if (permissions == -1) permissions = 0777; //set default permissions QByteArray arcTempDirEnc = arcTempDir.toLocal8Bit(); for (int i = 0;i < tempDir.length() && i >= 0; i = tempDir.indexOf(DIR_SEPARATOR, i + 1)) { QByteArray newDirs = encodeString(tempDir.left(i)); newDirs.prepend(arcTempDirEnc); QT_MKDIR(newDirs, permissions); } if (tempDir.endsWith(DIR_SEPARATOR)) tempDir.truncate(tempDir.length() - 1); // pack the directory KrLinecountingProcess proc; proc << putCmd << arcFilePath << localeEncodedString(tempDir); infoMessage(i18n("Creating %1...", url.fileName())); QDir::setCurrent(arcTempDir); SET_KRCODEC proc.start(); RESET_KRCODEC proc.waitForFinished(); // delete the temp directory QDir().rmdir(arcTempDir); if (proc.exitStatus() != QProcess::NormalExit || !checkStatus(proc.exitCode())) { error(ERR_COULD_NOT_WRITE, path + "\n\n" + proc.getErrorMsg()); return; } // force a refresh of archive information initDirDict(url, true); finished(); } void kio_krarcProtocol::put(const QUrl &url, int permissions, KIO::JobFlags flags) { KRFUNC; KRDEBUG(getPath(url)); if (!checkWriteSupport()) return; bool overwrite = !!(flags & KIO::Overwrite); bool resume = !!(flags & KIO::Resume); if (!setArcFile(url)) { error(ERR_CANNOT_ENTER_DIRECTORY, getPath(url)); return; } if (newArchiveURL && !initDirDict(url)) { error(ERR_CANNOT_ENTER_DIRECTORY, getPath(url)); return; } if (putCmd.isEmpty()) { error(ERR_UNSUPPORTED_ACTION, i18n("Writing to %1 archives is not supported", arcType)); return; } if (!overwrite && findFileEntry(url)) { error(ERR_FILE_ALREADY_EXIST, getPath(url)); return; } QString arcDir = findArcDirectory(url); if (arcDir.isEmpty()) KRDEBUG("arcDir is empty."); QString tempFile = arcDir.mid(1) + getPath(url).mid(getPath(url).lastIndexOf(DIR_SEPARATOR) + 1); QString tempDir = arcDir.mid(1); if (tempDir.right(1) != DIR_SEPARATOR) tempDir = tempDir + DIR_SEPARATOR; if (permissions == -1) permissions = 0777; //set default permissions QByteArray arcTempDirEnc = arcTempDir.toLocal8Bit(); for (int i = 0;i < tempDir.length() && i >= 0; i = tempDir.indexOf(DIR_SEPARATOR, i + 1)) { QByteArray newDirs = encodeString(tempDir.left(i)); newDirs.prepend(arcTempDirEnc); QT_MKDIR(newDirs, 0755); } int fd; if (resume) { QByteArray ba = encodeString(tempFile); ba.prepend(arcTempDirEnc); fd = QT_OPEN(ba, O_RDWR); // append if resuming QT_LSEEK(fd, 0, SEEK_END); // Seek to end } else { // WABA: Make sure that we keep writing permissions ourselves, // otherwise we can be in for a surprise on NFS. mode_t initialMode; if (permissions != -1) initialMode = permissions | S_IWUSR | S_IRUSR; else initialMode = 0666; QByteArray ba = encodeString(tempFile); ba.prepend(arcTempDirEnc); fd = QT_OPEN(ba, O_CREAT | O_TRUNC | O_WRONLY, initialMode); } QByteArray buffer; int readResult; bool isIncomplete = false; do { dataReq(); readResult = readData(buffer); auto bytesWritten = ::write(fd, buffer.data(), buffer.size()); if (bytesWritten < buffer.size()) { isIncomplete = true; break; } } while (readResult > 0); ::close(fd); if (isIncomplete) { error(ERR_COULD_NOT_WRITE, getPath(url)); return; } // pack the file KrLinecountingProcess proc; proc << putCmd << getPath(arcFile->url()) << localeEncodedString(tempFile); infoMessage(i18n("Packing %1...", url.fileName())); QDir::setCurrent(arcTempDir); SET_KRCODEC proc.start(); RESET_KRCODEC proc.waitForFinished(); // remove the files QDir().rmdir(arcTempDir); if (proc.exitStatus() != QProcess::NormalExit || !checkStatus(proc.exitCode())) { error(ERR_COULD_NOT_WRITE, getPath(url) + "\n\n" + proc.getErrorMsg()); return; } // force a refresh of archive information initDirDict(url, true); finished(); } void kio_krarcProtocol::get(const QUrl &url) { KRFUNC; get(url, TRIES_WITH_PASSWORDS); } void kio_krarcProtocol::get(const QUrl &url, int tries) { KRFUNC; KRDEBUG(getPath(url)); bool decompressToFile = false; if (!setArcFile(url)) { error(ERR_CANNOT_ENTER_DIRECTORY, getPath(url)); return; } if (newArchiveURL && !initDirDict(url)) { error(ERR_CANNOT_ENTER_DIRECTORY, getPath(url)); return; } if (getCmd.isEmpty()) { error(ERR_UNSUPPORTED_ACTION, i18n("Retrieving data from %1 archives is not supported", arcType)); return; } UDSEntry* entry = findFileEntry(url); if (!entry) { error(KIO::ERR_DOES_NOT_EXIST, getPath(url)); return; } if (KFileItem(*entry, url).isDir()) { error(KIO::ERR_IS_DIRECTORY, getPath(url)); return; } KIO::filesize_t expectedSize = KFileItem(*entry, url).size(); // for RPM files extract the cpio file first if (!extArcReady && arcType == "rpm") { KrLinecountingProcess cpio; cpio << "rpm2cpio" << getPath(arcFile->url(), QUrl::StripTrailingSlash); cpio.setStandardOutputFile(arcTempDir + "contents.cpio"); cpio.start(); cpio.waitForFinished(); if (cpio.exitStatus() != QProcess::NormalExit || !checkStatus(cpio.exitCode())) { error(ERR_COULD_NOT_READ, getPath(url) + "\n\n" + cpio.getErrorMsg()); return; } extArcReady = true; } // for DEB files extract the tar file first if (!extArcReady && arcType == "deb") { KrLinecountingProcess dpkg; dpkg << cmd << "--fsys-tarfile" << getPath(arcFile->url(), QUrl::StripTrailingSlash); dpkg.setStandardOutputFile(arcTempDir + "contents.cpio"); dpkg.start(); dpkg.waitForFinished(); if (dpkg.exitStatus() != QProcess::NormalExit || !checkStatus(dpkg.exitCode())) { error(ERR_COULD_NOT_READ, getPath(url) + "\n\n" + dpkg.getErrorMsg()); return; } extArcReady = true; } // Use the external unpacker to unpack the file QString file = getPath(url).mid(getPath(arcFile->url()).length() + 1); KrLinecountingProcess proc; if (extArcReady) { proc << getCmd << arcTempDir + "contents.cpio" << '*' + localeEncodedString(file); } else if (arcType == "arj" || arcType == "ace" || arcType == "7z") { proc << getCmd << getPath(arcFile->url(), QUrl::StripTrailingSlash) << localeEncodedString(file); if (arcType == "ace" && QFile("/dev/ptmx").exists()) // Don't remove, unace crashes if missing!!! proc.setStandardInputFile("/dev/ptmx"); file = url.fileName(); decompressToFile = true; } else { decompressedLen = 0; // Determine the mimetype of the file to be retrieved, and emit it. // This is mandatory in all slaves (for KRun/BrowserRun to work). QMimeDatabase db; QMimeType mt = db.mimeTypeForFile(arcTempDir + file); if (mt.isValid()) emit mimeType(mt.name()); QString escapedFilename = file; if(arcType == "zip") // left bracket needs to be escaped escapedFilename.replace('[', "[[]"); proc << getCmd << getPath(arcFile->url()); if (arcType != "gzip" && arcType != "bzip2" && arcType != "lzma" && arcType != "xz") proc << localeEncodedString(escapedFilename); connect(&proc, &KrLinecountingProcess::newOutputData, this, &kio_krarcProtocol::receivedData); proc.setMerge(false); } infoMessage(i18n("Unpacking %1...", url.fileName())); // change the working directory to our arcTempDir QDir::setCurrent(arcTempDir); SET_KRCODEC proc.setTextModeEnabled(false); proc.start(); RESET_KRCODEC proc.waitForFinished(); if (!extArcReady && !decompressToFile) { if (proc.exitStatus() != QProcess::NormalExit || !checkStatus(proc.exitCode()) || (arcType != "bzip2" && arcType != "lzma" && arcType != "xz" && expectedSize != decompressedLen)) { if (encrypted && tries) { invalidatePassword(); get(url, tries - 1); return; } error(KIO::ERR_ACCESS_DENIED, getPath(url) + "\n\n" + proc.getErrorMsg()); return; } } else { if (proc.exitStatus() != QProcess::NormalExit || !checkStatus(proc.exitCode()) || !QFileInfo(arcTempDir + file).exists()) { if (decompressToFile) QFile(arcTempDir + file).remove(); if (encrypted && tries) { invalidatePassword(); get(url, tries - 1); return; } error(KIO::ERR_ACCESS_DENIED, getPath(url)); return; } // the following block is ripped from KDE file KIO::Slave // $Id: krarc.cpp,v 1.43 2007/01/13 13:39:51 ckarai Exp $ QByteArray _path(QFile::encodeName(arcTempDir + file)); QT_STATBUF buff; if (QT_LSTAT(_path.data(), &buff) == -1) { if (errno == EACCES) error(KIO::ERR_ACCESS_DENIED, getPath(url)); else error(KIO::ERR_DOES_NOT_EXIST, getPath(url)); return; } if (S_ISDIR(buff.st_mode)) { error(KIO::ERR_IS_DIRECTORY, getPath(url)); return; } if (!S_ISREG(buff.st_mode)) { error(KIO::ERR_CANNOT_OPEN_FOR_READING, getPath(url)); return; } int fd = QT_OPEN(_path.data(), O_RDONLY); if (fd < 0) { error(KIO::ERR_CANNOT_OPEN_FOR_READING, getPath(url)); return; } // Determine the mimetype of the file to be retrieved, and emit it. // This is mandatory in all slaves (for KRun/BrowserRun to work). QMimeDatabase db; QMimeType mt = db.mimeTypeForFile(arcTempDir + file); if (mt.isValid()) emit mimeType(mt.name()); KIO::filesize_t processed_size = 0; QString resumeOffset = metaData("resume"); if (!resumeOffset.isEmpty()) { bool ok; KIO::fileoffset_t offset = resumeOffset.toLongLong(&ok); if (ok && (offset > 0) && (offset < buff.st_size)) { if (QT_LSEEK(fd, offset, SEEK_SET) == offset) { canResume(); processed_size = offset; } } } totalSize(buff.st_size); char buffer[ MAX_IPC_SIZE ]; while (1) { int n = ::read(fd, buffer, MAX_IPC_SIZE); if (n == -1) { if (errno == EINTR) continue; error(KIO::ERR_COULD_NOT_READ, getPath(url)); ::close(fd); return; } if (n == 0) break; // Finished { QByteArray array = QByteArray::fromRawData(buffer, n); data(array); } processed_size += n; } data(QByteArray()); ::close(fd); processedSize(buff.st_size); finished(); if (decompressToFile) QFile(arcTempDir + file).remove(); return; } // send empty buffer to mark EOF data(QByteArray()); finished(); } void kio_krarcProtocol::del(QUrl const & url, bool isFile) { KRFUNC; KRDEBUG(getPath(url)); if (!checkWriteSupport()) return; if (!setArcFile(url)) { error(ERR_CANNOT_ENTER_DIRECTORY, getPath(url)); return; } if (newArchiveURL && !initDirDict(url)) { error(ERR_CANNOT_ENTER_DIRECTORY, getPath(url)); return; } if (delCmd.isEmpty()) { error(ERR_UNSUPPORTED_ACTION, i18n("Deleting files from %1 archives is not supported", arcType)); return; } if (!findFileEntry(url)) { if ((arcType != "arj" && arcType != "lha") || isFile) { error(KIO::ERR_DOES_NOT_EXIST, getPath(url)); return; } } QString file = getPath(url).mid(getPath(arcFile->url()).length() + 1); if (!isFile && file.right(1) != DIR_SEPARATOR) { if (arcType == "zip") file = file + DIR_SEPARATOR; } KrLinecountingProcess proc; proc << delCmd << getPath(arcFile->url()) << localeEncodedString(file); infoMessage(i18n("Deleting %1...", url.fileName())); SET_KRCODEC proc.start(); RESET_KRCODEC proc.waitForFinished(); if (proc.exitStatus() != QProcess::NormalExit || !checkStatus(proc.exitCode())) { error(ERR_COULD_NOT_WRITE, getPath(url) + "\n\n" + proc.getErrorMsg()); return; } // force a refresh of archive information initDirDict(url, true); finished(); } void kio_krarcProtocol::stat(const QUrl &url) { KRFUNC; KRDEBUG(getPath(url)); if (!setArcFile(url)) { error(ERR_CANNOT_ENTER_DIRECTORY, getPath(url)); return; } if (newArchiveURL && !initDirDict(url)) { error(ERR_CANNOT_ENTER_DIRECTORY, getPath(url)); return; } if (listCmd.isEmpty()) { error(ERR_UNSUPPORTED_ACTION, i18n("Accessing files is not supported with %1 archives", arcType)); return; } QString path = getPath(url, QUrl::StripTrailingSlash); QUrl newUrl = url; // but treat the archive itself as the archive root if (path == getPath(arcFile->url(), QUrl::StripTrailingSlash)) { newUrl.setPath(path + DIR_SEPARATOR); path = getPath(newUrl); } // we might be stating a real file if (QFileInfo(path).exists()) { QT_STATBUF buff; QT_STAT(path.toLocal8Bit(), &buff); QString mime; QMimeDatabase db; QMimeType result = db.mimeTypeForFile(path); if (result.isValid()) mime = result.name(); statEntry(KFileItem(QUrl::fromLocalFile(path), mime, buff.st_mode).entry()); finished(); return; } UDSEntry* entry = findFileEntry(newUrl); if (entry) { statEntry(*entry); finished(); } else error(KIO::ERR_DOES_NOT_EXIST, path); } void kio_krarcProtocol::copy(const QUrl &url, const QUrl &dest, int, KIO::JobFlags flags) { KRDEBUG("source: " << url.path() << " dest: " << dest.path()); if (!checkWriteSupport()) return; bool overwrite = !!(flags & KIO::Overwrite); // KDE HACK: opening the password dlg in copy causes error for the COPY, and further problems // that's why encrypted files are not allowed to copy if (!encrypted && dest.isLocalFile()) do { if (url.fileName() != dest.fileName()) break; if (QTextCodec::codecForLocale()->name() != codec->name()) break; //the file exists and we don't want to overwrite if ((!overwrite) && (QFile(getPath(dest)).exists())) { error((int)ERR_FILE_ALREADY_EXIST, QString(QFile::encodeName(getPath(dest)))); return; }; if (!setArcFile(url)) { error(ERR_CANNOT_ENTER_DIRECTORY, getPath(url)); return; } if (newArchiveURL && !initDirDict(url)) { error(ERR_CANNOT_ENTER_DIRECTORY, getPath(url)); return; } UDSEntry* entry = findFileEntry(url); if (copyCmd.isEmpty() || !entry) break; QString file = getPath(url).mid(getPath(arcFile->url()).length() + 1); QString destDir = getPath(dest, QUrl::StripTrailingSlash); if (!QDir(destDir).exists()) { int ndx = destDir.lastIndexOf(DIR_SEPARATOR_CHAR); if (ndx != -1) destDir.truncate(ndx + 1); } QDir::setCurrent(destDir); QString escapedFilename = file; if(arcType == "zip") { // left bracket needs to be escaped escapedFilename.replace('[', "[[]"); } KrLinecountingProcess proc; proc << copyCmd << getPath(arcFile->url(), QUrl::StripTrailingSlash) << escapedFilename; if (arcType == "ace" && QFile("/dev/ptmx").exists()) // Don't remove, unace crashes if missing!!! proc.setStandardInputFile("/dev/ptmx"); proc.setOutputChannelMode(KProcess::SeparateChannels); // without this output redirection has no effect infoMessage(i18n("Unpacking %1...", url.fileName())); proc.start(); proc.waitForFinished(); if (proc.exitStatus() != QProcess::NormalExit || !checkStatus(proc.exitCode())) { error(KIO::ERR_COULD_NOT_WRITE, getPath(dest, QUrl::StripTrailingSlash) + "\n\n" + proc.getErrorMsg()); return; } if (!QFileInfo(getPath(dest, QUrl::StripTrailingSlash)).exists()) { error(KIO::ERR_COULD_NOT_WRITE, getPath(dest, QUrl::StripTrailingSlash)); return; } processedSize(KFileItem(*entry, url).size()); finished(); QDir::setCurrent(QDir::rootPath()); /* for being able to umount devices after copying*/ return; } while (0); if (encrypted) KRDEBUG("ERROR: " << url.path() << " is encrypted."); if (!dest.isLocalFile()) KRDEBUG("ERROR: " << url.path() << " is not a local file."); // CMD_COPY is no more in KF5 - replaced with 74 value (as stated in kio/src/core/commands_p.h, which could be found in cgit.kde.org/kio.git/tree) error(ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(mProtocol, 74)); } void kio_krarcProtocol::rename(const QUrl& src, const QUrl& dest, KIO::JobFlags flags) { Q_UNUSED(flags); KRDEBUG("renaming from: " << src.path() << " to: " << dest.path()); KRDEBUG("command: " << arcPath); if (!checkWriteSupport()) { return; } if (renCmd.isEmpty()) { error(KIO::ERR_CANNOT_RENAME, src.fileName()); return; } if (src.fileName() == dest.fileName()) { return; } KrLinecountingProcess proc; proc << renCmd << arcPath << src.path().remove(arcPath + '/') << dest.path().remove(arcPath + '/'); proc.start(); proc.waitForFinished(); if (proc.exitStatus() != QProcess::NormalExit || !checkStatus(proc.exitCode())) { error(KIO::ERR_CANNOT_RENAME, src.fileName()); return; } finished(); } void kio_krarcProtocol::listDir(const QUrl &url) { KRFUNC; KRDEBUG(getPath(url)); if (!setArcFile(url)) { error(ERR_CANNOT_ENTER_DIRECTORY, getPath(url)); return; } if (listCmd.isEmpty()) { error(ERR_UNSUPPORTED_ACTION, i18n("Listing directories is not supported for %1 archives", arcType)); return; } QString path = getPath(url); if (path.right(1) != DIR_SEPARATOR) path = path + DIR_SEPARATOR; // it might be a real dir ! if (QFileInfo(path).exists()) { if (QFileInfo(path).isDir()) { QUrl redir; redir.setPath(getPath(url)); redirection(redir); finished(); } else { // maybe it's an archive ! error(ERR_IS_FILE, path); } return; } if (!initDirDict(url)) { error(ERR_CANNOT_ENTER_DIRECTORY, getPath(url)); return; } QString arcDir = path.mid(getPath(arcFile->url()).length()); arcDir.truncate(arcDir.lastIndexOf(DIR_SEPARATOR)); if (arcDir.right(1) != DIR_SEPARATOR) arcDir = arcDir + DIR_SEPARATOR; if (dirDict.find(arcDir) == dirDict.end()) { error(ERR_CANNOT_ENTER_DIRECTORY, getPath(url)); return; } UDSEntryList* dirList = dirDict[ arcDir ]; totalSize(dirList->size()); listEntries(*dirList); finished(); } bool kio_krarcProtocol::setArcFile(const QUrl &url) { KRFUNC; KRDEBUG(url.fileName()); QString path = getPath(url); - time_t currTime = time(0); + time_t currTime = time(nullptr); archiveChanged = true; newArchiveURL = true; // is the file already set ? if (arcFile && getPath(arcFile->url(), QUrl::StripTrailingSlash) == path.left(getPath(arcFile->url(), QUrl::StripTrailingSlash).length())) { newArchiveURL = false; // Has it changed ? KFileItem* newArcFile = new KFileItem(arcFile->url(), QString(), arcFile->mode()); if (metaData("Charset") != currentCharset || !newArcFile->cmp(*arcFile)) { currentCharset = metaData("Charset"); codec = QTextCodec::codecForName(currentCharset.toLatin1()); - if (codec == 0) + if (codec == nullptr) codec = QTextCodec::codecForMib(4 /* latin-1 */); delete arcFile; password.clear(); extArcReady = false; arcFile = newArcFile; } else { // same old file delete newArcFile; archiveChanged = false; if (encrypted && password.isNull()) initArcParameters(); } } else { // it's a new file... extArcReady = false; // new archive file means new dirDict, too dirDict.clear(); if (arcFile) { delete arcFile; password.clear(); - arcFile = 0L; + arcFile = nullptr; } QString newPath = path; if (newPath.right(1) != DIR_SEPARATOR) newPath = newPath + DIR_SEPARATOR; for (int pos = 0; pos >= 0; pos = newPath.indexOf(DIR_SEPARATOR, pos + 1)) { QFileInfo qfi(newPath.left(pos)); if (qfi.exists() && !qfi.isDir()) { QT_STATBUF stat_p; QT_LSTAT(newPath.left(pos).toLocal8Bit(), &stat_p); arcFile = new KFileItem(QUrl::fromLocalFile(newPath.left(pos)), QString(), stat_p.st_mode); break; } } if (!arcFile) { // KRDEBUG("ERROR: " << path << " does not exist."); error(ERR_DOES_NOT_EXIST, path); return false; // file not found } currentCharset = metaData("Charset"); codec = QTextCodec::codecForName(currentCharset.toLatin1()); - if (codec == 0) + if (codec == nullptr) codec = QTextCodec::codecForMib(4 /* latin-1 */); } /* FIX: file change can only be detected if the timestamp between the two consequent changes is more than 1s. If the archive is continuously changing (check: move files inside the archive), krarc may errorneusly think, that the archive file is unchanged, because the timestamp is the same as the previous one. This situation can only occur if the modification time equals with the current time. While this condition is true, we can say, that the archive is changing, so content reread is always necessary during that period. */ if (archiveChanging) archiveChanged = true; archiveChanging = (currTime == (time_t)arcFile->time(KFileItem::ModificationTime).toTime_t()); arcPath = getPath(arcFile->url(), QUrl::StripTrailingSlash); arcType = detectArchive(encrypted, arcPath); if (arcType == "tbz") arcType = "bzip2"; else if (arcType == "tgz") arcType = "gzip"; else if (arcType == "tlz") arcType = "lzma"; else if (arcType == "txz") arcType = "xz"; if (arcType.isEmpty()) { arcType = arcFile->mimetype(); arcType = getShortTypeFromMime(arcType); if (arcType == "jar") arcType = "zip"; } return initArcParameters(); } bool kio_krarcProtocol::initDirDict(const QUrl &url, bool forced) { KRFUNC; KRDEBUG(getPath(url)); // set the archive location //if( !setArcFile(getPath(url)) ) return false; // no need to rescan the archive if it's not changed // KRDEBUG("achiveChanged: " << archiveChanged << " forced: " << forced); if (!archiveChanged && !forced) { // KRDEBUG("doing nothing."); return true; } extArcReady = false; if (!setArcFile(url)) return false; /* if the archive was changed refresh the file information */ // write the temp file KrLinecountingProcess proc; QTemporaryFile temp; // parse the temp file if (!temp.open()) { error(ERR_COULD_NOT_READ, temp.fileName()); return false; } if (arcType != "bzip2" && arcType != "lzma" && arcType != "xz") { if (arcType == "rpm") { proc << listCmd << arcPath; proc.setStandardOutputFile(temp.fileName()); } else { proc << listCmd << getPath(arcFile->url(), QUrl::StripTrailingSlash); proc.setStandardOutputFile(temp.fileName()); } if (arcType == "ace" && QFile("/dev/ptmx").exists()) // Don't remove, unace crashes if missing!!! proc.setStandardInputFile("/dev/ptmx"); proc.setOutputChannelMode(KProcess::SeparateChannels); // without this output redirection has no effect proc.start(); proc.waitForFinished(); if (proc.exitStatus() != QProcess::NormalExit || !checkStatus(proc.exitCode())) return false; } // clear the dir dictionary QHashIterator< QString, KIO::UDSEntryList *> lit(dirDict); while (lit.hasNext()) delete lit.next().value(); dirDict.clear(); // add the "/" directory - UDSEntryList* root = new UDSEntryList(); + auto* root = new UDSEntryList(); dirDict.insert(DIR_SEPARATOR, root); // and the "/" UDSEntry UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_NAME, "."); mode_t mode = parsePermString("drwxr-xr-x"); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, mode & S_IFMT); // keep file type only entry.insert(KIO::UDSEntry::UDS_ACCESS, mode & 07777); // keep permissions only root->append(entry); if (arcType == "bzip2" || arcType == "lzma" || arcType == "xz") abort(); char buf[1000]; QString line; int lineNo = 0; bool invalidLine = false; // the rar list is started with a ------ line. if (arcType == "rar" || arcType == "arj" || arcType == "lha" || arcType == "7z") { while (temp.readLine(buf, 1000) != -1) { line = decodeString(buf); if (line.startsWith(QLatin1String("----------"))) break; } } while (temp.readLine(buf, 1000) != -1) { line = decodeString(buf); if (arcType == "rar") { // the rar list is ended with a ------ line. if (line.startsWith(QLatin1String("----------"))) { invalidLine = !invalidLine; break; } if (invalidLine) continue; else { if (line[0] == '*') // encrypted archives starts with '*' line[0] = ' '; } } if (arcType == "ace") { // the ace list begins with a number. if (!line[0].isDigit()) continue; } if (arcType == "arj") { // the arj list is ended with a ------ line. if (line.startsWith(QLatin1String("----------"))) { invalidLine = !invalidLine; continue; } if (invalidLine) continue; else { temp.readLine(buf, 1000); line = line + decodeString(buf); temp.readLine(buf, 1000); line = line + decodeString(buf); temp.readLine(buf, 1000); line = line + decodeString(buf); } } if (arcType == "lha" || arcType == "7z") { // the arj list is ended with a ------ line. if (line.startsWith(QLatin1String("----------"))) break; } parseLine(lineNo++, line.trimmed()); } // close and delete our file temp.close(); archiveChanged = false; // KRDEBUG("done."); return true; } QString kio_krarcProtocol::findArcDirectory(const QUrl &url) { KRFUNC; KRDEBUG(url.fileName()); QString path = getPath(url); if (path.right(1) == DIR_SEPARATOR) path.truncate(path.length() - 1); if (!initDirDict(url)) { return QString(); } QString arcDir = path.mid(getPath(arcFile->url()).length()); arcDir.truncate(arcDir.lastIndexOf(DIR_SEPARATOR)); if (arcDir.right(1) != DIR_SEPARATOR) arcDir = arcDir + DIR_SEPARATOR; return arcDir; } UDSEntry* kio_krarcProtocol::findFileEntry(const QUrl &url) { KRFUNC; QString arcDir = findArcDirectory(url); - if (arcDir.isEmpty()) return 0; + if (arcDir.isEmpty()) return nullptr; QHash::iterator itef = dirDict.find(arcDir); if (itef == dirDict.end()) - return 0; + return nullptr; UDSEntryList* dirList = itef.value(); QString name = getPath(url); if (getPath(arcFile->url(), QUrl::StripTrailingSlash) == getPath(url, QUrl::StripTrailingSlash)) name = '.'; // the '/' case else { if (name.right(1) == DIR_SEPARATOR) name.truncate(name.length() - 1); name = name.mid(name.lastIndexOf(DIR_SEPARATOR) + 1); } UDSEntryList::iterator entry; for (entry = dirList->begin(); entry != dirList->end(); ++entry) { if ((entry->contains(KIO::UDSEntry::UDS_NAME)) && (entry->stringValue(KIO::UDSEntry::UDS_NAME) == name)) return &(*entry); } - return 0; + return nullptr; } QString kio_krarcProtocol::nextWord(QString &s, char d) { // Note: KRFUNC was not used here in order to avoid filling the log with too much information s = s.trimmed(); int j = s.indexOf(d, 0); QString temp = s.left(j); // find the leftmost word. s.remove(0, j); return temp; } mode_t kio_krarcProtocol::parsePermString(QString perm) { KRFUNC; mode_t mode = 0; // file type if (perm[0] == 'd') mode |= S_IFDIR; #ifndef Q_WS_WIN if (perm[0] == 'l') mode |= S_IFLNK; #endif if (perm[0] == '-') mode |= S_IFREG; // owner permissions if (perm[1] != '-') mode |= S_IRUSR; if (perm[2] != '-') mode |= S_IWUSR; if (perm[3] != '-') mode |= S_IXUSR; #ifndef Q_WS_WIN // group permissions if (perm[4] != '-') mode |= S_IRGRP; if (perm[5] != '-') mode |= S_IWGRP; if (perm[6] != '-') mode |= S_IXGRP; // other permissions if (perm[7] != '-') mode |= S_IROTH; if (perm[8] != '-') mode |= S_IWOTH; if (perm[9] != '-') mode |= S_IXOTH; #endif return mode; } -UDSEntryList* kio_krarcProtocol::addNewDir(QString path) +UDSEntryList* kio_krarcProtocol::addNewDir(const QString& path) { KRFUNC; UDSEntryList* dir; // check if the current dir exists QHash::iterator itef = dirDict.find(path); if (itef != dirDict.end()) return itef.value(); // set dir to the parent dir dir = addNewDir(path.left(path.lastIndexOf(DIR_SEPARATOR, -2) + 1)); // add a new entry in the parent dir QString name = path.mid(path.lastIndexOf(DIR_SEPARATOR, -2) + 1); name = name.left(name.length() - 1); if (name == "." || name == "..") { // entries with these names wouldn't be displayed // don't translate since this is an internal error QString err = QString("Cannot handle path: ") + path; // KRDEBUG("ERROR: " << err); error(KIO::ERR_INTERNAL, err); exit(); } UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_NAME, name); mode_t mode = parsePermString("drwxr-xr-x"); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, mode & S_IFMT); // keep file type only entry.insert(KIO::UDSEntry::UDS_ACCESS, mode & 07777); // keep permissions only entry.insert(KIO::UDSEntry::UDS_SIZE, 0); entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, arcFile->time(KFileItem::ModificationTime).toTime_t()); dir->append(entry); // create a new directory entry and add it.. dir = new UDSEntryList(); dirDict.insert(path, dir); return dir; } void kio_krarcProtocol::parseLine(int lineNo, QString line) { KRFUNC; UDSEntryList* dir; UDSEntry entry; QString owner; QString group; QString symlinkDest; QString perm; mode_t mode = 0666; size_t size = 0; - time_t time = ::time(0); + time_t time = ::time(nullptr); QString fullName; if (arcType == "zip") { // permissions perm = nextWord(line); // ignore the next 2 fields nextWord(line); nextWord(line); // size size = nextWord(line).toLong(); // ignore the next 2 fields nextWord(line);nextWord(line); // date & time QString d = nextWord(line); QDate qdate(d.mid(0, 4).toInt(), d.mid(4, 2).toInt(), d.mid(6, 2).toInt()); QTime qtime(d.mid(9, 2).toInt(), d.mid(11, 2).toInt(), d.mid(13, 2).toInt()); time = QDateTime(qdate, qtime).toTime_t(); // full name fullName = nextWord(line, '\n'); if (perm.length() != 10) perm = (perm.at(0) == 'd' || fullName.endsWith(DIR_SEPARATOR)) ? "drwxr-xr-x" : "-rw-r--r--" ; mode = parsePermString(perm); } if (arcType == "rar") { // permissions perm = nextWord(line); // size size = nextWord(line).toLong(); // ignore the next 2 fields : packed size and compression ration nextWord(line); nextWord(line); // date & time QString d = nextWord(line); int year = 1900 + d.mid(6, 2).toInt(); if (year < 1930) year += 100; QDate qdate(year, d.mid(3, 2).toInt(), d.mid(0, 2).toInt()); QString t = nextWord(line); QTime qtime(t.mid(0, 2).toInt(), t.mid(3, 2).toInt(), 0); time = QDateTime(qdate, qtime).toTime_t(); // checksum : ignored nextWord(line); // full name fullName = nextWord(line, '\n'); if (perm.length() == 7) { // windows rar permission format bool isDir = (perm.at(1).toLower() == 'd'); bool isReadOnly = (perm.at(2).toLower() == 'r'); perm = isDir ? "drwxr-xr-x" : "-rw-r--r--"; if (isReadOnly) perm[ 2 ] = '-'; } if (perm.length() != 10) perm = (perm.at(0) == 'd') ? "drwxr-xr-x" : "-rw-r--r--" ; mode = parsePermString(perm); } if (arcType == "arj") { nextWord(line); // full name fullName = nextWord(line, '\n'); // ignore the next 2 fields nextWord(line); nextWord(line); // size size = nextWord(line).toLong(); // ignore the next 2 fields nextWord(line); nextWord(line); // date & time QString d = nextWord(line); int year = 1900 + d.mid(0, 2).toInt(); if (year < 1930) year += 100; QDate qdate(year, d.mid(3, 2).toInt(), d.mid(6, 2).toInt()); QString t = nextWord(line); QTime qtime(t.mid(0, 2).toInt(), t.mid(3, 2).toInt(), 0); time = QDateTime(qdate, qtime).toTime_t(); // permissions perm = nextWord(line); if (perm.length() != 10) perm = (perm.at(0) == 'd') ? "drwxr-xr-x" : "-rw-r--r--" ; mode = parsePermString(perm); } if (arcType == "rpm") { // full name fullName = nextWord(line); // size size = nextWord(line).toULong(); // date & time time = nextWord(line).toULong(); // next field is md5sum, ignore it nextWord(line); // permissions - mode = nextWord(line).toULong(0, 8); + mode = nextWord(line).toULong(nullptr, 8); // Owner & Group owner = nextWord(line); group = nextWord(line); // symlink destination #ifndef Q_WS_WIN if (S_ISLNK(mode)) { // ignore the next 3 fields nextWord(line); nextWord(line); nextWord(line); symlinkDest = nextWord(line); } #endif } if (arcType == "gzip") { if (!lineNo) return; //ignore the first line // first field is uncompressed size - ignore it nextWord(line); // size size = nextWord(line).toULong(); // ignore the next field nextWord(line); // full name fullName = nextWord(line); fullName = fullName.mid(fullName.lastIndexOf(DIR_SEPARATOR) + 1); } if (arcType == "lzma") { fullName = arcFile->name(); if (fullName.endsWith(QLatin1String("lzma"))) { fullName.truncate(fullName.length() - 5); } mode = arcFile->mode(); size = arcFile->size(); } if (arcType == "xz") { fullName = arcFile->name(); if (fullName.endsWith(QLatin1String("xz"))) { fullName.truncate(fullName.length() - 3); } mode = arcFile->mode(); size = arcFile->size(); } if (arcType == "bzip2") { // There is no way to list bzip2 files, so we take our information from // the archive itself... fullName = arcFile->name(); if (fullName.endsWith(QLatin1String("bz2"))) { fullName.truncate(fullName.length() - 4); } mode = arcFile->mode(); size = arcFile->size(); } if (arcType == "lha") { // permissions perm = nextWord(line); if (perm.length() != 10) perm = (perm.at(0) == 'd') ? "drwxr-xr-x" : "-rw-r--r--" ; mode = parsePermString(perm); // ignore the next field nextWord(line); // size size = nextWord(line).toLong(); // ignore the next field nextWord(line); // date & time int month = (QString("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec").split(',')).indexOf(nextWord(line)) + 1; int day = nextWord(line).toInt(); int year = QDate::currentDate().year(); QString third = nextWord(line); QTime qtime; if (third.contains(":")) qtime = QTime::fromString(third); else year = third.toInt(); QDate qdate(year, month, day); time = QDateTime(qdate, qtime).toTime_t(); // full name fullName = nextWord(line, '\n'); } if (arcType == "ace") { // date & time QString d = nextWord(line); int year = 1900 + d.mid(6, 2).toInt(); if (year < 1930) year += 100; QDate qdate(year, d.mid(3, 2).toInt(), d.mid(0, 2).toInt()); QString t = nextWord(line); QTime qtime(t.mid(0, 2).toInt(), t.mid(3, 2).toInt(), 0); time = QDateTime(qdate, qtime).toTime_t(); // ignore the next field nextWord(line); // size size = nextWord(line).toLong(); // ignore the next field nextWord(line); // full name fullName = nextWord(line, '\n'); if (fullName[ 0 ] == '*') // encrypted archives starts with '*' fullName = fullName.mid(1); } if (arcType == "deb") { // permissions perm = nextWord(line); mode = parsePermString(perm); // Owner & Group owner = nextWord(line, DIR_SEPARATOR_CHAR); group = nextWord(line).mid(1); // size size = nextWord(line).toLong(); // date & time QString d = nextWord(line); QDate qdate(d.mid(0, 4).toInt(), d.mid(5, 2).toInt(), d.mid(8, 2).toInt()); QString t = nextWord(line); QTime qtime(t.mid(0, 2).toInt(), t.mid(3, 2).toInt(), 0); time = QDateTime(qdate, qtime).toTime_t(); // full name fullName = nextWord(line, '\n').mid(1); //if ( fullName.right( 1 ) == "/" ) return; if (fullName.contains("->")) { symlinkDest = fullName.mid(fullName.indexOf("->") + 2); fullName = fullName.left(fullName.indexOf("->") - 1); } } if (arcType == "7z") { // date & time QString d = nextWord(line); QDate qdate(d.mid(0, 4).toInt(), d.mid(5, 2).toInt(), d.mid(8, 2).toInt()); QString t = nextWord(line); QTime qtime(t.mid(0, 2).toInt(), t.mid(3, 2).toInt(), t.mid(6, 2).toInt()); time = QDateTime(qdate, qtime).toTime_t(); // permissions perm = nextWord(line); bool isDir = (perm.at(0).toLower() == 'd'); bool isReadOnly = (perm.at(1).toLower() == 'r'); perm = isDir ? "drwxr-xr-x" : "-rw-r--r--"; if (isReadOnly) perm[ 2 ] = '-'; mode = parsePermString(perm); // size size = nextWord(line).toLong(); // ignore the next 15 characters line = line.mid(15); // full name fullName = nextWord(line, '\n'); } if (fullName.right(1) == DIR_SEPARATOR) fullName = fullName.left(fullName.length() - 1); if (!fullName.startsWith(DIR_SEPARATOR)) fullName = DIR_SEPARATOR + fullName; QString path = fullName.left(fullName.lastIndexOf(DIR_SEPARATOR) + 1); // set/create the directory UDSEntryList QHash::iterator itef = dirDict.find(path); if (itef == dirDict.end()) dir = addNewDir(path); else dir = itef.value(); QString name = fullName.mid(fullName.lastIndexOf(DIR_SEPARATOR) + 1); // file name entry.insert(KIO::UDSEntry::UDS_NAME, name); // file type entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, mode & S_IFMT); // keep file type only // file permissions entry.insert(KIO::UDSEntry::UDS_ACCESS, mode & 07777); // keep permissions only // file size entry.insert(KIO::UDSEntry::UDS_SIZE, size); // modification time entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, time); // link destination if (!symlinkDest.isEmpty()) { entry.insert(KIO::UDSEntry::UDS_LINK_DEST, symlinkDest); } if (S_ISDIR(mode)) { fullName = fullName + DIR_SEPARATOR; if (dirDict.find(fullName) == dirDict.end()) dirDict.insert(fullName, new UDSEntryList()); else { // try to overwrite an existing entry UDSEntryList::iterator entryIt; for (entryIt = dir->begin(); entryIt != dir->end(); ++entryIt) { if (entryIt->contains(KIO::UDSEntry::UDS_NAME) && entryIt->stringValue(KIO::UDSEntry::UDS_NAME) == name) { entryIt->insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, time); entryIt->insert(KIO::UDSEntry::UDS_ACCESS, mode); return; } } return; // there is already an entry for this directory } } // multi volume archives can add a file twice, use only one UDSEntryList::iterator dirEntryIt; for (dirEntryIt = dir->begin(); dirEntryIt != dir->end(); ++dirEntryIt) if (dirEntryIt->contains(KIO::UDSEntry::UDS_NAME) && dirEntryIt->stringValue(KIO::UDSEntry::UDS_NAME) == name) return; dir->append(entry); } bool kio_krarcProtocol::initArcParameters() { KRFUNC; KRDEBUG("arcType: " << arcType); noencoding = false; cmd.clear(); listCmd = QStringList(); getCmd = QStringList(); copyCmd = QStringList(); delCmd = QStringList(); putCmd = QStringList(); renCmd = QStringList(); if (arcType == "zip") { noencoding = true; cmd = fullPathName("unzip"); listCmd << fullPathName("unzip") << "-ZTs-z-t-h"; getCmd << fullPathName("unzip") << "-p"; copyCmd << fullPathName("unzip") << "-jo"; if (QStandardPaths::findExecutable(QStringLiteral("zip")).isEmpty()) { delCmd = QStringList(); putCmd = QStringList(); } else { delCmd << fullPathName("zip") << "-d"; putCmd << fullPathName("zip") << "-ry"; } if (!QStandardPaths::findExecutable(QStringLiteral("7za")).isEmpty()) { renCmd << fullPathName("7za") << "rn"; } if (!getPassword().isEmpty()) { getCmd << "-P" << password; copyCmd << "-P" << password; putCmd << "-P" << password; } } else if (arcType == "rar") { noencoding = true; if (QStandardPaths::findExecutable(QStringLiteral("rar")).isEmpty()) { cmd = fullPathName("unrar"); listCmd << fullPathName("unrar") << "-c-" << "-v" << "v"; getCmd << fullPathName("unrar") << "p" << "-ierr" << "-idp" << "-c-" << "-y"; copyCmd << fullPathName("unrar") << "e" << "-y"; delCmd = QStringList(); putCmd = QStringList(); } else { cmd = fullPathName("rar"); listCmd << fullPathName("rar") << "-c-" << "-v" << "v"; getCmd << fullPathName("rar") << "p" << "-ierr" << "-idp" << "-c-" << "-y"; copyCmd << fullPathName("rar") << "e" << "-y"; delCmd << fullPathName("rar") << "d"; putCmd << fullPathName("rar") << "-r" << "a"; } if (!getPassword().isEmpty()) { getCmd << QString("-p%1").arg(password); listCmd << QString("-p%1").arg(password); copyCmd << QString("-p%1").arg(password); if (!putCmd.isEmpty()) { putCmd << QString("-p%1").arg(password); delCmd << QString("-p%1").arg(password); } } } else if (arcType == "rpm") { cmd = fullPathName("rpm"); listCmd << fullPathName("rpm") << "--dump" << "-lpq"; getCmd << fullPathName("cpio") << "--force-local" << "--no-absolute-filenames" << "-iuvdF"; delCmd = QStringList(); putCmd = QStringList(); copyCmd = QStringList(); } else if (arcType == "gzip") { cmd = fullPathName("gzip"); listCmd << fullPathName("gzip") << "-l"; getCmd << fullPathName("gzip") << "-dc"; copyCmd = QStringList(); delCmd = QStringList(); putCmd = QStringList(); } else if (arcType == "bzip2") { cmd = fullPathName("bzip2"); listCmd << fullPathName("bzip2"); getCmd << fullPathName("bzip2") << "-dc"; copyCmd = QStringList(); delCmd = QStringList(); putCmd = QStringList(); } else if (arcType == "lzma") { cmd = fullPathName("lzma"); listCmd << fullPathName("lzma"); getCmd << fullPathName("lzma") << "-dc"; copyCmd = QStringList(); delCmd = QStringList(); putCmd = QStringList(); } else if (arcType == "xz") { cmd = fullPathName("xz"); listCmd << fullPathName("xz"); getCmd << fullPathName("xz") << "-dc"; copyCmd = QStringList(); delCmd = QStringList(); putCmd = QStringList(); } else if (arcType == "arj") { cmd = fullPathName("arj"); listCmd << fullPathName("arj") << "v" << "-y" << "-v"; getCmd << fullPathName("arj") << "-jyov" << "-v" << "e"; copyCmd << fullPathName("arj") << "-jyov" << "-v" << "e"; delCmd << fullPathName("arj") << "d"; putCmd << fullPathName("arj") << "-r" << "a"; if (!getPassword().isEmpty()) { getCmd << QString("-g%1").arg(password); copyCmd << QString("-g%1").arg(password); putCmd << QString("-g%1").arg(password); } } else if (arcType == "lha") { cmd = fullPathName("lha"); listCmd << fullPathName("lha") << "l"; getCmd << fullPathName("lha") << "pq"; copyCmd << fullPathName("lha") << "eif"; delCmd << fullPathName("lha") << "d"; putCmd << fullPathName("lha") << "a"; } else if (arcType == "ace") { cmd = fullPathName("unace"); listCmd << fullPathName("unace") << "v"; getCmd << fullPathName("unace") << "e" << "-o"; copyCmd << fullPathName("unace") << "e" << "-o"; delCmd = QStringList(); putCmd = QStringList(); if (!getPassword().isEmpty()) { getCmd << QString("-p%1").arg(password); copyCmd << QString("-p%1").arg(password); } } else if (arcType == "deb") { cmd = fullPathName("dpkg"); listCmd << fullPathName("dpkg") << "-c"; getCmd << fullPathName("tar") << "xvf"; copyCmd = QStringList(); delCmd = QStringList(); putCmd = QStringList(); } else if (arcType == "7z") { noencoding = true; cmd = fullPathName("7z"); if (QStandardPaths::findExecutable(cmd).isEmpty()) cmd = fullPathName("7za"); listCmd << cmd << "l" << "-y"; getCmd << cmd << "e" << "-y"; copyCmd << cmd << "e" << "-y"; delCmd << cmd << "d" << "-y"; putCmd << cmd << "a" << "-y"; renCmd << cmd << "rn"; if (!getPassword().isEmpty()) { getCmd << QString("-p%1").arg(password); listCmd << QString("-p%1").arg(password); copyCmd << QString("-p%1").arg(password); if (!putCmd.isEmpty()) { putCmd << QString("-p%1").arg(password); delCmd << QString("-p%1").arg(password); } } } // checking if it's an absolute path #ifdef Q_WS_WIN if (cmd.length() > 2 && cmd[ 0 ].isLetter() && cmd[ 1 ] == ':') return true; #else if (cmd.startsWith(DIR_SEPARATOR)) return true; #endif if (QStandardPaths::findExecutable(cmd).isEmpty()) { error(KIO::ERR_CANNOT_LAUNCH_PROCESS, cmd + i18n("\nMake sure that the %1 binary is installed properly on your system.", cmd)); KRDEBUG("Failed to find cmd: " << cmd); return false; } return true; } bool kio_krarcProtocol::checkStatus(int exitCode) { KRFUNC; KRDEBUG(exitCode); return KrArcBaseManager::checkStatus(arcType, exitCode); } void kio_krarcProtocol::checkIf7zIsEncrypted(bool &encrypted, QString fileName) { KRFUNC; if (encryptedArchPath == fileName) encrypted = true; else { // we try to find whether the 7z archive is encrypted // this is hard as the headers are also compressed QString tester = fullPathName("7z"); if (QStandardPaths::findExecutable(tester).isEmpty()) { KRDEBUG("A 7z program was not found"); tester = fullPathName("7za"); if (QStandardPaths::findExecutable(tester).isEmpty()) { KRDEBUG("A 7za program was not found"); return; } } QString testCmd = tester + " t -y "; lastData = encryptedArchPath = ""; KrLinecountingProcess proc; proc << testCmd << fileName; connect(&proc, &KrLinecountingProcess::newOutputData, this, &kio_krarcProtocol::checkOutputForPassword); proc.start(); proc.waitForFinished(); encrypted = this->encrypted; if (encrypted) encryptedArchPath = fileName; } } void kio_krarcProtocol::checkOutputForPassword(KProcess * proc, QByteArray & buf) { KRFUNC; QString data = QString(buf); QString checkable = lastData + data; QStringList lines = checkable.split('\n'); lastData = lines[ lines.count() - 1 ]; for (int i = 0; i != lines.count(); i++) { QString line = lines[ i ].trimmed().toLower(); int ndx = line.indexOf("testing"); if (ndx >= 0) line.truncate(ndx); if (line.isEmpty()) continue; if (line.contains("password") && line.contains("enter")) { KRDEBUG("Encrypted 7z archive found!"); encrypted = true; proc->kill(); return; } } } void kio_krarcProtocol::invalidatePassword() { KRFUNC; KRDEBUG(getPath(arcFile->url(), QUrl::StripTrailingSlash) + DIR_SEPARATOR); if (!encrypted) return; KIO::AuthInfo authInfo; authInfo.caption = i18n("Krarc Password Dialog"); authInfo.username = "archive"; authInfo.readOnly = true; authInfo.keepPassword = true; authInfo.verifyPath = true; QString fileName = getPath(arcFile->url(), QUrl::StripTrailingSlash); authInfo.url = QUrl::fromLocalFile(ROOT_DIR); authInfo.url.setHost(fileName /*.replace('/','_')*/); authInfo.url.setScheme("krarc"); password.clear(); cacheAuthentication(authInfo); } QString kio_krarcProtocol::getPassword() { KRFUNC; KRDEBUG("Encrypted: " << encrypted); if (!password.isNull()) return password; if (!encrypted) return (password = ""); KIO::AuthInfo authInfo; authInfo.caption = i18n("Krarc Password Dialog"); authInfo.username = "archive"; authInfo.readOnly = true; authInfo.keepPassword = true; authInfo.verifyPath = true; QString fileName = getPath(arcFile->url(), QUrl::StripTrailingSlash); authInfo.url = QUrl::fromLocalFile(ROOT_DIR); authInfo.url.setHost(fileName /*.replace('/','_')*/); authInfo.url.setScheme("krarc"); if (checkCachedAuthentication(authInfo) && !authInfo.password.isNull()) { KRDEBUG(authInfo.password); return (password = authInfo.password); } authInfo.password.clear(); #if KIO_VERSION_MINOR >= 24 int errCode = openPasswordDialogV2(authInfo, i18n("Accessing the file requires a password.")); if (!errCode && !authInfo.password.isNull()) { #else if (openPasswordDialog(authInfo, i18n("Accessing the file requires a password.")) && !authInfo.password.isNull()) { #endif KRDEBUG(authInfo.password); return (password = authInfo.password); #if KIO_VERSION_MINOR >= 24 } else { error(errCode, QString()); #endif } KRDEBUG(password); return password; } QString kio_krarcProtocol::detectFullPathName(QString name) { // Note: KRFUNC was not used here in order to avoid filling the log with too much information KRDEBUG(name); name = name + EXEC_SUFFIX; QStringList path = QString::fromLocal8Bit(qgetenv("PATH")).split(':'); - for (QStringList::Iterator it = path.begin(); it != path.end(); ++it) { - if (QDir(*it).exists(name)) { - QString dir = *it; + for (auto & it : path) { + if (QDir(it).exists(name)) { + QString dir = it; if (!dir.endsWith(DIR_SEPARATOR)) dir += DIR_SEPARATOR; return dir + name; } } return name; } -QString kio_krarcProtocol::fullPathName(QString name) +QString kio_krarcProtocol::fullPathName(const QString& name) { // Note: KRFUNC was not used here in order to avoid filling the log with too much information KRDEBUG(name); QString supposedName = confGrp.readEntry(name, QString()); if (supposedName.isEmpty()) supposedName = detectFullPathName(name); return supposedName; } QString kio_krarcProtocol::localeEncodedString(QString str) { // Note: KRFUNC was not used here in order to avoid filling the log with too much information if (noencoding) return str; QByteArray array = codec->fromUnicode(str); // encoding the byte array to QString, mapping 0x0000-0x00FF to 0xE000-0xE0FF // see KrArcCodec for more explanation int size = array.size(); QString result; const char *data = array.data(); for (int i = 0; i != size; i++) { unsigned short ch = (((int)data[ i ]) & 0xFF) + 0xE000; // user defined character result.append(QChar(ch)); } return result; } -QByteArray kio_krarcProtocol::encodeString(QString str) +QByteArray kio_krarcProtocol::encodeString(const QString& str) { // Note: KRFUNC was not used here in order to avoid filling the log with too much information if (noencoding) return QTextCodec::codecForLocale()->fromUnicode(str); return codec->fromUnicode(str); } QString kio_krarcProtocol::decodeString(char * buf) { // Note: KRFUNC was not used here in order to avoid filling the log with too much information if (noencoding) return QTextCodec::codecForLocale()->toUnicode(buf); return codec->toUnicode(buf); } QString kio_krarcProtocol::getPath(const QUrl &url, QUrl::FormattingOptions options) { // Note: KRFUNC was not used here in order to avoid filling the log with too much information QString path = url.adjusted(options).path(); REPLACE_DIR_SEP2(path); #ifdef Q_WS_WIN if (path.startsWith(DIR_SEPARATOR)) { int p = 1; while (p < path.length() && path[ p ] == DIR_SEPARATOR_CHAR) p++; /* /C:/Folder */ if (p + 2 <= path.length() && path[ p ].isLetter() && path[ p + 1 ] == ':') { path = path.mid(p); } } #endif return path; } #endif // KRARC_ENABLED diff --git a/krArc/krarc.h b/krArc/krarc.h index b1cb811f..db5faa96 100644 --- a/krArc/krarc.h +++ b/krArc/krarc.h @@ -1,145 +1,145 @@ /***************************************************************************** * Copyright (C) 2003 Rafi Yanai * * Copyright (C) 2003 Shie Erlich * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef KRARC_H #define KRARC_H // QtCore #include #include #include #include #include #include #include #include #include #include "krarcbasemanager.h" #include "krlinecountingprocess.h" #include "../krusader/krdebuglogger.h" class KFileItem; class QByteArray; class QTextCodec; class kio_krarcProtocol : public QObject, public KIO::SlaveBase, public KrArcBaseManager { Q_OBJECT public: kio_krarcProtocol(const QByteArray &pool_socket, const QByteArray &app_socket); - virtual ~kio_krarcProtocol(); - virtual void stat(const QUrl &url) Q_DECL_OVERRIDE; - virtual void get(const QUrl &url) Q_DECL_OVERRIDE; - virtual void put(const QUrl &url, int permissions, KIO::JobFlags flags) Q_DECL_OVERRIDE; - virtual void mkdir(const QUrl &url, int permissions) Q_DECL_OVERRIDE; - virtual void listDir(const QUrl &url) Q_DECL_OVERRIDE; - virtual void del(QUrl const & url, bool isFile) Q_DECL_OVERRIDE; - virtual void copy(const QUrl &src, const QUrl &dest, int permissions, KIO::JobFlags flags) Q_DECL_OVERRIDE; - virtual void rename(const QUrl &src, const QUrl & dest, KIO::JobFlags flags) Q_DECL_OVERRIDE; + ~kio_krarcProtocol() override; + void stat(const QUrl &url) Q_DECL_OVERRIDE; + void get(const QUrl &url) Q_DECL_OVERRIDE; + void put(const QUrl &url, int permissions, KIO::JobFlags flags) Q_DECL_OVERRIDE; + void mkdir(const QUrl &url, int permissions) Q_DECL_OVERRIDE; + void listDir(const QUrl &url) Q_DECL_OVERRIDE; + void del(QUrl const & url, bool isFile) Q_DECL_OVERRIDE; + void copy(const QUrl &src, const QUrl &dest, int permissions, KIO::JobFlags flags) Q_DECL_OVERRIDE; + void rename(const QUrl &src, const QUrl & dest, KIO::JobFlags flags) Q_DECL_OVERRIDE; public slots: void receivedData(KProcess *, QByteArray &); void checkOutputForPassword(KProcess *, QByteArray &); protected: virtual bool initDirDict(const QUrl &url, bool forced = false); virtual bool initArcParameters(); void checkIf7zIsEncrypted(bool &, QString) Q_DECL_OVERRIDE; virtual void parseLine(int lineNo, QString line); virtual bool setArcFile(const QUrl &url); virtual QString getPassword(); virtual void invalidatePassword(); - QString getPath(const QUrl &url, QUrl::FormattingOptions options = 0); + QString getPath(const QUrl &url, QUrl::FormattingOptions options = nullptr); QString localeEncodedString(QString str); - QByteArray encodeString(QString); + QByteArray encodeString(const QString&); QString decodeString(char *); // archive specific commands QString cmd; ///< the archiver name. QStringList listCmd; ///< list files. QStringList getCmd; ///< unpack files command. QStringList delCmd; ///< delete files command. QStringList putCmd; ///< add file command. QStringList copyCmd; ///< copy to file command. QStringList renCmd; ///< rename file command. private: void get(const QUrl &url, int tries); /** checks if a returned status ("exit code") of an archiving-related process is OK. */ bool checkStatus(int exitCode); /** service function for parseLine. */ QString nextWord(QString &s, char d = ' '); /** translate permission string to mode_t. */ mode_t parsePermString(QString perm); /** return the name of the directory inside the archive. */ QString findArcDirectory(const QUrl &url); /** find the UDSEntry of a file in a directory. */ KIO::UDSEntry* findFileEntry(const QUrl &url); /** add a new directory (file list container). */ - KIO::UDSEntryList* addNewDir(QString path); - QString fullPathName(QString name); + KIO::UDSEntryList* addNewDir(const QString& path); + QString fullPathName(const QString& name); static QString detectFullPathName(QString name); bool checkWriteSupport(); QHash dirDict; //< the directories data structure. bool encrypted; //< tells whether the archive is encrypted bool archiveChanged; //< true if the archive was changed. bool archiveChanging; //< true if the archive is currently changing. bool newArchiveURL; //< true if new archive was entered for the protocol bool noencoding; //< 7z files use UTF-16, so encoding is unnecessary KIO::filesize_t decompressedLen; //< the number of the decompressed bytes KFileItem* arcFile; //< the archive file item. QString arcPath; //< the archive location QString arcTempDir; //< the currently used temp directory. QString arcType; //< the archive type. bool extArcReady; //< Used for RPM & DEB files. QString password; //< Password for the archives KConfig krConf; //< The configuration file for krusader KConfigGroup confGrp; //< the 'Dependencies' config group QString lastData; QString encryptedArchPath; QString currentCharset; QTextCodec * codec; }; #ifdef Q_WS_WIN #define DIR_SEPARATOR "/" #define DIR_SEPARATOR2 "\\" #define DIR_SEPARATOR_CHAR '/' #define DIR_SEPARATOR_CHAR2 '\\' #define REPLACE_DIR_SEP2(x) x = x.replace( DIR_SEPARATOR2, DIR_SEPARATOR ); #define ROOT_DIR "C:\\" #define EXEC_SUFFIX ".exe" #else #define DIR_SEPARATOR "/" #define DIR_SEPARATOR2 "/" #define DIR_SEPARATOR_CHAR '/' #define DIR_SEPARATOR_CHAR2 '/' #define REPLACE_DIR_SEP2(x) #define ROOT_DIR "/" #define EXEC_SUFFIX "" #endif #endif diff --git a/krArc/krarcbasemanager.cpp b/krArc/krarcbasemanager.cpp index 21a27aaa..8bec551f 100644 --- a/krArc/krarcbasemanager.cpp +++ b/krArc/krarcbasemanager.cpp @@ -1,234 +1,234 @@ /***************************************************************************** * Copyright (C) 2003 Rafi Yanai * * Copyright (C) 2003 Shie Erlich * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "krarcbasemanager.h" #include KrArcBaseManager::AutoDetectParams KrArcBaseManager::autoDetectParams[] = {{"zip", 0, "PK\x03\x04"}, {"rar", 0, "Rar!\x1a" }, {"arj", 0, "\x60\xea" }, {"rpm", 0, "\xed\xab\xee\xdb"}, {"ace", 7, "**ACE**" }, {"bzip2", 0, "\x42\x5a\x68\x39\x31" }, {"gzip", 0, "\x1f\x8b"}, {"deb", 0, "!\ndebian-binary " }, {"7z", 0, "7z\xbc\xaf\x27\x1c" }/*, {"xz", 0, "\xfd\x37\x7a\x58\x5a\x00"}*/ }; int KrArcBaseManager::autoDetectElems = sizeof(autoDetectParams) / sizeof(AutoDetectParams); const int KrArcBaseManager::maxLenType = 5; //! Checks if a returned status ("exit code") of an archiving-related process is OK /*! \param arcType A short QString which contains an identifier of the type of the archive. \param exitCode The returned status ("exit code") of an archiving-related process. \return If the exit code means that the archiving-related process ended without errors. */ bool KrArcBaseManager::checkStatus(const QString &arcType, int exitCode) { if (arcType == "zip" || arcType == "rar" || arcType == "7z") return exitCode == 0 || exitCode == 1; else if (arcType == "ace" || arcType == "bzip2" || arcType == "lha" || arcType == "rpm" || arcType == "cpio" || arcType == "tar" || arcType == "tarz" || arcType == "tbz" || arcType == "tgz" || arcType == "arj" || arcType == "deb" || arcType == "tlz" || arcType == "txz") return exitCode == 0; else if (arcType == "gzip" || arcType == "lzma" || arcType == "xz") return exitCode == 0 || exitCode == 2; else return exitCode == 0; } -QString KrArcBaseManager::detectArchive(bool &encrypted, QString fileName, bool checkEncrypted, bool fast) +QString KrArcBaseManager::detectArchive(bool &encrypted, const QString& fileName, bool checkEncrypted, bool fast) { encrypted = false; QFile arcFile(fileName); if (arcFile.open(QIODevice::ReadOnly)) { char buffer[ 1024 ]; long sizeMax = arcFile.read(buffer, sizeof(buffer)); arcFile.close(); for (int i = 0; i < autoDetectElems; i++) { QByteArray detectionString = autoDetectParams[ i ].detectionString; int location = autoDetectParams[ i ].location; int endPtr = detectionString.length() + location; if (endPtr > sizeMax) continue; int j = 0; for (; j != detectionString.length(); j++) { if (detectionString[ j ] == '?') continue; if (buffer[ location + j ] != detectionString[ j ]) break; } if (j == detectionString.length()) { QString type = autoDetectParams[ i ].type; if (type == "bzip2" || type == "gzip") { if (fast) { if (fileName.endsWith(QLatin1String(".tar.gz"))) type = "tgz"; else if (fileName.endsWith(QLatin1String(".tar.bz2"))) type = "tbz"; } else { KTar tapeArchive(fileName); if (tapeArchive.open(QIODevice::ReadOnly)) { tapeArchive.close(); if (type == "gzip") type = "tgz"; else if (type == "bzip2") type = "tbz"; } } } else if (type == "zip") encrypted = (buffer[6] & 1); else if (type == "arj") { if (sizeMax > 4) { long headerSize = ((unsigned char *)buffer)[ 2 ] + 256 * ((unsigned char *)buffer)[ 3 ]; long fileHeader = headerSize + 10; if (fileHeader + 9 < sizeMax && buffer[ fileHeader ] == (char)0x60 && buffer[ fileHeader + 1 ] == (char)0xea) encrypted = (buffer[ fileHeader + 8 ] & 1); } } else if (type == "rar") { if (sizeMax > 13 && buffer[ 9 ] == (char)0x73) { if (buffer[ 10 ] & 0x80) { // the header is encrypted? encrypted = true; } else { long offset = 7; long mainHeaderSize = ((unsigned char *)buffer)[ offset+5 ] + 256 * ((unsigned char *)buffer)[ offset+6 ]; offset += mainHeaderSize; while (offset + 10 < sizeMax) { long headerSize = ((unsigned char *)buffer)[ offset+5 ] + 256 * ((unsigned char *)buffer)[ offset+6 ]; bool isDir = (buffer[ offset+7 ] == '\0') && (buffer[ offset+8 ] == '\0') && (buffer[ offset+9 ] == '\0') && (buffer[ offset+10 ] == '\0'); if (buffer[ offset + 2 ] != (char)0x74) break; if (!isDir) { encrypted = (buffer[ offset + 3 ] & 4) != 0; break; } offset += headerSize; } } } } else if (type == "ace") { long offset = 0; long mainHeaderSize = ((unsigned char *)buffer)[ offset+2 ] + 256 * ((unsigned char *)buffer)[ offset+3 ] + 4; offset += mainHeaderSize; while (offset + 10 < sizeMax) { long headerSize = ((unsigned char *)buffer)[ offset+2 ] + 256 * ((unsigned char *)buffer)[ offset+3 ] + 4; bool isDir = (buffer[ offset+11 ] == '\0') && (buffer[ offset+12 ] == '\0') && (buffer[ offset+13 ] == '\0') && (buffer[ offset+14 ] == '\0'); if (buffer[ offset + 4 ] != (char)0x01) break; if (!isDir) { encrypted = (buffer[ offset + 6 ] & 64) != 0; break; } offset += headerSize; } } else if (type == "7z") { // encryption check is expensive, check only if it's necessary if (checkEncrypted) checkIf7zIsEncrypted(encrypted, fileName); } return type; } } if (sizeMax >= 512) { /* checking if it's a tar file */ unsigned checksum = 32 * 8; char chksum[ 9 ]; for (int i = 0; i != 512; i++) checksum += ((unsigned char *)buffer)[ i ]; for (int i = 148; i != 156; i++) checksum -= ((unsigned char *)buffer)[ i ]; sprintf(chksum, "0%o", checksum); if (!memcmp(buffer + 148, chksum, strlen(chksum))) { int k = strlen(chksum); for (; k < 8; k++) if (buffer[148+k] != 0 && buffer[148+k] != 32) break; if (k == 8) return "tar"; } } } if (fileName.endsWith(QLatin1String(".tar.lzma")) || fileName.endsWith(QLatin1String(".tlz"))) { return "tlz"; } if (fileName.endsWith(QLatin1String(".lzma"))) { return "lzma"; } if (fileName.endsWith(QLatin1String(".tar.xz")) || fileName.endsWith(QLatin1String(".txz"))) { return "txz"; } if (fileName.endsWith(QLatin1String(".xz"))) { return "xz"; } return QString(); } //! Returns a short identifier of the type of a file, obtained from the mime type of the file /*! \param mime The mime type of the file. \return A short QString which contains an identifier of the type of the file. */ QString KrArcBaseManager::getShortTypeFromMime(const QString &mime) { // 7zip files are a not a normal case because their mimetype does not // follow the norm of other types: zip, tar, lha, ace, arj, etc. if (mime == "application/x-7z-compressed") return "7z"; // If it's a rar file but its mimetype isn't "application/x-rar" if (mime == "application/x-rar-compressed") return "rar"; // The short type that will be returned QString sType = mime; int lastHyphen = sType.lastIndexOf('-'); if (lastHyphen != -1) sType = sType.mid(lastHyphen + 1); else { int lastSlash = sType.lastIndexOf('/'); if (lastSlash != -1) sType = sType.mid(lastSlash + 1); } // The identifier kept short if (sType.length() > maxLenType) sType = sType.right(maxLenType); return sType; } diff --git a/krArc/krarcbasemanager.h b/krArc/krarcbasemanager.h index b5a137f7..833f1cf3 100644 --- a/krArc/krarcbasemanager.h +++ b/krArc/krarcbasemanager.h @@ -1,59 +1,59 @@ /***************************************************************************** * Copyright (C) 2003 Rafi Yanai * * Copyright (C) 2003 Shie Erlich * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef KRARCBASEMANAGER_H #define KRARCBASEMANAGER_H // QtCore #include /*! * \brief An abstract base class for managing archives. */ class KrArcBaseManager { private: //! Information about a type of archive and the bytes that are used to detect it. struct AutoDetectParams { QString type; int location; QByteArray detectionString; }; static AutoDetectParams autoDetectParams[]; //! Information used to detect if a file is an archive static int autoDetectElems; //!< The size of autoDetectParams[] protected: //! The maximum length of a short QString that represents the type of a file static const int maxLenType; static bool checkStatus(const QString &, int); public: KrArcBaseManager() {} - QString detectArchive(bool &, QString, bool = true, bool = false); + QString detectArchive(bool &, const QString&, bool = true, bool = false); virtual void checkIf7zIsEncrypted(bool &, QString) = 0; static QString getShortTypeFromMime(const QString &); virtual ~KrArcBaseManager() {} }; #endif // KRARCBASEMANAGER_H diff --git a/krArc/krlinecountingprocess.cpp b/krArc/krlinecountingprocess.cpp index 8f4951cc..4a94c649 100644 --- a/krArc/krlinecountingprocess.cpp +++ b/krArc/krlinecountingprocess.cpp @@ -1,66 +1,66 @@ /***************************************************************************** * Copyright (C) 2001 Shie Erlich * * Copyright (C) 2001 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "krlinecountingprocess.h" -KrLinecountingProcess::KrLinecountingProcess() : KProcess() +KrLinecountingProcess::KrLinecountingProcess() { setOutputChannelMode(KProcess::SeparateChannels); // without this output redirection has no effect! connect(this, &KrLinecountingProcess::readyReadStandardError, this, &KrLinecountingProcess::receivedError); connect(this, &KrLinecountingProcess::readyReadStandardOutput, [=]() { receivedOutput(); }); mergedOutput = true; } void KrLinecountingProcess::setMerge(bool value) { mergedOutput = value; } QString KrLinecountingProcess::getErrorMsg() { if (errorData.trimmed().isEmpty()) return QString::fromLocal8Bit(outputData); else return QString::fromLocal8Bit(errorData); } void KrLinecountingProcess::receivedError() { QByteArray newData(this->readAllStandardError()); emit newErrorLines(newData.count('\n')); errorData += newData; if (errorData.length() > 500) errorData = errorData.right(500); if (mergedOutput) receivedOutput(newData); } void KrLinecountingProcess::receivedOutput(QByteArray newData) { if (newData.isEmpty()) newData = this->readAllStandardOutput(); emit newOutputLines(newData.count('\n')); emit newOutputData(this, newData); outputData += newData; if (outputData.length() > 500) outputData = outputData.right(500); } diff --git a/krusader/ActionMan/actionman.cpp b/krusader/ActionMan/actionman.cpp index 76f22d09..5e97c9f4 100644 --- a/krusader/ActionMan/actionman.cpp +++ b/krusader/ActionMan/actionman.cpp @@ -1,87 +1,86 @@ /***************************************************************************** * Copyright (C) 2006 Jonas Bähr * * Copyright (C) 2006-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "actionman.h" // QtWidgets #include #include #include #include #include #include "useractionpage.h" #include "../krusader.h" #include "../UserAction/useraction.h" ActionMan::ActionMan(QWidget * parent) : QDialog(parent) { setWindowModality(Qt::WindowModal); setWindowTitle(i18n("ActionMan - Manage Your Useractions")); - QVBoxLayout *mainLayout = new QVBoxLayout; + auto *mainLayout = new QVBoxLayout; setLayout(mainLayout); userActionPage = new UserActionPage(this); mainLayout->addWidget(userActionPage); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close|QDialogButtonBox::Apply); mainLayout->addWidget(buttonBox); applyButton = buttonBox->button(QDialogButtonBox::Apply); applyButton->setEnabled(false); connect(buttonBox, &QDialogButtonBox::rejected, this, &ActionMan::slotClose); connect(applyButton, &QPushButton::clicked, this, &ActionMan::slotApply); connect(userActionPage, &UserActionPage::changed, this, &ActionMan::slotEnableApplyButton); connect(userActionPage, &UserActionPage::applied, this, &ActionMan::slotDisableApplyButton); exec(); krApp->updateUserActions(); } ActionMan::~ActionMan() -{ -} += default; void ActionMan::slotClose() { if (userActionPage->readyToQuit()) reject(); } void ActionMan::slotApply() { userActionPage->applyChanges(); } void ActionMan::slotEnableApplyButton() { applyButton->setEnabled(true); } void ActionMan::slotDisableApplyButton() { applyButton->setEnabled(false); } diff --git a/krusader/ActionMan/actionman.h b/krusader/ActionMan/actionman.h index 3ae9891a..8aeaab0a 100644 --- a/krusader/ActionMan/actionman.h +++ b/krusader/ActionMan/actionman.h @@ -1,50 +1,50 @@ /***************************************************************************** * Copyright (C) 2006 Jonas Bähr * * Copyright (C) 2006-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef ACTIONMAN_H #define ACTIONMAN_H // QtWidgets #include class UserActionPage; /** * This manages all useractions */ class ActionMan : public QDialog { Q_OBJECT public: - explicit ActionMan(QWidget* parent = 0); - ~ActionMan(); + explicit ActionMan(QWidget* parent = nullptr); + ~ActionMan() override; protected slots: void slotClose(); void slotApply(); void slotEnableApplyButton(); void slotDisableApplyButton(); private: UserActionPage* userActionPage; QPushButton *applyButton; }; #endif // ifndef ACTIONMAN_H diff --git a/krusader/ActionMan/actionproperty.cpp b/krusader/ActionMan/actionproperty.cpp index e7bc16dc..a38469fb 100644 --- a/krusader/ActionMan/actionproperty.cpp +++ b/krusader/ActionMan/actionproperty.cpp @@ -1,518 +1,517 @@ /***************************************************************************** * Copyright (C) 2004-2007 Jonas Bähr * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "actionproperty.h" #include "addplaceholderpopup.h" #include "../UserAction/useraction.h" #include "../UserAction/kraction.h" #include "../krusader.h" #include "../krglobal.h" #include "../icon.h" // QtWidgets #include #include #include #include #include ActionProperty::ActionProperty(QWidget *parent, KrAction *action) : QWidget(parent), _modified(false) { setupUi(this); if (action) { _action = action; updateGUI(_action); } ButtonAddPlaceholder->setIcon(Icon("list-add")); ButtonAddStartpath->setIcon(Icon("document-open")); // fill with all existing categories cbCategory->addItems(krUserAction->allCategories()); connect(ButtonAddPlaceholder, &QToolButton::clicked, this, &ActionProperty::addPlaceholder); connect(ButtonAddStartpath, &QToolButton::clicked, this, &ActionProperty::addStartpath); connect(ButtonNewProtocol, &QToolButton::clicked, this, &ActionProperty::newProtocol); connect(ButtonEditProtocol, &QToolButton::clicked, this, &ActionProperty::editProtocol); connect(ButtonRemoveProtocol, &QToolButton::clicked, this, &ActionProperty::removeProtocol); connect(ButtonAddPath, &QToolButton::clicked, this, &ActionProperty::addPath); connect(ButtonEditPath, &QToolButton::clicked, this, &ActionProperty::editPath); connect(ButtonRemovePath, &QToolButton::clicked, this, &ActionProperty::removePath); connect(ButtonAddMime, &QToolButton::clicked, this, &ActionProperty::addMime); connect(ButtonEditMime, &QToolButton::clicked, this, &ActionProperty::editMime); connect(ButtonRemoveMime, &QToolButton::clicked, this, &ActionProperty::removeMime); connect(ButtonNewFile, &QToolButton::clicked, this, &ActionProperty::newFile); connect(ButtonEditFile, &QToolButton::clicked, this, &ActionProperty::editFile); connect(ButtonRemoveFile, &QToolButton::clicked, this, &ActionProperty::removeFile); connect(KeyButtonShortcut, &KKeySequenceWidget::keySequenceChanged, this, &ActionProperty::changedShortcut); // track modifications: connect(leDistinctName, &KLineEdit::textChanged, this, [=]() { setModified(true); }); connect(leTitle, &KLineEdit::textChanged, this, [=]() {setModified(true); }); connect(ButtonIcon, &KIconButton::iconChanged, this, [=]() {setModified(true); }); connect(cbCategory, &KComboBox::currentTextChanged, this, [=]() {setModified(true); }); connect(leTooltip, &KLineEdit::textChanged, this, [=]() {setModified(true); }); connect(textDescription, &KTextEdit::textChanged, this, [=]() {setModified(true); }); connect(leCommandline, &KLineEdit::textChanged, this, [=]() {setModified(true); }); connect(leStartpath, &KLineEdit::textChanged, this, [=]() {setModified(true); }); connect(chkSeparateStdError, &QCheckBox::clicked, this, &ActionProperty::setModified); connect(radioCollectOutput, &QRadioButton::clicked, this, &ActionProperty::setModified); connect(radioNormal, &QRadioButton::clicked, this, &ActionProperty::setModified); connect(radioTE, &QRadioButton::clicked, this, &ActionProperty::setModified); connect(radioTerminal, &QRadioButton::clicked, this, &ActionProperty::setModified); connect(radioLocal, &QRadioButton::clicked, this, &ActionProperty::setModified); connect(radioUrl, &QRadioButton::clicked, this, &ActionProperty::setModified); connect(KeyButtonShortcut, &KKeySequenceWidget::keySequenceChanged, this, [=]() {setModified(true); }); connect(chkEnabled, &QCheckBox::clicked, this, &ActionProperty::setModified); connect(leDifferentUser, &KLineEdit::textChanged, this, [=]() {setModified(true); }); connect(chkDifferentUser, &QCheckBox::clicked, this, &ActionProperty::setModified); connect(chkConfirmExecution, &QCheckBox::clicked, this, &ActionProperty::setModified); connect(chkSeparateStdError, &QCheckBox::clicked, this, &ActionProperty::setModified); // The modified-state of the ShowOnly-lists is tracked in the access-functions below } ActionProperty::~ActionProperty() -{ -} += default; void ActionProperty::changedShortcut(const QKeySequence& shortcut) { KeyButtonShortcut->setKeySequence(shortcut); } void ActionProperty::clear() { - _action = 0; + _action = nullptr; // This prevents the changed-signal from being emitted during the GUI-update _modified = true; // The real state is set at the end of this function. leDistinctName->clear(); cbCategory->clearEditText(); leTitle->clear(); leTooltip->clear(); textDescription->clear(); leCommandline->clear(); leStartpath->clear(); KeyButtonShortcut->clearKeySequence(); lbShowonlyProtocol->clear(); lbShowonlyPath->clear(); lbShowonlyMime->clear(); lbShowonlyFile->clear(); chkSeparateStdError->setChecked(false); radioNormal->setChecked(true); radioLocal->setChecked(true); chkEnabled->setChecked(true); chkConfirmExecution->setChecked(false); ButtonIcon->resetIcon(); leDifferentUser->clear(); chkDifferentUser->setChecked(false); setModified(false); } void ActionProperty::updateGUI(KrAction *action) { if (action) _action = action; if (! _action) return; // This prevents the changed-signal from being emitted during the GUI-update. _modified = true; // The real state is set at the end of this function. leDistinctName->setText(_action->objectName()); cbCategory->lineEdit()->setText(_action->category()); leTitle->setText(_action->text()); leTooltip->setText(_action->toolTip()); textDescription->setText(_action->whatsThis()); leCommandline->setText(_action->command()); leCommandline->home(false); leStartpath->setText(_action->startpath()); KeyButtonShortcut->setKeySequence(_action->shortcut()); lbShowonlyProtocol->clear(); lbShowonlyProtocol->addItems(_action->showonlyProtocol()); lbShowonlyPath->clear(); lbShowonlyPath->addItems(_action->showonlyPath()); lbShowonlyMime->clear(); lbShowonlyMime->addItems(_action->showonlyMime()); lbShowonlyFile->clear(); lbShowonlyFile->addItems(_action->showonlyFile()); chkSeparateStdError->setChecked(false); switch (_action->execType()) { case KrAction::CollectOutputSeparateStderr: chkSeparateStdError->setChecked(true); radioCollectOutput->setChecked(true); break; case KrAction::CollectOutput: radioCollectOutput->setChecked(true); break; case KrAction::Terminal: radioTerminal->setChecked(true); break; case KrAction::RunInTE: radioTE->setChecked(true); break; default: // case KrAction::Normal: radioNormal->setChecked(true); break; } if (_action->acceptURLs()) radioUrl->setChecked(true); else radioLocal->setChecked(true); chkEnabled->setChecked(_action->isVisible()); chkConfirmExecution->setChecked(_action->confirmExecution()); if (! _action->icon().isNull()) ButtonIcon->setIcon(_action->icon()); else ButtonIcon->resetIcon(); leDifferentUser->setText(_action->user()); if (_action->user().isEmpty()) chkDifferentUser->setChecked(false); else chkDifferentUser->setChecked(true); setModified(false); } void ActionProperty::updateAction(KrAction *action) { if (action) _action = action; if (! _action) return; if (_action->category() != cbCategory->currentText()) { _action->setCategory(cbCategory->currentText()); // Update the category-list cbCategory->clear(); cbCategory->addItems(krUserAction->allCategories()); cbCategory->lineEdit()->setText(_action->category()); } _action->setObjectName(leDistinctName->text()); _action->setText(leTitle->text()); _action->setToolTip(leTooltip->text()); _action->setWhatsThis(textDescription->toPlainText()); _action->setCommand(leCommandline->text()); _action->setStartpath(leStartpath->text()); _action->setShortcut(KeyButtonShortcut->keySequence()); QStringList list; for (int i1 = 0; i1 != lbShowonlyProtocol->count(); i1++) { QListWidgetItem* lbi = lbShowonlyProtocol->item(i1); list << lbi->text(); } _action->setShowonlyProtocol(list); list = QStringList(); for (int i1 = 0; i1 != lbShowonlyPath->count(); i1++) { QListWidgetItem* lbi = lbShowonlyPath->item(i1); list << lbi->text(); } _action->setShowonlyPath(list); list = QStringList(); for (int i1 = 0; i1 != lbShowonlyMime->count(); i1++) { QListWidgetItem* lbi = lbShowonlyMime->item(i1); list << lbi->text(); } _action->setShowonlyMime(list); list = QStringList(); for (int i1 = 0; i1 != lbShowonlyFile->count(); i1++) { QListWidgetItem* lbi = lbShowonlyFile->item(i1); list << lbi->text(); } _action->setShowonlyFile(list); if (radioCollectOutput->isChecked() && chkSeparateStdError->isChecked()) _action->setExecType(KrAction::CollectOutputSeparateStderr); else if (radioCollectOutput->isChecked() && ! chkSeparateStdError->isChecked()) _action->setExecType(KrAction::CollectOutput); else if (radioTerminal->isChecked()) _action->setExecType(KrAction::Terminal); else if (radioTE->isChecked()) _action->setExecType(KrAction::RunInTE); else _action->setExecType(KrAction::Normal); if (radioUrl->isChecked()) _action->setAcceptURLs(true); else _action->setAcceptURLs(false); _action->setEnabled(chkEnabled->isChecked()); _action->setVisible(chkEnabled->isChecked()); _action->setConfirmExecution(chkConfirmExecution->isChecked()); _action->setIcon(Icon(ButtonIcon->icon())); _action->setIconName(ButtonIcon->icon()); _action->setUser(leDifferentUser->text()); setModified(false); } void ActionProperty::addPlaceholder() { AddPlaceholderPopup popup(this); QString exp = popup.getPlaceholder(mapToGlobal( QPoint( ButtonAddPlaceholder->pos().x() + ButtonAddPlaceholder->width() + 6, // 6 is the default margin ButtonAddPlaceholder->pos().y() ) )); leCommandline->insert(exp); } void ActionProperty::addStartpath() { QString folder = QFileDialog::getExistingDirectory(this); if (!folder.isEmpty()) { leStartpath->setText(folder); } } void ActionProperty::newProtocol() { bool ok; QString currentText; if (lbShowonlyProtocol->currentItem()) currentText = lbShowonlyProtocol->currentItem()->text(); QString text = QInputDialog::getText(this, i18n("New protocol"), i18n("Set a protocol:"), QLineEdit::Normal, currentText, &ok); if (ok && !text.isEmpty()) { lbShowonlyProtocol->addItems(text.split(';')); setModified(); } } void ActionProperty::editProtocol() { - if (lbShowonlyProtocol->currentItem() == 0) + if (lbShowonlyProtocol->currentItem() == nullptr) return; bool ok; QString currentText = lbShowonlyProtocol->currentItem()->text(); QString text = QInputDialog::getText(this, i18n("Edit Protocol"), i18n("Set another protocol:"), QLineEdit::Normal, currentText, &ok); if (ok && !text.isEmpty()) { lbShowonlyProtocol->currentItem()->setText(text); setModified(); } } void ActionProperty::removeProtocol() { - if (lbShowonlyProtocol->currentItem() != 0) { + if (lbShowonlyProtocol->currentItem() != nullptr) { delete lbShowonlyProtocol->currentItem(); setModified(); } } void ActionProperty::addPath() { QString folder = QFileDialog::getExistingDirectory(this); if (!folder.isEmpty()) { lbShowonlyPath->addItem(folder); setModified(); } } void ActionProperty::editPath() { - if (lbShowonlyPath->currentItem() == 0) + if (lbShowonlyPath->currentItem() == nullptr) return; bool ok; QString currentText = lbShowonlyPath->currentItem()->text(); QString text = QInputDialog::getText(this, i18n("Edit Path"), i18n("Set another path:"), QLineEdit::Normal, currentText, &ok); if (ok && !text.isEmpty()) { lbShowonlyPath->currentItem()->setText(text); setModified(); } } void ActionProperty::removePath() { - if (lbShowonlyPath->currentItem() != 0) { + if (lbShowonlyPath->currentItem() != nullptr) { delete lbShowonlyPath->currentItem(); setModified(); } } void ActionProperty::addMime() { bool ok; QString currentText; if (lbShowonlyMime->currentItem()) currentText = lbShowonlyMime->currentItem()->text(); QString text = QInputDialog::getText(this, i18n("New MIME Type"), i18n("Set a MIME type:"), QLineEdit::Normal, currentText, &ok); if (ok && !text.isEmpty()) { lbShowonlyMime->addItems(text.split(';')); setModified(); } } void ActionProperty::editMime() { - if (lbShowonlyMime->currentItem() == 0) + if (lbShowonlyMime->currentItem() == nullptr) return; bool ok; QString currentText = lbShowonlyMime->currentItem()->text(); QString text = QInputDialog::getText(this, i18n("Edit MIME Type"), i18n("Set another MIME type:"), QLineEdit::Normal, currentText, &ok); if (ok && !text.isEmpty()) { lbShowonlyMime->currentItem()->setText(text); setModified(); } } void ActionProperty::removeMime() { - if (lbShowonlyMime->currentItem() != 0) { + if (lbShowonlyMime->currentItem() != nullptr) { delete lbShowonlyMime->currentItem(); setModified(); } } void ActionProperty::newFile() { bool ok; QString currentText; if (lbShowonlyFile->currentItem()) currentText = lbShowonlyFile->currentItem()->text(); QString text = QInputDialog::getText(this, i18n("New File Name"), i18n("Set a file name:"), QLineEdit::Normal, currentText, &ok); if (ok && !text.isEmpty()) { lbShowonlyFile->addItems(text.split(';')); setModified(); } } void ActionProperty::editFile() { - if (lbShowonlyFile->currentItem() == 0) + if (lbShowonlyFile->currentItem() == nullptr) return; bool ok; QString currentText = lbShowonlyFile->currentItem()->text(); QString text = QInputDialog::getText(this, i18n("Edit File Name"), i18n("Set another file name:"), QLineEdit::Normal, currentText, &ok); if (ok && !text.isEmpty()) { lbShowonlyFile->currentItem()->setText(text); setModified(); } } void ActionProperty::removeFile() { - if (lbShowonlyFile->currentItem() != 0) { + if (lbShowonlyFile->currentItem() != nullptr) { delete lbShowonlyFile->currentItem(); setModified(); } } bool ActionProperty::validProperties() { if (leDistinctName->text().simplified().isEmpty()) { KMessageBox::error(this, i18n("Please set a unique name for the useraction")); leDistinctName->setFocus(); return false; } if (leTitle->text().simplified().isEmpty()) { KMessageBox::error(this, i18n("Please set a title for the menu entry")); leTitle->setFocus(); return false; } if (leCommandline->text().simplified().isEmpty()) { KMessageBox::error(this, i18n("Command line is empty")); leCommandline->setFocus(); return false; } if (leDistinctName->isEnabled()) if (krApp->actionCollection()->action(leDistinctName->text())) { KMessageBox::error(this, i18n("There already is an action with this name.\n" "If you do not have such a useraction the name is used by Krusader for an internal action.") ); leDistinctName->setFocus(); return false; } return true; } void ActionProperty::setModified(bool m) { if (m && !_modified) { // emit only when the state _changes_to_true_, emit changed(); } _modified = m; } diff --git a/krusader/ActionMan/actionproperty.h b/krusader/ActionMan/actionproperty.h index 08caf115..612ead87 100644 --- a/krusader/ActionMan/actionproperty.h +++ b/krusader/ActionMan/actionproperty.h @@ -1,157 +1,157 @@ /***************************************************************************** * Copyright (C) 2004-2007 Jonas Bähr * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef ACTIONPROPERTY_H #define ACTIONPROPERTY_H #include "ui_actionproperty.h" class KrAction; /** * Use this widget where ever you need to manipulate a UserAction */ class ActionProperty : public QWidget, public Ui::ActionProperty { Q_OBJECT public: - explicit ActionProperty(QWidget *parent = 0, KrAction *action = 0); - ~ActionProperty(); + explicit ActionProperty(QWidget *parent = nullptr, KrAction *action = nullptr); + ~ActionProperty() override; /** * @return the currently displayed action */ KrAction* action() { return _action; }; /** * This inits the widget with the actions properties. * If no action is provided, the last used will be taken! * It also resets the changed() state. * @param action the action which should be displayd */ - void updateGUI(KrAction *action = 0); + void updateGUI(KrAction *action = nullptr); /** * This writes the displayed properties back into the action. * If no action is provided, the last used will be taken! * It also resets the changed() state. * @param action the action which should be manipulated */ - void updateAction(KrAction *action = 0); + void updateAction(KrAction *action = nullptr); /** * clears everything */ void clear(); /** * @return true if all properties got valid values */ bool validProperties(); /** * @return true if any property got changed */ bool isModified() { return _modified; }; signals: /** * emitted when any actionproperty changed. This signal is only emitted when * the _modified attribute changes to true. If there are changes made and * _modified is already true, no signal is emitted! */ void changed(); protected slots: void setModified(bool m = true); /** * executes the AddPlaceholderPopup */ void addPlaceholder(); /** * asks for an existing path */ void addStartpath(); /** * (availability) asks for a new protocol */ void newProtocol(); /** * (availability) changes a protocol of the list */ void editProtocol(); /** * (availability) removes a protocol from the list */ void removeProtocol(); /** * (availability) asks for a new path */ void addPath(); /** * (availability) edits a path of the list */ void editPath(); /** * (availability) removes a path from the list */ void removePath(); /** * (availability) asks for a new mime-type */ void addMime(); /** * (availability) changes a mime-type of the list */ void editMime(); /** * (availability) removes a mime-type from the list */ void removeMime(); /** * (availability) asks for a new file-filter */ void newFile(); /** * (availability) edits a file-filter of the list */ void editFile(); /** * (availability) removes a file-filter from the lsit */ void removeFile(); private: KrAction *_action; bool _modified; private slots: /** * This updates the ShortcutButton * @internal */ void changedShortcut(const QKeySequence& shortcut); }; #endif diff --git a/krusader/ActionMan/addplaceholderpopup.cpp b/krusader/ActionMan/addplaceholderpopup.cpp index 845ceb9f..406b5c51 100644 --- a/krusader/ActionMan/addplaceholderpopup.cpp +++ b/krusader/ActionMan/addplaceholderpopup.cpp @@ -1,703 +1,703 @@ /***************************************************************************** * Copyright (C) 2004 Shie Erlich * * Copyright (C) 2004 Rafi Yanai * * Copyright (C) 2004 Jonas Bähr * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "addplaceholderpopup.h" // for ParameterDialog #include "../krglobal.h" // for konfig-access #include "../icon.h" #include "../BookMan/krbookmarkbutton.h" #include "../GUI/profilemanager.h" // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define ACTIVE_MASK 0x0100 #define OTHER_MASK 0x0200 #define LEFT_MASK 0x0400 #define RIGHT_MASK 0x0800 #define INDEPENDENT_MASK 0x1000 #define EXECUTABLE_ID 0xFFFF AddPlaceholderPopup::AddPlaceholderPopup(QWidget *parent) : QMenu(parent) { _activeSub = new QMenu(i18n("Active panel"), this); _otherSub = new QMenu(i18n("Other panel"), this); _leftSub = new QMenu(i18n("Left panel"), this); _rightSub = new QMenu(i18n("Right panel"), this); _independentSub = new QMenu(i18n("Panel independent"), this); addMenu(_activeSub); addMenu(_otherSub); addMenu(_leftSub); addMenu(_rightSub); addMenu(_independentSub); QAction *chooseExecAct = _independentSub->addAction(i18n("Choose executable...")); chooseExecAct->setData(QVariant(EXECUTABLE_ID)); _independentSub->addSeparator(); // read the expressions array from the user menu and populate menus Expander expander; for (int i = 0; i < expander.placeholderCount(); ++i) { if (expander.placeholder(i)->expression().isEmpty()) { if (expander.placeholder(i)->needPanel()) { _activeSub->addSeparator(); _otherSub->addSeparator(); _leftSub->addSeparator(); _rightSub->addSeparator(); } else _independentSub->addSeparator(); } else { QAction * action; if (expander.placeholder(i)->needPanel()) { action = _activeSub->addAction(i18n(expander.placeholder(i)->description().toUtf8())); action->setData(QVariant(i | ACTIVE_MASK)); action = _otherSub->addAction(i18n(expander.placeholder(i)->description().toUtf8())); action->setData(QVariant(i | OTHER_MASK)); action = _leftSub->addAction(i18n(expander.placeholder(i)->description().toUtf8())); action->setData(QVariant(i | LEFT_MASK)); action = _rightSub->addAction(i18n(expander.placeholder(i)->description().toUtf8())); action->setData(QVariant(i | RIGHT_MASK)); } else { action = _independentSub->addAction(i18n(expander.placeholder(i)->description().toUtf8())); action->setData(QVariant(i | INDEPENDENT_MASK)); } } } } QString AddPlaceholderPopup::getPlaceholder(const QPoint& pos) { QAction *res = exec(pos); - if (res == 0) + if (res == nullptr) return QString(); // add the selected flag to the command line if (res->data().toInt() == EXECUTABLE_ID) { // did the user need an executable ? // select an executable QString filename = QFileDialog::getOpenFileName(this); if (!filename.isEmpty()) { return filename + ' '; // with extra space // return filename; // without extra space } } else { // user selected something from the menus Expander expander; const exp_placeholder* currentPlaceholder = expander.placeholder(res->data().toInt() & ~(ACTIVE_MASK | OTHER_MASK | LEFT_MASK | RIGHT_MASK | INDEPENDENT_MASK)); // if ( ¤tPlaceholder->expFunc == 0 ) { // KMessageBox::sorry( this, "BOFH Excuse #93:\nFeature not yet implemented" ); // return QString(); // } - ParameterDialog* parameterDialog = new ParameterDialog(currentPlaceholder, this); + auto* parameterDialog = new ParameterDialog(currentPlaceholder, this); QString panel, parameter = parameterDialog->getParameter(); delete parameterDialog; // indicate the panel with 'a' 'o', 'l', 'r' or '_'. if (res->data().toInt() & ACTIVE_MASK) panel = 'a'; else if (res->data().toInt() & OTHER_MASK) panel = 'o'; else if (res->data().toInt() & LEFT_MASK) panel = 'l'; else if (res->data().toInt() & RIGHT_MASK) panel = 'r'; else if (res->data().toInt() & INDEPENDENT_MASK) panel = '_'; //return '%' + panel + currentPlaceholder->expression() + parameter + "% "; // with extra space return '%' + panel + currentPlaceholder->expression() + parameter + '%'; // without extra space } return QString(); } //////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////// ParameterDialog //////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////// ParameterDialog::ParameterDialog(const exp_placeholder* currentPlaceholder, QWidget *parent) : QDialog(parent) { setWindowTitle(i18n("User Action Parameter Dialog")); - QVBoxLayout *mainLayout = new QVBoxLayout; + auto *mainLayout = new QVBoxLayout; setLayout(mainLayout); _parameter.clear(); _parameterCount = currentPlaceholder->parameterCount(); QWidget *page = new QWidget(this); mainLayout->addWidget(page); - QVBoxLayout* layout = new QVBoxLayout(page); + auto* layout = new QVBoxLayout(page); layout->setSpacing(11); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(new QLabel(i18n("This placeholder allows some parameter:"), page)); for (int i = 0; i < _parameterCount; ++i) { if (currentPlaceholder->parameter(i).preset() == "__placeholder") _parameter.append(new ParameterPlaceholder(currentPlaceholder->parameter(i), page)); else if (currentPlaceholder->parameter(i).preset() == "__yes") _parameter.append(new ParameterYes(currentPlaceholder->parameter(i), page)); else if (currentPlaceholder->parameter(i).preset() == "__no") _parameter.append(new ParameterNo(currentPlaceholder->parameter(i), page)); else if (currentPlaceholder->parameter(i).preset() == "__file") _parameter.append(new ParameterFile(currentPlaceholder->parameter(i), page)); else if (currentPlaceholder->parameter(i).preset().indexOf("__choose") != -1) _parameter.append(new ParameterChoose(currentPlaceholder->parameter(i), page)); else if (currentPlaceholder->parameter(i).preset() == "__select") _parameter.append(new ParameterSelect(currentPlaceholder->parameter(i), page)); else if (currentPlaceholder->parameter(i).preset() == "__goto") _parameter.append(new ParameterGoto(currentPlaceholder->parameter(i), page)); else if (currentPlaceholder->parameter(i).preset() == "__syncprofile") _parameter.append(new ParameterSyncprofile(currentPlaceholder->parameter(i), page)); else if (currentPlaceholder->parameter(i).preset() == "__searchprofile") _parameter.append(new ParameterSearch(currentPlaceholder->parameter(i), page)); else if (currentPlaceholder->parameter(i).preset() == "__panelprofile") _parameter.append(new ParameterPanelprofile(currentPlaceholder->parameter(i), page)); else if (currentPlaceholder->parameter(i).preset().indexOf("__int") != -1) _parameter.append(new ParameterInt(currentPlaceholder->parameter(i), page)); else _parameter.append(new ParameterText(currentPlaceholder->parameter(i), page)); layout->addWidget(_parameter.last()); } QFrame * line = new QFrame(page); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); layout->addWidget(line); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults); mainLayout->addWidget(buttonBox); QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); okButton->setDefault(true); okButton->setShortcut(Qt::CTRL | Qt::Key_Return); connect(okButton, &QPushButton:: clicked, this, &ParameterDialog::slotOk); connect(buttonBox, &QDialogButtonBox::accepted, this, &ParameterDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &ParameterDialog::reject); connect(buttonBox->button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked, this, &ParameterDialog::reset); } QString ParameterDialog::getParameter() { if (_parameterCount == 0) // meaning no parameters return QString(); if (exec() == -1) return QString(); int lastParameter = _parameterCount; while (--lastParameter > -1) { if (_parameter[ lastParameter ]->text() != _parameter[ lastParameter ]->preset() || _parameter[ lastParameter ]->necessary()) break; } if (lastParameter < 0) // all parameters have default-values return QString(); QString parameter; for (int i = 0; i <= lastParameter; ++i) { if (i > 0) parameter += ", "; parameter += '\"' + _parameter[ i ]->text().replace('\"', "\\\"") + '\"'; } return '(' + parameter + ')'; } void ParameterDialog::reset() { for (int i = 0; i < _parameterCount; ++i) _parameter[ i ]->reset(); } void ParameterDialog::slotOk() { bool valid = true; for (int i = 0; i < _parameterCount; ++i) { if (_parameter[ i ]->necessary() && ! _parameter[ i ]->valid()) valid = false; } if (valid) accept(); } ///////////// ParameterText ParameterText::ParameterText(const exp_parameter& parameter, QWidget* parent) : ParameterBase(parameter, parent) { - QVBoxLayout* layout = new QVBoxLayout(this); + auto* layout = new QVBoxLayout(this); layout->setSpacing(6); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(new QLabel(i18n(parameter.description().toUtf8()), this)); layout->addWidget(_lineEdit = new KLineEdit(parameter.preset(), this)); _preset = parameter.preset(); } QString ParameterText::text() { return _lineEdit->text(); } QString ParameterText::preset() { return _preset; } void ParameterText::reset() { _lineEdit->setText(_preset); } bool ParameterText::valid() { if (_lineEdit->text().isEmpty()) return false; else return true; } ///////////// ParameterPlaceholder ParameterPlaceholder::ParameterPlaceholder(const exp_parameter& parameter, QWidget* parent) : ParameterBase(parameter, parent) { - QVBoxLayout* layout = new QVBoxLayout(this); + auto* layout = new QVBoxLayout(this); layout->setSpacing(6); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(new QLabel(i18n(parameter.description().toUtf8()), this)); QWidget * hboxWidget = new QWidget(this); layout->addWidget(hboxWidget); - QHBoxLayout * hbox = new QHBoxLayout(hboxWidget); + auto * hbox = new QHBoxLayout(hboxWidget); hbox->setContentsMargins(0, 0, 0, 0); hbox->setSpacing(6); _lineEdit = new KLineEdit(hboxWidget); hbox->addWidget(_lineEdit); _button = new QToolButton(hboxWidget); _button->setIcon(Icon("list-add")); hbox->addWidget(_button); connect(_button, &QToolButton::clicked, this, &ParameterPlaceholder::addPlaceholder); } QString ParameterPlaceholder::text() { return _lineEdit->text(); } QString ParameterPlaceholder::preset() { return QString(); } void ParameterPlaceholder::reset() { _lineEdit->setText(QString()); } bool ParameterPlaceholder::valid() { if (_lineEdit->text().isEmpty()) return false; else return true; } void ParameterPlaceholder::addPlaceholder() { - AddPlaceholderPopup* popup = new AddPlaceholderPopup(this); + auto* popup = new AddPlaceholderPopup(this); QString exp = popup->getPlaceholder(mapToGlobal(QPoint(_button->pos().x() + _button->width() + 6, _button->pos().y() + _button->height() / 2))); _lineEdit->insert(exp); delete popup; } ///////////// ParameterYes ParameterYes::ParameterYes(const exp_parameter& parameter, QWidget* parent) : ParameterBase(parameter, parent) { - QVBoxLayout* layout = new QVBoxLayout(this); + auto* layout = new QVBoxLayout(this); layout->setSpacing(6); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(_checkBox = new QCheckBox(i18n(parameter.description().toUtf8()), this)); _checkBox->setChecked(true); } QString ParameterYes::text() { if (_checkBox->isChecked()) return QString(); else return "No"; } QString ParameterYes::preset() { return QString(); } void ParameterYes::reset() { _checkBox->setChecked(true); } bool ParameterYes::valid() { return true; } ///////////// ParameterNo ParameterNo::ParameterNo(const exp_parameter& parameter, QWidget* parent) : ParameterBase(parameter, parent) { - QVBoxLayout* layout = new QVBoxLayout(this); + auto* layout = new QVBoxLayout(this); layout->setSpacing(6); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(_checkBox = new QCheckBox(i18n(parameter.description().toUtf8()), this)); _checkBox->setChecked(false); } QString ParameterNo::text() { if (_checkBox->isChecked()) return "Yes"; else return QString(); } QString ParameterNo::preset() { return QString(); } void ParameterNo::reset() { _checkBox->setChecked(false); } bool ParameterNo::valid() { return true; } ///////////// ParameterFile ParameterFile::ParameterFile(const exp_parameter& parameter, QWidget* parent) : ParameterBase(parameter, parent) { - QVBoxLayout* layout = new QVBoxLayout(this); + auto* layout = new QVBoxLayout(this); layout->setSpacing(6); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(new QLabel(i18n(parameter.description().toUtf8()), this)); QWidget * hboxWidget = new QWidget(this); layout->addWidget(hboxWidget); - QHBoxLayout * hbox = new QHBoxLayout(hboxWidget); + auto * hbox = new QHBoxLayout(hboxWidget); hbox->setContentsMargins(0, 0, 0, 0); hbox->setSpacing(6); _lineEdit = new KLineEdit(hboxWidget); hbox->addWidget(_lineEdit); _button = new QToolButton(hboxWidget); hbox->addWidget(_button); _button->setIcon(Icon("document-open")); connect(_button, &QToolButton::clicked, this, &ParameterFile::addFile); } QString ParameterFile::text() { return _lineEdit->text(); } QString ParameterFile::preset() { return QString(); } void ParameterFile::reset() { _lineEdit->setText(QString()); } bool ParameterFile::valid() { if (_lineEdit->text().isEmpty()) return false; else return true; } void ParameterFile::addFile() { QString filename = QFileDialog::getOpenFileName(this); _lineEdit->insert(filename); } ///////////// ParameterChoose ParameterChoose::ParameterChoose(const exp_parameter& parameter, QWidget* parent) : ParameterBase(parameter, parent) { - QVBoxLayout* layout = new QVBoxLayout(this); + auto* layout = new QVBoxLayout(this); layout->setSpacing(6); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(new QLabel(i18n(parameter.description().toUtf8()), this)); layout->addWidget(_combobox = new KComboBox(this)); _combobox->addItems(parameter.preset().section(':', 1).split(';')); } QString ParameterChoose::text() { return _combobox->currentText(); } QString ParameterChoose::preset() { return _combobox->itemText(0); } void ParameterChoose::reset() { _combobox->setCurrentIndex(0); } bool ParameterChoose::valid() { return true; } ///////////// ParameterSelect ParameterSelect::ParameterSelect(const exp_parameter& parameter, QWidget* parent) : ParameterBase(parameter, parent) { - QVBoxLayout* layout = new QVBoxLayout(this); + auto* layout = new QVBoxLayout(this); layout->setSpacing(6); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(new QLabel(i18n(parameter.description().toUtf8()), this)); layout->addWidget(_combobox = new KComboBox(this)); _combobox->setEditable(true); KConfigGroup group(krConfig, "Private"); QStringList lst = group.readEntry("Predefined Selections", QStringList()); if (lst.size() > 0) _combobox->addItems(lst); _combobox->lineEdit()->setText("*"); } QString ParameterSelect::text() { return _combobox->currentText(); } QString ParameterSelect::preset() { return "*"; } void ParameterSelect::reset() { _combobox->lineEdit()->setText("*"); } bool ParameterSelect::valid() { return true; } ///////////// ParameterGoto ParameterGoto::ParameterGoto(const exp_parameter& parameter, QWidget* parent) : ParameterBase(parameter, parent) { - QVBoxLayout* layout = new QVBoxLayout(this); + auto* layout = new QVBoxLayout(this); layout->setSpacing(6); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(new QLabel(i18n(parameter.description().toUtf8()), this)); QWidget * hboxWidget = new QWidget(this); - QHBoxLayout * hbox = new QHBoxLayout(hboxWidget); + auto * hbox = new QHBoxLayout(hboxWidget); hbox->setContentsMargins(0, 0, 0, 0); hbox->setSpacing(6); _lineEdit = new KLineEdit(hboxWidget); _lineEdit->setCompletionObject(new KUrlCompletion(KUrlCompletion::DirCompletion)); hbox->addWidget(_lineEdit); _dirButton = new QToolButton(hboxWidget); hbox->addWidget(_dirButton); _dirButton->setIcon(Icon("document-open")); connect(_dirButton, &QToolButton::clicked, this, &ParameterGoto::setDir); _placeholderButton = new QToolButton(hboxWidget); _placeholderButton->setIcon(Icon("list-add")); hbox->addWidget(_placeholderButton); connect(_placeholderButton, &QToolButton::clicked, this, &ParameterGoto::addPlaceholder); layout->addWidget(hboxWidget); } QString ParameterGoto::text() { return _lineEdit->text(); } QString ParameterGoto::preset() { return QString(); } void ParameterGoto::reset() { _lineEdit->setText(QString()); } bool ParameterGoto::valid() { if (_lineEdit->text().isEmpty()) return false; else return true; } void ParameterGoto::setDir() { QString folder = QFileDialog::getExistingDirectory(this); _lineEdit->setText(folder); } void ParameterGoto::addPlaceholder() { - AddPlaceholderPopup* popup = new AddPlaceholderPopup(this); + auto* popup = new AddPlaceholderPopup(this); QString exp = popup->getPlaceholder(mapToGlobal(QPoint(_placeholderButton->pos().x() + _placeholderButton->width() + 6, _placeholderButton->pos().y() + _placeholderButton->height() / 2))); _lineEdit->insert(exp); delete popup; } ///////////// ParameterSyncprofile ParameterSyncprofile::ParameterSyncprofile(const exp_parameter& parameter, QWidget* parent) : ParameterBase(parameter, parent) { - QVBoxLayout* layout = new QVBoxLayout(this); + auto* layout = new QVBoxLayout(this); layout->setSpacing(6); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(new QLabel(i18n(parameter.description().toUtf8()), this)); layout->addWidget(_combobox = new KComboBox(this)); _combobox->addItems(ProfileManager::availableProfiles("SynchronizerProfile")); } QString ParameterSyncprofile::text() { return _combobox->currentText(); } QString ParameterSyncprofile::preset() { return _combobox->itemText(0); } void ParameterSyncprofile::reset() { _combobox->setCurrentIndex(0); } bool ParameterSyncprofile::valid() { return true; } ///////////// ParameterSearch ParameterSearch::ParameterSearch(const exp_parameter& parameter, QWidget* parent) : ParameterBase(parameter, parent) { - QVBoxLayout* layout = new QVBoxLayout(this); + auto* layout = new QVBoxLayout(this); layout->setSpacing(6); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(new QLabel(i18n(parameter.description().toUtf8()), this)); layout->addWidget(_combobox = new KComboBox(this)); _combobox->addItems(ProfileManager::availableProfiles("SearcherProfile")); } QString ParameterSearch::text() { return _combobox->currentText(); } QString ParameterSearch::preset() { return _combobox->itemText(0); } void ParameterSearch::reset() { _combobox->setCurrentIndex(0); } bool ParameterSearch::valid() { return true; } ///////////// ParameterPanelprofile ParameterPanelprofile::ParameterPanelprofile(const exp_parameter& parameter, QWidget* parent) : ParameterBase(parameter, parent) { - QVBoxLayout* layout = new QVBoxLayout(this); + auto* layout = new QVBoxLayout(this); layout->setSpacing(6); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(new QLabel(i18n(parameter.description().toUtf8()), this)); layout->addWidget(_combobox = new KComboBox(this)); _combobox->addItems(ProfileManager::availableProfiles("Panel")); } QString ParameterPanelprofile::text() { return _combobox->currentText(); } QString ParameterPanelprofile::preset() { return _combobox->itemText(0); } void ParameterPanelprofile::reset() { _combobox->setCurrentIndex(0); } bool ParameterPanelprofile::valid() { return true; } ///////////// ParameterInt ParameterInt::ParameterInt(const exp_parameter& parameter, QWidget* parent) : ParameterBase(parameter, parent) { - QHBoxLayout* layout = new QHBoxLayout(this); + auto* layout = new QHBoxLayout(this); layout->setSpacing(6); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(new QLabel(i18n(parameter.description().toUtf8()), this)); layout->addWidget(_spinbox = new QSpinBox(this)); QStringList para = parameter.preset().section(':', 1).split(';'); _spinbox->setMinimum(para[0].toInt()); _spinbox->setMaximum(para[1].toInt()); _spinbox->setSingleStep(para[2].toInt()); _spinbox->setValue(para[3].toInt()); _default = _spinbox->value(); } QString ParameterInt::text() { return _spinbox->text(); } QString ParameterInt::preset() { return QString("%1").arg(_default); } void ParameterInt::reset() { return _spinbox->setValue(_default); } bool ParameterInt::valid() { return true; } diff --git a/krusader/ActionMan/useractionlistview.cpp b/krusader/ActionMan/useractionlistview.cpp index e58634b5..3e3a3216 100644 --- a/krusader/ActionMan/useractionlistview.cpp +++ b/krusader/ActionMan/useractionlistview.cpp @@ -1,255 +1,251 @@ /***************************************************************************** * Copyright (C) 2006 Jonas Bähr * * Copyright (C) 2006-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "useractionlistview.h" // QtCore #include // QtXml #include #include #include "../krglobal.h" #include "../icon.h" #include "../UserAction/kraction.h" #include "../UserAction/useraction.h" #define COL_TITLE 0 // UserActionListView UserActionListView::UserActionListView(QWidget * parent) : KrTreeWidget(parent) { setHeaderLabel(i18n("Title")); setRootIsDecorated(true); setSelectionMode(QAbstractItemView::ExtendedSelection); // normally select single items but one may use Ctrl or Shift to select multiple setSortingEnabled(true); sortItems(COL_TITLE, Qt::AscendingOrder); connect(this, &UserActionListView::currentItemChanged, this, &UserActionListView::slotCurrentItemChanged); update(); } UserActionListView::~UserActionListView() -{ -} += default; QSize UserActionListView::sizeHint() const { return QSize(200, 400); } void UserActionListView::update() { clear(); UserAction::KrActionList list = krUserAction->actionList(); QListIterator it(list); while (it.hasNext()) insertAction(it.next()); } void UserActionListView::update(KrAction* action) { UserActionListViewItem* item = findActionItem(action); if (item) { // deleting & re-inserting is _much_easier then tracking all possible cases of category changes! bool current = (item == currentItem()); bool selected = item->isSelected(); delete item; item = insertAction(action); if (current) setCurrentItem(item); if (selected) item->setSelected(true); } } UserActionListViewItem* UserActionListView::insertAction(KrAction* action) { if (! action) - return 0; + return nullptr; UserActionListViewItem* item; if (action->category().isEmpty()) item = new UserActionListViewItem(this, action); else { QTreeWidgetItem* categoryItem = findCategoryItem(action->category()); if (! categoryItem) { categoryItem = new QTreeWidgetItem(this); // create the new category item it not already present categoryItem->setText(0, action->category()); categoryItem->setFlags(Qt::ItemIsEnabled); } item = new UserActionListViewItem(categoryItem, action); } item->setAction(action); return item; } QTreeWidgetItem* UserActionListView::findCategoryItem(const QString& category) { QTreeWidgetItemIterator it(this); while (*it) { if ((*it)->text(COL_TITLE) == category && !((*it)->flags() & Qt::ItemIsSelectable)) return *it; it++; } - return 0; + return nullptr; } UserActionListViewItem* UserActionListView::findActionItem(const KrAction* action) { QTreeWidgetItemIterator it(this); while (*it) { - if (UserActionListViewItem* item = dynamic_cast(*it)) { + if (auto* item = dynamic_cast(*it)) { if (item->action() == action) return item; } it++; } - return 0; + return nullptr; } KrAction * UserActionListView::currentAction() const { - if (UserActionListViewItem* item = dynamic_cast(currentItem())) + if (auto* item = dynamic_cast(currentItem())) return item->action(); else - return 0; + return nullptr; } void UserActionListView::setCurrentAction(const KrAction* action) { UserActionListViewItem* item = findActionItem(action); if (item) { setCurrentItem(item); } } void UserActionListView::setFirstActionCurrent() { QTreeWidgetItemIterator it(this); while (*it) { - if (UserActionListViewItem* item = dynamic_cast(*it)) { + if (auto* item = dynamic_cast(*it)) { setCurrentItem(item); break; } it++; } } void UserActionListView::slotCurrentItemChanged(QTreeWidgetItem* item) { if (! item) return; scrollTo(indexOf(item)); } QDomDocument UserActionListView::dumpSelectedActions(QDomDocument* mergeDoc) const { QList list = selectedItems(); QDomDocument doc; if (mergeDoc) doc = *mergeDoc; else doc = UserAction::createEmptyDoc(); QDomElement root = doc.documentElement(); - for (int i = 0; i < list.size(); ++i) { - QTreeWidgetItem* item = list.at(i); - if (UserActionListViewItem* actionItem = dynamic_cast(item)) + for (auto item : list) { + if (auto* actionItem = dynamic_cast(item)) root.appendChild(actionItem->action()->xmlDump(doc)); } return doc; } void UserActionListView::removeSelectedActions() { QList list = selectedItems(); - for (int i = 0; i < list.size(); ++i) { - QTreeWidgetItem* item = list.at(i); - if (UserActionListViewItem* actionItem = dynamic_cast(item)) { + for (auto item : list) { + if (auto* actionItem = dynamic_cast(item)) { delete actionItem->action(); // remove the action itself delete actionItem; // remove the action from the list } // if } } // UserActionListViewItem UserActionListViewItem::UserActionListViewItem(QTreeWidget* view, KrAction* action) : QTreeWidgetItem(view) { setAction(action); } UserActionListViewItem::UserActionListViewItem(QTreeWidgetItem* item, KrAction * action) : QTreeWidgetItem(item) { setAction(action); } UserActionListViewItem::~UserActionListViewItem() -{ -} += default; void UserActionListViewItem::setAction(KrAction * action) { if (! action) return; _action = action; update(); } KrAction * UserActionListViewItem::action() const { return _action; } void UserActionListViewItem::update() { if (! _action) return; if (! _action->icon().isNull()) setIcon(COL_TITLE, Icon(_action->iconName())); setText(COL_TITLE, _action->text()); } bool UserActionListViewItem::operator<(const QTreeWidgetItem &other) const { // FIXME some how this only produces bullshit :-/ // if ( i->text( COL_NAME ).isEmpty() ) { // categories only have titles // //qDebug() << "this->title: " << text(COL_TITLE) << " |=| i->title: " << i->text(COL_TITLE); // return ( ascending ? -1 : 1 ); // <0 means this is smaller then i // } // else return QTreeWidgetItem::operator<(other); } diff --git a/krusader/ActionMan/useractionlistview.h b/krusader/ActionMan/useractionlistview.h index b66461a5..1f79339f 100644 --- a/krusader/ActionMan/useractionlistview.h +++ b/krusader/ActionMan/useractionlistview.h @@ -1,87 +1,87 @@ /***************************************************************************** * Copyright (C) 2006 Jonas Bähr * * Copyright (C) 2006-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef USERACTIONLISTVIEW_H #define USERACTIONLISTVIEW_H #include "../GUI/krtreewidget.h" class KrAction; class QString; class UserActionListViewItem; class QDomDocument; class UserActionListView : public KrTreeWidget { Q_OBJECT public: - explicit UserActionListView(QWidget* parent = 0); - ~UserActionListView(); - virtual QSize sizeHint() const Q_DECL_OVERRIDE; + explicit UserActionListView(QWidget* parent = nullptr); + ~UserActionListView() override; + QSize sizeHint() const Q_DECL_OVERRIDE; void update(); void update(KrAction* action); UserActionListViewItem* insertAction(KrAction* action); KrAction* currentAction() const; void setCurrentAction(const KrAction*); - QDomDocument dumpSelectedActions(QDomDocument* mergeDoc = 0) const; + QDomDocument dumpSelectedActions(QDomDocument* mergeDoc = nullptr) const; void removeSelectedActions(); /** * makes the first action in the list current */ void setFirstActionCurrent(); /** * makes @e item current and ensures its visibility */ protected slots: void slotCurrentItemChanged(QTreeWidgetItem*); protected: QTreeWidgetItem* findCategoryItem(const QString& category); UserActionListViewItem* findActionItem(const KrAction* action); }; class UserActionListViewItem : public QTreeWidgetItem { public: UserActionListViewItem(QTreeWidget* view, KrAction* action); UserActionListViewItem(QTreeWidgetItem* item, KrAction* action); - ~UserActionListViewItem(); + ~UserActionListViewItem() override; void setAction(KrAction* action); KrAction* action() const; void update(); /** * This reimplements qt's compare-function in order to have categories on the top of the list */ - virtual bool operator<(const QTreeWidgetItem &other) const Q_DECL_OVERRIDE; + bool operator<(const QTreeWidgetItem &other) const Q_DECL_OVERRIDE; private: KrAction* _action; }; #endif diff --git a/krusader/ActionMan/useractionpage.cpp b/krusader/ActionMan/useractionpage.cpp index aecb2410..e0c9000e 100644 --- a/krusader/ActionMan/useractionpage.cpp +++ b/krusader/ActionMan/useractionpage.cpp @@ -1,356 +1,355 @@ /***************************************************************************** * Copyright (C) 2006 Shie Erlich * * Copyright (C) 2006 Rafi Yanai * * Copyright (C) 2006-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "useractionpage.h" // QtWidgets #include #include #include #include #include #include // QtGui #include // QtXml #include #include #include #include #include #include "actionproperty.h" #include "useractionlistview.h" #include "../UserAction/useraction.h" #include "../UserAction/kraction.h" #include "../krusader.h" #include "../krglobal.h" #include "../icon.h" //This is the filter in the QFileDialog of Import/Export: static const char* FILE_FILTER = I18N_NOOP("*.xml|XML files\n*|All files"); UserActionPage::UserActionPage(QWidget* parent) : QWidget(parent) { - QVBoxLayout* layout = new QVBoxLayout(this); + auto* layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(6); // 0px margin, 6px item-spacing // ======== pseudo-toolbar start ======== - QHBoxLayout* toolbarLayout = new QHBoxLayout; // neither margin nor spacing for the toolbar with autoRaise + auto* toolbarLayout = new QHBoxLayout; // neither margin nor spacing for the toolbar with autoRaise toolbarLayout->setSpacing(0); toolbarLayout->setContentsMargins(0, 0, 0, 0); newButton = new QToolButton(this); newButton->setIcon(Icon("document-new")); newButton->setAutoRaise(true); newButton->setToolTip(i18n("Create new useraction")); importButton = new QToolButton(this); importButton->setIcon(Icon("document-import")); importButton->setAutoRaise(true); importButton->setToolTip(i18n("Import useractions")); exportButton = new QToolButton(this); exportButton->setIcon(Icon("document-export")); exportButton->setAutoRaise(true); exportButton->setToolTip(i18n("Export useractions")); copyButton = new QToolButton(this); copyButton->setIcon(Icon("edit-copy")); copyButton->setAutoRaise(true); copyButton->setToolTip(i18n("Copy useractions to clipboard")); pasteButton = new QToolButton(this); pasteButton->setIcon(Icon("edit-paste")); pasteButton->setAutoRaise(true); pasteButton->setToolTip(i18n("Paste useractions from clipboard")); removeButton = new QToolButton(this); removeButton->setIcon(Icon("edit-delete")); removeButton->setAutoRaise(true); removeButton->setToolTip(i18n("Delete selected useractions")); toolbarLayout->addWidget(newButton); toolbarLayout->addWidget(importButton); toolbarLayout->addWidget(exportButton); toolbarLayout->addWidget(copyButton); toolbarLayout->addWidget(pasteButton); toolbarLayout->addSpacing(6); // 6 pixel nothing toolbarLayout->addWidget(removeButton); toolbarLayout->addStretch(1000); // some very large stretch-factor // ======== pseudo-toolbar end ======== /* This seems obsolete now! // Display some help KMessageBox::information( this, // parent i18n( "When you apply changes to an action, the modifications " "become available in the current session immediately.\n" "When closing ActionMan, you will be asked to save the changes permanently." ), QString(), // caption "show UserAction help" //dontShowAgainName for the config ); */ layout->addLayout(toolbarLayout); - QSplitter *split = new QSplitter(this); + auto *split = new QSplitter(this); layout->addWidget(split, 1000); // again a very large stretch-factor to fix the height of the toolbar actionTree = new UserActionListView(split); actionTree->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); actionProperties = new ActionProperty(split); actionProperties->setEnabled(false); // if there are any actions in the list, the first is displayed and this widget is enabled connect(actionTree, &UserActionListView::currentItemChanged, this, &UserActionPage::slotChangeCurrent); connect(newButton, &QToolButton::clicked, this, &UserActionPage::slotNewAction); connect(removeButton, &QToolButton::clicked, this, &UserActionPage::slotRemoveAction); connect(importButton, &QToolButton::clicked, this, &UserActionPage::slotImport); connect(exportButton, &QToolButton::clicked, this, &UserActionPage::slotExport); connect(copyButton, &QToolButton::clicked, this, &UserActionPage::slotToClip); connect(pasteButton, &QToolButton::clicked, this, &UserActionPage::slotFromClip); // forwards the changed signal of the properties connect(actionProperties, SIGNAL(changed()), SIGNAL(changed())); actionTree->setFirstActionCurrent(); actionTree->setFocus(); } UserActionPage::~UserActionPage() -{ -} += default; bool UserActionPage::continueInSpiteOfChanges() { if (! actionProperties->isModified()) return true; int answer = KMessageBox::questionYesNoCancel(this, i18n("The current action has been modified. Do you want to apply these changes?") ); if (answer == KMessageBox::Cancel) { disconnect(actionTree, &UserActionListView::currentItemChanged, this, &UserActionPage::slotChangeCurrent); actionTree->setCurrentAction(actionProperties->action()); connect(actionTree, &UserActionListView::currentItemChanged, this, &UserActionPage::slotChangeCurrent); return false; } if (answer == KMessageBox::Yes) { if (! actionProperties->validProperties()) { disconnect(actionTree, &UserActionListView::currentItemChanged, this, &UserActionPage::slotChangeCurrent); actionTree->setCurrentAction(actionProperties->action()); connect(actionTree, &UserActionListView::currentItemChanged, this, &UserActionPage::slotChangeCurrent); return false; } slotUpdateAction(); } // if Yes return true; } void UserActionPage::slotChangeCurrent() { if (! continueInSpiteOfChanges()) return; KrAction* action = actionTree->currentAction(); if (action) { actionProperties->setEnabled(true); // the distinct name is used as ID it is not allowed to change it afterwards because it is may referenced anywhere else actionProperties->leDistinctName->setEnabled(false); actionProperties->updateGUI(action); } else { // If the current item in the tree is no action (i.e. a category), disable the properties actionProperties->clear(); actionProperties->setEnabled(false); } emit applied(); // to disable the apply-button } void UserActionPage::slotUpdateAction() { // check that we have a command line, title and a name if (! actionProperties->validProperties()) return; if (actionProperties->leDistinctName->isEnabled()) { // := new entry KrAction* action = new KrAction(krApp->actionCollection(), actionProperties->leDistinctName->text()); krUserAction->addKrAction(action); actionProperties->updateAction(action); UserActionListViewItem* item = actionTree->insertAction(action); actionTree->setCurrentItem(item); } else { // := edit an existing actionProperties->updateAction(); actionTree->update(actionProperties->action()); // update the listviewitem as well... } apply(); } void UserActionPage::slotNewAction() { if (continueInSpiteOfChanges()) { actionTree->clearSelection(); // else the user may think that he is overwriting the selected action actionProperties->clear(); actionProperties->setEnabled(true); // it may be disabled because the tree has the focus on a category actionProperties->leDistinctName->setEnabled(true); actionProperties->leDistinctName->setFocus(); } } void UserActionPage::slotRemoveAction() { if (! dynamic_cast(actionTree->currentItem())) return; int messageDelete = KMessageBox::warningContinueCancel(this, //parent i18n("Are you sure that you want to remove all selected actions?"), //text i18n("Remove Selected Actions?"), //caption KStandardGuiItem::remove(), //Label for the continue-button KStandardGuiItem::cancel(), "Confirm Remove UserAction", //dontAskAgainName (for the config-file) KMessageBox::Dangerous | KMessageBox::Notify); if (messageDelete != KMessageBox::Continue) return; actionProperties->clear(); actionProperties->setEnabled(false); actionTree->removeSelectedActions(); apply(); } void UserActionPage::slotImport() { QString filename = QFileDialog::getOpenFileName(this, QString(), QString(), i18n(FILE_FILTER)); if (filename.isEmpty()) return; UserAction::KrActionList newActions; krUserAction->readFromFile(filename, UserAction::renameDoublicated, &newActions); QListIterator it(newActions); while (it.hasNext()) actionTree->insertAction(it.next()); if (newActions.count() > 0) { apply(); } } void UserActionPage::slotExport() { if (! dynamic_cast(actionTree->currentItem())) return; QString filename = QFileDialog::getSaveFileName(this, QString(), QString(), i18n(FILE_FILTER)); if (filename.isEmpty()) return; QDomDocument doc = QDomDocument(ACTION_DOCTYPE); QFile file(filename); int answer = 0; if (file.open(QIODevice::ReadOnly)) { // getting here, means the file already exists an can be read if (doc.setContent(&file)) // getting here means the file exists and already contains an UserAction-XML-tree answer = KMessageBox::warningYesNoCancel(this, //parent i18n("This file already contains some useractions.\nDo you want to overwrite it or should it be merged with the selected actions?"), //text i18n("Overwrite or Merge?"), //caption KStandardGuiItem::overwrite(), //label for Yes-Button KGuiItem(i18n("Merge")) //label for No-Button ); file.close(); } if (answer == 0 && file.exists()) answer = KMessageBox::warningContinueCancel(this, //parent i18n("This file already exists. Do you want to overwrite it?"), //text i18n("Overwrite Existing File?"), //caption KStandardGuiItem::overwrite() //label for Continue-Button ); if (answer == KMessageBox::Cancel) return; if (answer == KMessageBox::No) // that means the merge-button doc = actionTree->dumpSelectedActions(&doc); // merge else // Yes or Continue means overwrite doc = actionTree->dumpSelectedActions(); bool success = UserAction::writeToFile(doc, filename); if (! success) KMessageBox::error(this, i18n("Cannot open %1 for writing.\nNothing exported.", filename), i18n("Export Failed") ); } void UserActionPage::slotToClip() { if (! dynamic_cast(actionTree->currentItem())) return; QDomDocument doc = actionTree->dumpSelectedActions(); QApplication::clipboard()->setText(doc.toString()); } void UserActionPage::slotFromClip() { QDomDocument doc(ACTION_DOCTYPE); if (doc.setContent(QApplication::clipboard()->text())) { QDomElement root = doc.documentElement(); UserAction::KrActionList newActions; krUserAction->readFromElement(root, UserAction::renameDoublicated, &newActions); QListIterator it(newActions); while (it.hasNext()) actionTree->insertAction(it.next()); if (newActions.count() > 0) { apply(); } } // if ( doc.setContent ) } bool UserActionPage::readyToQuit() { // Check if the current UserAction has changed if (! continueInSpiteOfChanges()) return false; krUserAction->writeActionFile(); return true; } void UserActionPage::apply() { krUserAction->writeActionFile(); emit applied(); } void UserActionPage::applyChanges() { slotUpdateAction(); } diff --git a/krusader/ActionMan/useractionpage.h b/krusader/ActionMan/useractionpage.h index 1f3b833c..57a598e3 100644 --- a/krusader/ActionMan/useractionpage.h +++ b/krusader/ActionMan/useractionpage.h @@ -1,82 +1,82 @@ /***************************************************************************** * Copyright (C) 2006 Shie Erlich * * Copyright (C) 2006 Rafi Yanai * * Copyright (C) 2006-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef USERACTIONPAGE_H #define USERACTIONPAGE_H // QtWidgets #include class UserActionListView; class ActionProperty; class QToolButton; class UserActionPage : public QWidget { Q_OBJECT public: explicit UserActionPage(QWidget* parent); - ~UserActionPage(); + ~UserActionPage() override; /** * Be sure to call this function before you delete this page!! * @return true if this page can be closed */ bool readyToQuit(); void applyChanges(); signals: void changed(); ///< emitted on changes to an action (used to enable the apply-button) void applied(); ///< emitted when changes are applied to an action (used to disable the apply-button) private: /** * If there are modifications in the property-widget, the user is asked * what to do. Apply, discard or continue editing. In the first case, * saving is done in this function. * @return true if a new action can be loaded in the property-widget. */ bool continueInSpiteOfChanges(); /** * applies all changes by writing the actionfile and emits "applied" */ void apply(); //bool _modified; ///< true if the action-tree was changed (= changes were applied to an action) UserActionListView *actionTree; ActionProperty *actionProperties; QToolButton *importButton, *exportButton; QToolButton *copyButton, *pasteButton; QToolButton *removeButton, *newButton; private slots: void slotChangeCurrent(); //loads a new action into the detail-view void slotUpdateAction(); //updates the action to the xml-file void slotNewAction(); void slotRemoveAction(); void slotImport(); void slotExport(); void slotToClip(); void slotFromClip(); }; #endif diff --git a/krusader/Archive/abstractthreadedjob.cpp b/krusader/Archive/abstractthreadedjob.cpp index f8fc6945..1e22ec8e 100644 --- a/krusader/Archive/abstractthreadedjob.cpp +++ b/krusader/Archive/abstractthreadedjob.cpp @@ -1,664 +1,664 @@ /***************************************************************************** * Copyright (C) 2009 Csaba Karai * * Copyright (C) 2009-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #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 "../FileSystem/filesystemprovider.h" extern KRarcHandler arcHandler; -AbstractThreadedJob::AbstractThreadedJob() : KIO::Job(), _locker(), _waiter(), _stack(), _maxProgressValue(0), - _currentProgress(0), _exiting(false), _jobThread(0) +AbstractThreadedJob::AbstractThreadedJob() : _maxProgressValue(0), + _currentProgress(0), _exiting(false), _jobThread(nullptr) { } 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; + auto *event = (UserEvent*) e; switch (event->command()) { case CMD_SUCCESS: { emitResult(); } break; case CMD_ERROR: { - int error = event->args()[ 0 ].value(); + auto 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, &KIO::Job::result, this, &AbstractThreadedJob::slotDownloadResult); 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*,ulong)), this, SLOT(slotSpeed(KJob*,ulong))); connect(job, SIGNAL(description(KJob*,QString,QPair,QPair)), this, SLOT(slotDescription(KJob*,QString,QPair,QPair))); } break; case CMD_MAXPROGRESSVALUE: { - qulonglong maxValue = event->args()[ 0 ].value(); + auto maxValue = event->args()[ 0 ].value(); _maxProgressValue = maxValue; _currentProgress = 0; } break; case CMD_ADD_PROGRESS: { - qulonglong progress = event->args()[ 0 ].value(); + auto 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 (); + auto *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 (); + auto *ui = dynamic_cast(uiDelegate()); + KMessageBox::information(ui ? ui->window() : nullptr, message); + auto *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; + return nullptr; 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 (); + auto *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: explicit AbstractJobObserver(AbstractJobThread * thread): _jobThread(thread) {} - virtual ~AbstractJobObserver() {} + ~AbstractJobObserver() override = default; - virtual void processEvents() Q_DECL_OVERRIDE { + void processEvents() Q_DECL_OVERRIDE { usleep(1000); qApp->processEvents(); } - virtual void subJobStarted(const QString & jobTitle, int count) Q_DECL_OVERRIDE { + void subJobStarted(const QString & jobTitle, int count) Q_DECL_OVERRIDE { _jobThread->sendReset(jobTitle); _jobThread->sendMaxProgressValue(count); } - virtual void subJobStopped() Q_DECL_OVERRIDE { + void subJobStopped() Q_DECL_OVERRIDE { } - virtual bool wasCancelled() Q_DECL_OVERRIDE { + bool wasCancelled() Q_DECL_OVERRIDE { return _jobThread->_exited; } - virtual void error(const QString & error) Q_DECL_OVERRIDE { + 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 { + 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 { + 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() : _job(nullptr), _downloadTempDir(nullptr), _observer(nullptr), _tempFile(nullptr), + _tempDir(nullptr), _exited(false) { } AbstractJobThread::~AbstractJobThread() { if (_downloadTempDir) { delete _downloadTempDir; - _downloadTempDir = 0; + _downloadTempDir = nullptr; } if (_observer) { delete _observer; - _observer = 0; + _observer = nullptr; } if (_tempFile) { delete _tempFile; - _tempFile = 0; + _tempFile = nullptr; } } void AbstractJobThread::run() { QTimer::singleShot(0, this, &AbstractJobThread::slotStart); QPointer threadLoop = new QEventLoop(this); _loop = threadLoop; threadLoop->exec(); - _loop = 0; + _loop = nullptr; 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); + auto * downloadEvent = new UserEvent(CMD_DOWNLOAD_FILES, args); QList * result = _job->getEventResponse(downloadEvent); - if (result == 0) + if (result == nullptr) return QUrl(); - int errorCode = (*result)[ 0 ].value(); + auto 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); + auto * errorEvent = new UserEvent(CMD_SUCCESS, args); _job->sendEvent(errorEvent); } -void AbstractJobThread::sendError(int errorCode, QString message) +void AbstractJobThread::sendError(int errorCode, const QString& message) { terminate(); QList args; args << errorCode; args << message; - UserEvent * errorEvent = new UserEvent(CMD_ERROR, args); + auto * errorEvent = new UserEvent(CMD_ERROR, args); _job->sendEvent(errorEvent); } -void AbstractJobThread::sendInfo(QString message, QString a1, QString a2, QString a3, QString a4) +void AbstractJobThread::sendInfo(const QString& message, const QString& a1, const QString& a2, const QString& a3, const QString& a4) { QList args; args << message; args << a1; args << a2; args << a3; args << a4; - UserEvent * infoEvent = new UserEvent(CMD_INFO, args); + auto * infoEvent = new UserEvent(CMD_INFO, args); _job->sendEvent(infoEvent); } -void AbstractJobThread::sendReset(QString message, QString a1, QString a2, QString a3, QString a4) +void AbstractJobThread::sendReset(const QString& message, const QString& a1, const QString& a2, const QString& a3, const QString& a4) { QList args; args << message; args << a1; args << a2; args << a3; args << a4; - UserEvent * infoEvent = new UserEvent(CMD_RESET, args); + auto * 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); + auto * 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); + auto * infoEvent = new UserEvent(CMD_ADD_PROGRESS, args); _job->sendEvent(infoEvent); } void countFiles(const QString &path, unsigned long &totalFiles, bool &stop) { const QDir dir(path); if (!dir.exists()) { totalFiles++; // assume it's a file return; } - for (const QString name : dir.entryList()) { + for (const QString& name : dir.entryList()) { if (stop) return; if (name == QStringLiteral(".") || name == QStringLiteral("..")) continue; countFiles(dir.absoluteFilePath(name), totalFiles, stop); } } void AbstractJobThread::countLocalFiles(const QUrl &baseUrl, const QStringList &names, unsigned long &totalFiles) { sendReset(i18n("Counting files")); FileSystem *calcSpaceFileSystem = FileSystemProvider::instance().getFilesystem(baseUrl); calcSpaceFileSystem->scanDir(baseUrl); - for (const QString name : names) { + for (const QString& name : names) { if (_exited) return; const QString path = calcSpaceFileSystem->getUrl(name).toLocalFile(); if (!QFileInfo(path).exists()) return; countFiles(path, totalFiles, _exited); } delete calcSpaceFileSystem; } KRarcObserver * AbstractJobThread::observer() { if (_observer) return _observer; _observer = new AbstractJobObserver(this); return _observer; } bool AbstractJobThread::uploadTempFiles() { - if (_tempFile != 0 || _tempDir != 0) { + if (_tempFile != nullptr || _tempDir != nullptr) { 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); + auto * uploadEvent = new UserEvent(CMD_UPLOAD_FILES, args); QList * result = _job->getEventResponse(uploadEvent); - if (result == 0) + if (result == nullptr) return false; - int errorCode = (*result)[ 0 ].value(); + auto 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); + auto * uploadEvent = new UserEvent(CMD_UPLOAD_FILES, args); QList * result = _job->getEventResponse(uploadEvent); - if (result == 0) + if (result == nullptr) return false; - int errorCode = (*result)[ 0 ].value(); + auto 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); + auto * getPasswdEvent = new UserEvent(CMD_GET_PASSWORD, args); QList * result = _job->getEventResponse(getPasswdEvent); - if (result == 0) + if (result == nullptr) 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); + auto * getPasswdEvent = new UserEvent(CMD_MESSAGE, args); QList * result = _job->getEventResponse(getPasswdEvent); - if (result == 0) + if (result == nullptr) 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/Archive/abstractthreadedjob.h b/krusader/Archive/abstractthreadedjob.h index 4ea06ad0..85af4e5c 100644 --- a/krusader/Archive/abstractthreadedjob.h +++ b/krusader/Archive/abstractthreadedjob.h @@ -1,188 +1,188 @@ /***************************************************************************** * Copyright (C) 2009 Csaba Karai * * Copyright (C) 2009-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef ABSTRACTTHREADEDJOB_H #define ABSTRACTTHREADEDJOB_H // QtCore #include #include #include #include #include #include #include #include #include #include #include #include class AbstractJobThread; class QTemporaryDir; class UserEvent; class KRarcObserver; class QTemporaryFile; class AbstractThreadedJob : public KIO::Job { friend class AbstractJobThread; Q_OBJECT protected: AbstractThreadedJob(); void addEventResponse(QList * obj); QList * getEventResponse(UserEvent * event); void sendEvent(UserEvent * event); virtual ~AbstractThreadedJob(); virtual bool event(QEvent *) Q_DECL_OVERRIDE; virtual void startAbstractJobThread(AbstractJobThread*); virtual bool doSuspend() Q_DECL_OVERRIDE { return false; } protected slots: void slotDownloadResult(KJob*); void slotProcessedAmount(KJob *, KJob::Unit, qulonglong); void slotTotalAmount(KJob *, KJob::Unit, qulonglong); void slotSpeed(KJob *, unsigned long); void slotDescription(KJob *job, const QString &title, const QPair &field1, const QPair &field2); public: QMutex _locker; QWaitCondition _waiter; QStack *> _stack; QString _title; qulonglong _maxProgressValue; qulonglong _currentProgress; QTime _time; bool _exiting; private: AbstractJobThread * _jobThread; }; class AbstractJobThread : public QThread { friend class AbstractThreadedJob; friend class AbstractJobObserver; Q_OBJECT public: AbstractJobThread(); virtual ~AbstractJobThread(); void abort(); KRarcObserver * observer(); protected slots: virtual void slotStart() = 0; protected: virtual void run() Q_DECL_OVERRIDE; void setJob(AbstractThreadedJob * job) { _job = job; } QList remoteUrls(const QUrl &baseUrl, const QStringList & files); QUrl downloadIfRemote(const QUrl &baseUrl, const QStringList & files); void countLocalFiles(const QUrl &baseUrl, const QStringList &names, unsigned long &totalFiles); - void sendError(int errorCode, QString message); - void sendInfo(QString message, QString a1 = QString(), QString a2 = QString(), QString a3 = QString(), QString a4 = QString()); - void sendReset(QString message, QString a1 = QString(""), QString a2 = QString(""), QString a3 = QString(""), QString a4 = QString("")); + void sendError(int errorCode, const QString& message); + void sendInfo(const QString& message, const QString& a1 = QString(), const QString& a2 = QString(), const QString& a3 = QString(), const QString& a4 = QString()); + void sendReset(const QString& message, const QString& a1 = QString(""), const QString& a2 = QString(""), const QString& a3 = QString(""), const QString& a4 = QString("")); void sendSuccess(); void sendMessage(const QString &message); void sendMaxProgressValue(qulonglong value); void sendAddProgress(qulonglong value, const QString &progress = QString()); void setProgressTitle(const QString &title) { _progressTitle = title; } QString tempFileIfRemote(const QUrl &kurl, const QString &type); QString tempDirIfRemote(const QUrl &kurl); bool uploadTempFiles(); bool isExited() { return _exited; } void terminate(); QString getPassword(const QString &path); bool getArchiveInformation(QString &, QString &, QString &, QString &, const QUrl &); AbstractThreadedJob *_job; QEventLoop *_loop; QTemporaryDir *_downloadTempDir; KRarcObserver *_observer; QTemporaryFile *_tempFile; QString _tempFileName; QUrl _tempFileTarget; QTemporaryDir *_tempDir; QString _tempDirName; QUrl _tempDirTarget; bool _exited; QString _progressTitle; }; enum PossibleCommands { CMD_ERROR = 1, CMD_INFO = 2, CMD_RESET = 3, CMD_DOWNLOAD_FILES = 4, CMD_UPLOAD_FILES = 5, CMD_SUCCESS = 6, CMD_MAXPROGRESSVALUE = 7, CMD_ADD_PROGRESS = 8, CMD_GET_PASSWORD = 9, CMD_MESSAGE = 10 }; class UserEvent : public QEvent { public: UserEvent(int command, const QList &args) : QEvent(QEvent::User), _command(command), _args(args) {} inline int command() { return _command; } inline const QList & args() { return _args; } protected: int _command; QList _args; }; #endif // __ABSTRACTTHREADED_JOB_H__ diff --git a/krusader/Archive/kr7zencryptionchecker.cpp b/krusader/Archive/kr7zencryptionchecker.cpp index 2c4eb37b..27c72a6a 100644 --- a/krusader/Archive/kr7zencryptionchecker.cpp +++ b/krusader/Archive/kr7zencryptionchecker.cpp @@ -1,63 +1,63 @@ /***************************************************************************** * Copyright (C) 2001 Shie Erlich * * Copyright (C) 2001 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "kr7zencryptionchecker.h" -Kr7zEncryptionChecker::Kr7zEncryptionChecker() : KProcess(), encrypted(false), lastData() +Kr7zEncryptionChecker::Kr7zEncryptionChecker() : encrypted(false), lastData() { setOutputChannelMode(KProcess::SeparateChannels); // without this output redirection has no effect! connect(this, &Kr7zEncryptionChecker::readyReadStandardOutput, this, [=]() {receivedOutput(); }); } void Kr7zEncryptionChecker::setupChildProcess() { // This function is called after the fork but for the exec. We create a process group // to work around a broken wrapper script of 7z. Without this only the wrapper is killed. setsid(); // make this process leader of a new process group } void Kr7zEncryptionChecker::receivedOutput() { QString data = QString::fromLocal8Bit(this->readAllStandardOutput()); QString checkable = lastData + data; QStringList lines = checkable.split('\n'); lastData = lines[ lines.count() - 1 ]; for (int i = 0; i != lines.count(); i++) { QString line = lines[ i ].trimmed().toLower(); int ndx = line.indexOf("testing"); if (ndx >= 0) line.truncate(ndx); if (line.isEmpty()) continue; if (line.contains("password") && line.contains("enter")) { encrypted = true; ::kill(- pid(), SIGKILL); // kill the whole process group by giving the negative PID } } } bool Kr7zEncryptionChecker::isEncrypted() { return encrypted; } diff --git a/krusader/Archive/kr7zencryptionchecker.h b/krusader/Archive/kr7zencryptionchecker.h index ae48553b..160ec3da 100644 --- a/krusader/Archive/kr7zencryptionchecker.h +++ b/krusader/Archive/kr7zencryptionchecker.h @@ -1,53 +1,53 @@ /***************************************************************************** * Copyright (C) 2001 Shie Erlich * * Copyright (C) 2001 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef KR7ZENCRYPTIONCHECKER_H #define KR7ZENCRYPTIONCHECKER_H #include // for setsid, see Kr7zEncryptionChecker::setupChildProcess #include // for kill #include /** * Used by ArcHandler. */ class Kr7zEncryptionChecker : public KProcess { Q_OBJECT public: Kr7zEncryptionChecker(); protected: - virtual void setupChildProcess() Q_DECL_OVERRIDE; + void setupChildProcess() Q_DECL_OVERRIDE; public slots: void receivedOutput(); bool isEncrypted(); private: QString fileName; bool encrypted; QString lastData; }; #endif // KR7ZENCRYPTIONCHECKER_H diff --git a/krusader/Archive/krarchandler.cpp b/krusader/Archive/krarchandler.cpp index 6e409be3..3648e57e 100644 --- a/krusader/Archive/krarchandler.cpp +++ b/krusader/Archive/krarchandler.cpp @@ -1,668 +1,669 @@ /***************************************************************************** * Copyright (C) 2001 Shie Erlich * * Copyright (C) 2001 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "krarchandler.h" // QtCore #include #include #include // QtWidgets #include #include #include #include #include #include #include #include +#include #include "kr7zencryptionchecker.h" #include "../krglobal.h" #include "../defaults.h" #include "../krservices.h" #include "../Dialogs/krpleasewait.h" #include "../../krArc/krlinecountingprocess.h" #if 0 class DefaultKRarcObserver : public KRarcObserver { public: DefaultKRarcObserver() {} virtual ~DefaultKRarcObserver() {} virtual void processEvents() Q_DECL_OVERRIDE { usleep(1000); qApp->processEvents(); } virtual void subJobStarted(const QString & jobTitle, int count) Q_DECL_OVERRIDE { krApp->startWaiting(jobTitle, count, true); } virtual void subJobStopped() Q_DECL_OVERRIDE { krApp->stopWait(); } virtual bool wasCancelled() Q_DECL_OVERRIDE { return krApp->wasWaitingCancelled(); } virtual void error(const QString & error) Q_DECL_OVERRIDE { KMessageBox::error(krApp, error, i18n("Error")); } virtual void detailedError(const QString & error, const QString & details) Q_DECL_OVERRIDE { KMessageBox::detailedError(krApp, error, details, i18n("Error")); } virtual void incrementProgress(int c) Q_DECL_OVERRIDE { krApp->plzWait->incProgress(c); } }; #endif static QStringList arcProtocols = QString("tar;bzip;bzip2;lzma;xz;gzip;krarc;zip").split(';'); -KWallet::Wallet * KRarcHandler::wallet = 0; +KWallet::Wallet * KRarcHandler::wallet = nullptr; QStringList KRarcHandler::supportedPackers() { QStringList packers; // we will simply try to find the packers here.. if (KrServices::cmdExist("tar")) packers.append("tar"); if (KrServices::cmdExist("gzip")) packers.append("gzip"); if (KrServices::cmdExist("bzip2")) packers.append("bzip2"); if (KrServices::cmdExist("lzma")) packers.append("lzma"); if (KrServices::cmdExist("xz")) packers.append("xz"); if (KrServices::cmdExist("unzip")) packers.append("unzip"); if (KrServices::cmdExist("zip")) packers.append("zip"); if (KrServices::cmdExist("zip")) packers.append("cbz"); if (KrServices::cmdExist("lha")) packers.append("lha"); if (KrServices::cmdExist("cpio")) packers.append("cpio"); if (KrServices::cmdExist("unrar")) packers.append("unrar"); if (KrServices::cmdExist("rar")) packers.append("rar"); if (KrServices::cmdExist("rar")) packers.append("cbr"); if (KrServices::cmdExist("arj")) packers.append("arj"); if (KrServices::cmdExist("unarj")) packers.append("unarj"); if (KrServices::cmdExist("unace")) packers.append("unace"); if (KrServices::cmdExist("dpkg")) packers.append("dpkg"); if (KrServices::cmdExist("7z") || KrServices::cmdExist("7za")) packers.append("7z"); if (KrServices::cmdExist("rpm") && KrServices::cmdExist("rpm2cpio")) packers.append("rpm"); // qDebug() << "Supported Packers:"; //QStringList::Iterator it; //for( it = packers.begin(); it != packers.end(); ++it ) // qDebug() << *it; return packers; } bool KRarcHandler::arcSupported(QString type) { // lst will contain the supported unpacker list... const KConfigGroup group(krConfig, "Archives"); const QStringList lst = group.readEntry("Supported Packers", QStringList()); // Let's notice that in some cases the QString `type` that arrives here // represents a mimetype, and in some other cases it represents // a short identifier. // If `type` is not a short identifier then it's supposed that `type` is a mime type if (type.length() > maxLenType) { type = getShortTypeFromMime(type); } return (type == "zip" && lst.contains("unzip")) || (type == "tar" && lst.contains("tar")) || (type == "tbz" && lst.contains("tar")) || (type == "tgz" && lst.contains("tar")) || (type == "tlz" && lst.contains("tar")) || (type == "txz" && lst.contains("tar")) || (type == "tarz" && lst.contains("tar")) || (type == "gzip" && lst.contains("gzip")) || (type == "bzip2" && lst.contains("bzip2")) || (type == "lzma" && lst.contains("lzma")) || (type == "xz" && lst.contains("xz")) || (type == "lha" && lst.contains("lha")) || (type == "ace" && lst.contains("unace")) || (type == "rpm" && lst.contains("cpio")) || (type == "cpio" && lst.contains("cpio")) || (type == "rar" && (lst.contains("unrar") || lst.contains("rar"))) || (type == "arj" && (lst.contains("unarj") || lst.contains("arj"))) || (type == "deb" && (lst.contains("dpkg") && lst.contains("tar"))) || (type == "7z" && lst.contains("7z")); } -long KRarcHandler::arcFileCount(QString archive, QString type, QString password, KRarcObserver *observer) +long KRarcHandler::arcFileCount(const QString& archive, const QString& type, const QString& password, KRarcObserver *observer) { int divideWith = 1; // first check if supported if (!arcSupported(type)) return 0; // bzip2, gzip, etc. archives contain only one file if (type == "bzip2" || type == "gzip" || type == "lzma" || type == "xz") return 1L; // set the right lister to do the job QStringList lister; if (type == "zip") lister << KrServices::fullPathName("unzip") << "-ZTs"; else if (type == "tar") lister << KrServices::fullPathName("tar") << "-tvf"; else if (type == "tgz") lister << KrServices::fullPathName("tar") << "-tvzf"; else if (type == "tarz") lister << KrServices::fullPathName("tar") << "-tvzf"; else if (type == "tbz") lister << KrServices::fullPathName("tar") << "-tjvf"; else if (type == "tlz") lister << KrServices::fullPathName("tar") << "--lzma" << "-tvf"; else if (type == "txz") lister << KrServices::fullPathName("tar") << "--xz" << "-tvf"; else if (type == "lha") lister << KrServices::fullPathName("lha") << "l"; else if (type == "rar") lister << KrServices::fullPathName(KrServices::cmdExist("rar") ? "rar" : "unrar") << "l" << "-v"; else if (type == "ace") lister << KrServices::fullPathName("unace") << "l"; else if (type == "arj") { if (KrServices::cmdExist("arj")) lister << KrServices::fullPathName("arj") << "v" << "-y" << "-v", divideWith = 4; else lister << KrServices::fullPathName("unarj") << "l"; } else if (type == "rpm") lister << KrServices::fullPathName("rpm") << "--dump" << "-lpq"; else if (type == "deb") lister << KrServices::fullPathName("dpkg") << "-c"; else if (type == "7z") lister << KrServices::fullPathName("7z") << "-y" << "l"; else return 0L; if (!password.isNull()) { if (type == "arj") lister << QString("-g%1").arg(password); if (type == "ace" || type == "rar" || type == "7z") lister << QString("-p%1").arg(password); } // tell the user to wait observer->subJobStarted(i18n("Counting files in archive"), 0); // count the number of files in the archive long count = 1; KProcess list; list << lister << archive; if (type == "ace" && QFile("/dev/ptmx").exists()) // Don't remove, unace crashes if missing!!! list.setStandardInputFile("/dev/ptmx"); list.setOutputChannelMode(KProcess::SeparateChannels); // without this output redirection has no effect list.start(); // TODO make use of asynchronous process starting. waitForStarted(int msec = 30000) is blocking // it would be better to connect to started(), error() and finished() if (list.waitForStarted()) while (list.state() == QProcess::Running) { observer->processEvents(); if (observer->wasCancelled()) list.kill(); } ; // busy wait - need to find something better... observer->subJobStopped(); if (list.exitStatus() != QProcess::NormalExit || !checkStatus(type, list.exitCode())) { observer->detailedError(i18n("Failed to list the content of the archive (%1).", archive), QString::fromLocal8Bit(list.readAllStandardError())); return 0; } count = list.readAllStandardOutput().count('\n'); //make sure you call stopWait after this function return... // observer->subJobStopped(); return count / divideWith; } -bool KRarcHandler::unpack(QString archive, QString type, QString password, QString dest, KRarcObserver *observer) +bool KRarcHandler::unpack(QString archive, const QString& type, const QString& password, const QString& dest, KRarcObserver *observer) { KConfigGroup group(krConfig, "Archives"); if (group.readEntry("Test Before Unpack", _TestBeforeUnpack)) { // test first - or be sorry later... if (type != "rpm" && type != "deb" && !test(archive, type, password, observer, 0)) { observer->error(i18n("Failed to unpack %1.", archive)); return false; } } // count the files in the archive long count = arcFileCount(archive, type, password, observer); if (count == 0) return false; // not supported if (count == 1) count = 0; // choose the right packer for the job QString cpioName; QStringList packer; // set the right packer to do the job if (type == "zip") packer << KrServices::fullPathName("unzip") << "-o"; else if (type == "tar") packer << KrServices::fullPathName("tar") << "-xvf"; else if (type == "tgz") packer << KrServices::fullPathName("tar") << "-xvzf"; else if (type == "tarz") packer << KrServices::fullPathName("tar") << "-xvzf"; else if (type == "tbz") packer << KrServices::fullPathName("tar") << "-xjvf"; else if (type == "tlz") packer << KrServices::fullPathName("tar") << "--lzma" << "-xvf"; else if (type == "txz") packer << KrServices::fullPathName("tar") << "--xz" << "-xvf"; else if (type == "gzip") packer << KrServices::fullPathName("gzip") << "-cd"; else if (type == "bzip2") packer << KrServices::fullPathName("bzip2") << "-cdk"; else if (type == "lzma") packer << KrServices::fullPathName("lzma") << "-cdk"; else if (type == "xz") packer << KrServices::fullPathName("xz") << "-cdk"; else if (type == "lha") packer << KrServices::fullPathName("lha") << "xf"; else if (type == "rar") packer << KrServices::fullPathName(KrServices::cmdExist("rar") ? "rar" : "unrar") << "-y" << "x"; else if (type == "ace") packer << KrServices::fullPathName("unace") << "x"; else if (type == "arj") { if (KrServices::cmdExist("arj")) packer << KrServices::fullPathName("arj") << "-y" << "-v" << "x"; else packer << KrServices::fullPathName("unarj") << "x"; } else if (type == "7z") packer << KrServices::fullPathName("7z") << "-y" << "x"; else if (type == "rpm") { // TODO use QTemporaryFile (setAutoRemove(false) when asynchrone) cpioName = QDir::tempPath() + QStringLiteral("/contents.cpio"); KrLinecountingProcess cpio; cpio << KrServices::fullPathName("rpm2cpio") << archive; cpio.setStandardOutputFile(cpioName); // TODO maybe no tmpfile but a pipe (setStandardOutputProcess(packer)) cpio.start(); if (!cpio.waitForFinished() || cpio.exitStatus() != QProcess::NormalExit || !checkStatus("cpio", cpio.exitCode())) { observer->detailedError(i18n("Failed to convert rpm (%1) to cpio.", archive), cpio.getErrorMsg()); return 0; } archive = cpioName; packer << KrServices::fullPathName("cpio") << "--force-local" << "--no-absolute-filenames" << "-iuvdF"; } else if (type == "deb") { // TODO use QTemporaryFile (setAutoRemove(false) when asynchrone) cpioName = QDir::tempPath() + QStringLiteral("/contents.tar"); KrLinecountingProcess dpkg; dpkg << KrServices::fullPathName("dpkg") << "--fsys-tarfile" << archive; dpkg.setStandardOutputFile(cpioName); // TODO maybe no tmpfile but a pipe (setStandardOutputProcess(packer)) dpkg.start(); if (!dpkg.waitForFinished() || dpkg.exitStatus() != QProcess::NormalExit || !checkStatus("deb", dpkg.exitCode())) { observer->detailedError(i18n("Failed to convert deb (%1) to tar.", archive), dpkg.getErrorMsg()); return 0; } archive = cpioName; packer << KrServices::fullPathName("tar") << "xvf"; } else return false; if (!password.isNull()) { if (type == "zip") packer << "-P" << password; if (type == "arj") packer << QString("-g%1").arg(password); if (type == "ace" || type == "rar" || type == "7z") packer << QString("-p%1").arg(password); } // unpack the files KrLinecountingProcess proc; proc << packer << archive; if (type == "bzip2" || type == "gzip" || type == "lzma" || type == "xz") { QString arcname = archive.mid(archive.lastIndexOf("/") + 1); if (arcname.contains(".")) arcname = arcname.left(arcname.lastIndexOf(".")); proc.setStandardOutputFile(dest + '/' + arcname); } if (type == "ace" && QFile("/dev/ptmx").exists()) // Don't remove, unace crashes if missing!!! proc.setStandardInputFile("/dev/ptmx"); proc.setWorkingDirectory(dest); // tell the user to wait observer->subJobStarted(i18n("Unpacking File(s)"), count); if (count != 0) { connect(&proc, &KrLinecountingProcess::newOutputLines, observer, &KRarcObserver::incrementProgress); if (type == "rpm") connect(&proc, &KrLinecountingProcess::newErrorLines, observer, &KRarcObserver::incrementProgress); } // start the unpacking process proc.start(); // TODO make use of asynchronous process starting. waitForStarted(int msec = 30000) is blocking // it would be better to connect to started(), error() and finished() if (proc.waitForStarted()) while (proc.state() == QProcess::Running) { observer->processEvents(); if (observer->wasCancelled()) proc.kill(); } ; // busy wait - need to find something better... observer->subJobStopped(); if (!cpioName.isEmpty()) QFile(cpioName).remove(); /* remove the cpio file */ // check the return value if (proc.exitStatus() != QProcess::NormalExit || !checkStatus(type, proc.exitCode())) { observer->detailedError(i18n("Failed to unpack %1.", archive), observer->wasCancelled() ? i18n("User cancelled.") : proc.getErrorMsg()); return false; } return true; // SUCCESS } -bool KRarcHandler::test(QString archive, QString type, QString password, KRarcObserver *observer, long count) +bool KRarcHandler::test(const QString& archive, const QString& type, const QString& password, KRarcObserver *observer, long count) { // choose the right packer for the job QStringList packer; // set the right packer to do the job if (type == "zip") packer << KrServices::fullPathName("unzip") << "-t"; else if (type == "tar") packer << KrServices::fullPathName("tar") << "-tvf"; else if (type == "tgz") packer << KrServices::fullPathName("tar") << "-tvzf"; else if (type == "tarz") packer << KrServices::fullPathName("tar") << "-tvzf"; else if (type == "tbz") packer << KrServices::fullPathName("tar") << "-tjvf"; else if (type == "tlz") packer << KrServices::fullPathName("tar") << "--lzma" << "-tvf"; else if (type == "txz") packer << KrServices::fullPathName("tar") << "--xz" << "-tvf"; else if (type == "gzip") packer << KrServices::fullPathName("gzip") << "-tv"; else if (type == "bzip2") packer << KrServices::fullPathName("bzip2") << "-tv"; else if (type == "lzma") packer << KrServices::fullPathName("lzma") << "-tv"; else if (type == "xz") packer << KrServices::fullPathName("xz") << "-tv"; else if (type == "rar") packer << KrServices::fullPathName(KrServices::cmdExist("rar") ? "rar" : "unrar") << "t"; else if (type == "ace") packer << KrServices::fullPathName("unace") << "t"; else if (type == "lha") packer << KrServices::fullPathName("lha") << "t"; else if (type == "arj") packer << KrServices::fullPathName(KrServices::cmdExist("arj") ? "arj" : "unarj") << "t"; else if (type == "cpio") packer << KrServices::fullPathName("cpio") << "--only-verify-crc" << "-tvF"; else if (type == "7z") packer << KrServices::fullPathName("7z") << "-y" << "t"; else return false; if (!password.isNull()) { if (type == "zip") packer << "-P" << password; if (type == "arj") packer << QString("-g%1").arg(password); if (type == "ace" || type == "rar" || type == "7z") packer << QString("-p%1").arg(password); } // unpack the files KrLinecountingProcess proc; proc << packer << archive; if (type == "ace" && QFile("/dev/ptmx").exists()) // Don't remove, unace crashes if missing!!! proc.setStandardInputFile("/dev/ptmx"); // tell the user to wait observer->subJobStarted(i18n("Testing Archive"), count); if (count != 0) connect(&proc, &KrLinecountingProcess::newOutputLines, observer, &KRarcObserver::incrementProgress); // start the unpacking process proc.start(); // TODO make use of asynchronous process starting. waitForStarted(int msec = 30000) is blocking // it would be better to connect to started(), error() and finished() if (proc.waitForStarted()) while (proc.state() == QProcess::Running) { observer->processEvents(); if (observer->wasCancelled()) proc.kill(); } ; // busy wait - need to find something better... observer->subJobStopped(); // check the return value if (proc.exitStatus() != QProcess::NormalExit || !checkStatus(type, proc.exitCode())) return false; return true; // SUCCESS } -bool KRarcHandler::pack(QStringList fileNames, QString type, QString dest, long count, QMap extraProps, KRarcObserver *observer) +bool KRarcHandler::pack(QStringList fileNames, QString type, const QString& dest, long count, QMap extraProps, KRarcObserver *observer) { // set the right packer to do the job QStringList packer; if (type == "zip") { packer << KrServices::fullPathName("zip") << "-ry"; } else if (type == "cbz") { packer << KrServices::fullPathName("zip") << "-ry"; type = "zip"; } else if (type == "tar") { packer << KrServices::fullPathName("tar") << "-cvf"; } else if (type == "tar.gz") { packer << KrServices::fullPathName("tar") << "-cvzf"; type = "tgz"; } else if (type == "tar.bz2") { packer << KrServices::fullPathName("tar") << "-cvjf"; type = "tbz"; } else if (type == "tar.lzma") { packer << KrServices::fullPathName("tar") << "--lzma" << "-cvf"; type = "tlz"; } else if (type == "tar.xz") { packer << KrServices::fullPathName("tar") << "--xz" << "-cvf"; type = "txz"; } else if (type == "rar") { packer << KrServices::fullPathName("rar") << "-r" << "a"; } else if (type == "cbr") { packer << KrServices::fullPathName("rar") << "-r" << "a"; type = "rar"; } else if (type == "lha") { packer << KrServices::fullPathName("lha") << "a"; } else if (type == "arj") { packer << KrServices::fullPathName("arj") << "-r" << "-y" << "a"; } else if (type == "7z") { packer << KrServices::fullPathName("7z") << "-y" << "a"; } else return false; QString password; if (extraProps.count("Password") > 0) { password = extraProps[ "Password" ]; if (!password.isNull()) { if (type == "zip") packer << "-P" << password; else if (type == "arj") packer << QString("-g%1").arg(password); else if (type == "ace" || type == "7z") packer << QString("-p%1").arg(password); else if (type == "rar") { if (extraProps.count("EncryptHeaders") > 0) packer << QString("-hp%1").arg(password); else packer << QString("-p%1").arg(password); } else password.clear(); } } if (extraProps.count("VolumeSize") > 0) { QString sizeStr = extraProps[ "VolumeSize" ]; KIO::filesize_t size = sizeStr.toLongLong(); if (size >= 10000) { if (type == "arj" || type == "rar") packer << QString("-v%1b").arg(sizeStr); } } if (extraProps.count("CompressionLevel") > 0) { int level = extraProps[ "CompressionLevel" ].toInt() - 1; if (level < 0) level = 0; if (level > 8) level = 8; if (type == "rar") { static const int rarLevels[] = { 0, 1, 2, 2, 3, 3, 4, 4, 5 }; packer << QString("-m%1").arg(rarLevels[ level ]); } else if (type == "arj") { static const int arjLevels[] = { 0, 4, 4, 3, 3, 2, 2, 1, 1 }; packer << QString("-m%1").arg(arjLevels[ level ]); } else if (type == "zip") { static const int zipLevels[] = { 0, 1, 2, 4, 5, 6, 7, 8, 9 }; packer << QString("-%1").arg(zipLevels[ level ]); } else if (type == "7z") { static const int sevenZipLevels[] = { 0, 1, 2, 4, 5, 6, 7, 8, 9 }; packer << QString("-mx%1").arg(sevenZipLevels[ level ]); } } if (extraProps.count("CommandLineSwitches") > 0) packer << QString("%1").arg(extraProps[ "CommandLineSwitches" ]); // prepare to pack KrLinecountingProcess proc; proc << packer << dest; - for (QStringList::Iterator file = fileNames.begin(); file != fileNames.end(); ++file) { - proc << *file; + for (auto & fileName : fileNames) { + proc << fileName; } // tell the user to wait observer->subJobStarted(i18n("Packing File(s)"), count); if (count != 0) connect(&proc, &KrLinecountingProcess::newOutputLines, observer, &KRarcObserver::incrementProgress); // start the packing process proc.start(); // TODO make use of asynchronous process starting. waitForStarted(int msec = 30000) is blocking // it would be better to connect to started(), error() and finished() if (proc.waitForStarted()) while (proc.state() == QProcess::Running) { observer->processEvents(); if (observer->wasCancelled()) proc.kill(); } ; // busy wait - need to find something better... observer->subJobStopped(); // check the return value if (proc.exitStatus() != QProcess::NormalExit || !checkStatus(type, proc.exitCode())) { observer->detailedError(i18n("Failed to pack %1.", dest), observer->wasCancelled() ? i18n("User cancelled.") : proc.getErrorMsg()); return false; } KConfigGroup group(krConfig, "Archives"); if (group.readEntry("Test Archives", _TestArchives) && !test(dest, type, password, observer, count)) { observer->error(i18n("Failed to pack %1.", dest)); return false; } return true; // SUCCESS } bool KRarcHandler::openWallet() { if (!wallet) { // find a suitable parent window QWidget *actWindow = QApplication::activeWindow(); if (!actWindow) actWindow = (QWidget*) QApplication::desktop(); wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), actWindow->effectiveWinId()); } - return (wallet != 0); + return (wallet != nullptr); } -QString KRarcHandler::getPassword(QString path) +QString KRarcHandler::getPassword(const QString& path) { QString password; QString key = "krarc-" + path; if (!KWallet::Wallet::keyDoesNotExist(KWallet::Wallet::NetworkWallet(), KWallet::Wallet::PasswordFolder(), key)) { - if (!KWallet::Wallet::isOpen(KWallet::Wallet::NetworkWallet()) && wallet != 0) { + if (!KWallet::Wallet::isOpen(KWallet::Wallet::NetworkWallet()) && wallet != nullptr) { delete wallet; - wallet = 0; + wallet = nullptr; } if (openWallet() && wallet->hasFolder(KWallet::Wallet::PasswordFolder())) { wallet->setFolder(KWallet::Wallet::PasswordFolder()); QMap map; if (wallet->readMap(key, map) == 0) { QMap::const_iterator it = map.constFind("password"); if (it != map.constEnd()) password = it.value(); } } } bool keep = true; QString user = "archive"; - QPointer passDlg = new KPasswordDialog(0L, KPasswordDialog::ShowKeepPassword); + QPointer passDlg = new KPasswordDialog(nullptr, KPasswordDialog::ShowKeepPassword); passDlg->setPrompt(i18n("This archive is encrypted, please supply the password:") ), passDlg->setUsername(user); passDlg->setPassword(password); if (passDlg->exec() == KPasswordDialog::Accepted) { password = passDlg->password(); if (keep) { - if (!KWallet::Wallet::isOpen(KWallet::Wallet::NetworkWallet()) && wallet != 0) { + if (!KWallet::Wallet::isOpen(KWallet::Wallet::NetworkWallet()) && wallet != nullptr) { delete wallet; - wallet = 0; + wallet = nullptr; } if (openWallet()) { bool ok = true; if (!wallet->hasFolder(KWallet::Wallet::PasswordFolder())) ok = wallet->createFolder(KWallet::Wallet::PasswordFolder()); if (ok) { wallet->setFolder(KWallet::Wallet::PasswordFolder()); QMap map; map.insert("login", "archive"); map.insert("password", password); wallet->writeMap(key, map); } } } delete passDlg; return password; } delete passDlg; return ""; } bool KRarcHandler::isArchive(const QUrl &url) { QString protocol = url.scheme(); if (arcProtocols.indexOf(protocol) != -1) return true; else return false; } -QString KRarcHandler::getType(bool &encrypted, QString fileName, QString mime, bool checkEncrypted, bool fast) +QString KRarcHandler::getType(bool &encrypted, QString fileName, const QString& mime, bool checkEncrypted, bool fast) { - QString result = detectArchive(encrypted, fileName, checkEncrypted, fast); + QString result = detectArchive(encrypted, std::move(fileName), checkEncrypted, fast); if (result.isNull()) { // Then the type is based on the mime type return getShortTypeFromMime(mime); } return result; } -bool KRarcHandler::checkStatus(QString type, int exitCode) +bool KRarcHandler::checkStatus(const QString& type, int exitCode) { return KrArcBaseManager::checkStatus(type, exitCode); } void KRarcHandler::checkIf7zIsEncrypted(bool &encrypted, QString fileName) { Kr7zEncryptionChecker proc; // TODO incorporate all this in Kr7zEncryptionChecker proc << KrServices::fullPathName("7z") << "-y" << "t"; proc << fileName; proc.start(); proc.waitForFinished(); encrypted = proc.isEncrypted(); } diff --git a/krusader/Archive/krarchandler.h b/krusader/Archive/krarchandler.h index a5bbd6e8..7e641bd6 100644 --- a/krusader/Archive/krarchandler.h +++ b/krusader/Archive/krarchandler.h @@ -1,87 +1,87 @@ /***************************************************************************** * Copyright (C) 2001 Shie Erlich * * Copyright (C) 2001 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef KRARCHANDLER_H #define KRARCHANDLER_H // QtCore #include #include #include #include #include "../../krArc/krarcbasemanager.h" namespace KWallet { class Wallet; } class KRarcObserver : public QObject { Q_OBJECT public: - virtual ~KRarcObserver() {} + ~KRarcObserver() override = default; virtual void processEvents() = 0; virtual void subJobStarted(const QString & jobTitle, int count) = 0; virtual void subJobStopped() = 0; virtual bool wasCancelled() = 0; virtual void error(const QString & error) = 0; virtual void detailedError(const QString & error, const QString & details) = 0; public slots: virtual void incrementProgress(int) = 0; }; class KRarcHandler: public QObject, public KrArcBaseManager { Q_OBJECT public: // return the number of files in the archive - static long arcFileCount(QString archive, QString type, QString password, KRarcObserver *observer); + static long arcFileCount(const QString& archive, const QString& type, const QString& password, KRarcObserver *observer); // unpack an archive to destination directory - static bool unpack(QString archive, QString type, QString password, QString dest, KRarcObserver *observer ); + static bool unpack(QString archive, const QString& type, const QString& password, const QString& dest, KRarcObserver *observer ); // pack an archive to destination directory - static bool pack(QStringList fileNames, QString type, QString dest, long count, QMap extraProps, KRarcObserver *observer ); + static bool pack(QStringList fileNames, QString type, const QString& dest, long count, QMap extraProps, KRarcObserver *observer ); // test an archive - static bool test(QString archive, QString type, QString password, KRarcObserver *observer, long count = 0L ); + static bool test(const QString& archive, const QString& type, const QString& password, KRarcObserver *observer, long count = 0L ); // returns `true` if the right unpacker exist in the system static bool arcSupported(QString type); // return the list of supported packers static QStringList supportedPackers(); // returns `true` if the url is an archive (ie: tar:/home/test/file.tar.bz2) static bool isArchive(const QUrl &url); // used to determine the type of the archive - QString getType(bool &encrypted, QString fileName, QString mime, bool checkEncrypted = true, bool fast = false); + QString getType(bool &encrypted, QString fileName, const QString& mime, bool checkEncrypted = true, bool fast = false); // queries the password from the user - static QString getPassword(QString path); + static QString getPassword(const QString& path); // detects the archive type void checkIf7zIsEncrypted(bool &, QString) Q_DECL_OVERRIDE; private: //! checks if a returned status ("exit code") of an archiving-related process is OK - static bool checkStatus(QString type, int exitCode); + static bool checkStatus(const QString& type, int exitCode); static bool openWallet(); static KWallet::Wallet * wallet; }; #endif diff --git a/krusader/Archive/packjob.cpp b/krusader/Archive/packjob.cpp index 8409238e..4e4f413a 100644 --- a/krusader/Archive/packjob.cpp +++ b/krusader/Archive/packjob.cpp @@ -1,169 +1,169 @@ /***************************************************************************** * Copyright (C) 2009 Csaba Karai * * Copyright (C) 2009-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "packjob.h" #include "krarchandler.h" // QtCore #include #include #include #include #include extern KRarcHandler arcHandler; -PackJob::PackJob(const QUrl &srcUrl, const QUrl &destUrl, const QStringList & fileNames, const QString &type, const QMap &packProps) : AbstractThreadedJob() +PackJob::PackJob(const QUrl &srcUrl, const QUrl &destUrl, const QStringList & fileNames, const QString &type, const QMap &packProps) { startAbstractJobThread(new PackThread(srcUrl, destUrl, fileNames, type, packProps)); } PackJob * PackJob::createPacker(const QUrl &srcUrl, const QUrl &destUrl, const QStringList & fileNames, const QString &type, const QMap &packProps) { return new PackJob(srcUrl, destUrl, fileNames, type, packProps); } PackThread::PackThread(const QUrl &srcUrl, const QUrl &destUrl, const QStringList & fileNames, const QString &type, const QMap &packProps) : - AbstractJobThread(), _sourceUrl(srcUrl), _destUrl(destUrl), _fileNames(fileNames), + _sourceUrl(srcUrl), _destUrl(destUrl), _fileNames(fileNames), _type(type), _packProperties(packProps) { } void PackThread::slotStart() { QUrl newSource = downloadIfRemote(_sourceUrl, _fileNames); if (newSource.isEmpty()) return; unsigned long totalFiles = 0; countLocalFiles(newSource, _fileNames, totalFiles); QString arcFile = tempFileIfRemote(_destUrl, _type); QString arcDir = newSource.adjusted(QUrl::StripTrailingSlash).path(); setProgressTitle(i18n("Processed files")); QString save = QDir::currentPath(); QDir::setCurrent(arcDir); bool result = KRarcHandler::pack(_fileNames, _type, arcFile, totalFiles, _packProperties, observer()); QDir::setCurrent(save); if (isExited()) return; if (!result) { sendError(KIO::ERR_INTERNAL, i18n("Error while packing")); return; } if (!uploadTempFiles()) return; sendSuccess(); } -TestArchiveJob::TestArchiveJob(const QUrl &srcUrl, const QStringList & fileNames) : AbstractThreadedJob() +TestArchiveJob::TestArchiveJob(const QUrl &srcUrl, const QStringList & fileNames) { startAbstractJobThread(new TestArchiveThread(srcUrl, fileNames)); } TestArchiveJob * TestArchiveJob::testArchives(const QUrl &srcUrl, const QStringList & fileNames) { return new TestArchiveJob(srcUrl, fileNames); } -TestArchiveThread::TestArchiveThread(const QUrl &srcUrl, const QStringList & fileNames) : AbstractJobThread(), +TestArchiveThread::TestArchiveThread(const QUrl &srcUrl, const QStringList & fileNames) : _sourceUrl(srcUrl), _fileNames(fileNames) { } void TestArchiveThread::slotStart() { // Gets a QUrl of the source folder, which may be remote QUrl newSource = downloadIfRemote(_sourceUrl, _fileNames); if (newSource.isEmpty()) return; for (int i = 0; i < _fileNames.count(); ++i) { QString path, type, password, arcName = _fileNames[i]; if (!getArchiveInformation(path, type, password, arcName, newSource)) return; // test the archive if (!KRarcHandler::test(path, type, password, observer(), 0)) { sendError(KIO::ERR_NO_CONTENT, i18nc("%1=archive filename", "%1, test failed.", arcName)); return; } } sendMessage(i18n("Archive tests passed.")); sendSuccess(); } -UnpackJob::UnpackJob(const QUrl &srcUrl, const QUrl &destUrl, const QStringList & fileNames) : AbstractThreadedJob() +UnpackJob::UnpackJob(const QUrl &srcUrl, const QUrl &destUrl, const QStringList & fileNames) { startAbstractJobThread(new UnpackThread(srcUrl, destUrl, fileNames)); } UnpackJob * UnpackJob::createUnpacker(const QUrl &srcUrl, const QUrl &destUrl, const QStringList & fileNames) { return new UnpackJob(srcUrl, destUrl, fileNames); } UnpackThread::UnpackThread(const QUrl &srcUrl, const QUrl &destUrl, const QStringList & fileNames) : - AbstractJobThread(), _sourceUrl(srcUrl), _destUrl(destUrl), _fileNames(fileNames) + _sourceUrl(srcUrl), _destUrl(destUrl), _fileNames(fileNames) { } void UnpackThread::slotStart() { // Gets a QUrl of the source folder, which may be remote QUrl newSource = downloadIfRemote(_sourceUrl, _fileNames); if (newSource.isEmpty()) return; QString localDest = tempDirIfRemote(_destUrl); for (int i = 0; i < _fileNames.count(); ++i) { QString path, type, password, arcName = _fileNames[i]; if (!getArchiveInformation(path, type, password, arcName, newSource)) return; setProgressTitle(i18n("Processed files")); // unpack the files bool result = KRarcHandler::unpack(path, type, password, localDest, observer()); if (isExited()) return; if (!result) { sendError(KIO::ERR_INTERNAL, i18n("Error while unpacking")); return; } } if (!uploadTempFiles()) return; sendSuccess(); } diff --git a/krusader/Archive/packjob.h b/krusader/Archive/packjob.h index 4d7cab5a..4c40e4be 100644 --- a/krusader/Archive/packjob.h +++ b/krusader/Archive/packjob.h @@ -1,125 +1,125 @@ /***************************************************************************** * Copyright (C) 2009 Csaba Karai * * Copyright (C) 2009-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef PACKJOB_H #define PACKJOB_H // QtCore #include #include "abstractthreadedjob.h" class PackThread; class TestArchiveThread; class UnpackThread; class PackJob : public AbstractThreadedJob { Q_OBJECT private: PackJob(const QUrl &srcUrl, const QUrl &destUrl, const QStringList & fileNames, const QString &type, const QMap &packProps); public: static PackJob * createPacker(const QUrl &srcUrl, const QUrl &destUrl, const QStringList & fileNames, const QString &type, const QMap &packProps); }; class PackThread : public AbstractJobThread { Q_OBJECT public: PackThread(const QUrl &srcUrl, const QUrl &destUrl, const QStringList & fileNames, const QString &type, const QMap &packProps); - virtual ~PackThread() {} + ~PackThread() override = default; protected slots: - virtual void slotStart() Q_DECL_OVERRIDE; + void slotStart() Q_DECL_OVERRIDE; private: QUrl _sourceUrl; QUrl _destUrl; QStringList _fileNames; QString _type; QMap _packProperties; }; class TestArchiveJob : public AbstractThreadedJob { Q_OBJECT private: TestArchiveJob(const QUrl &srcUrl, const QStringList & fileNames); public: static TestArchiveJob * testArchives(const QUrl &srcUrl, const QStringList & fileNames); }; class TestArchiveThread : public AbstractJobThread { Q_OBJECT public: TestArchiveThread(const QUrl &srcUrl, const QStringList & fileNames); - virtual ~TestArchiveThread() {} + ~TestArchiveThread() override = default; protected slots: - virtual void slotStart() Q_DECL_OVERRIDE; + void slotStart() Q_DECL_OVERRIDE; private: QUrl _sourceUrl; QStringList _fileNames; }; class UnpackJob : public AbstractThreadedJob { Q_OBJECT private: UnpackJob(const QUrl &srcUrl, const QUrl &destUrl, const QStringList & fileNames); public: static UnpackJob * createUnpacker(const QUrl &srcUrl, const QUrl &destUrl, const QStringList & fileNames); }; class UnpackThread : public AbstractJobThread { Q_OBJECT public: UnpackThread(const QUrl &srcUrl, const QUrl &destUrl, const QStringList & fileNames); - virtual ~UnpackThread() {} + ~UnpackThread() override = default; protected slots: - virtual void slotStart() Q_DECL_OVERRIDE; + void slotStart() Q_DECL_OVERRIDE; private: QUrl _sourceUrl; QUrl _destUrl; QStringList _fileNames; }; #endif // __PACK_JOB_H__ diff --git a/krusader/BookMan/kraddbookmarkdlg.cpp b/krusader/BookMan/kraddbookmarkdlg.cpp index 99adaed5..21b69c60 100644 --- a/krusader/BookMan/kraddbookmarkdlg.cpp +++ b/krusader/BookMan/kraddbookmarkdlg.cpp @@ -1,186 +1,186 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "kraddbookmarkdlg.h" #include "../krglobal.h" #include "../icon.h" #include "krbookmarkhandler.h" // QtWidgets #include #include #include #include #include #include #include -KrAddBookmarkDlg::KrAddBookmarkDlg(QWidget *parent, QUrl url): +KrAddBookmarkDlg::KrAddBookmarkDlg(QWidget *parent, const QUrl& url): QDialog(parent) { setWindowModality(Qt::WindowModal); setWindowTitle(i18n("Add Bookmark")); - QVBoxLayout *mainLayout = new QVBoxLayout; + auto *mainLayout = new QVBoxLayout; setLayout(mainLayout); - QGridLayout *layout = new QGridLayout; // expanding + auto *layout = new QGridLayout; // expanding // name and url QLabel *lb1 = new QLabel(i18n("Name:"), this); _name = new KLineEdit(this); _name->setText(url.toDisplayString()); // default name is the url _name->selectAll(); // make the text selected layout->addWidget(lb1, 0, 0); layout->addWidget(_name, 0, 1); QLabel *lb2 = new QLabel(i18n("URL:"), this); _url = new KLineEdit(this); layout->addWidget(lb2, 1, 0); layout->addWidget(_url, 1, 1); _url->setText(url.toDisplayString()); // set the url in the field // create in linedit and button QLabel *lb3 = new QLabel(i18n("Create in:"), this); _folder = new KLineEdit(this); layout->addWidget(lb3, 2, 0); layout->addWidget(_folder, 2, 1); _folder->setReadOnly(true); _createInBtn = new QToolButton(this); _createInBtn->setIcon(Icon("go-down")); _createInBtn->setCheckable(true); connect(_createInBtn, &QToolButton::toggled, this, &KrAddBookmarkDlg::toggleCreateIn); layout->addWidget(_createInBtn, 2, 2); mainLayout->addLayout(layout); detailsWidget = createInWidget(); detailsWidget->setVisible(false); mainLayout->addWidget(detailsWidget); 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); newFolderButton = new QPushButton(i18n("New Folder")); buttonBox->addButton(newFolderButton, QDialogButtonBox::ActionRole); newFolderButton->setVisible(false);// hide it until _createIn is shown connect(newFolderButton, &QPushButton::clicked, this, &KrAddBookmarkDlg::newFolder); connect(buttonBox, &QDialogButtonBox::accepted, this, &KrAddBookmarkDlg::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &KrAddBookmarkDlg::reject); _name->setFocus(); resize(sizeHint().width() * 2, sizeHint().height()); } void KrAddBookmarkDlg::toggleCreateIn(bool show) { _createInBtn->setIcon(Icon(show ? "go-up" : "go-down")); newFolderButton->setVisible(show); detailsWidget->setVisible(show); } // creates the widget that lets you decide where to put the new bookmark QWidget *KrAddBookmarkDlg::createInWidget() { _createIn = new KrTreeWidget(this); _createIn->setHeaderLabel(i18n("Folders")); _createIn->header()->hide(); _createIn->setRootIsDecorated(true); _createIn->setAlternatingRowColors(false); // disable alternate coloring - QTreeWidgetItem *item = new QTreeWidgetItem(_createIn); + auto *item = new QTreeWidgetItem(_createIn); item->setText(0, i18n("Bookmarks")); _createIn->expandItem(item); item->setSelected(true); _xr[item] = krBookMan->_root; populateCreateInWidget(krBookMan->_root, item); _createIn->setCurrentItem(item); slotSelectionChanged(); connect(_createIn, &KrTreeWidget::itemSelectionChanged, this, &KrAddBookmarkDlg::slotSelectionChanged); return _createIn; } void KrAddBookmarkDlg::slotSelectionChanged() { QList items = _createIn->selectedItems(); if (items.count() > 0) { _folder->setText(_xr[ items[ 0 ] ]->text()); } } void KrAddBookmarkDlg::populateCreateInWidget(KrBookmark *root, QTreeWidgetItem *parent) { QListIterator it(root->children()); while (it.hasNext()) { KrBookmark *bm = it.next(); if (bm->isFolder()) { - QTreeWidgetItem *item = new QTreeWidgetItem(parent); + auto *item = new QTreeWidgetItem(parent); item->setText(0, bm->text()); item->treeWidget()->expandItem(item); _xr[item] = bm; populateCreateInWidget(bm, item); } } } void KrAddBookmarkDlg::newFolder() { // get the name QString newFolder = QInputDialog::getText(this, i18n("New Folder"), i18n("Folder name:")); if (newFolder.isEmpty()) { return; } QList items = _createIn->selectedItems(); if (items.count() == 0) return; // add to the list in bookman KrBookmark *bm = new KrBookmark(newFolder); krBookMan->addBookmark(bm, _xr[ items[ 0 ]]); // fix the gui - QTreeWidgetItem *item = new QTreeWidgetItem(items[ 0 ]); + auto *item = new QTreeWidgetItem(items[ 0 ]); item->setText(0, bm->text()); _xr[item] = bm; _createIn->setCurrentItem(item); item->setSelected(true); } KrBookmark * KrAddBookmarkDlg::folder() const { QList items = _createIn->selectedItems(); if (items.count() == 0) - return 0; + return nullptr; return _xr[ items[ 0 ] ]; } diff --git a/krusader/BookMan/kraddbookmarkdlg.h b/krusader/BookMan/kraddbookmarkdlg.h index 7997cae6..730eebe9 100644 --- a/krusader/BookMan/kraddbookmarkdlg.h +++ b/krusader/BookMan/kraddbookmarkdlg.h @@ -1,70 +1,70 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef KRADDBOOKMARKDLG_H #define KRADDBOOKMARKDLG_H #include "krbookmark.h" #include "../GUI/krtreewidget.h" // QtCore #include #include // QtWidgets #include #include #include class KrAddBookmarkDlg: public QDialog { Q_OBJECT public: - explicit KrAddBookmarkDlg(QWidget *parent, QUrl url = QUrl()); + explicit KrAddBookmarkDlg(QWidget *parent, const QUrl& url = QUrl()); QUrl url() const { return QUrl::fromUserInput(_url->text(), QString(), QUrl::AssumeLocalFile); } QString name() const { return _name->text(); } KrBookmark *folder() const; protected: QWidget *createInWidget(); void populateCreateInWidget(KrBookmark *root, QTreeWidgetItem *parent); protected slots: void toggleCreateIn(bool show); void slotSelectionChanged(); void newFolder(); private: KLineEdit *_name; KLineEdit *_url; KLineEdit *_folder; KrTreeWidget *_createIn; QMap _xr; QToolButton *_createInBtn; QPushButton *newFolderButton; QWidget *detailsWidget; }; #endif // KRADDBOOKMARKDLG_H diff --git a/krusader/BookMan/krbookmark.cpp b/krusader/BookMan/krbookmark.cpp index 7fe631c2..5575927f 100644 --- a/krusader/BookMan/krbookmark.cpp +++ b/krusader/BookMan/krbookmark.cpp @@ -1,151 +1,152 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "krbookmark.h" #include "../krglobal.h" #include "../icon.h" #include "../Archive/krarchandler.h" #include "../FileSystem/krtrashhandler.h" #include "../Panel/listpanelactions.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 iconName, QString actionName) : - QAction(parent), _url(url), _iconName(iconName), _folder(false), _separator(false), _autoDelete(true) +KrBookmark::KrBookmark(const QString& name, QUrl url, KActionCollection *parent, const QString& iconName, const QString& actionName) : + QAction(parent), _url(std::move(url)), _iconName(iconName), _folder(false), _separator(false), _autoDelete(true) { QString actName = actionName.isNull() ? BM_NAME(name) : BM_NAME(actionName); setText(name); parent->addAction(actName, this); connect(this, &KrBookmark::triggered, this, &KrBookmark::activatedProxy); setIconName(iconName); } -KrBookmark::KrBookmark(QString name, QString iconName) : - QAction(Icon(iconName), name, 0), _iconName(iconName), _folder(true), _separator(false), _autoDelete(false) +KrBookmark::KrBookmark(const QString& name, const QString& iconName) : + QAction(Icon(iconName), name, nullptr), _iconName(iconName), _folder(true), _separator(false), _autoDelete(false) { setIcon(Icon(iconName == "" ? "folder" : iconName)); } KrBookmark::~KrBookmark() { if (_autoDelete) { QListIterator it(_children); while (it.hasNext()) delete it.next(); _children.clear(); } } -void KrBookmark::setIconName(QString iconName) +void KrBookmark::setIconName(const QString& iconName) { if (!iconName.isEmpty()) { setIcon(Icon(iconName)); } else if (_url.isLocalFile()) { setIcon(Icon("folder")); } else if (KRarcHandler::isArchive(_url)) { setIcon(Icon("application-x-tar")); } else { setIcon(Icon("folder-html")); } } -KrBookmark * KrBookmark::getExistingBookmark(QString actionName, KActionCollection *collection) +KrBookmark * KrBookmark::getExistingBookmark(const QString& actionName, KActionCollection *collection) { - return static_cast(collection->action(BM_NAME(actionName))); + return dynamic_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(Icon(KrTrashHandler::trashIconName())); 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(Icon("document-open-remote")); } 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(Icon("network-workgroup")); } return bm; } QAction * KrBookmark::jumpBackAction(KActionCollection *collection, bool isSetter, ListPanelActions *sourceActions) { auto actionName = isSetter ? QString("setJumpBack") : QString("jumpBack"); auto action = collection->action(actionName); if (action) { return action; } if (!sourceActions) { return nullptr; } // copy essential part of source action auto sourceAction = isSetter ? sourceActions->actSetJumpBack : sourceActions->actJumpBack; action = new QAction(sourceAction->icon(), sourceAction->text(), sourceAction); action->setShortcut(sourceAction->shortcut()); action->setShortcutContext(Qt::WidgetShortcut); connect(action, &QAction::triggered, sourceAction, &QAction::trigger); // ensure there are no accelerator keys coming from another menu action->setText(KLocalizedString::removeAcceleratorMarker(action->text())); collection->addAction(actionName, action); return action; } 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/krbookmark.h b/krusader/BookMan/krbookmark.h index 58353bfb..561c68f2 100644 --- a/krusader/BookMan/krbookmark.h +++ b/krusader/BookMan/krbookmark.h @@ -1,93 +1,93 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef KRBOOKMARK_H #define KRBOOKMARK_H // QtCore #include #include // QtWidgets #include class KActionCollection; class ListPanelActions; class KrBookmark: public QAction { Q_OBJECT public: - KrBookmark(QString name, QUrl url, KActionCollection *parent, QString iconName = "", QString actionName = QString()); - explicit KrBookmark(QString name, QString iconName = ""); // creates a folder - ~KrBookmark(); + KrBookmark(const QString& name, QUrl url, KActionCollection *parent, const QString& iconName = "", const QString& actionName = QString()); + explicit KrBookmark(const QString& name, const QString& iconName = ""); // creates a folder + ~KrBookmark() override; // text() and setText() to change the name of the bookmark // icon() and setIcon() to change icons - void setIconName(QString iconName); + void setIconName(const QString& iconName); inline const QString& iconName() const { return _iconName; } inline const QUrl &url() const { return _url; } inline void setURL(const QUrl &url) { _url = url; } inline bool isFolder() const { return _folder; } inline bool isSeparator() const { return _separator; } QList& children() { return _children; } - static KrBookmark * getExistingBookmark(QString actionName, KActionCollection *collection); + static KrBookmark * getExistingBookmark(const QString& actionName, KActionCollection *collection); // ----- special bookmarks static KrBookmark * trash(KActionCollection *collection); static KrBookmark * virt(KActionCollection *collection); static KrBookmark * lan(KActionCollection *collection); - static QAction * jumpBackAction(KActionCollection *collection, bool isSetter = false, ListPanelActions *sourceActions = 0); + static QAction * jumpBackAction(KActionCollection *collection, bool isSetter = false, ListPanelActions *sourceActions = nullptr); static KrBookmark * separator(); signals: void activated(const QUrl &url); protected slots: void activatedProxy(); private: QUrl _url; QString _iconName; bool _folder; bool _separator; bool _autoDelete; QList _children; }; #endif // KRBOOKMARK_H diff --git a/krusader/BookMan/krbookmarkhandler.cpp b/krusader/BookMan/krbookmarkhandler.cpp index 5b34d673..d7bfad17 100644 --- a/krusader/BookMan/krbookmarkhandler.cpp +++ b/krusader/BookMan/krbookmarkhandler.cpp @@ -1,881 +1,881 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "krbookmarkhandler.h" #include "kraddbookmarkdlg.h" #include "../krglobal.h" #include "../icon.h" #include "../krslots.h" #include "../kractions.h" #include "../krmainwindow.h" #include "../Dialogs/popularurls.h" #include "../FileSystem/filesystem.h" #include "../Panel/krpanel.h" #include "../Panel/listpanelactions.h" // QtCore #include #include #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(QUrl)), 0, 0); connect(X, SIGNAL(activated(QUrl)), this, SLOT(slotActivated(QUrl))); } KrBookmarkHandler::KrBookmarkHandler(KrMainWindow *mainWindow) : QObject(mainWindow->widget()), _mainWindow(mainWindow), _middleClick(false), - _mainBookmarkPopup(0), - _specialBookmarks(), + _mainBookmarkPopup(nullptr), _quickSearchAction(nullptr), _quickSearchBar(nullptr), _quickSearchMenu(nullptr) { // 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(); // create bookmark manager QString filename = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + BOOKMARKS_FILE; manager = KBookmarkManager::managerForFile(filename, QStringLiteral("krusader")); connect(manager, &KBookmarkManager::changed, this, &KrBookmarkHandler::bookmarksChanged); // create the quick search bar and action _quickSearchAction = new QWidgetAction(this); _quickSearchBar = new QLineEdit(); _quickSearchBar->setPlaceholderText(i18n("Type to search...")); _quickSearchAction->setDefaultWidget(_quickSearchBar); // ownership of the bar is transferred to the action _quickSearchAction->setEnabled(false); _setQuickSearchText(""); // fill a dummy menu to properly init actions (allows toolbar bookmark buttons to work properly) auto menu = new QMenu(mainWindow->widget()); populate(menu); menu->deleteLater(); } KrBookmarkHandler::~KrBookmarkHandler() { delete manager; delete _privateCollection; } void KrBookmarkHandler::bookmarkCurrent(QUrl url) { - QPointer dlg = new KrAddBookmarkDlg(_mainWindow->widget(), url); + QPointer dlg = new KrAddBookmarkDlg(_mainWindow->widget(), std::move(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) + if (folder == nullptr) 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) +bool KrBookmarkHandler::importFromFileBookmark(QDomElement &e, KrBookmark *parent, const QString& path, QString *errorMsg) { QString url, name, iconName; // 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")) { iconName = 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, iconName, path + name); } else { bm->setURL(QUrl(url)); bm->setIconName(iconName); } parent->children().append(bm); return true; } -bool KrBookmarkHandler::importFromFileFolder(QDomNode &first, KrBookmark *parent, QString path, QString *errorMsg) +bool KrBookmarkHandler::importFromFileFolder(QDomNode &first, KrBookmark *parent, const 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, false); 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::_setQuickSearchText(const QString &text) { bool isEmptyQuickSearchBarVisible = KConfigGroup(krConfig, "Look&Feel").readEntry("Always show search bar", true); _quickSearchBar->setText(text); auto length = text.length(); bool isVisible = isEmptyQuickSearchBarVisible || length > 0; _quickSearchAction->setVisible(isVisible); _quickSearchBar->setVisible(isVisible); if (length == 0) { qDebug() << "Bookmark search: reset"; _resetActionTextAndHighlighting(); } else { qDebug() << "Bookmark search: query =" << text; } } QString KrBookmarkHandler::_quickSearchText() const { return _quickSearchBar->text(); } void KrBookmarkHandler::_highlightAction(QAction *action, bool isMatched) { auto font = action->font(); font.setBold(isMatched); action->setFont(font); } void KrBookmarkHandler::populate(QMenu *menu) { // removing action from previous menu is necessary // otherwise it won't be displayed in the currently populating menu if (_mainBookmarkPopup) { _mainBookmarkPopup->removeAction(_quickSearchAction); } _mainBookmarkPopup = menu; menu->clear(); _specialBookmarks.clear(); buildMenu(_root, menu); } void KrBookmarkHandler::buildMenu(KrBookmark *parent, QMenu *menu, int depth) { // add search bar widget to the top of the menu if (depth == 0) { menu->addAction(_quickSearchAction); } // 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); + auto *newMenu = new QMenu(menu); newMenu->setIcon(Icon(bm->iconName())); newMenu->setTitle(bm->text()); QAction *menuAction = menu->addMenu(newMenu); QVariant v; v.setValue(bm); menuAction->setData(v); buildMenu(bm, newMenu, depth + 1); } 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 (depth == 0) { 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); + auto *newMenu = new QMenu(menu); newMenu->setTitle(i18n("Popular URLs")); newMenu->setIcon(Icon("folder-bookmark")); 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) 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) { menu->addSeparator(); ListPanelActions *actions = _mainWindow->listPanelActions(); auto slotTriggered = [=] { if (_mainBookmarkPopup && !_mainBookmarkPopup->isHidden()) { _mainBookmarkPopup->close(); } }; auto addJumpBackAction = [=](bool isSetter) { auto action = KrBookmark::jumpBackAction(_privateCollection, isSetter, actions); if (action) { menu->addAction(action); _specialBookmarks.append(action); // disconnecting from this as a receiver is important: // we don't want to break connections established by KrBookmark::jumpBackAction disconnect(action, &QAction::triggered, this, nullptr); connect(action, &QAction::triggered, this, slotTriggered); } }; addJumpBackAction(true); addJumpBackAction(false); } } menu->addSeparator(); menu->addAction(KrActions::actAddBookmark); _specialBookmarks.append(KrActions::actAddBookmark); QAction *bmAct = menu->addAction(Icon("bookmarks"), i18n("Manage Bookmarks"), manager, SLOT(slotEditBookmarks())); _specialBookmarks.append(bmAct); // make sure the menu is connected to us - disconnect(menu, SIGNAL(triggered(QAction*)), 0, 0); + disconnect(menu, SIGNAL(triggered(QAction*)), nullptr, nullptr); } menu->installEventFilter(this); } void KrBookmarkHandler::clearBookmarks(KrBookmark *root, bool removeBookmarks) { for (auto it = root->children().begin(); it != root->children().end(); it = root->children().erase(it)) { KrBookmark *bm = *it; if (bm->isFolder()) { clearBookmarks(bm, removeBookmarks); delete bm; } else if (bm->isSeparator()) { delete bm; } else if (removeBookmarks) { foreach (QWidget *w, bm->associatedWidgets()) { w->removeAction(bm); } delete bm; } } } void KrBookmarkHandler::bookmarksChanged(const QString&, const QString&) { importFromFile(); } bool KrBookmarkHandler::eventFilter(QObject *obj, QEvent *ev) { auto eventType = ev->type(); - QMenu *menu = qobject_cast(obj); + auto *menu = qobject_cast(obj); if (eventType == QEvent::Show && menu) { _setQuickSearchText(""); _quickSearchMenu = menu; qDebug() << "Bookmark search: menu" << menu << "is shown"; return QObject::eventFilter(obj, ev); } if (eventType == QEvent::Close && menu && _quickSearchMenu) { if (_quickSearchMenu == menu) { qDebug() << "Bookmark search: stopped on menu" << menu; _setQuickSearchText(""); _quickSearchMenu = nullptr; } else { qDebug() << "Bookmark search: active action =" << _quickSearchMenu->activeAction(); // fix automatic deactivation of current action due to spurious close event from submenu auto quickSearchMenu = _quickSearchMenu; auto activeAction = _quickSearchMenu->activeAction(); QTimer::singleShot(0, this, [=]() { qDebug() << "Bookmark search: active action =" << quickSearchMenu->activeAction(); if (!quickSearchMenu->activeAction() && activeAction) { quickSearchMenu->setActiveAction(activeAction); qDebug() << "Bookmark search: restored active action =" << quickSearchMenu->activeAction(); } }); } return QObject::eventFilter(obj, ev); } // Having it occur on keypress is consistent with other shortcuts, // such as Ctrl+W and accelerator keys if (eventType == QEvent::KeyPress && menu) { - QKeyEvent *kev = static_cast(ev); + auto *kev = dynamic_cast(ev); QList acts = menu->actions(); bool quickSearchStarted = false; bool searchInSpecialItems = KConfigGroup(krConfig, "Look&Feel").readEntry("Search in special items", false); if (kev->key() == Qt::Key_Left && kev->modifiers() == Qt::NoModifier) { menu->close(); return true; } if ((kev->modifiers() != Qt::ShiftModifier && kev->modifiers() != Qt::NoModifier) || kev->text().isEmpty() || kev->key() == Qt::Key_Delete || kev->key() == Qt::Key_Return || kev->key() == Qt::Key_Escape) { return QObject::eventFilter(obj, ev); } // update quick search text if (kev->key() == Qt::Key_Backspace) { auto newSearchText = _quickSearchText(); newSearchText.chop(1); _setQuickSearchText(newSearchText); if (_quickSearchText().length() == 0) { return QObject::eventFilter(obj, ev); } } else { quickSearchStarted = _quickSearchText().length() == 0; _setQuickSearchText(_quickSearchText().append(kev->text())); } if (quickSearchStarted) { _quickSearchMenu = menu; qDebug() << "Bookmark search: started on menu" << menu; } // match actions QAction *matchedAction = nullptr; int nMatches = 0; const Qt::CaseSensitivity matchCase = _quickSearchText() == _quickSearchText().toLower() ? Qt::CaseInsensitive : Qt::CaseSensitive; for (auto act : acts) { if (act->isSeparator() || act->text().isEmpty()) { continue; } if (!searchInSpecialItems && _specialBookmarks.contains(act)) { continue; } if (quickSearchStarted) { // if the first key press is an accelerator key, let the accelerator handler process this event if (act->text().contains('&' + kev->text(), Qt::CaseInsensitive)) { qDebug() << "Bookmark search: hit accelerator key of" << act; _setQuickSearchText(""); return QObject::eventFilter(obj, ev); } // strip accelerator keys from actions so they don't interfere with the search key press events auto text = act->text(); _quickSearchOriginalActionTitles.insert(act, text); act->setText(KLocalizedString::removeAcceleratorMarker(text)); } // match prefix of the action text to the query if (act->text().left(_quickSearchText().length()).compare(_quickSearchText(), matchCase) == 0) { _highlightAction(act); if (!matchedAction || matchedAction->menu()) { // Can't highlight menus (see comment below), hopefully pick something we can matchedAction = act; } nMatches++; } else { _highlightAction(act, false); } } if (matchedAction) { qDebug() << "Bookmark search: primary match =" << matchedAction->text() << ", number of matches =" << nMatches; } else { qDebug() << "Bookmark search: no matches"; } // trigger the matched menu item or set an active item accordingly if (nMatches == 1) { _setQuickSearchText(""); if ((bool) matchedAction->menu()) { menu->setActiveAction(matchedAction); } else { matchedAction->activate(QAction::Trigger); } } else if (nMatches > 1) { // Because of a bug submenus cannot be highlighted // https://bugreports.qt.io/browse/QTBUG-939 if (!matchedAction->menu()) { menu->setActiveAction(matchedAction); } else { menu->setActiveAction(nullptr); } } else { menu->setActiveAction(nullptr); } return true; } if (eventType == QEvent::MouseButtonRelease) { - switch (static_cast(ev)->button()) { + switch (dynamic_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()); + auto *menu = dynamic_cast(obj); + QAction *act = menu->actionAt(dynamic_cast(ev)->pos()); if (obj == _mainBookmarkPopup && _specialBookmarks.contains(act)) { rightClickOnSpecialBookmark(); return true; } - KrBookmark *bm = qobject_cast(act); - if (bm != 0) { + auto *bm = qobject_cast(act); + if (bm != nullptr) { rightClicked(menu, bm); return true; } else if (act && act->data().canConvert()) { - KrBookmark *bm = act->data().value(); + auto *bm = act->data().value(); rightClicked(menu, bm); } } break; case Qt::LeftButton: _middleClick = false; break; case Qt::MidButton: _middleClick = true; break; default: break; } } return QObject::eventFilter(obj, ev); } void KrBookmarkHandler::_resetActionTextAndHighlighting() { for (QHash::const_iterator i = _quickSearchOriginalActionTitles.begin(); i != _quickSearchOriginalActionTitles.end(); ++i) { QAction *action = i.key(); action->setText(i.value()); _highlightAction(action, false); } _quickSearchOriginalActionTitles.clear(); } #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(Icon("document-open"), i18n("Open")); act->setData(QVariant(OPEN_ID)); act = popup.addAction(Icon("tab-new"), i18n("Open in a new tab")); act->setData(QVariant(OPEN_NEW_TAB_ID)); popup.addSeparator(); } act = popup.addAction(Icon("edit-delete"), 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/BookMan/krbookmarkhandler.h b/krusader/BookMan/krbookmarkhandler.h index b664507a..657e21d7 100644 --- a/krusader/BookMan/krbookmarkhandler.h +++ b/krusader/BookMan/krbookmarkhandler.h @@ -1,101 +1,101 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef KRBOOKMARKHANDLER_H #define KRBOOKMARKHANDLER_H // QtCore #include #include #include #include #include // QtXml #include // QtWidgets #include #include #include #include "krbookmark.h" class KActionCollection; class KBookmarkManager; class KrMainWindow; class KrBookmarkHandler: public QObject { Q_OBJECT friend class KrAddBookmarkDlg; enum Actions { BookmarkCurrent = 0, ManageBookmarks }; public: explicit KrBookmarkHandler(KrMainWindow *mainWindow); - ~KrBookmarkHandler(); + ~KrBookmarkHandler() override; void populate(QMenu *menu); - void addBookmark(KrBookmark *bm, KrBookmark *parent = 0); + void addBookmark(KrBookmark *bm, KrBookmark *parent = nullptr); void bookmarkCurrent(QUrl url); protected: void deleteBookmark(KrBookmark *bm); void importFromFile(); - bool importFromFileBookmark(QDomElement &e, KrBookmark *parent, QString path, QString *errorMsg); - bool importFromFileFolder(QDomNode &first, KrBookmark *parent, QString path, QString *errorMsg); + bool importFromFileBookmark(QDomElement &e, KrBookmark *parent, const QString& path, QString *errorMsg); + bool importFromFileFolder(QDomNode &first, KrBookmark *parent, const QString& path, QString *errorMsg); void exportToFile(); void exportToFileFolder(QDomDocument &doc, QDomElement &parent, KrBookmark *folder); void exportToFileBookmark(QDomDocument &doc, QDomElement &where, KrBookmark *bm); void clearBookmarks(KrBookmark *root, bool removeBookmarks = true); void buildMenu(KrBookmark *parent, QMenu *menu, int depth = 0); bool eventFilter(QObject *obj, QEvent *ev) Q_DECL_OVERRIDE; void rightClicked(QMenu *menu, KrBookmark *bm); void rightClickOnSpecialBookmark(); void removeReferences(KrBookmark *root, KrBookmark *bmToRemove); protected slots: void bookmarksChanged(const QString&, const QString&); void slotActivated(const QUrl &url); private: KrMainWindow *_mainWindow; KActionCollection *_collection, *_privateCollection; KrBookmark *_root; // the whole KBookmarkManager is an ugly hack. use it until we have our own KBookmarkManager *manager; bool _middleClick; // if true, the user clicked the middle button to open the bookmark QPointer _mainBookmarkPopup; // main bookmark popup menu QList _specialBookmarks; // the action list of the special bookmarks QWidgetAction *_quickSearchAction; ///< Search bar container action QLineEdit *_quickSearchBar; ///< Search bar containing current query QMenu *_quickSearchMenu; ///< The menu where the search is performed QHash _quickSearchOriginalActionTitles; ///< Saved original action text values to restore after search void _setQuickSearchText(const QString &text); QString _quickSearchText() const; static void _highlightAction(QAction *action, bool isMatched = true); void _resetActionTextAndHighlighting(); }; Q_DECLARE_METATYPE(KrBookmark *) #endif // KRBOOKMARK_HANDLER_H diff --git a/krusader/Dialogs/checksumdlg.cpp b/krusader/Dialogs/checksumdlg.cpp index 95b5a9ca..a5431de0 100644 --- a/krusader/Dialogs/checksumdlg.cpp +++ b/krusader/Dialogs/checksumdlg.cpp @@ -1,576 +1,576 @@ /***************************************************************************** * Copyright (C) 2005 Shie Erlich * * Copyright (C) 2007-2008 Csaba Karai * * Copyright (C) 2008 Jonas Bähr * * Copyright (C) 2005-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "checksumdlg.h" #include "../krglobal.h" #include "../icon.h" #include "../krservices.h" #include "../krusader.h" #include "../GUI/krlistwidget.h" #include "../GUI/krtreewidget.h" // QtCore #include #include #include #include #include #include // QtWidgets #include #include #include #include #include #include // krazy:exclude=includes #include #include #include void Checksum::startCreationWizard(const QString &path, const QStringList &files) { if (files.isEmpty()) return; QDialog *dialog = new CHECKSUM_::CreateWizard(path, files); dialog->show(); } void Checksum::startVerifyWizard(const QString &path, const QString &checksumFile) { QDialog *dialog = new CHECKSUM_::VerifyWizard(path, checksumFile); dialog->show(); } namespace CHECKSUM_ { bool stopListFiles; // async operation invoked by QtConcurrent::run in creation wizard QStringList listFiles(const QString &path, const QStringList &fileNames) { const QDir baseDir(path); QStringList allFiles; - for (const QString fileName : fileNames) { + for (const QString& fileName : fileNames) { if (stopListFiles) return QStringList(); QDir subDir = QDir(baseDir.filePath(fileName)); if (subDir.exists()) { subDir.setFilter(QDir::Files); QDirIterator it(subDir, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks); while (it.hasNext()) { if (stopListFiles) return QStringList(); allFiles << baseDir.relativeFilePath(it.next()); } } else { // assume this is a file allFiles << fileName; } } return allFiles; } // ------------- Checksum Process ChecksumProcess::ChecksumProcess(QObject *parent, const QString &path) : KProcess(parent), m_tmpOutFile(QDir::tempPath() + QLatin1String("/krusader_XXXXXX.stdout")), m_tmpErrFile(QDir::tempPath() + QLatin1String("/krusader_XXXXXX.stderr")) { m_tmpOutFile.open(); // necessary to create the filename m_tmpErrFile.open(); // necessary to create the filename setOutputChannelMode(KProcess::SeparateChannels); // without this the next 2 lines have no effect! setStandardOutputFile(m_tmpOutFile.fileName()); setStandardErrorFile(m_tmpErrFile.fileName()); setWorkingDirectory(path); #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) connect(this, &ChecksumProcess::errorOccurred, this, &ChecksumProcess::slotError); #endif connect(this, static_cast(&QProcess::finished), this, &ChecksumProcess::slotFinished); } ChecksumProcess::~ChecksumProcess() { - disconnect(this, 0, this, 0); // QProcess emits finished() on destruction + disconnect(this, nullptr, this, nullptr); // QProcess emits finished() on destruction close(); } void ChecksumProcess::slotError(QProcess::ProcessError error) { if (error == QProcess::FailedToStart) { - KMessageBox::error(0, i18n("Could not start %1.", program().join(" "))); + KMessageBox::error(nullptr, i18n("Could not start %1.", program().join(" "))); } } void ChecksumProcess::slotFinished(int, QProcess::ExitStatus exitStatus) { if (exitStatus != QProcess::NormalExit) { - KMessageBox::error(0, i18n("There was an error while running %1.", + KMessageBox::error(nullptr, i18n("There was an error while running %1.", program().join(" "))); return; } // parse result files if (!KrServices::fileToStringList(&m_tmpOutFile, m_outputLines) || !KrServices::fileToStringList(&m_tmpErrFile, m_errorLines)) { - KMessageBox::error(0, i18n("Error reading stdout or stderr")); + KMessageBox::error(nullptr, i18n("Error reading stdout or stderr")); return; } emit resultReady(); } // ------------- Generic Checksum Wizard -ChecksumWizard::ChecksumWizard(const QString &path) : QWizard(krApp), m_path(path), m_process(0) +ChecksumWizard::ChecksumWizard(const QString &path) : QWizard(krApp), m_path(path), m_process(nullptr) { setAttribute(Qt::WA_DeleteOnClose); // init the dictionary - pity it has to be manually m_checksumTools.insert("md5", "md5sum"); m_checksumTools.insert("sha1", "sha1sum"); m_checksumTools.insert("sha256", "sha256sum"); m_checksumTools.insert("sha224", "sha224sum"); m_checksumTools.insert("sha384", "sha384sum"); m_checksumTools.insert("sha512", "sha512sum"); connect(this, &QWizard::currentIdChanged, this, &ChecksumWizard::slotCurrentIdChanged); } ChecksumWizard::~ChecksumWizard() { if (m_process) { delete m_process; } } void ChecksumWizard::slotCurrentIdChanged(int id) { if (id == m_introId) { onIntroPage(); } else if (id == m_progressId) { if (m_process) { // we are coming from the result page; delete m_process; - m_process = 0; + m_process = nullptr; restart(); } else { button(QWizard::BackButton)->hide(); button(QWizard::NextButton)->hide(); onProgressPage(); } } else if (id == m_resultId) { onResultPage(); } } QWizardPage *ChecksumWizard::createProgressPage(const QString &title) { - QWizardPage *page = new QWizardPage; + auto *page = new QWizardPage; page->setTitle(title); page->setPixmap(QWizard::LogoPixmap, Icon("process-working").pixmap(32)); page->setSubTitle(i18n("Please wait...")); - QVBoxLayout *mainLayout = new QVBoxLayout; + auto *mainLayout = new QVBoxLayout; page->setLayout(mainLayout); // "busy" indicator - QProgressBar *bar = new QProgressBar(); + auto *bar = new QProgressBar(); bar->setRange(0,0); mainLayout->addWidget(bar); return page; } -bool ChecksumWizard::checkExists(const QString type) +bool ChecksumWizard::checkExists(const QString& type) { if (!KrServices::cmdExist(m_checksumTools[type])) { KMessageBox::error( this, i18n("Krusader cannot find a checksum tool that handles %1 on your system. " "Please check the Dependencies page in Krusader's settings.", type)); return false; } return true; } void ChecksumWizard::runProcess(const QString &type, const QStringList &args) { - Q_ASSERT(m_process == 0); + Q_ASSERT(m_process == nullptr); m_process = new ChecksumProcess(this, m_path); m_process->setProgram(KrServices::fullPathName(m_checksumTools[type]), args); // show next page (with results) (only) when process is done connect(m_process, &ChecksumProcess::resultReady, this, &QWizard::next); // run the process m_process->start(); } void ChecksumWizard::addChecksumLine(KrTreeWidget *tree, const QString &line) { - QTreeWidgetItem *item = new QTreeWidgetItem(tree); + auto *item = new QTreeWidgetItem(tree); const int hashLength = line.indexOf(' '); // delimiter is either " " or " *" item->setText(0, line.left(hashLength)); QString fileName = line.mid(hashLength + 2); if (fileName.endsWith('\n')) fileName.chop(1); item->setText(1, fileName); } // ------------- Create Wizard CreateWizard::CreateWizard(const QString &path, const QStringList &_files) : ChecksumWizard(path), - m_fileNames(_files), m_listFilesWatcher() + m_fileNames(_files) { m_introId = addPage(createIntroPage()); m_progressId = addPage(createProgressPage(i18n("Creating Checksums"))); m_resultId = addPage(createResultPage()); setButton(QWizard::FinishButton, QDialogButtonBox(QDialogButtonBox::Save).button(QDialogButtonBox::Save)); connect(&m_listFilesWatcher, &QFutureWatcher::resultReadyAt, this, &CreateWizard::createChecksums); } QWizardPage *CreateWizard::createIntroPage() { - QWizardPage *page = new QWizardPage; + auto *page = new QWizardPage; page->setTitle(i18n("Create Checksums")); page->setPixmap(QWizard::LogoPixmap, Icon("document-edit-sign").pixmap(32)); page->setSubTitle(i18n("About to calculate checksum for the following files or directories:")); - QVBoxLayout *mainLayout = new QVBoxLayout; + auto *mainLayout = new QVBoxLayout; page->setLayout(mainLayout); // file list - KrListWidget *listWidget = new KrListWidget; + auto *listWidget = new KrListWidget; listWidget->addItems(m_fileNames); mainLayout->addWidget(listWidget); // checksum method - QHBoxLayout *hLayout = new QHBoxLayout; + auto *hLayout = new QHBoxLayout; QLabel *methodLabel = new QLabel(i18n("Select the checksum method:")); hLayout->addWidget(methodLabel); m_methodBox = new KComboBox; // -- fill the combo with available methods - for (const QString type: m_checksumTools.keys()) + for (const QString& type: m_checksumTools.keys()) m_methodBox->addItem(type); m_methodBox->setFocus(); hLayout->addWidget(m_methodBox); mainLayout->addLayout(hLayout); return page; } QWizardPage *CreateWizard::createResultPage() { - QWizardPage *page = new QWizardPage; + auto *page = new QWizardPage; page->setTitle(i18n("Checksum Results")); - QVBoxLayout *mainLayout = new QVBoxLayout; + auto *mainLayout = new QVBoxLayout; page->setLayout(mainLayout); m_hashesTreeWidget = new KrTreeWidget(this); m_hashesTreeWidget->setAllColumnsShowFocus(true); m_hashesTreeWidget->setHeaderLabels(QStringList() << i18n("Hash") << i18n("File")); mainLayout->addWidget(m_hashesTreeWidget); m_errorLabel = new QLabel(i18n("Errors received:")); mainLayout->addWidget(m_errorLabel); m_errorListWidget = new KrListWidget; mainLayout->addWidget(m_errorListWidget); m_onePerFileBox = new QCheckBox(i18n("Save one checksum file for each source file")); m_onePerFileBox->setChecked(false); mainLayout->addWidget(m_onePerFileBox); return page; } void CreateWizard::onIntroPage() { button(QWizard::NextButton)->show(); } void CreateWizard::onProgressPage() { // first, get all files (recurse in directories) - async stopListFiles = false; // QFuture cannot cancel QtConcurrent::run connect(this, &CreateWizard::finished, this, [=]() { stopListFiles = true; }); QFuture listFuture = QtConcurrent::run(listFiles, m_path, m_fileNames); m_listFilesWatcher.setFuture(listFuture); } void CreateWizard::createChecksums() { const QString type = m_methodBox->currentText(); if (!checkExists(type)) { button(QWizard::BackButton)->show(); return; } const QStringList &allFiles = m_listFilesWatcher.result(); if (allFiles.isEmpty()) { KMessageBox::error(this, i18n("No files found")); button(QWizard::BackButton)->show(); return; } runProcess(type, allFiles); // set suggested filename m_suggestedFilePath = QDir(m_path).filePath( (m_fileNames.count() > 1 ? "checksum." : (m_fileNames[0] + '.')) + type); } void CreateWizard::onResultPage() { // hash tools display errors into stderr, so we'll use that to determine the result of the job const QStringList outputLines = m_process->stdOutput(); const QStringList errorLines = m_process->errOutput(); bool errors = !errorLines.isEmpty(); bool successes = !outputLines.isEmpty(); QWizardPage *page = currentPage(); page->setPixmap(QWizard::LogoPixmap, Icon(errors || !successes ? "dialog-error" : "dialog-information").pixmap(32)); page->setSubTitle(errors || !successes ? i18n("Errors were detected while creating the checksums") : i18n("Checksums were created successfully")); m_hashesTreeWidget->clear(); m_hashesTreeWidget->setVisible(successes); if (successes) { - for (const QString line : outputLines) + for (const QString& line : outputLines) addChecksumLine(m_hashesTreeWidget, line); //m_hashesTreeWidget->sortItems(1, Qt::AscendingOrder); } m_errorLabel->setVisible(errors); m_errorListWidget->setVisible(errors); m_errorListWidget->clear(); m_errorListWidget->addItems(errorLines); m_onePerFileBox->setEnabled(outputLines.size() > 1); button(QWizard::FinishButton)->setEnabled(successes); } bool CreateWizard::savePerFile() { const QString type = m_suggestedFilePath.mid(m_suggestedFilePath.lastIndexOf('.')); krApp->startWaiting(i18n("Saving checksum files..."), 0); - for (const QString line : m_process->stdOutput()) { + for (const QString& line : m_process->stdOutput()) { const QString filename = line.mid(line.indexOf(' ') + 2) + type; if (!saveChecksumFile(QStringList() << line, filename)) { KMessageBox::error(this, i18n("Errors occurred while saving multiple checksums. Stopping")); krApp->stopWait(); return false; } } krApp->stopWait(); return true; } bool CreateWizard::saveChecksumFile(const QStringList &data, const QString &filename) { QString filePath = filename.isEmpty() ? m_suggestedFilePath : filename; if (filename.isEmpty() || QFile::exists(filePath)) { filePath = QFileDialog::getSaveFileName(this, QString(), filePath); if (filePath.isEmpty()) return false; // user pressed cancel } QFile file(filePath); if (file.open(QIODevice::WriteOnly)) { QTextStream stream(&file); - for (const QString line : data) + for (const QString& line : data) stream << line << "\n"; file.close(); } if (file.error() != QFile::NoError) { KMessageBox::detailedError(this, i18n("Error saving file %1", filePath), file.errorString()); return false; } return true; } void CreateWizard::accept() { const bool saved = m_onePerFileBox->isChecked() ? savePerFile() : saveChecksumFile(m_process->stdOutput()); if (saved) QWizard::accept(); } // ------------- Verify Wizard VerifyWizard::VerifyWizard(const QString &path, const QString &inputFile) : ChecksumWizard(path) { m_checksumFile = isSupported(inputFile) ? inputFile : path; m_introId = addPage(createIntroPage()); // m_checksumFile must already be set m_progressId = addPage(createProgressPage(i18n("Verifying Checksums"))); m_resultId = addPage(createResultPage()); } void VerifyWizard::slotChecksumPathChanged(const QString &path) { m_hashesTreeWidget->clear(); button(QWizard::NextButton)->setEnabled(false); if (!isSupported(path)) return; m_checksumFile = path; // parse and display checksum file content; only for the user, parsed values are not used m_hashesTreeWidget->clear(); QFile file(m_checksumFile); if (file.open(QFile::ReadOnly)) { QTextStream inStream(&file); while (!inStream.atEnd()) { addChecksumLine(m_hashesTreeWidget, file.readLine()); } } file.close(); button(QWizard::NextButton)->setEnabled(true); } QWizardPage *VerifyWizard::createIntroPage() { - QWizardPage *page = new QWizardPage; + auto *page = new QWizardPage; page->setTitle(i18n("Verify Checksum File")); page->setPixmap(QWizard::LogoPixmap, Icon("document-edit-verify").pixmap(32)); page->setSubTitle(i18n("About to verify the following checksum file")); - QVBoxLayout *mainLayout = new QVBoxLayout; + auto *mainLayout = new QVBoxLayout; page->setLayout(mainLayout); // checksum file - QHBoxLayout *hLayout = new QHBoxLayout; + auto *hLayout = new QHBoxLayout; QLabel *checksumFileLabel = new QLabel(i18n("Checksum file:")); hLayout->addWidget(checksumFileLabel); - KUrlRequester *checksumFileReq = new KUrlRequester; + auto *checksumFileReq = new KUrlRequester; QString typesFilter; - for (const QString ext: m_checksumTools.keys()) + for (const QString& ext: m_checksumTools.keys()) typesFilter += ("*." + ext + ' '); checksumFileReq->setFilter(typesFilter); checksumFileReq->setText(m_checksumFile); checksumFileReq->setFocus(); connect(checksumFileReq, &KUrlRequester::textChanged, this, &VerifyWizard::slotChecksumPathChanged); hLayout->addWidget(checksumFileReq); mainLayout->addLayout(hLayout); // content of checksum file m_hashesTreeWidget = new KrTreeWidget(page); m_hashesTreeWidget->setAllColumnsShowFocus(true); m_hashesTreeWidget->setHeaderLabels(QStringList() << i18n("Hash") << i18n("File")); mainLayout->addWidget(m_hashesTreeWidget); return page; } QWizardPage *VerifyWizard::createResultPage() { - QWizardPage *page = new QWizardPage; + auto *page = new QWizardPage; page->setTitle(i18n("Verify Result")); - QVBoxLayout *mainLayout = new QVBoxLayout; + auto *mainLayout = new QVBoxLayout; page->setLayout(mainLayout); m_outputLabel = new QLabel(i18n("Result output:")); mainLayout->addWidget(m_outputLabel); m_outputListWidget = new KrListWidget; mainLayout->addWidget(m_outputListWidget); return page; } void VerifyWizard::onIntroPage() { // cannot do this in constructor: NextButton->hide() is overridden slotChecksumPathChanged(m_checksumFile); } void VerifyWizard::onProgressPage() { // verify checksum file... const QString extension = QFileInfo(m_checksumFile).suffix(); if (!checkExists(extension)) { button(QWizard::BackButton)->show(); return; } runProcess(extension, QStringList() << "--strict" << "-c" << m_checksumFile); } void VerifyWizard::onResultPage() { // better not only trust error output const bool errors = m_process->exitCode() != 0 || !m_process->errOutput().isEmpty(); QWizardPage *page = currentPage(); page->setPixmap(QWizard::LogoPixmap, Icon(errors ? "dialog-error" : "dialog-information").pixmap(32)); page->setSubTitle(errors ? i18n("Errors were detected while verifying the checksums") : i18n("Checksums were verified successfully")); // print everything, errors first m_outputListWidget->clear(); m_outputListWidget->addItems(m_process->errOutput() + m_process->stdOutput()); button(QWizard::FinishButton)->setEnabled(!errors); } bool VerifyWizard::isSupported(const QString &path) { const QFileInfo fileInfo(path); return fileInfo.isFile() && m_checksumTools.keys().contains(fileInfo.suffix()); } } // NAMESPACE CHECKSUM_ diff --git a/krusader/Dialogs/checksumdlg.h b/krusader/Dialogs/checksumdlg.h index 07d7c376..095c1a0e 100644 --- a/krusader/Dialogs/checksumdlg.h +++ b/krusader/Dialogs/checksumdlg.h @@ -1,180 +1,180 @@ /***************************************************************************** * Copyright (C) 2005 Shie Erlich * * Copyright (C) 2007-2008 Csaba Karai * * Copyright (C) 2008 Jonas Bähr * * Copyright (C) 2005-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef CHECKSUMDLG_H #define CHECKSUMDLG_H // QtCore #include #include #include // QtWidgets #include #include #include #include #include class KrListWidget; class KrTreeWidget; /** * Perform checksum operations: Creation of checksums or verifying files with a checksum file. * * The dialogs are not modal. The used checksum tools only support local files which are expected to * be in one directory (specified by 'path'). */ class Checksum { public: static void startCreationWizard(const QString &path, const QStringList &fileNames); static void startVerifyWizard(const QString &path, const QString &checksumFile = QString()); }; namespace CHECKSUM_ { // private namespace /** Wrapper for KProcess to handle errors and output. */ class ChecksumProcess : public KProcess { Q_OBJECT public: ChecksumProcess(QObject *parent, const QString &path); - ~ChecksumProcess(); + ~ChecksumProcess() override; QStringList stdOutput() const { return m_outputLines; } QStringList errOutput() const { return m_errorLines; } signals: void resultReady(); private slots: void slotError(QProcess::ProcessError error); void slotFinished(int, QProcess::ExitStatus exitStatus); private: QStringList m_outputLines; QStringList m_errorLines; QTemporaryFile m_tmpOutFile; QTemporaryFile m_tmpErrFile; }; /** Base class for common code in creation and verify wizard. */ class ChecksumWizard : public QWizard { Q_OBJECT public: explicit ChecksumWizard(const QString &path); - virtual ~ChecksumWizard(); + ~ChecksumWizard() override; private slots: void slotCurrentIdChanged(int id); protected: virtual QWizardPage *createIntroPage() = 0; virtual QWizardPage *createResultPage() = 0; virtual void onIntroPage() = 0; virtual void onProgressPage() = 0; virtual void onResultPage() = 0; QWizardPage *createProgressPage(const QString &title); - bool checkExists(const QString type); + bool checkExists(const QString& type); void runProcess(const QString &type, const QStringList &args); void addChecksumLine(KrTreeWidget *tree, const QString &line); const QString m_path; ChecksumProcess *m_process; QMap m_checksumTools; // extension/typ-name -> binary name int m_introId, m_progressId, m_resultId; }; class CreateWizard : public ChecksumWizard { Q_OBJECT public: CreateWizard(const QString &path, const QStringList &_files); public slots: void accept() Q_DECL_OVERRIDE; private: QWizardPage *createIntroPage() Q_DECL_OVERRIDE; QWizardPage *createResultPage() Q_DECL_OVERRIDE; void onIntroPage() Q_DECL_OVERRIDE; void onProgressPage() Q_DECL_OVERRIDE; void onResultPage() Q_DECL_OVERRIDE; void createChecksums(); bool savePerFile(); bool saveChecksumFile(const QStringList &data, const QString &filename = QString()); const QStringList m_fileNames; QFutureWatcher m_listFilesWatcher; QString m_suggestedFilePath; // intro page KComboBox *m_methodBox; // result page KrTreeWidget *m_hashesTreeWidget; QLabel *m_errorLabel; KrListWidget *m_errorListWidget; QCheckBox *m_onePerFileBox; }; class VerifyWizard : public ChecksumWizard { Q_OBJECT public: VerifyWizard(const QString &path, const QString &inputFile); private slots: void slotChecksumPathChanged(const QString &path); private: QWizardPage *createIntroPage() Q_DECL_OVERRIDE; QWizardPage *createResultPage() Q_DECL_OVERRIDE; void onIntroPage() Q_DECL_OVERRIDE; void onProgressPage() Q_DECL_OVERRIDE; void onResultPage() Q_DECL_OVERRIDE; bool isSupported(const QString &path); QString m_checksumFile; // intro page KrTreeWidget *m_hashesTreeWidget; // result page QLabel *m_outputLabel; KrListWidget *m_outputListWidget; }; } // NAMESPACE CHECKSUM_ #endif // CHECKSUMDLG_H diff --git a/krusader/Dialogs/krdialogs.cpp b/krusader/Dialogs/krdialogs.cpp index 5f24fe97..b293d90e 100644 --- a/krusader/Dialogs/krdialogs.cpp +++ b/krusader/Dialogs/krdialogs.cpp @@ -1,203 +1,203 @@ /***************************************************************************** * Copyright (C) 2000 Shie Erlich * * Copyright (C) 2000 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "krdialogs.h" // QtCore #include #include // QtGui #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include #include "../krglobal.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(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) { QScopedPointer dlg(new KUrlRequesterDlgForCopy(url, text, krMainWindow, true)); 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.enqueue = dlg->isQueued(); return result; } KUrlRequesterDlgForCopy::KUrlRequesterDlgForCopy(const QUrl &urlName, const QString &_text, QWidget *parent, bool modal) : QDialog(parent) { setWindowModality(modal ? Qt::WindowModal : Qt::NonModal); - QVBoxLayout *mainLayout = new QVBoxLayout; + auto *mainLayout = new QVBoxLayout; setLayout(mainLayout); mainLayout->addWidget(new QLabel(_text)); urlRequester_ = new KUrlRequester(urlName, this); urlRequester_->setMinimumWidth(urlRequester_->sizeHint().width() * 3); mainLayout->addWidget(urlRequester_); 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); QPushButton *queueButton = new QPushButton( krJobMan->isQueueModeEnabled() ? i18n("F2 Delay Job Start") : i18n("F2 Queue"), this); queueButton->setToolTip(krJobMan->isQueueModeEnabled() ? i18n("Do not start the job now.") : i18n("Enqueue the job if another job is running. Otherwise start immediately.")); buttonBox->addButton(queueButton, QDialogButtonBox::ActionRole); connect(buttonBox, &QDialogButtonBox::accepted, this, &KUrlRequesterDlgForCopy::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &KUrlRequesterDlgForCopy::reject); connect(queueButton, &QPushButton::clicked, this, &KUrlRequesterDlgForCopy::slotQueueButtonClicked); connect(urlRequester_, &KUrlRequester::textChanged, this, &KUrlRequesterDlgForCopy::slotTextChanged); urlRequester_->setFocus(); bool state = !urlName.isEmpty(); okButton->setEnabled(state); } void KUrlRequesterDlgForCopy::keyPressEvent(QKeyEvent *e) { switch (e->key()) { case Qt::Key_F2: slotQueueButtonClicked(); return; default: QDialog::keyPressEvent(e); } } void KUrlRequesterDlgForCopy::slotQueueButtonClicked() { queueStart = true; accept(); } void KUrlRequesterDlgForCopy::slotTextChanged(const QString & text) { bool state = !text.trimmed().isEmpty(); okButton->setEnabled(state); } QUrl KUrlRequesterDlgForCopy::selectedURL() const { if (result() == QDialog::Accepted) { QUrl url = urlRequester_->url(); qDebug() << "requester returned URL=" << url.toDisplayString(); if (url.isValid()) KRecentDocument::add(url); return url; } else return QUrl(); } KUrlRequester * KUrlRequesterDlgForCopy::urlRequester() { return urlRequester_; } 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, &KDatePicker::dateSelected, this, &KRGetDate::setDate); connect(dateWidget, &KDatePicker::dateEntered, this, &KRGetDate::setDate); // 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/krdialogs.h b/krusader/Dialogs/krdialogs.h index f78b3357..d9c89b41 100644 --- a/krusader/Dialogs/krdialogs.h +++ b/krusader/Dialogs/krdialogs.h @@ -1,119 +1,119 @@ /***************************************************************************** * Copyright (C) 2000 Shie Erlich * * Copyright (C) 2000 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef KRDIALOGS_H #define KRDIALOGS_H // QtCore #include #include // QtWidgets #include #include #include #include #include #include #include // QtGui #include #include #include #include #include /** \class KChooseDir * Used for asking the user for a folder. * example: * \code * QUrl u = KChooseDir::getDir("target folder", "/suggested/path", ACTIVE_PANEL->virtualPath()); * if (u.isEmpty()) { * // user canceled (either by pressing cancel, or esc * } else { * // do you thing here: you've got a safe url to use * } * \endcode */ class KChooseDir { public: struct ChooseResult { QUrl url; bool enqueue; }; /** * \param text - description of the info requested from the user * \param url - a suggested url to appear in the box as a default choice * \param cwd - a path which is the current working directory (usually ACTIVE_PANEL->virtualPath()). * this is used for completion of partial urls */ static QUrl getFile(const QString &text, const QUrl &url, const QUrl &cwd); static QUrl getDir(const QString &text, const QUrl &url, const QUrl &cwd); static ChooseResult getCopyDir(const QString &text, const QUrl &url, const QUrl &cwd); private: static QUrl get(const QString &text, const QUrl &url, const QUrl &cwd, KFile::Modes mode); }; class KUrlRequesterDlgForCopy : public QDialog { Q_OBJECT public: KUrlRequesterDlgForCopy(const QUrl& url, const QString& text, QWidget *parent, bool modal = true); QUrl selectedURL() const; bool isQueued() { return queueStart; } KUrlRequester *urlRequester(); protected: - virtual void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; + void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; private slots: void slotQueueButtonClicked(); void slotTextChanged(const QString &); private: KUrlRequester *urlRequester_; QPushButton *okButton; bool queueStart = false; }; class KRGetDate : public QDialog { Q_OBJECT public: - explicit KRGetDate(QDate date = QDate::currentDate(), QWidget *parent = 0); + explicit KRGetDate(QDate date = QDate::currentDate(), QWidget *parent = nullptr); QDate getDate(); private slots: void setDate(QDate); private: KDatePicker *dateWidget; QDate chosenDate, originalDate; }; #endif diff --git a/krusader/Dialogs/krmaskchoice.cpp b/krusader/Dialogs/krmaskchoice.cpp index 9c2e451b..1c5bf590 100644 --- a/krusader/Dialogs/krmaskchoice.cpp +++ b/krusader/Dialogs/krmaskchoice.cpp @@ -1,151 +1,151 @@ /***************************************************************************** * Copyright (C) 2000 Shie Erlich * * Copyright (C) 2000 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "krmaskchoice.h" // QtCore #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include "../GUI/krlistwidget.h" /** * Constructs a KRMaskChoice which is a child of 'parent', with the * name 'name' and widget flags set to 'f' * * The dialog will by default be modeless, unless you set 'modal' to * TRUE to construct a modal dialog. */ KRMaskChoice::KRMaskChoice(QWidget* parent) : QDialog(parent) { setModal(true); resize(401, 314); setWindowTitle(i18n("Choose Files")); - QVBoxLayout* MainLayout = new QVBoxLayout(this); + auto* MainLayout = new QVBoxLayout(this); - QHBoxLayout* HeaderLayout = new QHBoxLayout(); + auto* HeaderLayout = new QHBoxLayout(); MainLayout->addLayout(HeaderLayout); PixmapLabel1 = new QLabel(this); PixmapLabel1->setScaledContents(true); PixmapLabel1->setMaximumSize(QSize(31, 31)); HeaderLayout->addWidget(PixmapLabel1); label = new QLabel(this); label->setText(i18n("Select the following files:")); HeaderLayout->addWidget(label); selection = new KComboBox(this); selection->setEditable(true); selection->setInsertPolicy(QComboBox::InsertAtTop); selection->setAutoCompletion(true); MainLayout->addWidget(selection); - QGroupBox* GroupBox1 = new QGroupBox(this); + auto* GroupBox1 = new QGroupBox(this); GroupBox1->setTitle(i18n("Predefined Selections")); MainLayout->addWidget(GroupBox1); - QHBoxLayout* gbLayout = new QHBoxLayout(GroupBox1); + auto* gbLayout = new QHBoxLayout(GroupBox1); preSelections = new KrListWidget(GroupBox1); preSelections->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); preSelections->setWhatsThis(i18n("A predefined selection is a file-mask which you often use.\nSome examples are: \"*.c, *.h\", \"*.c, *.o\", etc.\nYou can add these masks to the list by typing them and pressing the Add button.\nDelete removes a predefined selection and Clear removes all of them.\nNotice that the line in which you edit the mask has its own history, you can scroll it, if needed.")); gbLayout->addWidget(preSelections); - QVBoxLayout* vbox = new QVBoxLayout(); + auto* vbox = new QVBoxLayout(); gbLayout->addLayout(vbox); PushButton7 = new QPushButton(GroupBox1); PushButton7->setText(i18n("Add")); PushButton7->setToolTip(i18n("Adds the selection in the line-edit to the list")); vbox->addWidget(PushButton7); PushButton7_2 = new QPushButton(GroupBox1); PushButton7_2->setText(i18n("Delete")); PushButton7_2->setToolTip(i18n("Delete the marked selection from the list")); vbox->addWidget(PushButton7_2); PushButton7_3 = new QPushButton(GroupBox1); PushButton7_3->setText(i18n("Clear")); PushButton7_3->setToolTip(i18n("Clears the entire list of selections")); vbox->addWidget(PushButton7_3); vbox->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Expanding)); QDialogButtonBox* ButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); MainLayout->addWidget(ButtonBox); // signals and slots connections connect(ButtonBox, &QDialogButtonBox::rejected, this, &KRMaskChoice::reject); connect(ButtonBox, &QDialogButtonBox::accepted, this, &KRMaskChoice::accept); connect(PushButton7, &QPushButton::clicked, this, &KRMaskChoice::addSelection); connect(PushButton7_2, &QPushButton::clicked, this, &KRMaskChoice::deleteSelection); connect(PushButton7_3, &QPushButton::clicked, this, &KRMaskChoice::clearSelections); connect(selection, QOverload::of(&KComboBox::activated), selection, &KComboBox::setEditText); connect(selection->lineEdit(), &QLineEdit::returnPressed, this, &KRMaskChoice::accept); connect(preSelections, &KrListWidget::currentItemChanged, this, &KRMaskChoice::currentItemChanged); connect(preSelections, &KrListWidget::itemActivated, this, &KRMaskChoice::acceptFromList); } /* * Destroys the object and frees any allocated resources */ KRMaskChoice::~KRMaskChoice() { // no need to delete child widgets, Qt does it all for us } void KRMaskChoice::addSelection() { qWarning("KRMaskChoice::addSelection(): Not implemented yet!"); } void KRMaskChoice::clearSelections() { qWarning("KRMaskChoice::clearSelections(): Not implemented yet!"); } void KRMaskChoice::deleteSelection() { qWarning("KRMaskChoice::deleteSelection(): Not implemented yet!"); } void KRMaskChoice::acceptFromList(QListWidgetItem *) { qWarning("KRMaskChoice::acceptFromList(QListWidgetItem *): Not implemented yet!"); } void KRMaskChoice::currentItemChanged(QListWidgetItem *) { qWarning("KRMaskChoice::currentItemChanged(QListWidgetItem *): Not implemented yet!"); } diff --git a/krusader/Dialogs/krmaskchoice.h b/krusader/Dialogs/krmaskchoice.h index e4a730c1..7b52778a 100644 --- a/krusader/Dialogs/krmaskchoice.h +++ b/krusader/Dialogs/krmaskchoice.h @@ -1,57 +1,57 @@ /***************************************************************************** * Copyright (C) 2000 Shie Erlich * * Copyright (C) 2000 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef KRMASKCHOICE_H #define KRMASKCHOICE_H // QtWidgets #include class QLabel; class QListWidgetItem; class QPushButton; class KComboBox; class KrListWidget; class KRMaskChoice : public QDialog { Q_OBJECT public: - explicit KRMaskChoice(QWidget* parent = 0); - ~KRMaskChoice(); + explicit KRMaskChoice(QWidget* parent = nullptr); + ~KRMaskChoice() override; KComboBox* selection; QLabel* PixmapLabel1; QLabel* label; KrListWidget* preSelections; QPushButton* PushButton7; QPushButton* PushButton7_2; QPushButton* PushButton7_3; public slots: virtual void addSelection(); virtual void clearSelections(); virtual void deleteSelection(); virtual void acceptFromList(QListWidgetItem *); virtual void currentItemChanged(QListWidgetItem *); }; #endif // KRMASKCHOICE_H diff --git a/krusader/Dialogs/krpleasewait.cpp b/krusader/Dialogs/krpleasewait.cpp index 13a9ef9f..48479731 100644 --- a/krusader/Dialogs/krpleasewait.cpp +++ b/krusader/Dialogs/krpleasewait.cpp @@ -1,156 +1,156 @@ /***************************************************************************** * Copyright (C) 2000 Shie Erlich * * Copyright (C) 2000 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "krpleasewait.h" // QtCore #include #include // QtGui #include // QtWidgets #include #include #include #include #include #include #include "../krglobal.h" -KRPleaseWait::KRPleaseWait(QString msg, QWidget *parent, int count, bool cancel): - QProgressDialog(cancel ? 0 : parent) , inc(true) +KRPleaseWait::KRPleaseWait(const QString& msg, QWidget *parent, int count, bool cancel): + QProgressDialog(cancel ? nullptr : parent) , inc(true) { setModal(!cancel); timer = new QTimer(this); setWindowTitle(i18n("Krusader::Wait")); setMinimumDuration(500); setAutoClose(false); setAutoReset(false); connect(timer, &QTimer::timeout, this, &KRPleaseWait::cycleProgress); - QProgressBar* progress = new QProgressBar(this); + auto* progress = new QProgressBar(this); progress->setMaximum(count); progress->setMinimum(0); setBar(progress); QLabel* label = new QLabel(this); setLabel(label); QPushButton* btn = new QPushButton(i18n("&Cancel"), this); setCancelButton(btn); btn->setEnabled(canClose = cancel); setLabelText(msg); show(); } void KRPleaseWait::closeEvent(QCloseEvent * e) { if (canClose) { emit canceled(); e->accept(); } else /* if cancel is not allowed, we disable */ e->ignore(); /* the window closing [x] also */ } void KRPleaseWait::incProgress(int howMuch) { setValue(value() + howMuch); } void KRPleaseWait::cycleProgress() { if (inc) setValue(value() + 1); else setValue(value() - 1); if (value() >= 9) inc = false; if (value() <= 0) inc = true; } KRPleaseWaitHandler::KRPleaseWaitHandler(QWidget *parentWindow) - : QObject(parentWindow), _parentWindow(parentWindow), job(), dlg(0) + : QObject(parentWindow), _parentWindow(parentWindow), dlg(nullptr) { } void KRPleaseWaitHandler::stopWait() { - if (dlg != 0) delete dlg; - dlg = 0; + if (dlg != nullptr) delete dlg; + dlg = nullptr; cycleMutex = incMutex = false; // return cursor to normal arrow _parentWindow->setCursor(Qt::ArrowCursor); } -void KRPleaseWaitHandler::startWaiting(QString msg, int count , bool cancel) +void KRPleaseWaitHandler::startWaiting(const QString& msg, int count , bool cancel) { - if (dlg == 0) { + if (dlg == nullptr) { dlg = new KRPleaseWait(msg , _parentWindow, count, cancel); connect(dlg, &KRPleaseWait::canceled, this, &KRPleaseWaitHandler::killJob); } incMutex = cycleMutex = _wasCancelled = false; dlg->setValue(0); dlg->setLabelText(msg); if (count == 0) { dlg->setMaximum(10); cycle = true; cycleProgress(); } else { dlg->setMaximum(count); cycle = false; } } void KRPleaseWaitHandler::cycleProgress() { if (cycleMutex) return; cycleMutex = true; if (dlg) dlg->cycleProgress(); if (cycle) QTimer::singleShot(2000, this, &KRPleaseWaitHandler::cycleProgress); cycleMutex = false; } void KRPleaseWaitHandler::killJob() { if (!job.isNull()) job->kill(KJob::EmitResult); stopWait(); _wasCancelled = true; } void KRPleaseWaitHandler::setJob(KIO::Job* j) { job = j; } void KRPleaseWaitHandler::incProgress(int i) { if (incMutex) return; incMutex = true; if (dlg) dlg->incProgress(i); incMutex = false; } diff --git a/krusader/Dialogs/krpleasewait.h b/krusader/Dialogs/krpleasewait.h index 3d11e2ca..febceda4 100644 --- a/krusader/Dialogs/krpleasewait.h +++ b/krusader/Dialogs/krpleasewait.h @@ -1,81 +1,81 @@ /***************************************************************************** * Copyright (C) 2000 Shie Erlich * * Copyright (C) 2000 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef KRPLEASEWAIT_H #define KRPLEASEWAIT_H // QtCore #include #include // QtGui #include // QtWidgets #include #include class KRPleaseWait; class KRPleaseWaitHandler : public QObject { Q_OBJECT public: explicit KRPleaseWaitHandler(QWidget *parentWindow); public slots: - void startWaiting(QString msg, int count = 0, bool cancel = false); + void startWaiting(const QString& msg, int count = 0, bool cancel = false); void stopWait(); void cycleProgress(); void incProgress(int i); void killJob(); void setJob(KIO::Job* j); bool wasCancelled() const { return _wasCancelled; } private: QWidget *_parentWindow; QPointer job; KRPleaseWait * dlg; bool cycle, cycleMutex, incMutex, _wasCancelled; }; class KRPleaseWait : public QProgressDialog { Q_OBJECT public: - KRPleaseWait(QString msg, QWidget *parent, int count = 0 , bool cancel = false); + KRPleaseWait(const QString& msg, QWidget *parent, int count = 0 , bool cancel = false); public slots: void incProgress(int howMuch); void cycleProgress(); protected: bool inc; QTimer* timer; - virtual void closeEvent(QCloseEvent * e) Q_DECL_OVERRIDE; + void closeEvent(QCloseEvent * e) Q_DECL_OVERRIDE; bool canClose; }; #endif diff --git a/krusader/Dialogs/krspecialwidgets.cpp b/krusader/Dialogs/krspecialwidgets.cpp index 8ed7936b..a4cd2e04 100644 --- a/krusader/Dialogs/krspecialwidgets.cpp +++ b/krusader/Dialogs/krspecialwidgets.cpp @@ -1,218 +1,219 @@ /***************************************************************************** * Copyright (C) 2000 Shie Erlich * * Copyright (C) 2000 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "krspecialwidgets.h" #include "krmaskchoice.h" #include "newftpgui.h" #include "../krglobal.h" // QtGui #include #include +#include ///////////////////////////////////////////////////////////////////////////// /////////////////////// Pie related widgets ///////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // The pie-related widgets use hard-coded coordinates to create the look. // This is ok since the whole widget is fitted into an existing view and thus // no re-alignments are needed. #define LEFT 10 #define BOTTOM 150 #define WIDTH 120 #define HEIGHT 40 #define Z_HEIGHT 10 #define STARTANGLE 0 #define DEG(x) (16*(x)) QColor KRPie::colors[ 12 ] = {Qt::red, Qt::blue, Qt::green, Qt::cyan, Qt::magenta, Qt::gray, Qt::black, Qt::white, Qt::darkRed, Qt::darkBlue, Qt::darkMagenta, Qt::darkCyan }; ////////////////////////////////////////////////////////////////////////////// /////////////// KRFSDisplay - Filesystem / Freespace Display ///////////////// ////////////////////////////////////////////////////////////////////////////// // This is the full constructor: use it for a mounted filesystem KRFSDisplay::KRFSDisplay(QWidget *parent, QString _alias, QString _realName, KIO::filesize_t _total, KIO::filesize_t _free) : QWidget(parent), totalSpace(_total), - freeSpace(_free), alias(_alias), realName(_realName), mounted(true), + freeSpace(_free), alias(std::move(_alias)), realName(std::move(_realName)), mounted(true), empty(false), supermount(false) { int leftMargin, topMargin, rightMargin, bottomMargin; getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin); resize(150 + leftMargin + rightMargin, 200 + topMargin + bottomMargin); setMinimumSize(150 + leftMargin + rightMargin, 200 + topMargin + bottomMargin); show(); } // Use this one for an unmounted filesystem KRFSDisplay::KRFSDisplay(QWidget *parent, QString _alias, QString _realName, bool sm) : - QWidget(parent), alias(_alias), realName(_realName), mounted(false), + QWidget(parent), alias(std::move(_alias)), realName(std::move(_realName)), mounted(false), empty(false), supermount(sm) { int leftMargin, topMargin, rightMargin, bottomMargin; getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin); resize(150 + leftMargin + rightMargin, 200 + topMargin + bottomMargin); setMinimumSize(150 + leftMargin + rightMargin, 200 + topMargin + bottomMargin); show(); } // This is used only when an empty widget needs to be displayed (for example: // when filesystem statistics haven't been calculated yet) KRFSDisplay::KRFSDisplay(QWidget *parent) : QWidget(parent), empty(true) { int leftMargin, topMargin, rightMargin, bottomMargin; getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin); resize(150 + leftMargin + rightMargin, 200 + topMargin + bottomMargin); setMinimumSize(150 + leftMargin + rightMargin, 200 + topMargin + bottomMargin); show(); } // The main painter! void KRFSDisplay::paintEvent(QPaintEvent *) { QPainter paint(this); if (!empty) { int leftMargin, topMargin, rightMargin, bottomMargin; getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin); // create the text // first, name and location QFont font = paint.font(); font.setWeight(QFont::Bold); paint.setFont(font); paint.drawText(leftMargin + 10, topMargin + 20, alias); font.setWeight(QFont::Normal); paint.setFont(font); paint.drawText(leftMargin + 10, topMargin + 37, '(' + realName + ')'); if (mounted) { // incase the filesystem is already mounted // second, the capacity paint.drawText(leftMargin + 10, topMargin + 70, i18n("Capacity: %1", KIO::convertSizeFromKiB(totalSpace))); // third, the 2 boxes (used, free) QPen systemPen = paint.pen(); paint.setPen(Qt::black); paint.drawRect(leftMargin + 10, topMargin + 90, 10, 10); paint.fillRect(leftMargin + 11, topMargin + 91, 8, 8, QBrush(Qt::gray)); paint.drawRect(leftMargin + 10, topMargin + 110, 10, 10); paint.fillRect(leftMargin + 11, topMargin + 111, 8, 8, QBrush(Qt::white)); // now, the text for the boxes paint.setPen(systemPen); paint.drawText(leftMargin + 25, topMargin + 100, i18n("Used: %1", KIO::convertSizeFromKiB(totalSpace - freeSpace))); paint.drawText(leftMargin + 25, topMargin + 120, i18n("Free: %1", KIO::convertSizeFromKiB(freeSpace))); // first, create the empty pie // bottom... paint.setPen(Qt::black); paint.setBrush(Qt::white); paint.drawPie(leftMargin + LEFT, topMargin + BOTTOM, WIDTH, HEIGHT, STARTANGLE, DEG(360)); // body... paint.setPen(Qt::lightGray); for (int i = 1; i < Z_HEIGHT; ++i) paint.drawPie(leftMargin + LEFT, topMargin + BOTTOM - i, WIDTH, HEIGHT, STARTANGLE, DEG(360)); // side lines... paint.setPen(Qt::black); paint.drawLine(leftMargin + LEFT, topMargin + BOTTOM + HEIGHT / 2, LEFT, BOTTOM + HEIGHT / 2 - Z_HEIGHT); paint.drawLine(leftMargin + LEFT + WIDTH, topMargin + BOTTOM + HEIGHT / 2, LEFT + WIDTH, BOTTOM + HEIGHT / 2 - Z_HEIGHT); // top of the pie paint.drawPie(leftMargin + LEFT, topMargin + BOTTOM - Z_HEIGHT, WIDTH, HEIGHT, STARTANGLE, DEG(360)); // the "used space" slice float i = ((float)(totalSpace - freeSpace) / (totalSpace)) * 360.0; paint.setBrush(Qt::gray); paint.drawPie(leftMargin + LEFT, topMargin + BOTTOM - Z_HEIGHT, WIDTH, HEIGHT, STARTANGLE, (int) DEG(i)); // if we need to draw a 3d stripe ... if (i > 180.0) { for (int j = 1; j < Z_HEIGHT; ++j) paint.drawArc(leftMargin + LEFT, topMargin + BOTTOM - j, WIDTH, HEIGHT, STARTANGLE - 16 * 180, (int)(DEG(i - 180.0))); } } else { // if the filesystem is unmounted... font.setWeight(QFont::Bold); paint.setFont(font); paint.drawText(leftMargin + 10, topMargin + 60, i18n("Not mounted.")); } } else { // if the widget is in empty situation... } } //////////////////////////////////////////////////////////////////////////////// KRPie::KRPie(KIO::filesize_t _totalSize, QWidget *parent) : QWidget(parent), totalSize(_totalSize) { slices.push_back(KRPieSlice(100, Qt::yellow, "DEFAULT")); sizeLeft = totalSize; resize(300, 300); } void KRPie::paintEvent(QPaintEvent *) { QPainter paint(this); // now create the slices float sAngle = STARTANGLE; for (int ndx = 0; ndx != slices.count(); ndx++) { paint.setBrush(slices[ndx].getColor()); paint.setPen(slices[ndx].getColor()); // angles are negative to create a clock-wise drawing of slices float angle = -(slices[ndx].getPerct() / 100 * 360) * 16; for (int i = 1; i < Z_HEIGHT; ++i) paint.drawPie(LEFT, BOTTOM + i, WIDTH, HEIGHT, (int) sAngle, (int) angle); sAngle += angle; } paint.setPen(Qt::yellow); // pen paint.setBrush(Qt::yellow); // fill // for (int i=1; i * * Copyright (C) 2000 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef KRSPECIALWIDGETS_H #define KRSPECIALWIDGETS_H // QtCore #include // QtGui #include #include #include #include // QtWidgets #include #include #include +#include class KRPieSlice; class KRPie : public QWidget { Q_OBJECT public: - explicit KRPie(KIO::filesize_t _totalSize, QWidget *parent = 0); + explicit KRPie(KIO::filesize_t _totalSize, QWidget *parent = nullptr); void addSlice(KIO::filesize_t size, QString label); protected: void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; private: QList slices; KIO::filesize_t totalSize, sizeLeft; static QColor colors[ 12 ]; }; class KRFSDisplay : public QWidget { Q_OBJECT public: // this constructor is used for a mounted filesystem KRFSDisplay(QWidget *parent, QString _alias, QString _realName, KIO::filesize_t _total, KIO::filesize_t _free); // this one is for an unmounted/supermount file system KRFSDisplay(QWidget *parent, QString _alias, QString _realName, bool sm = false); // the last one is used inside MountMan(R), when no filesystem is selected explicit KRFSDisplay(QWidget *parent); inline void setTotalSpace(KIO::filesize_t t) { totalSpace = t; } inline void setFreeSpace(KIO::filesize_t t) { freeSpace = t; } inline void setAlias(QString a) { - alias = a; + alias = std::move(a); } inline void setRealName(QString r) { - realName = r; + realName = std::move(r); } inline void setMounted(bool m) { mounted = m; } inline void setEmpty(bool e) { empty = e; } inline void setSupermount(bool s) { supermount = s; } protected: void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; private: KIO::filesize_t totalSpace, freeSpace; QString alias, realName; bool mounted, empty, supermount; }; class KRPieSlice { public: KRPieSlice(float _perct, QColor _color, QString _label) : - perct(_perct), color(_color), label(_label) {} + perct(_perct), color(std::move(_color)), label(std::move(_label)) {} inline QColor getColor() { return color; } inline float getPerct() { return perct; } inline QString getLabel() { return label; } inline void setPerct(float _perct) { perct = _perct; } inline void setLabel(QString _label) { - label = _label; + label = std::move(_label); } private: float perct; QColor color; QString label; }; #endif diff --git a/krusader/Dialogs/krspwidgets.cpp b/krusader/Dialogs/krspwidgets.cpp index 0eed58ef..9017ad0a 100644 --- a/krusader/Dialogs/krspwidgets.cpp +++ b/krusader/Dialogs/krspwidgets.cpp @@ -1,259 +1,258 @@ /***************************************************************************** * Copyright (C) 2000 Shie Erlich * * Copyright (C) 2000 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "krspwidgets.h" #include "../krglobal.h" #include "../icon.h" #include "../Filter/filtertabs.h" #include "../GUI/krlistwidget.h" // QtCore #include // QtGui #include // QtWidgets #include #include #include #include #include #include // missing ? #include #include #include #include #include ///////////////////// initiation of the static members //////////////////////// QStringList KRSpWidgets::maskList; /////////////////////////////////////////////////////////////////////////////// KRSpWidgets::KRSpWidgets() -{ -} += default; -KRQuery KRSpWidgets::getMask(QString caption, bool nameOnly, QWidget * parent) +KRQuery KRSpWidgets::getMask(const QString& caption, bool nameOnly, QWidget * parent) { if (!nameOnly) { return FilterTabs::getQuery(parent); } else { QPointer p = new KRMaskChoiceSub(parent); p->setWindowTitle(caption); p->exec(); QString selection = p->selection->currentText(); delete p; if (selection.isEmpty()) { return KRQuery(); } else { return KRQuery(selection); } } } /////////////////////////// newFTP //////////////////////////////////////// QUrl KRSpWidgets::newFTP() { QPointer p = new newFTPSub(); p->exec(); QString uri = p->url->currentText(); if (uri.isEmpty()) { delete p; return QUrl(); // empty url } QString protocol = p->prefix->currentText(); protocol.truncate(protocol.length() - 3); // remove the trailing :// QString username = p->username->text().simplified(); QString password = p->password->text().simplified(); int uriStart = uri.lastIndexOf('@'); /* lets the user enter user and password in the URI field */ if (uriStart != -1) { QString uriUser = uri.left(uriStart); QString uriPsw; uri = uri.mid(uriStart + 1); int pswStart = uriUser.indexOf(':'); /* getting the password name from the URL */ if (pswStart != -1) { uriPsw = uriUser.mid(pswStart + 1); uriUser = uriUser.left(pswStart); } if (!uriUser.isEmpty()) { /* handling the ftp proxy username and password also */ username = username.isEmpty() ? uriUser : username + '@' + uriUser; } if (!uriPsw.isEmpty()) { /* handling the ftp proxy username and password also */ password = password.isEmpty() ? uriPsw : password + '@' + uriPsw; } } QString host = uri; /* separating the hostname and path from the uri */ QString path; int pathStart = uri.indexOf("/"); if (pathStart != -1) { path = host.mid(pathStart); host = host.left(pathStart); } /* setting the parameters of the URL */ QUrl url; url.setScheme(protocol); url.setHost(host); url.setPath(path); if (protocol == "ftp" || protocol == "fish" || protocol == "sftp") { url.setPort(p->port->cleanText().toInt()); } if (!username.isEmpty()) { url.setUserName(username); } if (!password.isEmpty()) { url.setPassword(password); } delete p; return url; } -newFTPSub::newFTPSub() : newFTPGUI(0) +newFTPSub::newFTPSub() : newFTPGUI(nullptr) { url->setFocus(); setGeometry(krMainWindow->x() + krMainWindow->width() / 2 - width() / 2, krMainWindow->y() + krMainWindow->height() / 2 - height() / 2, width(), height()); } void newFTPSub::accept() { url->addToHistory(url->currentText()); // save the history and completion list when the history combo is // destroyed KConfigGroup group(krConfig, "Private"); QStringList list = url->completionObject()->items(); group.writeEntry("newFTP Completion list", list); list = url->historyItems(); group.writeEntry("newFTP History list", list); QString protocol = prefix->currentText(); group.writeEntry("newFTP Protocol", protocol); newFTPGUI::accept(); } void newFTPSub::reject() { url->lineEdit()->setText(""); newFTPGUI::reject(); } /////////////////////////// KRMaskChoiceSub /////////////////////////////// KRMaskChoiceSub::KRMaskChoiceSub(QWidget * parent) : KRMaskChoice(parent) { PixmapLabel1->setPixmap(Icon("edit-select").pixmap(32)); label->setText(i18n("Enter a selection:")); // the predefined selections list KConfigGroup group(krConfig, "Private"); QStringList lst = group.readEntry("Predefined Selections", QStringList()); if (lst.size() > 0) preSelections->addItems(lst); // the combo-box tweaks selection->setDuplicatesEnabled(false); selection->addItems(KRSpWidgets::maskList); selection->lineEdit()->setText("*"); selection->lineEdit()->selectAll(); selection->setFocus(); } void KRMaskChoiceSub::reject() { selection->clear(); KRMaskChoice::reject(); } void KRMaskChoiceSub::accept() { bool add = true; // make sure we don't have that already for (int i = 0; i != KRSpWidgets::maskList.count(); i++) if (KRSpWidgets::maskList[ i ].simplified() == selection->currentText().simplified()) { // break if we found one such as this add = false; break; } if (add) KRSpWidgets::maskList.insert(0, selection->currentText().toLocal8Bit()); // write down the predefined selections list QStringList list; for (int j = 0; j != preSelections->count(); j++) { QListWidgetItem *i = preSelections->item(j); list.append(i->text()); } KConfigGroup group(krConfig, "Private"); group.writeEntry("Predefined Selections", list); KRMaskChoice::accept(); } void KRMaskChoiceSub::addSelection() { QString temp = selection->currentText(); bool itemExists = false; // check if the selection already exists for (int j = 0; j != preSelections->count(); j++) { QListWidgetItem *i = preSelections->item(j); if (i->text() == temp) { itemExists = true; break; } } if (!temp.isEmpty() && !itemExists) { preSelections->addItem(selection->currentText()); preSelections->update(); } } void KRMaskChoiceSub::deleteSelection() { delete preSelections->currentItem(); preSelections->update(); } void KRMaskChoiceSub::clearSelections() { preSelections->clear(); preSelections->update(); } void KRMaskChoiceSub::acceptFromList(QListWidgetItem *i) { selection->addItem(i->text(), 0); accept(); } void KRMaskChoiceSub::currentItemChanged(QListWidgetItem *i) { if (i) selection->setEditText(i->text()); } diff --git a/krusader/Dialogs/krspwidgets.h b/krusader/Dialogs/krspwidgets.h index bd277e55..3de8cd38 100644 --- a/krusader/Dialogs/krspwidgets.h +++ b/krusader/Dialogs/krspwidgets.h @@ -1,83 +1,83 @@ /***************************************************************************** * Copyright (C) 2000 Shie Erlich * * Copyright (C) 2000 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef KRSPWIDGETS_H #define KRSPWIDGETS_H // QtCore #include // QtGui #include #include #include #include "krmaskchoice.h" #include "newftpgui.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 KRQuery getMask(const 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() Q_DECL_OVERRIDE; void accept() Q_DECL_OVERRIDE; }; /////////////////////////// KRMaskChoiceSub ///////////////////////////////// // Inherits KRMaskChoice's generated code to fully implement the functions // ///////////////////////////////////////////////////////////////////////////// class KRMaskChoiceSub : public KRMaskChoice { public: explicit KRMaskChoiceSub(QWidget * parent = 0); public slots: void addSelection() Q_DECL_OVERRIDE; void deleteSelection() Q_DECL_OVERRIDE; void clearSelections() Q_DECL_OVERRIDE; void acceptFromList(QListWidgetItem *i) Q_DECL_OVERRIDE; void currentItemChanged(QListWidgetItem *i) Q_DECL_OVERRIDE; protected: void reject() Q_DECL_OVERRIDE; void accept() Q_DECL_OVERRIDE; }; #endif diff --git a/krusader/Dialogs/krsqueezedtextlabel.cpp b/krusader/Dialogs/krsqueezedtextlabel.cpp index 4dc16881..100f9bf6 100644 --- a/krusader/Dialogs/krsqueezedtextlabel.cpp +++ b/krusader/Dialogs/krsqueezedtextlabel.cpp @@ -1,103 +1,102 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "krsqueezedtextlabel.h" // QtGui #include #include // QtWidgets #include #include #include #include KrSqueezedTextLabel::KrSqueezedTextLabel(QWidget *parent): KSqueezedTextLabel(parent), _index(-1), _length(-1) { setAutoFillBackground(true); } KrSqueezedTextLabel::~KrSqueezedTextLabel() -{ -} += default; void KrSqueezedTextLabel::mousePressEvent(QMouseEvent *e) { e->ignore(); emit clicked(e); } void KrSqueezedTextLabel::squeezeTextToLabel(int index, int length) { if (index == -1 || length == -1) KSqueezedTextLabel::squeezeTextToLabel(); else { QString sqtext = fullText; QFontMetrics fm(fontMetrics()); int labelWidth = size().width(); int textWidth = fm.width(sqtext); if (textWidth > labelWidth) { int avgCharSize = textWidth / sqtext.length(); int numOfExtraChars = (textWidth - labelWidth) / avgCharSize; int delta; // remove as much as possible from the left, and then from the right if (index > 3) { delta = qMin(index, numOfExtraChars); numOfExtraChars -= delta; sqtext.replace(0, delta, "..."); } if (numOfExtraChars > 0 && ((int)sqtext.length() > length + 3)) { delta = qMin(numOfExtraChars, (int)sqtext.length() - (length + 3)); sqtext.replace(sqtext.length() - delta, delta, "..."); } QLabel::setText(sqtext); setToolTip(QString()); setToolTip(fullText); } else { QLabel::setText(fullText); setToolTip(QString()); QToolTip::hideText(); } } } void KrSqueezedTextLabel::setText(const QString &text, int index, int length) { _index = index; _length = length; fullText = text; KSqueezedTextLabel::setText(fullText); squeezeTextToLabel(_index, _length); } void KrSqueezedTextLabel::paintEvent(QPaintEvent * e) { KSqueezedTextLabel::paintEvent(e); } diff --git a/krusader/Dialogs/krsqueezedtextlabel.h b/krusader/Dialogs/krsqueezedtextlabel.h index 14426857..a55a2970 100644 --- a/krusader/Dialogs/krsqueezedtextlabel.h +++ b/krusader/Dialogs/krsqueezedtextlabel.h @@ -1,70 +1,70 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef KRSQUEEZEDTEXTLABEL_H #define KRSQUEEZEDTEXTLABEL_H // QtGui #include #include #include #include class QMouseEvent; class QDragEnterEvent; class QPaintEvent; /** This class overloads KSqueezedTextLabel and simply adds a clicked signal, so that users will be able to click the label and switch focus between panels. NEW: a special setText() method allows to choose which part of the string should be displayed (example: make sure that search results won't be cut out) */ class KrSqueezedTextLabel : public KSqueezedTextLabel { Q_OBJECT public: - explicit KrSqueezedTextLabel(QWidget *parent = 0); - ~KrSqueezedTextLabel(); + explicit KrSqueezedTextLabel(QWidget *parent = nullptr); + ~KrSqueezedTextLabel() override; public slots: void setText(const QString &text, int index = -1, int length = -1); signals: void clicked(QMouseEvent *); /**< emitted when someone clicks on the label */ protected: void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE { squeezeTextToLabel(_index, _length); } - virtual void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE; - virtual void paintEvent(QPaintEvent * e) Q_DECL_OVERRIDE; + void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent * e) Q_DECL_OVERRIDE; void squeezeTextToLabel(int index = -1, int length = -1); QString fullText; private: int _index, _length; }; #endif diff --git a/krusader/Dialogs/kurllistrequester.cpp b/krusader/Dialogs/kurllistrequester.cpp index 9b0c5642..f5dfacbe 100644 --- a/krusader/Dialogs/kurllistrequester.cpp +++ b/krusader/Dialogs/kurllistrequester.cpp @@ -1,187 +1,187 @@ /***************************************************************************** * Copyright (C) 2005 Csaba Karai * * Copyright (C) 2005-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "kurllistrequester.h" #include "../FileSystem/filesystem.h" #include "../icon.h" // QtGui #include #include #include // QtWidgets #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); + auto *urlListRequesterGrid = new QGridLayout(this); urlListRequesterGrid->setSpacing(0); urlListRequesterGrid->setContentsMargins(0, 0, 0, 0); urlLineEdit = new KLineEdit(this); urlListRequesterGrid->addWidget(urlLineEdit, 0, 0); urlAddBtn = new QToolButton(this); urlAddBtn->setText(""); urlAddBtn->setIcon(Icon("arrow-down")); urlListRequesterGrid->addWidget(urlAddBtn, 0, 1); urlBrowseBtn = new QToolButton(this); urlBrowseBtn->setText(""); urlBrowseBtn->setIcon(Icon("folder")); urlListRequesterGrid->addWidget(urlBrowseBtn, 0, 2); urlListBox = new KrListWidget(this); urlListBox->setSelectionMode(QAbstractItemView::ExtendedSelection); urlListRequesterGrid->addWidget(urlListBox, 1, 0, 1, 3); // add shell completion completion.setMode(KUrlCompletion::FileCompletion); urlLineEdit->setCompletionObject(&completion); // connection table connect(urlAddBtn, &QToolButton::clicked, this, &KURLListRequester::slotAdd); connect(urlBrowseBtn, &QToolButton::clicked, this, &KURLListRequester::slotBrowse); connect(urlLineEdit, &KLineEdit::returnPressed, this, &KURLListRequester::slotAdd); connect(urlListBox, &KrListWidget::itemRightClicked, this, &KURLListRequester::slotRightClicked); connect(urlLineEdit, &KLineEdit::textChanged, this, &KURLListRequester::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 selectedItems = urlListBox->selectedItems(); for (QListWidgetItem *item : selectedItems) delete item; emit changed(); } void KURLListRequester::slotRightClicked(QListWidgetItem *item, const QPoint &pos) { - if (item == 0) + if (item == nullptr) 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() { QStringList lines; const QString lineEditText = urlLineEdit->text().simplified(); if (!lineEditText.isEmpty()) { lines.append(lineEditText); } for (int i = 0; i != urlListBox->count(); i++) { QListWidgetItem *item = urlListBox->item(i); lines.append(item->text().simplified()); } QList urls; for (QString text : lines) { QString error; emit checkValidity(text, error); if (error.isNull()) urls.append(QUrl::fromUserInput(text, QString(), QUrl::AssumeLocalFile)); } return urls; } void KURLListRequester::setUrlList(const QList &urlList) { urlLineEdit->clear(); urlListBox->clear(); - for (const QUrl url : urlList) { + for (const QUrl& url : urlList) { urlListBox->addItem(url.toDisplayString(QUrl::PreferLocalFile)); } emit changed(); } diff --git a/krusader/Dialogs/kurllistrequester.h b/krusader/Dialogs/kurllistrequester.h index 3e778b16..5499e413 100644 --- a/krusader/Dialogs/kurllistrequester.h +++ b/krusader/Dialogs/kurllistrequester.h @@ -1,78 +1,78 @@ /***************************************************************************** * Copyright (C) 2005 Csaba Karai * * Copyright (C) 2005-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef KURLLISTREQUESTER_H #define KURLLISTREQUESTER_H // QtGui #include // QtWidgets #include #include #include #include #include "../GUI/krlistwidget.h" /** * Widget for letting the user define a list of URLs. */ class KURLListRequester : public QWidget { Q_OBJECT public: enum Mode { RequestFiles, RequestDirs }; - explicit KURLListRequester(Mode requestMode, QWidget *parent = 0); + explicit KURLListRequester(Mode requestMode, QWidget *parent = nullptr); QList urlList(); void setUrlList(const QList &); KLineEdit *lineEdit() { return urlLineEdit; } KrListWidget *listBox() { return urlListBox; } void setCompletionDir(const QUrl &dir) { completion.setDir(dir); } signals: void checkValidity(QString &text, QString &error); void changed(); protected slots: void slotAdd(); void slotBrowse(); void slotRightClicked(QListWidgetItem *, const QPoint &); protected: - virtual void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; + void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; void deleteSelectedItems(); Mode mode; KLineEdit *urlLineEdit; KrListWidget *urlListBox; QToolButton *urlAddBtn; QToolButton *urlBrowseBtn; KUrlCompletion completion; }; #endif /* __KURLLISTREQUESTER_H__ */ diff --git a/krusader/Dialogs/newftpgui.cpp b/krusader/Dialogs/newftpgui.cpp index 2bf5fc9d..24a306d6 100644 --- a/krusader/Dialogs/newftpgui.cpp +++ b/krusader/Dialogs/newftpgui.cpp @@ -1,203 +1,203 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * Copyright (C) 2009 Fathi Boudra * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "newftpgui.h" // QtCore #include #include // QtGui #include // QtWidgets #include #include #include #include #include #include #include #include #include #include "../krglobal.h" #include "../icon.h" #define SIZE_MINIMUM QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) const QStringList sProtocols = QStringList() << QStringLiteral("ftp") << QStringLiteral("ftps") << QStringLiteral("sftp") << QStringLiteral("fish") << QStringLiteral("nfs") << QStringLiteral("smb") << QStringLiteral("webdav") << QStringLiteral("svn") << QStringLiteral("svn+file") << QStringLiteral("svn+http") << QStringLiteral("svn+https") << QStringLiteral("svn+ssh"); /** * Constructs a newFTPGUI which is a child of 'parent', * with the name 'name' and widget flags set to 'f' */ newFTPGUI::newFTPGUI(QWidget* parent) : QDialog(parent) { setModal(true); setWindowTitle(i18n("New Network Connection")); resize(500, 240); - QVBoxLayout *mainLayout = new QVBoxLayout; + auto *mainLayout = new QVBoxLayout; setLayout(mainLayout); QSizePolicy policy(QSizePolicy::Preferred, QSizePolicy::Preferred); policy.setHeightForWidth(sizePolicy().hasHeightForWidth()); setSizePolicy(policy); iconLabel = new QLabel(this); iconLabel->setPixmap(Icon("network-wired").pixmap(32)); iconLabel->setSizePolicy(SIZE_MINIMUM); aboutLabel = new QLabel(i18n("About to connect to..."), this); QFont font(aboutLabel->font()); font.setBold(true); aboutLabel->setFont(font); protocolLabel = new QLabel(i18n("Protocol:"), this); hostLabel = new QLabel(i18n("Host:"), this); portLabel = new QLabel(i18n("Port:"), this); prefix = new KComboBox(this); prefix->setObjectName(QString::fromUtf8("protocol")); prefix->setSizePolicy(SIZE_MINIMUM); url = new KHistoryComboBox(this); url->setMaxCount(50); url->setMinimumContentsLength(10); const QStringList availableProtocols = KProtocolInfo::protocols(); - for (const QString protocol : sProtocols) { + for (const QString& protocol : sProtocols) { if (availableProtocols.contains(protocol)) prefix->addItem(protocol + QStringLiteral("://")); } // load the history and completion list after creating the history combo KConfigGroup group(krConfig, "Private"); QStringList list = group.readEntry("newFTP Completion list", QStringList()); url->completionObject()->setItems(list); list = group.readEntry("newFTP History list", QStringList()); url->setHistoryItems(list); // Select last used protocol const QString lastUsedProtocol = group.readEntry("newFTP Protocol", QString()); if(!lastUsedProtocol.isEmpty()) { prefix->setCurrentItem(lastUsedProtocol); } port = new QSpinBox(this); port->setMaximum(65535); port->setValue(21); port->setSizePolicy(SIZE_MINIMUM); usernameLabel = new QLabel(i18n("Username:"), this); username = new KLineEdit(this); passwordLabel = new QLabel(i18n("Password:"), this); password = new KLineEdit(this); password->setEchoMode(QLineEdit::Password); - QHBoxLayout *horizontalLayout = new QHBoxLayout(); + auto *horizontalLayout = new QHBoxLayout(); horizontalLayout->addWidget(iconLabel); horizontalLayout->addWidget(aboutLabel); - QGridLayout *gridLayout = new QGridLayout(); + auto *gridLayout = new QGridLayout(); gridLayout->addWidget(protocolLabel, 0, 0, 1, 1); gridLayout->addWidget(hostLabel, 0, 1, 1, 1); gridLayout->addWidget(portLabel, 0, 2, 1, 1); gridLayout->addWidget(prefix, 1, 0, 1, 1); gridLayout->addWidget(url, 1, 1, 1, 1); gridLayout->addWidget(port, 1, 2, 1, 1); gridLayout->addWidget(usernameLabel, 2, 0, 1, 1); gridLayout->addWidget(username, 3, 0, 1, 3); gridLayout->addWidget(passwordLabel, 4, 0, 1, 1); gridLayout->addWidget(password, 5, 0, 1, 3); - QGridLayout *widgetLayout = new QGridLayout(); + auto *widgetLayout = new QGridLayout(); widgetLayout->addLayout(horizontalLayout, 0, 0, 1, 1); widgetLayout->addLayout(gridLayout, 1, 0, 1, 1); mainLayout->addLayout(widgetLayout); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); mainLayout->addWidget(buttonBox); QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); okButton->setText(i18n("&Connect")); okButton->setDefault(true); okButton->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox, &QDialogButtonBox::accepted, this, &newFTPGUI::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &newFTPGUI::reject); connect(prefix, QOverload::of(&KComboBox::activated), this, &newFTPGUI::slotTextChanged); connect(url, QOverload::of(&KHistoryComboBox::activated), url, &KHistoryComboBox::addToHistory); if(!lastUsedProtocol.isEmpty()) { // update the port field slotTextChanged(lastUsedProtocol); } setTabOrder(url, username); setTabOrder(username, password); setTabOrder(password, prefix); } /** * Destroys the object and frees any allocated resources */ newFTPGUI::~newFTPGUI() { // no need to delete child widgets, Qt does it all for us } void newFTPGUI::slotTextChanged(const QString &string) { if (string.startsWith(QLatin1String("ftp")) || string.startsWith(QLatin1String("sftp")) || string.startsWith(QLatin1String("fish"))) { if (port->value() == 21 || port->value() == 22) { port->setValue(string.startsWith(QLatin1String("ftp")) ? 21 : 22); } port->setEnabled(true); } else { port->setEnabled(false); } } /** * Main event handler. Reimplemented to handle application font changes */ bool newFTPGUI::event(QEvent *ev) { bool ret = QDialog::event(ev); if (ev->type() == QEvent::ApplicationFontChange) { QFont font(aboutLabel->font()); font.setBold(true); aboutLabel->setFont(font); } return ret; } diff --git a/krusader/Dialogs/newftpgui.h b/krusader/Dialogs/newftpgui.h index 40b1532f..4e20c40e 100644 --- a/krusader/Dialogs/newftpgui.h +++ b/krusader/Dialogs/newftpgui.h @@ -1,68 +1,68 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * Copyright (C) 2009 Fathi Boudra * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef NEWFTPGUI_H #define NEWFTPGUI_H // QtWidgets #include #include #include #include #include #include /** * The "New Network Connection" dialog */ class newFTPGUI : public QDialog { Q_OBJECT public: - explicit newFTPGUI(QWidget *parent = 0); - ~newFTPGUI(); + explicit newFTPGUI(QWidget *parent = nullptr); + ~newFTPGUI() override; KComboBox* prefix; KHistoryComboBox* url; QSpinBox* port; KLineEdit* username; KLineEdit* password; protected: bool event(QEvent *) Q_DECL_OVERRIDE; private slots: void slotTextChanged(const QString &); private: QLabel* iconLabel; QLabel* aboutLabel; QLabel* protocolLabel; QLabel* passwordLabel; QLabel* hostLabel; QLabel* usernameLabel; QLabel* portLabel; }; #endif diff --git a/krusader/Dialogs/packgui.cpp b/krusader/Dialogs/packgui.cpp index b6bf1794..61c2ea51 100644 --- a/krusader/Dialogs/packgui.cpp +++ b/krusader/Dialogs/packgui.cpp @@ -1,127 +1,127 @@ /***************************************************************************** * Copyright (C) 2000 Shie Erlich * * Copyright (C) 2000 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "packgui.h" #include "../krglobal.h" #include "../defaults.h" // QtCore #include // QtWidgets #include #include #include #include #include #include #include #include #include #define PS(x) lst.contains(x)>0 // clear the statics first -QString PackGUI::filename = 0; -QString PackGUI::destination = 0; -QString PackGUI::type = 0; +QString PackGUI::filename = nullptr; +QString PackGUI::destination = nullptr; +QString PackGUI::type = nullptr; QMap PackGUI::extraProps; -PackGUI::PackGUI(QString defaultName, QString defaultPath, int noOfFiles, QString filename) : - PackGUIBase(0) +PackGUI::PackGUI(const QString& defaultName, const QString& defaultPath, int noOfFiles, const QString& filename) : + PackGUIBase(nullptr) { // first, fill the WhatToPack textfield with information if (noOfFiles == 1) TextLabel1->setText(i18n("Pack %1", filename)); else TextLabel1->setText(i18np("Pack %1 file", "Pack %1 files", noOfFiles)); // now, according to the Konfigurator, fill the combobox with the information // about what kind of packing we can do KConfigGroup group(krConfig, "Archives"); QStringList lst = group.readEntry("Supported Packers", QStringList()); // now, clear the type combo and begin... typeData->clear(); if (PS("tar")) typeData->addItem("tar"); if (PS("tar") && PS("gzip")) typeData->addItem("tar.gz"); if (PS("tar") && PS("bzip2")) typeData->addItem("tar.bz2"); if (PS("tar") && PS("lzma")) typeData->addItem("tar.lzma"); if (PS("tar") && PS("xz")) typeData->addItem("tar.xz"); if (PS("zip")) typeData->addItem("zip"); if (PS("zip")) typeData->addItem("cbz"); if (PS("rar")) typeData->addItem("rar"); if (PS("rar")) typeData->addItem("cbr"); if (PS("lha")) typeData->addItem("lha"); if (PS("arj")) typeData->addItem("arj"); if (PS("7z")) typeData->addItem("7z"); // set the last used packer as the top one QString tmp = group.readEntry("lastUsedPacker", QString()); if (!tmp.isEmpty()) { for (int i = 0; i < typeData->count(); ++i) if (typeData->itemText(i) == tmp) { typeData->removeItem(i); typeData->insertItem(0, tmp); typeData->setCurrentIndex(0); break; } } checkConsistency(); // and go on with the normal stuff dirData->setText(defaultPath); nameData->setText(defaultName); nameData->setFocus(); if (typeData->count() == 0) // if no packers are available okButton->setEnabled(false); setGeometry(krMainWindow->x() + krMainWindow->width() / 2 - width() / 2, krMainWindow->y() + krMainWindow->height() / 2 - height() / 2, width(), height()); exec(); } void PackGUI::browse() { - QString temp = QFileDialog::getExistingDirectory(0, i18n("Please select a folder"), dirData->text()); + QString temp = QFileDialog::getExistingDirectory(nullptr, i18n("Please select a folder"), dirData->text()); if (!temp.isEmpty()) { dirData->setText(temp); } } void PackGUI::accept() { if (!extraProperties(extraProps)) return; filename = nameData->text(); destination = dirData->text(); type = typeData->currentText(); // write down the packer chosen, to be lastUsedPacker KConfigGroup group(krConfig, "Archives"); group.writeEntry("lastUsedPacker", type); krConfig->sync(); PackGUIBase::accept(); } void PackGUI::reject() { filename.clear(); destination.clear(); type.clear(); PackGUIBase::reject(); } diff --git a/krusader/Dialogs/packgui.h b/krusader/Dialogs/packgui.h index caea6ec6..ed4ef376 100644 --- a/krusader/Dialogs/packgui.h +++ b/krusader/Dialogs/packgui.h @@ -1,45 +1,45 @@ /***************************************************************************** * Copyright (C) 2000 Shie Erlich * * Copyright (C) 2000 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef PACKGUI_H #define PACKGUI_H #include "packguibase.h" class PackGUI : public PackGUIBase { Q_OBJECT public: - PackGUI(QString defaultName, QString defaultPath, int noOfFiles, QString filename = ""); + PackGUI(const QString& defaultName, const QString& defaultPath, int noOfFiles, const QString& filename = ""); public slots: void browse() Q_DECL_OVERRIDE; protected slots: void accept() Q_DECL_OVERRIDE; void reject() Q_DECL_OVERRIDE; public: static QString filename, destination, type; static QMap extraProps; }; #endif diff --git a/krusader/Dialogs/packguibase.cpp b/krusader/Dialogs/packguibase.cpp index f7e67a75..8535484e 100644 --- a/krusader/Dialogs/packguibase.cpp +++ b/krusader/Dialogs/packguibase.cpp @@ -1,496 +1,496 @@ /***************************************************************************** * Copyright (C) 2000 Shie Erlich * * Copyright (C) 2000 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "packguibase.h" // QtCore #include // QtGui #include #include #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../defaults.h" #include "../krglobal.h" #include "../icon.h" /* * Constructs a PackGUIBase which is a child of 'parent', with the * name 'name' and widget flags set to 'f' * * The dialog will by default be modeless, unless you set 'modal' to * TRUE to construct a modal dialog. */ PackGUIBase::PackGUIBase(QWidget* parent) : QDialog(parent), expanded(false) { KConfigGroup group(krConfig, "Archives"); setModal(true); resize(430, 140); setWindowTitle(i18n("Pack")); grid = new QGridLayout(this); grid->setSpacing(6); grid->setContentsMargins(11, 11, 11, 11); hbox = new QHBoxLayout; hbox->setSpacing(6); hbox->setContentsMargins(0, 0, 0, 0); TextLabel3 = new QLabel(this); TextLabel3->setText(i18n("To archive")); hbox->addWidget(TextLabel3); nameData = new QLineEdit(this); hbox->addWidget(nameData); typeData = new QComboBox(this); typeData->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed)); connect(typeData, QOverload::of(&QComboBox::activated), this, &PackGUIBase::checkConsistency); connect(typeData, QOverload::of(&QComboBox::highlighted), this, &PackGUIBase::checkConsistency); hbox->addWidget(typeData); grid->addLayout(hbox, 1, 0); hbox_2 = new QHBoxLayout; hbox_2->setSpacing(6); hbox_2->setContentsMargins(0, 0, 0, 0); TextLabel5 = new QLabel(this); TextLabel5->setText(i18n("In folder")); hbox_2->addWidget(TextLabel5); dirData = new QLineEdit(this); hbox_2->addWidget(dirData); browseButton = new QToolButton(this); browseButton->setIcon(Icon("document-open")); hbox_2->addWidget(browseButton); - QSpacerItem* spacer = new QSpacerItem(48, 20, QSizePolicy::Fixed, QSizePolicy::Fixed); + auto* spacer = new QSpacerItem(48, 20, QSizePolicy::Fixed, QSizePolicy::Fixed); hbox_2->addItem(spacer); grid->addLayout(hbox_2, 2, 0); hbox_3 = new QHBoxLayout; hbox_3->setSpacing(6); hbox_3->setContentsMargins(0, 0, 0, 0); PixmapLabel1 = new QLabel(this); PixmapLabel1->setPixmap(Icon("package-x-generic").pixmap(32)); PixmapLabel1->setScaledContents(true); PixmapLabel1->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); hbox_3->addWidget(PixmapLabel1); TextLabel1 = new QLabel(this); TextLabel1->setText(i18n("Pack")); hbox_3->addWidget(TextLabel1); grid->addLayout(hbox_3, 0, 0); hbox_4 = new QHBoxLayout; hbox_4->setSpacing(6); hbox_4->setContentsMargins(0, 0, 0, 0); - QSpacerItem* spacer_3 = new QSpacerItem(20, 26, QSizePolicy::Fixed, QSizePolicy::Expanding); + auto* spacer_3 = new QSpacerItem(20, 26, QSizePolicy::Fixed, QSizePolicy::Expanding); hbox_4->addItem(spacer_3); grid->addLayout(hbox_4, 3, 0); advancedWidget = new QWidget(this); hbox_5 = new QGridLayout(advancedWidget); hbox_5->setSpacing(6); hbox_5->setContentsMargins(0, 0, 0, 0); - QVBoxLayout *compressLayout = new QVBoxLayout; + auto *compressLayout = new QVBoxLayout; compressLayout->setSpacing(6); compressLayout->setContentsMargins(0, 0, 0, 0); multipleVolume = new QCheckBox(i18n("Multiple volume archive"), advancedWidget); connect(multipleVolume, &QCheckBox::toggled, this, &PackGUIBase::checkConsistency); - compressLayout->addWidget(multipleVolume, 0, 0); + compressLayout->addWidget(multipleVolume, 0, nullptr); - QHBoxLayout * volumeHbox = new QHBoxLayout; + auto * volumeHbox = new QHBoxLayout; - QSpacerItem* spacer_5 = new QSpacerItem(20, 26, QSizePolicy::Fixed, QSizePolicy::Fixed); + auto* spacer_5 = new QSpacerItem(20, 26, QSizePolicy::Fixed, QSizePolicy::Fixed); volumeHbox->addItem(spacer_5); TextLabel7 = new QLabel(i18n("Size:"), advancedWidget); volumeHbox->addWidget(TextLabel7); volumeSpinBox = new QSpinBox(advancedWidget); volumeSpinBox->setMinimum(1); volumeSpinBox->setMaximum(9999); volumeSpinBox->setValue(1440); volumeHbox->addWidget(volumeSpinBox); volumeUnitCombo = new QComboBox(advancedWidget); volumeUnitCombo->addItem("B"); volumeUnitCombo->addItem("KB"); volumeUnitCombo->addItem("MB"); volumeUnitCombo->setCurrentIndex(1); volumeHbox->addWidget(volumeUnitCombo); compressLayout->addLayout(volumeHbox); int level = group.readEntry("Compression level", _defaultCompressionLevel); setCompressionLevel = new QCheckBox(i18n("Set compression level"), advancedWidget); if (level != _defaultCompressionLevel) setCompressionLevel->setChecked(true); connect(setCompressionLevel, &QCheckBox::toggled, this, &PackGUIBase::checkConsistency); - compressLayout->addWidget(setCompressionLevel, 0, 0); + compressLayout->addWidget(setCompressionLevel, 0, nullptr); - QHBoxLayout * sliderHbox = new QHBoxLayout; + auto * sliderHbox = new QHBoxLayout; - QSpacerItem* spacer_6 = new QSpacerItem(20, 26, QSizePolicy::Fixed, QSizePolicy::Fixed); + auto* spacer_6 = new QSpacerItem(20, 26, QSizePolicy::Fixed, QSizePolicy::Fixed); sliderHbox->addItem(spacer_6); QWidget * sliderVBoxWidget = new QWidget(advancedWidget); - QVBoxLayout *sliderVBox = new QVBoxLayout(sliderVBoxWidget); + auto *sliderVBox = new QVBoxLayout(sliderVBoxWidget); compressionSlider = new QSlider(Qt::Horizontal, sliderVBoxWidget); compressionSlider->setMinimum(1); compressionSlider->setMaximum(9); compressionSlider->setPageStep(1); compressionSlider->setValue(level); compressionSlider->setTickPosition(QSlider::TicksBelow); sliderVBox->addWidget(compressionSlider); QWidget * minmaxWidget = new QWidget(sliderVBoxWidget); sliderVBox->addWidget(minmaxWidget); - QHBoxLayout * minmaxHbox = new QHBoxLayout(minmaxWidget); + auto * minmaxHbox = new QHBoxLayout(minmaxWidget); minLabel = new QLabel(i18n("MIN"), minmaxWidget); maxLabel = new QLabel(i18n("MAX"), minmaxWidget); maxLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); minmaxHbox->addWidget(minLabel); minmaxHbox->addWidget(maxLabel); sliderHbox->addWidget(sliderVBoxWidget); compressLayout->addLayout(sliderHbox); compressLayout->addStretch(0); hbox_5->addLayout(compressLayout, 0, 0); QFrame *vline = new QFrame(advancedWidget); vline->setFrameStyle(QFrame::VLine | QFrame::Sunken); vline->setMinimumWidth(20); hbox_5->addWidget(vline, 0, 1); - QGridLayout * passwordGrid = new QGridLayout; + auto * passwordGrid = new QGridLayout; passwordGrid->setSpacing(6); passwordGrid->setContentsMargins(0, 0, 0, 0); TextLabel4 = new QLabel(advancedWidget); TextLabel4->setText(i18n("Password")); passwordGrid->addWidget(TextLabel4, 0, 0); password = new QLineEdit(advancedWidget); password->setEchoMode(QLineEdit::Password); connect(password, &QLineEdit::textChanged, this, &PackGUIBase::checkConsistency); passwordGrid->addWidget(password, 0, 1); TextLabel6 = new QLabel(advancedWidget); TextLabel6->setText(i18n("Again")); passwordGrid->addWidget(TextLabel6, 1, 0); passwordAgain = new QLineEdit(advancedWidget); passwordAgain->setEchoMode(QLineEdit::Password); connect(passwordAgain, &QLineEdit::textChanged, this, &PackGUIBase::checkConsistency); passwordGrid->addWidget(passwordAgain, 1, 1); - QHBoxLayout *consistencyHbox = new QHBoxLayout; + auto *consistencyHbox = new QHBoxLayout; - QSpacerItem* spacer_cons = new QSpacerItem(48, 20, QSizePolicy::Expanding, QSizePolicy::Fixed); + auto* spacer_cons = new QSpacerItem(48, 20, QSizePolicy::Expanding, QSizePolicy::Fixed); consistencyHbox->addItem(spacer_cons); passwordConsistencyLabel = new QLabel(advancedWidget); consistencyHbox->addWidget(passwordConsistencyLabel); passwordGrid->addLayout(consistencyHbox, 2, 0, 1, 2); encryptHeaders = new QCheckBox(i18n("Encrypt headers"), advancedWidget); passwordGrid->addWidget(encryptHeaders, 3, 0, 1, 2); - QSpacerItem* spacer_psw = new QSpacerItem(20, 20, QSizePolicy::Fixed, QSizePolicy::Expanding); + auto* spacer_psw = new QSpacerItem(20, 20, QSizePolicy::Fixed, QSizePolicy::Expanding); passwordGrid->addItem(spacer_psw, 4, 0); hbox_5->addLayout(passwordGrid, 0, 2); hbox_7 = new QHBoxLayout; hbox_7->setSpacing(6); hbox_7->setContentsMargins(0, 0, 0, 0); TextLabel8 = new QLabel(i18n("Command line switches:"), advancedWidget); TextLabel8->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); hbox_7->addWidget(TextLabel8); commandLineSwitches = new KHistoryComboBox(advancedWidget); commandLineSwitches->setMaxCount(25); // remember 25 items commandLineSwitches->setDuplicatesEnabled(false); commandLineSwitches->setMinimumContentsLength(10); QStringList list = group.readEntry("Command Line Switches", QStringList()); commandLineSwitches->setHistoryItems(list); hbox_7->addWidget(commandLineSwitches); hbox_5->addLayout(hbox_7, 1, 0, 1, 3); advancedWidget->hide(); checkConsistency(); grid->addWidget(advancedWidget, 4, 0); hbox_6 = new QHBoxLayout; hbox_6->setSpacing(6); hbox_6->setContentsMargins(0, 0, 0, 0); advancedButton = new QPushButton(this); advancedButton->setText(i18n("&Advanced >>")); hbox_6->addWidget(advancedButton); - QSpacerItem* spacer_2 = new QSpacerItem(140, 20, QSizePolicy::Expanding, QSizePolicy::Fixed); + auto* spacer_2 = new QSpacerItem(140, 20, QSizePolicy::Expanding, QSizePolicy::Fixed); hbox_6->addItem(spacer_2); okButton = new QPushButton(this); KStandardGuiItem::assign(okButton, KStandardGuiItem::Ok); okButton->setDefault(true); hbox_6->addWidget(okButton); cancelButton = new QPushButton(this); KStandardGuiItem::assign(cancelButton, KStandardGuiItem::Cancel); hbox_6->addWidget(cancelButton); grid->addLayout(hbox_6, 6, 0); // signals and slots connections connect(okButton, &QPushButton::clicked, this, &PackGUIBase::accept); connect(advancedButton, &QPushButton::clicked, this, &PackGUIBase::expand); connect(cancelButton, &QPushButton::clicked, this, &PackGUIBase::reject); connect(browseButton, &QToolButton::clicked, this, &PackGUIBase::browse); } /* * Destroys the object and frees any allocated resources */ PackGUIBase::~PackGUIBase() { // no need to delete child widgets, Qt does it all for us } void PackGUIBase::browse() { qWarning("PackGUIBase::browse(): Not implemented yet!"); } void PackGUIBase::expand() { expanded = !expanded; advancedButton->setText(expanded ? i18n("&Advanced <<") : i18n("&Advanced >>")); if (expanded) advancedWidget->show(); else { advancedWidget->hide(); layout()->activate(); QSize minSize = minimumSize(); resize(width(), minSize.height()); } show(); } void PackGUIBase::checkConsistency() { QPalette p = QGuiApplication::palette(); QPalette pal = passwordConsistencyLabel->palette(); if (password->text().isEmpty() && passwordAgain->text().isEmpty()) { pal.setColor(passwordConsistencyLabel->foregroundRole(), p.color(QPalette::Active, QPalette::Text)); passwordConsistencyLabel->setText(i18n("No password specified")); } else if (password->text() == passwordAgain->text()) { pal.setColor(passwordConsistencyLabel->foregroundRole(), p.color(QPalette::Active, QPalette::Text)); passwordConsistencyLabel->setText(i18n("The passwords are equal")); } else { pal.setColor(passwordConsistencyLabel->foregroundRole(), Qt::red); passwordConsistencyLabel->setText(i18n("The passwords are different")); } passwordConsistencyLabel->setPalette(pal); QString packer = typeData->currentText(); bool passworded = false; if (packer == "7z" || packer == "rar" || packer == "zip" || packer == "arj") passworded = true; passwordConsistencyLabel->setEnabled(passworded); password->setEnabled(passworded); passwordAgain->setEnabled(passworded); TextLabel4->setEnabled(passworded); TextLabel6->setEnabled(passworded); encryptHeaders->setEnabled(packer == "rar"); multipleVolume->setEnabled(packer == "rar" || packer == "arj"); bool volumeEnabled = multipleVolume->isEnabled() && multipleVolume->isChecked(); volumeSpinBox->setEnabled(volumeEnabled); volumeUnitCombo->setEnabled(volumeEnabled); TextLabel7->setEnabled(volumeEnabled); /* TODO */ setCompressionLevel->setEnabled(packer == "rar" || packer == "arj" || packer == "zip" || packer == "7z"); bool sliderEnabled = setCompressionLevel->isEnabled() && setCompressionLevel->isChecked(); compressionSlider->setEnabled(sliderEnabled); minLabel->setEnabled(sliderEnabled); maxLabel->setEnabled(sliderEnabled); } bool PackGUIBase::extraProperties(QMap & inMap) { inMap.clear(); KConfigGroup group(krConfig, "Archives"); if (password->isEnabled() && passwordAgain->isEnabled()) { if (password->text() != passwordAgain->text()) { KMessageBox::error(this, i18n("Cannot pack, the passwords are different.")); return false; } if (!password->text().isEmpty()) { inMap[ "Password" ] = password->text(); if (encryptHeaders->isEnabled() && encryptHeaders->isChecked()) inMap[ "EncryptHeaders" ] = '1'; } } if (multipleVolume->isEnabled() && multipleVolume->isChecked()) { KIO::filesize_t size = volumeSpinBox->value(); switch (volumeUnitCombo->currentIndex()) { case 2: size *= 1000; #if __GNUC__ >= 7 [[gnu::fallthrough]]; #endif case 1: size *= 1000; default: break; } if (size < 10000) { KMessageBox::error(this, i18n("Invalid volume size.")); return false; } QString sbuffer; sbuffer.sprintf("%llu", size); inMap[ "VolumeSize" ] = sbuffer; } if (setCompressionLevel->isEnabled() && setCompressionLevel->isChecked()) { inMap[ "CompressionLevel" ] = QString("%1").arg(compressionSlider->value()); int level = compressionSlider->value(); group.writeEntry("Compression level", level); } QString cmdArgs = commandLineSwitches->currentText().trimmed(); if (!cmdArgs.isEmpty()) { bool firstChar = true; QChar quote = QChar::Null; for (int i = 0; i < cmdArgs.length(); i++) { QChar ch(cmdArgs[ i ]); if (ch.isSpace()) continue; if (ch == quote) { quote = QChar::Null; continue; } if (firstChar && ch != QLatin1Char('-')) { KMessageBox::error(this, i18n("Invalid command line switch.\nA switch must start with '-'.")); return false; } firstChar = false; if (quote == QLatin1Char('"')) continue; if (quote == QChar::Null && (ch == QLatin1Char('\'') || ch == QLatin1Char('"'))) quote = ch; if (ch == QLatin1Char('\\')) { if (i == cmdArgs.length() - 1) { KMessageBox::error(this, i18n("Invalid command line switch.\nBackslashes cannot be the last character.")); return false; } i++; } } if (quote != QChar::Null) { KMessageBox::error(this, i18n("Invalid command line switch.\nUnclosed quotation mark.")); return false; } commandLineSwitches->addToHistory(cmdArgs); QStringList list = commandLineSwitches->historyItems(); group.writeEntry("Command Line Switches", list); inMap[ "CommandLineSwitches" ] = cmdArgs; } return true; } diff --git a/krusader/Dialogs/packguibase.h b/krusader/Dialogs/packguibase.h index 6538eedb..daa297c8 100644 --- a/krusader/Dialogs/packguibase.h +++ b/krusader/Dialogs/packguibase.h @@ -1,103 +1,103 @@ /***************************************************************************** * Copyright (C) 2000 Shie Erlich * * Copyright (C) 2000 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef PACKGUIBASE_H #define PACKGUIBASE_H // QtCore #include // QtWidgets #include #include #include #include #include class QHBoxLayout; class QGridLayout; class QCheckBox; class QComboBox; class QLabel; class QLineEdit; class QPushButton; class QToolButton; class QSpinBox; class QSlider; class KHistoryComboBox; class PackGUIBase : public QDialog { Q_OBJECT public: - explicit PackGUIBase(QWidget* parent = 0); - ~PackGUIBase(); + explicit PackGUIBase(QWidget* parent = nullptr); + ~PackGUIBase() override; QLabel* TextLabel3; QLineEdit* nameData; QComboBox* typeData; QLabel* TextLabel5; QLineEdit* dirData; QToolButton* browseButton; QWidget* advancedWidget; QLabel* PixmapLabel1; QLabel* TextLabel1; QLabel* TextLabel4; QLabel* TextLabel6; QLabel* TextLabel7; QLabel* TextLabel8; QLabel* minLabel; QLabel* maxLabel; QLineEdit* password; QLineEdit* passwordAgain; QLabel* passwordConsistencyLabel; QPushButton* okButton; QPushButton* cancelButton; QPushButton* advancedButton; QCheckBox* encryptHeaders; QCheckBox* multipleVolume; QSpinBox* volumeSpinBox; QComboBox* volumeUnitCombo; QCheckBox* setCompressionLevel; QSlider* compressionSlider; KHistoryComboBox *commandLineSwitches; public slots: virtual void browse(); virtual bool extraProperties(QMap &); void expand(); void checkConsistency(); protected: QHBoxLayout* hbox; QHBoxLayout* hbox_2; QHBoxLayout* hbox_3; QHBoxLayout* hbox_4; QGridLayout* hbox_5; QHBoxLayout* hbox_6; QHBoxLayout* hbox_7; QGridLayout* grid; private: bool expanded; }; #endif // PACKGUIBASE_H diff --git a/krusader/Dialogs/percentalsplitter.cpp b/krusader/Dialogs/percentalsplitter.cpp index ddd02434..c4e40f59 100644 --- a/krusader/Dialogs/percentalsplitter.cpp +++ b/krusader/Dialogs/percentalsplitter.cpp @@ -1,83 +1,82 @@ /***************************************************************************** * Copyright (C) 2006 Csaba Karai * * Copyright (C) 2006-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "percentalsplitter.h" // QtCore #include // QtGui #include #include // QtWidgets #include #include #include #include -PercentalSplitter::PercentalSplitter(QWidget * parent) : QSplitter(parent), label(0), opaqueOldPos(-1) +PercentalSplitter::PercentalSplitter(QWidget * parent) : QSplitter(parent), label(nullptr), opaqueOldPos(-1) { connect(this, &PercentalSplitter::splitterMoved, this, &PercentalSplitter::slotSplitterMoved); } PercentalSplitter::~PercentalSplitter() -{ -} += default; QString PercentalSplitter::toolTipString(int p) { QList values = sizes(); if (values.count() != 0) { int sum = 0; QListIterator it(values); while (it.hasNext()) sum += it.next(); if (sum == 0) sum++; - int percent = (int)(((double)p / (double)(sum)) * 10000. + 0.5); + auto percent = (int)(((double)p / (double)(sum)) * 10000. + 0.5); return QString("%1.%2%3").arg(percent / 100).arg((percent / 10) % 10).arg(percent % 10) + '%'; } return QString(); } void PercentalSplitter::slotSplitterMoved(int p, int index) { handle(index) -> setToolTip(toolTipString(p)); QToolTip::showText(QCursor::pos(), toolTipString(p) , this); } void PercentalSplitter::showEvent(QShowEvent * event) { QList values = sizes(); for (int i = 0; i != count(); i++) { int p = 0; for (int j = 0; j < i; j++) p += values[ j ]; handle(i) -> setToolTip(toolTipString(p)); } QSplitter::showEvent(event); } diff --git a/krusader/Dialogs/percentalsplitter.h b/krusader/Dialogs/percentalsplitter.h index 5e81235a..1bbe6bba 100644 --- a/krusader/Dialogs/percentalsplitter.h +++ b/krusader/Dialogs/percentalsplitter.h @@ -1,50 +1,50 @@ /***************************************************************************** * Copyright (C) 2006 Csaba Karai * * Copyright (C) 2006-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef PERCENTALSPLITTER_H #define PERCENTALSPLITTER_H // QtWidgets #include #include class PercentalSplitter : public QSplitter { Q_OBJECT public: - explicit PercentalSplitter(QWidget * parent = 0); - virtual ~PercentalSplitter(); + explicit PercentalSplitter(QWidget * parent = nullptr); + ~PercentalSplitter() override; QString toolTipString(int p); protected: - virtual void showEvent(QShowEvent * event) Q_DECL_OVERRIDE; + void showEvent(QShowEvent * event) Q_DECL_OVERRIDE; protected slots: void slotSplitterMoved(int pos, int index); private: QLabel * label; int opaqueOldPos; QPoint labelLocation; }; #endif /* __PERCENTAL_SPLITTER__ */ diff --git a/krusader/Dialogs/popularurls.cpp b/krusader/Dialogs/popularurls.cpp index 7457b69d..26ab7299 100644 --- a/krusader/Dialogs/popularurls.cpp +++ b/krusader/Dialogs/popularurls.cpp @@ -1,373 +1,373 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "popularurls.h" #include // QtCore #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include "../krglobal.h" #include "../icon.h" #include "../krslots.h" #include "../GUI/krtreewidget.h" #define STARTING_RANK 20 #define INCREASE 2 #define DECREASE 1 PopularUrls::PopularUrls(QObject *parent) : QObject(parent), - head(0), tail(0), count(0) + head(nullptr), tail(nullptr), count(0) { dlg = new PopularUrlsDlg(); } PopularUrls::~PopularUrls() { clearList(); delete dlg; } void PopularUrls::clearList() { if (head) { UrlNodeP p = head, tmp; while (p) { tmp = p; p = p->next; delete tmp; } } ranks.clear(); - head = tail = 0; + head = tail = nullptr; } void PopularUrls::save() { KConfigGroup svr(krConfig, "Private"); // prepare the string list containing urls and int list with ranks QStringList urlList; QList rankList; UrlNodeP p = head; while (p) { urlList << p->url.toDisplayString(); rankList << p->rank; p = p->next; } svr.writeEntry("PopularUrls", urlList); svr.writeEntry("PopularUrlsRank", rankList); } void PopularUrls::load() { KConfigGroup svr(krConfig, "Private"); QStringList urlList = svr.readEntry("PopularUrls", QStringList()); QList rankList = svr.readEntry("PopularUrlsRank", QList()); if (urlList.count() != rankList.count()) { KMessageBox::error(krMainWindow, i18n("The saved 'Popular URLs' are invalid. The list will be cleared.")); return; } clearList(); count = 0; // iterate through both lists and QStringList::Iterator uit; QList::Iterator rit; for (uit = urlList.begin(), rit = rankList.begin(); uit != urlList.end() && rit != rankList.end(); ++uit, ++rit) { - UrlNodeP node = new UrlNode; + auto node = new UrlNode; node->url = QUrl(*uit); node->rank = *rit; appendNode(node); ranks.insert(*uit, node); } } // returns a url list with the 'max' top popular urls QList PopularUrls::getMostPopularUrls(int max) { // get at most 'max' urls QList list; UrlNodeP p = head; int tmp = 0; if (maxUrls < max) max = maxUrls; // don't give more than maxUrls while (p && tmp < max) { list << p->url; p = p->next; ++tmp; } return list; } // adds a url to the list, or increase rank of an existing url, making // sure to bump it up the list if needed void PopularUrls::addUrl(const QUrl& url) { QUrl tmpurl = url; tmpurl.setPassword(QString()); // make sure no passwords are permanently stored if (!tmpurl.path().endsWith('/')) // make a uniform trailing slash policy tmpurl.setPath(tmpurl.path() + '/'); UrlNodeP pnode; decreaseRanks(); if (!head) { // if the list is empty ... (assumes dict to be empty as well) pnode = new UrlNode; pnode->rank = STARTING_RANK; pnode->url = tmpurl; appendNode(pnode); ranks.insert(tmpurl.url(), head); } else { if (ranks.find(tmpurl.url()) == ranks.end()) { // is the added url new? if so, append it pnode = new UrlNode; pnode->rank = STARTING_RANK; pnode->url = tmpurl; appendNode(pnode); ranks.insert(tmpurl.url(), pnode); } else { pnode = ranks[ tmpurl.url()]; pnode->rank += INCREASE; } } // do we need to change location for this one? relocateIfNeeded(pnode); // too many urls? if (count > maxUrls) removeNode(tail); //dumpList(); } // checks if 'node' needs to be bumped-up the ranking list and does it if needed void PopularUrls::relocateIfNeeded(UrlNodeP node) { if (node->prev && (node->prev->rank < node->rank)) { // iterate until we find the correct place to put it UrlNodeP tmp = node->prev->prev; while (tmp) { if (tmp->rank >= node->rank) break; // found it! else tmp = tmp->prev; } // now, if tmp isn't null, we need to move node to tmp->next // else move it to become head removeNode(node); insertNode(node, tmp); } } // iterate over the list, decreasing each url's rank // this is very naive, but a 1..30 for loop is acceptable (i hope) void PopularUrls::decreaseRanks() { if (head) { UrlNodeP p = head; while (p) { if (p->rank - DECREASE >= 0) p->rank -= DECREASE; else p->rank = 0; p = p->next; } } } // removes a node from the list, but doesn't free memory! // note: this will be buggy in case the list becomes empty (which should never happen) void PopularUrls::removeNode(UrlNodeP node) { if (node->prev) { if (tail == node) tail = node->prev; node->prev->next = node->next; } if (node->next) { if (head == node) head = node->next; node->next->prev = node->prev; } --count; } void PopularUrls::insertNode(UrlNodeP node, UrlNodeP after) { if (!after) { // make node head node->next = head; - node->prev = 0; + node->prev = nullptr; head->prev = node; head = node; } else { if (tail == after) tail = node; node->prev = after; node->next = after->next; if (node->next) { after->next->prev = node; after->next = node; } } ++count; } // appends 'node' to the end of the list, collecting garbage if needed void PopularUrls::appendNode(UrlNodeP node) { if (!tail) { // creating the first element head = tail = node; - node->prev = node->next = 0; + node->prev = node->next = nullptr; } else { - node->next = 0; + node->next = nullptr; node->prev = tail; tail->next = node; tail = node; } ++count; } void PopularUrls::dumpList() { UrlNodeP p = head; printf("====start %d====\n", count); while (p) { printf("%d : %s\n", p->rank, p->url.url().toLatin1().data()); p = p->next; } fflush(stdout); } void PopularUrls::showDialog() { QList list = getMostPopularUrls(maxUrls); dlg->run(list); if (dlg->result() == -1) return; SLOTS->refresh(list[dlg->result()]); //printf("running %s\n", list[dlg->result()].url().toLatin1());fflush(stdout); } // ===================================== PopularUrlsDlg ====================================== PopularUrlsDlg::PopularUrlsDlg(): QDialog(krMainWindow) { setWindowTitle(i18n("Popular URLs")); setWindowModality(Qt::WindowModal); - QVBoxLayout *mainLayout = new QVBoxLayout; + auto *mainLayout = new QVBoxLayout; setLayout(mainLayout); - QGridLayout *layout = new QGridLayout; + auto *layout = new QGridLayout; layout->setContentsMargins(0, 0, 0, 0); // listview to contain the urls urls = new KrTreeWidget(this); urls->header()->hide(); urls->setSortingEnabled(false); urls->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); // quick search search = new KTreeWidgetSearchLine(this, urls); QLabel *lbl = new QLabel(i18n("&Search:"), this); lbl->setBuddy(search); layout->addWidget(lbl, 0, 0); layout->addWidget(search, 0, 1); layout->addWidget(urls, 1, 0, 1, 2); mainLayout->addLayout(layout); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); mainLayout->addWidget(buttonBox); setTabOrder(search, urls); setTabOrder((QWidget *)urls, buttonBox->button(QDialogButtonBox::Close)); connect(buttonBox, &QDialogButtonBox::rejected, this, &PopularUrlsDlg::reject); connect(urls, &KrTreeWidget::activated, this, &PopularUrlsDlg::slotItemSelected); connect(search, &KTreeWidgetSearchLine::hiddenChanged, this, &PopularUrlsDlg::slotVisibilityChanged); } void PopularUrlsDlg::slotItemSelected(const QModelIndex & ndx) { selection = ndx.row(); accept(); } void PopularUrlsDlg::slotVisibilityChanged() { // select the first visible item QList list = urls->selectedItems(); if (list.count() > 0 && !list[0]->isHidden()) return; urls->clearSelection(); - urls->setCurrentItem(0); + urls->setCurrentItem(nullptr); QTreeWidgetItemIterator it(urls); while (*it) { if (!(*it)->isHidden()) { (*it)->setSelected(true); urls->setCurrentItem(*it); break; } it++; } } PopularUrlsDlg::~PopularUrlsDlg() { delete search; delete urls; } void PopularUrlsDlg::run(QList list) { // populate the listview urls->clear(); QList::Iterator it; - QTreeWidgetItem * lastItem = 0; + QTreeWidgetItem * lastItem = nullptr; for (it = list.begin(); it != list.end(); ++it) { - QTreeWidgetItem *item = new QTreeWidgetItem(urls, lastItem); + auto *item = new QTreeWidgetItem(urls, lastItem); lastItem = item; item->setText(0, (*it).isLocalFile() ? (*it).path() : (*it).toDisplayString()); item->setIcon(0, (*it).isLocalFile() ? Icon("folder") : Icon("folder-html")); } setMinimumSize(urls->sizeHint().width() + 45, 400); search->clear(); search->setFocus(); selection = -1; slotVisibilityChanged(); exec(); } diff --git a/krusader/Dialogs/popularurls.h b/krusader/Dialogs/popularurls.h index 7f028711..67149375 100644 --- a/krusader/Dialogs/popularurls.h +++ b/krusader/Dialogs/popularurls.h @@ -1,111 +1,111 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef POPULARURLS_H #define POPULARURLS_H // QtCore #include #include #include // QtWidgets #include // the class holds a list of most popular links in a dual data structure // * linked list, with head and tail: for fast append/prepend support // * dictionary that maps urls to list nodes: to save the need to iterate // over the list in order to find the correct node for each new url // // also, the class holds a maximum number of urls. two variables affect this: // * maxUrls - the num. of urls the user can see // * hardLimit - the actual number of urls kept. // when the number of urls reaches hardLimit, a garbage collection is done and // the bottom (hardLimit-maxUrls) entries are removed from the list typedef struct _UrlNode* UrlNodeP; typedef struct _UrlNode { UrlNodeP prev; QUrl url; int rank; UrlNodeP next; } UrlNode; class PopularUrlsDlg; class PopularUrls : public QObject { Q_OBJECT public: - explicit PopularUrls(QObject *parent = 0); - ~PopularUrls(); + explicit PopularUrls(QObject *parent = nullptr); + ~PopularUrls() override; void save(); void load(); void addUrl(const QUrl& url); QList getMostPopularUrls(int max); public slots: void showDialog(); protected: // NOTE: the following methods append/insert/remove a node to the list // but NEVER free memory or allocate memory! void appendNode(UrlNodeP node); void insertNode(UrlNodeP node, UrlNodeP after); void removeNode(UrlNodeP node); void relocateIfNeeded(UrlNodeP node); void clearList(); void dumpList(); void decreaseRanks(); private: UrlNodeP head, tail; QHash ranks; // actually holds UrlNode* int count; static const int maxUrls = 30; PopularUrlsDlg *dlg; }; class KrTreeWidget; class KTreeWidgetSearchLine; class QModelIndex; class PopularUrlsDlg: public QDialog { Q_OBJECT public: PopularUrlsDlg(); - ~PopularUrlsDlg(); + ~PopularUrlsDlg() override; void run(QList list); // use this to open the dialog inline int result() const { return selection; } // returns index 0 - topmost, or -1 protected slots: void slotVisibilityChanged(); void slotItemSelected(const QModelIndex &); private: KrTreeWidget *urls; KTreeWidgetSearchLine *search; int selection; }; #endif diff --git a/krusader/DiskUsage/diskusage.cpp b/krusader/DiskUsage/diskusage.cpp index 95a2e66e..27a972ee 100644 --- a/krusader/DiskUsage/diskusage.cpp +++ b/krusader/DiskUsage/diskusage.cpp @@ -1,1133 +1,1134 @@ /***************************************************************************** * Copyright (C) 2004 Csaba Karai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "diskusage.h" // QtCore #include #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 #include "dufilelight.h" #include "dulines.h" #include "dulistview.h" #include "filelightParts/Config.h" #include "../FileSystem/fileitem.h" #include "../FileSystem/filesystemprovider.h" #include "../FileSystem/krpermhandler.h" #include "../Panel/krpanel.h" #include "../Panel/panelfunc.h" #include "../defaults.h" #include "../krglobal.h" #include "../filelisticon.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); + auto *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); + auto *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); + auto * hbox = new QHBoxLayout(hboxWidget); - QSpacerItem* spacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding); + auto* spacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding); hbox->addItem(spacer); - QPushButton *cancelButton = new QPushButton(hboxWidget); + auto *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, &QPushButton::clicked, this, &LoaderWidget::slotCancelled); } void LoaderWidget::init() { cancelled = false; } void LoaderWidget::setCurrentURL(const QUrl &url) { 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), searchFileSystem(0) + currentDirectory(nullptr), root(nullptr), configGroup(std::move(confGroup)), loading(false), + abortLoading(false), clearAfterAbort(false), deleting(false), searchFileSystem(nullptr) { 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, &QTimer::timeout, this, &DiskUsage::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 (searchFileSystem) { delete searchFileSystem; - searchFileSystem = 0; + searchFileSystem = nullptr; } searchFileSystem = FileSystemProvider::instance().getFilesystem(baseDir); - if (searchFileSystem == 0) { + if (searchFileSystem == nullptr) { qWarning() << "could not get filesystem for directory=" << baseDir; loading = abortLoading = clearAfterAbort = false; emit loadFinished(false); return; } - currentFileItem = 0; + currentFileItem = nullptr; 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 ((currentFileItem == 0 && directoryStack.isEmpty()) || loaderView->wasCancelled() || abortLoading) { + if ((currentFileItem == nullptr && directoryStack.isEmpty()) || loaderView->wasCancelled() || abortLoading) { if (searchFileSystem) delete searchFileSystem; - searchFileSystem = 0; - currentFileItem = 0; + searchFileSystem = nullptr; + currentFileItem = nullptr; 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 (currentFileItem == 0) { + if (currentFileItem == nullptr) { 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 (!searchFileSystem->scanDir(url)) break; fileItems = searchFileSystem->fileItems(); dirNum++; currentFileItem = fileItems.isEmpty() ? 0 : fileItems.takeFirst(); } else { fileNum++; - File *newItem = 0; + File *newItem = nullptr; QString mime = currentFileItem->getMime(); // fast == not using mimetype magic 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 + '/') + currentFileItem->getName()); parentStack.push(dynamic_cast(newItem)); } else { newItem = new File(currentParent, currentFileItem->getName(), dirToCheck, currentFileItem->getSize(), currentFileItem->getMode(), currentFileItem->getOwner(), currentFileItem->getGroup(), currentFileItem->getPerm(), currentFileItem->getTime_t(), currentFileItem->isSymLink(), mime); currentSize += currentFileItem->getSize(); } currentParent->append(newItem); 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) + if (currentDirectory != nullptr) { + if (currentDirectory->parent() != nullptr) 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 nullptr; return contentMap[ dir ]; } -File * DiskUsage::getFile(QString path) +File * DiskUsage::getFile(const 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; + if (dirEntry == nullptr) + return nullptr; for (Iterator it = dirEntry->iterator(); it != dirEntry->end(); ++it) if ((*it)->name() == file) return *it; - return 0; + return nullptr; } 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; + root = currentDirectory = nullptr; } int DiskUsage::calculateSizes(Directory *dirEntry, bool emitSig, int depth) { int changeNr = 0; - if (dirEntry == 0) + if (dirEntry == nullptr) 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); + auto *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) + if (dir == nullptr) 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); + auto *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()) { + for (const Directory *d = (Directory*)file; d != root && d && d->parent() != nullptr; 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) +void * DiskUsage::getProperty(File *item, const QString& key) { QHash< File *, Properties *>::iterator itr = propertyMap.find(item); if (itr == propertyMap.end()) - return 0; + return nullptr; QHash::iterator it = (*itr)->find(key); if (it == (*itr)->end()) - return 0; + return nullptr; return it.value(); } -void DiskUsage::addProperty(File *item, QString key, void * prop) +void DiskUsage::addProperty(File *item, const 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) +void DiskUsage::removeProperty(File *item, const 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) + if (dirEntry == nullptr) 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) +void DiskUsage::rightClickMenu(const QPoint & pos, File *fileItem, QMenu *addPopup, const QString& addPopupName) { QMenu popup(this); popup.setTitle(i18n("Disk Usage")); QHash actionHash; - if (fileItem != 0) { + if (fileItem != nullptr) { 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) { + if (addPopup != nullptr) { 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; } break; case Qt::Key_D: if (e->modifiers() == Qt::ControlModifier) { executeAction(DETAILED_VIEW_ID); return; } break; case Qt::Key_F: if (e->modifiers() == Qt::ControlModifier) { executeAction(FILELIGHT_VIEW_ID); return; } break; 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; } break; 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; } break; 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 DiskUsage::getIcon(const 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 = FileListIcon("file-broken").pixmap(); else { QMimeDatabase db; QMimeType mt = db.mimeTypeForName(mime); if (mt.isValid()) icon = FileListIcon(mt.iconName()).pixmap(); else icon = FileListIcon("file-broken").pixmap(); } // 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) + if (dirEntry == nullptr) 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; + File * file = nullptr; 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; + auto* 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 14e1b279..3e7696db 100644 --- a/krusader/DiskUsage/diskusage.h +++ b/krusader/DiskUsage/diskusage.h @@ -1,209 +1,209 @@ /***************************************************************************** * Copyright (C) 2004 Csaba Karai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef DISKUSAGE_H #define DISKUSAGE_H // QtCore #include #include #include #include #include // QtGui #include #include #include // QtWidgets #include #include #include #include #include #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 FileItem; class FileSystem; class DiskUsage : public QStackedWidget { Q_OBJECT public: explicit 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); + File * getFile(const QString& path); QString getConfigGroup() { return configGroup; } - void * getProperty(File *, QString); - void addProperty(File *, QString, void *); - void removeProperty(File *, QString); + void * getProperty(File *, const QString&); + void addProperty(File *, const QString&, void *); + void removeProperty(File *, const 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 rightClickMenu(const QPoint &, File *, QMenu * = 0, const QString& = QString()); void changeDirectory(Directory *dir); Directory* getCurrentDir(); File* getCurrentFile(); - QPixmap getIcon(QString mime); + QPixmap getIcon(const 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; 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: explicit 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 36ba3bc8..9a38de44 100644 --- a/krusader/DiskUsage/diskusagegui.cpp +++ b/krusader/DiskUsage/diskusagegui.cpp @@ -1,242 +1,242 @@ /***************************************************************************** * Copyright (C) 2004 Csaba Karai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "diskusagegui.h" // QtCore #include // QtGui #include // QtWidgets #include #include #include #include #include #include #include "../krglobal.h" #include "../icon.h" #include "../FileSystem/filesystem.h" #include "../Dialogs/krdialogs.h" DiskUsageGUI::DiskUsageGUI(const QUrl &openDir) : QDialog(nullptr), exitAtFailure(true) { setWindowTitle(i18n("Krusader::Disk Usage")); setAttribute(Qt::WA_DeleteOnClose); baseDirectory = openDir; - QVBoxLayout *mainLayout = new QVBoxLayout; + auto *mainLayout = new QVBoxLayout; setLayout(mainLayout); - QGridLayout *duGrid = new QGridLayout(); + auto *duGrid = new QGridLayout(); duGrid->setSpacing(6); duGrid->setContentsMargins(11, 11, 11, 11); QWidget *duTools = new QWidget(this); - QHBoxLayout *duHBox = new QHBoxLayout(duTools); + auto *duHBox = new QHBoxLayout(duTools); duHBox->setContentsMargins(0, 0, 0, 0); duTools->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); btnNewSearch = new QToolButton(duTools); btnNewSearch->setIcon(Icon("document-open")); duHBox->addWidget(btnNewSearch); btnNewSearch->setToolTip(i18n("Start new disk usage search")); btnRefresh = new QToolButton(duTools); btnRefresh->setIcon(Icon("view-refresh")); duHBox->addWidget(btnRefresh); btnRefresh->setToolTip(i18n("Refresh")); btnDirUp = new QToolButton(duTools); btnDirUp->setIcon(Icon("go-up")); 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(Icon("view-list-details")); btnLines->setCheckable(true); duHBox->addWidget(btnLines); btnLines->setToolTip(i18n("Line view")); btnDetailed = new QToolButton(duTools); btnDetailed->setIcon(Icon("view-list-tree")); btnDetailed->setCheckable(true); duHBox->addWidget(btnDetailed); btnDetailed->setToolTip(i18n("Detailed view")); btnFilelight = new QToolButton(duTools); btnFilelight->setIcon(Icon("kr_diskusage")); 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); + auto *hboxlayout = new QHBoxLayout(spacerWidget); + auto* 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, &QDialogButtonBox::rejected, this, &DiskUsageGUI::close); connect(diskUsage, &DiskUsage::status, this, &DiskUsageGUI::slotStatus); connect(diskUsage, &DiskUsage::viewChanged, this, &DiskUsageGUI::slotViewChanged); connect(diskUsage, &DiskUsage::newSearch, this, &DiskUsageGUI::askDir); connect(diskUsage, &DiskUsage::loadFinished, this, &DiskUsageGUI::slotLoadFinished); connect(btnNewSearch, &QToolButton::clicked, this, &DiskUsageGUI::askDir); connect(btnRefresh, &QToolButton::clicked, this, &DiskUsageGUI::slotLoadUsageInfo); connect(btnDirUp, &QToolButton::clicked, diskUsage, &DiskUsage::dirUp); connect(btnLines, &QToolButton::clicked, this, &DiskUsageGUI::slotSelectLinesView); connect(btnDetailed, &QToolButton::clicked, this, &DiskUsageGUI::slotSelectListView); connect(btnFilelight, &QToolButton::clicked, this, &DiskUsageGUI::slotSelectFilelightView); 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)) { setWindowState(windowState() | Qt::WindowMaximized); } } void DiskUsageGUI::askDirAndShow() { if (askDir()) { show(); } } void DiskUsageGUI::slotLoadFinished(bool result) { if (exitAtFailure && !result) { close(); } 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::closeEvent(QCloseEvent *event) { KConfigGroup group(krConfig, "DiskUsage"); group.writeEntry("Window Width", sizeX); group.writeEntry("Window Height", sizeY); group.writeEntry("Window Maximized", isMaximized()); group.writeEntry("View", diskUsage->getActiveView()); event->accept(); } void DiskUsageGUI::slotLoadUsageInfo() { diskUsage->load(baseDirectory); } -void DiskUsageGUI::slotStatus(QString stat) +void DiskUsageGUI::slotStatus(const 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::askDir() { // ask the user for the copy destX const QUrl newDir = KChooseDir::getDir(i18n("Viewing the usage of folder:"), baseDirectory, baseDirectory); if (newDir.isEmpty()) return false; baseDirectory = newDir; QTimer::singleShot(0, this, &DiskUsageGUI::slotLoadUsageInfo); return true; } diff --git a/krusader/DiskUsage/diskusagegui.h b/krusader/DiskUsage/diskusagegui.h index 268f77e4..8313bc94 100644 --- a/krusader/DiskUsage/diskusagegui.h +++ b/krusader/DiskUsage/diskusagegui.h @@ -1,87 +1,87 @@ /***************************************************************************** * Copyright (C) 2004 Csaba Karai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef DISKUSAGEGUI_H #define DISKUSAGEGUI_H // QtCore #include // QtGui #include // QtWidgets #include #include #include #include #include "diskusage.h" class DiskUsageGUI : public QDialog { Q_OBJECT public: explicit DiskUsageGUI(const QUrl &openDir); - ~DiskUsageGUI() {} + ~DiskUsageGUI() override = default; void askDirAndShow(); protected slots: - virtual void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; + void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; protected: - virtual void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE; + void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE; private slots: bool askDir(); void slotLoadUsageInfo(); - void slotStatus(QString); + void slotStatus(const QString&); void slotSelectLinesView() { diskUsage->setView(VIEW_LINES); } void slotSelectListView() { diskUsage->setView(VIEW_DETAILED); } void slotSelectFilelightView() { diskUsage->setView(VIEW_FILELIGHT); } void slotViewChanged(int view); void slotLoadFinished(bool); private: void enableButtons(bool); DiskUsage *diskUsage; QUrl baseDirectory; KSqueezedTextLabel *status; QToolButton *btnNewSearch; QToolButton *btnRefresh; QToolButton *btnDirUp; QToolButton *btnLines; QToolButton *btnDetailed; QToolButton *btnFilelight; int sizeX; int sizeY; bool exitAtFailure; }; #endif /* __DISK_USAGE_GUI_H__ */ diff --git a/krusader/DiskUsage/dufilelight.cpp b/krusader/DiskUsage/dufilelight.cpp index 2aa18b36..249bf6b9 100644 --- a/krusader/DiskUsage/dufilelight.cpp +++ b/krusader/DiskUsage/dufilelight.cpp @@ -1,225 +1,225 @@ /***************************************************************************** * Copyright (C) 2004 Csaba Karai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "dufilelight.h" #include "radialMap/radialMap.h" // QtGui #include #include // QtWidgets #include #include #include #define SCHEME_POPUP_ID 6730 DUFilelight::DUFilelight(DiskUsage *usage) - : RadialMap::Widget(usage), diskUsage(usage), currentDir(0), refreshNeeded(true) + : RadialMap::Widget(usage), diskUsage(usage), currentDir(nullptr), refreshNeeded(true) { // setFocusPolicy(Qt::StrongFocus); connect(diskUsage, &DiskUsage::enteringDirectory, this, &DUFilelight::slotDirChanged); connect(diskUsage, &DiskUsage::clearing, this, &DUFilelight::clear); connect(diskUsage, &DiskUsage::changed, this, &DUFilelight::slotChanged); connect(diskUsage, &DiskUsage::deleted, this, &DUFilelight::slotChanged); connect(diskUsage, &DiskUsage::changeFinished, this, &DUFilelight::slotRefresh); connect(diskUsage, &DiskUsage::deleteFinished, this, &DUFilelight::slotRefresh); connect(diskUsage, &DiskUsage::currentChanged, this, &DUFilelight::slotAboutToShow); } void DUFilelight::slotDirChanged(Directory *dir) { if (diskUsage->currentWidget() != this) return; if (currentDir != dir) { currentDir = dir; invalidate(false); create(dir); refreshNeeded = false; } } void DUFilelight::clear() { invalidate(false); - currentDir = 0; + currentDir = nullptr; } File * DUFilelight::getCurrentFile() { const RadialMap::Segment * focus = focusSegment(); if (!focus || focus->isFake() || focus->file() == currentDir) - return 0; + return nullptr; return (File *)focus->file(); } void DUFilelight::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::RightButton) { - File * file = 0; + File * file = nullptr; const RadialMap::Segment * focus = focusSegment(); if (focus && !focus->isFake() && focus->file() != currentDir) file = (File *)focus->file(); QMenu filelightPopup; filelightPopup.addAction(i18n("Zoom In"), this, SLOT(zoomIn()), Qt::Key_Plus); filelightPopup.addAction(i18n("Zoom Out"), this, SLOT(zoomOut()), Qt::Key_Minus); QMenu schemePopup; schemePopup.addAction(i18n("Rainbow"), this, SLOT(schemeRainbow())); schemePopup.addAction(i18n("High Contrast"), this, SLOT(schemeHighContrast())); schemePopup.addAction(i18n("KDE"), this, SLOT(schemeKDE())); filelightPopup.addMenu(&schemePopup); schemePopup.setTitle(i18n("Scheme")); filelightPopup.addAction(i18n("Increase contrast"), this, SLOT(increaseContrast())); filelightPopup.addAction(i18n("Decrease contrast"), this, SLOT(decreaseContrast())); QAction * act = filelightPopup.addAction(i18n("Use anti-aliasing"), this, SLOT(changeAntiAlias())); act->setCheckable(true); act->setChecked(Filelight::Config::antiAliasFactor > 1); act = filelightPopup.addAction(i18n("Show small files"), this, SLOT(showSmallFiles())); act->setCheckable(true); act->setChecked(Filelight::Config::showSmallFiles); act = filelightPopup.addAction(i18n("Vary label font sizes"), this, SLOT(varyLabelFontSizes())); act->setCheckable(true); act->setChecked(Filelight::Config::varyLabelFontSizes); filelightPopup.addAction(i18n("Minimum font size"), this, SLOT(minFontSize())); diskUsage->rightClickMenu(event->globalPos(), file, &filelightPopup, i18n("Filelight")); return; } else if (event->button() == Qt::LeftButton) { const RadialMap::Segment * focus = focusSegment(); if (focus && !focus->isFake() && focus->file() == currentDir) { diskUsage->dirUp(); return; } else if (focus && !focus->isFake() && focus->file()->isDir()) { diskUsage->changeDirectory((Directory *)focus->file()); return; } } RadialMap::Widget::mousePressEvent(event); } void DUFilelight::setScheme(Filelight::MapScheme scheme) { Filelight::Config::scheme = scheme; Filelight::Config::write(); slotRefresh(); } void DUFilelight::increaseContrast() { if ((Filelight::Config::contrast += 10) > 100) Filelight::Config::contrast = 100; Filelight::Config::write(); slotRefresh(); } void DUFilelight::decreaseContrast() { if ((Filelight::Config::contrast -= 10) > 100) Filelight::Config::contrast = 0; Filelight::Config::write(); slotRefresh(); } void DUFilelight::changeAntiAlias() { Filelight::Config::antiAliasFactor = 1 + (Filelight::Config::antiAliasFactor == 1); Filelight::Config::write(); slotRefresh(); } void DUFilelight::showSmallFiles() { Filelight::Config::showSmallFiles = !Filelight::Config::showSmallFiles; Filelight::Config::write(); slotRefresh(); } void DUFilelight::varyLabelFontSizes() { Filelight::Config::varyLabelFontSizes = !Filelight::Config::varyLabelFontSizes; Filelight::Config::write(); slotRefresh(); } void DUFilelight::minFontSize() { bool ok = false; int result = QInputDialog::getInt(this, i18n("Krusader::Filelight"), i18n("Minimum font size"), (int)Filelight::Config::minFontPitch, 1, 100, 1, &ok); if (ok) { Filelight::Config::minFontPitch = (uint)result; Filelight::Config::write(); slotRefresh(); } } void DUFilelight::slotAboutToShow(int ndx) { QWidget *widget = diskUsage->widget(ndx); if (widget == this && (diskUsage->getCurrentDir() != currentDir || refreshNeeded)) { refreshNeeded = false; - if ((currentDir = diskUsage->getCurrentDir()) != 0) { + if ((currentDir = diskUsage->getCurrentDir()) != nullptr) { invalidate(false); create(currentDir); } } } void DUFilelight::slotRefresh() { if (diskUsage->currentWidget() != this) return; refreshNeeded = false; if (currentDir && currentDir == diskUsage->getCurrentDir()) { invalidate(false); create(currentDir); } } void DUFilelight::slotChanged(File *) { if (!refreshNeeded) refreshNeeded = true; } diff --git a/krusader/DiskUsage/dufilelight.h b/krusader/DiskUsage/dufilelight.h index c3cb7068..bc5eef0c 100644 --- a/krusader/DiskUsage/dufilelight.h +++ b/krusader/DiskUsage/dufilelight.h @@ -1,79 +1,79 @@ /***************************************************************************** * Copyright (C) 2004 Csaba Karai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef DUFILELIGHT_H #define DUFILELIGHT_H // QtGui #include #include "diskusage.h" #include "radialMap/widget.h" #include "filelightParts/Config.h" class DUFilelight : public RadialMap::Widget { Q_OBJECT public: explicit DUFilelight(DiskUsage *usage); File * getCurrentFile(); public slots: void slotDirChanged(Directory *); void clear(); void slotChanged(File *); void slotRefresh(); protected slots: void slotAboutToShow(int); void schemeRainbow() { setScheme(Filelight::Rainbow); } void schemeHighContrast() { setScheme(Filelight::HighContrast); } void schemeKDE() { setScheme(Filelight::KDE); } void increaseContrast(); void decreaseContrast(); void changeAntiAlias(); void showSmallFiles(); void varyLabelFontSizes(); void minFontSize(); protected: - virtual void mousePressEvent(QMouseEvent*) Q_DECL_OVERRIDE; + void mousePressEvent(QMouseEvent*) Q_DECL_OVERRIDE; void setScheme(Filelight::MapScheme); DiskUsage *diskUsage; Directory *currentDir; private: bool refreshNeeded; }; #endif /* __DU_FILELIGHT_H__ */ diff --git a/krusader/DiskUsage/dulines.cpp b/krusader/DiskUsage/dulines.cpp index 62e80978..b40b2f70 100644 --- a/krusader/DiskUsage/dulines.cpp +++ b/krusader/DiskUsage/dulines.cpp @@ -1,534 +1,534 @@ /***************************************************************************** * Copyright (C) 2004 Csaba Karai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "dulines.h" #include "../icon.h" #include "../krglobal.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: - explicit DULinesItemDelegate(QObject *parent = 0) : QItemDelegate(parent) {} + explicit DULinesItemDelegate(QObject *parent = nullptr) : QItemDelegate(parent) {} - virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE { + 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), + DULinesItem(DiskUsage *diskUsageIn, File *fileItem, QTreeWidget * parent, const QString& label1, + const QString& label2, const 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), + const QString& label1, const QString& label2, const 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 { + 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) + const auto *compWith = dynamic_cast< const DULinesItem * >(&other); + if (compWith == nullptr) 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, &DiskUsage::enteringDirectory, this, &DULines::slotDirChanged); connect(diskUsage, &DiskUsage::clearing, this, &DULines::clear); connect(header(), &QHeaderView::sectionResized, this, &DULines::sectionResized); connect(this, &DULines::itemRightClicked, this, &DULines::slotRightClicked); connect(diskUsage, &DiskUsage::changed, this, &DULines::slotChanged); connect(diskUsage, &DiskUsage::deleted, this, &DULines::slotDeleted); 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); + auto *he = dynamic_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; + QTreeWidgetItem * lastItem = nullptr; - if (!(dirEntry->parent() == 0)) { + if (!(dirEntry->parent() == nullptr)) { lastItem = new QTreeWidgetItem(this); lastItem->setText(0, ".."); lastItem->setIcon(0, Icon("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) + if (lastItem == nullptr) 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) + if (currentDir == nullptr) 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); + auto *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(); + auto *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; + File * file = nullptr; 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; + if (item == nullptr || item->text(0) == "..") + return nullptr; 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); + auto *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, &DULines::slotRefresh); } break; } } } } void DULines::slotDeleted(File * item) { QTreeWidgetItemIterator it(this); while (*it) { QTreeWidgetItem *lvitem = *it; it++; if (lvitem->text(0) != "..") { - DULinesItem *duItem = (DULinesItem *)(lvitem); + auto *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/dulines.h b/krusader/DiskUsage/dulines.h index f5df71e8..73440996 100644 --- a/krusader/DiskUsage/dulines.h +++ b/krusader/DiskUsage/dulines.h @@ -1,78 +1,78 @@ /***************************************************************************** * Copyright (C) 2004 Csaba Karai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef DULINES_H #define DULINES_H // QtGui #include #include #include #include #include "diskusage.h" #include "../GUI/krtreewidget.h" class DULinesToolTip; class DULinesItemDelegate; class DULines : public KrTreeWidget { Q_OBJECT public: explicit DULines(DiskUsage *usage); - ~DULines(); + ~DULines() override; File * getCurrentFile(); public slots: void slotDirChanged(Directory *dirEntry); void sectionResized(int); void slotRightClicked(QTreeWidgetItem *, const QPoint &); void slotChanged(File *); void slotDeleted(File *); void slotShowFileSizes(); void slotRefresh(); protected: DiskUsage *diskUsage; - virtual bool event(QEvent * event) Q_DECL_OVERRIDE; - virtual void mouseDoubleClickEvent(QMouseEvent * e) Q_DECL_OVERRIDE; - virtual void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; - virtual void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE; + bool event(QEvent * event) Q_DECL_OVERRIDE; + void mouseDoubleClickEvent(QMouseEvent * e) Q_DECL_OVERRIDE; + void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; + void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE; private: QPixmap createPixmap(int percent, int maxPercent, int maxWidth); bool doubleClicked(QTreeWidgetItem * item); bool refreshNeeded; bool started; bool showFileSize; DULinesToolTip *toolTip; DULinesItemDelegate *itemDelegate; }; #endif /* __DU_LINES_H__ */ diff --git a/krusader/DiskUsage/dulistview.cpp b/krusader/DiskUsage/dulistview.cpp index f1dd37a5..b779969f 100644 --- a/krusader/DiskUsage/dulistview.cpp +++ b/krusader/DiskUsage/dulistview.cpp @@ -1,271 +1,271 @@ /***************************************************************************** * Copyright (C) 2004 Csaba Karai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "dulistview.h" #include "../krglobal.h" #include "../icon.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, &DiskUsage::enteringDirectory, this, &DUListView::slotDirChanged); connect(diskUsage, &DiskUsage::clearing, this, &DUListView::clear); connect(diskUsage, &DiskUsage::changed, this, &DUListView::slotChanged); connect(diskUsage, &DiskUsage::deleted, this, &DUListView::slotDeleted); connect(this, &DUListView::itemRightClicked, this, &DUListView::slotRightClicked); connect(this, &DUListView::itemExpanded, this, &DUListView::slotExpanded); } DUListView::~ DUListView() { KConfigGroup group(krConfig, diskUsage->getConfigGroup()); group.writeEntry("D State", header()->saveState()); } void DUListView::addDirectory(Directory *dirEntry, QTreeWidgetItem *parent) { - QTreeWidgetItem * lastItem = 0; + QTreeWidgetItem * lastItem = nullptr; - if (parent == 0 && !(dirEntry->parent() == 0)) { + if (parent == nullptr && !(dirEntry->parent() == nullptr)) { lastItem = new QTreeWidgetItem(this); lastItem->setText(0, ".."); lastItem->setIcon(0, Icon("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) + if (lastItem == nullptr && parent == nullptr) lastItem = new DUListViewItem(diskUsage, item, this, item->name(), percent, totalSize, ownSize, mime, date, item->perm(), item->owner(), item->group()); - else if (lastItem == 0) + else if (lastItem == nullptr) lastItem = new DUListViewItem(diskUsage, item, parent, item->name(), percent, totalSize, ownSize, mime, date, item->perm(), item->owner(), item->group()); - else if (parent == 0) + else if (parent == nullptr) 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); + addDirectory(dirEntry, nullptr); } File * DUListView::getCurrentFile() { QTreeWidgetItem *item = currentItem(); - if (item == 0 || item->text(0) == "..") - return 0; + if (item == nullptr || item->text(0) == "..") + return nullptr; return ((DUListViewItem *)item)->getFile(); } void DUListView::slotChanged(File * item) { void * itemPtr = diskUsage->getProperty(item, "ListView-Ref"); - if (itemPtr == 0) + if (itemPtr == nullptr) return; - DUListViewItem *duItem = (DUListViewItem *)itemPtr; + auto *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) + if (itemPtr == nullptr) return; - DUListViewItem *duItem = (DUListViewItem *)itemPtr; + auto *duItem = (DUListViewItem *)itemPtr; delete duItem; } void DUListView::slotRightClicked(QTreeWidgetItem *item, const QPoint & pos) { - File * file = 0; + File * file = nullptr; 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(); + auto *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) == "..") + if (item == nullptr || 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/DiskUsage/dulistview.h b/krusader/DiskUsage/dulistview.h index 16691a6e..60c6cd2f 100644 --- a/krusader/DiskUsage/dulistview.h +++ b/krusader/DiskUsage/dulistview.h @@ -1,184 +1,184 @@ /***************************************************************************** * Copyright (C) 2004 Csaba Karai * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #ifndef DULISTVIEW_H #define DULISTVIEW_H // QtGui #include #include #include "../GUI/krtreewidget.h" #include "diskusage.h" class DUListViewItem : public QTreeWidgetItem { public: - DUListViewItem(DiskUsage *diskUsageIn, File *fileIn, QTreeWidget * parent, QString label1, - QString label2, QString label3, QString label4, QString label5, QString label6, - QString label7, QString label8, QString label9) + DUListViewItem(DiskUsage *diskUsageIn, File *fileIn, QTreeWidget * parent, const QString& label1, + const QString& label2, const QString& label3, const QString& label4, const QString& label5, const QString& label6, + const QString& label7, const QString& label8, const QString& label9) : QTreeWidgetItem(parent), diskUsage(diskUsageIn), file(fileIn) { setText(0, label1); setText(1, label2); setText(2, label3); setText(3, label4); setText(4, label5); setText(5, label6); setText(6, label7); setText(7, label8); setText(8, label9); setTextAlignment(1, Qt::AlignRight); setTextAlignment(2, Qt::AlignRight); setTextAlignment(3, Qt::AlignRight); setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless); diskUsage->addProperty(file, "ListView-Ref", this); } - DUListViewItem(DiskUsage *diskUsageIn, File *fileIn, QTreeWidgetItem * parent, QString label1, - QString label2, QString label3, QString label4, QString label5, QString label6, - QString label7, QString label8, QString label9) + DUListViewItem(DiskUsage *diskUsageIn, File *fileIn, QTreeWidgetItem * parent, const QString& label1, + const QString& label2, const QString& label3, const QString& label4, const QString& label5, const QString& label6, + const QString& label7, const QString& label8, const QString& label9) : QTreeWidgetItem(parent), diskUsage(diskUsageIn), file(fileIn) { setText(0, label1); setText(1, label2); setText(2, label3); setText(3, label4); setText(4, label5); setText(5, label6); setText(6, label7); setText(7, label8); setText(8, label9); setTextAlignment(1, Qt::AlignRight); setTextAlignment(2, Qt::AlignRight); setTextAlignment(3, Qt::AlignRight); setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless); diskUsage->addProperty(file, "ListView-Ref", this); } DUListViewItem(DiskUsage *diskUsageIn, File *fileIn, QTreeWidget * parent, QTreeWidgetItem * after, - QString label1, QString label2, QString label3, QString label4, QString label5, - QString label6, QString label7, QString label8, QString label9) + const QString& label1, const QString& label2, const QString& label3, const QString& label4, const QString& label5, + const QString& label6, const QString& label7, const QString& label8, const QString& label9) : QTreeWidgetItem(parent, after), diskUsage(diskUsageIn), file(fileIn) { setText(0, label1); setText(1, label2); setText(2, label3); setText(3, label4); setText(4, label5); setText(5, label6); setText(6, label7); setText(7, label8); setText(8, label9); setTextAlignment(1, Qt::AlignRight); setTextAlignment(2, Qt::AlignRight); setTextAlignment(3, Qt::AlignRight); setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless); diskUsage->addProperty(file, "ListView-Ref", this); } DUListViewItem(DiskUsage *diskUsageIn, File *fileIn, QTreeWidgetItem * parent, QTreeWidgetItem * after, - QString label1, QString label2, QString label3, QString label4, QString label5, - QString label6, QString label7, QString label8, QString label9) + const QString& label1, const QString& label2, const QString& label3, const QString& label4, const QString& label5, + const QString& label6, const QString& label7, const QString& label8, const QString& label9) : QTreeWidgetItem(parent, after), diskUsage(diskUsageIn), file(fileIn) { setText(0, label1); setText(1, label2); setText(2, label3); setText(3, label4); setText(4, label5); setText(5, label6); setText(6, label7); setText(7, label8); setText(8, label9); setTextAlignment(1, Qt::AlignRight); setTextAlignment(2, Qt::AlignRight); setTextAlignment(3, Qt::AlignRight); setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless); diskUsage->addProperty(file, "ListView-Ref", this); } - ~DUListViewItem() { + ~DUListViewItem() override { diskUsage->removeProperty(file, "ListView-Ref"); } - virtual bool operator<(const QTreeWidgetItem &other) const Q_DECL_OVERRIDE { + bool operator<(const QTreeWidgetItem &other) const Q_DECL_OVERRIDE { int column = treeWidget() ? treeWidget()->sortColumn() : 0; if (text(0) == "..") return true; - const DUListViewItem *compWith = dynamic_cast< const DUListViewItem * >(&other); - if (compWith == 0) + const auto *compWith = dynamic_cast< const DUListViewItem * >(&other); + if (compWith == nullptr) return false; switch (column) { case 1: case 2: return file->size() > compWith->file->size(); case 3: return file->ownSize() > compWith->file->ownSize(); case 5: return file->time() < compWith->file->time(); default: return text(column) < other.text(column); } } inline File * getFile() { return file; } private: DiskUsage *diskUsage; File *file; }; class DUListView : public KrTreeWidget { Q_OBJECT public: explicit DUListView(DiskUsage *usage); - ~DUListView(); + ~DUListView() override; File * getCurrentFile(); public slots: void slotDirChanged(Directory *); void slotChanged(File *); void slotDeleted(File *); void slotRightClicked(QTreeWidgetItem *, const QPoint &); void slotExpanded(QTreeWidgetItem *); protected: DiskUsage *diskUsage; - virtual void mouseDoubleClickEvent(QMouseEvent * e) Q_DECL_OVERRIDE; - virtual void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; + void mouseDoubleClickEvent(QMouseEvent * e) Q_DECL_OVERRIDE; + void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; private: void addDirectory(Directory *dirEntry, QTreeWidgetItem *parent); bool doubleClicked(QTreeWidgetItem * item); }; #endif /* __DU_LISTVIEW_H__ */ diff --git a/krusader/DiskUsage/filelightParts/fileTree.cpp b/krusader/DiskUsage/filelightParts/fileTree.cpp index 0cc03e52..36934814 100644 --- a/krusader/DiskUsage/filelightParts/fileTree.cpp +++ b/krusader/DiskUsage/filelightParts/fileTree.cpp @@ -1,91 +1,91 @@ /***************************************************************************** * Copyright (C) 2004 Max Howell * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "fileTree.h" // QtCore #include #include //static definitions const FileSize File::DENOMINATOR[4] = { 1ull, 1ull << 10, 1ull << 20, 1ull << 30 }; const char File::PREFIX[5][2] = { "", "K", "M", "G", "T" }; QString File::fullPath(const Directory *root /*= 0*/) const { QString path; - if (root == this) root = 0; //prevent returning empty string when there is something we could return + if (root == this) root = nullptr; //prevent returning empty string when there is something we could return const File *d; - for (d = this; d != root && d && d->parent() != 0; d = d->parent()) { + for (d = this; d != root && d && d->parent() != nullptr; d = d->parent()) { if (!path.isEmpty()) path = '/' + path; path = d->name() + path; } if (d) { while (d->parent()) d = d->parent(); if (d->directory().endsWith('/')) return d->directory() + path; else return d->directory() + '/' + path; } else return path; } QString File::humanReadableSize(UnitPrefix key /*= mega*/) const //FIXME inline { return humanReadableSize(m_size, key); } QString File::humanReadableSize(FileSize size, UnitPrefix key /*= mega*/) //static { QString s; double prettySize = (double)size / (double)DENOMINATOR[key]; const QLocale locale; if (prettySize >= 0.01) { if (prettySize < 1) s = locale.toString(prettySize, 'f', 2); else if (prettySize < 100) s = locale.toString(prettySize, 'f', 1); else s = locale.toString(prettySize, 'f', 0); s += ' '; s += PREFIX[key]; s += 'B'; } if (prettySize < 0.1) { s += " ("; s += locale.toString(size / DENOMINATOR[ key ? key - 1 : 0 ]); s += ' '; s += PREFIX[key]; s += "B)"; } return s; } diff --git a/krusader/DiskUsage/radialMap/builder.cpp b/krusader/DiskUsage/radialMap/builder.cpp index 983a73ef..a12ba42d 100644 --- a/krusader/DiskUsage/radialMap/builder.cpp +++ b/krusader/DiskUsage/radialMap/builder.cpp @@ -1,149 +1,149 @@ /***************************************************************************** * Copyright (C) 2003-2004 Max Howell * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "builder.h" #include "Config.h" #include "widget.h" // QtCore #include #include //**** REMOVE NEED FOR the +1 with MAX_RING_DEPTH uses //**** add some angle bounds checking (possibly in Segment ctor? can I delete in a ctor?) //**** this class is a mess RadialMap::Builder::Builder(RadialMap::Map *m, const Directory* const d, bool fast) : m_map(m) , m_root(d) , m_minSize(static_cast((d->size() * 3) / (PI * m->height() - m->MAP_2MARGIN))) , m_depth(&m->m_visibleDepth) { m_signature = new Chain [*m_depth + 1]; if (!fast) { //|| *m_depth == 0 ) //depth 0 is special case usability-wise //**** WHY?! //determine depth rather than use old one findVisibleDepth(d); //sets m_depth } m_map->setRingBreadth(); setLimits(m_map->m_ringBreadth); build(d); m_map->m_signature = m_signature; delete []m_limits; } void RadialMap::Builder::findVisibleDepth(const Directory* const dir, const unsigned int depth) { //**** because I don't use the same minimumSize criteria as in the visual function // this can lead to incorrect visual representation //**** BUT, you can't set those limits until you know m_depth! //**** also this function doesn't check to see if anything is actually visible // it just assumes that when it reaches a new level everything in it is visible // automatically. This isn't right especially as there might be no files in the // dir provided to this function! static uint stopDepth = 0; if (dir == m_root) { stopDepth = *m_depth; *m_depth = 0; } if (*m_depth < depth) *m_depth = depth; if (*m_depth >= stopDepth) return; for (ConstIterator it = dir->constIterator(); it != dir->end(); ++it) if ((*it)->isDir() && (*it)->size() > m_minSize) findVisibleDepth((Directory *)*it, depth + 1); //if no files greater than min size the depth is still recorded } void RadialMap::Builder::setLimits(const uint &b) //b = breadth? { double size3 = m_root->size() * 3; double pi2B = PI * 2 * b; m_limits = new FileSize [*m_depth + 1]; //FIXME delete! for (unsigned int d = 0; d <= *m_depth; ++d) m_limits[d] = (FileSize)(size3 / (double)(pi2B * (d + 1))); //min is angle that gives 3px outer diameter for that depth } //**** segments currently overlap at edges (i.e. end of first is start of next) bool RadialMap::Builder::build(const Directory* const dir, const unsigned int depth, unsigned int a_start, const unsigned int a_end) { //first iteration: dir == m_root if (dir->fileCount() == 0) //we do fileCount rather than size to avoid chance of divide by zero later return false; FileSize hiddenSize = 0; uint hiddenFileCount = 0; for (ConstIterator it = dir->constIterator(); it != dir->end(); ++it) { if ((*it)->size() > m_limits[depth]) { - unsigned int a_len = (unsigned int)(5760 * ((double)(*it)->size() / (double)m_root->size())); + auto a_len = (unsigned int)(5760 * ((double)(*it)->size() / (double)m_root->size())); - Segment *s = new Segment(*it, a_start, a_len); + auto *s = new Segment(*it, a_start, a_len); (m_signature + depth)->append(s); if ((*it)->isDir()) { if (depth != *m_depth) { //recurse s->m_hasHiddenChildren = build((Directory*) * it, depth + 1, a_start, a_start + a_len); } else s->m_hasHiddenChildren = true; } a_start += a_len; //**** should we add 1? } else { hiddenSize += (*it)->size(); if ((*it)->isDir()) //**** considered virtual, but dir wouldn't count itself! - hiddenFileCount += static_cast(*it)->fileCount(); //need to add one to count the dir as well + hiddenFileCount += dynamic_cast(*it)->fileCount(); //need to add one to count the dir as well ++hiddenFileCount; } } if (hiddenFileCount == dir->fileCount() && !Config::showSmallFiles) return true; else if ((Config::showSmallFiles && hiddenSize > m_limits[depth]) || (depth == 0 && (hiddenSize > dir->size() / 8)) /*|| > size() * 0.75*/) { //append a segment for unrepresented space - a "fake" segment const QString s = i18np("%1 file: ~ %2", "%1 files: ~ %2", QLocale().toString(hiddenFileCount), File::humanReadableSize(hiddenSize / hiddenFileCount)); (m_signature + depth)->append(new Segment(new File(s, hiddenSize), a_start, a_end - a_start, true)); } return false; } diff --git a/krusader/DiskUsage/radialMap/labels.cpp b/krusader/DiskUsage/radialMap/labels.cpp index 765e8a9e..fb1237bb 100644 --- a/krusader/DiskUsage/radialMap/labels.cpp +++ b/krusader/DiskUsage/radialMap/labels.cpp @@ -1,366 +1,366 @@ /***************************************************************************** * Copyright (C) 2003-2004 Max Howell * * Copyright (C) 2004-2018 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ // QtCore #include // QtGui #include #include #include #include #include "Config.h" #include "fileTree.h" #include "radialMap.h" #include "sincos.h" #include "widget.h" namespace RadialMap { struct Label { Label(const RadialMap::Segment *s, int l) : segment(s), lvl(l), a(segment->start() + (segment->length() / 2)) { } bool tooClose(const int &aa) const { return (a > aa - LABEL_ANGLE_MARGIN && a < aa + LABEL_ANGLE_MARGIN); } const RadialMap::Segment *segment; const unsigned int lvl; const int a; int x1, y1, x2, y2, x3; int tx, ty; QString qs; }; class LabelList : public QList