diff --git a/krusader/Dialogs/packguibase.cpp b/krusader/Dialogs/packguibase.cpp index f2049f4e..f7e67a75 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, SIGNAL(activated(QString)), this, SLOT(checkConsistency())); - connect(typeData, SIGNAL(highlighted(QString)), this, SLOT(checkConsistency())); + 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); 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); 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; compressLayout->setSpacing(6); compressLayout->setContentsMargins(0, 0, 0, 0); multipleVolume = new QCheckBox(i18n("Multiple volume archive"), advancedWidget); - connect(multipleVolume, SIGNAL(toggled(bool)), this, SLOT(checkConsistency())); + connect(multipleVolume, &QCheckBox::toggled, this, &PackGUIBase::checkConsistency); compressLayout->addWidget(multipleVolume, 0, 0); QHBoxLayout * volumeHbox = new QHBoxLayout; QSpacerItem* 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, SIGNAL(toggled(bool)), this, SLOT(checkConsistency())); + connect(setCompressionLevel, &QCheckBox::toggled, this, &PackGUIBase::checkConsistency); compressLayout->addWidget(setCompressionLevel, 0, 0); QHBoxLayout * sliderHbox = new QHBoxLayout; QSpacerItem* spacer_6 = new QSpacerItem(20, 26, QSizePolicy::Fixed, QSizePolicy::Fixed); sliderHbox->addItem(spacer_6); QWidget * sliderVBoxWidget = new QWidget(advancedWidget); QVBoxLayout *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); 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; 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, SIGNAL(textChanged(QString)), this, SLOT(checkConsistency())); + 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, SIGNAL(textChanged(QString)), this, SLOT(checkConsistency())); + connect(passwordAgain, &QLineEdit::textChanged, this, &PackGUIBase::checkConsistency); passwordGrid->addWidget(passwordAgain, 1, 1); QHBoxLayout *consistencyHbox = new QHBoxLayout; QSpacerItem* 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); 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); 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, SIGNAL(clicked()), this, SLOT(accept())); - connect(advancedButton, SIGNAL(clicked()), this, SLOT(expand())); - connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject())); - connect(browseButton, SIGNAL(clicked()), this, SLOT(browse())); + 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/percentalsplitter.cpp b/krusader/Dialogs/percentalsplitter.cpp index d17d80b0..ddd02434 100644 --- a/krusader/Dialogs/percentalsplitter.cpp +++ b/krusader/Dialogs/percentalsplitter.cpp @@ -1,83 +1,83 @@ /***************************************************************************** * 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) { - connect(this, SIGNAL(splitterMoved(int,int)), SLOT(slotSplitterMoved(int,int))); + connect(this, &PercentalSplitter::splitterMoved, this, &PercentalSplitter::slotSplitterMoved); } PercentalSplitter::~PercentalSplitter() { } 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); 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/popularurls.cpp b/krusader/Dialogs/popularurls.cpp index c39d8c60..7457b69d 100644 --- a/krusader/Dialogs/popularurls.cpp +++ b/krusader/Dialogs/popularurls.cpp @@ -1,375 +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) { 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; } 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; 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; 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; } else { node->next = 0; 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; setLayout(mainLayout); QGridLayout *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, SIGNAL(rejected()), this, SLOT(reject())); - connect(urls, SIGNAL(activated(QModelIndex)), - this, SLOT(slotItemSelected(QModelIndex))); - connect(search, SIGNAL(hiddenChanged(QTreeWidgetItem*,bool)), - this, SLOT(slotVisibilityChanged())); + 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); 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; for (it = list.begin(); it != list.end(); ++it) { QTreeWidgetItem *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/DiskUsage/diskusage.cpp b/krusader/DiskUsage/diskusage.cpp index fa5a3d57..95a2e66e 100644 --- a/krusader/DiskUsage/diskusage.cpp +++ b/krusader/DiskUsage/diskusage.cpp @@ -1,1133 +1,1133 @@ /***************************************************************************** * 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 "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); loaderLayout->setSpacing(0); loaderLayout->setContentsMargins(0, 0, 0, 0); QFrame *loaderBox = new QFrame(widget); loaderBox->setFrameShape(QFrame::Box); loaderBox->setFrameShadow(QFrame::Sunken); loaderBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); loaderBox->setFrameStyle(QFrame::Panel + QFrame::Raised); loaderBox->setLineWidth(2); QGridLayout *synchGrid = new QGridLayout(loaderBox); synchGrid->setSpacing(6); synchGrid->setContentsMargins(11, 11, 11, 11); QLabel *titleLabel = new QLabel(i18n("Loading Usage Information"), loaderBox); titleLabel->setAlignment(Qt::AlignHCenter); synchGrid->addWidget(titleLabel, 0, 0, 1, 2); QLabel *filesLabel = new QLabel(i18n("Files:"), loaderBox); filesLabel->setFrameShape(QLabel::StyledPanel); filesLabel->setFrameShadow(QLabel::Sunken); synchGrid->addWidget(filesLabel, 1, 0); QLabel *directoriesLabel = new QLabel(i18n("Directories:"), loaderBox); directoriesLabel->setFrameShape(QLabel::StyledPanel); directoriesLabel->setFrameShadow(QLabel::Sunken); synchGrid->addWidget(directoriesLabel, 2, 0); QLabel *totalSizeLabel = new QLabel(i18n("Total Size:"), loaderBox); totalSizeLabel->setFrameShape(QLabel::StyledPanel); totalSizeLabel->setFrameShadow(QLabel::Sunken); synchGrid->addWidget(totalSizeLabel, 3, 0); files = new QLabel(loaderBox); files->setFrameShape(QLabel::StyledPanel); files->setFrameShadow(QLabel::Sunken); files->setAlignment(Qt::AlignRight); synchGrid->addWidget(files, 1, 1); directories = new QLabel(loaderBox); directories->setFrameShape(QLabel::StyledPanel); directories->setFrameShadow(QLabel::Sunken); directories->setAlignment(Qt::AlignRight); synchGrid->addWidget(directories, 2, 1); totalSize = new QLabel(loaderBox); totalSize->setFrameShape(QLabel::StyledPanel); totalSize->setFrameShadow(QLabel::Sunken); totalSize->setAlignment(Qt::AlignRight); synchGrid->addWidget(totalSize, 3, 1); int width; searchedDirectory = new KSqueezedTextLabel(loaderBox); searchedDirectory->setFrameShape(QLabel::StyledPanel); searchedDirectory->setFrameShadow(QLabel::Sunken); searchedDirectory->setMinimumWidth(width = QFontMetrics(searchedDirectory->font()).width("W") * 30); searchedDirectory->setMaximumWidth(width); synchGrid->addWidget(searchedDirectory, 4, 0, 1, 2); QFrame *line = new QFrame(loaderBox); line->setFrameStyle(QFrame::HLine | QFrame::Sunken); synchGrid->addWidget(line, 5, 0, 1, 2); QWidget *hboxWidget = new QWidget(loaderBox); QHBoxLayout * hbox = new QHBoxLayout(hboxWidget); QSpacerItem* spacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding); hbox->addItem(spacer); QPushButton *cancelButton = new QPushButton(hboxWidget); KStandardGuiItem::assign(cancelButton, KStandardGuiItem::Cancel); hbox->addWidget(cancelButton); synchGrid->addWidget(hboxWidget, 6, 1); loaderLayout->addWidget(loaderBox, 0, 0); setWidget(widget); setAlignment(Qt::AlignCenter); - connect(cancelButton, SIGNAL(clicked()), this, SLOT(slotCancelled())); + 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) { listView = new DUListView(this); lineView = new DULines(this); filelightView = new DUFilelight(this); loaderView = new LoaderWidget(this); addWidget(listView); addWidget(lineView); addWidget(filelightView); addWidget(loaderView); setView(VIEW_LINES); Filelight::Config::read(); - connect(&loadingTimer, SIGNAL(timeout()), this, SLOT(slotLoadDirectory())); + 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 = FileSystemProvider::instance().getFilesystem(baseDir); if (searchFileSystem == 0) { qWarning() << "could not get filesystem for directory=" << baseDir; loading = abortLoading = clearAfterAbort = false; emit loadFinished(false); return; } currentFileItem = 0; if (!loading) { viewBeforeLoad = activeView; setView(VIEW_LOADER); } loading = true; loaderView->init(); loaderView->setCurrentURL(baseURL); loaderView->setValues(fileNum, dirNum, currentSize); loadingTimer.setSingleShot(true); loadingTimer.start(0); } void DiskUsage::slotLoadDirectory() { if ((currentFileItem == 0 && directoryStack.isEmpty()) || loaderView->wasCancelled() || abortLoading) { if (searchFileSystem) delete searchFileSystem; searchFileSystem = 0; currentFileItem = 0; setView(viewBeforeLoad); if (clearAfterAbort) clear(); else { calculateSizes(); changeDirectory(root); } emit loadFinished(!(loaderView->wasCancelled() || abortLoading)); loading = abortLoading = clearAfterAbort = false; } else if (loading) { for (int counter = 0; counter != MAX_FILENUM; counter ++) { if (currentFileItem == 0) { if (directoryStack.isEmpty()) break; dirToCheck = directoryStack.pop(); currentParent = parentStack.pop(); contentMap.insert(dirToCheck, currentParent); QUrl url = baseURL; if (!dirToCheck.isEmpty()) { url = url.adjusted(QUrl::StripTrailingSlash); url.setPath(url.path() + '/' + (dirToCheck)); } #ifdef BSD if (url.isLocalFile() && url.path().left(7) == "/procfs") break; #else if (url.isLocalFile() && url.path().left(5) == "/proc") break; #endif loaderView->setCurrentURL(url); if (!searchFileSystem->scanDir(url)) break; fileItems = searchFileSystem->fileItems(); dirNum++; currentFileItem = fileItems.isEmpty() ? 0 : fileItems.takeFirst(); } else { fileNum++; File *newItem = 0; 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) changeDirectory((Directory *)(currentDirectory->parent())); else { QUrl up = KIO::upUrl(baseURL); if (KMessageBox::questionYesNo(this, i18n("Stepping into the parent folder requires " "loading the content of the \"%1\" URL. Do you wish " "to continue?", up.toDisplayString(QUrl::PreferLocalFile)), i18n("Krusader::DiskUsage"), KStandardGuiItem::yes(), KStandardGuiItem::no(), "DiskUsageLoadParentDir" ) == KMessageBox::Yes) load(up); } } } Directory * DiskUsage::getDirectory(QString dir) { while (dir.endsWith('/')) dir.truncate(dir.length() - 1); if (dir.isEmpty()) return root; if (contentMap.find(dir) == contentMap.end()) return 0; return contentMap[ dir ]; } File * DiskUsage::getFile(QString path) { if (path.isEmpty()) return root; QString dir = path; int ndx = path.lastIndexOf('/'); QString file = path.mid(ndx + 1); if (ndx == -1) dir = ""; else dir.truncate(ndx); Directory *dirEntry = getDirectory(dir); if (dirEntry == 0) return 0; for (Iterator it = dirEntry->iterator(); it != dirEntry->end(); ++it) if ((*it)->name() == file) return *it; return 0; } void DiskUsage::clear() { baseURL = QUrl(); emit clearing(); QHashIterator< File *, Properties * > lit(propertyMap); while (lit.hasNext()) delete lit.next().value(); propertyMap.clear(); contentMap.clear(); if (root) delete root; root = currentDirectory = 0; } int DiskUsage::calculateSizes(Directory *dirEntry, bool emitSig, int depth) { int changeNr = 0; if (dirEntry == 0) dirEntry = root; KIO::filesize_t own = 0, total = 0; for (Iterator it = dirEntry->iterator(); it != dirEntry->end(); ++it) { File * item = *it; if (!item->isExcluded()) { if (item->isDir()) changeNr += calculateSizes(dynamic_cast(item), emitSig, depth + 1); else own += item->size(); total += item->size(); } } KIO::filesize_t oldOwn = dirEntry->ownSize(), oldTotal = dirEntry->size(); dirEntry->setSizes(total, own); if (dirEntry == currentDirectory) currentSize = total; if (emitSig && (own != oldOwn || total != oldTotal)) { emit changed(dirEntry); changeNr++; } if (depth == 0 && changeNr != 0) emit changeFinished(); return changeNr; } int DiskUsage::exclude(File *file, bool calcPercents, int depth) { int changeNr = 0; if (!file->isExcluded()) { file->exclude(true); emit changed(file); changeNr++; if (file->isDir()) { Directory *dir = dynamic_cast(file); for (Iterator it = dir->iterator(); it != dir->end(); ++it) changeNr += exclude(*it, false, depth + 1); } } if (calcPercents) { calculateSizes(root, true); calculatePercents(true); createStatus(); } if (depth == 0 && changeNr != 0) emit changeFinished(); return changeNr; } int DiskUsage::include(Directory *dir, int depth) { int changeNr = 0; if (dir == 0) return 0; for (Iterator it = dir->iterator(); it != dir->end(); ++it) { File *item = *it; if (item->isDir()) changeNr += include(dynamic_cast(item), depth + 1); if (item->isExcluded()) { item->exclude(false); emit changed(item); changeNr++; } } if (depth == 0 && changeNr != 0) emit changeFinished(); return changeNr; } void DiskUsage::includeAll() { include(root); calculateSizes(root, true); calculatePercents(true); createStatus(); } int DiskUsage::del(File *file, bool calcPercents, int depth) { int deleteNr = 0; if (file == root) return 0; KConfigGroup gg(krConfig, "General"); bool trash = gg.readEntry("Move To Trash", _MoveToTrash); QUrl url = QUrl::fromLocalFile(file->fullPath()); if (calcPercents) { // now ask the user if he want to delete: KConfigGroup ga(krConfig, "Advanced"); if (ga.readEntry("Confirm Delete", _ConfirmDelete)) { QString s; KGuiItem b; if (trash && url.isLocalFile()) { s = i18nc("singularOnly", "Do you really want to move this item to the trash?"); b = KGuiItem(i18n("&Trash")); } else { s = i18nc("singularOnly", "Do you really want to delete this item?"); b = KStandardGuiItem::del(); } QStringList name; name.append(file->fullPath()); // show message // note: i'm using continue and not yes/no because the yes/no has cancel as default button if (KMessageBox::warningContinueCancelList(krMainWindow, s, name, i18n("Warning"), b) != KMessageBox::Continue) return 0; } emit status(i18n("Deleting %1...", file->name())); } if (file == currentDirectory) dirUp(); if (file->isDir()) { Directory *dir = dynamic_cast(file); Iterator it; while ((it = dir->iterator()) != dir->end()) deleteNr += del(*it, false, depth + 1); QString path; for (const Directory *d = (Directory*)file; d != root && d && d->parent() != 0; d = d->parent()) { if (!path.isEmpty()) path = '/' + path; path = d->name() + path; } contentMap.remove(path); } emit deleted(file); deleteNr++; KIO::Job *job; if (trash) { job = KIO::trash(url); } else { job = KIO::del(QUrl::fromLocalFile(file->fullPath()), KIO::HideProgressInfo); } deleting = true; // during qApp->processEvent strange things can occur grabMouse(); // that's why we disable the mouse and keyboard events grabKeyboard(); job->exec(); delete job; releaseMouse(); releaseKeyboard(); deleting = false; ((Directory *)(file->parent()))->remove(file); delete file; if (depth == 0) createStatus(); if (calcPercents) { calculateSizes(root, true); calculatePercents(true); createStatus(); emit enteringDirectory(currentDirectory); } if (depth == 0 && deleteNr != 0) emit deleteFinished(); return deleteNr; } void * DiskUsage::getProperty(File *item, QString key) { QHash< File *, Properties *>::iterator itr = propertyMap.find(item); if (itr == propertyMap.end()) return 0; QHash::iterator it = (*itr)->find(key); if (it == (*itr)->end()) return 0; return it.value(); } void DiskUsage::addProperty(File *item, QString key, void * prop) { Properties *props; QHash< File *, Properties *>::iterator itr = propertyMap.find(item); if (itr == propertyMap.end()) { props = new Properties(); propertyMap.insert(item, props); } else props = *itr; props->insert(key, prop); } void DiskUsage::removeProperty(File *item, QString key) { QHash< File *, Properties *>::iterator itr = propertyMap.find(item); if (itr == propertyMap.end()) return; (*itr)->remove(key); if ((*itr)->count() == 0) propertyMap.remove(item); } void DiskUsage::createStatus() { Directory *dirEntry = currentDirectory; if (dirEntry == 0) return; QUrl url = baseURL; if (dirEntry != root) { url = url.adjusted(QUrl::StripTrailingSlash); url.setPath(url.path() + '/' + (dirEntry->directory())); } emit status(i18n("Current folder:%1, Total size:%2, Own size:%3", url.toDisplayString(QUrl::PreferLocalFile | QUrl::StripTrailingSlash), ' ' + KRpermHandler::parseSize(dirEntry->size()), ' ' + KRpermHandler::parseSize(dirEntry->ownSize()))); } void DiskUsage::changeDirectory(Directory *dir) { currentDirectory = dir; currentSize = dir->size(); calculatePercents(true, dir); createStatus(); emit enteringDirectory(dir); } Directory* DiskUsage::getCurrentDir() { return currentDirectory; } void DiskUsage::rightClickMenu(const QPoint & pos, File *fileItem, QMenu *addPopup, QString addPopupName) { QMenu popup(this); popup.setTitle(i18n("Disk Usage")); QHash actionHash; if (fileItem != 0) { QAction * actDelete = popup.addAction(i18n("Delete")); actionHash[ actDelete ] = DELETE_ID; actDelete->setShortcut(Qt::Key_Delete); QAction * actExclude = popup.addAction(i18n("Exclude")); actionHash[ actExclude ] = EXCLUDE_ID; actExclude->setShortcut(Qt::CTRL + Qt::Key_E); popup.addSeparator(); } QAction * myAct = popup.addAction(i18n("Up one folder")); actionHash[ myAct ] = PARENT_DIR_ID; myAct->setShortcut(Qt::SHIFT + Qt::Key_Up); myAct = popup.addAction(i18n("New search")); actionHash[ myAct ] = NEW_SEARCH_ID; myAct->setShortcut(Qt::CTRL + Qt::Key_N); myAct = popup.addAction(i18n("Refresh")); actionHash[ myAct ] = REFRESH_ID; myAct->setShortcut(Qt::CTRL + Qt::Key_R); myAct = popup.addAction(i18n("Include all")); actionHash[ myAct ] = INCLUDE_ALL_ID; myAct->setShortcut(Qt::CTRL + Qt::Key_I); myAct = popup.addAction(i18n("Step into")); actionHash[ myAct ] = STEP_INTO_ID; myAct->setShortcut(Qt::SHIFT + Qt::Key_Down); popup.addSeparator(); if (addPopup != 0) { QAction * menu = popup.addMenu(addPopup); menu->setText(addPopupName); } QMenu viewPopup; myAct = viewPopup.addAction(i18n("Lines")); actionHash[ myAct ] = LINES_VIEW_ID; myAct->setShortcut(Qt::CTRL + Qt::Key_L); myAct = viewPopup.addAction(i18n("Detailed")); actionHash[ myAct ] = DETAILED_VIEW_ID; myAct->setShortcut(Qt::CTRL + Qt::Key_D); myAct = viewPopup.addAction(i18n("Filelight")); actionHash[ myAct ] = FILELIGHT_VIEW_ID; myAct->setShortcut(Qt::CTRL + Qt::Key_F); viewPopup.addSeparator(); myAct = viewPopup.addAction(i18n("Next")); actionHash[ myAct ] = NEXT_VIEW_ID; myAct->setShortcut(Qt::SHIFT + Qt::Key_Right); myAct = viewPopup.addAction(i18n("Previous")); actionHash[ myAct ] = PREVIOUS_VIEW_ID; myAct->setShortcut(Qt::SHIFT + Qt::Key_Left); QAction * menu = popup.addMenu(&viewPopup); menu->setText(i18n("View")); QAction * res = popup.exec(pos); if (actionHash.contains(res)) executeAction(actionHash[ res ], fileItem); } void DiskUsage::executeAction(int action, File * fileItem) { // check out the user's option switch (action) { case DELETE_ID: if (fileItem) del(fileItem); break; case EXCLUDE_ID: if (fileItem) exclude(fileItem); break; case PARENT_DIR_ID: dirUp(); break; case NEW_SEARCH_ID: emit newSearch(); break; case REFRESH_ID: load(baseURL); break; case INCLUDE_ALL_ID: includeAll(); break; case STEP_INTO_ID: { QString uri; if (fileItem && fileItem->isDir()) uri = fileItem->fullPath(); else uri = currentDirectory->fullPath(); ACTIVE_FUNC->openUrl(QUrl::fromLocalFile(uri)); } break; case LINES_VIEW_ID: setView(VIEW_LINES); break; case DETAILED_VIEW_ID: setView(VIEW_DETAILED); break; case FILELIGHT_VIEW_ID: setView(VIEW_FILELIGHT); break; case NEXT_VIEW_ID: setView((activeView + 1) % 3); break; case PREVIOUS_VIEW_ID: setView((activeView + 2) % 3); break; } // currentWidget()->setFocus(); } void DiskUsage::keyPressEvent(QKeyEvent *e) { if (activeView != VIEW_LOADER) { switch (e->key()) { case Qt::Key_E: if (e->modifiers() == Qt::ControlModifier) { executeAction(EXCLUDE_ID, getCurrentFile()); return; } 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 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) dirEntry = root; for (Iterator it = dirEntry->iterator(); it != dirEntry->end(); ++it) { File *item = *it; if (!item->isExcluded()) { int newPerc; if (dirEntry->size() == 0 && item->size() == 0) newPerc = 0; else if (dirEntry->size() == 0) newPerc = -1; else newPerc = (int)((double)item->size() / (double)currentSize * 10000. + 0.5); int oldPerc = item->intPercent(); item->setPercent(newPerc); if (emitSig && newPerc != oldPerc) { emit changed(item); changeNr++; } if (item->isDir()) changeNr += calculatePercents(emitSig, dynamic_cast(item), depth + 1); } } if (depth == 0 && changeNr != 0) emit changeFinished(); return changeNr; } QString DiskUsage::getToolTip(File *item) { QMimeDatabase db; QMimeType mt = db.mimeTypeForName(item->mime()); QString mime; if (mt.isValid()) mime = mt.comment(); time_t tma = item->time(); struct tm* t = localtime((time_t *) & tma); QDateTime tmp(QDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday), QTime(t->tm_hour, t->tm_min)); QString date = QLocale().toString(tmp, QLocale::ShortFormat); QString str = "
" + "" + ""; if (item->isDir()) str += ""; str += "" + "" + "" + "
" + i18n("Name:") + "" + item->name() + "
" + i18n("Type:") + "" + mime + "
" + i18n("Size:") + "" + KRpermHandler::parseSize(item->size()) + "
" + i18n("Own size:") + "" + KRpermHandler::parseSize(item->ownSize()) + "
" + i18n("Last modified:") + "" + date + "
" + i18n("Permissions:") + "" + item->perm() + "
" + i18n("Owner:") + "" + item->owner() + " - " + item->group() + "
"; str.replace(' ', " "); return str; } void DiskUsage::setView(int view) { switch (view) { case VIEW_LINES: setCurrentWidget(lineView); break; case VIEW_DETAILED: setCurrentWidget(listView); break; case VIEW_FILELIGHT: setCurrentWidget(filelightView); break; case VIEW_LOADER: setCurrentWidget(loaderView); break; } // currentWidget()->setFocus(); emit viewChanged(activeView = view); } File * DiskUsage::getCurrentFile() { File * file = 0; switch (activeView) { case VIEW_LINES: file = lineView->getCurrentFile(); break; case VIEW_DETAILED: file = listView->getCurrentFile(); break; case VIEW_FILELIGHT: file = filelightView->getCurrentFile(); break; } return file; } bool DiskUsage::event(QEvent * e) { if (deleting) { // if we are deleting, disable the mouse and switch (e->type()) { // keyboard events case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: case QEvent::MouseButtonDblClick: case QEvent::MouseMove: case QEvent::KeyPress: case QEvent::KeyRelease: return true; default: break; } } if (e->type() == QEvent::ShortcutOverride) { QKeyEvent* ke = (QKeyEvent*) e; if (ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::KeypadModifier) { switch (ke->key()) { case Qt::Key_Delete: case Qt::Key_Plus: case Qt::Key_Minus: ke->accept(); break; } } else if (ke->modifiers() == Qt::ShiftModifier) { switch (ke->key()) { case Qt::Key_Left: case Qt::Key_Right: case Qt::Key_Up: case Qt::Key_Down: ke->accept(); break; } } else if (ke->modifiers() & Qt::ControlModifier) { switch (ke->key()) { case Qt::Key_D: case Qt::Key_E: case Qt::Key_F: case Qt::Key_I: case Qt::Key_L: case Qt::Key_N: case Qt::Key_R: ke->accept(); break; } } } return QStackedWidget::event(e); } diff --git a/krusader/DiskUsage/diskusagegui.cpp b/krusader/DiskUsage/diskusagegui.cpp index dc7e3756..306bc4d9 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; setLayout(mainLayout); QGridLayout *duGrid = new QGridLayout(); duGrid->setSpacing(6); duGrid->setContentsMargins(11, 11, 11, 11); QWidget *duTools = new QWidget(this); QHBoxLayout *duHBox = new QHBoxLayout(duTools); duHBox->setContentsMargins(0, 0, 0, 0); duTools->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); btnNewSearch = new QToolButton(duTools); btnNewSearch->setIcon(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); hboxlayout->addItem(spacer); duGrid->addWidget(duTools, 0, 0); diskUsage = new DiskUsage("DiskUsage", this); duGrid->addWidget(diskUsage, 1, 0); status = new KSqueezedTextLabel(this); duGrid->addWidget(status, 2, 0); mainLayout->addLayout(duGrid); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); mainLayout->addWidget(buttonBox); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(close())); - connect(diskUsage, SIGNAL(status(QString)), this, SLOT(slotStatus(QString))); - connect(diskUsage, SIGNAL(viewChanged(int)), this, SLOT(slotViewChanged(int))); - connect(diskUsage, SIGNAL(newSearch()), this, SLOT(askDir())); - connect(diskUsage, SIGNAL(loadFinished(bool)), this, SLOT(slotLoadFinished(bool))); - connect(btnNewSearch, SIGNAL(clicked()), this, SLOT(askDir())); - connect(btnRefresh, SIGNAL(clicked()), this, SLOT(slotLoadUsageInfo())); - connect(btnDirUp, SIGNAL(clicked()), diskUsage, SLOT(dirUp())); - connect(btnLines, SIGNAL(clicked()), this, SLOT(slotSelectLinesView())); - connect(btnDetailed, SIGNAL(clicked()), this, SLOT(slotSelectListView())); - connect(btnFilelight, SIGNAL(clicked()), this, SLOT(slotSelectFilelightView())); + 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) { 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, SLOT(slotLoadUsageInfo())); return true; } diff --git a/krusader/DiskUsage/dufilelight.cpp b/krusader/DiskUsage/dufilelight.cpp index c762d33c..2aa18b36 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) { // setFocusPolicy(Qt::StrongFocus); - connect(diskUsage, SIGNAL(enteringDirectory(Directory*)), this, SLOT(slotDirChanged(Directory*))); - connect(diskUsage, SIGNAL(clearing()), this, SLOT(clear())); - connect(diskUsage, SIGNAL(changed(File*)), this, SLOT(slotChanged(File*))); - connect(diskUsage, SIGNAL(deleted(File*)), this, SLOT(slotChanged(File*))); - connect(diskUsage, SIGNAL(changeFinished()), this, SLOT(slotRefresh())); - connect(diskUsage, SIGNAL(deleteFinished()), this, SLOT(slotRefresh())); - connect(diskUsage, SIGNAL(currentChanged(int)), this, SLOT(slotAboutToShow(int))); + 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; } File * DUFilelight::getCurrentFile() { const RadialMap::Segment * focus = focusSegment(); if (!focus || focus->isFake() || focus->file() == currentDir) return 0; return (File *)focus->file(); } void DUFilelight::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::RightButton) { File * file = 0; 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) { 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/dulines.cpp b/krusader/DiskUsage/dulines.cpp index b51517dc..85ba4948 100644 --- a/krusader/DiskUsage/dulines.cpp +++ b/krusader/DiskUsage/dulines.cpp @@ -1,535 +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) {} virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE { QItemDelegate::paint(painter, option, index); QVariant value = index.data(Qt::UserRole); if (value.isValid()) { QString text = value.toString(); value = index.data(Qt::DisplayRole); QString display; if (value.isValid()) display = value.toString(); QSize iconSize; value = index.data(Qt::DecorationRole); if (value.isValid()) iconSize = qvariant_cast(value).actualSize(option.decorationSize); painter->save(); painter->setClipRect(option.rect); QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; if (cg == QPalette::Normal && !(option.state & QStyle::State_Active)) cg = QPalette::Inactive; if (option.state & QStyle::State_Selected) { painter->setPen(option.palette.color(cg, QPalette::HighlightedText)); } else { painter->setPen(option.palette.color(cg, QPalette::Text)); } QFont fnt = option.font; fnt.setItalic(true); painter->setFont(fnt); QFontMetrics fm(fnt); QString renderedText = text; int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin); int pos = 3 * textMargin + option.fontMetrics.width(display) + iconSize.width(); bool truncd = false; QRect rct = option.rect; if (rct.width() > pos) { rct.setX(rct.x() + pos); if (fm.width(renderedText) > rct.width()) { truncd = true; int points = fm.width("..."); while (!renderedText.isEmpty() && (fm.width(renderedText) + points > rct.width())) renderedText.truncate(renderedText.length() - 1); renderedText += "..."; } painter->drawText(rct, Qt::AlignLeft, renderedText); } else truncd = true; if (truncd) ((QAbstractItemModel *)index.model())->setData(index, QVariant(display + " " + text), Qt::ToolTipRole); else ((QAbstractItemModel *)index.model())->setData(index, QVariant(), Qt::ToolTipRole); painter->restore(); } } }; class DULinesItem : public QTreeWidgetItem { public: DULinesItem(DiskUsage *diskUsageIn, File *fileItem, QTreeWidget * parent, QString label1, QString label2, QString label3) : QTreeWidgetItem(parent), diskUsage(diskUsageIn), file(fileItem) { setText(0, label1); setText(1, label2); setText(2, label3); setTextAlignment(1, Qt::AlignRight); } DULinesItem(DiskUsage *diskUsageIn, File *fileItem, QTreeWidget * parent, QTreeWidgetItem * after, QString label1, QString label2, QString label3) : QTreeWidgetItem(parent, after), diskUsage(diskUsageIn), file(fileItem) { setText(0, label1); setText(1, label2); setText(2, label3); setTextAlignment(1, Qt::AlignRight); } virtual bool operator<(const QTreeWidgetItem &other) const Q_DECL_OVERRIDE { int column = treeWidget() ? treeWidget()->sortColumn() : 0; if (text(0) == "..") return true; const DULinesItem *compWith = dynamic_cast< const DULinesItem * >(&other); if (compWith == 0) return false; switch (column) { case 0: case 1: return file->size() > compWith->file->size(); default: return text(column) < other.text(column); } } inline File * getFile() { return file; } private: DiskUsage *diskUsage; File *file; }; DULines::DULines(DiskUsage *usage) : KrTreeWidget(usage), diskUsage(usage), refreshNeeded(false), started(false) { setItemDelegate(itemDelegate = new DULinesItemDelegate()); setAllColumnsShowFocus(true); setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); setIndentation(10); int defaultSize = QFontMetrics(font()).width("W"); QStringList labels; labels << i18n("Line View"); labels << i18n("Percent"); labels << i18n("Name"); setHeaderLabels(labels); header()->setSectionResizeMode(QHeaderView::Interactive); KConfigGroup group(krConfig, diskUsage->getConfigGroup()); showFileSize = group.readEntry("L Show File Size", true); if (group.hasKey("L State")) header()->restoreState(group.readEntry("L State", QByteArray())); else { setColumnWidth(0, defaultSize * 20); setColumnWidth(1, defaultSize * 6); setColumnWidth(2, defaultSize * 20); } setStretchingColumn(0); header()->setSortIndicatorShown(true); sortItems(1, Qt::AscendingOrder); // toolTip = new DULinesToolTip( diskUsage, viewport(), this ); - connect(diskUsage, SIGNAL(enteringDirectory(Directory*)), this, SLOT(slotDirChanged(Directory*))); - connect(diskUsage, SIGNAL(clearing()), this, SLOT(clear())); + connect(diskUsage, &DiskUsage::enteringDirectory, this, &DULines::slotDirChanged); + connect(diskUsage, &DiskUsage::clearing, this, &DULines::clear); - connect(header(), SIGNAL(sectionResized(int,int,int)), this, SLOT(sectionResized(int))); + connect(header(), &QHeaderView::sectionResized, this, &DULines::sectionResized); - connect(this, SIGNAL(itemRightClicked(QTreeWidgetItem*,QPoint,int)), - this, SLOT(slotRightClicked(QTreeWidgetItem*,QPoint))); - connect(diskUsage, SIGNAL(changed(File*)), this, SLOT(slotChanged(File*))); - connect(diskUsage, SIGNAL(deleted(File*)), this, SLOT(slotDeleted(File*))); + 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); if (viewport()) { QPoint pos = viewport()->mapFromGlobal(he->globalPos()); QTreeWidgetItem * item = itemAt(pos); int column = columnAt(pos.x()); if (item && column == 1) { File *fileItem = ((DULinesItem *)item)->getFile(); QToolTip::showText(he->globalPos(), diskUsage->getToolTip(fileItem), this); return true; } } } break; default: break; } return KrTreeWidget::event(event); } void DULines::slotDirChanged(Directory *dirEntry) { clear(); QTreeWidgetItem * lastItem = 0; if (!(dirEntry->parent() == 0)) { lastItem = new QTreeWidgetItem(this); lastItem->setText(0, ".."); lastItem->setIcon(0, 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) lastItem = new DULinesItem(diskUsage, item, this, "", item->percent() + " ", fileName); else lastItem = new DULinesItem(diskUsage, item, this, lastItem, "", item->percent() + " ", fileName); if (item->isExcluded()) lastItem->setHidden(true); int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; lastItem->setIcon(2, diskUsage->getIcon(item->mime())); lastItem->setData(0, Qt::DecorationRole, createPixmap(item->intPercent(), maxPercent, header()->sectionSize(0) - 2 * textMargin)); if (showFileSize) lastItem->setData(2, Qt::UserRole, " [" + KIO::convertSize(item->size()) + ']'); QSize size = lastItem->sizeHint(0); size.setWidth(16); lastItem->setSizeHint(0, size); } if (topLevelItemCount() > 0) { setCurrentItem(topLevelItem(0)); } } QPixmap DULines::createPixmap(int percent, int maxPercent, int maxWidth) { if (percent < 0 || percent > maxPercent || maxWidth < 2 || maxPercent == 0) return QPixmap(); maxWidth -= 2; int actualWidth = maxWidth * percent / maxPercent; if (actualWidth == 0) return QPixmap(); QPen pen; pen.setColor(Qt::black); QPainter painter; int size = QFontMetrics(font()).height() - 2; QRect rect(0, 0, actualWidth, size); QRect frameRect(0, 0, actualWidth - 1, size - 1); QPixmap pixmap(rect.width(), rect.height()); painter.begin(&pixmap); painter.setPen(pen); for (int i = 1; i < actualWidth - 1; i++) { int color = (511 * i / (maxWidth - 1)); if (color < 256) pen.setColor(QColor(255 - color, 255, 0)); else pen.setColor(QColor(color - 256, 511 - color, 0)); painter.setPen(pen); painter.drawLine(i, 1, i, size - 1); } pen.setColor(Qt::black); painter.setPen(pen); if (actualWidth != 1) painter.drawRect(frameRect); else painter.drawLine(0, 0, 0, size); painter.end(); pixmap.detach(); return pixmap; } void DULines::resizeEvent(QResizeEvent * re) { KrTreeWidget::resizeEvent(re); if (started && (re->oldSize() != re->size())) sectionResized(0); } void DULines::sectionResized(int column) { if (topLevelItemCount() == 0 || column != 0) return; Directory * currentDir = diskUsage->getCurrentDir(); if (currentDir == 0) return; int maxPercent = -1; for (Iterator it = currentDir->iterator(); it != currentDir->end(); ++it) { File *item = *it; if (!item->isExcluded() && item->intPercent() > maxPercent) maxPercent = item->intPercent(); } QTreeWidgetItemIterator it2(this); while (*it2) { QTreeWidgetItem *lvitem = *it2; if (lvitem->text(0) != "..") { DULinesItem *duItem = dynamic_cast< DULinesItem *>(lvitem); if (duItem) { int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; duItem->setData(0, Qt::DecorationRole, createPixmap(duItem->getFile()->intPercent(), maxPercent, header()->sectionSize(0) - 2 * textMargin)); QSize size = duItem->sizeHint(0); size.setWidth(16); duItem->setSizeHint(0, size); } } it2++; } } bool DULines::doubleClicked(QTreeWidgetItem * item) { if (item) { if (item->text(0) != "..") { File *fileItem = ((DULinesItem *)item)->getFile(); if (fileItem->isDir()) diskUsage->changeDirectory(dynamic_cast(fileItem)); return true; } else { Directory *upDir = (Directory *)diskUsage->getCurrentDir()->parent(); if (upDir) diskUsage->changeDirectory(upDir); return true; } } return false; } void DULines::mouseDoubleClickEvent(QMouseEvent * e) { if (e || e->button() == Qt::LeftButton) { QPoint vp = viewport()->mapFromGlobal(e->globalPos()); QTreeWidgetItem * item = itemAt(vp); if (doubleClicked(item)) return; } KrTreeWidget::mouseDoubleClickEvent(e); } void DULines::keyPressEvent(QKeyEvent *e) { switch (e->key()) { case Qt::Key_Return : case Qt::Key_Enter : if (doubleClicked(currentItem())) return; break; case Qt::Key_Left : case Qt::Key_Right : case Qt::Key_Up : case Qt::Key_Down : if (e->modifiers() == Qt::ShiftModifier) { e->ignore(); return; } break; case Qt::Key_Delete : e->ignore(); return; } KrTreeWidget::keyPressEvent(e); } void DULines::slotRightClicked(QTreeWidgetItem *item, const QPoint &pos) { File * file = 0; if (item && item->text(0) != "..") file = ((DULinesItem *)item)->getFile(); QMenu linesPopup; QAction *act = linesPopup.addAction(i18n("Show file sizes"), this, SLOT(slotShowFileSizes())); act->setChecked(showFileSize); diskUsage->rightClickMenu(pos, file, &linesPopup, i18n("Lines")); } void DULines::slotShowFileSizes() { showFileSize = !showFileSize; slotDirChanged(diskUsage->getCurrentDir()); } File * DULines::getCurrentFile() { QTreeWidgetItem *item = currentItem(); if (item == 0 || item->text(0) == "..") return 0; return ((DULinesItem *)item)->getFile(); } void DULines::slotChanged(File * item) { QTreeWidgetItemIterator it(this); while (*it) { QTreeWidgetItem *lvitem = *it; it++; if (lvitem->text(0) != "..") { DULinesItem *duItem = (DULinesItem *)(lvitem); if (duItem->getFile() == item) { setSortingEnabled(false); duItem->setHidden(item->isExcluded()); duItem->setText(1, item->percent()); if (!refreshNeeded) { refreshNeeded = true; QTimer::singleShot(0, this, SLOT(slotRefresh())); } break; } } } } void DULines::slotDeleted(File * item) { QTreeWidgetItemIterator it(this); while (*it) { QTreeWidgetItem *lvitem = *it; it++; if (lvitem->text(0) != "..") { DULinesItem *duItem = (DULinesItem *)(lvitem); if (duItem->getFile() == item) { delete duItem; break; } } } } void DULines::slotRefresh() { if (refreshNeeded) { refreshNeeded = false; setSortingEnabled(true); sortItems(1, Qt::AscendingOrder); } } diff --git a/krusader/DiskUsage/dulistview.cpp b/krusader/DiskUsage/dulistview.cpp index 716bd69d..f1dd37a5 100644 --- a/krusader/DiskUsage/dulistview.cpp +++ b/krusader/DiskUsage/dulistview.cpp @@ -1,273 +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, SIGNAL(enteringDirectory(Directory*)), this, SLOT(slotDirChanged(Directory*))); - connect(diskUsage, SIGNAL(clearing()), this, SLOT(clear())); - connect(diskUsage, SIGNAL(changed(File*)), this, SLOT(slotChanged(File*))); - connect(diskUsage, SIGNAL(deleted(File*)), this, SLOT(slotDeleted(File*))); - - connect(this, SIGNAL(itemRightClicked(QTreeWidgetItem*,QPoint,int)), - this, SLOT(slotRightClicked(QTreeWidgetItem*,QPoint))); - connect(this, SIGNAL(itemExpanded(QTreeWidgetItem*)), - this, SLOT(slotExpanded(QTreeWidgetItem*))); + 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; if (parent == 0 && !(dirEntry->parent() == 0)) { 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) lastItem = new DUListViewItem(diskUsage, item, this, item->name(), percent, totalSize, ownSize, mime, date, item->perm(), item->owner(), item->group()); else if (lastItem == 0) lastItem = new DUListViewItem(diskUsage, item, parent, item->name(), percent, totalSize, ownSize, mime, date, item->perm(), item->owner(), item->group()); else if (parent == 0) lastItem = new DUListViewItem(diskUsage, item, this, lastItem, item->name(), percent, totalSize, ownSize, mime, date, item->perm(), item->owner(), item->group()); else lastItem = new DUListViewItem(diskUsage, item, parent, lastItem, item->name(), percent, totalSize, ownSize, mime, date, item->perm(), item->owner(), item->group()); if (item->isExcluded()) lastItem->setHidden(true); lastItem->setIcon(0, diskUsage->getIcon(item->mime())); if (item->isDir() && !item->isSymLink()) lastItem->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator); } if (topLevelItemCount() > 0) { setCurrentItem(topLevelItem(0)); } } void DUListView::slotDirChanged(Directory *dirEntry) { clear(); addDirectory(dirEntry, 0); } File * DUListView::getCurrentFile() { QTreeWidgetItem *item = currentItem(); if (item == 0 || item->text(0) == "..") return 0; return ((DUListViewItem *)item)->getFile(); } void DUListView::slotChanged(File * item) { void * itemPtr = diskUsage->getProperty(item, "ListView-Ref"); if (itemPtr == 0) return; DUListViewItem *duItem = (DUListViewItem *)itemPtr; duItem->setHidden(item->isExcluded()); duItem->setText(1, item->percent()); duItem->setText(2, KRpermHandler::parseSize(item->size()) + ' '); duItem->setText(3, KRpermHandler::parseSize(item->ownSize()) + ' '); } void DUListView::slotDeleted(File * item) { void * itemPtr = diskUsage->getProperty(item, "ListView-Ref"); if (itemPtr == 0) return; DUListViewItem *duItem = (DUListViewItem *)itemPtr; delete duItem; } void DUListView::slotRightClicked(QTreeWidgetItem *item, const QPoint & pos) { File * file = 0; if (item && item->text(0) != "..") file = ((DUListViewItem *)item)->getFile(); diskUsage->rightClickMenu(pos, file); } bool DUListView::doubleClicked(QTreeWidgetItem * item) { if (item) { if (item->text(0) != "..") { File *fileItem = ((DUListViewItem *)item)->getFile(); if (fileItem->isDir()) diskUsage->changeDirectory(dynamic_cast(fileItem)); return true; } else { Directory *upDir = (Directory *)diskUsage->getCurrentDir()->parent(); if (upDir) diskUsage->changeDirectory(upDir); return true; } } return false; } void DUListView::mouseDoubleClickEvent(QMouseEvent * e) { if (e || e->button() == Qt::LeftButton) { QPoint vp = viewport()->mapFromGlobal(e->globalPos()); QTreeWidgetItem * item = itemAt(vp); if (doubleClicked(item)) return; } KrTreeWidget::mouseDoubleClickEvent(e); } void DUListView::keyPressEvent(QKeyEvent *e) { switch (e->key()) { case Qt::Key_Return : case Qt::Key_Enter : if (doubleClicked(currentItem())) return; break; case Qt::Key_Left : case Qt::Key_Right : case Qt::Key_Up : case Qt::Key_Down : if (e->modifiers() == Qt::ShiftModifier) { e->ignore(); return; } break; case Qt::Key_Delete : e->ignore(); return; } KrTreeWidget::keyPressEvent(e); } void DUListView::slotExpanded(QTreeWidgetItem * item) { if (item == 0 || item->text(0) == "..") return; if (item->childCount() == 0) { File *fileItem = ((DUListViewItem *)item)->getFile(); if (fileItem->isDir()) addDirectory(dynamic_cast(fileItem), item); } } diff --git a/krusader/DiskUsage/radialMap/widget.cpp b/krusader/DiskUsage/radialMap/widget.cpp index 457b81cc..9dee06b0 100644 --- a/krusader/DiskUsage/radialMap/widget.cpp +++ b/krusader/DiskUsage/radialMap/widget.cpp @@ -1,216 +1,216 @@ /***************************************************************************** * 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 "widget.h" // QtCore #include #include //member #include // QtGui #include #include //ctor - finding cursor size #include //slotPostMouseEvent() #include // QtWidgets #include //sendEvent #include //ctor #include "fileTree.h" #include "Config.h" #include "radialMap.h" //constants RadialMap::Widget::Widget(QWidget *parent) : QWidget(parent) , m_tree(0) , m_focus(0) , m_tip(QFontMetrics(font()).height()) //needs to know cursor height , m_rootSegment(0) //TODO we don't delete it, *shrug* { QPalette pal = palette(); pal.setColor(backgroundRole(), Qt::white); setPalette(pal); - connect(this, SIGNAL(created(const Directory*)), SLOT(sendFakeMouseEvent())); - connect(this, SIGNAL(created(const Directory*)), SLOT(update())); - connect(&m_timer, SIGNAL(timeout()), SLOT(resizeTimeout())); + connect(this, &Widget::created, this, &Widget::sendFakeMouseEvent); + connect(this, &Widget::created, this, QOverload<>::of(&Widget::update)); + connect(&m_timer, &QTimer::timeout, this, &Widget::resizeTimeout); } QString RadialMap::Widget::path() const { if (m_tree == 0) return QString(); return m_tree->fullPath(); } QUrl RadialMap::Widget::url(File const * const file) const { if (file == 0 && m_tree == 0) return QUrl(); return QUrl::fromLocalFile(file ? file->fullPath() : m_tree->fullPath()); } void RadialMap::Widget::invalidate(const bool b) { if (isValid()) { //**** have to check that only way to invalidate is this function frankly //**** otherwise you may get bugs.. //disable mouse tracking setMouseTracking(false); QUrl urlInv = url(); //ensure this class won't think we have a map still m_tree = 0; m_focus = 0; delete m_rootSegment; m_rootSegment = 0; //FIXME move this disablement thing no? // it is confusing in other areas, like the whole createFromCache() thing m_map.invalidate(b); //b signifies whether the pixmap is made to look disabled or not if (b) update(); //tell rest of Filelight emit invalidated(urlInv); } } void RadialMap::Widget::create(const Directory *tree) { //it is not the responsibility of create() to invalidate first //skip invalidation at your own risk //FIXME make it the responsibility of create to invalidate first if (tree) { m_focus = 0; //generate the filemap image m_map.make(tree); //this is the inner circle in the center m_rootSegment = new Segment(tree, 0, 16*360); setMouseTracking(true); } m_tree = tree; //tell rest of Filelight emit created(tree); } void RadialMap::Widget::createFromCache(const Directory *tree) { //no scan was necessary, use cached tree, however we MUST still emit invalidate invalidate(false); create(tree); } void RadialMap::Widget::sendFakeMouseEvent() //slot { QMouseEvent me(QEvent::MouseMove, mapFromGlobal(QCursor::pos()), Qt::NoButton, Qt::NoButton, Qt::NoModifier); QApplication::sendEvent(this, &me); } void RadialMap::Widget::resizeTimeout() //slot { // the segments are about to erased! // this was a horrid bug, and proves the OO programming should be obeyed always! m_focus = 0; if (m_tree) m_map.make(m_tree, true); update(); } void RadialMap::Widget::refresh(int filth) { //TODO consider a more direct connection if (!m_map.isNull()) { switch (filth) { case 1: m_focus = 0; if (m_tree) m_map.make(m_tree, true); //true means refresh only break; case 2: m_map.aaPaint(); break; case 3: m_map.colorise(); //FALL THROUGH! case 4: m_map.paint(); default: break; } update(); } } void RadialMap::Widget::zoomIn() //slot { if (m_map.m_visibleDepth > MIN_RING_DEPTH) { m_focus = 0; --m_map.m_visibleDepth; if (m_tree) m_map.make(m_tree); Config::defaultRingDepth = m_map.m_visibleDepth; update(); } } void RadialMap::Widget::zoomOut() //slot { m_focus = 0; ++m_map.m_visibleDepth; if (m_tree) m_map.make(m_tree); if (m_map.m_visibleDepth > Config::defaultRingDepth) Config::defaultRingDepth = m_map.m_visibleDepth; update(); } RadialMap::Segment::~Segment() { if (isFake()) delete m_file; //created by us in Builder::build() } diff --git a/krusader/DiskUsage/radialMap/widgetEvents.cpp b/krusader/DiskUsage/radialMap/widgetEvents.cpp index 845c08e4..18a7efb0 100644 --- a/krusader/DiskUsage/radialMap/widgetEvents.cpp +++ b/krusader/DiskUsage/radialMap/widgetEvents.cpp @@ -1,252 +1,252 @@ /***************************************************************************** * 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 "fileTree.h" #include "radialMap.h" //class Segment #include "widget.h" #include "../../icon.h" #include // QtCore #include //::resizeEvent() // QtGui #include #include #include #include // QtWidgets #include //QApplication::setOverrideCursor() #include #include #include #include #include #include #include #include void RadialMap::Widget::resizeEvent(QResizeEvent*) { if (m_map.resize(rect())) { m_timer.setSingleShot(true); m_timer.start(500); //will cause signature to rebuild for new size } //always do these as they need to be initialised on creation m_offset.rx() = (width() - m_map.width()) / 2; m_offset.ry() = (height() - m_map.height()) / 2; } void RadialMap::Widget::paintEvent(QPaintEvent*) { //bltBit for some Qt setups will bitBlt _after_ the labels are painted. Which buggers things up! //shame as bitBlt is faster, possibly Qt bug? Should report the bug? - seems to be race condition //bitBlt( this, m_offset, &m_map ); QPainter paint(this); paint.drawPixmap(m_offset, m_map); //vertical strips if (m_map.width() < width()) { paint.eraseRect(0, 0, m_offset.x(), height()); paint.eraseRect(m_map.width() + m_offset.x(), 0, m_offset.x() + 1, height()); } //horizontal strips if (m_map.height() < height()) { paint.eraseRect(0, 0, width(), m_offset.y()); paint.eraseRect(0, m_map.height() + m_offset.y(), width(), m_offset.y() + 1); } //exploded labels if (!m_map.isNull() && !m_timer.isActive()) paintExplodedLabels(paint); } const RadialMap::Segment* RadialMap::Widget::segmentAt(QPoint &e) const { //determine which segment QPoint e is above e -= m_offset; if (e.x() <= m_map.width() && e.y() <= m_map.height()) { //transform to cartesian coords e.rx() -= m_map.width() / 2; //should be an int e.ry() = m_map.height() / 2 - e.y(); double length = std::hypot(e.x(), e.y()); if (length >= m_map.m_innerRadius) { //not hovering over inner circle uint depth = ((int)length - m_map.m_innerRadius) / m_map.m_ringBreadth; if (depth <= m_map.m_visibleDepth) { //**** do earlier since you can //** check not outside of range //vector calculation, reduces to simple trigonometry //cos angle = (aibi + ajbj) / albl //ai = x, bi=1, aj=y, bj=0 //cos angle = x / (length) uint a = (uint)(acos((double)e.x() / length) * 916.736); //916.7324722 = #radians in circle * 16 //acos only understands 0-180 degrees if (e.y() < 0) a = 5760 - a; #define ring (m_map.m_signature + depth) for (ConstIterator it = ring->constIterator(); it != ring->end(); ++it) if ((*it)->intersects(a)) return *it; #undef ring } } else return m_rootSegment; //hovering over inner circle } return 0; } void RadialMap::Widget::mouseMoveEvent(QMouseEvent *e) { //set m_focus to what we hover over, update UI if it's a new segment Segment const * const oldFocus = m_focus; QPoint p = e->pos(); m_focus = segmentAt(p); //NOTE p is passed by non-const reference if (m_focus && m_focus->file() != m_tree) { if (m_focus != oldFocus) { //if not same as last time setCursor(QCursor(Qt::PointingHandCursor)); m_tip.updateTip(m_focus->file(), m_tree); emit mouseHover(m_focus->file()->fullPath()); //repaint required to update labels now before transparency is generated repaint(); } // updates tooltip pseudo-transparent background m_tip.moveto(e->globalPos(), *this, (p.y() < 0)); } else if (oldFocus && oldFocus->file() != m_tree) { unsetCursor(); m_tip.hide(); update(); emit mouseHover(QString()); } } void RadialMap::Widget::mousePressEvent(QMouseEvent *e) { //m_tip is hidden already by event filter //m_focus is set correctly (I've been strict, I assure you it is correct!) if (m_focus && !m_focus->isFake()) { const QUrl url = Widget::url(m_focus->file()); const bool isDir = m_focus->file()->isDir(); if (e->button() == Qt::RightButton) { QMenu popup; popup.setTitle(m_focus->file()->fullPath(m_tree)); QAction * actKonq = 0, * actKonsole = 0, *actViewMag = 0, * actFileOpen = 0, * actEditDel = 0; if (isDir) { actKonq = popup.addAction(Icon("system-file-manager"), i18n("Open File Manager Here")); if (url.scheme() == "file") actKonsole = popup.addAction(Icon("utilities-terminal"), i18n("Open Terminal Here")); if (m_focus->file() != m_tree) { popup.addSeparator(); actViewMag = popup.addAction(Icon("zoom-original"), i18n("&Center Map Here")); } } else actFileOpen = popup.addAction(Icon("document-open"), i18n("&Open")); popup.addSeparator(); actEditDel = popup.addAction(Icon("edit-delete"), i18n("&Delete")); QAction * result = popup.exec(e->globalPos()); if (result == 0) result = (QAction *) - 1; // sanity if (result == actKonq) //KRun::runCommand will show an error message if there was trouble KRun::runCommand(QString("kfmclient openURL '%1'").arg(url.url()), this); else if (result == actKonsole) KRun::runCommand(QString("konsole --workdir '%1'").arg(url.url()), this); else if (result == actViewMag || result == actFileOpen) goto sectionTwo; else if (result == actEditDel) { const QUrl url = Widget::url(m_focus->file()); const QString message = (m_focus->file()->isDir() ? i18n("The folder at '%1' will be recursively and permanently deleted.", url.toDisplayString()) : i18n("'%1' will be permanently deleted.", url.toDisplayString())); const int userIntention = KMessageBox::warningContinueCancel(this, message, QString(), KStandardGuiItem::del()); if (userIntention == KMessageBox::Continue) { KIO::Job *job = KIO::del(url); KIO::JobUiDelegate *ui = static_cast(job->uiDelegate()); ui->setWindow(this); - connect(job, SIGNAL(result(KJob*)), SLOT(deleteJobFinished(KJob*))); + connect(job, &KIO::Job::result, this, &Widget::deleteJobFinished); QApplication::setOverrideCursor(Qt::BusyCursor); } } else //ensure m_focus is set for new mouse position sendFakeMouseEvent(); } else { sectionTwo: const QRect rect(e->x() - 20, e->y() - 20, 40, 40); m_tip.hide(); //user expects this if (!isDir || e->button() == Qt::MidButton) { #if 0 // TODO: PORTME KIconEffect::visualActivate(this, rect); #endif new KRun(url, this, true); //FIXME see above } else if (m_focus->file() != m_tree) { //is left mouse button #if 0 // TODO: PORTME KIconEffect::visualActivate(this, rect); #endif emit activated(url); //activate first, this will cause UI to prepare itself if (m_focus) createFromCache((Directory *)m_focus->file()); } } } } void RadialMap::Widget::deleteJobFinished(KJob *job) { QApplication::restoreOverrideCursor(); if (!job->error()) invalidate(); else job->uiDelegate()->showErrorMessage(); } diff --git a/krusader/FileSystem/defaultfilesystem.cpp b/krusader/FileSystem/defaultfilesystem.cpp index 7c0cddd2..12d4560c 100644 --- a/krusader/FileSystem/defaultfilesystem.cpp +++ b/krusader/FileSystem/defaultfilesystem.cpp @@ -1,412 +1,412 @@ /***************************************************************************** * 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 "defaultfilesystem.h" // QtCore #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "fileitem.h" #include "../defaults.h" #include "../krglobal.h" #include "../krservices.h" #include "../JobMan/krjob.h" DefaultFileSystem::DefaultFileSystem(): FileSystem(), _watcher() { _type = FS_DEFAULT; } void DefaultFileSystem::copyFiles(const QList &urls, const QUrl &destination, KIO::CopyJob::CopyMode mode, bool showProgressInfo, JobMan::StartMode startMode) { // resolve relative path before resolving symlinks const QUrl dest = resolveRelativePath(destination); KIO::JobFlags flags = showProgressInfo ? KIO::DefaultFlags : KIO::HideProgressInfo; KrJob *krJob = KrJob::createCopyJob(mode, urls, dest, flags); // destination can be a full path with filename when copying/moving a single file const QUrl destDir = dest.adjusted(QUrl::RemoveFilename); connect(krJob, &KrJob::started, this, [=](KIO::Job *job) { connectJobToDestination(job, destDir); }); if (mode == KIO::CopyJob::Move) { // notify source about removed files connect(krJob, &KrJob::started, this, [=](KIO::Job *job) { connectJobToSources(job, urls); }); } krJobMan->manageJob(krJob, startMode); } void DefaultFileSystem::dropFiles(const QUrl &destination, QDropEvent *event) { qDebug() << "destination=" << destination; // resolve relative path before resolving symlinks const QUrl dest = resolveRelativePath(destination); KIO::DropJob *job = KIO::drop(event, dest); #if KIO_VERSION >= QT_VERSION_CHECK(5, 30, 0) // NOTE: a DropJob "starts" with showing a menu. If the operation is chosen (copy/move/link) // the actual CopyJob starts automatically - we cannot manage the start of the CopyJob (see // documentation for KrJob) connect(job, &KIO::DropJob::copyJobStarted, this, [=](KIO::CopyJob *kJob) { connectJobToDestination(job, dest); // now we have to refresh the destination KrJob *krJob = KrJob::createDropJob(job, kJob); krJobMan->manageStartedJob(krJob, kJob); if (kJob->operationMode() == KIO::CopyJob::Move) { // notify source about removed files connectJobToSources(kJob, kJob->srcUrls()); } }); #else // NOTE: DropJob does not provide information about the actual user choice // (move/copy/link/abort). We have to assume the worst (move) connectJobToDestination(job, dest); connectJobToSources(job, KUrlMimeData::urlsFromMimeData(event->mimeData())); #endif } void DefaultFileSystem::addFiles(const QList &fileUrls, KIO::CopyJob::CopyMode mode, const QString &dir) { QUrl destination(_currentDirectory); if (!dir.isEmpty()) { destination.setPath(QDir::cleanPath(destination.path() + '/' + dir)); const QString scheme = destination.scheme(); if (scheme == "tar" || scheme == "zip" || scheme == "krarc") { if (QDir(destination.path()).exists()) // if we get out from the archive change the protocol destination.setScheme("file"); } } destination = ensureTrailingSlash(destination); // destination is always a directory copyFiles(fileUrls, destination, mode); } void DefaultFileSystem::mkDir(const QString &name) { KJob *job; if (name.contains('/')) { job = KIO::mkpath(getUrl(name)); } else { job = KIO::mkdir(getUrl(name)); } connectJobToDestination(job, currentDirectory()); } void DefaultFileSystem::rename(const QString &oldName, const QString &newName) { const QUrl oldUrl = getUrl(oldName); const QUrl newUrl = getUrl(newName); KIO::Job *job = KIO::moveAs(oldUrl, newUrl, KIO::HideProgressInfo); connectJobToDestination(job, currentDirectory()); KIO::FileUndoManager::self()->recordJob(KIO::FileUndoManager::Rename, {oldUrl}, newUrl, job); } QUrl DefaultFileSystem::getUrl(const QString& name) const { // NOTE: on non-local fs file URL does not have to be path + name! FileItem *fileItem = getFileItem(name); if (fileItem) return fileItem->getUrl(); QUrl absoluteUrl(_currentDirectory); if (name.startsWith('/')) { absoluteUrl.setPath(name); } else { absoluteUrl.setPath(absoluteUrl.path() + '/' + name); } return absoluteUrl; } void DefaultFileSystem::updateFilesystemInfo() { if (!KConfigGroup(krConfig, "Look&Feel").readEntry("ShowSpaceInformation", true)) { _mountPoint = ""; emit fileSystemInfoChanged(i18n("Space information disabled"), "", 0, 0); return; } // TODO get space info for trash:/ with KIO spaceInfo job if (!_currentDirectory.isLocalFile()) { _mountPoint = ""; emit fileSystemInfoChanged(i18n("No space information on non-local filesystems"), "", 0, 0); return; } const QString path = _currentDirectory.path(); const KDiskFreeSpaceInfo info = KDiskFreeSpaceInfo::freeSpaceInfo(path); if (!info.isValid()) { _mountPoint = ""; emit fileSystemInfoChanged(i18n("Space information unavailable"), "", 0, 0); return; } _mountPoint = info.mountPoint(); const KMountPoint::Ptr mountPoint = KMountPoint::currentMountPoints().findByPath(path); const QString fsType = mountPoint ? mountPoint->mountType() : ""; emit fileSystemInfoChanged("", fsType, info.size(), info.available()); } // ==== protected ==== bool DefaultFileSystem::refreshInternal(const QUrl &directory, bool onlyScan) { qDebug() << "refresh internal to URL=" << directory.toDisplayString(); if (!KProtocolManager::supportsListing(directory)) { emit error(i18n("Protocol not supported by Krusader:\n%1", directory.url())); return false; } delete _watcher; // stop watching the old dir if (directory.isLocalFile()) { qDebug() << "start local refresh to URL=" << directory.toDisplayString(); // we could read local directories with KIO but using Qt is a lot faster! return refreshLocal(directory, onlyScan); } _currentDirectory = cleanUrl(directory); // start the listing job KIO::ListJob *job = KIO::listDir(_currentDirectory, KIO::HideProgressInfo, showHiddenFiles()); connect(job, &KIO::ListJob::entries, this, &DefaultFileSystem::slotAddFiles); connect(job, &KIO::ListJob::redirection, this, &DefaultFileSystem::slotRedirection); connect(job, &KIO::ListJob::permanentRedirection, this, &DefaultFileSystem::slotRedirection); connect(job, &KIO::Job::result, this, &DefaultFileSystem::slotListResult); // ensure connection credentials are asked only once if(!parentWindow.isNull()) { KIO::JobUiDelegate *ui = static_cast(job->uiDelegate()); ui->setWindow(parentWindow); } emit refreshJobStarted(job); _listError = false; // ugly: we have to wait here until the list job is finished QEventLoop eventLoop; connect(job, &KJob::finished, &eventLoop, &QEventLoop::quit); eventLoop.exec(); // blocking until quit() return !_listError; } // ==== protected slots ==== void DefaultFileSystem::slotListResult(KJob *job) { qDebug() << "got list result"; if (job && job->error()) { // we failed to refresh _listError = true; qDebug() << "error=" << job->errorString() << "; text=" << job->errorText(); emit error(job->errorString()); // display error message (in panel) } } void DefaultFileSystem::slotAddFiles(KIO::Job *, const KIO::UDSEntryList& entries) { for (const KIO::UDSEntry entry : entries) { FileItem *fileItem = FileSystem::createFileItemFromKIO(entry, _currentDirectory); if (fileItem) { addFileItem(fileItem); } } } void DefaultFileSystem::slotRedirection(KIO::Job *job, const QUrl &url) { qDebug() << "redirection to URL=" << url.toDisplayString(); // some protocols (zip, tar) send redirect to local URL without scheme const QUrl newUrl = preferLocalUrl(url); if (newUrl.scheme() != _currentDirectory.scheme()) { // abort and start over again, // some protocols (iso, zip, tar) do this on transition to local fs job->kill(); _isRefreshing = false; refresh(newUrl); return; } _currentDirectory = cleanUrl(newUrl); } void DefaultFileSystem::slotWatcherCreated(const QString& path) { qDebug() << "path created (doing nothing): " << path; } void DefaultFileSystem::slotWatcherDirty(const QString& path) { qDebug() << "path dirty: " << path; if (path == realPath()) { // this happens // 1. if a directory was created/deleted/renamed inside this directory. // 2. during and after a file operation (create/delete/rename/touch) inside this directory // KDirWatcher doesn't reveal the name of changed directories and we have to refresh. // (QFileSystemWatcher in Qt5.7 can't help here either) refresh(); return; } const QString name = QUrl::fromLocalFile(path).fileName(); FileItem *fileItem = getFileItem(name); if (!fileItem) { qWarning() << "file not found (unexpected), path=" << path; // this happens at least for cifs mounted filesystems: when a new file is created, a dirty // signal with its file path but no other signals are sent (buggy behaviour of KDirWatch) refresh(); return; } // we have an updated file.. FileItem *newFileItem = createLocalFileItem(name); addFileItem(newFileItem); emit updatedFileItem(newFileItem); delete fileItem; } void DefaultFileSystem::slotWatcherDeleted(const QString& path) { qDebug() << "path deleted: " << path; if (path != _currentDirectory.toLocalFile()) { // ignore deletion of files here, a 'dirty' signal will be send anyway return; } // the current directory was deleted. Try a refresh, which will fail. An error message will // be emitted and the empty (non-existing) directory remains. refresh(); } bool DefaultFileSystem::refreshLocal(const QUrl &directory, bool onlyScan) { const QString path = KrServices::urlToLocalPath(directory); #ifdef Q_WS_WIN if (!path.contains("/")) { // change C: to C:/ path = path + QString("/"); } #endif // check if the new directory exists if (!QDir(path).exists()) { emit error(i18n("The folder %1 does not exist.", path)); return false; } // mount if needed emit aboutToOpenDir(path); // set the current directory... _currentDirectory = directory; _currentDirectory.setPath(QDir::cleanPath(_currentDirectory.path())); // Note: we are using low-level Qt functions here. // It's around twice as fast as using the QDir class. QT_DIR* dir = QT_OPENDIR(path.toLocal8Bit()); if (!dir) { emit error(i18n("Cannot open the folder %1.", path)); return false; } // change directory to the new directory const QString savedDir = QDir::currentPath(); if (!QDir::setCurrent(path)) { emit error(i18nc("%1=folder path", "Access to %1 denied", path)); QT_CLOSEDIR(dir); return false; } QT_DIRENT* dirEnt; QString name; const bool showHidden = showHiddenFiles(); while ((dirEnt = QT_READDIR(dir)) != NULL) { name = QString::fromLocal8Bit(dirEnt->d_name); // show hidden files? if (!showHidden && name.left(1) == ".") continue; // we don't need the "." and ".." entries if (name == "." || name == "..") continue; FileItem* temp = createLocalFileItem(name); addFileItem(temp); } // clean up QT_CLOSEDIR(dir); QDir::setCurrent(savedDir); if (!onlyScan) { // start watching the new dir for file changes _watcher = new KDirWatch(this); // if the current dir is a link path the watcher needs to watch the real path - and signal // parameters will be the real path _watcher->addDir(realPath(), KDirWatch::WatchFiles); connect(_watcher.data(), &KDirWatch::dirty, this, &DefaultFileSystem::slotWatcherDirty); // NOTE: not connecting 'created' signal. A 'dirty' is send after that anyway - //connect(_watcher, SIGNAL(created(QString)), this, SLOT(slotWatcherCreated(QString))); + //connect(_watcher.data(), &KDirWatch::created, this, &DefaultFileSystem::slotWatcherCreated); connect(_watcher.data(), &KDirWatch::deleted, this, &DefaultFileSystem::slotWatcherDeleted); _watcher->startScan(false); } return true; } FileItem *DefaultFileSystem::createLocalFileItem(const QString &name) { return FileSystem::createLocalFileItem(name, _currentDirectory.path()); } QString DefaultFileSystem::DefaultFileSystem::realPath() { // NOTE: current dir must exist return QDir(_currentDirectory.toLocalFile()).canonicalPath(); } QUrl DefaultFileSystem::resolveRelativePath(const QUrl &url) { // if e.g. "/tmp/bin" is a link to "/bin", // resolve "/tmp/bin/.." to "/tmp" and not "/" return url.adjusted(QUrl::NormalizePathSegments); } diff --git a/krusader/Filter/advancedfilter.cpp b/krusader/Filter/advancedfilter.cpp index 40787741..b37be22b 100644 --- a/krusader/Filter/advancedfilter.cpp +++ b/krusader/Filter/advancedfilter.cpp @@ -1,612 +1,612 @@ /***************************************************************************** * Copyright (C) 2003 Shie Erlich * * Copyright (C) 2003 Rafi Yanai * * Copyright (C) 2003 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 "advancedfilter.h" // QtCore #include #include #include // QtGui #include // QtWidgets #include #include #include #include #include #include #include #include #include #include "../krglobal.h" #include "../icon.h" #include "../Dialogs/krdialogs.h" #define USERSFILE QString("/etc/passwd") #define GROUPSFILE QString("/etc/group") AdvancedFilter::AdvancedFilter(FilterTabs *tabs, QWidget *parent) : QWidget(parent), fltTabs(tabs) { QGridLayout *filterLayout = new QGridLayout(this); filterLayout->setSpacing(6); filterLayout->setContentsMargins(11, 11, 11, 11); // Options for size QGroupBox *sizeGroup = new QGroupBox(this); QSizePolicy sizeGroupPolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); sizeGroupPolicy.setHeightForWidth(sizeGroup->sizePolicy().hasHeightForWidth()); sizeGroup->setSizePolicy(sizeGroupPolicy); sizeGroup->setTitle(i18n("Size")); QGridLayout *sizeLayout = new QGridLayout(sizeGroup); sizeLayout->setAlignment(Qt::AlignTop); sizeLayout->setSpacing(6); sizeLayout->setContentsMargins(11, 11, 11, 11); minSizeEnabled = new QCheckBox(sizeGroup); minSizeEnabled->setText(i18n("At Least")); minSizeEnabled->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); sizeLayout->addWidget(minSizeEnabled, 0, 0); minSizeAmount = new QSpinBox(sizeGroup); minSizeAmount->setRange(0, 999999999); minSizeAmount->setEnabled(false); sizeLayout->addWidget(minSizeAmount, 0, 1); minSizeType = new KComboBox(false, sizeGroup); // i18n: @item:inlistbox next to a text field containing the amount minSizeType->addItem(i18n("Byte")); // i18n: @item:inlistbox next to a text field containing the amount minSizeType->addItem(i18n("KiB")); // i18n: @item:inlistbox next to a text field containing the amount minSizeType->addItem(i18n("MiB")); // i18n: @item:inlistbox next to a text field containing the amount minSizeType->addItem(i18n("GiB")); minSizeType->setEnabled(false); sizeLayout->addWidget(minSizeType, 0, 2); maxSizeEnabled = new QCheckBox(sizeGroup); maxSizeEnabled->setText(i18n("At Most")); maxSizeEnabled->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); sizeLayout->addWidget(maxSizeEnabled, 0, 3); maxSizeAmount = new QSpinBox(sizeGroup); maxSizeAmount->setRange(0, 999999999); maxSizeAmount->setEnabled(false); sizeLayout->addWidget(maxSizeAmount, 0, 4); maxSizeType = new KComboBox(false, sizeGroup); // i18n: @item:inlistbox next to a text field containing the amount maxSizeType->addItem(i18n("Byte")); // i18n: @item:inlistbox next to a text field containing the amount maxSizeType->addItem(i18n("KiB")); // i18n: @item:inlistbox next to a text field containing the amount maxSizeType->addItem(i18n("MiB")); // i18n: @item:inlistbox next to a text field containing the amount maxSizeType->addItem(i18n("GiB")); maxSizeType->setEnabled(false); sizeLayout->addWidget(maxSizeType, 0, 5); filterLayout->addWidget(sizeGroup, 0, 0); // Options for date Icon iconDate("view-calendar"); QGroupBox *dateGroup = new QGroupBox(this); QButtonGroup *btnGroup = new QButtonGroup(dateGroup); dateGroup->setTitle(i18n("Date")); btnGroup->setExclusive(true); QGridLayout *dateLayout = new QGridLayout(dateGroup); dateLayout->setAlignment(Qt::AlignTop); dateLayout->setSpacing(6); dateLayout->setContentsMargins(11, 11, 11, 11); anyDateEnabled = new QRadioButton(dateGroup); anyDateEnabled->setText(i18n("Any date")); btnGroup->addButton(anyDateEnabled); anyDateEnabled->setChecked(true); modifiedBetweenEnabled = new QRadioButton(dateGroup); modifiedBetweenEnabled->setText(i18n("&Modified between")); btnGroup->addButton(modifiedBetweenEnabled); modifiedBetweenData1 = new KLineEdit(dateGroup); modifiedBetweenData1->setEnabled(false); modifiedBetweenData1->setText(""); modifiedBetweenBtn1 = new QToolButton(dateGroup); modifiedBetweenBtn1->setEnabled(false); modifiedBetweenBtn1->setText(""); modifiedBetweenBtn1->setIcon(iconDate); QLabel *andLabel = new QLabel(dateGroup); andLabel->setText(i18n("an&d")); modifiedBetweenData2 = new KLineEdit(dateGroup); modifiedBetweenData2->setEnabled(false); modifiedBetweenData2->setText(""); andLabel->setBuddy(modifiedBetweenData2); modifiedBetweenBtn2 = new QToolButton(dateGroup); modifiedBetweenBtn2->setEnabled(false); modifiedBetweenBtn2->setText(""); modifiedBetweenBtn2->setIcon(iconDate); notModifiedAfterEnabled = new QRadioButton(dateGroup); notModifiedAfterEnabled->setText(i18n("&Not modified after")); btnGroup->addButton(notModifiedAfterEnabled); notModifiedAfterData = new KLineEdit(dateGroup); notModifiedAfterData->setEnabled(false); notModifiedAfterData->setText(""); notModifiedAfterBtn = new QToolButton(dateGroup); notModifiedAfterBtn->setEnabled(false); notModifiedAfterBtn->setText(""); notModifiedAfterBtn->setIcon(iconDate); modifiedInTheLastEnabled = new QRadioButton(dateGroup); modifiedInTheLastEnabled->setText(i18n("Mod&ified in the last")); btnGroup->addButton(modifiedInTheLastEnabled); modifiedInTheLastData = new QSpinBox(dateGroup); modifiedInTheLastData->setRange(0, 99999); modifiedInTheLastData->setEnabled(false); modifiedInTheLastType = new KComboBox(dateGroup); modifiedInTheLastType->addItem(i18n("days")); modifiedInTheLastType->addItem(i18n("weeks")); modifiedInTheLastType->addItem(i18n("months")); modifiedInTheLastType->addItem(i18n("years")); modifiedInTheLastType->setEnabled(false); notModifiedInTheLastData = new QSpinBox(dateGroup); notModifiedInTheLastData->setRange(0, 99999); notModifiedInTheLastData->setEnabled(false); QLabel *notModifiedInTheLastLbl = new QLabel(dateGroup); notModifiedInTheLastLbl->setText(i18n("No&t modified in the last")); notModifiedInTheLastLbl->setBuddy(notModifiedInTheLastData); notModifiedInTheLastType = new KComboBox(dateGroup); notModifiedInTheLastType->addItem(i18n("days")); notModifiedInTheLastType->addItem(i18n("weeks")); notModifiedInTheLastType->addItem(i18n("months")); notModifiedInTheLastType->addItem(i18n("years")); notModifiedInTheLastType->setEnabled(false); // Date options layout dateLayout->addWidget(anyDateEnabled, 0, 0); dateLayout->addWidget(modifiedBetweenEnabled, 1, 0); dateLayout->addWidget(modifiedBetweenData1, 1, 1); dateLayout->addWidget(modifiedBetweenBtn1, 1, 2); dateLayout->addWidget(andLabel, 1, 3); dateLayout->addWidget(modifiedBetweenData2, 1, 4); dateLayout->addWidget(modifiedBetweenBtn2, 1, 5); dateLayout->addWidget(notModifiedAfterEnabled, 2, 0); dateLayout->addWidget(notModifiedAfterData, 2, 1); dateLayout->addWidget(notModifiedAfterBtn, 2, 2); dateLayout->addWidget(modifiedInTheLastEnabled, 3, 0); QHBoxLayout *modifiedInTheLastLayout = new QHBoxLayout(); modifiedInTheLastLayout->addWidget(modifiedInTheLastData); modifiedInTheLastLayout->addWidget(modifiedInTheLastType); dateLayout->addLayout(modifiedInTheLastLayout, 3, 1); dateLayout->addWidget(notModifiedInTheLastLbl, 4, 0); modifiedInTheLastLayout = new QHBoxLayout(); modifiedInTheLastLayout->addWidget(notModifiedInTheLastData); modifiedInTheLastLayout->addWidget(notModifiedInTheLastType); dateLayout->addLayout(modifiedInTheLastLayout, 4, 1); filterLayout->addWidget(dateGroup, 1, 0); // Options for ownership QGroupBox *ownershipGroup = new QGroupBox(this); ownershipGroup->setTitle(i18n("Ownership")); QGridLayout *ownershipLayout = new QGridLayout(ownershipGroup); ownershipLayout->setAlignment(Qt::AlignTop); ownershipLayout->setSpacing(6); ownershipLayout->setContentsMargins(11, 11, 11, 11); QHBoxLayout *hboxLayout = new QHBoxLayout(); hboxLayout->setSpacing(6); hboxLayout->setContentsMargins(0, 0, 0, 0); belongsToUserEnabled = new QCheckBox(ownershipGroup); belongsToUserEnabled->setText(i18n("Belongs to &user")); hboxLayout->addWidget(belongsToUserEnabled); belongsToUserData = new KComboBox(ownershipGroup); belongsToUserData->setEnabled(false); belongsToUserData->setEditable(false); hboxLayout->addWidget(belongsToUserData); belongsToGroupEnabled = new QCheckBox(ownershipGroup); belongsToGroupEnabled->setText(i18n("Belongs to gr&oup")); hboxLayout->addWidget(belongsToGroupEnabled); belongsToGroupData = new KComboBox(ownershipGroup); belongsToGroupData->setEnabled(false); belongsToGroupData->setEditable(false); hboxLayout->addWidget(belongsToGroupData); ownershipLayout->addLayout(hboxLayout, 0, 0, 1, 4); permissionsEnabled = new QCheckBox(ownershipGroup); permissionsEnabled->setText(i18n("P&ermissions")); ownershipLayout->addWidget(permissionsEnabled, 1, 0); QGroupBox *ownerGroup = new QGroupBox(ownershipGroup); QHBoxLayout *ownerHBox = new QHBoxLayout(ownerGroup); ownerGroup->setTitle(i18n("O&wner")); ownerR = new KComboBox(ownerGroup); ownerR->addItem(i18n("?")); ownerR->addItem(i18n("r")); ownerR->addItem(i18n("-")); ownerR->setEnabled(false); ownerHBox->addWidget(ownerR); ownerW = new KComboBox(ownerGroup); ownerW->addItem(i18n("?")); ownerW->addItem(i18n("w")); ownerW->addItem(i18n("-")); ownerW->setEnabled(false); ownerHBox->addWidget(ownerW); ownerX = new KComboBox(ownerGroup); ownerX->addItem(i18n("?")); ownerX->addItem(i18n("x")); ownerX->addItem(i18n("-")); ownerX->setEnabled(false); ownerHBox->addWidget(ownerX); ownershipLayout->addWidget(ownerGroup, 1, 1); QGroupBox *groupGroup = new QGroupBox(ownershipGroup); QHBoxLayout *groupHBox = new QHBoxLayout(groupGroup); groupGroup->setTitle(i18n("Grou&p")); groupR = new KComboBox(groupGroup); groupR->addItem(i18n("?")); groupR->addItem(i18n("r")); groupR->addItem(i18n("-")); groupR->setEnabled(false); groupHBox->addWidget(groupR); groupW = new KComboBox(groupGroup); groupW->addItem(i18n("?")); groupW->addItem(i18n("w")); groupW->addItem(i18n("-")); groupW->setEnabled(false); groupHBox->addWidget(groupW); groupX = new KComboBox(groupGroup); groupX->addItem(i18n("?")); groupX->addItem(i18n("x")); groupX->addItem(i18n("-")); groupX->setEnabled(false); groupHBox->addWidget(groupX); ownershipLayout->addWidget(groupGroup, 1, 2); QGroupBox *allGroup = new QGroupBox(ownershipGroup); QHBoxLayout *allHBox = new QHBoxLayout(allGroup); allGroup->setTitle(i18n("A&ll")); allR = new KComboBox(allGroup); allR->addItem(i18n("?")); allR->addItem(i18n("r")); allR->addItem(i18n("-")); allR->setEnabled(false); allHBox->addWidget(allR); allW = new KComboBox(allGroup); allW->addItem(i18n("?")); allW->addItem(i18n("w")); allW->addItem(i18n("-")); allW->setEnabled(false); allHBox->addWidget(allW); allX = new KComboBox(allGroup); allX->addItem(i18n("?")); allX->addItem(i18n("x")); allX->addItem(i18n("-")); allX->setEnabled(false); allHBox->addWidget(allX); ownershipLayout->addWidget(allGroup, 1, 3); QLabel *infoLabel = new QLabel(ownershipGroup); QFont infoLabel_font(infoLabel->font()); infoLabel_font.setFamily("adobe-helvetica"); infoLabel_font.setItalic(true); infoLabel->setFont(infoLabel_font); infoLabel->setText(i18n("Note: a '?' is a wildcard")); ownershipLayout->addWidget(infoLabel, 2, 0, 1, 4, Qt::AlignRight); filterLayout->addWidget(ownershipGroup, 2, 0); // Connection table - connect(minSizeEnabled, SIGNAL(toggled(bool)), minSizeAmount, SLOT(setEnabled(bool))); - connect(minSizeEnabled, SIGNAL(toggled(bool)), minSizeType, SLOT(setEnabled(bool))); - connect(maxSizeEnabled, SIGNAL(toggled(bool)), maxSizeAmount, SLOT(setEnabled(bool))); - connect(maxSizeEnabled, SIGNAL(toggled(bool)), maxSizeType, SLOT(setEnabled(bool))); - connect(modifiedBetweenEnabled, SIGNAL(toggled(bool)), modifiedBetweenData1, SLOT(setEnabled(bool))); - connect(modifiedBetweenEnabled, SIGNAL(toggled(bool)), modifiedBetweenBtn1, SLOT(setEnabled(bool))); - connect(modifiedBetweenEnabled, SIGNAL(toggled(bool)), modifiedBetweenData2, SLOT(setEnabled(bool))); - connect(modifiedBetweenEnabled, SIGNAL(toggled(bool)), modifiedBetweenBtn2, SLOT(setEnabled(bool))); - connect(notModifiedAfterEnabled, SIGNAL(toggled(bool)), notModifiedAfterData, SLOT(setEnabled(bool))); - connect(notModifiedAfterEnabled, SIGNAL(toggled(bool)), notModifiedAfterBtn, SLOT(setEnabled(bool))); - connect(modifiedInTheLastEnabled, SIGNAL(toggled(bool)), modifiedInTheLastData, SLOT(setEnabled(bool))); - connect(modifiedInTheLastEnabled, SIGNAL(toggled(bool)), modifiedInTheLastType, SLOT(setEnabled(bool))); - connect(modifiedInTheLastEnabled, SIGNAL(toggled(bool)), notModifiedInTheLastData, SLOT(setEnabled(bool))); - connect(modifiedInTheLastEnabled, SIGNAL(toggled(bool)), notModifiedInTheLastType, SLOT(setEnabled(bool))); - connect(belongsToUserEnabled, SIGNAL(toggled(bool)), belongsToUserData, SLOT(setEnabled(bool))); - connect(belongsToGroupEnabled, SIGNAL(toggled(bool)), belongsToGroupData, SLOT(setEnabled(bool))); - connect(permissionsEnabled, SIGNAL(toggled(bool)), ownerR, SLOT(setEnabled(bool))); - connect(permissionsEnabled, SIGNAL(toggled(bool)), ownerW, SLOT(setEnabled(bool))); - connect(permissionsEnabled, SIGNAL(toggled(bool)), ownerX, SLOT(setEnabled(bool))); - connect(permissionsEnabled, SIGNAL(toggled(bool)), groupR, SLOT(setEnabled(bool))); - connect(permissionsEnabled, SIGNAL(toggled(bool)), groupW, SLOT(setEnabled(bool))); - connect(permissionsEnabled, SIGNAL(toggled(bool)), groupX, SLOT(setEnabled(bool))); - connect(permissionsEnabled, SIGNAL(toggled(bool)), allR, SLOT(setEnabled(bool))); - connect(permissionsEnabled, SIGNAL(toggled(bool)), allW, SLOT(setEnabled(bool))); - connect(permissionsEnabled, SIGNAL(toggled(bool)), allX, SLOT(setEnabled(bool))); - connect(modifiedBetweenBtn1, SIGNAL(clicked()), this, SLOT(modifiedBetweenSetDate1())); - connect(modifiedBetweenBtn2, SIGNAL(clicked()), this, SLOT(modifiedBetweenSetDate2())); - connect(notModifiedAfterBtn, SIGNAL(clicked()), this, SLOT(notModifiedAfterSetDate())); + connect(minSizeEnabled, &QCheckBox::toggled, minSizeAmount, &QSpinBox::setEnabled); + connect(minSizeEnabled, &QCheckBox::toggled, minSizeType, &KComboBox::setEnabled); + connect(maxSizeEnabled, &QCheckBox::toggled, maxSizeAmount, &QSpinBox::setEnabled); + connect(maxSizeEnabled, &QCheckBox::toggled, maxSizeType, &KComboBox::setEnabled); + connect(modifiedBetweenEnabled, &QRadioButton::toggled, modifiedBetweenData1, &KLineEdit::setEnabled); + connect(modifiedBetweenEnabled, &QRadioButton::toggled, modifiedBetweenBtn1, &QToolButton::setEnabled); + connect(modifiedBetweenEnabled, &QRadioButton::toggled, modifiedBetweenData2, &KLineEdit::setEnabled); + connect(modifiedBetweenEnabled, &QRadioButton::toggled, modifiedBetweenBtn2, &QToolButton::setEnabled); + connect(notModifiedAfterEnabled, &QRadioButton::toggled, notModifiedAfterData, &KLineEdit::setEnabled); + connect(notModifiedAfterEnabled, &QRadioButton::toggled, notModifiedAfterBtn, &QToolButton::setEnabled); + connect(modifiedInTheLastEnabled, &QRadioButton::toggled, modifiedInTheLastData, &QSpinBox::setEnabled); + connect(modifiedInTheLastEnabled, &QRadioButton::toggled, modifiedInTheLastType, &KComboBox::setEnabled); + connect(modifiedInTheLastEnabled, &QRadioButton::toggled, notModifiedInTheLastData, &QSpinBox::setEnabled); + connect(modifiedInTheLastEnabled, &QRadioButton::toggled, notModifiedInTheLastType, &KComboBox::setEnabled); + connect(belongsToUserEnabled, &QCheckBox::toggled, belongsToUserData, &KComboBox::setEnabled); + connect(belongsToGroupEnabled, &QCheckBox::toggled, belongsToGroupData, &KComboBox::setEnabled); + connect(permissionsEnabled, &QCheckBox::toggled, ownerR, &KComboBox::setEnabled); + connect(permissionsEnabled, &QCheckBox::toggled, ownerW, &KComboBox::setEnabled); + connect(permissionsEnabled, &QCheckBox::toggled, ownerX, &KComboBox::setEnabled); + connect(permissionsEnabled, &QCheckBox::toggled, groupR, &KComboBox::setEnabled); + connect(permissionsEnabled, &QCheckBox::toggled, groupW, &KComboBox::setEnabled); + connect(permissionsEnabled, &QCheckBox::toggled, groupX, &KComboBox::setEnabled); + connect(permissionsEnabled, &QCheckBox::toggled, allR, &KComboBox::setEnabled); + connect(permissionsEnabled, &QCheckBox::toggled, allW, &KComboBox::setEnabled); + connect(permissionsEnabled, &QCheckBox::toggled, allX, &KComboBox::setEnabled); + connect(modifiedBetweenBtn1, &QToolButton::clicked, this, &AdvancedFilter::modifiedBetweenSetDate1); + connect(modifiedBetweenBtn2, &QToolButton::clicked, this, &AdvancedFilter::modifiedBetweenSetDate2); + connect(notModifiedAfterBtn, &QToolButton::clicked, this, &AdvancedFilter::notModifiedAfterSetDate); // fill the users and groups list fillList(belongsToUserData, USERSFILE); fillList(belongsToGroupData, GROUPSFILE); // tab order setTabOrder(minSizeEnabled, minSizeAmount); setTabOrder(minSizeAmount, maxSizeEnabled); setTabOrder(maxSizeEnabled, maxSizeAmount); setTabOrder(maxSizeAmount, modifiedBetweenEnabled); setTabOrder(modifiedBetweenEnabled, modifiedBetweenData1); setTabOrder(modifiedBetweenData1, modifiedBetweenData2); setTabOrder(modifiedBetweenData2, notModifiedAfterEnabled); setTabOrder(notModifiedAfterEnabled, notModifiedAfterData); setTabOrder(notModifiedAfterData, modifiedInTheLastEnabled); setTabOrder(modifiedInTheLastEnabled, modifiedInTheLastData); setTabOrder(modifiedInTheLastData, notModifiedInTheLastData); setTabOrder(notModifiedInTheLastData, belongsToUserEnabled); setTabOrder(belongsToUserEnabled, belongsToUserData); setTabOrder(belongsToUserData, belongsToGroupEnabled); setTabOrder(belongsToGroupEnabled, belongsToGroupData); setTabOrder(belongsToGroupData, permissionsEnabled); setTabOrder(permissionsEnabled, ownerR); setTabOrder(ownerR, ownerW); setTabOrder(ownerW, ownerX); setTabOrder(ownerX, groupR); setTabOrder(groupR, groupW); setTabOrder(groupW, groupX); setTabOrder(groupX, allR); setTabOrder(allR, allW); setTabOrder(allW, allX); setTabOrder(allX, minSizeType); setTabOrder(minSizeType, maxSizeType); setTabOrder(maxSizeType, modifiedInTheLastType); setTabOrder(modifiedInTheLastType, notModifiedInTheLastType); } void AdvancedFilter::modifiedBetweenSetDate1() { changeDate(modifiedBetweenData1); } void AdvancedFilter::modifiedBetweenSetDate2() { changeDate(modifiedBetweenData2); } void AdvancedFilter::notModifiedAfterSetDate() { changeDate(notModifiedAfterData); } void AdvancedFilter::changeDate(KLineEdit *p) { // check if the current date is valid QDate d = stringToDate(p->text()); if (!d.isValid()) d = QDate::currentDate(); KRGetDate *gd = new KRGetDate(d, this); d = gd->getDate(); // if a user pressed ESC or closed the dialog, we'll return an invalid date if (d.isValid()) p->setText(dateToString(d)); delete gd; } void AdvancedFilter::fillList(KComboBox *list, QString filename) { QFile data(filename); if (!data.open(QIODevice::ReadOnly)) { qWarning() << "Search: Unable to read " << filename << " !!!"; return; } // and read it into the temporary array QTextStream t(&data); while (!t.atEnd()) { QString s = t.readLine(); QString name = s.left(s.indexOf(':')); if (!name.startsWith('#')) list->addItem(name); } } void AdvancedFilter::invalidDateMessage(KLineEdit *p) { // FIXME p->text() is empty sometimes (to reproduce, set date to "13.09.005") KMessageBox::detailedError(this, i18n("Invalid date entered."), i18n("The date %1 is not valid according to your locale. Please re-enter a valid date (use the date button for easy access).", p->text())); p->setFocus(); } bool AdvancedFilter::getSettings(FilterSettings &s) { s.minSizeEnabled = minSizeEnabled->isChecked(); s.minSize.amount = minSizeAmount->value(); s.minSize.unit = static_cast(minSizeType->currentIndex()); s.maxSizeEnabled = maxSizeEnabled->isChecked(); s.maxSize.amount = maxSizeAmount->value(); s.maxSize.unit = static_cast(maxSizeType->currentIndex()); if (s.minSizeEnabled && s.maxSizeEnabled && (s.maxSize.size() < s.minSize.size())) { KMessageBox::detailedError(this, i18n("Specified sizes are inconsistent."), i18n("Please re-enter the values, so that the left side size " "will be smaller than (or equal to) the right side size.")); minSizeAmount->setFocus(); return false; } s.modifiedBetweenEnabled = modifiedBetweenEnabled->isChecked(); s.modifiedBetween1 = stringToDate(modifiedBetweenData1->text()); s.modifiedBetween2 = stringToDate(modifiedBetweenData2->text()); if (s.modifiedBetweenEnabled) { // check if date is valid if (!s.modifiedBetween1.isValid()) { invalidDateMessage(modifiedBetweenData1); return false; } else if (!s.modifiedBetween2.isValid()) { invalidDateMessage(modifiedBetweenData2); return false; } else if (s.modifiedBetween1 > s.modifiedBetween2) { KMessageBox::detailedError(this, i18n("Dates are inconsistent."), i18n("The date on the left is later than the date on the right. " "Please re-enter the dates, so that the left side date " "will be earlier than the right side date.")); modifiedBetweenData1->setFocus(); return false; } } s.notModifiedAfterEnabled = notModifiedAfterEnabled->isChecked(); s.notModifiedAfter = stringToDate(notModifiedAfterData->text()); if(s.notModifiedAfterEnabled && !s.notModifiedAfter.isValid()) { invalidDateMessage(notModifiedAfterData); return false; } s.modifiedInTheLastEnabled = modifiedInTheLastEnabled->isChecked(); s.modifiedInTheLast.amount = modifiedInTheLastData->value(); s.modifiedInTheLast.unit = static_cast(modifiedInTheLastType->currentIndex()); s.notModifiedInTheLast.amount = notModifiedInTheLastData->value(); s.notModifiedInTheLast.unit = static_cast(notModifiedInTheLastType->currentIndex()); if (s.modifiedInTheLastEnabled && s.modifiedInTheLast.amount && s.notModifiedInTheLast.amount) { if (s.modifiedInTheLast.days() < s.notModifiedInTheLast.days()) { KMessageBox::detailedError(this, i18n("Dates are inconsistent."), i18n("The date on top is later than the date on the bottom. " "Please re-enter the dates, so that the top date " "will be earlier than the bottom date.")); modifiedInTheLastData->setFocus(); return false; } } s.ownerEnabled = belongsToUserEnabled->isChecked(); s.owner = belongsToUserData->currentText(); s.groupEnabled = belongsToGroupEnabled->isChecked(); s.group = belongsToGroupData->currentText(); s.permissionsEnabled = permissionsEnabled->isChecked(); s.permissions = ownerR->currentText() + ownerW->currentText() + ownerX->currentText() + groupR->currentText() + groupW->currentText() + groupX->currentText() + allR->currentText() + allW->currentText() + allX->currentText(); return true; } void AdvancedFilter::applySettings(const FilterSettings &s) { minSizeEnabled->setChecked(s.minSizeEnabled); minSizeAmount->setValue(s.minSize.amount); minSizeType->setCurrentIndex(s.minSize.unit); maxSizeEnabled->setChecked(s.maxSizeEnabled); maxSizeAmount->setValue(s.maxSize.amount); maxSizeType->setCurrentIndex(s.maxSize.unit); if (s.modifiedBetweenEnabled) modifiedBetweenEnabled->setChecked(true); else if (s.notModifiedAfterEnabled) notModifiedAfterEnabled->setChecked(true); else if (s.modifiedInTheLastEnabled) modifiedInTheLastEnabled->setChecked(true); else anyDateEnabled->setChecked(true); modifiedBetweenData1->setText(dateToString(s.modifiedBetween1)); modifiedBetweenData2->setText(dateToString(s.modifiedBetween2)); notModifiedAfterData->setText(dateToString(s.notModifiedAfter)); modifiedInTheLastData->setValue(s.modifiedInTheLast.amount); modifiedInTheLastType->setCurrentIndex(s.modifiedInTheLast.unit); notModifiedInTheLastData->setValue(s.notModifiedInTheLast.amount); notModifiedInTheLastType->setCurrentIndex(s.notModifiedInTheLast.unit); belongsToUserEnabled->setChecked(s.ownerEnabled); setComboBoxValue(belongsToUserData, s.owner); belongsToGroupEnabled->setChecked(s.groupEnabled); setComboBoxValue(belongsToGroupData, s.group); permissionsEnabled->setChecked(s.permissionsEnabled); QString perm = s.permissions; if (perm.length() != 9) perm = "?????????"; setComboBoxValue(ownerR, QString(perm[0])); setComboBoxValue(ownerW, QString(perm[1])); setComboBoxValue(ownerX, QString(perm[2])); setComboBoxValue(groupR, QString(perm[3])); setComboBoxValue(groupW, QString(perm[4])); setComboBoxValue(groupX, QString(perm[5])); setComboBoxValue(allR, QString(perm[6])); setComboBoxValue(allW, QString(perm[7])); setComboBoxValue(allX, QString(perm[8])); } diff --git a/krusader/Filter/filterdialog.cpp b/krusader/Filter/filterdialog.cpp index 68c74f44..7486eb59 100644 --- a/krusader/Filter/filterdialog.cpp +++ b/krusader/Filter/filterdialog.cpp @@ -1,106 +1,106 @@ /***************************************************************************** * 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 "filterdialog.h" #include "filtertabs.h" #include "generalfilter.h" // QtWidgets #include #include #include #include FilterDialog::FilterDialog(QWidget *parent, QString caption, QStringList extraOptions, bool modal) : QDialog(parent) { setWindowTitle(caption.isNull() ? i18n("Krusader::Choose Files") : caption); setModal(modal); QVBoxLayout *mainLayout = new QVBoxLayout; setLayout(mainLayout); QTabWidget *filterWidget = new QTabWidget; filterTabs = FilterTabs::addTo(filterWidget, FilterTabs::HasProfileHandler, extraOptions); generalFilter = static_cast (filterTabs->get("GeneralFilter")); mainLayout->addWidget(filterWidget); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel|QDialogButtonBox::Reset); mainLayout->addWidget(buttonBox); QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); okButton->setDefault(true); okButton->setShortcut(Qt::CTRL | Qt::Key_Return); - connect(buttonBox, SIGNAL(accepted()), SLOT(slotOk())); - connect(buttonBox, SIGNAL(rejected()), SLOT(reject())); - connect(buttonBox->button(QDialogButtonBox::Reset), SIGNAL(clicked()), SLOT(slotReset())); - connect(filterTabs, SIGNAL(closeRequest(bool)), this, SLOT(slotCloseRequest(bool))); + connect(buttonBox, &QDialogButtonBox::accepted, this, &FilterDialog::slotOk); + connect(buttonBox, &QDialogButtonBox::rejected, this, &FilterDialog::reject); + connect(buttonBox->button(QDialogButtonBox::Reset), &QPushButton::clicked, this, &FilterDialog::slotReset); + connect(filterTabs, &FilterTabs::closeRequest, this, &FilterDialog::slotCloseRequest); generalFilter->searchFor->setFocus(); if(modal) exec(); } void FilterDialog::applySettings(const FilterSettings &s) { filterTabs->applySettings(s); } KRQuery FilterDialog::getQuery() { return settings.toQuery(); } bool FilterDialog::isExtraOptionChecked(QString name) { return filterTabs->isExtraOptionChecked(name); } void FilterDialog::checkExtraOption(QString name, bool check) { filterTabs->checkExtraOption(name, check); } void FilterDialog::slotCloseRequest(bool doAccept) { if (doAccept) { slotOk(); accept(); } else reject(); } void FilterDialog::slotReset() { filterTabs->reset(); generalFilter->searchFor->setFocus(); } void FilterDialog::slotOk() { settings = filterTabs->getSettings(); if(settings.isValid()) accept(); } diff --git a/krusader/Filter/generalfilter.cpp b/krusader/Filter/generalfilter.cpp index 0f2555c0..717be545 100644 --- a/krusader/Filter/generalfilter.cpp +++ b/krusader/Filter/generalfilter.cpp @@ -1,666 +1,666 @@ /***************************************************************************** * Copyright (C) 2003 Shie Erlich * * Copyright (C) 2003 Rafi Yanai * * Copyright (C) 2003 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 "generalfilter.h" #include "filtertabs.h" #include "../krglobal.h" #include "../krservices.h" #include "../FileSystem/filesystem.h" // QtWidgets #include #include #include #include #include #include #include #include #include #include typedef struct { const char *description; const char *regExp; int cursorAdjustment; } term; static const term items[] = { { I18N_NOOP("Any Character"), ".", 0 }, { I18N_NOOP("Start of Line"), "^", 0 }, { I18N_NOOP("End of Line"), "$", 0 }, { I18N_NOOP("Set of Characters"), "[]", -1 }, { I18N_NOOP("Repeats, Zero or More Times"), "*", 0 }, { I18N_NOOP("Repeats, One or More Times"), "+", 0 }, { I18N_NOOP("Optional"), "?", 0 }, { I18N_NOOP("Escape"), "\\", 0 }, { I18N_NOOP("TAB"), "\\t", 0 }, { I18N_NOOP("Newline"), "\\n", 0 }, { I18N_NOOP("Carriage Return"), "\\r", 0 }, { I18N_NOOP("White Space"), "\\s", 0 }, { I18N_NOOP("Digit"), "\\d", 0 }, }; class RegExpAction : public QAction { public: RegExpAction(QObject *parent, const QString &text, const QString ®Exp, int cursor) : QAction(text, parent), mText(text), mRegExp(regExp), mCursor(cursor) { } QString text() const { return mText; } QString regExp() const { return mRegExp; } int cursor() const { return mCursor; } private: QString mText; QString mRegExp; int mCursor; }; GeneralFilter::GeneralFilter(FilterTabs *tabs, int properties, QWidget *parent, QStringList extraOptions) : QWidget(parent), profileManager(0), fltTabs(tabs) { QGridLayout *filterLayout = new QGridLayout(this); filterLayout->setSpacing(6); filterLayout->setContentsMargins(11, 11, 11, 11); this->properties = properties; // Options for name filtering QGroupBox *nameGroup = new QGroupBox(this); nameGroup->setTitle(i18n("File Name")); QGridLayout *nameGroupLayout = new QGridLayout(nameGroup); nameGroupLayout->setAlignment(Qt::AlignTop); nameGroupLayout->setSpacing(6); nameGroupLayout->setContentsMargins(11, 11, 11, 11); searchForCase = new QCheckBox(nameGroup); searchForCase->setText(i18n("&Case sensitive")); searchForCase->setChecked(false); nameGroupLayout->addWidget(searchForCase, 1, 2); QLabel *searchForLabel = new QLabel(nameGroup); searchForLabel->setText(i18n("Search &for:")); nameGroupLayout->addWidget(searchForLabel, 0, 0); searchFor = new KHistoryComboBox(false, nameGroup/*, "searchFor"*/); QSizePolicy searchForPolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); searchForPolicy.setHeightForWidth(searchFor->sizePolicy().hasHeightForWidth()); searchFor->setSizePolicy(searchForPolicy); searchFor->setEditable(true); searchFor->setDuplicatesEnabled(false); searchFor->setMaxCount(25); searchFor->setMinimumContentsLength(10); searchForLabel->setBuddy(searchFor); nameGroupLayout->addWidget(searchFor, 0, 1, 1, 2); const QString s = "

" + i18n("

The filename filtering criteria is defined here.

" "

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

" "

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

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

" "

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

" "

Examples:

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

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

"); searchFor->setWhatsThis(s); searchForLabel->setWhatsThis(s); QLabel *searchType = new QLabel(nameGroup); searchType->setText(i18n("&Of type:")); nameGroupLayout->addWidget(searchType, 1, 0); ofType = new KComboBox(false, nameGroup); ofType->setObjectName("ofType"); QSizePolicy ofTypePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); ofTypePolicy.setHeightForWidth(ofType->sizePolicy().hasHeightForWidth()); ofType->setSizePolicy(ofTypePolicy); ofType->setEditable(false); searchType->setBuddy(ofType); ofType->addItem(i18n("All Files")); ofType->addItem(i18n("Archives")); ofType->addItem(i18n("Folders")); ofType->addItem(i18n("Image Files")); ofType->addItem(i18n("Text Files")); ofType->addItem(i18n("Video Files")); ofType->addItem(i18n("Audio Files")); - connect(ofType, SIGNAL(currentIndexChanged(int)), this, SLOT(slotDisable())); + connect(ofType, QOverload::of(&KComboBox::currentIndexChanged), this, &GeneralFilter::slotDisable); nameGroupLayout->addWidget(ofType, 1, 1); filterLayout->addWidget(nameGroup, 0, 0); middleLayout = new QHBoxLayout(); middleLayout->setSpacing(6); middleLayout->setContentsMargins(0, 0, 0, 0); if (properties & FilterTabs::HasProfileHandler) { // The profile handler QGroupBox *profileHandler = new QGroupBox(this); profileHandler->setTitle(i18n("&Profile handler")); QGridLayout *profileLayout = new QGridLayout(profileHandler); profileLayout->setAlignment(Qt::AlignTop); profileLayout->setSpacing(6); profileLayout->setContentsMargins(11, 11, 11, 11); profileListBox = new KrListWidget(profileHandler); profileLayout->addWidget(profileListBox, 0, 0, 4, 1); profileAddBtn = new QPushButton(profileHandler); KStandardGuiItem::assign(profileAddBtn, KStandardGuiItem::Add); profileLayout->addWidget(profileAddBtn, 0, 1); profileLoadBtn = new QPushButton(i18n("&Load"), profileHandler); profileLoadBtn->setEnabled(false); profileLayout->addWidget(profileLoadBtn, 1, 1); profileOverwriteBtn = new QPushButton(profileHandler); profileOverwriteBtn->setEnabled(false); KStandardGuiItem::assign(profileOverwriteBtn, KStandardGuiItem::Overwrite); profileLayout->addWidget(profileOverwriteBtn, 2, 1); profileRemoveBtn = new QPushButton(profileHandler); profileRemoveBtn->setEnabled(false); KStandardGuiItem::assign(profileRemoveBtn, KStandardGuiItem::Remove); profileLayout->addWidget(profileRemoveBtn, 3, 1); profileManager = new ProfileManager("SelectionProfile", this); profileManager->hide(); middleLayout->addWidget(profileHandler); refreshProfileListBox(); } if (properties & FilterTabs::HasSearchIn) { // Options for search in QGroupBox *searchGroupBox = new QGroupBox(i18n("Searc&h in"), this); QGridLayout *searchLayout = new QGridLayout(searchGroupBox); searchLayout->setAlignment(Qt::AlignTop); searchLayout->setSpacing(6); searchLayout->setContentsMargins(11, 11, 11, 11); searchIn = new KURLListRequester(KURLListRequester::RequestDirs, searchGroupBox); searchLayout->addWidget(searchIn, 0, 0); connect(searchIn, &KURLListRequester::changed, this, &GeneralFilter::slotDisable); middleLayout->addWidget(searchGroupBox); } if (properties & FilterTabs::HasDontSearchIn) { // Options for don't search in QGroupBox *searchGroupBox = new QGroupBox(i18n("&Do not search in"), this); QGridLayout *searchLayout = new QGridLayout(searchGroupBox); searchLayout->setAlignment(Qt::AlignTop); searchLayout->setSpacing(6); searchLayout->setContentsMargins(11, 11, 11, 11); dontSearchIn = new KURLListRequester(KURLListRequester::RequestDirs, searchGroupBox); searchLayout->addWidget(dontSearchIn, 0, 0, 1, 2); if (properties & FilterTabs::HasRecurseOptions) { KConfigGroup group(krConfig, "Search"); useExcludeFolderNames = createExcludeCheckBox(group); searchLayout->addWidget(useExcludeFolderNames, 1, 0, 1, 1); excludeFolderNames = createExcludeComboBox(group); searchLayout->addWidget(excludeFolderNames, 1, 1, 1, 1); if (!useExcludeFolderNames->isChecked()) { excludeFolderNames->setDisabled(true); } connect(useExcludeFolderNames, &QCheckBox::toggled, excludeFolderNames, &KHistoryComboBox::setEnabled); } middleLayout->addWidget(searchGroupBox); } filterLayout->addLayout(middleLayout, 1, 0); // Options for containing text QGroupBox *containsGroup = new QGroupBox(this); containsGroup->setTitle(i18n("Containing text")); QGridLayout *containsLayout = new QGridLayout(containsGroup); containsLayout->setAlignment(Qt::AlignTop); containsLayout->setSpacing(6); containsLayout->setContentsMargins(11, 11, 11, 11); QHBoxLayout *containsTextLayout = new QHBoxLayout(); containsTextLayout->setSpacing(6); containsTextLayout->setContentsMargins(0, 0, 0, 0); containsLabel = new QLabel(containsGroup); QSizePolicy containsLabelPolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); containsLabelPolicy.setHeightForWidth(containsLabel->sizePolicy().hasHeightForWidth()); containsLabel->setSizePolicy(containsLabelPolicy); containsLabel->setText(i18n("&Text:")); containsTextLayout->addWidget(containsLabel); containsText = new KHistoryComboBox(false, containsGroup/*, "containsText"*/); QSizePolicy containsTextPolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); containsTextPolicy.setHeightForWidth(containsText->sizePolicy().hasHeightForWidth()); containsText->setSizePolicy(containsTextPolicy); containsText->setDuplicatesEnabled(false); containsText->setMaxCount(25); containsText->setMinimumContentsLength(10); containsTextLayout->addWidget(containsText); containsLabel->setBuddy(containsText); containsRegExp = new QToolButton(containsGroup); containsRegExp->setPopupMode(QToolButton::MenuButtonPopup); containsRegExp->setCheckable(true); containsRegExp->setText(i18n("RegExp")); // Populate the popup menu. QMenu *patterns = new QMenu(containsRegExp); for (int i = 0; (unsigned)i < sizeof(items) / sizeof(items[0]); i++) { patterns->addAction(new RegExpAction(patterns, i18n(items[i].description), items[i].regExp, items[i].cursorAdjustment)); } connect(containsRegExp, &QToolButton::toggled, this, &GeneralFilter::slotDisable); connect(containsRegExp, &QToolButton::triggered, this, &GeneralFilter::slotRegExpTriggered); containsRegExp->setMenu(patterns); patterns->setEnabled(false); containsTextLayout->addWidget(containsRegExp); containsLayout->addLayout(containsTextLayout, 0, 0); QHBoxLayout *containsCbsLayout = new QHBoxLayout(); containsCbsLayout->setSpacing(6); containsCbsLayout->setContentsMargins(0, 0, 0, 0); encLabel = new QLabel(i18n("Encoding:"), containsGroup); containsCbsLayout->addWidget(encLabel); contentEncoding = new KComboBox(containsGroup); contentEncoding->setEditable(false); contentEncoding->addItem(i18nc("Default encoding", "Default")); contentEncoding->addItems(KCharsets::charsets()->descriptiveEncodingNames()); containsCbsLayout->addWidget(contentEncoding); QSpacerItem* cbSpacer = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); containsCbsLayout->addItem(cbSpacer); containsWholeWord = new QCheckBox(containsGroup); QSizePolicy containsWholeWordPolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); containsWholeWordPolicy.setHeightForWidth(containsWholeWord->sizePolicy().hasHeightForWidth()); containsWholeWord->setSizePolicy(containsWholeWordPolicy); containsWholeWord->setText(i18n("&Match whole word only")); containsWholeWord->setChecked(false); containsCbsLayout->addWidget(containsWholeWord); containsTextCase = new QCheckBox(containsGroup); QSizePolicy containsTextCasePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); containsTextCasePolicy.setHeightForWidth(containsTextCase->sizePolicy().hasHeightForWidth()); containsTextCase->setSizePolicy(containsTextCasePolicy); containsTextCase->setText(i18n("Cas&e sensitive")); containsTextCase->setChecked(true); containsCbsLayout->addWidget(containsTextCase); containsLayout->addLayout(containsCbsLayout, 1, 0); filterLayout->addWidget(containsGroup, 2, 0); QHBoxLayout *recurseLayout = new QHBoxLayout(); recurseLayout->setSpacing(6); recurseLayout->setContentsMargins(0, 0, 0, 0); QSpacerItem* recurseSpacer = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); recurseLayout->addItem(recurseSpacer); if (properties & FilterTabs::HasRecurseOptions) { // Options for recursive searching searchInDirs = new QCheckBox(this); searchInDirs->setText(i18n("Search in s&ub folders")); searchInDirs->setChecked(true); recurseLayout->addWidget(searchInDirs); searchInArchives = new QCheckBox(this); searchInArchives->setText(i18n("Search in arch&ives")); recurseLayout->addWidget(searchInArchives); followLinks = new QCheckBox(this); followLinks->setText(i18n("Follow &links")); recurseLayout->addWidget(followLinks); } filterLayout->addLayout(recurseLayout, 3, 0); for(int i = 0; i < extraOptions.length(); i++) { QCheckBox *option = new QCheckBox(this); option->setText(extraOptions[i]); recurseLayout->addWidget(option); this->extraOptions.insert(extraOptions[i], option); } // Connection table if (properties & FilterTabs::HasProfileHandler) { connect(profileAddBtn, &QPushButton::clicked, this, &GeneralFilter::slotAddBtnClicked); connect(profileLoadBtn, &QPushButton::clicked, this, &GeneralFilter::slotLoadBtnClicked); connect(profileOverwriteBtn, &QPushButton::clicked, this, &GeneralFilter::slotOverwriteBtnClicked); connect(profileRemoveBtn, &QPushButton::clicked, this, &GeneralFilter::slotRemoveBtnClicked); connect(profileListBox, &KrListWidget::itemDoubleClicked, this, &GeneralFilter::slotProfileDoubleClicked); connect(profileManager, &ProfileManager::loadFromProfile, fltTabs, &FilterTabs::loadFromProfile); connect(profileManager, &ProfileManager::saveToProfile, fltTabs, &FilterTabs::saveToProfile); } connect(searchFor, SIGNAL(activated(QString)), searchFor, SLOT(addToHistory(QString))); connect(containsText, SIGNAL(activated(QString)), containsText, SLOT(addToHistory(QString))); // load the completion and history lists // ==> search for KConfigGroup group(krConfig, "Search"); QStringList list = group.readEntry("SearchFor Completion", QStringList()); searchFor->completionObject()->setItems(list); list = group.readEntry("SearchFor History", QStringList()); searchFor->setHistoryItems(list); // ==> grep list = group.readEntry("ContainsText Completion", QStringList()); containsText->completionObject()->setItems(list); list = group.readEntry("ContainsText History", QStringList()); containsText->setHistoryItems(list); setTabOrder(searchFor, containsText); // search for -> content setTabOrder(containsText, searchType); // content -> search type slotDisable(); } GeneralFilter::~GeneralFilter() { // save the history combos // ==> search for QStringList list = searchFor->completionObject()->items(); KConfigGroup group(krConfig, "Search"); group.writeEntry("SearchFor Completion", list); list = searchFor->historyItems(); group.writeEntry("SearchFor History", list); // ==> grep text list = containsText->completionObject()->items(); group.writeEntry("ContainsText Completion", list); list = containsText->historyItems(); group.writeEntry("ContainsText History", list); if ((properties & FilterTabs::HasDontSearchIn) && (properties & FilterTabs::HasRecurseOptions)) { list = excludeFolderNames->historyItems(); group.writeEntry("ExcludeFolderNamesHistory", list); group.writeEntry("ExcludeFolderNames", excludeFolderNames->currentText()); group.writeEntry("ExcludeFolderNamesUse", static_cast(useExcludeFolderNames->checkState())); } krConfig->sync(); } bool GeneralFilter::isExtraOptionChecked(QString name) { QCheckBox *option = extraOptions[name]; return option ? option->isChecked() : false; } void GeneralFilter::checkExtraOption(QString name, bool check) { QCheckBox *option = extraOptions[name]; if (option) option->setChecked(check); } void GeneralFilter::queryAccepted() { searchFor->addToHistory(searchFor->currentText()); containsText->addToHistory(containsText->currentText()); if ((properties & FilterTabs::HasDontSearchIn) && (properties & FilterTabs::HasRecurseOptions)) { excludeFolderNames->addToHistory(excludeFolderNames->currentText()); } } void GeneralFilter::refreshProfileListBox() { profileListBox->clear(); profileListBox->addItems(ProfileManager::availableProfiles("SelectionProfile")); if (profileListBox->count() != 0) { profileLoadBtn->setEnabled(true); profileOverwriteBtn->setEnabled(true); profileRemoveBtn->setEnabled(true); } else { profileLoadBtn->setEnabled(false); profileOverwriteBtn->setEnabled(false); profileRemoveBtn->setEnabled(false); } } QCheckBox *GeneralFilter::createExcludeCheckBox(const KConfigGroup &group) { QCheckBox *excludeCheckBox = new QCheckBox(this); excludeCheckBox->setText(i18n("Exclude Folder Names")); excludeCheckBox->setToolTip(i18n("Filters out specified directory names from the results.")); excludeCheckBox->setChecked(static_cast(group.readEntry("ExcludeFolderNamesUse", 0))); return excludeCheckBox; } KHistoryComboBox *GeneralFilter::createExcludeComboBox(const KConfigGroup &group) { KHistoryComboBox *excludeComboBox = new KHistoryComboBox(false, this); QSizePolicy excludeFolderNamesPolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); excludeFolderNamesPolicy.setHeightForWidth(excludeComboBox->sizePolicy().hasHeightForWidth()); excludeComboBox->setSizePolicy(excludeFolderNamesPolicy); excludeComboBox->setEditable(true); excludeComboBox->setDuplicatesEnabled(false); excludeComboBox->setMaxCount(25); excludeComboBox->setMinimumContentsLength(10); excludeComboBox->lineEdit()->setPlaceholderText(i18n("Enter space-separated folder names")); excludeComboBox->lineEdit()->setWhatsThis( i18n("You can insert names with escaped spaces or quoted.\nExample: .git \"target " "build\" build\\ krusader")); excludeComboBox->setHistoryItems(group.readEntry("ExcludeFolderNamesHistory", QStringList())); excludeComboBox->setEditText(group.readEntry("ExcludeFolderNames", "")); return excludeComboBox; } void GeneralFilter::slotAddBtnClicked() { profileManager->newProfile(searchFor->currentText().simplified()); refreshProfileListBox(); } void GeneralFilter::slotOverwriteBtnClicked() { QListWidgetItem *item = profileListBox->currentItem(); if (item != 0) profileManager->overwriteProfile(item->text()); } void GeneralFilter::slotRemoveBtnClicked() { QListWidgetItem *item = profileListBox->currentItem(); if (item != 0) { profileManager->deleteProfile(item->text()); refreshProfileListBox(); } } void GeneralFilter::slotProfileDoubleClicked(QListWidgetItem *item) { if (item != 0) { QString profileName = item->text(); profileManager->loadProfile(profileName); fltTabs->close(true); } } void GeneralFilter::slotLoadBtnClicked() { QListWidgetItem *item = profileListBox->currentItem(); if (item != 0) profileManager->loadProfile(item->text()); } void GeneralFilter::slotDisable() { bool state = containsRegExp->isChecked(); bool global = ofType->currentText() != i18n("Folders"); bool remoteOnly = false; if (properties & FilterTabs::HasSearchIn) { QList urlList = searchIn->urlList(); remoteOnly = urlList.count() != 0; foreach(const QUrl &url, urlList) if (url.scheme() == "file") remoteOnly = false; } containsWholeWord->setEnabled(!state && global); containsRegExp->menu()->setEnabled(state && global); encLabel->setEnabled(global); contentEncoding->setEnabled(global); containsTextCase->setEnabled(global); containsRegExp->setEnabled(global); if (properties & FilterTabs::HasRecurseOptions) searchInArchives->setEnabled(global && !remoteOnly); containsLabel->setEnabled(global); containsText->setEnabled(global); } void GeneralFilter::slotRegExpTriggered(QAction * act) { if (act == 0) return; RegExpAction *regAct = dynamic_cast(act); if (regAct == 0) return; containsText->lineEdit()->insert(regAct->regExp()); containsText->lineEdit()->setCursorPosition(containsText->lineEdit()->cursorPosition() + regAct->cursor()); containsText->lineEdit()->setFocus(); } bool GeneralFilter::getSettings(FilterSettings &s) { // check that we have (at least) what to search, and where to search in if (searchFor->currentText().simplified().isEmpty()) { KMessageBox::error(this , i18n("No search criteria entered.")); searchFor->setFocus(); return false; } s.searchFor = searchFor->currentText().trimmed(); s.searchForCase = searchForCase->isChecked(); if (ofType->currentText() != i18n("All Files")) s.mimeType = ofType->currentText(); if (containsText->isEnabled()) { s.containsText = containsText->currentText(); s.containsTextCase = containsTextCase->isChecked(); s.containsWholeWord = containsWholeWord->isChecked(); s.containsRegExp = containsRegExp->isChecked(); } if (contentEncoding->currentIndex() != 0) s.contentEncoding = KCharsets::charsets()->encodingForName(contentEncoding->currentText()); if (properties & FilterTabs::HasRecurseOptions) { s.recursive = searchInDirs->isChecked(); s.searchInArchives = searchInArchives->isChecked(); s.followLinks = followLinks->isChecked(); } if (properties & FilterTabs::HasSearchIn) { s.searchIn = searchIn->urlList(); if (s.searchIn.isEmpty()) { // we need a place to search in KMessageBox::error(this , i18n("Please specify a location to search in.")); searchIn->lineEdit()->setFocus(); return false; } } if (properties & FilterTabs::HasDontSearchIn) { s.dontSearchIn = dontSearchIn->urlList(); if (properties & FilterTabs::HasRecurseOptions) { if (useExcludeFolderNames->isChecked()) { s.excludeFolderNames = KShell::splitArgs(excludeFolderNames->currentText()); } else { s.excludeFolderNames = QStringList(); } } } return true; } void GeneralFilter::applySettings(const FilterSettings &s) { searchFor->setEditText(s.searchFor); searchForCase->setChecked(s.searchForCase); setComboBoxValue(ofType, s.mimeType); containsText->setEditText(s.containsText); containsTextCase->setChecked(s.containsTextCase); containsWholeWord->setChecked(s.containsWholeWord); containsRegExp->setChecked(s.containsRegExp); setComboBoxValue(contentEncoding, KCharsets::charsets()->descriptionForEncoding(s.contentEncoding)); if (properties & FilterTabs::HasRecurseOptions) { searchInDirs->setChecked(s.recursive); searchInArchives->setChecked(s.searchInArchives); followLinks->setChecked(s.followLinks); } if (properties & FilterTabs::HasSearchIn) { searchIn->lineEdit()->clear(); searchIn->listBox()->clear(); searchIn->listBox()->addItems(KrServices::toStringList(s.searchIn)); } if (properties & FilterTabs::HasDontSearchIn) { dontSearchIn->lineEdit()->clear(); dontSearchIn->listBox()->clear(); dontSearchIn->listBox()->addItems(KrServices::toStringList(s.dontSearchIn)); } } diff --git a/krusader/GUI/dirhistorybutton.cpp b/krusader/GUI/dirhistorybutton.cpp index 38d0d94b..d2e61775 100644 --- a/krusader/GUI/dirhistorybutton.cpp +++ b/krusader/GUI/dirhistorybutton.cpp @@ -1,96 +1,96 @@ /***************************************************************************** * Copyright (C) 2004 Shie Erlich * * Copyright (C) 2004 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 "dirhistorybutton.h" #include "../icon.h" #include "../Panel/dirhistoryqueue.h" #include "../FileSystem/filesystem.h" // QtCore #include #include // QtGui #include // QtWidgets #include #include DirHistoryButton::DirHistoryButton(DirHistoryQueue* hQ, QWidget *parent) : QToolButton(parent) { setAutoRaise(true); setIcon(Icon("chronometer")); setText(i18n("Open the folder history list")); setToolTip(i18n("Open the folder history list")); setPopupMode(QToolButton::InstantPopup); setAcceptDrops(false); popupMenu = new QMenu(this); Q_CHECK_PTR(popupMenu); setMenu(popupMenu); historyQueue = hQ; - connect(popupMenu, SIGNAL(aboutToShow()), this, SLOT(slotAboutToShow())); - connect(popupMenu, SIGNAL(triggered(QAction*)), this, SLOT(slotPopupActivated(QAction*))); + connect(popupMenu, &QMenu::aboutToShow, this, &DirHistoryButton::slotAboutToShow); + connect(popupMenu, &QMenu::triggered, this, &DirHistoryButton::slotPopupActivated); } DirHistoryButton::~DirHistoryButton() {} void DirHistoryButton::showMenu() { QMenu * pP = menu(); if (pP) { menu() ->exec(mapToGlobal(QPoint(0, height()))); } } /** No descriptions */ void DirHistoryButton::slotPopup() { // qDebug() << "History slot"; } /** No descriptions */ void DirHistoryButton::slotAboutToShow() { emit aboutToShow(); // qDebug() << "about to show"; popupMenu->clear(); for (int i = 0; i < historyQueue->count(); i++) { QAction *act = popupMenu->addAction(historyQueue->get(i).toDisplayString()); act->setData(QVariant(i)); if(historyQueue->currentPos() == i) { act->setCheckable(true); act->setChecked(true); } } } /** No descriptions */ void DirHistoryButton::slotPopupActivated(QAction * action) { if (action && action->data().canConvert()) { int id = action->data().toInt(); emit gotoPos(id); } } diff --git a/krusader/GUI/krremoteencodingmenu.cpp b/krusader/GUI/krremoteencodingmenu.cpp index d7910c94..878067ee 100644 --- a/krusader/GUI/krremoteencodingmenu.cpp +++ b/krusader/GUI/krremoteencodingmenu.cpp @@ -1,226 +1,226 @@ /***************************************************************************** * Copyright (C) 2005 Csaba Karai * * Copyright (C) 2005-2018 Krusader Krew [https://krusader.org] * * * * Based on KRemoteEncodingPlugin from Dawit Alemayehu * * * * 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 "krremoteencodingmenu.h" // QtCore #include // QtWidgets #include #include #include #include #include #include #include #include #include "../krglobal.h" #include "../icon.h" #include "../Panel/krpanel.h" #include "../Panel/panelfunc.h" #define DATA_KEY QString::fromLatin1("Charset") KrRemoteEncodingMenu::KrRemoteEncodingMenu(const QString &text, const QString &iconName, KActionCollection *parent) : KActionMenu(Icon(iconName), text, parent), settingsLoaded(false) { - connect(menu(), SIGNAL(aboutToShow()), this, SLOT(slotAboutToShow())); + connect(menu(), &QMenu::aboutToShow, this, &KrRemoteEncodingMenu::slotAboutToShow); parent->addAction("changeremoteencoding", this); } void KrRemoteEncodingMenu::slotAboutToShow() { if (!settingsLoaded) loadSettings(); // uncheck everything QList acts = menu()->actions(); foreach(QAction *act, acts) act->setChecked(false); QString charset = currentCharacterSet(); if (!charset.isEmpty()) { int id = 1; QStringList::Iterator it; for (it = encodingNames.begin(); it != encodingNames.end(); ++it, ++id) if ((*it).indexOf(charset) != -1) break; bool found = false; foreach(QAction *act, acts) { if (act->data().canConvert ()) { int idr = act->data().toInt(); if (idr == id) { act->setChecked(found = true); break; } } } if (!found) qWarning() << Q_FUNC_INFO << "could not find entry for charset=" << charset; } else { foreach(QAction *act, acts) { if (act->data().canConvert ()) { int idr = act->data().toInt(); if (idr == -2) { act->setChecked(true); break; } } } } } QString KrRemoteEncodingMenu::currentCharacterSet() { QUrl currentURL = ACTIVE_PANEL->virtualPath(); return KProtocolManager::charsetFor(currentURL); } void KrRemoteEncodingMenu::loadSettings() { settingsLoaded = true; encodingNames = KCharsets::charsets()->descriptiveEncodingNames(); QMenu *qmenu = menu(); - disconnect(qmenu, SIGNAL(triggered(QAction*)), this, SLOT(slotTriggered(QAction*))); - connect(qmenu, SIGNAL(triggered(QAction*)), this, SLOT(slotTriggered(QAction*))); + disconnect(qmenu, &QMenu::triggered, this, &KrRemoteEncodingMenu::slotTriggered); + connect(qmenu, &QMenu::triggered, this, &KrRemoteEncodingMenu::slotTriggered); qmenu->clear(); QStringList::ConstIterator it; int count = 0; QAction *act; for (it = encodingNames.constBegin(); it != encodingNames.constEnd(); ++it) { act = qmenu->addAction(*it); act->setData(QVariant(++count)); act->setCheckable(true); } qmenu->addSeparator(); act = qmenu->addAction(i18n("Reload")); act->setCheckable(true); act->setData(QVariant(-1)); act = qmenu->addAction(i18nc("Default encoding", "Default")); act->setCheckable(true); act->setData(QVariant(-2)); } void KrRemoteEncodingMenu::slotTriggered(QAction * act) { if (!act || !act->data().canConvert ()) return; int id = act->data().toInt(); switch (id) { case -1: slotReload(); return; case -2: chooseDefault(); return; default: chooseEncoding(encodingNames[id - 1]); } } void KrRemoteEncodingMenu::chooseEncoding(QString encoding) { QUrl currentURL = ACTIVE_PANEL->virtualPath(); KConfig config(("kio_" + currentURL.scheme() + "rc").toLatin1()); QString host = currentURL.host(); QString charset = KCharsets::charsets()->encodingForName(encoding); KConfigGroup group(&config, host); group.writeEntry(DATA_KEY, charset); config.sync(); // Update the io-slaves... updateKIOSlaves(); } void KrRemoteEncodingMenu::slotReload() { loadSettings(); } void KrRemoteEncodingMenu::chooseDefault() { QUrl currentURL = ACTIVE_PANEL->virtualPath(); // We have no choice but delete all higher domain level // settings here since it affects what will be matched. KConfig config(("kio_" + currentURL.scheme() + "rc").toLatin1()); QStringList partList = currentURL.host().split('.', QString::SkipEmptyParts); if (!partList.isEmpty()) { partList.erase(partList.begin()); QStringList domains; // Remove the exact name match... domains << currentURL.host(); while (partList.count()) { if (partList.count() == 2) if (partList[0].length() <= 2 && partList[1].length() == 2) break; if (partList.count() == 1) break; domains << partList.join("."); partList.erase(partList.begin()); } for (QStringList::Iterator it = domains.begin(); it != domains.end(); ++it) { //qDebug() << "Domain to remove: " << *it; if (config.hasGroup(*it)) config.deleteGroup(*it); else if (config.group("").hasKey(*it)) config.group("").deleteEntry(*it); //don't know what group name is supposed to be XXX } } config.sync(); updateKIOSlaves(); } void KrRemoteEncodingMenu::updateKIOSlaves() { KIO::Scheduler::emitReparseSlaveConfiguration(); // Reload the page with the new charset QTimer::singleShot(500, ACTIVE_FUNC, SLOT(refresh())); } diff --git a/krusader/GUI/mediabutton.cpp b/krusader/GUI/mediabutton.cpp index 516f827f..ecffc132 100644 --- a/krusader/GUI/mediabutton.cpp +++ b/krusader/GUI/mediabutton.cpp @@ -1,633 +1,630 @@ /***************************************************************************** * 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 "mediabutton.h" #include "../krglobal.h" #include "../icon.h" #include "../MountMan/kmountman.h" // QtCore #include // QtGui #include #include #include #include #include #include #include #include #include #include #include #include #include #include QString MediaButton::remotePrefix = QLatin1String("remote:"); MediaButton::MediaButton(QWidget *parent) : QToolButton(parent), popupMenu(0), rightMenu(0), openInNewTab(false) { setAutoRaise(true); setIcon(Icon("system-file-manager")); setText(i18n("Open the available media list")); setToolTip(i18n("Open the available media list")); setPopupMode(QToolButton::InstantPopup); setAcceptDrops(false); popupMenu = new QMenu(this); popupMenu->installEventFilter(this); Q_CHECK_PTR(popupMenu); setMenu(popupMenu); - connect(popupMenu, SIGNAL(aboutToShow()), this, SLOT(slotAboutToShow())); - connect(popupMenu, SIGNAL(aboutToHide()), this, SLOT(slotAboutToHide())); - connect(popupMenu, SIGNAL(triggered(QAction*)), this, SLOT(slotPopupActivated(QAction*))); + connect(popupMenu, &QMenu::aboutToShow, this, &MediaButton::slotAboutToShow); + connect(popupMenu, &QMenu::aboutToHide, this, &MediaButton::slotAboutToHide); + connect(popupMenu, &QMenu::triggered, this, &MediaButton::slotPopupActivated); Solid::DeviceNotifier *notifier = Solid::DeviceNotifier::instance(); - connect(notifier, SIGNAL(deviceAdded(QString)), - this, SLOT(slotDeviceAdded(QString))); - connect(notifier, SIGNAL(deviceRemoved(QString)), - this, SLOT(slotDeviceRemoved(QString))); + connect(notifier, &Solid::DeviceNotifier::deviceAdded, this, &MediaButton::slotDeviceAdded); + connect(notifier, &Solid::DeviceNotifier::deviceRemoved, this, &MediaButton::slotDeviceRemoved); - connect(&mountCheckerTimer, SIGNAL(timeout()), this, SLOT(slotCheckMounts())); + connect(&mountCheckerTimer, &QTimer::timeout, this, &MediaButton::slotCheckMounts); } MediaButton::~MediaButton() { } void MediaButton::updateIcon(const QString &mountPoint) { if(!mountPoint.isEmpty() && mountPoint == currentMountPoint) return; currentMountPoint = mountPoint; QString iconName("system-file-manager"); QStringList overlays; if(!mountPoint.isEmpty()) { Solid::Device device(krMtMan.findUdiForPath(mountPoint, Solid::DeviceInterface::StorageAccess));; Solid::StorageVolume *vol = device.as (); if(device.isValid()) iconName = device.icon(); if (vol && vol->usage() == Solid::StorageVolume::Encrypted) overlays << "security-high"; } setIcon(Icon(iconName, overlays)); } void MediaButton::slotAboutToShow() { emit aboutToShow(); popupMenu->clear(); udiNameMap.clear(); createMediaList(); } void MediaButton::slotAboutToHide() { if (rightMenu) rightMenu->close(); mountCheckerTimer.stop(); } void MediaButton::createMediaList() { // devices detected by solid storageDevices = Solid::Device::listFromType(Solid::DeviceInterface::StorageAccess); for (int p = storageDevices.count() - 1 ; p >= 0; p--) { Solid::Device device = storageDevices[ p ]; QString udi = device.udi(); QString name; QIcon kdeIcon; if (!getNameAndIcon(device, name, kdeIcon)) continue; QAction * act = popupMenu->addAction(kdeIcon, name); act->setData(QVariant(udi)); udiNameMap[ udi ] = name; - connect(device.as(), SIGNAL(accessibilityChanged(bool,QString)), - this, SLOT(slotAccessibilityChanged(bool,QString))); + connect(device.as(), &Solid::StorageAccess::accessibilityChanged, + this, &MediaButton::slotAccessibilityChanged); } KMountPoint::List possibleMountList = KMountPoint::possibleMountPoints(); KMountPoint::List currentMountList = KMountPoint::currentMountPoints(); for (KMountPoint::List::iterator it = possibleMountList.begin(); it != possibleMountList.end(); ++it) { if (krMtMan.networkFilesystem((*it)->mountType())) { QString path = (*it)->mountPoint(); bool mounted = false; for (KMountPoint::List::iterator it2 = currentMountList.begin(); it2 != currentMountList.end(); ++it2) { if (krMtMan.networkFilesystem((*it2)->mountType()) && (*it)->mountPoint() == (*it2)->mountPoint()) { mounted = true; break; } } QString name = i18nc("%1 is the mount point of the remote share", "Remote Share [%1]", (*it)->mountPoint()); QStringList overlays; if (mounted) overlays << "emblem-mounted"; QAction * act = popupMenu->addAction(Icon("network-wired", overlays), name); QString udi = remotePrefix + (*it)->mountPoint(); act->setData(QVariant(udi)); } } mountCheckerTimer.setSingleShot(true); mountCheckerTimer.start(1000); } bool MediaButton::getNameAndIcon(Solid::Device & device, QString &name, QIcon &iconOut) { Solid::StorageAccess *access = device.as(); if (access == 0) return false; QString udi = device.udi(); QString label = i18nc("Unknown label", "Unknown"); bool mounted = access->isAccessible(); QString path = access->filePath(); QString type = i18nc("Unknown media type", "Unknown"); QString iconName = device.icon(); QString fstype; QString size; Solid::StorageVolume * vol = device.as (); if (vol) { label = vol->label(); fstype = vol->fsType(); size = KIO::convertSize(vol->size()); } bool printSize = false; if (iconName == "media-floppy") type = i18n("Floppy"); else if (iconName == "drive-optical") type = i18n("CD/DVD-ROM"); else if (iconName == "drive-removable-media-usb-pendrive") type = i18n("USB pen drive"), printSize = true; else if (iconName == "drive-removable-media-usb") type = i18n("USB device"), printSize = true; else if (iconName == "drive-removable-media") type = i18n("Removable media"), printSize = true; else if (iconName == "drive-harddisk") type = i18n("Hard Disk"), printSize = true; else if (iconName == "camera-photo") type = i18n("Camera"); else if (iconName == "media-optical-video") type = i18n("Video CD/DVD-ROM"); else if (iconName == "media-optical-audio") type = i18n("Audio CD/DVD-ROM"); else if (iconName == "media-optical") type = i18n("Recordable CD/DVD-ROM"); KConfigGroup cfg(KSharedConfig::openConfig(), QStringLiteral("MediaMenu")); if (printSize) { QString showSizeSetting = cfg.readEntry("ShowSize", "Always"); if (showSizeSetting == "WhenNoLabel") printSize = label.isEmpty(); else if (showSizeSetting == "Never") printSize = false; } if (printSize && !size.isEmpty()) name += size + ' '; if (!label.isEmpty()) name += label + ' '; else name += type + ' '; if (!fstype.isEmpty() && cfg.readEntry("ShowFSType", true)) name += '(' + fstype + ") "; if (!path.isEmpty() && cfg.readEntry("ShowPath", true)) name += '[' + path + "] "; name = name.trimmed(); QStringList overlays; if (mounted) { overlays << "emblem-mounted"; } else { overlays << QString(); // We have to guarantee the placement of the next emblem } if (vol && vol->usage() == Solid::StorageVolume::Encrypted) { overlays << "security-high"; } iconOut = Icon(iconName, overlays); return true; } void MediaButton::slotPopupActivated(QAction *action) { if (action && action->data().canConvert()) { QString udi = action->data().toString(); if (!udi.isEmpty()) { bool mounted = false; QString mountPoint; getStatus(udi, mounted, &mountPoint); if (mounted) emit openUrl(QUrl::fromLocalFile(mountPoint)); else mount(udi, true); } } } void MediaButton::showMenu() { QMenu * pP = menu(); if (pP) { menu() ->exec(mapToGlobal(QPoint(0, height()))); } } bool MediaButton::eventFilter(QObject *o, QEvent *e) { if (o == popupMenu) { if (e->type() == QEvent::ContextMenu) { QAction *act = popupMenu->activeAction(); if (act && act->data().canConvert()) { QString id = act->data().toString(); if (!id.isEmpty()) { QPoint globalPos = popupMenu->mapToGlobal(popupMenu->actionGeometry(act).topRight()); rightClickMenu(id, globalPos); return true; } } } else if (e->type() == QEvent::KeyPress) { QKeyEvent *ke = static_cast(e); if (ke->key() == Qt::Key_Return && ke->modifiers() == Qt::ControlModifier) { if (QAction *act = popupMenu->activeAction()) { QString id = act->data().toString(); if (!id.isEmpty()) { toggleMount(id); return true; } } } } else if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease) { QMouseEvent *m = static_cast(e); if (m->button() == Qt::RightButton) { if (e->type() == QEvent::MouseButtonPress) { QAction * act = popupMenu->actionAt(m->pos()); if (act && act->data().canConvert()) { QString id = act->data().toString(); if (!id.isEmpty()) rightClickMenu(id, m->globalPos()); } } m->accept(); return true; } } } return false; } void MediaButton::rightClickMenu(QString udi, QPoint pos) { if (rightMenu) rightMenu->close(); bool ejectable = false; bool mounted = false; QString mountPoint; getStatus(udi, mounted, &mountPoint, &ejectable); QUrl openURL = QUrl::fromLocalFile(mountPoint); QMenu * myMenu = rightMenu = new QMenu(popupMenu); QAction * actOpen = myMenu->addAction(i18n("Open")); actOpen->setData(QVariant(1)); QAction * actOpenNewTab = myMenu->addAction(i18n("Open in a new tab")); actOpenNewTab->setData(QVariant(2)); myMenu->addSeparator(); if (!mounted) { QAction * actMount = myMenu->addAction(i18n("Mount")); actMount->setData(QVariant(3)); } else { QAction * actUnmount = myMenu->addAction(i18n("Unmount")); actUnmount->setData(QVariant(4)); } if (ejectable) { QAction * actEject = myMenu->addAction(i18n("Eject")); actEject->setData(QVariant(5)); } QAction *act = myMenu->exec(pos); int result = -1; if (act != 0 && act->data().canConvert()) result = act->data().toInt(); delete myMenu; if (rightMenu == myMenu) rightMenu = 0; else return; switch (result) { case 1: case 2: popupMenu->close(); if (mounted) { if (result == 1) emit openUrl(openURL); else emit newTab(openURL); } else { mount(udi, true, result == 2); // mount first, when mounted open the tab } break; case 3: mount(udi); break; case 4: umount(udi); break; case 5: eject(udi); break; default: break; } } void MediaButton::toggleMount(QString udi) { bool mounted = false; getStatus(udi, mounted); if (mounted) umount(udi); else mount(udi); } void MediaButton::getStatus(QString udi, bool &mounted, QString *mountPointOut, bool *ejectableOut) { mounted = false; bool network = udi.startsWith(remotePrefix); bool ejectable = false; QString mountPoint; if (network) { mountPoint = udi.mid(remotePrefix.length()); KMountPoint::List currentMountList = KMountPoint::currentMountPoints(); for (KMountPoint::List::iterator it = currentMountList.begin(); it != currentMountList.end(); ++it) { if (krMtMan.networkFilesystem((*it)->mountType()) && (*it)->mountPoint() == mountPoint) { mounted = true; break; } } } else { Solid::Device device(udi); Solid::StorageAccess *access = device.as(); Solid::OpticalDisc *optdisc = device.as(); if (access) mountPoint = access->filePath(); if (access && access->isAccessible()) mounted = true; if (optdisc) ejectable = true; } if (mountPointOut) *mountPointOut = mountPoint; if (ejectableOut) *ejectableOut = ejectable; } void MediaButton::mount(QString udi, bool open, bool newtab) { if (udi.startsWith(remotePrefix)) { QString mp = udi.mid(remotePrefix.length()); krMtMan.mount(mp, true); if (newtab) emit newTab(QUrl::fromLocalFile(mp)); else emit openUrl(QUrl::fromLocalFile(mp)); return; } Solid::Device device(udi); Solid::StorageAccess *access = device.as(); if (access && !access->isAccessible()) { if (open) udiToOpen = device.udi(), openInNewTab = newtab; - connect(access, SIGNAL(setupDone(Solid::ErrorType,QVariant,QString)), - this, SLOT(slotSetupDone(Solid::ErrorType,QVariant,QString))); + connect(access, &Solid::StorageAccess::setupDone, this, &MediaButton::slotSetupDone); access->setup(); } } void MediaButton::slotSetupDone(Solid::ErrorType error, QVariant errorData, const QString &udi) { if (error == Solid::NoError) { if (udi == udiToOpen) { Solid::StorageAccess *access = Solid::Device(udi).as(); if (access && access->isAccessible()) { if (openInNewTab) emit newTab(QUrl::fromLocalFile(access->filePath())); else emit openUrl(QUrl::fromLocalFile(access->filePath())); } udiToOpen = QString(), openInNewTab = false; } } else { if (udi == udiToOpen) udiToOpen = QString(), openInNewTab = false; QString name; if (udiNameMap.contains(udi)) name = udiNameMap[ udi ]; if (errorData.isValid()) { KMessageBox::sorry(this, i18n("An error occurred while accessing '%1', the system responded: %2", name, errorData.toString())); } else { KMessageBox::sorry(this, i18n("An error occurred while accessing '%1'", name)); } } } void MediaButton::umount(QString udi) { if (udi.startsWith(remotePrefix)) { krMtMan.unmount(udi.mid(remotePrefix.length()), false); return; } krMtMan.unmount(krMtMan.pathForUdi(udi), false); } void MediaButton::eject(QString udi) { krMtMan.eject(krMtMan.pathForUdi(udi)); } void MediaButton::slotAccessibilityChanged(bool /*accessible*/, const QString & udi) { QList actionList = popupMenu->actions(); foreach(QAction * act, actionList) { if (act && act->data().canConvert() && act->data().toString() == udi) { Solid::Device device(udi); QString name; QIcon kdeIcon; if (getNameAndIcon(device, name, kdeIcon)) { act->setText(name); act->setIcon(kdeIcon); } break; } } } void MediaButton::slotDeviceAdded(const QString& udi) { if (popupMenu->isHidden()) return; Solid::Device device(udi); Solid::StorageAccess *access = device.as(); if (access == 0) return; QString name; QIcon kdeIcon; if (!getNameAndIcon(device, name, kdeIcon)) return; QAction * act = popupMenu->addAction(kdeIcon, name); act->setData(QVariant(udi)); udiNameMap[ udi ] = name; - connect(device.as(), SIGNAL(accessibilityChanged(bool,QString)), - this, SLOT(slotAccessibilityChanged(bool,QString))); + connect(device.as(), &Solid::StorageAccess::accessibilityChanged, + this, &MediaButton::slotAccessibilityChanged); } void MediaButton::slotDeviceRemoved(const QString& udi) { if (popupMenu->isHidden()) return; QList actionList = popupMenu->actions(); foreach(QAction * act, actionList) { if (act && act->data().canConvert() && act->data().toString() == udi) { popupMenu->removeAction(act); delete act; break; } } } void MediaButton::slotCheckMounts() { if (isHidden()) return; KMountPoint::List possibleMountList = KMountPoint::possibleMountPoints(); KMountPoint::List currentMountList = KMountPoint::currentMountPoints(); QList actionList = popupMenu->actions(); foreach(QAction * act, actionList) { if (act && act->data().canConvert() && act->data().toString().startsWith(remotePrefix)) { QString mountPoint = act->data().toString().mid(remotePrefix.length()); bool available = false; for (KMountPoint::List::iterator it = possibleMountList.begin(); it != possibleMountList.end(); ++it) { if (krMtMan.networkFilesystem((*it)->mountType()) && (*it)->mountPoint() == mountPoint) { available = true; break; } } if (!available) { popupMenu->removeAction(act); delete act; } } } for (KMountPoint::List::iterator it = possibleMountList.begin(); it != possibleMountList.end(); ++it) { if (krMtMan.networkFilesystem((*it)->mountType())) { QString path = (*it)->mountPoint(); bool mounted = false; QString udi = remotePrefix + path; QAction * correspondingAct = 0; foreach(QAction * act, actionList) { if (act && act->data().canConvert() && act->data().toString() == udi) { correspondingAct = act; break; } } for (KMountPoint::List::iterator it2 = currentMountList.begin(); it2 != currentMountList.end(); ++it2) { if (krMtMan.networkFilesystem((*it2)->mountType()) && path == (*it2)->mountPoint()) { mounted = true; break; } } QString name = i18nc("%1 is the mount point of the remote share", "Remote Share [%1]", (*it)->mountPoint()); QStringList overlays; if (mounted) overlays << "emblem-mounted"; QIcon kdeIcon = Icon("network-wired", overlays); if (!correspondingAct) { QAction * act = popupMenu->addAction(kdeIcon, name); act->setData(QVariant(udi)); } else { correspondingAct->setText(name); correspondingAct->setIcon(kdeIcon); } } } mountCheckerTimer.setSingleShot(true); mountCheckerTimer.start(1000); } diff --git a/krusader/GUI/profilemanager.cpp b/krusader/GUI/profilemanager.cpp index db688d52..8c6f58ba 100644 --- a/krusader/GUI/profilemanager.cpp +++ b/krusader/GUI/profilemanager.cpp @@ -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/]. * *****************************************************************************/ #include "profilemanager.h" // QtGui #include // QtWidgets #include #include #include #include #include "../krglobal.h" #include "../icon.h" ProfileManager::ProfileManager(QString profileType, QWidget * parent) : QPushButton(parent) { setText(""); setIcon(Icon("user-identity")); setFixedWidth(16 + 15); setToolTip(i18n("Profiles")); this->profileType = profileType; - connect(this, SIGNAL(clicked()), this, SLOT(profilePopup())); + connect(this, &ProfileManager::clicked, this, &ProfileManager::profilePopup); KConfigGroup group(krConfig, "Private"); profileList = group.readEntry(profileType, QStringList()); } void ProfileManager::profilePopup() { // profile menu identifiers #define ADD_NEW_ENTRY_ID 1000 #define LOAD_ENTRY_ID 2000 #define REMOVE_ENTRY_ID 3000 #define OVERWRITE_ENTRY_ID 4000 // create the menu QMenu popup, removePopup, overwritePopup; popup.setTitle(i18n("Profiles")); for (int i = 0; i != profileList.count() ; i++) { KConfigGroup group(krConfig, profileType + " - " + profileList[i]); QString name = group.readEntry("Name"); popup.addAction(name)->setData(QVariant((int)(LOAD_ENTRY_ID + i))); removePopup.addAction(name)->setData(QVariant((int)(REMOVE_ENTRY_ID + i))); overwritePopup.addAction(name)->setData(QVariant((int)(OVERWRITE_ENTRY_ID + i))); } popup.addSeparator(); if (profileList.count()) { popup.addMenu(&removePopup)->setText(i18n("Remove entry")); popup.addMenu(&overwritePopup)->setText(i18n("Overwrite entry")); } popup.addAction(i18n("Add new entry"))->setData(QVariant((int)(ADD_NEW_ENTRY_ID))); int result = 0; QAction * res = popup.exec(QCursor::pos()); if (res && res->data().canConvert()) result = res->data().toInt(); // check out the user's selection if (result == ADD_NEW_ENTRY_ID) newProfile(); else if (result >= LOAD_ENTRY_ID && result < LOAD_ENTRY_ID + profileList.count()) { emit loadFromProfile(profileType + " - " + profileList[ result - LOAD_ENTRY_ID ]); } else if (result >= REMOVE_ENTRY_ID && result < REMOVE_ENTRY_ID + profileList.count()) { krConfig->deleteGroup(profileType + " - " + profileList[ result - REMOVE_ENTRY_ID ]); profileList.removeAll(profileList[ result - REMOVE_ENTRY_ID ]); KConfigGroup group(krConfig, "Private"); group.writeEntry(profileType, profileList); krConfig->sync(); } else if (result >= OVERWRITE_ENTRY_ID && result < OVERWRITE_ENTRY_ID + profileList.count()) { emit saveToProfile(profileType + " - " + profileList[ result - OVERWRITE_ENTRY_ID ]); } } void ProfileManager::newProfile(QString defaultName) { QString profile = QInputDialog::getText(this, i18n("Krusader::ProfileManager"), i18n("Enter the profile name:"), QLineEdit::Normal, defaultName); if (!profile.isEmpty()) { int profileNum = 1; while (profileList.contains(QString("%1").arg(profileNum))) profileNum++; QString profileString = QString("%1").arg(profileNum); QString profileName = profileType + " - " + profileString; profileList.append(QString("%1").arg(profileString)); KConfigGroup group(krConfig, "Private"); group.writeEntry(profileType, profileList); KConfigGroup pg(krConfig, profileName); pg.writeEntry("Name", profile); emit saveToProfile(profileName); krConfig->sync(); } } void ProfileManager::deleteProfile(QString name) { for (int i = 0; i != profileList.count() ; i++) { KConfigGroup group(krConfig, profileType + " - " + profileList[ i ]); QString currentName = group.readEntry("Name"); if (name == currentName) { krConfig->deleteGroup(profileType + " - " + profileList[ i ]); profileList.removeAll(profileList[ i ]); KConfigGroup pg(krConfig, "Private"); pg.writeEntry(profileType, profileList); krConfig->sync(); return; } } } void ProfileManager::overwriteProfile(QString name) { for (int i = 0; i != profileList.count() ; i++) { KConfigGroup group(krConfig, profileType + " - " + profileList[ i ]); QString currentName = group.readEntry("Name"); if (name == currentName) { emit saveToProfile(profileType + " - " + profileList[ i ]); return; } } } bool ProfileManager::loadProfile(QString name) { for (int i = 0; i != profileList.count() ; i++) { KConfigGroup group(krConfig, profileType + " - " + profileList[i]); QString currentName = group.readEntry("Name"); if (name == currentName) { emit loadFromProfile(profileType + " - " + profileList[ i ]); return true; } } return false; } QStringList ProfileManager::availableProfiles(QString profileType) { KConfigGroup group(krConfig, "Private"); QStringList profiles = group.readEntry(profileType, QStringList()); QStringList profileNames; for (int i = 0; i != profiles.count() ; i++) { KConfigGroup pg(krConfig, profileType + " - " + profiles[ i ]); profileNames.append(pg.readEntry("Name")); } return profileNames; } diff --git a/krusader/KViewer/diskusageviewer.cpp b/krusader/KViewer/diskusageviewer.cpp index ec931221..74c8a481 100644 --- a/krusader/KViewer/diskusageviewer.cpp +++ b/krusader/KViewer/diskusageviewer.cpp @@ -1,121 +1,121 @@ /***************************************************************************** * 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 "diskusageviewer.h" // QtWidgets #include #include #include #include "../FileSystem/filesystem.h" #include "../Panel/krpanel.h" #include "../Panel/panelfunc.h" #include "../krglobal.h" DiskUsageViewer::DiskUsageViewer(QWidget *parent) : QWidget(parent), diskUsage(0), statusLabel(0) { layout = new QGridLayout(this); layout->setContentsMargins(0, 0, 0, 0); } DiskUsageViewer::~ DiskUsageViewer() { if (diskUsage) { KConfigGroup group(krConfig, "DiskUsageViewer"); group.writeEntry("View", diskUsage->getActiveView()); delete diskUsage; } } void DiskUsageViewer::openUrl(QUrl url) { if (diskUsage == 0) { diskUsage = new DiskUsage("DiskUsageViewer", this); - connect(diskUsage, SIGNAL(enteringDirectory(Directory*)), this, SLOT(slotUpdateStatus())); - connect(diskUsage, SIGNAL(status(QString)), this, SLOT(slotUpdateStatus(QString))); - connect(diskUsage, SIGNAL(newSearch()), this, SLOT(slotNewSearch())); + connect(diskUsage, &DiskUsage::enteringDirectory, this, [=]() { slotUpdateStatus(); }); + connect(diskUsage, &DiskUsage::status, this, &DiskUsageViewer::slotUpdateStatus); + connect(diskUsage, &DiskUsage::newSearch, this, &DiskUsageViewer::slotNewSearch); layout->addWidget(diskUsage, 0, 0); this->show(); diskUsage->show(); KConfigGroup group(krConfig, "DiskUsageViewer"); int view = group.readEntry("View", VIEW_FILELIGHT); if (view < VIEW_LINES || view > VIEW_FILELIGHT) view = VIEW_FILELIGHT; diskUsage->setView(view); } url.setPath(url.adjusted(QUrl::StripTrailingSlash).path()); QUrl baseURL = diskUsage->getBaseURL(); if (!diskUsage->isLoading() && !baseURL.isEmpty()) { if (url.scheme() == baseURL.scheme() && (url.host().isEmpty() || url.host() == baseURL.host())) { QString baseStr = FileSystem::ensureTrailingSlash(baseURL).path(); QString urlStr = FileSystem::ensureTrailingSlash(url).path(); if (urlStr.startsWith(baseStr)) { QString relURL = urlStr.mid(baseStr.length()); if (relURL.endsWith('/')) relURL.truncate(relURL.length() - 1); Directory *dir = diskUsage->getDirectory(relURL); if (dir) { diskUsage->changeDirectory(dir); return; } } } } diskUsage->load(url); } void DiskUsageViewer::closeUrl() { if (diskUsage) diskUsage->close(); } void DiskUsageViewer::setStatusLabel(QLabel *statLabel, QString pref) { statusLabel = statLabel; prefix = pref; } void DiskUsageViewer::slotUpdateStatus(QString status) { if (statusLabel) { if (status.isEmpty()) { Directory * dir = diskUsage->getCurrentDir(); if (dir) status = prefix + dir->name() + " [" + KIO::convertSize(dir->size()) + ']'; } statusLabel->setText(status); } } void DiskUsageViewer::slotNewSearch() { diskUsage->load(ACTIVE_PANEL->virtualPath()); } diff --git a/krusader/KViewer/krviewer.cpp b/krusader/KViewer/krviewer.cpp index 50ee9c50..db166ba7 100644 --- a/krusader/KViewer/krviewer.cpp +++ b/krusader/KViewer/krviewer.cpp @@ -1,714 +1,711 @@ /***************************************************************************** * 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 "krviewer.h" // QtCore #include #include #include #include #include // QtGui #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../defaults.h" #include "../icon.h" #include "panelviewer.h" #define VIEW_ICON "document-preview" #define EDIT_ICON "document-edit" #define MODIFIED_ICON "document-save-as" #define CHECK_MODFIED_INTERVAL 500 /* NOTE: Currently the code expects PanelViewer::openUrl() to be called only once in the panel viewer's life time - otherwise unexpected things might happen. */ QList KrViewer::viewers; KrViewer::KrViewer(QWidget *parent) : KParts::MainWindow(parent, (Qt::WindowFlags)KDE_DEFAULT_WINDOWFLAGS), manager(this, this), tabBar(this), reservedKeys(), reservedKeyActions(), sizeX(-1), sizeY(-1) { //setWFlags(Qt::WType_TopLevel | WDestructiveClose); setXMLFile("krviewer.rc"); // kpart-related xml file setHelpMenuEnabled(false); - connect(&manager, SIGNAL(activePartChanged(KParts::Part*)), - this, SLOT(createGUI(KParts::Part*))); + connect(&manager, &KParts::PartManager::activePartChanged, this, &KrViewer::createGUI); connect(&tabBar, &QTabWidget::currentChanged, this, &KrViewer::tabChanged); - connect(&tabBar, SIGNAL(tabCloseRequested(int)), this, SLOT(tabCloseRequest(int))); + connect(&tabBar, &QTabWidget::tabCloseRequested, this, [=](int index) { tabCloseRequest(index, false); }); tabBar.setDocumentMode(true); tabBar.setMovable(true); setCentralWidget(&tabBar); printAction = KStandardAction::print(this, SLOT(print()), 0); copyAction = KStandardAction::copy(this, SLOT(copy()), 0); viewerMenu = new QMenu(this); QAction *tempAction; KActionCollection *ac = actionCollection(); #define addCustomMenuAction(name, text, slot, shortcut)\ tempAction = ac->addAction(name, this, slot);\ tempAction->setText(text);\ ac->setDefaultShortcut(tempAction, shortcut);\ viewerMenu->addAction(tempAction); addCustomMenuAction("genericViewer", i18n("&Generic Viewer"), SLOT(viewGeneric()), Qt::CTRL + Qt::SHIFT + Qt::Key_G); addCustomMenuAction("textViewer", i18n("&Text Viewer"), SLOT(viewText()), Qt::CTRL + Qt::SHIFT + Qt::Key_T); addCustomMenuAction("hexViewer", i18n("&Hex Viewer"), SLOT(viewHex()), Qt::CTRL + Qt::SHIFT + Qt::Key_H); addCustomMenuAction("lister", i18n("&Lister"), SLOT(viewLister()), Qt::CTRL + Qt::SHIFT + Qt::Key_L); viewerMenu->addSeparator(); addCustomMenuAction("textEditor", i18n("Text &Editor"), SLOT(editText()), Qt::CTRL + Qt::SHIFT + Qt::Key_E); viewerMenu->addSeparator(); QList actList = menuBar()->actions(); bool hasPrint = false, hasCopy = false; foreach(QAction *a, actList) { if (a->shortcut().matches(printAction->shortcut()) != QKeySequence::NoMatch) hasPrint = true; if (a->shortcut().matches(copyAction->shortcut()) != QKeySequence::NoMatch) hasCopy = true; } QAction *printAct = viewerMenu->addAction(printAction->icon(), printAction->text(), this, SLOT(print())); if (hasPrint) printAct->setShortcut(printAction->shortcut()); QAction *copyAct = viewerMenu->addAction(copyAction->icon(), copyAction->text(), this, SLOT(copy())); if (hasCopy) copyAct->setShortcut(copyAction->shortcut()); viewerMenu->addSeparator(); configKeysAction = ac->addAction(KStandardAction::KeyBindings, this, SLOT(configureShortcuts())); viewerMenu->addAction(configKeysAction); viewerMenu->addSeparator(); detachAction = ac->addAction("detachTab", this, SLOT(detachTab())); detachAction->setText(i18n("&Detach Tab")); //no point in detaching only one tab.. detachAction->setEnabled(false); ac->setDefaultShortcut(detachAction, Qt::META + Qt::Key_D); viewerMenu->addAction(detachAction); quitAction = ac->addAction(KStandardAction::Quit, this, SLOT(close())); viewerMenu->addAction(quitAction); QList shortcuts; tabCloseAction = ac->addAction("closeTab", this, SLOT(tabCloseRequest())); tabCloseAction->setText(i18n("&Close Current Tab")); shortcuts = KStandardShortcut::close(); shortcuts.append(Qt::Key_Escape); ac->setDefaultShortcuts(tabCloseAction, shortcuts); tabNextAction = ac->addAction("nextTab", this, SLOT(nextTab())); tabNextAction->setText(i18n("&Next Tab")); shortcuts = KStandardShortcut::tabNext(); shortcuts.append(Qt::CTRL + Qt::Key_Tab); // reenforce QTabWidget shortcut ac->setDefaultShortcuts(tabNextAction, shortcuts); tabPrevAction = ac->addAction("prevTab", this, SLOT(prevTab())); tabPrevAction->setText(i18n("&Previous Tab")); shortcuts = KStandardShortcut::tabPrev(); shortcuts.append(Qt::CTRL + Qt::SHIFT + Qt::Key_Tab); // reenforce QTabWidget shortcut ac->setDefaultShortcuts(tabPrevAction, shortcuts); tabBar.setTabsClosable(true); checkModified(); KConfigGroup group(krConfig, "KrViewerWindow"); int sx = group.readEntry("Window Width", -1); int sy = group.readEntry("Window Height", -1); if (sx != -1 && sy != -1) resize(sx, sy); else resize(900, 700); if (group.readEntry("Window Maximized", false)) { setWindowState(windowState() | Qt::WindowMaximized); } // filtering out the key events menuBar() ->installEventFilter(this); } KrViewer::~KrViewer() { disconnect(&manager, SIGNAL(activePartChanged(KParts::Part*)), this, SLOT(createGUI(KParts::Part*))); viewers.removeAll(this); // close tabs before deleting tab bar - this avoids Qt bug 26115 // https://bugreports.qt-project.org/browse/QTBUG-26115 while(tabBar.count()) tabCloseRequest(tabBar.currentIndex(), true); delete printAction; delete copyAction; } void KrViewer::configureDeps() { PanelEditor::configureDeps(); } void KrViewer::createGUI(KParts::Part* part) { KParts::MainWindow::createGUI(part); updateActions(); toolBar() ->show(); statusBar() ->show(); // the KParts part may override the viewer shortcuts. We prevent it // by installing an event filter on the menuBar() and the part reservedKeys.clear(); reservedKeyActions.clear(); QList list = viewerMenu->actions(); // also add the actions that are not in the menu... list << tabCloseAction << tabNextAction << tabPrevAction; // getting the key sequences of the viewer menu for (int w = 0; w != list.count(); w++) { QAction *act = list[ w ]; QList sequences = act->shortcuts(); foreach(QKeySequence keySeq, sequences) { for(int i = 0; i < keySeq.count(); ++i) { reservedKeys.push_back(keySeq[i]); reservedKeyActions.push_back(act); //the same action many times in case of multiple shortcuts } } } // and "fix" the menubar QList actList = menuBar()->actions(); viewerMenu->setTitle(i18n("&KrViewer")); QAction * act = menuBar() ->addMenu(viewerMenu); act->setData(QVariant(70)); menuBar() ->show(); } void KrViewer::configureShortcuts() { KShortcutsDialog::configure(actionCollection(), KShortcutsEditor::LetterShortcutsAllowed, this); } bool KrViewer::eventFilter(QObject * /* watched */, QEvent * e) { // TODO: after porting to Qt5/KF5 we never catch *ANY* KeyPress or ShortcutOverride events here anymore. // Should look into if there is any way to fix it. Currently if a KPart has same shortcut as KrViewer then // it causes a conflict, messagebox shown to user and no action triggered. if (e->type() == QEvent::ShortcutOverride) { QKeyEvent* ke = (QKeyEvent*) e; if (reservedKeys.contains(ke->key())) { ke->accept(); QAction *act = reservedKeyActions[ reservedKeys.indexOf(ke->key())]; if (act != 0) { // don't activate the close functions immediately! // it can cause crash if (act == tabCloseAction || act == quitAction) { QTimer::singleShot(0, act, SLOT(trigger())); } else { act->activate(QAction::Trigger); } } return true; } } else if (e->type() == QEvent::KeyPress) { QKeyEvent* ke = (QKeyEvent*) e; if (reservedKeys.contains(ke->key())) { ke->accept(); return true; } } return false; } KrViewer* KrViewer::getViewer(bool new_window) { if (!new_window) { if (viewers.isEmpty()) { viewers.prepend(new KrViewer()); // add to first (active) } else { if (viewers.first()->isMinimized()) { // minimized? -> show it again viewers.first()->setWindowState((viewers.first()->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); viewers.first()->show(); } viewers.first()->raise(); viewers.first()->activateWindow(); } return viewers.first(); } else { KrViewer *newViewer = new KrViewer(); viewers.prepend(newViewer); return newViewer; } } void KrViewer::view(QUrl url, QWidget * parent) { KConfigGroup group(krConfig, "General"); bool defaultWindow = group.readEntry("View In Separate Window", _ViewInSeparateWindow); view(url, Default, defaultWindow, parent); } void KrViewer::view(QUrl url, Mode mode, bool new_window, QWidget * parent) { KrViewer* viewer = getViewer(new_window); viewer->viewInternal(url, mode, parent); viewer->show(); } void KrViewer::edit(QUrl url, QWidget * parent) { edit(url, Text, -1, parent); } void KrViewer::edit(QUrl url, Mode mode, int new_window, QWidget * parent) { KConfigGroup group(krConfig, "General"); QString editor = group.readEntry("Editor", _Editor); if (new_window == -1) new_window = group.readEntry("View In Separate Window", _ViewInSeparateWindow); if (editor != "internal editor" && !editor.isEmpty()) { KProcess proc; QStringList cmdArgs = KShell::splitArgs(editor, KShell::TildeExpand); if (cmdArgs.isEmpty()) { KMessageBox::error(krMainWindow, i18nc("Arg is a string containing the bad quoting.", "Bad quoting in editor command:\n%1", editor)); return; } // if the file is local, pass a normal path and not a url. this solves // the problem for editors that aren't url-aware proc << cmdArgs << url.toDisplayString(QUrl::PreferLocalFile); if (!proc.startDetached()) KMessageBox::sorry(krMainWindow, i18n("Can not open \"%1\"", editor)); return; } KrViewer* viewer = getViewer(new_window); viewer->editInternal(url, mode, parent); viewer->show(); } void KrViewer::addTab(PanelViewerBase *pvb) { int tabIndex = tabBar.addTab(pvb, makeTabIcon(pvb), makeTabText(pvb)); tabBar.setCurrentIndex(tabIndex); tabBar.setTabToolTip(tabIndex, makeTabToolTip(pvb)); updateActions(); // now we can offer the option to detach tabs (we have more than one) if (tabBar.count() > 1) { detachAction->setEnabled(true); } tabBar.show(); - connect(pvb, SIGNAL(openUrlFinished(PanelViewerBase*,bool)), - SLOT(openUrlFinished(PanelViewerBase*,bool))); + connect(pvb, &PanelViewerBase::openUrlFinished, this, &KrViewer::openUrlFinished); - connect(pvb, SIGNAL(urlChanged(PanelViewerBase*,QUrl)), - this, SLOT(tabURLChanged(PanelViewerBase*,QUrl))); + connect(pvb, &PanelViewerBase::urlChanged, this, &KrViewer::tabURLChanged); } void KrViewer::tabURLChanged(PanelViewerBase *pvb, const QUrl &url) { Q_UNUSED(url) refreshTab(pvb); } void KrViewer::openUrlFinished(PanelViewerBase *pvb, bool success) { if (success) { KParts::ReadOnlyPart *part = pvb->part(); if (part) { if (!isPartAdded(part)) addPart(part); if (tabBar.currentWidget() == pvb) { manager.setActivePart(part); if (part->widget()) part->widget()->setFocus(); } } } else { tabCloseRequest(tabBar.currentIndex(), false); } } void KrViewer::tabChanged(int index) { QWidget *w = tabBar.widget(index); if(!w) return; KParts::ReadOnlyPart *part = static_cast(w)->part(); if (part && isPartAdded(part)) { manager.setActivePart(part); if (part->widget()) part->widget()->setFocus(); } else manager.setActivePart(0); // set this viewer to be the main viewer if (viewers.removeAll(this)) viewers.prepend(this); // move to first } void KrViewer::tabCloseRequest(int index, bool force) { // important to save as returnFocusTo will be cleared at removePart QWidget *returnFocusToThisWidget = returnFocusTo; PanelViewerBase *pvb = static_cast(tabBar.widget(index)); if (!pvb) return; if (!force && !pvb->queryClose()) return; if (pvb->part() && isPartAdded(pvb->part())) removePart(pvb->part()); disconnect(pvb, 0, this, 0); pvb->closeUrl(); tabBar.removeTab(index); delete pvb; pvb = 0; if (tabBar.count() <= 0) { if (returnFocusToThisWidget) { returnFocusToThisWidget->raise(); returnFocusToThisWidget->activateWindow(); } else { krMainWindow->raise(); krMainWindow->activateWindow(); } QTimer::singleShot(0, this, SLOT(close())); } else if (tabBar.count() == 1) { // no point in detaching only one tab.. detachAction->setEnabled(false); } } void KrViewer::tabCloseRequest() { tabCloseRequest(tabBar.currentIndex()); } bool KrViewer::queryClose() { KConfigGroup group(krConfig, "KrViewerWindow"); group.writeEntry("Window Width", sizeX); group.writeEntry("Window Height", sizeY); group.writeEntry("Window Maximized", isMaximized()); for (int i = 0; i != tabBar.count(); i++) { PanelViewerBase* pvb = static_cast(tabBar.widget(i)); if (!pvb) continue; tabBar.setCurrentIndex(i); if (!pvb->queryClose()) return false; } return true; } void KrViewer::viewGeneric() { PanelViewerBase* pvb = static_cast(tabBar.currentWidget()); if (pvb) viewInternal(pvb->url(), Generic); } void KrViewer::viewText() { PanelViewerBase* pvb = static_cast(tabBar.currentWidget()); if (pvb) viewInternal(pvb->url(), Text); } void KrViewer::viewLister() { PanelViewerBase* pvb = static_cast(tabBar.currentWidget()); if (pvb) viewInternal(pvb->url(), Lister); } void KrViewer::viewHex() { PanelViewerBase* pvb = static_cast(tabBar.currentWidget()); if (pvb) viewInternal(pvb->url(), Hex); } void KrViewer::editText() { PanelViewerBase* pvb = static_cast(tabBar.currentWidget()); if (pvb) editInternal(pvb->url(), Text); } void KrViewer::checkModified() { QTimer::singleShot(CHECK_MODFIED_INTERVAL, this, SLOT(checkModified())); PanelViewerBase* pvb = static_cast(tabBar.currentWidget()); if (pvb) refreshTab(pvb); } void KrViewer::refreshTab(PanelViewerBase* pvb) { int ndx = tabBar.indexOf(pvb); tabBar.setTabText(ndx, makeTabText(pvb)); tabBar.setTabIcon(ndx, makeTabIcon(pvb)); tabBar.setTabToolTip(ndx, makeTabToolTip(pvb)); } void KrViewer::nextTab() { int index = (tabBar.currentIndex() + 1) % tabBar.count(); tabBar.setCurrentIndex(index); } void KrViewer::prevTab() { int index = (tabBar.currentIndex() - 1) % tabBar.count(); while (index < 0) index += tabBar.count(); tabBar.setCurrentIndex(index); } void KrViewer::detachTab() { PanelViewerBase* pvb = static_cast(tabBar.currentWidget()); if (!pvb) return; KrViewer* viewer = getViewer(true); bool wasPartAdded = false; KParts::ReadOnlyPart *part = pvb->part(); if (part && isPartAdded(part)) { wasPartAdded = true; removePart(part); } disconnect(pvb, 0, this, 0); tabBar.removeTab(tabBar.indexOf(pvb)); if (tabBar.count() == 1) { //no point in detaching only one tab.. detachAction->setEnabled(false); } pvb->setParent(&viewer->tabBar); pvb->move(QPoint(0, 0)); viewer->addTab(pvb); if (wasPartAdded) { viewer->addPart(part); if (part->widget()) part->widget()->setFocus(); } viewer->show(); } void KrViewer::changeEvent(QEvent *e) { if (e->type() == QEvent::ActivationChange && isActiveWindow()) if (viewers.removeAll(this)) viewers.prepend(this); // move to first } void KrViewer::print() { PanelViewerBase* pvb = static_cast(tabBar.currentWidget()); if (!pvb || !pvb->part() || !isPartAdded(pvb->part())) return; KParts::BrowserExtension * ext = KParts::BrowserExtension::childObject(pvb->part()); if (ext && ext->isActionEnabled("print")) Invoker(ext, SLOT(print())).invoke(); } void KrViewer::copy() { PanelViewerBase* pvb = static_cast(tabBar.currentWidget()); if (!pvb || !pvb->part() || !isPartAdded(pvb->part())) return; KParts::BrowserExtension * ext = KParts::BrowserExtension::childObject(pvb->part()); if (ext && ext->isActionEnabled("copy")) Invoker(ext, SLOT(copy())).invoke(); } void KrViewer::updateActions() { QList actList = toolBar()->actions(); bool hasPrint = false, hasCopy = false; foreach(QAction *a, actList) { if (a->text() == printAction->text()) hasPrint = true; if (a->text() == copyAction->text()) hasCopy = true; } if (!hasPrint) toolBar()->addAction(printAction->icon(), printAction->text(), this, SLOT(print())); if (!hasCopy) toolBar()->addAction(copyAction->icon(), copyAction->text(), this, SLOT(copy())); } bool KrViewer::isPartAdded(KParts::Part* part) { return manager.parts().contains(part); } void KrViewer::resizeEvent(QResizeEvent *e) { if (!isMaximized()) { sizeX = e->size().width(); sizeY = e->size().height(); } KParts::MainWindow::resizeEvent(e); } QString KrViewer::makeTabText(PanelViewerBase *pvb) { QString fileName = pvb->url().fileName(); if (pvb->isModified()) fileName.prepend("*"); return pvb->isEditor() ? i18nc("filename (filestate)", "%1 (Editing)", fileName) : i18nc("filename (filestate)", "%1 (Viewing)", fileName); } QString KrViewer::makeTabToolTip(PanelViewerBase *pvb) { QString url = pvb->url().toDisplayString(QUrl::PreferLocalFile); return pvb->isEditor() ? i18nc("filestate: filename", "Editing: %1", url) : i18nc("filestate: filename", "Viewing: %1", url); } QIcon KrViewer::makeTabIcon(PanelViewerBase *pvb) { QString iconName; if (pvb->isModified()) iconName = MODIFIED_ICON; else if (pvb->isEditor()) iconName = EDIT_ICON; else iconName = VIEW_ICON; return Icon(iconName); } void KrViewer::addPart(KParts::ReadOnlyPart *part) { Q_ASSERT(part); Q_ASSERT(!isPartAdded(part)); if (isPartAdded(part)) { qDebug()<<"part already added:"<installEventFilter(this); manager.addPart(part, false); // don't automatically set active part } void KrViewer::removePart(KParts::ReadOnlyPart *part) { Q_ASSERT(part); Q_ASSERT(isPartAdded(part)); if (isPartAdded(part)) { disconnect(part, 0, this, 0); part->removeEventFilter(this); manager.removePart(part); } else qDebug()<<"part hasn't been added:"<openUrl(url); } void KrViewer::editInternal(QUrl url, Mode mode, QWidget * parent) { returnFocusTo = parent; PanelViewerBase* editWidget = new PanelEditor(&tabBar, mode); addTab(editWidget); editWidget->openUrl(url); } diff --git a/krusader/KViewer/lister.cpp b/krusader/KViewer/lister.cpp index 55219316..de750c80 100644 --- a/krusader/KViewer/lister.cpp +++ b/krusader/KViewer/lister.cpp @@ -1,2277 +1,2277 @@ /***************************************************************************** * 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 "lister.h" // QtCore #include #include #include #include #include // QtGui #include #include #include #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include // QtPrintSupport #include #include #include #include #include #include #include #include #include #include #include #include "../krglobal.h" #include "../icon.h" #include "../kractions.h" #include "../GUI/krremoteencodingmenu.h" #define SEARCH_CACHE_CHARS 100000 #define SEARCH_MAX_ROW_LEN 4000 #define CONTROL_CHAR 752 #define CACHE_SIZE 1048576 // cache size set to 1MiB ListerTextArea::ListerTextArea(Lister *lister, QWidget *parent) : KTextEdit(parent), _lister(lister) { connect(this, &QTextEdit::cursorPositionChanged, this, &ListerTextArea::slotCursorPositionChanged); _tabWidth = 4; setWordWrapMode(QTextOption::NoWrap); setLineWrapMode(QTextEdit::NoWrap); // zoom shortcuts - connect(new QShortcut(QKeySequence("Ctrl++"), this), SIGNAL(activated()), this, SLOT(zoomIn())); - connect(new QShortcut(QKeySequence("Ctrl+-"), this), SIGNAL(activated()), this, SLOT(zoomOut())); + connect(new QShortcut(QKeySequence("Ctrl++"), this), &QShortcut::activated, this, [=]() { zoomIn(); }); + connect(new QShortcut(QKeySequence("Ctrl+-"), this), &QShortcut::activated, this, [=]() { zoomOut(); }); // start cursor blinking connect(&_blinkTimer, &QTimer::timeout, this, [=] { if (!_cursorBlinkMutex.tryLock()) { return; } setCursorWidth(cursorWidth() == 0 ? 2 : 0); _cursorBlinkMutex.unlock(); }); _blinkTimer.start(500); } void ListerTextArea::reset() { _screenStartPos = 0; _cursorPos = 0; _cursorAnchorPos = -1; _cursorAtFirstColumn = true; calculateText(); } void ListerTextArea::sizeChanged() { if (_cursorAnchorPos > _lister->fileSize()) _cursorAnchorPos = -1; if (_cursorPos > _lister->fileSize()) _cursorPos = _lister->fileSize(); redrawTextArea(true); } void ListerTextArea::resizeEvent(QResizeEvent * event) { KTextEdit::resizeEvent(event); redrawTextArea(); } void ListerTextArea::calculateText(const bool forcedUpdate) { const QRect contentRect = viewport()->contentsRect(); const QFontMetrics fm(font()); const int fontHeight = std::max(fm.height(), 1); // This is quite accurate (although not perfect) way of getting // a single character width along with its surrounding space. const float fontWidth = (fm.width("WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW") - fm.width("W")) / 99.0; const int sizeY = contentRect.height() / fontHeight; _pageSize = sizeY; const int textViewportWidth = std::max(contentRect.width() - (int) fontWidth, 0); setTabStopWidth(fontWidth * _tabWidth); const int sizeX = textViewportWidth / fontWidth; _sizeChanged = (_sizeY != sizeY) || (_sizeX != sizeX) || forcedUpdate; _sizeY = sizeY; _sizeX = sizeX; QList rowStarts; QStringList list = readLines(_screenStartPos, _screenEndPos, _sizeY, &rowStarts); if (_sizeChanged) { _averagePageSize = _screenEndPos - _screenStartPos; setUpScrollBar(); } const QStringList listRemn = readLines(_screenEndPos, _screenEndPos, 1); list << listRemn; if (list != _rowContent) { _cursorBlinkMutex.lock(); _blinkTimer.stop(); setCursorWidth(0); setPlainText(list.join("\n")); if (_cursorAnchorPos == -1 || _cursorAnchorPos == _cursorPos) { clearSelection(); _blinkTimer.start(500); } _cursorBlinkMutex.unlock(); _rowContent = list; _rowStarts = rowStarts; if (_rowStarts.size() < _sizeY) { _rowStarts << _screenEndPos; } } } qint64 ListerTextArea::textToFilePositionOnScreen(const int x, const int y, bool &isfirst) { isfirst = (x == 0); if (y >= _rowStarts.count()) { return 0; } const qint64 rowStart = _rowStarts[ y ]; if (x == 0) { return rowStart; } if (_hexMode) { const qint64 pos = rowStart + _lister->hexPositionToIndex(_sizeX, x); if (pos > _lister->fileSize()) { return _lister->fileSize(); } return pos; } // we can't use fromUnicode because of the invalid encoded chars const int maxBytes = 2 * _sizeX * MAX_CHAR_LENGTH; QByteArray chunk = _lister->cacheChunk(rowStart, maxBytes); QTextStream stream(&chunk); stream.setCodec(_lister->codec()); stream.read(x); return rowStart + stream.pos(); } void ListerTextArea::fileToTextPositionOnScreen(const qint64 p, const bool isfirst, int &x, int &y) { // check if cursor is outside of visible area if (p < _screenStartPos || p > _screenEndPos || _rowStarts.count() < 1) { x = -1; y = (p > _screenEndPos) ? -2 : -1; return; } // find row y = 0; while (y < _rowStarts.count() && _rowStarts[ y ] <= p) { y++; } y--; if (y < 0) { x = y = -1; return; } const qint64 rowStart = _rowStarts[ y ]; if (_hexMode) { x = _lister->hexIndexToPosition(_sizeX, (int)(p - rowStart)); return; } // find column const int maxBytes = 2 * _sizeX * MAX_CHAR_LENGTH; x = 0; if (rowStart >= p) { if ((rowStart == p) && !isfirst && y > 0) { const qint64 previousRow = _rowStarts[ y - 1 ]; const QByteArray chunk = _lister->cacheChunk(previousRow, maxBytes); QByteArray cachedBuffer = chunk.left(p - previousRow); QTextStream stream(&cachedBuffer); stream.setCodec(_lister->codec()); stream.read(_rowContent[ y - 1].length()); if (previousRow + stream.pos() == p) { y--; x = _rowContent[ y ].length(); } } return; } const QByteArray chunk = _lister->cacheChunk(rowStart, maxBytes); const QByteArray cachedBuffer = chunk.left(p - rowStart); x = _lister->codec()->toUnicode(cachedBuffer).length(); } void ListerTextArea::getCursorPosition(int &x, int &y) { getScreenPosition(textCursor().position(), x, y); } void ListerTextArea::getScreenPosition(const int position, int &x, int &y) { x = position; y = 0; foreach (const QString &row, _rowContent) { const int rowLen = row.length() + 1; if (x < rowLen) { return; } x -= rowLen; y++; } } void ListerTextArea::setCursorPositionOnScreen(const int x, const int y, const int anchorX, const int anchorY) { setCursorWidth(0); int finalX = x; int finalY = y; if (finalX == -1 || finalY < 0) { if (anchorY == -1) { return; } if (finalY == -2) { finalY = _sizeY; finalX = (_rowContent.count() > _sizeY) ? _rowContent[ _sizeY ].length() : 0; } else finalX = finalY = 0; } const int realSizeY = std::min(_sizeY + 1, _rowContent.count()); const auto setUpCursor = [&] (const int cursorX, const int cursorY, const QTextCursor::MoveMode mode) -> bool { if (cursorY > realSizeY) { return false; } _skipCursorChangedListener = true; moveCursor(QTextCursor::Start, mode); for (int i = 0; i < cursorY; i++) { moveCursor(QTextCursor::Down, mode); } int finalCursorX = cursorX; if (_rowContent.count() > cursorY && finalCursorX > _rowContent[ cursorY ].length()) { finalCursorX = _rowContent[ cursorY ].length(); } for (int i = 0; i < finalCursorX; i++) { moveCursor(QTextCursor::Right, mode); } _skipCursorChangedListener = false; return true; }; QTextCursor::MoveMode mode = QTextCursor::MoveAnchor; // set cursor anchor if (anchorX != -1 && anchorY != -1) { const bool canContinue = setUpCursor(anchorX, anchorY, mode); if (!canContinue) { return; } mode = QTextCursor::KeepAnchor; } // set cursor position setUpCursor(finalX, finalY, mode); } qint64 ListerTextArea::getCursorPosition(bool &isfirst) { if (cursorWidth() == 0) { isfirst = _cursorAtFirstColumn; return _cursorPos; } int x, y; getCursorPosition(x, y); return textToFilePositionOnScreen(x, y, isfirst); } void ListerTextArea::setCursorPositionInDocument(const qint64 p, const bool isfirst) { _cursorPos = p; int x, y; fileToTextPositionOnScreen(p, isfirst, x, y); bool startBlinkTimer = _screenStartPos <= _cursorPos && _cursorPos <= _screenEndPos; int anchorX = -1, anchorY = -1; if (_cursorAnchorPos != -1 && _cursorAnchorPos != p) { int anchPos = _cursorAnchorPos; bool anchorBelow = false, anchorAbove = false; if (anchPos < _screenStartPos) { anchPos = _screenStartPos; anchorY = -2; anchorAbove = true; } if (anchPos > _screenEndPos) { anchPos = _screenEndPos; anchorY = -3; anchorBelow = true; } fileToTextPositionOnScreen(anchPos, isfirst, anchorX, anchorY); if (_hexMode) { if (anchorAbove) { anchorX = 0; } if (anchorBelow && _rowContent.count() > 0) { anchorX = _rowContent[ 0 ].length(); } } startBlinkTimer = startBlinkTimer && !anchorAbove && !anchorBelow; } if (startBlinkTimer) { _blinkTimer.start(500); } setCursorPositionOnScreen(x, y, anchorX, anchorY); _lister->slotUpdate(); } void ListerTextArea::slotCursorPositionChanged() { if (_skipCursorChangedListener) { return; } int cursorX, cursorY; getCursorPosition(cursorX, cursorY); _cursorAtFirstColumn = (cursorX == 0); _cursorPos = textToFilePositionOnScreen(cursorX, cursorY, _cursorAtFirstColumn); _lister->slotUpdate(); } QString ListerTextArea::readSection(const qint64 p1, const qint64 p2) { if (p1 == p2) return QString(); qint64 sel1 = p1; qint64 sel2 = p2; if (sel1 > sel2) { std::swap(sel1, sel2); } QString section; if (_hexMode) { while (sel1 != sel2) { const QStringList list = _lister->readHexLines(sel1, sel2, _sizeX, 1); if (list.isEmpty()) { break; } if (!section.isEmpty()) { section += QChar('\n'); } section += list.at(0); } return section; } qint64 pos = sel1; QScopedPointer decoder(_lister->codec()->makeDecoder()); do { const int maxBytes = std::min(_sizeX * _sizeY * MAX_CHAR_LENGTH, (int) (sel2 - pos)); const QByteArray chunk = _lister->cacheChunk(pos, maxBytes); if (chunk.isEmpty()) break; section += decoder->toUnicode(chunk); pos += chunk.size(); } while (pos < sel2); return section; } QStringList ListerTextArea::readLines(qint64 filePos, qint64 &endPos, const int lines, QList * locs) { QStringList list; if (_hexMode) { endPos = _lister->fileSize(); if (filePos >= endPos) { return list; } const int bytes = _lister->hexBytesPerLine(_sizeX); qint64 startPos = (filePos / bytes) * bytes; qint64 shiftPos = startPos; list = _lister->readHexLines(shiftPos, endPos, _sizeX, lines); endPos = shiftPos; if (locs) { for (int i = 0; i < list.count(); i++) { (*locs) << startPos; startPos += bytes; } } return list; } endPos = filePos; const int maxBytes = _sizeX * _sizeY * MAX_CHAR_LENGTH; const QByteArray chunk = _lister->cacheChunk(filePos, maxBytes); if (chunk.isEmpty()) return list; int byteCounter = 0; QString row = ""; int effLength = 0; if (locs) (*locs) << filePos; bool skipImmediateNewline = false; const auto performNewline = [&] (qint64 nextRowStartOffset) { list << row; effLength = 0; row = ""; if (locs) { (*locs) << (filePos + nextRowStartOffset); } }; QScopedPointer decoder(_lister->codec()->makeDecoder()); while (byteCounter < chunk.size() && list.size() < lines) { const int lastCnt = byteCounter; QString chr = decoder->toUnicode(chunk.mid(byteCounter++, 1)); if (chr.isEmpty()) { continue; } if ((chr[ 0 ] < 32) && (chr[ 0 ] != '\n') && (chr[ 0 ] != '\t')) { chr = QChar(CONTROL_CHAR); } if (chr == "\n") { if (!skipImmediateNewline) { performNewline(byteCounter); } skipImmediateNewline = false; continue; } skipImmediateNewline = false; if (chr == "\t") { effLength += _tabWidth - (effLength % _tabWidth) - 1; if (effLength > _sizeX) { performNewline(lastCnt); } } row += chr; effLength++; if (effLength >= _sizeX) { performNewline(byteCounter); skipImmediateNewline = true; } } if (list.size() < lines) list << row; endPos = filePos + byteCounter; return list; } void ListerTextArea::setUpScrollBar() { if (_averagePageSize == _lister->fileSize()) { _lister->scrollBar()->setPageStep(0); _lister->scrollBar()->setMaximum(0); _lister->scrollBar()->hide(); _lastPageStartPos = 0; } else { const int maxPage = MAX_CHAR_LENGTH * _sizeX * _sizeY; qint64 pageStartPos = _lister->fileSize() - maxPage; qint64 endPos; if (pageStartPos < 0) pageStartPos = 0; QStringList list = readLines(pageStartPos, endPos, maxPage); if (list.count() <= _sizeY) { _lastPageStartPos = 0; } else { readLines(pageStartPos, _lastPageStartPos, list.count() - _sizeY); } const int maximum = (_lastPageStartPos > SLIDER_MAX) ? SLIDER_MAX : _lastPageStartPos; int pageSize = (_lastPageStartPos > SLIDER_MAX) ? SLIDER_MAX * _averagePageSize / _lastPageStartPos : _averagePageSize; if (pageSize == 0) pageSize++; _lister->scrollBar()->setPageStep(pageSize); _lister->scrollBar()->setMaximum(maximum); _lister->scrollBar()->show(); } } void ListerTextArea::keyPressEvent(QKeyEvent * ke) { if (KrGlobal::copyShortcut == QKeySequence(ke->key() | ke->modifiers())) { copySelectedToClipboard(); ke->accept(); return; } if (ke->modifiers() == Qt::NoModifier || ke->modifiers() & Qt::ShiftModifier) { qint64 newAnchor = -1; if (ke->modifiers() & Qt::ShiftModifier) { newAnchor = _cursorAnchorPos; if (_cursorAnchorPos == -1) newAnchor = _cursorPos; } switch (ke->key()) { case Qt::Key_F3: ke->accept(); if (ke->modifiers() == Qt::ShiftModifier) _lister->searchPrev(); else _lister->searchNext(); return; case Qt::Key_Home: case Qt::Key_End: _cursorAnchorPos = newAnchor; break; case Qt::Key_Left: { _cursorAnchorPos = newAnchor; ensureVisibleCursor(); int x, y; getCursorPosition(x, y); if (y == 0 && x == 0) slotActionTriggered(QAbstractSlider::SliderSingleStepSub); } break; case Qt::Key_Right: { _cursorAnchorPos = newAnchor; ensureVisibleCursor(); if (textCursor().position() == toPlainText().length()) slotActionTriggered(QAbstractSlider::SliderSingleStepAdd); } break; case Qt::Key_Up: { _cursorAnchorPos = newAnchor; ensureVisibleCursor(); int x, y; getCursorPosition(x, y); if (y == 0) slotActionTriggered(QAbstractSlider::SliderSingleStepSub); } break; case Qt::Key_Down: { _cursorAnchorPos = newAnchor; ensureVisibleCursor(); int x, y; getCursorPosition(x, y); if (y >= _sizeY-1) slotActionTriggered(QAbstractSlider::SliderSingleStepAdd); } break; case Qt::Key_PageDown: { _cursorAnchorPos = newAnchor; ensureVisibleCursor(); ke->accept(); int x, y; getCursorPosition(x, y); slotActionTriggered(QAbstractSlider::SliderPageStepAdd); y += _sizeY - _skippedLines; if (y > _rowContent.count()) { y = _rowContent.count() - 1; if (y > 0) x = _rowContent[ y - 1 ].length(); else x = 0; } _cursorPos = textToFilePositionOnScreen(x, y, _cursorAtFirstColumn); setCursorPositionInDocument(_cursorPos, _cursorAtFirstColumn); } return; case Qt::Key_PageUp: { _cursorAnchorPos = newAnchor; ensureVisibleCursor(); ke->accept(); int x, y; getCursorPosition(x, y); slotActionTriggered(QAbstractSlider::SliderPageStepSub); y -= _sizeY - _skippedLines; if (y < 0) { y = 0; x = 0; } _cursorPos = textToFilePositionOnScreen(x, y, _cursorAtFirstColumn); setCursorPositionInDocument(_cursorPos, _cursorAtFirstColumn); } return; } } if (ke->modifiers() == Qt::ControlModifier) { switch (ke->key()) { case Qt::Key_G: ke->accept(); _lister->jumpToPosition(); return; case Qt::Key_F: ke->accept(); _lister->enableSearch(true); return; case Qt::Key_Home: _cursorAnchorPos = -1; ke->accept(); slotActionTriggered(QAbstractSlider::SliderToMinimum); setCursorPositionInDocument((qint64)0, true); return; case Qt::Key_A: case Qt::Key_End: { _cursorAnchorPos = (ke->key() == Qt::Key_A) ? 0 : -1; ke->accept(); slotActionTriggered(QAbstractSlider::SliderToMaximum); const qint64 endPos = _lister->fileSize(); setCursorPositionInDocument(endPos, false); return; } case Qt::Key_Down: ke->accept(); slotActionTriggered(QAbstractSlider::SliderSingleStepAdd); return; case Qt::Key_Up: ke->accept(); slotActionTriggered(QAbstractSlider::SliderSingleStepSub); return; case Qt::Key_PageDown: ke->accept(); slotActionTriggered(QAbstractSlider::SliderPageStepAdd); return; case Qt::Key_PageUp: ke->accept(); slotActionTriggered(QAbstractSlider::SliderPageStepSub); return; } } const int oldAnchor = textCursor().anchor(); KTextEdit::keyPressEvent(ke); handleAnchorChange(oldAnchor); } void ListerTextArea::mousePressEvent(QMouseEvent * e) { KTextEdit::mousePressEvent(e); // do change anchor only when shift is not pressed if (!(QGuiApplication::keyboardModifiers() & Qt::ShiftModifier)) { performAnchorChange(textCursor().anchor()); } } void ListerTextArea::mouseDoubleClickEvent(QMouseEvent * e) { _cursorAnchorPos = -1; const int oldAnchor = textCursor().anchor(); KTextEdit::mouseDoubleClickEvent(e); handleAnchorChange(oldAnchor); } void ListerTextArea::mouseMoveEvent(QMouseEvent * e) { if (e->pos().y() < 0) { slotActionTriggered(QAbstractSlider::SliderSingleStepSub); } else if (e->pos().y() > height()) { slotActionTriggered(QAbstractSlider::SliderSingleStepAdd); } KTextEdit::mouseMoveEvent(e); } void ListerTextArea::wheelEvent(QWheelEvent * e) { int delta = e->delta(); if (delta) { // zooming if (e->modifiers() & Qt::ControlModifier) { e->accept(); if (delta > 0) { zoomIn(); } else { zoomOut(); } return; } if (delta > 0) { e->accept(); while (delta > 0) { slotActionTriggered(QAbstractSlider::SliderSingleStepSub); slotActionTriggered(QAbstractSlider::SliderSingleStepSub); slotActionTriggered(QAbstractSlider::SliderSingleStepSub); delta -= 120; } } else { e->accept(); while (delta < 0) { slotActionTriggered(QAbstractSlider::SliderSingleStepAdd); slotActionTriggered(QAbstractSlider::SliderSingleStepAdd); slotActionTriggered(QAbstractSlider::SliderSingleStepAdd); delta += 120; } } setCursorPositionInDocument(_cursorPos, false); } } void ListerTextArea::slotActionTriggered(int action) { switch (action) { case QAbstractSlider::SliderSingleStepAdd: { qint64 endPos; readLines(_screenStartPos, endPos, 1); if (endPos <= _lastPageStartPos) { _screenStartPos = endPos; } } break; case QAbstractSlider::SliderSingleStepSub: { if (_screenStartPos == 0) { break; } if (_hexMode) { int bytesPerRow = _lister->hexBytesPerLine(_sizeX); _screenStartPos = (_screenStartPos / bytesPerRow) * bytesPerRow; _screenStartPos -= bytesPerRow; if (_screenStartPos < 0) { _screenStartPos = 0; } break; } int maxSize = _sizeX * _sizeY * MAX_CHAR_LENGTH; const QByteArray encodedEnter = _lister->codec()->fromUnicode(QString("\n")); qint64 readPos = _screenStartPos - maxSize; if (readPos < 0) { readPos = 0; } maxSize = _screenStartPos - readPos; const QByteArray chunk = _lister->cacheChunk(readPos, maxSize); int from = chunk.size(); while (from > 0) { from--; from = chunk.lastIndexOf(encodedEnter, from); if (from == -1) { from = 0; break; } const int backRef = std::max(from - 20, 0); const int size = from - backRef + encodedEnter.size(); const QString decoded = _lister->codec()->toUnicode(chunk.mid(backRef, size)); if (decoded.endsWith(QLatin1String("\n"))) { if (from < (chunk.size() - encodedEnter.size())) { from += encodedEnter.size(); break; } } } readPos += from; qint64 previousPos = readPos; while (readPos < _screenStartPos) { previousPos = readPos; readLines(readPos, readPos, 1); } _screenStartPos = previousPos; } break; case QAbstractSlider::SliderPageStepAdd: { _skippedLines = 0; qint64 endPos; for (int i = 0; i < _sizeY; i++) { readLines(_screenStartPos, endPos, 1); if (endPos <= _lastPageStartPos) { _screenStartPos = endPos; _skippedLines++; } else { break; } } } break; case QAbstractSlider::SliderPageStepSub: { _skippedLines = 0; if (_screenStartPos == 0) { break; } if (_hexMode) { const int bytesPerRow = _lister->hexBytesPerLine(_sizeX); _screenStartPos = (_screenStartPos / bytesPerRow) * bytesPerRow; _screenStartPos -= _sizeY * bytesPerRow; if (_screenStartPos < 0) { _screenStartPos = 0; } break; } // text lister mode int maxSize = 2 * _sizeX * _sizeY * MAX_CHAR_LENGTH; const QByteArray encodedEnter = _lister->codec()->fromUnicode(QString("\n")); qint64 readPos = _screenStartPos - maxSize; if (readPos < 0) readPos = 0; maxSize = _screenStartPos - readPos; const QByteArray chunk = _lister->cacheChunk(readPos, maxSize); maxSize = chunk.size(); int sizeY = _sizeY + 1; int origSizeY = sizeY; int from = maxSize; int lastEnter = maxSize; bool readNext = true; while (readNext) { readNext = false; while (from > 0) { from--; from = chunk.lastIndexOf(encodedEnter, from); if (from == -1) { from = 0; break; } const int backRef = std::max(from - 20, 0); const int size = from - backRef + encodedEnter.size(); QString decoded = _lister->codec()->toUnicode(chunk.mid(backRef, size)); if (decoded.endsWith(QLatin1String("\n"))) { if (from < (maxSize - encodedEnter.size())) { int arrayStart = from + encodedEnter.size(); decoded = _lister->codec()->toUnicode(chunk.mid(arrayStart, lastEnter - arrayStart)); sizeY -= ((decoded.length() / (_sizeX + 1)) + 1); if (sizeY < 0) { from = arrayStart; break; } } lastEnter = from; } } qint64 searchPos = readPos + from; QList locs; while (searchPos < _screenStartPos) { locs << searchPos; readLines(searchPos, searchPos, 1); } if (locs.count() >= _sizeY) { _screenStartPos = locs[ locs.count() - _sizeY ]; } else if (from != 0) { origSizeY += locs.count() + 1; sizeY = origSizeY; readNext = true; } else if (readPos == 0) { _screenStartPos = 0; } } } break; case QAbstractSlider::SliderToMinimum: _screenStartPos = 0; break; case QAbstractSlider::SliderToMaximum: _screenStartPos = _lastPageStartPos; break; case QAbstractSlider::SliderMove: { if (_inSliderOp) // self created call? return; qint64 pos = _lister->scrollBar()->sliderPosition(); if (pos == SLIDER_MAX) { _screenStartPos = _lastPageStartPos; break; } else if (pos == 0) { _screenStartPos = 0; break; } if (_lastPageStartPos > SLIDER_MAX) pos = _lastPageStartPos * pos / SLIDER_MAX; if (pos != 0) { if (_hexMode) { const int bytesPerRow = _lister->hexBytesPerLine(_sizeX); pos = (pos / bytesPerRow) * bytesPerRow; } else { const int maxSize = _sizeX * _sizeY * MAX_CHAR_LENGTH; qint64 readPos = pos - maxSize; if (readPos < 0) readPos = 0; qint64 previousPos = readPos; while (readPos <= pos) { previousPos = readPos; readLines(readPos, readPos, 1); } pos = previousPos; } } _screenStartPos = pos; } break; case QAbstractSlider::SliderNoAction: break; }; _inSliderOp = true; const int value = (_lastPageStartPos > SLIDER_MAX) ? SLIDER_MAX * _screenStartPos / _lastPageStartPos : _screenStartPos; _lister->scrollBar()->setSliderPosition(value); _inSliderOp = false; redrawTextArea(); } void ListerTextArea::redrawTextArea(bool forcedUpdate) { if (_redrawing) { return; } _redrawing = true; bool isfirst; const qint64 pos = getCursorPosition(isfirst); calculateText(forcedUpdate); setCursorPositionInDocument(pos, isfirst); _redrawing = false; } void ListerTextArea::ensureVisibleCursor() { if (_screenStartPos <= _cursorPos && _cursorPos <= _screenEndPos) { return; } int delta = _sizeY / 2; if (delta == 0) delta++; qint64 newScreenStart = _cursorPos; while (delta) { const int maxSize = _sizeX * MAX_CHAR_LENGTH; qint64 readPos = newScreenStart - maxSize; if (readPos < 0) readPos = 0; qint64 previousPos = readPos; while (readPos < newScreenStart) { previousPos = readPos; readLines(readPos, readPos, 1); if (readPos == previousPos) break; } newScreenStart = previousPos; delta--; } if (newScreenStart > _lastPageStartPos) { newScreenStart = _lastPageStartPos; } _screenStartPos = newScreenStart; slotActionTriggered(QAbstractSlider::SliderNoAction); } void ListerTextArea::setAnchorAndCursor(qint64 anchor, qint64 cursor) { _cursorPos = cursor; _cursorAnchorPos = anchor; ensureVisibleCursor(); setCursorPositionInDocument(cursor, false); } QString ListerTextArea::getSelectedText() { if (_cursorAnchorPos != -1 && _cursorAnchorPos != _cursorPos) { return readSection(_cursorAnchorPos, _cursorPos); } return QString(); } void ListerTextArea::copySelectedToClipboard() { const QString selection = getSelectedText(); if (!selection.isEmpty()) { QApplication::clipboard()->setText(selection); } } void ListerTextArea::clearSelection() { QTextCursor cursor = textCursor(); cursor.clearSelection(); setTextCursor(cursor); _cursorAnchorPos = -1; } void ListerTextArea::performAnchorChange(int anchor) { int x, y; bool isfirst; getScreenPosition(anchor, x, y); _cursorAnchorPos = textToFilePositionOnScreen(x, y, isfirst); } void ListerTextArea::handleAnchorChange(int oldAnchor) { const int anchor = textCursor().anchor(); if (oldAnchor != anchor) { performAnchorChange(anchor); } } void ListerTextArea::setHexMode(bool hexMode) { bool isfirst; const qint64 pos = getCursorPosition(isfirst); _hexMode = hexMode; _screenStartPos = 0; calculateText(true); setCursorPositionInDocument(pos, isfirst); ensureVisibleCursor(); } void ListerTextArea::zoomIn(int range) { KTextEdit::zoomIn(range); redrawTextArea(); } void ListerTextArea::zoomOut(int range) { KTextEdit::zoomOut(range); redrawTextArea(); } ListerPane::ListerPane(Lister *lister, QWidget *parent) : QWidget(parent), _lister(lister) { } bool ListerPane::event(QEvent *e) { const bool handled = ListerPane::handleCloseEvent(e); if (!handled) { return QWidget::event(e); } return true; } bool ListerPane::handleCloseEvent(QEvent *e) { if (e->type() == QEvent::ShortcutOverride) { QKeyEvent *ke = static_cast(e); if (ke->key() == Qt::Key_Escape) { if (_lister->isSearchEnabled()) { _lister->searchDelete(); _lister->enableSearch(false); ke->accept(); return true; } if (!_lister->textArea()->getSelectedText().isEmpty()) { _lister->textArea()->clearSelection(); ke->accept(); return true; } } } return false; } ListerBrowserExtension::ListerBrowserExtension(Lister * lister) : KParts::BrowserExtension(lister) { _lister = lister; emit enableAction("copy", true); emit enableAction("print", true); } void ListerBrowserExtension::copy() { _lister->textArea()->copySelectedToClipboard(); } void ListerBrowserExtension::print() { _lister->print(); } class ListerEncodingMenu : public KrRemoteEncodingMenu { public: ListerEncodingMenu(Lister *lister, const QString &text, const QString &icon, KActionCollection *parent) : KrRemoteEncodingMenu(text, icon, parent), _lister(lister) { } protected: virtual QString currentCharacterSet() Q_DECL_OVERRIDE { return _lister->characterSet(); } virtual void chooseDefault() Q_DECL_OVERRIDE { _lister->setCharacterSet(QString()); } virtual void chooseEncoding(QString encodingName) Q_DECL_OVERRIDE { QString charset = KCharsets::charsets()->encodingForName(encodingName); _lister->setCharacterSet(charset); } Lister * _lister; }; Lister::Lister(QWidget *parent) : KParts::ReadOnlyPart(parent) { setXMLFile("krusaderlisterui.rc"); _actionSaveSelected = new QAction(Icon("document-save"), i18n("Save selection..."), this); - connect(_actionSaveSelected, SIGNAL(triggered(bool)), SLOT(saveSelected())); + connect(_actionSaveSelected, &QAction::triggered, this, &Lister::saveSelected); actionCollection()->addAction("save_selected", _actionSaveSelected); _actionSaveAs = new QAction(Icon("document-save-as"), i18n("Save as..."), this); - connect(_actionSaveAs, SIGNAL(triggered(bool)), SLOT(saveAs())); + connect(_actionSaveAs, &QAction::triggered, this, &Lister::saveAs); actionCollection()->addAction("save_as", _actionSaveAs); _actionPrint = new QAction(Icon("document-print"), i18n("Print..."), this); - connect(_actionPrint, SIGNAL(triggered(bool)), SLOT(print())); + connect(_actionPrint, &QAction::triggered, this, &Lister::print); actionCollection()->addAction("print", _actionPrint); actionCollection()->setDefaultShortcut(_actionPrint, Qt::CTRL + Qt::Key_P); _actionSearch = new QAction(Icon("system-search"), i18n("Search"), this); - connect(_actionSearch, SIGNAL(triggered(bool)), SLOT(searchAction())); + connect(_actionSearch, &QAction::triggered, this, &Lister::searchAction); actionCollection()->addAction("search", _actionSearch); actionCollection()->setDefaultShortcut(_actionSearch, Qt::CTRL + Qt::Key_F); _actionSearchNext = new QAction(Icon("go-down"), i18n("Search next"), this); - connect(_actionSearchNext, SIGNAL(triggered(bool)), SLOT(searchNext())); + connect(_actionSearchNext, &QAction::triggered, this, &Lister::searchNext); actionCollection()->addAction("search_next", _actionSearchNext); actionCollection()->setDefaultShortcut(_actionSearchNext, Qt::Key_F3); _actionSearchPrev = new QAction(Icon("go-up"), i18n("Search previous"), this); - connect(_actionSearchPrev, SIGNAL(triggered(bool)), SLOT(searchPrev())); + connect(_actionSearchPrev, &QAction::triggered, this, &Lister::searchPrev); actionCollection()->addAction("search_prev", _actionSearchPrev); actionCollection()->setDefaultShortcut(_actionSearchPrev, Qt::SHIFT + Qt::Key_F3); _actionJumpToPosition = new QAction(Icon("go-jump"), i18n("Jump to position"), this); - connect(_actionJumpToPosition, SIGNAL(triggered(bool)), SLOT(jumpToPosition())); + connect(_actionJumpToPosition, &QAction::triggered, this, &Lister::jumpToPosition); actionCollection()->addAction("jump_to_position", _actionJumpToPosition); actionCollection()->setDefaultShortcut(_actionJumpToPosition, Qt::CTRL + Qt::Key_G); _actionHexMode = new QAction(Icon("document-preview"), i18n("Hex mode"), this); - connect(_actionHexMode, SIGNAL(triggered(bool)), SLOT(toggleHexMode())); + connect(_actionHexMode, &QAction::triggered, this, &Lister::toggleHexMode); actionCollection()->addAction("hex_mode", _actionHexMode); actionCollection()->setDefaultShortcut(_actionHexMode, Qt::CTRL + Qt::Key_H); new ListerEncodingMenu(this, i18n("Select charset"), "character-set", actionCollection()); QWidget * widget = new ListerPane(this, parent); widget->setFocusPolicy(Qt::StrongFocus); QGridLayout *grid = new QGridLayout(widget); _textArea = new ListerTextArea(this, widget); _textArea->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); _textArea->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard); _textArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); _textArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); widget->setFocusProxy(_textArea); grid->addWidget(_textArea, 0, 0); _scrollBar = new QScrollBar(Qt::Vertical, widget); grid->addWidget(_scrollBar, 0, 1); _scrollBar->hide(); QWidget * statusWidget = new QWidget(widget); QHBoxLayout *hbox = new QHBoxLayout(statusWidget); _listerLabel = new QLabel(i18n("Lister:"), statusWidget); hbox->addWidget(_listerLabel); _searchProgressBar = new QProgressBar(statusWidget); _searchProgressBar->setMinimum(0); _searchProgressBar->setMaximum(1000); _searchProgressBar->setValue(0); _searchProgressBar->hide(); hbox->addWidget(_searchProgressBar); _searchStopButton = new QToolButton(statusWidget); _searchStopButton->setIcon(Icon("process-stop")); _searchStopButton->setToolTip(i18n("Stop search")); _searchStopButton->hide(); - connect(_searchStopButton, SIGNAL(clicked()), this, SLOT(searchDelete())); + connect(_searchStopButton, &QToolButton::clicked, this, &Lister::searchDelete); hbox->addWidget(_searchStopButton); _searchLineEdit = new KLineEdit(statusWidget); _searchLineEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); _originalBackground = _searchLineEdit->palette().color(QPalette::Base); _originalForeground = _searchLineEdit->palette().color(QPalette::Text); - connect(_searchLineEdit, SIGNAL(returnPressed()), this, SLOT(searchNext())); - connect(_searchLineEdit, SIGNAL(textChanged(QString)), this, SLOT(searchTextChanged())); + connect(_searchLineEdit, &KLineEdit::returnPressed, this, &Lister::searchNext); + connect(_searchLineEdit, &KLineEdit::textChanged, this, &Lister::searchTextChanged); hbox->addWidget(_searchLineEdit); _searchNextButton = new QPushButton(Icon("go-down"), i18n("Next"), statusWidget); _searchNextButton->setToolTip(i18n("Jump to next match")); - connect(_searchNextButton, SIGNAL(clicked()), this, SLOT(searchNext())); + connect(_searchNextButton, &QPushButton::clicked, this, &Lister::searchNext); hbox->addWidget(_searchNextButton); _searchPrevButton = new QPushButton(Icon("go-up"), i18n("Previous"), statusWidget); _searchPrevButton->setToolTip(i18n("Jump to previous match")); - connect(_searchPrevButton, SIGNAL(clicked()), this, SLOT(searchPrev())); + connect(_searchPrevButton, &QPushButton::clicked, this, &Lister::searchPrev); hbox->addWidget(_searchPrevButton); _searchOptions = new QPushButton(i18n("Options"), statusWidget); _searchOptions->setToolTip(i18n("Modify search behavior")); QMenu * menu = new QMenu(); _fromCursorAction = menu->addAction(i18n("From cursor")); _fromCursorAction->setCheckable(true); _fromCursorAction->setChecked(true); _caseSensitiveAction = menu->addAction(i18n("Case sensitive")); _caseSensitiveAction->setCheckable(true); _matchWholeWordsOnlyAction = menu->addAction(i18n("Match whole words only")); _matchWholeWordsOnlyAction->setCheckable(true); _regExpAction = menu->addAction(i18n("RegExp")); _regExpAction->setCheckable(true); _hexAction = menu->addAction(i18n("Hexadecimal")); _hexAction->setCheckable(true); _searchOptions->setMenu(menu); hbox->addWidget(_searchOptions); hbox->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); _statusLabel = new QLabel(statusWidget); hbox->addWidget(_statusLabel); grid->addWidget(statusWidget, 1, 0, 1, 2); setWidget(widget); connect(_scrollBar, SIGNAL(actionTriggered(int)), _textArea, SLOT(slotActionTriggered(int))); connect(&_searchUpdateTimer, &QTimer::timeout, this, &Lister::slotUpdate); new ListerBrowserExtension(this); enableSearch(false); _tempFile = new QTemporaryFile(this); _tempFile->setFileTemplate(QDir::tempPath() + QLatin1String("/krusader_lister.XXXXXX")); } bool Lister::openUrl(const QUrl &listerUrl) { _downloading = false; setUrl(listerUrl); _fileSize = 0; if (listerUrl.isLocalFile()) { _filePath = listerUrl.path(); if (!QFile::exists(_filePath)) return false; _fileSize = getFileSize(); } else { if (_tempFile->isOpen()) { _tempFile->close(); } _tempFile->open(); _filePath = _tempFile->fileName(); KIO::TransferJob *downloadJob = KIO::get(listerUrl, KIO::NoReload, KIO::HideProgressInfo); connect(downloadJob, &KIO::TransferJob::data, this, [=](KIO::Job*, QByteArray array) { if (array.size() != 0) { _tempFile->write(array); } }); connect(downloadJob, &KIO::TransferJob::result, this, [=](KJob *job) { _tempFile->flush(); if (job->error()) { /* any error occurred? */ KIO::TransferJob *kioJob = (KIO::TransferJob *)job; KMessageBox::error(_textArea, i18n("Error reading file %1.", kioJob->url().toDisplayString(QUrl::PreferLocalFile))); } _downloading = false; _downloadUpdateTimer.stop(); slotUpdate(); }); connect(&_downloadUpdateTimer, &QTimer::timeout, this, [&]() { slotUpdate(); }); _downloadUpdateTimer.start(500); _downloading = true; } // invalidate cache _cache.clear(); _textArea->reset(); emit started(0); emit setWindowCaption(listerUrl.toDisplayString()); emit completed(); return true; } QByteArray Lister::cacheChunk(const qint64 filePos, const int maxSize) { if (filePos >= _fileSize) { return QByteArray(); } int size = maxSize; if (_fileSize - filePos < size) { size = _fileSize - filePos; } if (!_cache.isEmpty() && (filePos >= _cachePos) && (filePos + size <= _cachePos + _cache.size())) { return _cache.mid(filePos - _cachePos, size); } const int negativeOffset = CACHE_SIZE * 2 / 5; qint64 cachePos = filePos - negativeOffset; if (cachePos < 0) cachePos = 0; QFile sourceFile(_filePath); if (!sourceFile.open(QIODevice::ReadOnly)) { return QByteArray(); } if (!sourceFile.seek(cachePos)) { return QByteArray(); } const QByteArray bytes = sourceFile.read(CACHE_SIZE); if (bytes.isEmpty()) { return bytes; } _cache = bytes; _cachePos = cachePos; const qint64 cacheRefIndex = filePos - _cachePos; int newSize = bytes.size() - cacheRefIndex; if (newSize < size) size = newSize; return _cache.mid(cacheRefIndex, size); } qint64 Lister::getFileSize() { return QFile(_filePath).size(); } void Lister::guiActivateEvent(KParts::GUIActivateEvent * event) { if (event->activated()) { slotUpdate(); _textArea->redrawTextArea(true); } else { enableSearch(false); } KParts::ReadOnlyPart::guiActivateEvent(event); } void Lister::slotUpdate() { const qint64 oldSize = _fileSize; _fileSize = getFileSize(); if (oldSize != _fileSize) _textArea->sizeChanged(); int cursorX = 0, cursorY = 0; _textArea->getCursorPosition(cursorX, cursorY); bool isfirst = false; const qint64 cursor = _textArea->getCursorPosition(isfirst); const int percent = (_fileSize == 0) ? 0 : (int)((201 * cursor) / _fileSize / 2); const QString status = i18n("Column: %1, Position: %2 (%3, %4%)", cursorX, cursor, _fileSize, percent); _statusLabel->setText(status); if (_searchProgressCounter) _searchProgressCounter--; } bool Lister::isSearchEnabled() { return !_searchLineEdit->isHidden() || !_searchProgressBar->isHidden(); } void Lister::enableSearch(const bool enable) { if (enable) { _listerLabel->setText(i18n("Search:")); _searchLineEdit->show(); _searchNextButton->show(); _searchPrevButton->show(); _searchOptions->show(); if (!_searchLineEdit->hasFocus()) { _searchLineEdit->setFocus(); const QString selection = _textArea->getSelectedText(); if (!selection.isEmpty()) { _searchLineEdit->setText(selection); } _searchLineEdit->selectAll(); } } else { _listerLabel->setText(i18n("Lister:")); _searchLineEdit->hide(); _searchNextButton->hide(); _searchPrevButton->hide(); _searchOptions->hide(); _textArea->setFocus(); } } void Lister::searchNext() { search(true); } void Lister::searchPrev() { search(false); } void Lister::search(const bool forward, const bool restart) { _restartFromBeginning = restart; if (_searchInProgress || _searchLineEdit->text().isEmpty()) return; if (_searchLineEdit->isHidden()) enableSearch(true); _searchPosition = forward ? 0 : _fileSize; if (_fromCursorAction->isChecked()) { bool isfirst; qint64 cursor = _textArea->getCursorPosition(isfirst); if (cursor != 0 && !forward) cursor--; if (_searchLastFailedPosition == -1 || _searchLastFailedPosition != cursor) _searchPosition = cursor; } const bool caseSensitive = _caseSensitiveAction->isChecked(); const bool matchWholeWord = _matchWholeWordsOnlyAction->isChecked(); const bool regExp = _regExpAction->isChecked(); const bool hex = _hexAction->isChecked(); if (hex) { QString hexcontent = _searchLineEdit->text(); hexcontent.remove(QLatin1String("0x")); hexcontent.remove(' '); hexcontent.remove('\t'); hexcontent.remove('\n'); hexcontent.remove('\r'); _searchHexQuery = QByteArray(); if (hexcontent.length() & 1) { setColor(false, false); return; } while (!hexcontent.isEmpty()) { const QString hexData = hexcontent.left(2); hexcontent = hexcontent.mid(2); bool ok = true; const int c = hexData.toUInt(&ok, 16); if (!ok) { setColor(false, false); return; } _searchHexQuery.push_back((char) c); } } else { _searchQuery.setContent(_searchLineEdit->text(), caseSensitive, matchWholeWord, codec()->name(), regExp); } _searchIsForward = forward; _searchHexadecimal = hex; QTimer::singleShot(0, this, SLOT(slotSearchMore())); _searchInProgress = true; _searchProgressCounter = 3; enableActions(false); } void Lister::enableActions(const bool state) { _actionSearch->setEnabled(state); _actionSearchNext->setEnabled(state); _actionSearchPrev->setEnabled(state); _actionJumpToPosition->setEnabled(state); if (state) { _searchUpdateTimer.stop(); } else { slotUpdate(); } } void Lister::slotSearchMore() { if (!_searchInProgress) return; if (!_searchUpdateTimer.isActive()) { _searchUpdateTimer.start(200); } updateProgressBar(); if (!_searchIsForward) _searchPosition--; if (_searchPosition < 0 || _searchPosition >= _fileSize) { if (_restartFromBeginning) resetSearchPosition(); else { searchFailed(); return; } } int maxCacheSize = SEARCH_CACHE_CHARS; qint64 searchPos = _searchPosition; bool setPosition = true; if (!_searchIsForward) { qint64 origSearchPos = _searchPosition; searchPos -= maxCacheSize; if (searchPos <= 0) { searchPos = 0; _searchPosition = 0; setPosition = false; } qint64 diff = origSearchPos - searchPos; if (diff < maxCacheSize) maxCacheSize = diff; } const QByteArray chunk = cacheChunk(searchPos, maxCacheSize); if (chunk.isEmpty()) { searchFailed(); return; } const int chunkSize = chunk.size(); qint64 foundAnchor = -1; qint64 foundCursor = -1; int byteCounter = 0; if (_searchHexadecimal) { const int ndx = _searchIsForward ? chunk.indexOf(_searchHexQuery) : chunk.lastIndexOf(_searchHexQuery); if (chunkSize > _searchHexQuery.length()) { if (_searchIsForward) { _searchPosition = searchPos + chunkSize; if ((_searchPosition < _fileSize) && (chunkSize > _searchHexQuery.length())) _searchPosition -= _searchHexQuery.length(); byteCounter = _searchPosition - searchPos; } else { if (_searchPosition > 0) _searchPosition += _searchHexQuery.length(); } } if (ndx != -1) { foundAnchor = searchPos + ndx; foundCursor = foundAnchor + _searchHexQuery.length(); } } else { int rowStart = 0; QString row = ""; QScopedPointer decoder(_codec->makeDecoder()); while (byteCounter < chunkSize) { const QString chr = decoder->toUnicode(chunk.mid(byteCounter++, 1)); if (chr.isEmpty() && byteCounter < chunkSize) { continue; } if (chr != "\n") row += chr; if (chr == "\n" || row.length() >= SEARCH_MAX_ROW_LEN || byteCounter >= chunkSize) { if (setPosition) { _searchPosition = searchPos + byteCounter; if (!_searchIsForward) { _searchPosition++; setPosition = false; } } if (_searchQuery.checkLine(row, !_searchIsForward)) { QByteArray cachedBuffer = chunk.mid(rowStart, chunkSize - rowStart); QTextStream stream(&cachedBuffer); stream.setCodec(_codec); stream.read(_searchQuery.matchIndex()); foundAnchor = searchPos + rowStart + stream.pos(); stream.read(_searchQuery.matchLength()); foundCursor = searchPos + rowStart + stream.pos(); if (_searchIsForward) break; } row = ""; rowStart = byteCounter; } } } if (foundAnchor != -1 && foundCursor != -1) { _textArea->setAnchorAndCursor(foundAnchor, foundCursor); searchSucceeded(); return; } if (_searchIsForward && searchPos + byteCounter >= _fileSize) { if (_restartFromBeginning) resetSearchPosition(); else { searchFailed(); return; } } else if (_searchPosition <= 0 || _searchPosition >= _fileSize) { if (_restartFromBeginning) resetSearchPosition(); else { searchFailed(); return; } } QTimer::singleShot(0, this, SLOT(slotSearchMore())); } void Lister::resetSearchPosition() { _restartFromBeginning = false; _searchPosition = _searchIsForward ? 0 : _fileSize - 1; } void Lister::searchSucceeded() { _searchInProgress = false; setColor(true, false); hideProgressBar(); _searchLastFailedPosition = -1; enableActions(true); } void Lister::searchFailed() { _searchInProgress = false; setColor(false, false); hideProgressBar(); bool isfirst; _searchLastFailedPosition = _textArea->getCursorPosition(isfirst); if (!_searchIsForward) _searchLastFailedPosition--; enableActions(true); } void Lister::searchDelete() { _searchInProgress = false; setColor(false, true); hideProgressBar(); _searchLastFailedPosition = -1; enableActions(true); } void Lister::searchTextChanged() { searchDelete(); if (_fileSize < 0x10000) { // autosearch files less than 64k if (!_searchLineEdit->text().isEmpty()) { bool isfirst; const qint64 anchor = _textArea->getCursorAnchor(); const qint64 cursor = _textArea->getCursorPosition(isfirst); if (cursor > anchor && anchor != -1) { _textArea->setCursorPositionInDocument(anchor, true); } search(true, true); } } } void Lister::setColor(const bool match, const bool restore) { QColor fore, back; if (!restore) { const KConfigGroup gc(krConfig, "Colors"); QString foreground, background; const QPalette p = QGuiApplication::palette(); if (match) { foreground = "Quicksearch Match Foreground"; background = "Quicksearch Match Background"; fore = Qt::black; back = QColor(192, 255, 192); } else { foreground = "Quicksearch Non-match Foreground"; background = "Quicksearch Non-match Background"; fore = Qt::black; back = QColor(255, 192, 192); } if (gc.readEntry(foreground, QString()) == "KDE default") fore = p.color(QPalette::Active, QPalette::Text); else if (!gc.readEntry(foreground, QString()).isEmpty()) fore = gc.readEntry(foreground, fore); if (gc.readEntry(background, QString()) == "KDE default") back = p.color(QPalette::Active, QPalette::Base); else if (!gc.readEntry(background, QString()).isEmpty()) back = gc.readEntry(background, back); } else { back = _originalBackground; fore = _originalForeground; } QPalette pal = _searchLineEdit->palette(); pal.setColor(QPalette::Base, back); pal.setColor(QPalette::Text, fore); _searchLineEdit->setPalette(pal); } void Lister::hideProgressBar() { if (!_searchProgressBar->isHidden()) { _searchProgressBar->hide(); _searchStopButton->hide(); _searchLineEdit->show(); _searchNextButton->show(); _searchPrevButton->show(); _searchOptions->show(); _listerLabel->setText(i18n("Search:")); } } void Lister::updateProgressBar() { if (_searchProgressCounter) return; if (_searchProgressBar->isHidden()) { _searchProgressBar->show(); _searchStopButton->show(); _searchOptions->hide(); _searchLineEdit->hide(); _searchNextButton->hide(); _searchPrevButton->hide(); _listerLabel->setText(i18n("Search position:")); // otherwise focus is set to document tab _textArea->setFocus(); } const qint64 pcnt = (_fileSize == 0) ? 1000 : (2001 * _searchPosition) / _fileSize / 2; const int pctInt = (int) pcnt; if (_searchProgressBar->value() != pctInt) _searchProgressBar->setValue(pctInt); } void Lister::jumpToPosition() { bool ok = true; QString res = QInputDialog::getText(_textArea, i18n("Jump to position"), i18n("Text position:"), QLineEdit::Normal, "0", &ok); if (!ok) return; res = res.trimmed(); qint64 pos = -1; if (res.startsWith(QLatin1String("0x"))) { res = res.mid(2); bool ok; const qulonglong upos = res.toULongLong(&ok, 16); if (!ok) { KMessageBox::error(_textArea, i18n("Invalid number."), i18n("Jump to position")); return; } pos = (qint64)upos; } else { bool ok; const qulonglong upos = res.toULongLong(&ok); if (!ok) { KMessageBox::error(_textArea, i18n("Invalid number."), i18n("Jump to position")); return; } pos = (qint64)upos; } if (pos < 0 || pos > _fileSize) { KMessageBox::error(_textArea, i18n("Number out of range."), i18n("Jump to position")); return; } _textArea->deleteAnchor(); _textArea->setCursorPositionInDocument(pos, true); _textArea->ensureVisibleCursor(); } void Lister::saveAs() { const QUrl url = QFileDialog::getSaveFileUrl(_textArea, i18n("Lister")); if (url.isEmpty()) return; QUrl sourceUrl; if (!_downloading) sourceUrl = QUrl::fromLocalFile(_filePath); else sourceUrl = this->url(); QList urlList; urlList << sourceUrl; KIO::Job *job = KIO::copy(urlList, url); job->setUiDelegate(new KIO::JobUiDelegate()); KIO::getJobTracker()->registerJob(job); job->uiDelegate()->setAutoErrorHandlingEnabled(true); } void Lister::saveSelected() { bool isfirst; const qint64 start = _textArea->getCursorAnchor(); const qint64 end = _textArea->getCursorPosition(isfirst); if (start == -1 || start == end) { KMessageBox::error(_textArea, i18n("Nothing is selected."), i18n("Save selection...")); return; } if (start > end) { _savePosition = end; _saveEnd = start; } else { _savePosition = start; _saveEnd = end; } const QUrl url = QFileDialog::getSaveFileUrl(_textArea, i18n("Lister")); if (url.isEmpty()) return; KIO::Job *saveJob = KIO::put(url, -1, KIO::Overwrite); connect(saveJob, SIGNAL(dataReq(KIO::Job*,QByteArray&)), this, SLOT(slotDataSend(KIO::Job*,QByteArray&))); connect(saveJob, SIGNAL(result(KJob*)), this, SLOT(slotSendFinished(KJob*))); saveJob->setUiDelegate(new KIO::JobUiDelegate()); KIO::getJobTracker()->registerJob(saveJob); saveJob->uiDelegate()->setAutoErrorHandlingEnabled(true); _actionSaveSelected->setEnabled(false); } void Lister::slotDataSend(KIO::Job *, QByteArray &array) { if (_savePosition >= _saveEnd) { array = QByteArray(); return; } qint64 max = _saveEnd - _savePosition; if (max > 1000) max = 1000; array = cacheChunk(_savePosition, (int) max); _savePosition += array.size(); } void Lister::slotSendFinished(KJob *) { _actionSaveSelected->setEnabled(true); } void Lister::setCharacterSet(const QString set) { _characterSet = set; if (_characterSet.isEmpty()) { _codec = QTextCodec::codecForLocale(); } else { _codec = KCharsets::charsets()->codecForName(_characterSet); } _textArea->redrawTextArea(true); } void Lister::print() { bool isfirst; const qint64 anchor = _textArea->getCursorAnchor(); const qint64 cursor = _textArea->getCursorPosition(isfirst); const bool hasSelection = (anchor != -1 && anchor != cursor); const QString docName = url().fileName(); QPrinter printer; printer.setDocName(docName); QScopedPointer printDialog(new QPrintDialog(&printer, _textArea)); if (hasSelection) { printDialog->addEnabledOption(QAbstractPrintDialog::PrintSelection); } if (!printDialog->exec()) { return; } if (printer.pageOrder() == QPrinter::LastPageFirst) { switch (KMessageBox::warningContinueCancel(_textArea, i18n("Reverse printing is not supported. Continue with normal printing?"))) { case KMessageBox::Continue : break; default: return; } } QPainter painter; painter.begin(&printer); const QString dateString = QDate::currentDate().toString(Qt::SystemLocaleShortDate); const QRect pageRect = printer.pageRect(); const QRect drawingRect(0, 0, pageRect.width(), pageRect.height()); const QFont normalFont = QFontDatabase::systemFont(QFontDatabase::GeneralFont); const QFont fixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); const QFontMetrics fmNormal(normalFont); const int normalFontHeight = fmNormal.height(); const QFontMetrics fmFixed(fixedFont); const int fixedFontHeight = std::max(fmFixed.height(), 1); const int fixedFontWidth = std::max(fmFixed.width("W"), 1); const int effPageSize = drawingRect.height() - normalFontHeight - 1; const int rowsPerPage = std::max(effPageSize / fixedFontHeight, 1); const int columnsPerPage = std::max(drawingRect.width() / fixedFontWidth, 1); bool firstPage = true; qint64 startPos = 0; qint64 endPos = _fileSize; if (printer.printRange() == QPrinter::Selection) { if (anchor > cursor) startPos = cursor, endPos = anchor; else startPos = anchor, endPos = cursor; } int page = 0; while (startPos < endPos) { page++; QStringList rows = readLines(startPos, endPos, columnsPerPage, rowsPerPage); // print since set-up fromPage number if (printer.fromPage() && page < printer.fromPage()) { continue; } // print until set-up toPage number if (printer.toPage() && printer.toPage() >= printer.fromPage() && page > printer.toPage()) break; if (!firstPage) { printer.newPage(); } firstPage = false; // Use the painter to draw on the page. painter.setFont(normalFont); painter.drawText(drawingRect, Qt::AlignLeft, dateString); painter.drawText(drawingRect, Qt::AlignHCenter, docName); painter.drawText(drawingRect, Qt::AlignRight, QString("%1").arg(page)); painter.drawLine(0, normalFontHeight, drawingRect.width(), normalFontHeight); painter.setFont(fixedFont); int yOffset = normalFontHeight + 1; foreach (const QString &row, rows) { painter.drawText(0, yOffset + fixedFontHeight, row); yOffset += fixedFontHeight; } } } QStringList Lister::readLines(qint64 &filePos, const qint64 endPos, const int columns, const int lines) { if (_textArea->hexMode()) { return readHexLines(filePos, endPos, columns, lines); } QStringList list; const int maxBytes = std::min(columns * lines * MAX_CHAR_LENGTH, (int) (endPos - filePos)); if (maxBytes <= 0) { return list; } const QByteArray chunk = cacheChunk(filePos, maxBytes); if (chunk.isEmpty()) { return list; } QScopedPointer decoder(_codec->makeDecoder()); int byteCounter = 0; QString row = ""; bool skipImmediateNewline = false; while (byteCounter < chunk.size() && list.size() < lines) { QString chr = decoder->toUnicode(chunk.mid(byteCounter++, 1)); if (chr.isEmpty()) { continue; } // replace unreadable characters if ((chr[ 0 ] < 32) && (chr[ 0 ] != '\n') && (chr[ 0 ] != '\t')) { chr = QChar(' '); } // handle newline if (chr == "\n") { if (!skipImmediateNewline) { list << row; row = ""; } skipImmediateNewline = false; continue; } skipImmediateNewline = false; // handle tab if (chr == "\t") { const int tabLength = _textArea->tabWidth() - (row.length() % _textArea->tabWidth()); if (row.length() + tabLength > columns) { list << row; row = ""; } row += QString(tabLength, QChar(' ')); } else { // normal printable character row += chr; } if (row.length() >= columns) { list << row; row = ""; skipImmediateNewline = true; } } if (list.size() < lines) { list << row; } filePos += byteCounter; return list; } int Lister::hexPositionDigits() { int positionDigits = 0; qint64 checker = _fileSize; while (checker) { positionDigits++; checker /= 16; } if (positionDigits < 8) { return 8; } return positionDigits; } int Lister::hexBytesPerLine(const int columns) { const int positionDigits = hexPositionDigits(); if (columns >= positionDigits + 5 + 128) { return 32; } if (columns >= positionDigits + 5 + 64) { return 16; } return 8; } QStringList Lister::readHexLines(qint64 &filePos, const qint64 endPos, const int columns, const int lines) { const int positionDigits = hexPositionDigits(); const int bytesPerRow = hexBytesPerLine(columns); QStringList list; const qint64 choppedPos = (filePos / bytesPerRow) * bytesPerRow; const int maxBytes = std::min(bytesPerRow * lines, (int) (endPos - choppedPos)); if (maxBytes <= 0) return list; const QByteArray chunk = cacheChunk(choppedPos, maxBytes); if (chunk.isEmpty()) return list; int cnt = 0; for (int l = 0; l < lines; l++) { if (filePos >= endPos) { break; } const qint64 printPos = (filePos / bytesPerRow) * bytesPerRow; QString pos; pos.setNum(printPos, 16); while (pos.length() < positionDigits) pos = QString("0") + pos; pos = QString("0x") + pos; pos += QString(": "); QString charData; for (int i = 0; i != bytesPerRow; ++i, ++cnt) { const qint64 currentPos = printPos + i; if (currentPos < filePos || currentPos >= endPos) { pos += QString(" "); charData += QString(" "); } else { char c = chunk.at(cnt); int charCode = (int)c; if (charCode < 0) charCode += 256; QString hex; hex.setNum(charCode, 16); if (hex.length() < 2) hex = QString("0") + hex; pos += hex + QString(" "); if (c < 32) c = '.'; charData += QChar(c); } } pos += QString(" ") + charData; list << pos; filePos = printPos + bytesPerRow; } if (filePos > endPos) { filePos = endPos; } return list; } int Lister::hexIndexToPosition(const int columns, const int index) { const int positionDigits = hexPositionDigits(); const int bytesPerRow = hexBytesPerLine(columns); const int finalIndex = std::min(index, bytesPerRow); return positionDigits + 4 + (3*finalIndex); } int Lister::hexPositionToIndex(const int columns, const int position) { const int positionDigits = hexPositionDigits(); const int bytesPerRow = hexBytesPerLine(columns); int finalPosition = position; finalPosition -= 4 + positionDigits; if (finalPosition <= 0) return 0; finalPosition /= 3; if (finalPosition >= bytesPerRow) return bytesPerRow; return finalPosition; } void Lister::toggleHexMode() { setHexMode(!_textArea->hexMode()); } void Lister::setHexMode(const bool mode) { if (mode) { _textArea->setHexMode(true); _actionHexMode->setText(i18n("Text mode")); } else { _textArea->setHexMode(false); _actionHexMode->setText(i18n("Hex mode")); } } diff --git a/krusader/Konfigurator/kgcolors.cpp b/krusader/Konfigurator/kgcolors.cpp index 6b99585b..1d713005 100644 --- a/krusader/Konfigurator/kgcolors.cpp +++ b/krusader/Konfigurator/kgcolors.cpp @@ -1,705 +1,705 @@ /***************************************************************************** * 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 "kgcolors.h" #include "../defaults.h" #include "../Panel/krcolorcache.h" #include "../Synchronizer/synchronizercolors.h" // QtCore #include #include // QtGui #include // QtWidgets #include #include #include #include #include #include #include KgColors::KgColors(bool first, QWidget* parent) : KonfiguratorPage(first, parent), offset(0), activeTabIdx(-1), inactiveTabIdx(-1), #ifdef SYNCHRONIZER_ENABLED synchronizerTabIdx(-1), #endif otherTabIdx(-1) { QWidget *innerWidget = new QFrame(this); setWidget(innerWidget); setWidgetResizable(true); QGridLayout *kgColorsLayout = new QGridLayout(innerWidget); kgColorsLayout->setSpacing(6); // -------------------------- GENERAL GROUPBOX ---------------------------------- QGroupBox *generalGrp = createFrame(i18n("General"), innerWidget); QGridLayout *generalGrid = createGridLayout(generalGrp); generalGrid->setSpacing(0); generalGrid->setContentsMargins(5, 5, 5, 5); KONFIGURATOR_CHECKBOX_PARAM generalSettings[] = // cfg_class cfg_name default text restart tooltip {{"Colors", "KDE Default", _KDEDefaultColors, i18n("Use the default KDE colors"), false, "

" + i18n("

Use KDE's global color configuration.

KDE System Settings -> Application Appearance -> Colors

") }, {"Colors", "Enable Alternate Background", _AlternateBackground, i18n("Use alternate background color"), false, i18n("

The background color and the alternate background color alternates line by line.

When you don't use the KDE default colors, you can configure the alternate colors in the colors box.

") }, {"Colors", "Show Current Item Always", _ShowCurrentItemAlways, i18n("Show current item even if not focused"), false, i18n("

Shows the last cursor position in the non active list panel.

This option is only available when you don't use the KDE default colors.

") }, {"Colors", "Dim Inactive Colors", _DimInactiveColors, i18n("Dim the colors of the inactive panel"), false, i18n("

The colors of the inactive panel are calculated by a dim color and a dim factor.

") } }; generals = createCheckBoxGroup(0, 2, generalSettings, sizeof(generalSettings) / sizeof(generalSettings[0]), generalGrp); generalGrid->addWidget(generals, 1, 0); generals->layout()->setSpacing(5); - connect(generals->find("KDE Default"), SIGNAL(stateChanged(int)), this, SLOT(slotDisable())); - connect(generals->find("Show Current Item Always"), SIGNAL(stateChanged(int)), this, SLOT(slotDisable())); - connect(generals->find("Dim Inactive Colors"), SIGNAL(stateChanged(int)), this, SLOT(slotDisable())); + connect(generals->find("KDE Default"), &KonfiguratorCheckBox::stateChanged, this, &KgColors::slotDisable); + connect(generals->find("Show Current Item Always"), &KonfiguratorCheckBox::stateChanged, this, &KgColors::slotDisable); + connect(generals->find("Dim Inactive Colors"), &KonfiguratorCheckBox::stateChanged, this, &KgColors::slotDisable); kgColorsLayout->addWidget(generalGrp, 0 , 0, 1, 3); QWidget *hboxWidget = new QWidget(innerWidget); QHBoxLayout *hbox = new QHBoxLayout(hboxWidget); // -------------------------- COLORS GROUPBOX ---------------------------------- QGroupBox *colorsFrameGrp = createFrame(i18n("Colors"), hboxWidget); QGridLayout *colorsFrameGrid = createGridLayout(colorsFrameGrp); colorsFrameGrid->setSpacing(0); colorsFrameGrid->setContentsMargins(3, 3, 3, 3); colorTabWidget = new QTabWidget(colorsFrameGrp); colorsGrp = new QWidget(colorTabWidget); activeTabIdx = colorTabWidget->addTab(colorsGrp, i18n("Active")); colorsGrid = new QGridLayout(colorsGrp); colorsGrid->setSpacing(0); colorsGrid->setContentsMargins(2, 2, 2, 2); ADDITIONAL_COLOR transparent = { i18n("Transparent"), Qt::white, "transparent" }; QPalette p = QGuiApplication::palette(); addColorSelector("Foreground", i18n("Foreground:"), p.color(QPalette::Active, QPalette::Text)); addColorSelector("Directory Foreground", i18n("Folder foreground:"), getColorSelector("Foreground")->getColor(), i18n("Same as foreground")); addColorSelector("Executable Foreground", i18n("Executable foreground:"), getColorSelector("Foreground")->getColor(), i18n("Same as foreground")); addColorSelector("Symlink Foreground", i18n("Symbolic link foreground:"), getColorSelector("Foreground")->getColor(), i18n("Same as foreground")); addColorSelector("Invalid Symlink Foreground", i18n("Invalid symlink foreground:"), getColorSelector("Foreground")->getColor(), i18n("Same as foreground")); addColorSelector("Background", i18n("Background:"), p.color(QPalette::Active, QPalette::Base)); ADDITIONAL_COLOR sameAsBckgnd = { i18n("Same as background"), getColorSelector("Background")->getColor(), "Background" }; addColorSelector("Alternate Background", i18n("Alternate background:"), p.color(QPalette::Active, QPalette::AlternateBase), "", &sameAsBckgnd, 1); addColorSelector("Marked Foreground", i18n("Selected foreground:"), p.color(QPalette::Active, QPalette::HighlightedText), "", &transparent, 1); addColorSelector("Marked Background", i18n("Selected background:"), p.color(QPalette::Active, QPalette::Highlight), "", &sameAsBckgnd, 1); ADDITIONAL_COLOR sameAsAltern = { i18n("Same as alt. background"), getColorSelector("Alternate Background")->getColor(), "Alternate Background" }; addColorSelector("Alternate Marked Background", i18n("Alternate selected background:"), getColorSelector("Marked Background")->getColor(), i18n("Same as selected background"), &sameAsAltern, 1); addColorSelector("Current Foreground", i18n("Current foreground:"), Qt::white, i18n("Not used")); ADDITIONAL_COLOR sameAsMarkedForegnd = { i18n("Same as selected foreground"), getColorSelector("Marked Foreground")->getColor(), "Marked Foreground" }; addColorSelector("Marked Current Foreground", i18n("Selected current foreground:"), Qt::white, i18n("Not used"), &sameAsMarkedForegnd, 1); addColorSelector("Current Background", i18n("Current background:"), Qt::white, i18n("Not used"), &sameAsBckgnd, 1); colorsGrid->addWidget(createSpacer(colorsGrp), itemList.count() - offset, 1); - connect(getColorSelector("Foreground"), SIGNAL(colorChanged()), this, SLOT(slotForegroundChanged())); - connect(getColorSelector("Background"), SIGNAL(colorChanged()), this, SLOT(slotBackgroundChanged())); - connect(getColorSelector("Alternate Background"), SIGNAL(colorChanged()), this, SLOT(slotAltBackgroundChanged())); - connect(getColorSelector("Marked Background"), SIGNAL(colorChanged()), this, SLOT(slotMarkedBackgroundChanged())); + connect(getColorSelector("Foreground"), &KonfiguratorColorChooser::colorChanged, this, &KgColors::slotForegroundChanged); + connect(getColorSelector("Background"), &KonfiguratorColorChooser::colorChanged, this, &KgColors::slotBackgroundChanged); + connect(getColorSelector("Alternate Background"), &KonfiguratorColorChooser::colorChanged, this, &KgColors::slotAltBackgroundChanged); + connect(getColorSelector("Marked Background"), &KonfiguratorColorChooser::colorChanged, this, &KgColors::slotMarkedBackgroundChanged); inactiveColorStack = new QStackedWidget(colorTabWidget); inactiveTabIdx = colorTabWidget->addTab(inactiveColorStack, i18n("Inactive")); colorsGrp = normalInactiveWidget = new QWidget(inactiveColorStack); colorsGrid = new QGridLayout(normalInactiveWidget); colorsGrid->setSpacing(0); colorsGrid->setContentsMargins(2, 2, 2, 2); offset = endOfActiveColors = itemList.count(); addColorSelector("Inactive Foreground", i18n("Foreground:"), getColorSelector("Foreground")->getColor(), i18n("Same as active")); ADDITIONAL_COLOR sameAsInactForegnd = { i18n("Same as foreground"), getColorSelector("Inactive Foreground")->getColor(), "Inactive Foreground" }; addColorSelector("Inactive Directory Foreground", i18n("Folder foreground:"), getColorSelector("Directory Foreground")->getColor(), i18n("Same as active"), &sameAsInactForegnd, 1); addColorSelector("Inactive Executable Foreground", i18n("Executable foreground:"), getColorSelector("Executable Foreground")->getColor(), i18n("Same as active"), &sameAsInactForegnd, 1); addColorSelector("Inactive Symlink Foreground", i18n("Symbolic link foreground:"), getColorSelector("Symlink Foreground")->getColor(), i18n("Same as active"), &sameAsInactForegnd, 1); addColorSelector("Inactive Invalid Symlink Foreground", i18n("Invalid symlink foreground:"), getColorSelector("Invalid Symlink Foreground")->getColor(), i18n("Same as active"), &sameAsInactForegnd, 1); addColorSelector("Inactive Background", i18n("Background:"), getColorSelector("Background")->getColor(), i18n("Same as active")); ADDITIONAL_COLOR sameAsInactBckgnd = { i18n("Same as background"), getColorSelector("Inactive Background")->getColor(), "Inactive Background" }; addColorSelector("Inactive Alternate Background", i18n("Alternate background:"), getColorSelector("Alternate Background")->getColor(), i18n("Same as active"), &sameAsInactBckgnd, 1); addColorSelector("Inactive Marked Foreground", i18n("Selected foreground:"), getColorSelector("Marked Foreground")->getColor(), i18n("Same as active"), &transparent, 1); addColorSelector("Inactive Marked Background", i18n("Selected background:"), getColorSelector("Marked Background")->getColor(), i18n("Same as active"), &sameAsInactBckgnd, 1); ADDITIONAL_COLOR sameAsInactAltern[] = {{ i18n("Same as alt. background"), getColorSelector("Inactive Alternate Background")->getColor(), "Inactive Alternate Background" }, { i18n("Same as selected background"), getColorSelector("Inactive Marked Background")->getColor(), "Inactive Marked Background" } }; addColorSelector("Inactive Alternate Marked Background", i18n("Alternate selected background:"), getColorSelector("Alternate Marked Background")->getColor(), i18n("Same as active"), sameAsInactAltern, 2); addColorSelector("Inactive Current Foreground", i18n("Current foreground:"), getColorSelector("Current Foreground")->getColor(), i18n("Same as active")); ADDITIONAL_COLOR sameAsInactMarkedForegnd = { i18n("Same as selected foreground"), getColorSelector("Inactive Marked Foreground")->getColor(), "Inactive Marked Foreground" }; addColorSelector("Inactive Marked Current Foreground", i18n("Selected current foreground:"), getColorSelector("Marked Current Foreground")->getColor(), i18n("Same as active"), &sameAsInactMarkedForegnd, 1); addColorSelector("Inactive Current Background", i18n("Current background:"), getColorSelector("Current Background")->getColor(), i18n("Same as active"), &sameAsInactBckgnd, 1); colorsGrid->addWidget(createSpacer(normalInactiveWidget), itemList.count() - offset, 1); - connect(getColorSelector("Inactive Foreground"), SIGNAL(colorChanged()), this, SLOT(slotInactiveForegroundChanged())); - connect(getColorSelector("Inactive Background"), SIGNAL(colorChanged()), this, SLOT(slotInactiveBackgroundChanged())); - connect(getColorSelector("Inactive Alternate Background"), SIGNAL(colorChanged()), this, SLOT(slotInactiveAltBackgroundChanged())); - connect(getColorSelector("Inactive Marked Background"), SIGNAL(colorChanged()), this, SLOT(slotInactiveMarkedBackgroundChanged())); + connect(getColorSelector("Inactive Foreground"), &KonfiguratorColorChooser::colorChanged, this, &KgColors::slotInactiveForegroundChanged); + connect(getColorSelector("Inactive Background"), &KonfiguratorColorChooser::colorChanged, this, &KgColors::slotInactiveBackgroundChanged); + connect(getColorSelector("Inactive Alternate Background"), &KonfiguratorColorChooser::colorChanged, this, &KgColors::slotInactiveAltBackgroundChanged); + connect(getColorSelector("Inactive Marked Background"), &KonfiguratorColorChooser::colorChanged, this, &KgColors::slotInactiveMarkedBackgroundChanged); offset = endOfPanelColors = itemList.count(); inactiveColorStack->addWidget(normalInactiveWidget); colorsGrp = dimmedInactiveWidget = new QWidget(inactiveColorStack); colorsGrid = new QGridLayout(dimmedInactiveWidget); colorsGrid->setSpacing(0); colorsGrid->setContentsMargins(2, 2, 2, 2); addColorSelector("Dim Target Color", i18n("Dim target color:"), Qt::black); int index = itemList.count() - offset; labelList.append(addLabel(colorsGrid, index, 0, i18n("Dim factor:"), colorsGrp)); dimFactor = createSpinBox("Colors", "Dim Factor", 80, 0, 100, colorsGrp); dimFactor->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); colorsGrid->addWidget(dimFactor, index++, 1); colorsGrid->addWidget(createSpacer(dimmedInactiveWidget), itemList.count() + 1 - offset, 1); inactiveColorStack->addWidget(dimmedInactiveWidget); inactiveColorStack->setCurrentWidget(normalInactiveWidget); ADDITIONAL_COLOR KDEDefaultBase = { i18n("KDE default"), p.color(QPalette::Active, QPalette::Base), "KDE default" }; ADDITIONAL_COLOR KDEDefaultFore = { i18n("KDE default"), p.color(QPalette::Active, QPalette::Text), "KDE default" }; #ifdef SYNCHRONIZER_ENABLED colorsGrp = new QWidget(colorTabWidget); synchronizerTabIdx = colorTabWidget->addTab(colorsGrp, i18n("Synchronizer")); colorsGrid = new QGridLayout(colorsGrp); colorsGrid->setSpacing(0); colorsGrid->setContentsMargins(2, 2, 2, 2); offset = endOfPanelColors = itemList.count(); DECLARE_SYNCHRONIZER_BACKGROUND_DEFAULTS; DECLARE_SYNCHRONIZER_FOREGROUND_DEFAULTS; addColorSelector("Synchronizer Equals Foreground", i18n("Equals foreground:"), SYNCHRONIZER_FOREGROUND_DEFAULTS[0], QString(), &KDEDefaultFore, 1); addColorSelector("Synchronizer Equals Background", i18n("Equals background:"), SYNCHRONIZER_BACKGROUND_DEFAULTS[0], QString(), &KDEDefaultBase, 1); addColorSelector("Synchronizer Differs Foreground", i18n("Differing foreground:"), SYNCHRONIZER_FOREGROUND_DEFAULTS[1], QString(), &KDEDefaultFore, 1); addColorSelector("Synchronizer Differs Background", i18n("Differing background:"), SYNCHRONIZER_BACKGROUND_DEFAULTS[1], QString(), &KDEDefaultBase, 1); addColorSelector("Synchronizer LeftCopy Foreground", i18n("Copy to left foreground:"), SYNCHRONIZER_FOREGROUND_DEFAULTS[2], QString(), &KDEDefaultFore, 1); addColorSelector("Synchronizer LeftCopy Background", i18n("Copy to left background:"), SYNCHRONIZER_BACKGROUND_DEFAULTS[2], QString(), &KDEDefaultBase, 1); addColorSelector("Synchronizer RightCopy Foreground", i18n("Copy to right foreground:"), SYNCHRONIZER_FOREGROUND_DEFAULTS[3], QString(), &KDEDefaultFore, 1); addColorSelector("Synchronizer RightCopy Background", i18n("Copy to right background:"), SYNCHRONIZER_BACKGROUND_DEFAULTS[3], QString(), &KDEDefaultBase, 1); addColorSelector("Synchronizer Delete Foreground", i18n("Delete foreground:"), SYNCHRONIZER_FOREGROUND_DEFAULTS[4], QString(), &KDEDefaultFore, 1); addColorSelector("Synchronizer Delete Background", i18n("Delete background:"), SYNCHRONIZER_BACKGROUND_DEFAULTS[4], QString(), &KDEDefaultBase, 1); colorsGrid->addWidget(createSpacer(colorsGrp), itemList.count() - offset, 1); #endif colorsGrp = new QWidget(colorTabWidget); otherTabIdx = colorTabWidget->addTab(colorsGrp, i18n("Other")); colorsGrid = new QGridLayout(colorsGrp); colorsGrid->setSpacing(0); colorsGrid->setContentsMargins(2, 2, 2, 2); offset = endOfPanelColors = itemList.count(); addColorSelector("Quicksearch Match Foreground", i18n("Quicksearch, match foreground:"), Qt::black, QString(), &KDEDefaultFore, 1); addColorSelector("Quicksearch Match Background", i18n("Quicksearch, match background:"), QColor(192, 255, 192), QString(), &KDEDefaultBase, 1); addColorSelector("Quicksearch Non-match Foreground", i18n("Quicksearch, non-match foreground:"), Qt::black, QString(), &KDEDefaultFore, 1); addColorSelector("Quicksearch Non-match Background", i18n("Quicksearch, non-match background:"), QColor(255, 192, 192), QString(), &KDEDefaultBase, 1); ADDITIONAL_COLOR KDEDefaultWindowFore = { i18n("KDE default"), p.color(QPalette::Active, QPalette::WindowText), "KDE default" }; ADDITIONAL_COLOR KDEDefaultWindowBack = { i18n("KDE default"), p.color(QPalette::Active, QPalette::Window), "KDE default" }; addColorSelector("Statusbar Foreground Active", i18n("Statusbar, active foreground:"), p.color(QPalette::Active, QPalette::HighlightedText), QString(), &KDEDefaultWindowFore, 1); addColorSelector("Statusbar Background Active", i18n("Statusbar, active background:"), p.color(QPalette::Active, QPalette::Highlight), QString(), &KDEDefaultWindowBack, 1); addColorSelector("Statusbar Foreground Inactive", i18n("Statusbar, inactive foreground:"), p.color(QPalette::Inactive, QPalette::Text), QString(), &KDEDefaultWindowFore, 1); addColorSelector("Statusbar Background Inactive", i18n("Statusbar, inactive background:"), p.color(QPalette::Inactive, QPalette::Base), QString(), &KDEDefaultWindowBack, 1); colorsGrid->addWidget(createSpacer(colorsGrp), itemList.count() - offset, 1); colorsFrameGrid->addWidget(colorTabWidget, 0, 0); hbox->addWidget(colorsFrameGrp); // -------------------------- PREVIEW GROUPBOX ---------------------------------- previewGrp = createFrame(i18n("Preview"), hboxWidget); previewGrid = createGridLayout(previewGrp); preview = new KrTreeWidget(previewGrp); preview->setBackgroundRole(QPalette::Window); preview->setAutoFillBackground(true); QStringList labels; labels << i18n("Colors"); preview->setHeaderLabels(labels); preview->header()->setSortIndicatorShown(false); preview->setSortingEnabled(false); preview->setEnabled(false); previewGrid->addWidget(preview, 0 , 0); hbox->addWidget(previewGrp); - connect(generals->find("Enable Alternate Background"), SIGNAL(stateChanged(int)), this, SLOT(generatePreview())); - connect(colorTabWidget, SIGNAL(currentChanged(int)), this, SLOT(generatePreview())); - connect(dimFactor, SIGNAL(valueChanged(int)), this, SLOT(generatePreview())); + connect(generals->find("Enable Alternate Background"), &KonfiguratorCheckBox::stateChanged, this, &KgColors::generatePreview); + connect(colorTabWidget, &QTabWidget::currentChanged, this, &KgColors::generatePreview); + connect(dimFactor, QOverload::of(&KonfiguratorSpinBox::valueChanged), this, &KgColors::generatePreview); kgColorsLayout->addWidget(hboxWidget, 1 , 0, 1, 3); importBtn = new QPushButton(i18n("Import color-scheme"), innerWidget); kgColorsLayout->addWidget(importBtn, 2, 0); exportBtn = new QPushButton(i18n("Export color-scheme"), innerWidget); kgColorsLayout->addWidget(exportBtn, 2, 1); kgColorsLayout->addWidget(createSpacer(innerWidget), 2, 2); - connect(importBtn, SIGNAL(clicked()), this, SLOT(slotImportColors())); - connect(exportBtn, SIGNAL(clicked()), this, SLOT(slotExportColors())); + connect(importBtn, &QPushButton::clicked, this, &KgColors::slotImportColors); + connect(exportBtn, &QPushButton::clicked, this, &KgColors::slotExportColors); slotDisable(); } int KgColors::addColorSelector(QString cfgName, QString name, QColor defaultValue, QString dfltName, ADDITIONAL_COLOR *addColor, int addColNum) { int index = itemList.count() - offset; labelList.append(addLabel(colorsGrid, index, 0, name, colorsGrp)); KonfiguratorColorChooser *chooser = createColorChooser("Colors", cfgName, defaultValue, colorsGrp, false, addColor, addColNum); chooser->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); if (!dfltName.isEmpty()) chooser->setDefaultText(dfltName); colorsGrid->addWidget(chooser, index, 1); - connect(chooser, SIGNAL(colorChanged()), this, SLOT(generatePreview())); + connect(chooser, &KonfiguratorColorChooser::colorChanged, this, &KgColors::generatePreview); if (!offset) - connect(chooser, SIGNAL(colorChanged()), this, SLOT(slotActiveChanged())); + connect(chooser, &KonfiguratorColorChooser::colorChanged, this, &KgColors::slotActiveChanged); itemList.append(chooser); itemNames.append(cfgName); return index; } KonfiguratorColorChooser *KgColors::getColorSelector(QString name) { QList::iterator it; int position = 0; for (it = itemNames.begin(); it != itemNames.end(); it++, position++) if (*it == name) return itemList.at(position); return 0; } QLabel *KgColors::getSelectorLabel(QString name) { QList::iterator it; int position = 0; for (it = itemNames.begin(); it != itemNames.end(); it++, position++) if (*it == name) return labelList.at(position); return 0; } void KgColors::slotDisable() { bool enabled = generals->find("KDE Default")->isChecked(); importBtn->setEnabled(!enabled); exportBtn->setEnabled(!enabled); for (int i = 0; i < labelList.count() && i < endOfPanelColors ; i++) labelList.at(i)->setEnabled(!enabled); for (int j = 0; j < itemList.count() && j < endOfPanelColors ; j++) itemList.at(j)->setEnabled(!enabled); generals->find("Enable Alternate Background")->setEnabled(enabled); generals->find("Show Current Item Always")->setEnabled(!enabled); generals->find("Dim Inactive Colors")->setEnabled(!enabled); bool dimmed = !enabled && generals->find("Dim Inactive Colors")->isChecked(); if (dimmed) inactiveColorStack->setCurrentWidget(dimmedInactiveWidget); else inactiveColorStack->setCurrentWidget(normalInactiveWidget); enabled = enabled || !generals->find("Show Current Item Always")->isChecked(); getColorSelector("Inactive Current Foreground")->setEnabled(!enabled); getColorSelector("Inactive Current Background")->setEnabled(!enabled); generatePreview(); } void KgColors::slotActiveChanged() { for (int i = 0; i != endOfActiveColors; i++) itemList.at(endOfActiveColors + i)->setDefaultColor(itemList.at(i)->getColor()); } void KgColors::slotForegroundChanged() { QColor color = getColorSelector("Foreground")->getColor(); getColorSelector("Directory Foreground")->setDefaultColor(color); getColorSelector("Executable Foreground")->setDefaultColor(color); getColorSelector("Symlink Foreground")->setDefaultColor(color); getColorSelector("Invalid Symlink Foreground")->setDefaultColor(color); } void KgColors::slotBackgroundChanged() { QColor color = getColorSelector("Background")->getColor(); getColorSelector("Alternate Background")->changeAdditionalColor(0, color); getColorSelector("Marked Background")->changeAdditionalColor(0, color); getColorSelector("Current Background")->changeAdditionalColor(0, color); } void KgColors::slotAltBackgroundChanged() { QColor color = getColorSelector("Alternate Background")->getColor(); getColorSelector("Alternate Marked Background")->changeAdditionalColor(0, color); } void KgColors::slotMarkedBackgroundChanged() { QColor color = getColorSelector("Marked Background")->getColor(); getColorSelector("Alternate Marked Background")->setDefaultColor(color); } void KgColors::slotInactiveForegroundChanged() { QColor color = getColorSelector("Inactive Foreground")->getColor(); getColorSelector("Inactive Directory Foreground")->changeAdditionalColor(0, color); getColorSelector("Inactive Executable Foreground")->changeAdditionalColor(0, color); getColorSelector("Inactive Symlink Foreground")->changeAdditionalColor(0, color); getColorSelector("Inactive Invalid Symlink Foreground")->changeAdditionalColor(0, color); } void KgColors::slotInactiveBackgroundChanged() { QColor color = getColorSelector("Inactive Background")->getColor(); getColorSelector("Inactive Alternate Background")->changeAdditionalColor(0, color); getColorSelector("Inactive Marked Background")->changeAdditionalColor(0, color); getColorSelector("Inactive Current Background")->changeAdditionalColor(0, color); } void KgColors::slotInactiveAltBackgroundChanged() { QColor color = getColorSelector("Inactive Alternate Background")->getColor(); getColorSelector("Inactive Alternate Marked Background")->changeAdditionalColor(0, color); } void KgColors::slotInactiveMarkedBackgroundChanged() { QColor color = getColorSelector("Inactive Marked Background")->getColor(); getColorSelector("Inactive Alternate Marked Background")->changeAdditionalColor(1, color); } void KgColors::setColorWithDimming(PreviewItem * item, QColor foreground, QColor background, bool dimmed) { if (dimmed && dimFactor->value() < 100) { int dim = dimFactor->value(); QColor dimColor = getColorSelector("Dim Target Color")->getColor(); foreground = QColor((dimColor.red() * (100 - dim) + foreground.red() * dim) / 100, (dimColor.green() * (100 - dim) + foreground.green() * dim) / 100, (dimColor.blue() * (100 - dim) + foreground.blue() * dim) / 100); background = QColor((dimColor.red() * (100 - dim) + background.red() * dim) / 100, (dimColor.green() * (100 - dim) + background.green() * dim) / 100, (dimColor.blue() * (100 - dim) + background.blue() * dim) / 100); } item->setColor(foreground, background); } void KgColors::generatePreview() { const int currentPage = colorTabWidget->currentIndex(); preview->clear(); if (currentPage == activeTabIdx || currentPage == inactiveTabIdx) { PreviewItem *pwMarkCur = new PreviewItem(preview, i18n("Selected + Current")); PreviewItem *pwMark2 = new PreviewItem(preview, i18n("Selected 2")); PreviewItem *pwMark1 = new PreviewItem(preview, i18n("Selected 1")); PreviewItem *pwCurrent = new PreviewItem(preview, i18n("Current")); PreviewItem *pwInvLink = new PreviewItem(preview, i18n("Invalid symlink")); PreviewItem *pwSymLink = new PreviewItem(preview, i18n("Symbolic link")); PreviewItem *pwApp = new PreviewItem(preview, i18n("Application")); PreviewItem *pwFile = new PreviewItem(preview, i18n("File")); PreviewItem *pwDir = new PreviewItem(preview, i18n("Folder")); bool isActive = currentPage == 0; // create local color cache instance, which does NOT affect the color cache instance using to paint the panels KrColorCache colCache; // create local color settings instance, which initially contains the settings from krConfig KrColorSettings colorSettings; // copy over local settings to color settings instance, which does not affect the persisted krConfig settings QList names = KrColorSettings::getColorNames(); for (QList::Iterator it = names.begin(); it != names.end(); ++it) { KonfiguratorColorChooser * chooser = getColorSelector(*it); if (!chooser) continue; colorSettings.setColorTextValue(*it, chooser->getValue()); if (chooser->isValueRGB()) colorSettings.setColorValue(*it, chooser->getColor()); else colorSettings.setColorValue(*it, QColor()); } colorSettings.setBoolValue("KDE Default", generals->find("KDE Default")->isChecked()); colorSettings.setBoolValue("Enable Alternate Background", generals->find("Enable Alternate Background")->isChecked()); colorSettings.setBoolValue("Show Current Item Always", generals->find("Show Current Item Always")->isChecked()); colorSettings.setBoolValue("Dim Inactive Colors", generals->find("Dim Inactive Colors")->isChecked()); colorSettings.setNumValue("Dim Factor", dimFactor->value()); // let the color cache use the local color settings colCache.setColors(colorSettings); // ask the local color cache for certain color groups and use them to color the preview KrColorGroup cg; // setting the background color colCache.getColors(cg, KrColorItemType(KrColorItemType::File, false, isActive, false, false)); QPalette pal = preview->palette(); pal.setColor(QPalette::Base, cg.background()); preview->setPalette(pal); colCache.getColors(cg, KrColorItemType(KrColorItemType::Directory, false, isActive, false, false)); pwDir->setColor(cg.text(), cg.background()); colCache.getColors(cg, KrColorItemType(KrColorItemType::File, true, isActive, false, false)); pwFile->setColor(cg.text(), cg.background()); colCache.getColors(cg, KrColorItemType(KrColorItemType::Executable, false, isActive, false, false)); pwApp->setColor(cg.text(), cg.background()); colCache.getColors(cg, KrColorItemType(KrColorItemType::Symlink, true, isActive, false, false)); pwSymLink->setColor(cg.text(), cg.background()); colCache.getColors(cg, KrColorItemType(KrColorItemType::InvalidSymlink, false, isActive, false, false)); pwInvLink->setColor(cg.text(), cg.background()); colCache.getColors(cg, KrColorItemType(KrColorItemType::File, true, isActive, true, false)); pwCurrent->setColor(cg.text(), cg.background()); colCache.getColors(cg, KrColorItemType(KrColorItemType::File, false, isActive, false, true)); pwMark1->setColor(cg.highlightedText(), cg.highlight()); colCache.getColors(cg, KrColorItemType(KrColorItemType::File, true, isActive, false, true)); pwMark2->setColor(cg.highlightedText(), cg.highlight()); colCache.getColors(cg, KrColorItemType(KrColorItemType::File, false, isActive, true, true)); pwMarkCur->setColor(cg.highlightedText(), cg.highlight()); } #ifdef SYNCHRONIZER_ENABLED else if (currentPage == synchronizerTabIdx) { PreviewItem *pwDelete = new PreviewItem(preview, i18n("Delete")); PreviewItem *pwRightCopy = new PreviewItem(preview, i18n("Copy to right")); PreviewItem *pwLeftCopy = new PreviewItem(preview, i18n("Copy to left")); PreviewItem *pwDiffers = new PreviewItem(preview, i18n("Differing")); PreviewItem *pwEquals = new PreviewItem(preview, i18n("Equals")); pwEquals->setColor(getColorSelector("Synchronizer Equals Foreground")->getColor(), getColorSelector("Synchronizer Equals Background")->getColor()); pwDiffers->setColor(getColorSelector("Synchronizer Differs Foreground")->getColor(), getColorSelector("Synchronizer Differs Background")->getColor()); pwLeftCopy->setColor(getColorSelector("Synchronizer LeftCopy Foreground")->getColor(), getColorSelector("Synchronizer LeftCopy Background")->getColor()); pwRightCopy->setColor(getColorSelector("Synchronizer RightCopy Foreground")->getColor(), getColorSelector("Synchronizer RightCopy Background")->getColor()); pwDelete->setColor(getColorSelector("Synchronizer Delete Foreground")->getColor(), getColorSelector("Synchronizer Delete Background")->getColor()); } #endif else if (currentPage == otherTabIdx) { PreviewItem *pwNonMatch = new PreviewItem(preview, i18n("Quicksearch non-match")); PreviewItem *pwMatch = new PreviewItem(preview, i18n("Quicksearch match")); pwMatch->setColor(getColorSelector("Quicksearch Match Foreground")->getColor(), getColorSelector("Quicksearch Match Background")->getColor()); pwNonMatch->setColor(getColorSelector("Quicksearch Non-match Foreground")->getColor(), getColorSelector("Quicksearch Non-match Background")->getColor()); PreviewItem *pwStatusActive = new PreviewItem(preview, i18n("Statusbar active")); PreviewItem *pwStatusInactive = new PreviewItem(preview, i18n("Statusbar inactive")); pwStatusActive->setColor(getColorSelector("Statusbar Foreground Active")->getColor(), getColorSelector("Statusbar Background Active")->getColor()); pwStatusInactive->setColor(getColorSelector("Statusbar Foreground Inactive")->getColor(), getColorSelector("Statusbar Background Inactive")->getColor()); } } bool KgColors::apply() { bool result = KonfiguratorPage::apply(); KrColorCache::getColorCache().refreshColors(); return result; } void KgColors::slotImportColors() { // find $KDEDIR/share/apps/krusader QString basedir= QStandardPaths::locate(QStandardPaths::DataLocation, QStringLiteral("total_commander.keymap")); basedir = QFileInfo(basedir).absolutePath(); // let the user select a file to load QString file = QFileDialog::getOpenFileName(0, i18n("Select a color-scheme file"), basedir, QStringLiteral("*.color")); if (file.isEmpty()) { return; } QFile f(file); if (!f.open(QIODevice::ReadOnly)) { KMessageBox::error(this, i18n("Error: unable to read from file"), i18n("Error")); return; } QDataStream stream(&f); // ok, import away deserialize(stream); generatePreview(); } void KgColors::slotExportColors() { QString file = QFileDialog::getSaveFileName(0, i18n("Select a color scheme file"), QString(), QStringLiteral("*")); if (file.isEmpty()) { return; } QFile f(file); if (f.exists() && KMessageBox::warningContinueCancel(this, i18n("File %1 already exists. Are you sure you want to overwrite it?", file), i18n("Warning"), KStandardGuiItem::overwrite()) != KMessageBox::Continue) return; if (!f.open(QIODevice::WriteOnly)) { KMessageBox::error(this, i18n("Error: unable to write to file"), i18n("Error")); return; } QDataStream stream(&f); serialize(stream); } void KgColors::serialize(QDataStream & stream) { serializeItem(stream, "Alternate Background"); serializeItem(stream, "Alternate Marked Background"); serializeItem(stream, "Background"); serializeItem(stream, "Current Background"); serializeItem(stream, "Current Foreground"); serializeItem(stream, "Enable Alternate Background"); serializeItem(stream, "Foreground"); serializeItem(stream, "Directory Foreground"); serializeItem(stream, "Executable Foreground"); serializeItem(stream, "Symlink Foreground"); serializeItem(stream, "Invalid Symlink Foreground"); serializeItem(stream, "Inactive Alternate Background"); serializeItem(stream, "Inactive Alternate Marked Background"); serializeItem(stream, "Inactive Background"); serializeItem(stream, "Inactive Current Foreground"); serializeItem(stream, "Inactive Current Background"); serializeItem(stream, "Inactive Marked Background"); serializeItem(stream, "Inactive Marked Current Foreground"); serializeItem(stream, "Inactive Marked Foreground"); serializeItem(stream, "Inactive Foreground"); serializeItem(stream, "Inactive Directory Foreground"); serializeItem(stream, "Inactive Executable Foreground"); serializeItem(stream, "Inactive Symlink Foreground"); serializeItem(stream, "Inactive Invalid Symlink Foreground"); serializeItem(stream, "Dim Inactive Colors"); serializeItem(stream, "Dim Target Color"); serializeItem(stream, "Dim Factor"); serializeItem(stream, "KDE Default"); serializeItem(stream, "Marked Background"); serializeItem(stream, "Marked Current Foreground"); serializeItem(stream, "Marked Foreground"); serializeItem(stream, "Show Current Item Always"); #ifdef SYNCHRONIZER_ENABLED serializeItem(stream, "Synchronizer Equals Foreground"); serializeItem(stream, "Synchronizer Equals Background"); serializeItem(stream, "Synchronizer Differs Foreground"); serializeItem(stream, "Synchronizer Differs Background"); serializeItem(stream, "Synchronizer LeftCopy Foreground"); serializeItem(stream, "Synchronizer LeftCopy Background"); serializeItem(stream, "Synchronizer RightCopy Foreground"); serializeItem(stream, "Synchronizer RightCopy Background"); serializeItem(stream, "Synchronizer Delete Foreground"); serializeItem(stream, "Synchronizer Delete Background"); #endif serializeItem(stream, "Quicksearch Match Foreground"); serializeItem(stream, "Quicksearch Match Background"); serializeItem(stream, "Quicksearch Non-match Foreground"); serializeItem(stream, "Quicksearch Non-match Background"); serializeItem(stream, "Statusbar Foreground Active"); serializeItem(stream, "Statusbar Background Active"); serializeItem(stream, "Statusbar Foreground Inactive"); serializeItem(stream, "Statusbar Background Inactive"); stream << QString("") << QString(""); } void KgColors::deserialize(QDataStream & stream) { for (;;) { QString name; QString value; stream >> name >> value; if (name.isEmpty()) break; if (name == "KDE Default" || name == "Enable Alternate Background" || name == "Show Current Item Always" || name == "Dim Inactive Colors") { bool bValue = false; value = value.toLower(); if (value == "true" || value == "yes" || value == "on" || value == "1") bValue = true; generals->find(name)->setChecked(bValue); continue; } if (name == "Dim Factor") { dimFactor->setValue(value.toInt()); continue; } KonfiguratorColorChooser *selector = getColorSelector(name); if (selector == 0) break; selector->setValue(value); } } void KgColors::serializeItem(class QDataStream & stream, const char * name) { stream << QString(name); if (strcmp(name, "KDE Default") == 0 || strcmp(name, "Enable Alternate Background") == 0 || strcmp(name, "Show Current Item Always") == 0 || strcmp(name, "Dim Inactive Colors") == 0) { bool bValue = generals->find(name)->isChecked(); stream << QString(bValue ? "true" : "false"); } else if (strcmp(name, "Dim Factor") == 0) stream << QString::number(dimFactor->value()); else { KonfiguratorColorChooser *selector = getColorSelector(name); stream << selector->getValue(); } } diff --git a/krusader/Konfigurator/kgdependencies.cpp b/krusader/Konfigurator/kgdependencies.cpp index 03cf737c..ab83db83 100644 --- a/krusader/Konfigurator/kgdependencies.cpp +++ b/krusader/Konfigurator/kgdependencies.cpp @@ -1,173 +1,172 @@ /***************************************************************************** * 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 "kgdependencies.h" #include "../krservices.h" #include "../krglobal.h" // QtCore #include // QtWidgets #include #include #include #include #include #include #define PAGE_GENERAL 0 #define PAGE_PACKERS 1 #define PAGE_CHECKSUM 2 KgDependencies::KgDependencies(bool first, QWidget* parent) : KonfiguratorPage(first, parent) { QGridLayout *kgDependenciesLayout = new QGridLayout(this); kgDependenciesLayout->setSpacing(6); // ---------------------------- GENERAL TAB ------------------------------------- tabWidget = new QTabWidget(this); QWidget *general_tab = new QWidget(tabWidget); QScrollArea* general_scroll = new QScrollArea(tabWidget); general_scroll->setFrameStyle(QFrame::NoFrame); general_scroll->setWidget(general_tab); // this also sets scrollacrea as the new parent for widget general_scroll->setWidgetResizable(true); // let the widget use every space available tabWidget->addTab(general_scroll, i18n("General")); QGridLayout *pathsGrid = new QGridLayout(general_tab); pathsGrid->setSpacing(6); pathsGrid->setContentsMargins(11, 11, 11, 11); pathsGrid->setAlignment(Qt::AlignTop); addApplication("kget", pathsGrid, 0, general_tab, PAGE_GENERAL); addApplication("mailer", pathsGrid, 1, general_tab, PAGE_GENERAL); addApplication("diff utility", pathsGrid, 2, general_tab, PAGE_GENERAL); addApplication("krename", pathsGrid, 3, general_tab, PAGE_GENERAL); addApplication("locate", pathsGrid, 4, general_tab, PAGE_GENERAL); addApplication("mount", pathsGrid, 5, general_tab, PAGE_GENERAL); addApplication("umount", pathsGrid, 6, general_tab, PAGE_GENERAL); addApplication("updatedb", pathsGrid, 7, general_tab, PAGE_GENERAL); // ---------------------------- PACKERS TAB ------------------------------------- QWidget *packers_tab = new QWidget(tabWidget); QScrollArea* packers_scroll = new QScrollArea(tabWidget); packers_scroll->setFrameStyle(QFrame::NoFrame); packers_scroll->setWidget(packers_tab); // this also sets scrollacrea as the new parent for widget packers_scroll->setWidgetResizable(true); // let the widget use every space available tabWidget->addTab(packers_scroll, i18n("Packers")); QGridLayout *archGrid1 = new QGridLayout(packers_tab); archGrid1->setSpacing(6); archGrid1->setContentsMargins(11, 11, 11, 11); archGrid1->setAlignment(Qt::AlignTop); addApplication("7z", archGrid1, 0, packers_tab, PAGE_PACKERS, "7za"); addApplication("arj", archGrid1, 1, packers_tab, PAGE_PACKERS); addApplication("bzip2", archGrid1, 2, packers_tab, PAGE_PACKERS); addApplication("cpio", archGrid1, 3, packers_tab, PAGE_PACKERS); addApplication("dpkg", archGrid1, 4, packers_tab, PAGE_PACKERS); addApplication("gzip", archGrid1, 5, packers_tab, PAGE_PACKERS); addApplication("lha", archGrid1, 6, packers_tab, PAGE_PACKERS); addApplication("lzma", archGrid1, 7, packers_tab, PAGE_PACKERS); addApplication("rar", archGrid1, 8, packers_tab, PAGE_PACKERS); addApplication("tar", archGrid1, 9, packers_tab, PAGE_PACKERS); addApplication("unace", archGrid1, 10, packers_tab, PAGE_PACKERS); addApplication("unarj", archGrid1, 11, packers_tab, PAGE_PACKERS); addApplication("unrar", archGrid1, 12, packers_tab, PAGE_PACKERS); addApplication("unzip", archGrid1, 13, packers_tab, PAGE_PACKERS); addApplication("zip", archGrid1, 14, packers_tab, PAGE_PACKERS); addApplication("xz", archGrid1, 15, packers_tab, PAGE_PACKERS); // ---------------------------- CHECKSUM TAB ------------------------------------- QWidget *checksum_tab = new QWidget(tabWidget); QScrollArea* checksum_scroll = new QScrollArea(tabWidget); checksum_scroll->setFrameStyle(QFrame::NoFrame); checksum_scroll->setWidget(checksum_tab); // this also sets scrollacrea as the new parent for widget checksum_scroll->setWidgetResizable(true); // let the widget use every space available tabWidget->addTab(checksum_scroll, i18n("Checksum Utilities")); QGridLayout *archGrid2 = new QGridLayout(checksum_tab); archGrid2->setSpacing(6); archGrid2->setContentsMargins(11, 11, 11, 11); archGrid2->setAlignment(Qt::AlignTop); addApplication("md5sum", archGrid2, 0, checksum_tab, PAGE_CHECKSUM); addApplication("sha1sum", archGrid2, 1, checksum_tab, PAGE_CHECKSUM); addApplication("sha224sum", archGrid2, 2, checksum_tab, PAGE_CHECKSUM); addApplication("sha256sum", archGrid2, 3, checksum_tab, PAGE_CHECKSUM); addApplication("sha384sum", archGrid2, 4, checksum_tab, PAGE_CHECKSUM); addApplication("sha512sum", archGrid2, 5, checksum_tab, PAGE_CHECKSUM); kgDependenciesLayout->addWidget(tabWidget, 0, 0); } void KgDependencies::addApplication(QString name, QGridLayout *grid, int row, QWidget *parent, int page, QString additionalList) { // try to autodetect the full path name QString defaultValue = KrServices::fullPathName(name); if (defaultValue.isEmpty()) { QStringList list = additionalList.split(',', QString::SkipEmptyParts); for (int i = 0; i != list.count(); i++) if (!KrServices::fullPathName(list[ i ]).isEmpty()) { defaultValue = KrServices::fullPathName(list[ i ]); break; } } addLabel(grid, row, 0, name, parent); KonfiguratorURLRequester *fullPath = createURLRequester("Dependencies", name, defaultValue, parent, false, page); - connect(fullPath->extension(), SIGNAL(applyManually(QObject*,QString,QString)), - this, SLOT(slotApply(QObject*,QString,QString))); + connect(fullPath->extension(), &KonfiguratorExtension::applyManually, this, &KgDependencies::slotApply); grid->addWidget(fullPath, row, 1); } void KgDependencies::slotApply(QObject *obj, QString configGroup, QString name) { KonfiguratorURLRequester *urlRequester = (KonfiguratorURLRequester *) obj; KConfigGroup group(krConfig, configGroup); group.writeEntry(name, urlRequester->url().toDisplayString(QUrl::PreferLocalFile)); QString usedPath = KrServices::fullPathName(name); if (urlRequester->url().toDisplayString(QUrl::PreferLocalFile) != usedPath) { group.writeEntry(name, usedPath); if (usedPath.isEmpty()) KMessageBox::error(this, i18n("The %1 path is incorrect, no valid path found.", urlRequester->url().toDisplayString(QUrl::PreferLocalFile))); else KMessageBox::error( this, i18n("The %1 path is incorrect, %2 used instead.", urlRequester->url().toDisplayString(QUrl::PreferLocalFile), usedPath)); urlRequester->setUrl(QUrl::fromLocalFile(usedPath)); } } int KgDependencies::activeSubPage() { return tabWidget->currentIndex(); } diff --git a/krusader/Konfigurator/kggeneral.cpp b/krusader/Konfigurator/kggeneral.cpp index ece73eab..c110766e 100644 --- a/krusader/Konfigurator/kggeneral.cpp +++ b/krusader/Konfigurator/kggeneral.cpp @@ -1,330 +1,329 @@ /***************************************************************************** * 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 "kggeneral.h" // QtCore #include // QtGui #include #include // QtWidgets #include #include #include #include #include #include #include #include "krresulttabledialog.h" #include "../defaults.h" #include "../icon.h" #include "../krglobal.h" #define PAGE_GENERAL 0 #define PAGE_VIEWER 1 #define PAGE_EXTENSIONS 2 KgGeneral::KgGeneral(bool first, QWidget* parent) : KonfiguratorPage(first, parent) { if (first) slotFindTools(); tabWidget = new QTabWidget(this); setWidget(tabWidget); setWidgetResizable(true); createGeneralTab(); createViewerTab(); createExtensionsTab(); } QWidget* KgGeneral::createTab(QString name) { QScrollArea *scrollArea = new QScrollArea(tabWidget); tabWidget->addTab(scrollArea, name); scrollArea->setFrameStyle(QFrame::NoFrame); scrollArea->setWidgetResizable(true); QWidget *tab = new QWidget(scrollArea); scrollArea->setWidget(tab); return tab; } void KgGeneral::createViewerTab() { QWidget *tab = createTab(i18n("Viewer/Editor")); QGridLayout *tabLayout = new QGridLayout(tab); tabLayout->setSpacing(6); tabLayout->setContentsMargins(11, 11, 11, 11); tabLayout->addWidget(createCheckBox("General", "View In Separate Window", _ViewInSeparateWindow, i18n("Internal editor and viewer opens each file in a separate window"), tab, false, i18n("If checked, each file will open in a separate window, otherwise, the viewer will work in a single, tabbed mode"), PAGE_VIEWER)); // ------------------------- viewer ---------------------------------- QGroupBox *viewerGrp = createFrame(i18n("Viewer"), tab); tabLayout->addWidget(viewerGrp, 1, 0); QGridLayout *viewerGrid = createGridLayout(viewerGrp); QWidget * hboxWidget2 = new QWidget(viewerGrp); QHBoxLayout * hbox2 = new QHBoxLayout(hboxWidget2); QWidget * vboxWidget = new QWidget(hboxWidget2); QVBoxLayout * vbox = new QVBoxLayout(vboxWidget); vbox->addWidget(new QLabel(i18n("Default viewer mode:"), vboxWidget)); KONFIGURATOR_NAME_VALUE_TIP viewMode[] = // name value tooltip {{ i18n("Generic mode"), "generic", i18n("Use the system's default viewer") }, { i18n("Text mode"), "text", i18n("View the file in text-only mode") }, { i18n("Hex mode"), "hex", i18n("View the file in hex-mode (better for binary files)") }, { i18n("Lister mode"), "lister", i18n("View the file with lister (for huge text files)") } }; vbox->addWidget(createRadioButtonGroup("General", "Default Viewer Mode", "generic", 0, 4, viewMode, 4, vboxWidget, false, PAGE_VIEWER)); vbox->addWidget( createCheckBox("General", "UseOktetaViewer", _UseOktetaViewer, i18n("Use Okteta as Hex viewer"), vboxWidget, false, i18n("If available, use Okteta as Hex viewer instead of the internal viewer"), PAGE_VIEWER) ); QWidget * hboxWidget4 = new QWidget(vboxWidget); QHBoxLayout * hbox4 = new QHBoxLayout(hboxWidget4); QLabel *label5 = new QLabel(i18n("Use lister if the text file is bigger than:"), hboxWidget4); hbox4->addWidget(label5); KonfiguratorSpinBox *spinBox = createSpinBox("General", "Lister Limit", _ListerLimit, 0, 0x7FFFFFFF, hboxWidget4, false, PAGE_VIEWER); hbox4->addWidget(spinBox); QLabel *label6 = new QLabel(i18n("MB"), hboxWidget4); hbox4->addWidget(label6); vbox->addWidget(hboxWidget4); hbox2->addWidget(vboxWidget); viewerGrid->addWidget(hboxWidget2, 0, 0); // ------------------------- editor ---------------------------------- QGroupBox *editorGrp = createFrame(i18n("Editor"), tab); tabLayout->addWidget(editorGrp, 2, 0); QGridLayout *editorGrid = createGridLayout(editorGrp); QLabel *label1 = new QLabel(i18n("Editor:"), editorGrp); editorGrid->addWidget(label1, 0, 0); KonfiguratorURLRequester *urlReq = createURLRequester("General", "Editor", "internal editor", editorGrp, false, PAGE_VIEWER, false); editorGrid->addWidget(urlReq, 0, 1); QLabel *label2 = new QLabel(i18n("Hint: use 'internal editor' if you want to use Krusader's fast built-in editor"), editorGrp); editorGrid->addWidget(label2, 1, 0, 1, 2); } void KgGeneral::createExtensionsTab() { // ------------------------- atomic extensions ---------------------------------- QWidget *tab = createTab(i18n("Atomic extensions")); QGridLayout *tabLayout = new QGridLayout(tab); tabLayout->setSpacing(6); tabLayout->setContentsMargins(11, 11, 11, 11); QWidget * vboxWidget2 = new QWidget(tab); tabLayout->addWidget(vboxWidget2); QVBoxLayout * vbox2 = new QVBoxLayout(vboxWidget2); QWidget * hboxWidget3 = new QWidget(vboxWidget2); vbox2->addWidget(hboxWidget3); QHBoxLayout * hbox3 = new QHBoxLayout(hboxWidget3); QLabel * atomLabel = new QLabel(i18n("Atomic extensions:"), hboxWidget3); hbox3->addWidget(atomLabel); int size = QFontMetrics(atomLabel->font()).height(); QToolButton *addButton = new QToolButton(hboxWidget3); hbox3->addWidget(addButton); QPixmap iconPixmap = Icon("list-add").pixmap(size); addButton->setFixedSize(iconPixmap.width() + 4, iconPixmap.height() + 4); addButton->setIcon(QIcon(iconPixmap)); - connect(addButton, SIGNAL(clicked()), this, SLOT(slotAddExtension())); + connect(addButton, &QToolButton::clicked, this, &KgGeneral::slotAddExtension); QToolButton *removeButton = new QToolButton(hboxWidget3); hbox3->addWidget(removeButton); iconPixmap = Icon("list-remove").pixmap(size); removeButton->setFixedSize(iconPixmap.width() + 4, iconPixmap.height() + 4); removeButton->setIcon(QIcon(iconPixmap)); - connect(removeButton, SIGNAL(clicked()), this, SLOT(slotRemoveExtension())); + connect(removeButton, &QToolButton::clicked, this, &KgGeneral::slotRemoveExtension); QStringList defaultAtomicExtensions; defaultAtomicExtensions += ".tar.gz"; defaultAtomicExtensions += ".tar.bz2"; defaultAtomicExtensions += ".tar.lzma"; defaultAtomicExtensions += ".tar.xz"; defaultAtomicExtensions += ".moc.cpp"; listBox = createListBox("Look&Feel", "Atomic Extensions", defaultAtomicExtensions, vboxWidget2, true, PAGE_EXTENSIONS); vbox2->addWidget(listBox); } void KgGeneral::createGeneralTab() { QWidget *tab = createTab(i18n("General")); QGridLayout *kgGeneralLayout = new QGridLayout(tab); kgGeneralLayout->setSpacing(6); kgGeneralLayout->setContentsMargins(11, 11, 11, 11); // -------------------------- GENERAL GROUPBOX ---------------------------------- QGroupBox *generalGrp = createFrame(i18n("General"), tab); QGridLayout *generalGrid = createGridLayout(generalGrp); KONFIGURATOR_CHECKBOX_PARAM settings[] = { // cfg_class cfg_name default text restart tooltip {"Look&Feel", "Warn On Exit", _WarnOnExit, i18n("Warn on exit"), false, i18n("Display a warning when trying to close the main window.") }, // KDE4: move warn on exit to the other confirmations {"Look&Feel", "Minimize To Tray", _ShowTrayIcon, i18n("Show and close to tray"), false, i18n("Show an icon in the system tray and keep running in the background when the window is closed.") }, }; KonfiguratorCheckBoxGroup *cbs = createCheckBoxGroup(2, 0, settings, 2 /*count*/, generalGrp, PAGE_GENERAL); generalGrid->addWidget(cbs, 0, 0); // temp dir QHBoxLayout *hbox = new QHBoxLayout(); hbox->addWidget(new QLabel(i18n("Temp Folder:"), generalGrp)); KonfiguratorURLRequester *urlReq3 = createURLRequester("General", "Temp Directory", _TempDirectory, generalGrp, false, PAGE_GENERAL); urlReq3->setMode(KFile::Directory); - connect(urlReq3->extension(), SIGNAL(applyManually(QObject*,QString,QString)), - this, SLOT(applyTempDir(QObject*,QString,QString))); + connect(urlReq3->extension(), &KonfiguratorExtension::applyManually, this, &KgGeneral::applyTempDir); hbox->addWidget(urlReq3); generalGrid->addLayout(hbox, 13, 0, 1, 1); QLabel *label4 = new QLabel(i18n("Note: you must have full permissions for the temporary folder."), generalGrp); generalGrid->addWidget(label4, 14, 0, 1, 1); kgGeneralLayout->addWidget(generalGrp, 0 , 0); // ----------------------- delete mode -------------------------------------- QGroupBox *delGrp = createFrame(i18n("Delete mode"), tab); QGridLayout *delGrid = createGridLayout(delGrp); KONFIGURATOR_NAME_VALUE_TIP deleteMode[] = // name value tooltip {{i18n("Move to trash"), "true", i18n("Files will be moved to trash when deleted.")}, {i18n("Delete files"), "false", i18n("Files will be permanently deleted.")} }; KonfiguratorRadioButtons *trashRadio = createRadioButtonGroup("General", "Move To Trash", _MoveToTrash ? "true" : "false", 2, 0, deleteMode, 2, delGrp, false, PAGE_GENERAL); delGrid->addWidget(trashRadio); kgGeneralLayout->addWidget(delGrp, 1 , 0); // ----------------------- terminal ----------------------------------------- QGroupBox *terminalGrp = createFrame(i18n("Terminal"), tab); QGridLayout *terminalGrid = createGridLayout(terminalGrp); QLabel *label3 = new QLabel(i18n("External Terminal:"), generalGrp); terminalGrid->addWidget(label3, 0, 0); KonfiguratorURLRequester *urlReq2 = createURLRequester("General", "Terminal", _Terminal, generalGrp, false, PAGE_GENERAL, false); terminalGrid->addWidget(urlReq2, 0, 1); QLabel *terminalLabel = new QLabel(i18n("%d will be replaced by the workdir."), terminalGrp); terminalGrid->addWidget(terminalLabel, 1, 1); KONFIGURATOR_CHECKBOX_PARAM terminal_settings[] = { // cfg_class cfg_name default text restart tooltip {"General", "Send CDs", _SendCDs, i18n("Embedded Terminal sends Chdir on panel change"), false, i18n("When checked, whenever the panel is changed (for example, by pressing Tab), Krusader changes the current folder in the embedded terminal.") }, }; cbs = createCheckBoxGroup(1, 0, terminal_settings, 1 /*count*/, terminalGrp, PAGE_GENERAL); terminalGrid->addWidget(cbs, 2, 0, 1, 2); kgGeneralLayout->addWidget(terminalGrp, 2 , 0); } void KgGeneral::applyTempDir(QObject *obj, QString configGroup, QString name) { KonfiguratorURLRequester *urlReq = (KonfiguratorURLRequester *)obj; QString value = urlReq->url().toDisplayString(QUrl::PreferLocalFile); KConfigGroup(krConfig, configGroup).writeEntry(name, value); } void KgGeneral::slotFindTools() { QPointer dlg = new KrResultTableDialog(this, KrResultTableDialog::Tool, i18n("Search results"), i18n("Searching for tools..."), "tools-wizard", i18n("Make sure to install new tools in your $PATH (e.g. /usr/bin)")); dlg->exec(); delete dlg; } void KgGeneral::slotAddExtension() { bool ok; QString atomExt = QInputDialog::getText(this, i18n("Add new atomic extension"), i18n("Extension:"), QLineEdit::Normal, QString(), &ok); if (ok) { if (!atomExt.startsWith('.') || atomExt.indexOf('.', 1) == -1) KMessageBox::error(krMainWindow, i18n("Atomic extensions must start with '.' and must contain at least one more '.' character."), i18n("Error")); else listBox->addItem(atomExt); } } void KgGeneral::slotRemoveExtension() { QList list = listBox->selectedItems(); for (int i = 0; i != list.count(); i++) listBox->removeItem(list[ i ]->text()); } diff --git a/krusader/Konfigurator/kgpanel.cpp b/krusader/Konfigurator/kgpanel.cpp index 9a37fcb2..93b1c6de 100644 --- a/krusader/Konfigurator/kgpanel.cpp +++ b/krusader/Konfigurator/kgpanel.cpp @@ -1,745 +1,745 @@ /***************************************************************************** * Copyright (C) 2010 Jan Lepper * * Copyright (C) 2010-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 "kgpanel.h" #include "../defaults.h" #include "../Dialogs/krdialogs.h" // QtGui #include // QtWidgets #include #include #include #include #include #include #include #include "../GUI/krtreewidget.h" #include "../Panel/krsearchbar.h" #include "../Panel/PanelView/krselectionmode.h" #include "../Panel/PanelView/krview.h" #include "../Panel/PanelView/krviewfactory.h" #include "../Panel/krlayoutfactory.h" enum { PAGE_GENERAL = 0, PAGE_VIEW, PAGE_PANELTOOLBAR, PAGE_MOUSE, PAGE_MEDIA_MENU, PAGE_LAYOUT }; KgPanel::KgPanel(bool first, QWidget* parent) : KonfiguratorPage(first, parent) { tabWidget = new QTabWidget(this); setWidget(tabWidget); setWidgetResizable(true); setupGeneralTab(); setupPanelTab(); setupButtonsTab(); setupMouseModeTab(); setupMediaMenuTab(); setupLayoutTab(); } // --------------------------------------------------------------------------------------- // ---------------------------- General TAB ---------------------------------------------- // --------------------------------------------------------------------------------------- void KgPanel::setupGeneralTab() { QScrollArea *scrollArea = new QScrollArea(tabWidget); QWidget *tab = new QWidget(scrollArea); scrollArea->setFrameStyle(QFrame::NoFrame); scrollArea->setWidget(tab); scrollArea->setWidgetResizable(true); tabWidget->addTab(scrollArea, i18n("General")); QVBoxLayout *layout = new QVBoxLayout(tab); layout->setSpacing(6); layout->setContentsMargins(11, 11, 11, 11); // --------------------------------------------------------------------------------------- // ------------------------------- Navigator bar ------------------------------------- // --------------------------------------------------------------------------------------- QGroupBox *groupBox = createFrame(i18n("Navigator bar"), tab); QGridLayout *gridLayout = createGridLayout(groupBox); KONFIGURATOR_CHECKBOX_PARAM navigatorbar_settings[] = { // cfg_class, cfg_name, default, text, restart, tooltip {"Look&Feel", "Navigator Edit Mode", false, i18n("Edit Mode by default"), true, i18n("Show editable path in Navigator bar by default") }, {"Look&Feel", "Navigator Full Path", false, i18n("Show full path by default"), true, i18n("Always show full path in Navigator bar by default.") }, }; KonfiguratorCheckBoxGroup* cbs = createCheckBoxGroup(2, 0, navigatorbar_settings, 2 /*count*/, groupBox, PAGE_GENERAL); gridLayout->addWidget(cbs, 0, 0); layout->addWidget(groupBox); // --------------------------------------------------------------------------------------- // ------------------------------- Operation --------------------------------------------- // --------------------------------------------------------------------------------------- groupBox = createFrame(i18n("Operation"), tab); gridLayout = createGridLayout(groupBox); KONFIGURATOR_CHECKBOX_PARAM operation_settings[] = { // cfg_class, cfg_name, default, text, restart, tooltip {"Look&Feel", "Mark Dirs", _MarkDirs, i18n("Autoselect folders"), false, i18n("When matching the select criteria, not only files will be selected, but also folders.") }, {"Look&Feel", "Rename Selects Extension", true, i18n("Rename selects extension"), false, i18n("When renaming a file, the whole text is selected. If you want Total-Commander like renaming of just the name, without extension, uncheck this option.") }, {"Look&Feel", "UnselectBeforeOperation", _UnselectBeforeOperation, i18n("Unselect files before copy/move"), false, i18n("Unselect files, which are to be copied/moved, before the operation starts.") }, {"Look&Feel", "FilterDialogRemembersSettings", _FilterDialogRemembersSettings, i18n("Filter dialog remembers settings"), false, i18n("The filter dialog is opened with the last filter settings that where applied to the panel.") }, }; cbs = createCheckBoxGroup(2, 0, operation_settings, 4 /*count*/, groupBox, PAGE_GENERAL); gridLayout->addWidget(cbs, 0, 0); layout->addWidget(groupBox); // --------------------------------------------------------------------------------------- // ------------------------------ Tabs --------------------------------------------------- // --------------------------------------------------------------------------------------- groupBox = createFrame(i18n("Tabs"), tab); gridLayout = createGridLayout(groupBox); KONFIGURATOR_CHECKBOX_PARAM tabbar_settings[] = { // cfg_class cfg_name default text restart tooltip {"Look&Feel", "Fullpath Tab Names", _FullPathTabNames, i18n("Use full path tab names"), true , i18n("Display the full path in the folder tabs. By default only the last part of the path is displayed.") }, {"Look&Feel", "Show Tab Buttons", true, i18n("Show new/close tab buttons"), true , i18n("Show the new/close tab buttons.") }, }; cbs = createCheckBoxGroup(2, 0, tabbar_settings, 2 /*count*/, groupBox, PAGE_GENERAL); gridLayout->addWidget(cbs, 0, 0, 1, 2); // ----------------- Tab Bar position ---------------------------------- QHBoxLayout *hbox = new QHBoxLayout(); hbox->addWidget(new QLabel(i18n("Tab Bar position:"), groupBox)); KONFIGURATOR_NAME_VALUE_PAIR positions[] = { { i18n("Top"), "top" }, { i18n("Bottom"), "bottom" } }; KonfiguratorComboBox *cmb = createComboBox("Look&Feel", "Tab Bar Position", "bottom", positions, 2, groupBox, true, false, PAGE_GENERAL); hbox->addWidget(cmb); gridLayout->addLayout(hbox, 1, 0, Qt::AlignLeft); // ----------------- Show Tab bar ---------------------------------- KonfiguratorCheckBox *checkBox = createCheckBox("Look&Feel", "Show Tab Bar On Single Tab", true, i18n("Show Tab Bar on single tab"), groupBox, true, i18n("Show the tab bar with only one tab.")); gridLayout->addWidget(checkBox, 1, 1, Qt::AlignLeft); layout->addWidget(groupBox); // --------------------------------------------------------------------------------------- // ----------------------------- Search bar -------------------------------------------- // --------------------------------------------------------------------------------------- groupBox = createFrame(i18n("Search bar"), tab); gridLayout = createGridLayout(groupBox); KONFIGURATOR_CHECKBOX_PARAM quicksearch[] = { // cfg_class cfg_name default text restart tooltip {"Look&Feel", "New Style Quicksearch", _NewStyleQuicksearch, i18n("Start by typing"), false, i18n("Open search bar and start searching by typing in panel.") }, {"Look&Feel", "Case Sensitive Quicksearch", _CaseSensitiveQuicksearch, i18n("Case sensitive"), false, i18n("Search must match case.") }, {"Look&Feel", "Up/Down Cancels Quicksearch", false, i18n("Up/Down cancels search"), false, i18n("Pressing the Up/Down buttons closes the search bar (only in search mode).") }, {"Look&Feel", "Navigation with Right Arrow Quicksearch", _NavigationWithRightArrowQuicksearch, i18n("Directory navigation with Right Arrow"), false, i18n("Pressing the Right button enters directory if no search text editing intention is captured.") }, }; cbs = createCheckBoxGroup(2, 0, quicksearch, 4 /*count*/, groupBox, PAGE_GENERAL); gridLayout->addWidget(cbs, 0, 0, 1, -1); // -------------- Search bar position ----------------------- hbox = new QHBoxLayout(); hbox->addWidget(new QLabel(i18n("Position:"), groupBox)); cmb = createComboBox("Look&Feel", "Quicksearch Position", "bottom", positions, 2, groupBox, true, false, PAGE_GENERAL); hbox->addWidget(cmb); hbox->addWidget(createSpacer(groupBox)); gridLayout->addLayout(hbox, 1, 0); // -------------- Default search mode ----------------------- hbox = new QHBoxLayout(); hbox->addWidget(new QLabel(i18n("Default mode:"), groupBox)); KONFIGURATOR_NAME_VALUE_PAIR modes[] = { {i18n("Search"), QString::number(KrSearchBar::MODE_SEARCH)}, {i18n("Select"), QString::number(KrSearchBar::MODE_SELECT)}, {i18n("Filter"), QString::number(KrSearchBar::MODE_FILTER)}}; cmb = createComboBox("Look&Feel", "Default Search Mode", QString::number(KrSearchBar::MODE_SEARCH), modes, 3, groupBox, true, false, PAGE_GENERAL); cmb->setToolTip(i18n("Set the default mode on first usage")); hbox->addWidget(cmb); hbox->addWidget(createSpacer(groupBox)); gridLayout->addLayout(hbox, 1, 1); layout->addWidget(groupBox); // -------------------------------------------------------------------------------------------- // ------------------------------- Bookmark search settings ---------------------------------- // -------------------------------------------------------------------------------------------- groupBox = createFrame(i18n("Bookmark Search"), tab); gridLayout = createGridLayout(groupBox); KONFIGURATOR_CHECKBOX_PARAM bookmarkSearchSettings[] = { {"Look&Feel", "Always show search bar", true, i18n("Always show search bar"), false, i18n("Make bookmark search bar always visible") }, {"Look&Feel", "Search in special items", false, i18n("Search in special items"), false, i18n("Bookmark search is also applied to special items in bookmark menu like Trash, Popular URLs, Jump Back, etc.") }, }; KonfiguratorCheckBoxGroup *bookmarkSearchSettingsGroup = createCheckBoxGroup(2, 0, bookmarkSearchSettings, 2 /*count*/, groupBox, PAGE_GENERAL); gridLayout->addWidget(bookmarkSearchSettingsGroup, 1, 0, 1, 2); layout->addWidget(groupBox); // -------------------------------------------------------------------------------------------- // ------------------------------- Status/Totalsbar settings ---------------------------------- // -------------------------------------------------------------------------------------------- groupBox = createFrame(i18n("Status/Totalsbar"), tab); gridLayout = createGridLayout(groupBox); KONFIGURATOR_CHECKBOX_PARAM barSettings[] = { {"Look&Feel", "Show Size In Bytes", false, i18n("Show size in bytes too"), true, i18n("Show size in bytes too") }, {"Look&Feel", "ShowSpaceInformation", true, i18n("Show space information"), true, i18n("Show free/total space on the device") }, }; KonfiguratorCheckBoxGroup *barSett = createCheckBoxGroup(2, 0, barSettings, 2 /*count*/, groupBox, PAGE_GENERAL); gridLayout->addWidget(barSett, 1, 0, 1, 2); layout->addWidget(groupBox); } // -------------------------------------------------------------------------------------------- // ------------------------------------ Layout Tab -------------------------------------------- // -------------------------------------------------------------------------------------------- void KgPanel::setupLayoutTab() { QScrollArea *scrollArea = new QScrollArea(tabWidget); QWidget *tab = new QWidget(scrollArea); scrollArea->setFrameStyle(QFrame::NoFrame); scrollArea->setWidget(tab); scrollArea->setWidgetResizable(true); tabWidget->addTab(scrollArea, i18n("Layout")); QGridLayout *grid = createGridLayout(tab); QStringList layoutNames = KrLayoutFactory::layoutNames(); int numLayouts = layoutNames.count(); grid->addWidget(createSpacer(tab), 0, 2); QLabel *l = new QLabel(i18n("Layout:"), tab); l->setAlignment(Qt::AlignRight | Qt::AlignVCenter); grid->addWidget(l, 0, 0); KONFIGURATOR_NAME_VALUE_PAIR *layouts = new KONFIGURATOR_NAME_VALUE_PAIR[numLayouts]; for (int i = 0; i != numLayouts; i++) { layouts[ i ].text = KrLayoutFactory::layoutDescription(layoutNames[i]); layouts[ i ].value = layoutNames[i]; } KonfiguratorComboBox *cmb = createComboBox("PanelLayout", "Layout", "default", layouts, numLayouts, tab, true, false, PAGE_LAYOUT); grid->addWidget(cmb, 0, 1); delete [] layouts; l = new QLabel(i18n("Frame Color:"), tab); l->setAlignment(Qt::AlignRight | Qt::AlignVCenter); grid->addWidget(l, 1, 0); KONFIGURATOR_NAME_VALUE_PAIR frameColor[] = { { i18nc("Frame color", "Defined by Layout"), "default" }, { i18nc("Frame color", "None"), "none" }, { i18nc("Frame color", "Statusbar"), "Statusbar" } }; cmb = createComboBox("PanelLayout", "FrameColor", "default", frameColor, 3, tab, true, false, PAGE_LAYOUT); grid->addWidget(cmb, 1, 1); l = new QLabel(i18n("Frame Shape:"), tab); l->setAlignment(Qt::AlignRight | Qt::AlignVCenter); grid->addWidget(l, 2, 0); KONFIGURATOR_NAME_VALUE_PAIR frameShape[] = { { i18nc("Frame shape", "Defined by Layout"), "default" }, { i18nc("Frame shape", "None"), "NoFrame" }, { i18nc("Frame shape", "Box"), "Box" }, { i18nc("Frame shape", "Panel"), "Panel" }, }; cmb = createComboBox("PanelLayout", "FrameShape", "default", frameShape, 4, tab, true, false, PAGE_LAYOUT); grid->addWidget(cmb, 2, 1); l = new QLabel(i18n("Frame Shadow:"), tab); l->setAlignment(Qt::AlignRight | Qt::AlignVCenter); grid->addWidget(l, 3, 0); KONFIGURATOR_NAME_VALUE_PAIR frameShadow[] = { { i18nc("Frame shadow", "Defined by Layout"), "default" }, { i18nc("Frame shadow", "None"), "Plain" }, { i18nc("Frame shadow", "Raised"), "Raised" }, { i18nc("Frame shadow", "Sunken"), "Sunken" }, }; cmb = createComboBox("PanelLayout", "FrameShadow", "default", frameShadow, 4, tab, true, false, PAGE_LAYOUT); grid->addWidget(cmb, 3, 1); } void KgPanel::setupView(KrViewInstance *instance, QWidget *parent) { QGridLayout *grid = createGridLayout(parent); // -------------------- Filelist icon size ---------------------------------- QHBoxLayout *hbox = new QHBoxLayout(); hbox->addWidget(new QLabel(i18n("Default icon size:"), parent)); KONFIGURATOR_NAME_VALUE_PAIR *iconSizes = new KONFIGURATOR_NAME_VALUE_PAIR[KrView::iconSizes.count()]; for(int i = 0; i < KrView::iconSizes.count(); i++) iconSizes[i].text = iconSizes[i].value = QString::number(KrView::iconSizes[i]); KonfiguratorComboBox *cmb = createComboBox(instance->name(), "IconSize", _FilelistIconSize, iconSizes, KrView::iconSizes.count(), parent, true, true, PAGE_VIEW); delete [] iconSizes; cmb->lineEdit()->setValidator(new QRegExpValidator(QRegExp("[1-9]\\d{0,1}"), cmb)); hbox->addWidget(cmb); hbox->addWidget(createSpacer(parent)); grid->addLayout(hbox, 1, 0); //-------------------------------------------------------------------- KONFIGURATOR_CHECKBOX_PARAM iconSettings[] = // cfg_class cfg_name default text restart tooltip { {instance->name(), "With Icons", _WithIcons, i18n("Use icons in the filenames"), true, i18n("Show the icons for filenames and folders.") }, {instance->name(), "ShowPreviews", false, i18n("Show previews by default"), false, i18n("Show previews of files and folders.") }, }; KonfiguratorCheckBoxGroup *iconSett = createCheckBoxGroup(2, 0, iconSettings, 2 /*count*/, parent, PAGE_VIEW); grid->addWidget(iconSett, 2, 0, 1, 2); } // ---------------------------------------------------------------------------------- // ---------------------------- VIEW TAB ------------------------------------------- // ---------------------------------------------------------------------------------- void KgPanel::setupPanelTab() { QScrollArea *scrollArea = new QScrollArea(tabWidget); QWidget *tab_panel = new QWidget(scrollArea); scrollArea->setFrameStyle(QFrame::NoFrame); scrollArea->setWidget(tab_panel); scrollArea->setWidgetResizable(true); tabWidget->addTab(scrollArea, i18n("View")); QGridLayout *panelLayout = new QGridLayout(tab_panel); panelLayout->setSpacing(6); panelLayout->setContentsMargins(11, 11, 11, 11); QGroupBox *panelGrp = createFrame(i18n("General"), tab_panel); panelLayout->addWidget(panelGrp, 0, 0); QGridLayout *panelGrid = createGridLayout(panelGrp); // ---------------------------------------------------------------------------------- // ---------------------------- General settings ----------------------------------- // ---------------------------------------------------------------------------------- // -------------------- Panel Font ---------------------------------- QHBoxLayout *hbox = new QHBoxLayout(); QHBoxLayout *fontLayout = new QHBoxLayout(); fontLayout->addWidget(new QLabel(i18n("View font:"), panelGrp)); KonfiguratorFontChooser *chsr = createFontChooser("Look&Feel", "Filelist Font", _FilelistFont, panelGrp, true, PAGE_VIEW); fontLayout->addWidget(chsr); fontLayout->addStretch(1); hbox->addLayout(fontLayout, 1); // -------------------- Panel Tooltip ---------------------------------- QHBoxLayout *tooltipLayout = new QHBoxLayout(); QLabel *tooltipLabel = new QLabel(i18n("Tooltip delay (msec):")); tooltipLabel->setWhatsThis(i18n("The duration after a tooltip is shown for a file item, in " "milliseconds. Set a negative value to disable tooltips.")); tooltipLayout->addWidget(tooltipLabel); KonfiguratorSpinBox *tooltipSpinBox = createSpinBox("Look&Feel", "Panel Tooltip Delay", 1000, -100, 5000, panelGrp, false, PAGE_VIEW); tooltipSpinBox->setSingleStep(100); tooltipLayout->addWidget(tooltipSpinBox); tooltipLayout->addStretch(1); hbox->addLayout(tooltipLayout, 1); panelGrid->addLayout(hbox, 1, 0); // -------------------- General options ---------------------------------- KONFIGURATOR_CHECKBOX_PARAM panelSettings[] = // cfg_class cfg_name default text restart tooltip { {"Look&Feel", "Human Readable Size", _HumanReadableSize, i18n("Use human-readable file size"), true , i18n("File sizes are displayed in B, KB, MB and GB, not just in bytes.") }, {"Look&Feel", "Show Hidden", _ShowHidden, i18n("Show hidden files"), false, i18n("Display files beginning with a dot.") }, {"Look&Feel", "Numeric permissions", _NumericPermissions, i18n("Numeric Permissions"), true, i18n("Show octal numbers (0755) instead of the standard permissions (rwxr-xr-x) in the permission column.") }, {"Look&Feel", "Load User Defined Folder Icons", _UserDefinedFolderIcons, i18n("Load the user defined folder icons"), true , i18n("Load the user defined folder icons (can cause decrease in performance).") }, {"Look&Feel", "Always Show Current Item", _AlwaysShowCurrentItem, i18n("Always show current item"), false, i18n("Show current item border decoration in inactive panel.") }, }; KonfiguratorCheckBoxGroup *panelSett = createCheckBoxGroup(2, 0, panelSettings, 5 /*count*/, panelGrp, PAGE_VIEW); panelGrid->addWidget(panelSett, 3, 0, 1, 2); // ========================================================= panelGrid->addWidget(createLine(panelGrp), 4, 0); // ------------------------ Sort Method ---------------------------------- hbox = new QHBoxLayout(); hbox->addWidget(new QLabel(i18n("Sort method:"), panelGrp)); KONFIGURATOR_NAME_VALUE_PAIR sortMethods[] = {{ i18n("Alphabetical"), QString::number(KrViewProperties::Alphabetical) }, { i18n("Alphabetical and numbers"), QString::number(KrViewProperties::AlphabeticalNumbers) }, { i18n("Character code"), QString::number(KrViewProperties::CharacterCode) }, { i18n("Character code and numbers"), QString::number(KrViewProperties::CharacterCodeNumbers) }, { i18nc("Krusader sort", "Krusader"), QString::number(KrViewProperties::Krusader) } }; KonfiguratorComboBox *cmb = createComboBox("Look&Feel", "Sort method", QString::number(_DefaultSortMethod), sortMethods, 5, panelGrp, true, false, PAGE_VIEW); hbox->addWidget(cmb); hbox->addWidget(createSpacer(panelGrp)); panelGrid->addLayout(hbox, 5, 0); // ------------------------ Sort Options ---------------------------------- KONFIGURATOR_CHECKBOX_PARAM sortSettings[] = // cfg_class, cfg_name, default, text, restart, tooltip { {"Look&Feel", "Case Sensative Sort", _CaseSensativeSort, i18n("Case sensitive sorting"), true, i18n("All files beginning with capital letters appear before files beginning with non-capital letters (UNIX default).") }, {"Look&Feel", "Show Directories First", true, i18n("Show folders first"), true, 0 }, {"Look&Feel", "Always sort dirs by name", false, i18n("Always sort dirs by name"), true, i18n("Folders are sorted by name, regardless of the sort column.") }, {"Look&Feel", "Locale Aware Sort", true, i18n("Locale aware sorting"), true, i18n("The sorting is performed in a locale- and also platform-dependent manner. Can be slow.") }, }; KonfiguratorCheckBoxGroup *sortSett = createCheckBoxGroup(2, 0, sortSettings, 4 /*count*/, panelGrp, PAGE_VIEW); sortSett->find("Show Directories First")->addDep(sortSett->find("Always sort dirs by name")); panelGrid->addWidget(sortSett, 6, 0, 1, 2); // ---------------------------------------------------------------------------------- // ---------------------------- View modes ----------------------------------------- // ---------------------------------------------------------------------------------- panelGrp = createFrame(i18n("View modes"), tab_panel); panelLayout->addWidget(panelGrp, 1, 0); panelGrid = createGridLayout(panelGrp); // -------------------- Default Panel Type ---------------------------------- hbox = new QHBoxLayout(); hbox->addWidget(new QLabel(i18n("Default view mode:"), panelGrp)); QList views = KrViewFactory::registeredViews(); const int viewsSize = views.size(); KONFIGURATOR_NAME_VALUE_PAIR *panelTypes = new KONFIGURATOR_NAME_VALUE_PAIR[ viewsSize ]; QString defType = QString('0'); for (int i = 0; i != viewsSize; i++) { KrViewInstance * inst = views[ i ]; panelTypes[ i ].text = inst->description(); panelTypes[ i ].text.remove('&'); panelTypes[ i ].value = QString("%1").arg(inst->id()); if (inst->id() == KrViewFactory::defaultViewId()) defType = QString("%1").arg(inst->id()); } cmb = createComboBox("Look&Feel", "Default Panel Type", defType, panelTypes, viewsSize, panelGrp, false, false, PAGE_VIEW); hbox->addWidget(cmb); hbox->addWidget(createSpacer(panelGrp)); delete [] panelTypes; panelGrid->addLayout(hbox, 0, 0); // ----- Individual Settings Per View Type ------------------------ QTabWidget *tabs_view = new QTabWidget(panelGrp); panelGrid->addWidget(tabs_view, 11, 0); for(int i = 0; i < views.count(); i++) { QWidget *tab = new QWidget(tabs_view); tabs_view->addTab(tab, views[i]->description()); setupView(views[i], tab); } } // ----------------------------------------------------------------------------------- // -------------------------- Panel Toolbar TAB ---------------------------------- // ----------------------------------------------------------------------------------- void KgPanel::setupButtonsTab() { QScrollArea *scrollArea = new QScrollArea(tabWidget); QWidget *tab = new QWidget(scrollArea); scrollArea->setFrameStyle(QFrame::NoFrame); scrollArea->setWidget(tab); scrollArea->setWidgetResizable(true); tabWidget->addTab(scrollArea, i18n("Buttons")); QBoxLayout * tabLayout = new QVBoxLayout(tab); tabLayout->setSpacing(6); tabLayout->setContentsMargins(11, 11, 11, 11); KONFIGURATOR_CHECKBOX_PARAM buttonsParams[] = // cfg_class cfg_name default text restart tooltip { {"ListPanelButtons", "Icons", false, i18n("Toolbar buttons have icons"), true, "" }, {"Look&Feel", "Media Button Visible", true, i18n("Show Media Button"), true , i18n("The media button will be visible.") }, {"Look&Feel", "Back Button Visible", false, i18n("Show Back Button"), true , "Goes back in history." }, {"Look&Feel", "Forward Button Visible", false, i18n("Show Forward Button"), true , "Goes forward in history." }, {"Look&Feel", "History Button Visible", true, i18n("Show History Button"), true , i18n("The history button will be visible.") }, {"Look&Feel", "Bookmarks Button Visible", true, i18n("Show Bookmarks Button"), true , i18n("The bookmarks button will be visible.") }, {"Look&Feel", "Panel Toolbar visible", _PanelToolBar, i18n("Show Panel Toolbar"), true, i18n("The panel toolbar will be visible.") }, }; buttonsCheckboxes = createCheckBoxGroup(1, 0, buttonsParams, 7/*count*/, tab, PAGE_PANELTOOLBAR); - connect(buttonsCheckboxes->find("Panel Toolbar visible"), SIGNAL(stateChanged(int)), this, SLOT(slotEnablePanelToolbar())); + connect(buttonsCheckboxes->find("Panel Toolbar visible"), &KonfiguratorCheckBox::stateChanged, this, &KgPanel::slotEnablePanelToolbar); tabLayout->addWidget(buttonsCheckboxes, 0, 0); QGroupBox * panelToolbarGrp = createFrame(i18n("Visible Panel Toolbar buttons"), tab); QGridLayout * panelToolbarGrid = createGridLayout(panelToolbarGrp); KONFIGURATOR_CHECKBOX_PARAM panelToolbarButtonsParams[] = { // cfg_class cfg_name default text restart tooltip {"Look&Feel", "Equal Button Visible", _cdOther, i18n("Equal button (=)"), true , i18n("Changes the panel folder to the other panel folder.") }, {"Look&Feel", "Up Button Visible", _cdUp, i18n("Up button (..)"), true , i18n("Changes the panel folder to the parent folder.") }, {"Look&Feel", "Home Button Visible", _cdHome, i18n("Home button (~)"), true , i18n("Changes the panel folder to the home folder.") }, {"Look&Feel", "Root Button Visible", _cdRoot, i18n("Root button (/)"), true , i18n("Changes the panel folder to the root folder.") }, {"Look&Feel", "SyncBrowse Button Visible", _syncBrowseButton, i18n("Toggle-button for sync-browsing"), true , i18n("Each folder change in the panel is also performed in the other panel.") }, }; panelToolbarButtonsCheckboxes = createCheckBoxGroup(1, 0, panelToolbarButtonsParams, sizeof(panelToolbarButtonsParams) / sizeof(*panelToolbarButtonsParams), panelToolbarGrp, PAGE_PANELTOOLBAR); panelToolbarGrid->addWidget(panelToolbarButtonsCheckboxes, 0, 0); tabLayout->addWidget(panelToolbarGrp, 1, 0); // Enable panel toolbar checkboxes slotEnablePanelToolbar(); } // --------------------------------------------------------------------------- // -------------------------- Mouse TAB ---------------------------------- // --------------------------------------------------------------------------- void KgPanel::setupMouseModeTab() { QScrollArea *scrollArea = new QScrollArea(tabWidget); QWidget *tab_mouse = new QWidget(scrollArea); scrollArea->setFrameStyle(QFrame::NoFrame); scrollArea->setWidget(tab_mouse); scrollArea->setWidgetResizable(true); tabWidget->addTab(scrollArea, i18n("Selection Mode")); QGridLayout *mouseLayout = new QGridLayout(tab_mouse); mouseLayout->setSpacing(6); mouseLayout->setContentsMargins(11, 11, 11, 11); // -------------- General ----------------- QGroupBox *mouseGeneralGroup = createFrame(i18n("General"), tab_mouse); QGridLayout *mouseGeneralGrid = createGridLayout(mouseGeneralGroup); mouseGeneralGrid->setSpacing(0); mouseGeneralGrid->setContentsMargins(5, 5, 5, 5); KONFIGURATOR_NAME_VALUE_TIP mouseSelection[] = { // name value tooltip { i18n("Krusader Mode"), "0", i18n("Both keys allow selecting files. To select more than one file, hold the Ctrl key and click the left mouse button. Right-click menu is invoked using a short click on the right mouse button.") }, { i18n("Konqueror Mode"), "1", i18n("Pressing the left mouse button selects files - you can click and select multiple files. Right-click menu is invoked using a short click on the right mouse button.") }, { i18n("Total-Commander Mode"), "2", i18n("The left mouse button does not select, but sets the current file without affecting the current selection. The right mouse button selects multiple files and the right-click menu is invoked by pressing and holding the right mouse button.") }, { i18n("Ergonomic Mode"), "4", i18n("The left mouse button does not select, but sets the current file without affecting the current selection. The right mouse button invokes the context-menu. You can select with Ctrl key and the left button.") }, { i18n("Custom Selection Mode"), "3", i18n("Design your own selection mode.") } }; mouseRadio = createRadioButtonGroup("Look&Feel", "Mouse Selection", "0", 1, 5, mouseSelection, 5, mouseGeneralGroup, true, PAGE_MOUSE); mouseRadio->layout()->setContentsMargins(0, 0, 0, 0); mouseGeneralGrid->addWidget(mouseRadio, 0, 0); for (int i = 0; i != mouseRadio->count(); i++) - connect(mouseRadio->find(i), SIGNAL(clicked()), SLOT(slotSelectionModeChanged())); + connect(mouseRadio->find(i), &QRadioButton::clicked, this, &KgPanel::slotSelectionModeChanged); mouseLayout->addWidget(mouseGeneralGroup, 0, 0); // -------------- Details ----------------- QGroupBox *mouseDetailGroup = createFrame(i18n("Details"), tab_mouse); QGridLayout *mouseDetailGrid = createGridLayout(mouseDetailGroup); mouseDetailGrid->setSpacing(0); mouseDetailGrid->setContentsMargins(5, 5, 5, 5); KONFIGURATOR_NAME_VALUE_TIP singleOrDoubleClick[] = { // name value tooltip { i18n("Double-click selects (classic)"), "0", i18n("A single click on a file will select and focus, a double click opens the file or steps into the folder.") }, { i18n("Obey global selection policy"), "1", i18n("

Use global setting:

Plasma System Settings -> Input Devices -> Mouse

") } }; KonfiguratorRadioButtons *clickRadio = createRadioButtonGroup("Look&Feel", "Single Click Selects", "0", 1, 0, singleOrDoubleClick, 2, mouseDetailGroup, true, PAGE_MOUSE); clickRadio->layout()->setContentsMargins(0, 0, 0, 0); mouseDetailGrid->addWidget(clickRadio, 0, 0); KONFIGURATOR_CHECKBOX_PARAM mouseCheckboxesParam[] = { // {cfg_class, cfg_name, default // text, restart, // tooltip } {"Custom Selection Mode", "QT Selection", _QtSelection, i18n("Based on KDE's selection mode"), true, i18n("If checked, use a mode based on KDE's style.") }, {"Custom Selection Mode", "Left Selects", _LeftSelects, i18n("Left mouse button selects"), true, i18n("If checked, left clicking an item will select it.") }, {"Custom Selection Mode", "Left Preserves", _LeftPreserves, i18n("Left mouse button preserves selection"), true, i18n("If checked, left clicking an item will select it, but will not unselect other, already selected items.") }, {"Custom Selection Mode", "ShiftCtrl Left Selects", _ShiftCtrlLeft, i18n("Shift/Ctrl-Left mouse button selects"), true, i18n("If checked, Shift/Ctrl left clicking will select items.\nNote: this is meaningless if 'Left Button Selects' is checked.") }, {"Custom Selection Mode", "Right Selects", _RightSelects, i18n("Right mouse button selects"), true, i18n("If checked, right clicking an item will select it.") }, {"Custom Selection Mode", "Right Preserves", _RightPreserves, i18n("Right mouse button preserves selection"), true, i18n("If checked, right clicking an item will select it, but will not unselect other, already selected items.") }, {"Custom Selection Mode", "ShiftCtrl Right Selects", _ShiftCtrlRight, i18n("Shift/Ctrl-Right mouse button selects"), true, i18n("If checked, Shift/Ctrl right clicking will select items.\nNote: this is meaningless if 'Right Button Selects' is checked.") }, {"Custom Selection Mode", "Space Moves Down", _SpaceMovesDown, i18n("Spacebar moves down"), true, i18n("If checked, pressing the spacebar will select the current item and move down.\nOtherwise, current item is selected, but remains the current item.") }, {"Custom Selection Mode", "Space Calc Space", _SpaceCalcSpace, i18n("Spacebar calculates disk space"), true, i18n("If checked, pressing the spacebar while the current item is a folder, will (except from selecting the folder)\ncalculate space occupied of the folder (recursively).") }, {"Custom Selection Mode", "Insert Moves Down", _InsertMovesDown, i18n("Insert moves down"), true, i18n("If checked, pressing Insert will select the current item, and move down to the next item.\nOtherwise, current item is not changed.") }, {"Custom Selection Mode", "Immediate Context Menu", _ImmediateContextMenu, i18n("Right clicking pops context menu immediately"), true, i18n("If checked, right clicking will result in an immediate showing of the context menu.\nOtherwise, user needs to click and hold the right mouse button for 500ms.") }, }; mouseCheckboxes = createCheckBoxGroup(1, 0, mouseCheckboxesParam, 11 /*count*/, mouseDetailGroup, PAGE_MOUSE); mouseDetailGrid->addWidget(mouseCheckboxes, 1, 0); for (int i = 0; i < mouseCheckboxes->count(); i++) - connect(mouseCheckboxes->find(i), SIGNAL(clicked()), SLOT(slotMouseCheckBoxChanged())); + connect(mouseCheckboxes->find(i), &KonfiguratorCheckBox::clicked, this, &KgPanel::slotMouseCheckBoxChanged); mouseLayout->addWidget(mouseDetailGroup, 0, 1, 2, 1); // Disable the details-button if not in custom-mode slotSelectionModeChanged(); // -------------- Preview ----------------- QGroupBox *mousePreviewGroup = createFrame(i18n("Preview"), tab_mouse); QGridLayout *mousePreviewGrid = createGridLayout(mousePreviewGroup); // TODO preview mousePreview = new KrTreeWidget(mousePreviewGroup); mousePreviewGrid->addWidget(mousePreview, 0 , 0); mousePreviewGroup->setEnabled(false); // TODO re-enable once the preview is implemented // ------------------------------------------ mouseLayout->addWidget(mousePreviewGroup, 1, 0); } // --------------------------------------------------------------------------- // -------------------------- Media Menu TAB ---------------------------------- // --------------------------------------------------------------------------- void KgPanel::setupMediaMenuTab() { QScrollArea *scrollArea = new QScrollArea(tabWidget); QWidget *tab = new QWidget(scrollArea); scrollArea->setFrameStyle(QFrame::NoFrame); scrollArea->setWidget(tab); scrollArea->setWidgetResizable(true); tabWidget->addTab(scrollArea, i18n("Media Menu")); QBoxLayout * tabLayout = new QVBoxLayout(tab); tabLayout->setSpacing(6); tabLayout->setContentsMargins(11, 11, 11, 11); KONFIGURATOR_CHECKBOX_PARAM mediaMenuParams[] = { // cfg_class cfg_name default text restart tooltip {"MediaMenu", "ShowPath", true, i18n("Show Mount Path"), false, 0 }, {"MediaMenu", "ShowFSType", true, i18n("Show File System Type"), false, 0 }, }; KonfiguratorCheckBoxGroup *mediaMenuCheckBoxes = createCheckBoxGroup(1, 0, mediaMenuParams, sizeof(mediaMenuParams) / sizeof(*mediaMenuParams), tab, PAGE_MEDIA_MENU); tabLayout->addWidget(mediaMenuCheckBoxes, 0, 0); QHBoxLayout *showSizeHBox = new QHBoxLayout(); showSizeHBox->addWidget(new QLabel(i18n("Show Size:"), tab)); KONFIGURATOR_NAME_VALUE_PAIR showSizeValues[] = { { i18nc("setting 'show size'", "Always"), "Always" }, { i18nc("setting 'show size'", "When Device has no Label"), "WhenNoLabel" }, { i18nc("setting 'show size'", "Never"), "Never" }, }; KonfiguratorComboBox *showSizeCmb = createComboBox("MediaMenu", "ShowSize", "Always", showSizeValues, sizeof(showSizeValues) / sizeof(*showSizeValues), tab, false, false, PAGE_MEDIA_MENU); showSizeHBox->addWidget(showSizeCmb); showSizeHBox->addStretch(); tabLayout->addLayout(showSizeHBox); tabLayout->addStretch(); } void KgPanel::slotEnablePanelToolbar() { bool enableTB = buttonsCheckboxes->find("Panel Toolbar visible")->isChecked(); panelToolbarButtonsCheckboxes->find("Root Button Visible")->setEnabled(enableTB); panelToolbarButtonsCheckboxes->find("Home Button Visible")->setEnabled(enableTB); panelToolbarButtonsCheckboxes->find("Up Button Visible")->setEnabled(enableTB); panelToolbarButtonsCheckboxes->find("Equal Button Visible")->setEnabled(enableTB); panelToolbarButtonsCheckboxes->find("SyncBrowse Button Visible")->setEnabled(enableTB); } void KgPanel::slotSelectionModeChanged() { KrSelectionMode *selectionMode = KrSelectionMode::getSelectionHandlerForMode(mouseRadio->selectedValue()); if (selectionMode == NULL) //User mode return; selectionMode->init(); mouseCheckboxes->find("QT Selection")->setChecked(selectionMode->useQTSelection()); mouseCheckboxes->find("Left Selects")->setChecked(selectionMode->leftButtonSelects()); mouseCheckboxes->find("Left Preserves")->setChecked(selectionMode->leftButtonPreservesSelection()); mouseCheckboxes->find("ShiftCtrl Left Selects")->setChecked(selectionMode->shiftCtrlLeftButtonSelects()); mouseCheckboxes->find("Right Selects")->setChecked(selectionMode->rightButtonSelects()); mouseCheckboxes->find("Right Preserves")->setChecked(selectionMode->rightButtonPreservesSelection()); mouseCheckboxes->find("ShiftCtrl Right Selects")->setChecked(selectionMode->shiftCtrlRightButtonSelects()); mouseCheckboxes->find("Space Moves Down")->setChecked(selectionMode->spaceMovesDown()); mouseCheckboxes->find("Space Calc Space")->setChecked(selectionMode->spaceCalculatesDiskSpace()); mouseCheckboxes->find("Insert Moves Down")->setChecked(selectionMode->insertMovesDown()); mouseCheckboxes->find("Immediate Context Menu")->setChecked(selectionMode->showContextMenu() == -1); } void KgPanel::slotMouseCheckBoxChanged() { mouseRadio->selectButton("3"); //custom selection mode } int KgPanel::activeSubPage() { return tabWidget->currentIndex(); } diff --git a/krusader/Konfigurator/kgprotocols.cpp b/krusader/Konfigurator/kgprotocols.cpp index 51fd57b7..bd4abd58 100644 --- a/krusader/Konfigurator/kgprotocols.cpp +++ b/krusader/Konfigurator/kgprotocols.cpp @@ -1,389 +1,389 @@ /***************************************************************************** * 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 "kgprotocols.h" #include "../krglobal.h" #include "../icon.h" #include "../krservices.h" // QtCore #include #include // QtWidgets #include #include #include #include #include #include KgProtocols::KgProtocols(bool first, QWidget* parent) : KonfiguratorPage(first, parent) { QGridLayout *KgProtocolsLayout = new QGridLayout(this); KgProtocolsLayout->setSpacing(6); // -------------------------- LINK VIEW ---------------------------------- QGroupBox *linkGrp = createFrame(i18n("Links"), this); QGridLayout *linkGrid = createGridLayout(linkGrp); QStringList labels; labels << i18n("Defined Links"); linkList = new KrTreeWidget(linkGrp); linkList->setHeaderLabels(labels); linkList->setRootIsDecorated(true); linkGrid->addWidget(linkList, 0, 0); KgProtocolsLayout->addWidget(linkGrp, 0, 0, 2, 1); // -------------------------- BUTTONS ---------------------------------- QWidget *vbox1Widget = new QWidget(this); QVBoxLayout *vbox1 = new QVBoxLayout(vbox1Widget); addSpacer(vbox1); btnAddProtocol = new QPushButton(vbox1Widget); btnAddProtocol->setIcon(Icon("arrow-left")); btnAddProtocol->setWhatsThis(i18n("Add protocol to the link list.")); vbox1->addWidget(btnAddProtocol); btnRemoveProtocol = new QPushButton(vbox1Widget); btnRemoveProtocol->setIcon(Icon("arrow-right")); btnRemoveProtocol->setWhatsThis(i18n("Remove protocol from the link list.")); vbox1->addWidget(btnRemoveProtocol); addSpacer(vbox1); KgProtocolsLayout->addWidget(vbox1Widget, 0 , 1); QWidget *vbox2Widget = new QWidget(this); QVBoxLayout *vbox2 = new QVBoxLayout(vbox2Widget); addSpacer(vbox2); btnAddMime = new QPushButton(vbox2Widget); btnAddMime->setIcon(Icon("arrow-left")); btnAddMime->setWhatsThis(i18n("Add MIME to the selected protocol on the link list.")); vbox2->addWidget(btnAddMime); btnRemoveMime = new QPushButton(vbox2Widget); btnRemoveMime->setIcon(Icon("arrow-right")); btnRemoveMime->setWhatsThis(i18n("Remove MIME from the link list.")); vbox2->addWidget(btnRemoveMime); addSpacer(vbox2); KgProtocolsLayout->addWidget(vbox2Widget, 1 , 1); // -------------------------- PROTOCOLS LISTBOX ---------------------------------- QGroupBox *protocolGrp = createFrame(i18n("Protocols"), this); QGridLayout *protocolGrid = createGridLayout(protocolGrp); protocolList = new KrListWidget(protocolGrp); loadProtocols(); protocolGrid->addWidget(protocolList, 0, 0); KgProtocolsLayout->addWidget(protocolGrp, 0 , 2); // -------------------------- MIMES LISTBOX ---------------------------------- QGroupBox *mimeGrp = createFrame(i18n("MIMEs"), this); QGridLayout *mimeGrid = createGridLayout(mimeGrp); mimeList = new KrListWidget(mimeGrp); loadMimes(); mimeGrid->addWidget(mimeList, 0, 0); KgProtocolsLayout->addWidget(mimeGrp, 1 , 2); // -------------------------- CONNECT TABLE ---------------------------------- - connect(protocolList, SIGNAL(itemSelectionChanged()), this, SLOT(slotDisableButtons())); - connect(linkList, SIGNAL(itemSelectionChanged()), this, SLOT(slotDisableButtons())); - connect(mimeList, SIGNAL(itemSelectionChanged()), this, SLOT(slotDisableButtons())); - connect(linkList, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(slotDisableButtons())); - connect(btnAddProtocol, SIGNAL(clicked()) , this, SLOT(slotAddProtocol())); - connect(btnRemoveProtocol, SIGNAL(clicked()) , this, SLOT(slotRemoveProtocol())); - connect(btnAddMime, SIGNAL(clicked()) , this, SLOT(slotAddMime())); - connect(btnRemoveMime, SIGNAL(clicked()) , this, SLOT(slotRemoveMime())); + connect(protocolList, &KrListWidget::itemSelectionChanged, this, &KgProtocols::slotDisableButtons); + connect(linkList, &KrTreeWidget::itemSelectionChanged, this, &KgProtocols::slotDisableButtons); + connect(mimeList, &KrListWidget::itemSelectionChanged, this, &KgProtocols::slotDisableButtons); + connect(linkList, &KrTreeWidget::currentItemChanged , this, &KgProtocols::slotDisableButtons); + connect(btnAddProtocol, &QPushButton::clicked , this, &KgProtocols::slotAddProtocol); + connect(btnRemoveProtocol, &QPushButton::clicked , this, &KgProtocols::slotRemoveProtocol); + connect(btnAddMime, &QPushButton::clicked , this, &KgProtocols::slotAddMime); + connect(btnRemoveMime, &QPushButton::clicked , this, &KgProtocols::slotRemoveMime); loadInitialValues(); slotDisableButtons(); } void KgProtocols::addSpacer(QBoxLayout *layout) { layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding)); } void KgProtocols::loadProtocols() { QStringList protocols = KProtocolInfo::protocols(); protocols.sort(); foreach(const QString &protocol, protocols) { QUrl u; u.setScheme(protocol); if(KProtocolManager::inputType(u) == KProtocolInfo::T_FILESYSTEM) { protocolList->addItem(protocol); } } } void KgProtocols::loadMimes() { QMimeDatabase db; QList mimes = db.allMimeTypes(); for (QList::const_iterator it = mimes.constBegin(); it != mimes.constEnd(); ++it) mimeList->addItem((*it).name()); mimeList->sortItems(); } void KgProtocols::slotDisableButtons() { btnAddProtocol->setEnabled(protocolList->selectedItems().count() != 0); QTreeWidgetItem *listViewItem = linkList->currentItem(); bool isProtocolSelected = (listViewItem == 0 ? false : listViewItem->parent() == 0); btnRemoveProtocol->setEnabled(isProtocolSelected); btnAddMime->setEnabled(listViewItem != 0 && mimeList->selectedItems().count() != 0); btnRemoveMime->setEnabled(listViewItem == 0 ? false : listViewItem->parent() != 0); if (linkList->currentItem() == 0 && linkList->topLevelItemCount() != 0) linkList->setCurrentItem(linkList->topLevelItem(0)); QList list = linkList->selectedItems(); if (list.count() == 0 && linkList->currentItem() != 0) linkList->currentItem()->setSelected(true); } void KgProtocols::slotAddProtocol() { QList list = protocolList->selectedItems(); if (list.count() > 0) { addProtocol(list[ 0 ]->text(), true); slotDisableButtons(); emit sigChanged(); } } void KgProtocols::addProtocol(QString name, bool changeCurrent) { QList list = protocolList->findItems(name, Qt::MatchExactly); if (list.count() > 0) { delete list[ 0 ]; QTreeWidgetItem *listViewItem = new QTreeWidgetItem(linkList); listViewItem->setText(0, name); QString iconName = KProtocolInfo::icon(name); if (iconName.isEmpty()) iconName = "go-next-view"; listViewItem->setIcon(0, Icon(iconName)); if (changeCurrent) linkList->setCurrentItem(listViewItem); } } void KgProtocols::slotRemoveProtocol() { QTreeWidgetItem *item = linkList->currentItem(); if (item) { removeProtocol(item->text(0)); slotDisableButtons(); emit sigChanged(); } } void KgProtocols::removeProtocol(QString name) { QList itemList = linkList->findItems(name, Qt::MatchExactly, 0); if (itemList.count()) { QTreeWidgetItem *item = itemList[ 0 ]; while (item->childCount() != 0) removeMime(item->child(0)->text(0)); linkList->takeTopLevelItem(linkList->indexOfTopLevelItem(item)); protocolList->addItem(name); protocolList->sortItems(); } } void KgProtocols::slotAddMime() { QList list = mimeList->selectedItems(); if (list.count() > 0 && linkList->currentItem() != 0) { QTreeWidgetItem *itemToAdd = linkList->currentItem(); if (itemToAdd->parent()) itemToAdd = itemToAdd->parent(); addMime(list[ 0 ]->text(), itemToAdd->text(0)); slotDisableButtons(); emit sigChanged(); } } void KgProtocols::addMime(QString name, QString protocol) { QList list = mimeList->findItems(name, Qt::MatchExactly); QList itemList = linkList->findItems(protocol, Qt::MatchExactly | Qt::MatchRecursive, 0); QTreeWidgetItem *currentListItem = 0; if (itemList.count() != 0) currentListItem = itemList[ 0 ]; if (list.count() > 0 && currentListItem && currentListItem->parent() == 0) { delete list[ 0 ]; QTreeWidgetItem *listViewItem = new QTreeWidgetItem(currentListItem); listViewItem->setText(0, name); listViewItem->setIcon(0, Icon(name.replace(QLatin1Char('/'), QLatin1Char('-')), Icon("unknown"))); linkList->expandItem( currentListItem ); } } void KgProtocols::slotRemoveMime() { QTreeWidgetItem *item = linkList->currentItem(); if (item) { removeMime(item->text(0)); slotDisableButtons(); emit sigChanged(); } } void KgProtocols::removeMime(QString name) { QList itemList = linkList->findItems(name, Qt::MatchExactly | Qt::MatchRecursive, 0); QTreeWidgetItem *currentMimeItem = 0; if (itemList.count() != 0) currentMimeItem = itemList[ 0 ]; if (currentMimeItem && currentMimeItem->parent() != 0) { mimeList->addItem(currentMimeItem->text(0)); mimeList->sortItems(); currentMimeItem->parent()->removeChild(currentMimeItem); } } void KgProtocols::loadInitialValues() { if (linkList->model()->rowCount() > 0) while (linkList->topLevelItemCount() != 0) removeProtocol(linkList->topLevelItem(0)->text(0)); KConfigGroup group(krConfig, "Protocols"); QStringList protList = group.readEntry("Handled Protocols", QStringList()); for (QStringList::Iterator it = protList.begin(); it != protList.end(); ++it) { addProtocol(*it); QStringList mimes = group.readEntry(QString("Mimes For %1").arg(*it), QStringList()); for (QStringList::Iterator it2 = mimes.begin(); it2 != mimes.end(); ++it2) addMime(*it2, *it); } if (linkList->topLevelItemCount() != 0) linkList->setCurrentItem(linkList->topLevelItem(0)); slotDisableButtons(); linkList->expandAll(); emit sigChanged(); } void KgProtocols::setDefaults() { while (linkList->topLevelItemCount() != 0) removeProtocol(linkList->topLevelItem(0)->text(0)); slotDisableButtons(); if (isChanged()) emit sigChanged(); } bool KgProtocols::isChanged() { KConfigGroup group(krConfig, "Protocols"); QStringList protList = group.readEntry("Handled Protocols", QStringList()); if ((int)protList.count() != linkList->topLevelItemCount()) return true; for (int i = 0; i != linkList->topLevelItemCount(); i++) { QTreeWidgetItem *item = linkList->topLevelItem(i); if (!protList.contains(item->text(0))) return true; QStringList mimes = group.readEntry(QString("Mimes For %1").arg(item->text(0)), QStringList()); if ((int)mimes.count() != item->childCount()) return true; for (int j = 0; j != item->childCount(); j++) { QTreeWidgetItem *children = item->child(j); if (!mimes.contains(children->text(0))) return true; } } return false; } bool KgProtocols::apply() { KConfigGroup group(krConfig, "Protocols"); QStringList protocolList; for (int i = 0; i != linkList->topLevelItemCount(); i++) { QTreeWidgetItem *item = linkList->topLevelItem(i); protocolList.append(item->text(0)); QStringList mimes; for (int j = 0; j != item->childCount(); j++) { QTreeWidgetItem *children = item->child(j); mimes.append(children->text(0)); } group.writeEntry(QString("Mimes For %1").arg(item->text(0)), mimes); } group.writeEntry("Handled Protocols", protocolList); krConfig->sync(); KrServices::clearProtocolCache(); emit sigChanged(); return false; } void KgProtocols::init() { } diff --git a/krusader/Konfigurator/kgstartup.cpp b/krusader/Konfigurator/kgstartup.cpp index 320c20e5..d5905e61 100644 --- a/krusader/Konfigurator/kgstartup.cpp +++ b/krusader/Konfigurator/kgstartup.cpp @@ -1,140 +1,140 @@ /***************************************************************************** * 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 "kgstartup.h" #include "../defaults.h" #include "../GUI/profilemanager.h" // QtWidgets #include #include #include #include KgStartup::KgStartup(bool first, QWidget* parent) : KonfiguratorPage(first, parent), profileCombo(0) { QWidget *innerWidget = new QFrame(this); setWidget(innerWidget); setWidgetResizable(true); QGridLayout *kgStartupLayout = new QGridLayout(innerWidget); kgStartupLayout->setSpacing(6); // --------------------------- PANELS GROUPBOX ---------------------------------- QGroupBox *panelsGrp = createFrame(i18n("General"), innerWidget); QGridLayout *panelsGrid = createGridLayout(panelsGrp); QString s = "

" + i18n("Defines the panel profile used at startup. A panel profile contains:
  • all the tabs paths
  • the current tab
  • the active panel
<Last session> is a special panel profile which is saved automatically when Krusader is closed."); QLabel *label = addLabel(panelsGrid, 0, 0, i18n("Startup profile:"), panelsGrp); label->setWhatsThis(s); panelsGrp->setWhatsThis(s); QStringList profileList = ProfileManager::availableProfiles("Panel"); profileList.push_front(i18n("")); const int profileListSize = profileList.size(); KONFIGURATOR_NAME_VALUE_PAIR *comboItems = new KONFIGURATOR_NAME_VALUE_PAIR[ profileListSize ]; for (int i = 0; i != profileListSize; i++) comboItems[ i ].text = comboItems[ i ].value = profileList [ i ]; comboItems[ 0 ].value = ""; profileCombo = createComboBox("Startup", "Starter Profile Name", comboItems[ 0 ].value, comboItems, profileListSize, panelsGrp, false, false); profileCombo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); panelsGrid->addWidget(profileCombo, 0, 1); delete [] comboItems; //------------------------------------------------ panelsGrid->addWidget(createLine(panelsGrp), 1, 0, 1, 2); KONFIGURATOR_CHECKBOX_PARAM settings[] = { // cfg_class cfg_name default text restart tooltip {"Look&Feel", "Show splashscreen", _ShowSplashScreen, i18n("Show splashscreen"), false, i18n("Display a splashscreen when starting Krusader.") }, {"Look&Feel", "Single Instance Mode", _SingleInstanceMode, i18n("Single instance mode"), false, i18n("Only one Krusader instance is allowed to run.") } }; KonfiguratorCheckBoxGroup* cbs = createCheckBoxGroup(2, 0, settings, 2 /* settings count */, panelsGrp); panelsGrid->addWidget(cbs, 2, 0, 1, 2); QHBoxLayout *iconThemeLayout = new QHBoxLayout(); QLabel *iconThemeLabel = new QLabel(i18n("Fallback Icon Theme:")); iconThemeLabel->setWhatsThis(i18n("Whenever icon is not found in system icon theme, " "this theme will be used as a fallback. " "If fallback theme doesn't contain the icon, " "Breeze or Oxygen will be used if any of these are present.")); iconThemeLayout->addWidget(iconThemeLabel); KonfiguratorEditBox *iconThemeEditBox = createEditBox("Startup", "Fallback Icon Theme", "", panelsGrp, true); iconThemeLayout->addWidget(iconThemeEditBox); iconThemeLayout->addStretch(1); panelsGrid->addLayout(iconThemeLayout, 3, 0, 1, 2); kgStartupLayout->addWidget(panelsGrp, 0, 0); // ------------------------ USERINTERFACE GROUPBOX ------------------------------ QGroupBox *uiGrp = createFrame(i18n("User Interface"), innerWidget); QGridLayout *uiGrid = createGridLayout(uiGrp); KONFIGURATOR_CHECKBOX_PARAM uiSettings[] = { // cfg_class cfg_name default text restart tooltip {"Startup", "Remember Position", _RememberPos,i18n("Save last position, size and panel settings"), false, i18n("

At startup, the main window will resize itself to the size it was when last shutdown. " "It will also appear in the same location of the screen, having panels sorted and aligned as they were before.

" "

If this option is disabled, you can use the menu Window -> Save Position option " "to manually set the main window's size and position at startup.

") }, {"Startup", "Update Default Panel Settings", _RememberPos, i18n("Update default panel settings"), true, i18n("When settings of a panel are changed, save them as the default for new panels of the same type.") }, {"Startup", "Start To Tray", _StartToTray, i18n("Start to tray"), false, i18n("Krusader starts to tray, without showing the main window") }, }; KonfiguratorCheckBoxGroup *uiSettingsGroup = createCheckBoxGroup(1, 0, uiSettings, 3, uiGrp); uiGrid->addWidget(uiSettingsGroup, 1, 0); KONFIGURATOR_CHECKBOX_PARAM uiCheckBoxes[] = { // cfg_class, cfg_name, default, text, restart, ToolTip {"Startup", "UI Save Settings", _UiSave, i18n("Save component settings on exit"), false, i18n("Check the state of the user interface components and restore them to their condition when last shutdown.") }, {"Startup", "Show FN Keys", _ShowFNkeys, i18n("Show function keys"), false, i18n("Function keys will be visible after startup.") }, {"Startup", "Show Cmd Line", _ShowCmdline, i18n("Show command line"), false, i18n("Command line will be visible after startup.") }, {"Startup", "Show Terminal Emulator", _ShowTerminalEmulator, i18n("Show embedded terminal"), false, i18n("Embedded terminal will be visible after startup.") }, }; uiCbGroup = createCheckBoxGroup(1, 0, uiCheckBoxes, 4, uiGrp); - connect(uiCbGroup->find("UI Save Settings"), SIGNAL(stateChanged(int)), this, SLOT(slotDisable())); + connect(uiCbGroup->find("UI Save Settings"), &KonfiguratorCheckBox::stateChanged, this, &KgStartup::slotDisable); uiGrid->addWidget(uiCbGroup, 2, 0); slotDisable(); kgStartupLayout->addWidget(uiGrp, 1, 0); } void KgStartup::slotDisable() { bool isUiSave = !uiCbGroup->find("UI Save Settings")->isChecked(); int i = 1; while (uiCbGroup->find(i)) uiCbGroup->find(i++)->setEnabled(isUiSave); } diff --git a/krusader/Konfigurator/kguseractions.cpp b/krusader/Konfigurator/kguseractions.cpp index 9197e49b..8bd372bc 100644 --- a/krusader/Konfigurator/kguseractions.cpp +++ b/krusader/Konfigurator/kguseractions.cpp @@ -1,114 +1,114 @@ /***************************************************************************** * 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 "kguseractions.h" #include "../defaults.h" #include "../ActionMan/actionman.h" // QtWidgets #include #include #include #include KgUserActions::KgUserActions(bool first, QWidget* parent) : KonfiguratorPage(first, parent) { QWidget *innerWidget = new QFrame(this); setWidget(innerWidget); setWidgetResizable(true); QGridLayout *kgUserActionLayout = new QGridLayout(innerWidget); // ============= Info Group ============= QGroupBox *InfoGroup = createFrame(i18n("Information"), innerWidget); QGridLayout *InfoGrid = createGridLayout(InfoGroup); // terminal for the UserActions QLabel *labelInfo = new QLabel(i18n( "Here you can configure settings about useractions.\n" "To set up, configure and manage your useractions please use ActionMan." ), InfoGroup); InfoGrid->addWidget(labelInfo, 0, 0); QPushButton *actionmanButton = new QPushButton(i18n("Start ActionMan"), InfoGroup); - connect(actionmanButton, SIGNAL(clicked()), SLOT(startActionMan())); + connect(actionmanButton, &QPushButton::clicked, this, &KgUserActions::startActionMan); InfoGrid->addWidget(actionmanButton, 1, 0); kgUserActionLayout->addWidget(InfoGroup, 0 , 0); // ============= Terminal Group ============= QGroupBox *terminalGroup = createFrame(i18n("Terminal execution"), innerWidget); QGridLayout *terminalGrid = createGridLayout(terminalGroup); // terminal for the UserActions QLabel *labelTerminal = new QLabel(i18n("Terminal for UserActions:"), terminalGroup); terminalGrid->addWidget(labelTerminal, 0, 0); KonfiguratorURLRequester *urlReqUserActions = createURLRequester("UserActions", "Terminal", _UserActions_Terminal, terminalGroup, false, FIRST_PAGE, false); terminalGrid->addWidget(urlReqUserActions, 0, 1); labelTerminal = new QLabel(i18n("%t will be replaced by the title of the action,\n%d with the workdir."), terminalGroup); terminalGrid->addWidget(labelTerminal, 1, 1); kgUserActionLayout->addWidget(terminalGroup, 1 , 0); // ============= Outputcollection Group ============= QGroupBox *outputGroup = createFrame(i18n("Output collection"), innerWidget); QGridLayout *outputGrid = createGridLayout(outputGroup); QWidget *hboxWidget = new QWidget(outputGroup); QHBoxLayout *hbox = new QHBoxLayout(hboxWidget); QLabel *lbel = new QLabel(i18n("Normal font:"), hboxWidget); hbox->addWidget(lbel); KonfiguratorFontChooser *chser = createFontChooser("UserActions", "Normal Font", _UserActions_NormalFont, hboxWidget); hbox->addWidget(chser); QWidget *spcer = createSpacer(hboxWidget); hbox->addWidget(spcer); outputGrid->addWidget(hboxWidget, 2, 0); hboxWidget = new QWidget(outputGroup); hbox = new QHBoxLayout(hboxWidget); lbel = new QLabel(i18n("Font with fixed width:"), hboxWidget); hbox->addWidget(lbel); chser = createFontChooser("UserActions", "Fixed Font", _UserActions_FixedFont, hboxWidget); hbox->addWidget(chser); spcer = createSpacer(hboxWidget); hbox->addWidget(spcer); outputGrid->addWidget(hboxWidget, 3, 0); KonfiguratorCheckBox *useFixed = createCheckBox("UserActions", "Use Fixed Font", _UserActions_UseFixedFont, i18n("Use fixed width font as default"), outputGroup); outputGrid->addWidget(useFixed, 4, 0); kgUserActionLayout->addWidget(outputGroup, 2 , 0); } void KgUserActions::startActionMan() { ActionMan actionMan(static_cast(this)); } diff --git a/krusader/Konfigurator/konfigurator.cpp b/krusader/Konfigurator/konfigurator.cpp index a2b7cb30..3862f044 100644 --- a/krusader/Konfigurator/konfigurator.cpp +++ b/krusader/Konfigurator/konfigurator.cpp @@ -1,241 +1,241 @@ /***************************************************************************** * 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 "konfigurator.h" #include "../krglobal.h" #include "../icon.h" #include "../Dialogs/krdialogs.h" // QtGui #include #include #include #include #include #include #include "../defaults.h" #include "../krusaderview.h" #include "../GUI/kfnkeys.h" // the frames #include "kgstartup.h" #include "kgpanel.h" #include "kggeneral.h" #include "kgadvanced.h" #include "kgarchives.h" #include "kgdependencies.h" #include "kgcolors.h" #include "kguseractions.h" #include "kgprotocols.h" Konfigurator::Konfigurator(bool f, int startPage) : KPageDialog((QWidget *)0), firstTime(f), internalCall(false), sizeX(-1), sizeY(-1) { setWindowTitle(i18n("Konfigurator - Creating Your Own Krusader")); setWindowModality(Qt::ApplicationModal); setFaceType(KPageDialog::List); setStandardButtons(QDialogButtonBox::Help|QDialogButtonBox::RestoreDefaults|QDialogButtonBox::Close| QDialogButtonBox::Apply|QDialogButtonBox::Reset); button(QDialogButtonBox::Apply)->setDefault(true); - connect(button(QDialogButtonBox::Close), SIGNAL(clicked()), SLOT(slotClose())); - connect(button(QDialogButtonBox::Help), SIGNAL(clicked()), SLOT(slotShowHelp())); - connect(button(QDialogButtonBox::RestoreDefaults), SIGNAL(clicked()), SLOT(slotRestoreDefaults())); - connect(button(QDialogButtonBox::Reset), SIGNAL(clicked()), SLOT(slotReset())); - connect(button(QDialogButtonBox::Apply), SIGNAL(clicked()), SLOT(slotApply())); - connect(this, SIGNAL(currentPageChanged(KPageWidgetItem*,KPageWidgetItem*)), this, SLOT(slotPageSwitch(KPageWidgetItem*,KPageWidgetItem*))); - connect(&restoreTimer, SIGNAL(timeout()), this, SLOT(slotRestorePage())); + connect(button(QDialogButtonBox::Close), &QPushButton::clicked, this, &Konfigurator::slotClose); + connect(button(QDialogButtonBox::Help), &QPushButton::clicked, this, &Konfigurator::slotShowHelp); + connect(button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked, this, &Konfigurator::slotRestoreDefaults); + connect(button(QDialogButtonBox::Reset), &QPushButton::clicked, this, &Konfigurator::slotReset); + connect(button(QDialogButtonBox::Apply), &QPushButton::clicked, this, &Konfigurator::slotApply); + connect(this, &Konfigurator::currentPageChanged, this, &Konfigurator::slotPageSwitch); + connect(&restoreTimer, &QTimer::timeout, this, &Konfigurator::slotRestorePage); createLayout(startPage); KConfigGroup group(krConfig, "Konfigurator"); int sx = group.readEntry("Window Width", -1); int sy = group.readEntry("Window Height", -1); if (sx != -1 && sy != -1) resize(sx, sy); else resize(900, 680); if (group.readEntry("Window Maximized", false)) showMaximized(); else show(); } void Konfigurator::resizeEvent(QResizeEvent *e) { if (!isMaximized()) { sizeX = e->size().width(); sizeY = e->size().height(); } QDialog::resizeEvent(e); } void Konfigurator::closeDialog() { KConfigGroup group(krConfig, "Konfigurator"); group.writeEntry("Window Width", sizeX); group.writeEntry("Window Height", sizeY); group.writeEntry("Window Maximized", isMaximized()); } void Konfigurator::reject() { closeDialog(); QDialog::reject(); } void Konfigurator::newPage(KonfiguratorPage *page, const QString &name, const QString &desc, const QIcon &icon) { KPageWidgetItem *item = new KPageWidgetItem(page, name); item->setIcon(icon); item->setHeader(desc); addPage(item); kgPages.append(item); - connect(page, SIGNAL(sigChanged()), this, SLOT(slotApplyEnable())); + connect(page, &KonfiguratorPage::sigChanged, this, &Konfigurator::slotApplyEnable); } void Konfigurator::createLayout(int startPage) { // startup newPage(new KgStartup(firstTime, this), i18n("Startup"), i18n("Krusader's settings upon startup"), Icon("go-home")); // panel newPage(new KgPanel(firstTime, this), i18n("Panel"), i18n("Panel"), Icon("view-choose")); // colors newPage(new KgColors(firstTime, this), i18n("Colors"), i18n("Colors"), Icon("color-picker")); // general newPage(new KgGeneral(firstTime, this), i18n("General"), i18n("Basic Operations"), Icon("system-run")); // advanced newPage(new KgAdvanced(firstTime, this), i18n("Advanced"), i18n("Be sure you know what you are doing."), Icon("dialog-messages")); // archives newPage(new KgArchives(firstTime, this), i18n("Archives"), i18n("Customize the way Krusader deals with archives"), Icon("archive-extract")); // dependencies newPage(new KgDependencies(firstTime, this), i18n("Dependencies"), i18n("Set the full path of the external applications"), Icon("debug-run")); // useractions newPage(new KgUserActions(firstTime, this), i18n("User Actions"), i18n("Configure your personal actions"), Icon("user-properties")); // protocols newPage(new KgProtocols(firstTime, this), i18n("Protocols"), i18n("Link MIMEs to protocols"), Icon("document-preview")); setCurrentPage(kgPages.at(startPage)); slotApplyEnable(); } void Konfigurator::closeEvent(QCloseEvent *event) { lastPage = currentPage(); if(slotPageSwitch(lastPage, lastPage)) { hide(); KPageDialog::closeEvent(event); } else event->ignore(); } void Konfigurator::slotApplyEnable() { lastPage = currentPage(); bool isChanged = ((KonfiguratorPage *)(lastPage->widget()))->isChanged(); button(QDialogButtonBox::Apply)->setEnabled(isChanged); button(QDialogButtonBox::Reset)->setEnabled(isChanged); } bool Konfigurator::slotPageSwitch(KPageWidgetItem *current, KPageWidgetItem *before) { if (before == 0) return true; KonfiguratorPage *currentPg = (KonfiguratorPage *)(before->widget()); if (internalCall) { internalCall = false; return true; } if (currentPg->isChanged()) { int result = KMessageBox::questionYesNoCancel(0, i18n("The current page has been changed. Do you want to apply changes?")); switch (result) { case KMessageBox::No: currentPg->loadInitialValues(); currentPg->apply(); break; case KMessageBox::Yes: emit configChanged(currentPg->apply()); break; default: restoreTimer.setSingleShot(true); restoreTimer.start(0); return false; } } button(QDialogButtonBox::Apply)->setEnabled(currentPg->isChanged()); lastPage = current; return true; } void Konfigurator::slotRestorePage() { if (lastPage != currentPage()) { internalCall = true; setCurrentPage(lastPage); } } void Konfigurator::slotClose() { lastPage = currentPage(); if (slotPageSwitch(lastPage, lastPage)) { reject(); } } void Konfigurator::slotApply() { emit configChanged(((KonfiguratorPage*)(currentPage()->widget()))->apply()); } void Konfigurator::slotReset() { ((KonfiguratorPage *)(currentPage()->widget()))->loadInitialValues(); } void Konfigurator::slotRestoreDefaults() { ((KonfiguratorPage *)(currentPage()->widget()))->setDefaults(); } void Konfigurator::slotShowHelp() { KHelpClient::invokeHelp(QStringLiteral("konfigurator")); } diff --git a/krusader/Konfigurator/konfiguratoritems.cpp b/krusader/Konfigurator/konfiguratoritems.cpp index 1cafc095..71d994e1 100644 --- a/krusader/Konfigurator/konfiguratoritems.cpp +++ b/krusader/Konfigurator/konfiguratoritems.cpp @@ -1,838 +1,836 @@ /***************************************************************************** * Copyright (C) 2003 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 "konfiguratoritems.h" #include "../krglobal.h" #include "../icon.h" // QtCore #include // QtGui #include #include #include // QtWidgets #include #include #include #include #include #include KonfiguratorExtension::KonfiguratorExtension(QObject *obj, QString cfgGroup, QString cfgName, bool restartNeeded, int page) : QObject(), objectPtr(obj), applyConnected(false), setDefaultsConnected(false), changed(false), restartNeeded(restartNeeded), subpage(page), configGroup(cfgGroup), configName(cfgName) { } void KonfiguratorExtension::connectNotify(const QMetaMethod &signal) { if (signal == QMetaMethod::fromSignal(&KonfiguratorExtension::applyManually)) applyConnected = true; else if (signal == QMetaMethod::fromSignal(&KonfiguratorExtension::setDefaultsManually)) setDefaultsConnected = true; QObject::connectNotify(signal); } bool KonfiguratorExtension::apply() { if (!changed) return false; if (applyConnected) emit applyManually(objectPtr, configGroup, configName); else emit applyAuto(objectPtr, configGroup, configName); setChanged(false); return restartNeeded; } void KonfiguratorExtension::setDefaults() { if (setDefaultsConnected) emit setDefaultsManually(objectPtr); else emit setDefaultsAuto(objectPtr); } void KonfiguratorExtension::loadInitialValue() { emit setInitialValue(objectPtr); } bool KonfiguratorExtension::isChanged() { return changed; } // KonfiguratorCheckBox class /////////////////////////////// KonfiguratorCheckBox::KonfiguratorCheckBox(QString configGroup, QString name, bool defaultValue, QString text, QWidget *parent, bool restart, int page) : QCheckBox(text, parent), defaultValue(defaultValue) { ext = new KonfiguratorExtension(this, configGroup, name, restart, page); - connect(ext, SIGNAL(applyAuto(QObject*,QString,QString)), this, SLOT(slotApply(QObject*,QString,QString))); - connect(ext, SIGNAL(setDefaultsAuto(QObject*)), this, SLOT(slotSetDefaults(QObject*))); - connect(ext, SIGNAL(setInitialValue(QObject*)), this, SLOT(loadInitialValue())); + connect(ext, &KonfiguratorExtension::applyAuto, this, &KonfiguratorCheckBox::slotApply); + connect(ext, &KonfiguratorExtension::setDefaultsAuto, this, &KonfiguratorCheckBox::slotSetDefaults); + connect(ext, &KonfiguratorExtension::setInitialValue, this, &KonfiguratorCheckBox::loadInitialValue); - connect(this, SIGNAL(stateChanged(int)), ext, SLOT(setChanged())); + connect(this, &KonfiguratorCheckBox::stateChanged, ext, QOverload<>::of(&KonfiguratorExtension::setChanged)); loadInitialValue(); } KonfiguratorCheckBox::~KonfiguratorCheckBox() { delete ext; } void KonfiguratorCheckBox::loadInitialValue() { KConfigGroup group(krConfig, ext->getConfigGroup()); setChecked(group.readEntry(ext->getConfigName(), defaultValue)); ext->setChanged(false); } void KonfiguratorCheckBox::checkStateSet() { QCheckBox::checkStateSet(); updateDeps(); } void KonfiguratorCheckBox::nextCheckState() { QCheckBox::nextCheckState(); updateDeps(); } void KonfiguratorCheckBox::addDep(KonfiguratorCheckBox *dep) { deps << dep; dep->setEnabled(isChecked()); } void KonfiguratorCheckBox::updateDeps() { foreach(KonfiguratorCheckBox *dep, deps) dep->setEnabled(isChecked()); } void KonfiguratorCheckBox::slotApply(QObject *, QString configGroup, QString name) { KConfigGroup(krConfig, configGroup).writeEntry(name, isChecked()); } void KonfiguratorCheckBox::slotSetDefaults(QObject *) { if (isChecked() != defaultValue) setChecked(defaultValue); } // KonfiguratorSpinBox class /////////////////////////////// KonfiguratorSpinBox::KonfiguratorSpinBox(QString configGroup, QString configName, int defaultValue, int min, int max, QWidget *parent, bool restartNeeded, int page) : QSpinBox(parent), defaultValue(defaultValue) { ext = new KonfiguratorExtension(this, configGroup, configName, restartNeeded, page); - connect(ext, SIGNAL(applyAuto(QObject*,QString,QString)), this, SLOT(slotApply(QObject*,QString,QString))); - connect(ext, SIGNAL(setDefaultsAuto(QObject*)), this, SLOT(slotSetDefaults(QObject*))); - connect(ext, SIGNAL(setInitialValue(QObject*)), this, SLOT(loadInitialValue())); + connect(ext, &KonfiguratorExtension::applyAuto, this, &KonfiguratorSpinBox::slotApply); + connect(ext, &KonfiguratorExtension::setDefaultsAuto, this, &KonfiguratorSpinBox::slotSetDefaults); + connect(ext, &KonfiguratorExtension::setInitialValue, this, &KonfiguratorSpinBox::loadInitialValue); - connect(this, SIGNAL(valueChanged(int)), ext, SLOT(setChanged())); + connect(this, QOverload::of(&KonfiguratorSpinBox::valueChanged), ext, QOverload<>::of(&KonfiguratorExtension::setChanged)); setMinimum(min); setMaximum(max); loadInitialValue(); } KonfiguratorSpinBox::~KonfiguratorSpinBox() { delete ext; } void KonfiguratorSpinBox::loadInitialValue() { KConfigGroup group(krConfig, ext->getConfigGroup()); setValue(group.readEntry(ext->getConfigName(), defaultValue)); ext->setChanged(false); } void KonfiguratorSpinBox::slotApply(QObject *, QString configGroup, QString name) { KConfigGroup(krConfig, configGroup).writeEntry(name, value()); } void KonfiguratorSpinBox::slotSetDefaults(QObject *) { if (value() != defaultValue) setValue(defaultValue); } // KonfiguratorCheckBoxGroup class /////////////////////////////// void KonfiguratorCheckBoxGroup::add(KonfiguratorCheckBox *checkBox) { checkBoxList.append(checkBox); } KonfiguratorCheckBox * KonfiguratorCheckBoxGroup::find(int index) { if (index < 0 || index >= checkBoxList.count()) return 0; return checkBoxList.at(index); } KonfiguratorCheckBox * KonfiguratorCheckBoxGroup::find(QString name) { QListIterator it(checkBoxList); while (it.hasNext()) { KonfiguratorCheckBox * checkBox = it.next(); if (checkBox->extension()->getConfigName() == name) return checkBox; } return 0; } // KonfiguratorRadioButtons class /////////////////////////////// KonfiguratorRadioButtons::KonfiguratorRadioButtons(QString configGroup, QString name, QString defaultValue, QWidget *parent, bool restart, int page) : QWidget(parent), defaultValue(defaultValue) { ext = new KonfiguratorExtension(this, configGroup, name, restart, page); - connect(ext, SIGNAL(applyAuto(QObject*,QString,QString)), this, SLOT(slotApply(QObject*,QString,QString))); - connect(ext, SIGNAL(setDefaultsAuto(QObject*)), this, SLOT(slotSetDefaults(QObject*))); - connect(ext, SIGNAL(setInitialValue(QObject*)), this, SLOT(loadInitialValue())); + connect(ext, &KonfiguratorExtension::applyAuto, this, &KonfiguratorRadioButtons::slotApply); + connect(ext, &KonfiguratorExtension::setDefaultsAuto, this, &KonfiguratorRadioButtons::slotSetDefaults); + connect(ext, &KonfiguratorExtension::setInitialValue, this, &KonfiguratorRadioButtons::loadInitialValue); } KonfiguratorRadioButtons::~KonfiguratorRadioButtons() { delete ext; } void KonfiguratorRadioButtons::addRadioButton(QRadioButton *radioWidget, QString name, QString value) { radioButtons.append(radioWidget); radioNames.push_back(name); radioValues.push_back(value); - connect(radioWidget, SIGNAL(toggled(bool)), ext, SLOT(setChanged())); + connect(radioWidget, &QRadioButton::toggled, ext, QOverload<>::of(&KonfiguratorExtension::setChanged)); } QRadioButton * KonfiguratorRadioButtons::find(int index) { if (index < 0 || index >= radioButtons.count()) return 0; return radioButtons.at(index); } QRadioButton * KonfiguratorRadioButtons::find(QString name) { int index = radioNames.indexOf(name); if (index == -1) return 0; return radioButtons.at(index); } void KonfiguratorRadioButtons::selectButton(QString value) { int cnt = 0; QListIterator it(radioButtons); while (it.hasNext()) { QRadioButton * btn = it.next(); if (value == radioValues[ cnt ]) { btn->setChecked(true); return; } cnt++; } if (!radioButtons.isEmpty()) radioButtons.first()->setChecked(true); } void KonfiguratorRadioButtons::loadInitialValue() { KConfigGroup group(krConfig, ext->getConfigGroup()); QString initValue = group.readEntry(ext->getConfigName(), defaultValue); selectButton(initValue); ext->setChanged(false); } QString KonfiguratorRadioButtons::selectedValue() { int cnt = 0; QListIterator it(radioButtons); while (it.hasNext()) { QRadioButton * btn = it.next(); if (btn->isChecked()) { return radioValues[ cnt ]; } cnt++; } return QString(); } void KonfiguratorRadioButtons::slotApply(QObject *, QString configGroup, QString name) { QString value = selectedValue(); if (!value.isEmpty()) KConfigGroup(krConfig, configGroup).writeEntry(name, value); } void KonfiguratorRadioButtons::slotSetDefaults(QObject *) { selectButton(defaultValue); } // KonfiguratorEditBox class /////////////////////////////// KonfiguratorEditBox::KonfiguratorEditBox(QString configGroup, QString name, QString defaultValue, QWidget *parent, bool restart, int page) : QLineEdit(parent), defaultValue(defaultValue) { ext = new KonfiguratorExtension(this, configGroup, name, restart, page); - connect(ext, SIGNAL(applyAuto(QObject*,QString,QString)), this, - SLOT(slotApply(QObject*,QString,QString))); - connect(ext, SIGNAL(setDefaultsAuto(QObject*)), this, SLOT(slotSetDefaults(QObject*))); - connect(ext, SIGNAL(setInitialValue(QObject*)), this, SLOT(loadInitialValue())); + connect(ext, &KonfiguratorExtension::applyAuto, this, &KonfiguratorEditBox::slotApply); + connect(ext, &KonfiguratorExtension::setDefaultsAuto, this, &KonfiguratorEditBox::slotSetDefaults); + connect(ext, &KonfiguratorExtension::setInitialValue, this, &KonfiguratorEditBox::loadInitialValue); - connect(this, SIGNAL(textChanged(QString)), ext, SLOT(setChanged())); + connect(this, &KonfiguratorEditBox::textChanged, ext, QOverload<>::of(&KonfiguratorExtension::setChanged)); loadInitialValue(); } KonfiguratorEditBox::~KonfiguratorEditBox() { delete ext; } void KonfiguratorEditBox::loadInitialValue() { KConfigGroup group(krConfig, ext->getConfigGroup()); setText(group.readEntry(ext->getConfigName(), defaultValue)); ext->setChanged(false); } void KonfiguratorEditBox::slotApply(QObject *, QString configGroup, QString name) { KConfigGroup(krConfig, configGroup).writeEntry(name, text()); } void KonfiguratorEditBox::slotSetDefaults(QObject *) { if (text() != defaultValue) setText(defaultValue); } // KonfiguratorURLRequester class /////////////////////////////// KonfiguratorURLRequester::KonfiguratorURLRequester(QString configGroup, QString name, QString defaultValue, QWidget *parent, bool restart, int page, bool expansion) : KUrlRequester(parent), defaultValue(defaultValue), expansion(expansion) { ext = new KonfiguratorExtension(this, configGroup, name, restart, page); - connect(ext, SIGNAL(applyAuto(QObject*,QString,QString)), this, - SLOT(slotApply(QObject*,QString,QString))); - connect(ext, SIGNAL(setDefaultsAuto(QObject*)), this, SLOT(slotSetDefaults(QObject*))); - connect(ext, SIGNAL(setInitialValue(QObject*)), this, SLOT(loadInitialValue())); + connect(ext, &KonfiguratorExtension::applyAuto, this, &KonfiguratorURLRequester::slotApply); + connect(ext, &KonfiguratorExtension::setDefaultsAuto, this, &KonfiguratorURLRequester::slotSetDefaults); + connect(ext, &KonfiguratorExtension::setInitialValue, this, &KonfiguratorURLRequester::loadInitialValue); - connect(this, SIGNAL(textChanged(QString)), ext, SLOT(setChanged())); + connect(this, &KonfiguratorURLRequester::textChanged, ext, QOverload<>::of(&KonfiguratorExtension::setChanged)); loadInitialValue(); } KonfiguratorURLRequester::~KonfiguratorURLRequester() { delete ext; } void KonfiguratorURLRequester::loadInitialValue() { KConfigGroup group(krConfig, ext->getConfigGroup()); lineEdit()->setText(group.readEntry(ext->getConfigName(), defaultValue)); ext->setChanged(false); } void KonfiguratorURLRequester::slotApply(QObject *, QString configGroup, QString name) { KConfigGroup(krConfig, configGroup) .writeEntry(name, expansion ? url().toDisplayString(QUrl::PreferLocalFile) : text()); } void KonfiguratorURLRequester::slotSetDefaults(QObject *) { if (url().toDisplayString(QUrl::PreferLocalFile) != defaultValue) lineEdit()->setText(defaultValue); } // KonfiguratorFontChooser class /////////////////////////////// KonfiguratorFontChooser::KonfiguratorFontChooser(QString configGroup, QString name, QFont defaultValue, QWidget *parent, bool restart, int page) : QWidget(parent), defaultValue(defaultValue) { QHBoxLayout *layout = new QHBoxLayout(this); ext = new KonfiguratorExtension(this, configGroup, name, restart, page); connect(ext, SIGNAL(applyAuto(QObject*,QString,QString)), this, SLOT(slotApply(QObject*,QString,QString))); connect(ext, SIGNAL(setDefaultsAuto(QObject*)), this, SLOT(slotSetDefaults(QObject*))); connect(ext, SIGNAL(setInitialValue(QObject*)), this, SLOT(loadInitialValue())); pLabel = new QLabel(this); pLabel->setMinimumWidth(150); layout->addWidget(pLabel); pToolButton = new QToolButton(this); connect(pToolButton, SIGNAL(clicked()), this, SLOT(slotBrowseFont())); pToolButton->setIcon(Icon("document-open")); layout->addWidget(pToolButton); loadInitialValue(); } KonfiguratorFontChooser::~KonfiguratorFontChooser() { delete ext; } void KonfiguratorFontChooser::loadInitialValue() { KConfigGroup group(krConfig, ext->getConfigGroup()); font = group.readEntry(ext->getConfigName(), defaultValue); ext->setChanged(false); setFont(); } void KonfiguratorFontChooser::setFont() { pLabel->setFont(font); pLabel->setText(font.family() + QString(", %1").arg(font.pointSize())); } void KonfiguratorFontChooser::slotApply(QObject *, QString configGroup, QString name) { KConfigGroup(krConfig, configGroup).writeEntry(name, font); } void KonfiguratorFontChooser::slotSetDefaults(QObject *) { font = defaultValue; ext->setChanged(); setFont(); } void KonfiguratorFontChooser::slotBrowseFont() { bool ok; font = QFontDialog::getFont(&ok, font, this); if (!ok) return; // cancelled by the user, and font is actually not changed (getFont returns the font we gave it) ext->setChanged(); setFont(); } // KonfiguratorComboBox class /////////////////////////////// KonfiguratorComboBox::KonfiguratorComboBox(QString configGroup, QString name, QString defaultValue, KONFIGURATOR_NAME_VALUE_PAIR *listIn, int listInLen, QWidget *parent, bool restart, bool editable, int page) : QComboBox(parent), defaultValue(defaultValue), listLen(listInLen) { list = new KONFIGURATOR_NAME_VALUE_PAIR[ listInLen ]; for (int i = 0; i != listLen; i++) { list[i] = listIn[i]; addItem(list[i].text); } ext = new KonfiguratorExtension(this, configGroup, name, restart, page); connect(ext, SIGNAL(applyAuto(QObject*,QString,QString)), this, SLOT(slotApply(QObject*,QString,QString))); connect(ext, SIGNAL(setDefaultsAuto(QObject*)), this, SLOT(slotSetDefaults(QObject*))); connect(ext, SIGNAL(setInitialValue(QObject*)), this, SLOT(loadInitialValue())); // connect( this, SIGNAL(highlighted(int)), ext, SLOT(setChanged()) ); /* Removed because of startup combo failure */ connect(this, SIGNAL(activated(int)), ext, SLOT(setChanged())); connect(this, SIGNAL(currentTextChanged(QString)), ext, SLOT(setChanged())); setEditable(editable); loadInitialValue(); } KonfiguratorComboBox::~KonfiguratorComboBox() { delete []list; delete ext; } void KonfiguratorComboBox::loadInitialValue() { KConfigGroup group(krConfig, ext->getConfigGroup()); QString select = group.readEntry(ext->getConfigName(), defaultValue); selectEntry(select); ext->setChanged(false); } void KonfiguratorComboBox::slotApply(QObject *, QString configGroup, QString name) { QString text = isEditable() ? lineEdit()->text() : currentText(); QString value = text; for (int i = 0; i != listLen; i++) if (list[i].text == text) { value = list[i].value; break; } KConfigGroup(krConfig, configGroup).writeEntry(name, value); } void KonfiguratorComboBox::selectEntry(QString entry) { for (int i = 0; i != listLen; i++) if (list[i].value == entry) { setCurrentIndex(i); return; } if (isEditable()) lineEdit()->setText(entry); else setCurrentIndex(0); } void KonfiguratorComboBox::slotSetDefaults(QObject *) { selectEntry(defaultValue); } // KonfiguratorColorChooser class /////////////////////////////// KonfiguratorColorChooser::KonfiguratorColorChooser(QString configGroup, QString name, QColor defaultValue, QWidget *parent, bool restart, ADDITIONAL_COLOR *addColPtr, int addColNum, int page) : QComboBox(parent), defaultValue(defaultValue), disableColorChooser(true) { ext = new KonfiguratorExtension(this, configGroup, name, restart, page); connect(ext, SIGNAL(applyAuto(QObject*,QString,QString)), this, SLOT(slotApply(QObject*,QString,QString))); connect(ext, SIGNAL(setDefaultsAuto(QObject*)), this, SLOT(slotSetDefaults(QObject*))); connect(ext, SIGNAL(setInitialValue(QObject*)), this, SLOT(loadInitialValue())); addColor(i18n("Custom color"), QColor(255, 255, 255)); addColor(i18nc("Default color", "Default"), defaultValue); for (int i = 0; i != addColNum; i++) { additionalColors.push_back(addColPtr[i]); addColor(addColPtr[i].name, addColPtr[i].color); } addColor(i18n("Red"), Qt::red); addColor(i18n("Green"), Qt::green); addColor(i18n("Blue"), Qt::blue); addColor(i18n("Cyan"), Qt::cyan); addColor(i18n("Magenta"), Qt::magenta); addColor(i18n("Yellow"), Qt::yellow); addColor(i18n("Dark Red"), Qt::darkRed); addColor(i18n("Dark Green"), Qt::darkGreen); addColor(i18n("Dark Blue"), Qt::darkBlue); addColor(i18n("Dark Cyan"), Qt::darkCyan); addColor(i18n("Dark Magenta"), Qt::darkMagenta); addColor(i18n("Dark Yellow"), Qt::darkYellow); addColor(i18n("White"), Qt::white); addColor(i18n("Light Gray"), Qt::lightGray); addColor(i18n("Gray"), Qt::gray); addColor(i18n("Dark Gray"), Qt::darkGray); addColor(i18n("Black"), Qt::black); connect(this, SIGNAL(activated(int)), this, SLOT(slotCurrentChanged(int))); loadInitialValue(); } KonfiguratorColorChooser::~KonfiguratorColorChooser() { delete ext; } QPixmap KonfiguratorColorChooser::createPixmap(QColor color) { QPainter painter; QPen pen; int size = QFontMetrics(font()).height() * 3 / 4; QRect rect(0, 0, size, size); QPixmap pixmap(rect.width(), rect.height()); pen.setColor(Qt::black); painter.begin(&pixmap); QBrush brush(color); painter.fillRect(rect, brush); painter.setPen(pen); painter.drawRect(rect); painter.end(); pixmap.detach(); return pixmap; } void KonfiguratorColorChooser::addColor(QString text, QColor color) { addItem(createPixmap(color), text); palette.push_back(color); } void KonfiguratorColorChooser::loadInitialValue() { KConfigGroup group(krConfig, ext->getConfigGroup()); QString selected = group.readEntry(ext->getConfigName(), QString("")); setValue(selected); ext->setChanged(false); } void KonfiguratorColorChooser::setDefaultColor(QColor dflt) { defaultValue = dflt; palette[1] = defaultValue; setItemIcon(1, createPixmap(defaultValue)); if (currentIndex() == 1) emit colorChanged(); } void KonfiguratorColorChooser::changeAdditionalColor(int num, QColor color) { if (num < additionalColors.size()) { palette[2+num] = color; additionalColors[num].color = color; setItemIcon(2 + num, createPixmap(color)); if (currentIndex() == 2 + num) emit colorChanged(); } } void KonfiguratorColorChooser::setDefaultText(QString text) { setItemIcon(1, createPixmap(defaultValue)); setItemText(1, text); } void KonfiguratorColorChooser::slotApply(QObject *, QString configGroup, QString name) { KConfigGroup(krConfig, configGroup).writeEntry(name, getValue()); } void KonfiguratorColorChooser::setValue(QString value) { disableColorChooser = true; if (value.isEmpty()) { setCurrentIndex(1); customValue = defaultValue; } else { bool found = false; for (int j = 0; j != additionalColors.size(); j++) if (additionalColors[j].value == value) { setCurrentIndex(2 + j); found = true; break; } if (! found) { KConfigGroup colGroup(krConfig, ext->getConfigGroup()); colGroup.writeEntry("TmpColor", value); QColor color = colGroup.readEntry("TmpColor", defaultValue); customValue = color; colGroup.deleteEntry("TmpColor"); setCurrentIndex(0); for (int i = 2 + additionalColors.size(); i != palette.size(); i++) if (palette[i] == color) { setCurrentIndex(i); break; } } } palette[0] = customValue; setItemIcon(0, createPixmap(customValue)); ext->setChanged(); emit colorChanged(); disableColorChooser = false; } QString KonfiguratorColorChooser::getValue() { QColor color = palette[ currentIndex()]; if (currentIndex() == 1) /* it's the default value? */ return ""; else if (currentIndex() >= 2 && currentIndex() < 2 + additionalColors.size()) return additionalColors[ currentIndex() - 2 ].value; else return QString("%1,%2,%3").arg(color.red()).arg(color.green()).arg(color.blue()); } bool KonfiguratorColorChooser::isValueRGB() { return !(currentIndex() >= 1 && currentIndex() < 2 + additionalColors.size()); } void KonfiguratorColorChooser::slotSetDefaults(QObject *) { ext->setChanged(); setCurrentIndex(1); emit colorChanged(); } void KonfiguratorColorChooser::slotCurrentChanged(int number) { ext->setChanged(); if (number == 0 && !disableColorChooser) { QColor color = QColorDialog::getColor(customValue, this); if (color.isValid()) { disableColorChooser = true; customValue = color; palette[0] = customValue; setItemIcon(0, createPixmap(customValue)); disableColorChooser = false; } } emit colorChanged(); } QColor KonfiguratorColorChooser::getColor() { return palette[ currentIndex()]; } // KonfiguratorListBox class /////////////////////////////// KonfiguratorListBox::KonfiguratorListBox(QString configGroup, QString name, QStringList defaultValue, QWidget *parent, bool restart, int page) : KrListWidget(parent), defaultValue(defaultValue) { ext = new KonfiguratorExtension(this, configGroup, name, restart, page); connect(ext, SIGNAL(applyAuto(QObject*,QString,QString)), this, SLOT(slotApply(QObject*,QString,QString))); connect(ext, SIGNAL(setDefaultsAuto(QObject*)), this, SLOT(slotSetDefaults(QObject*))); connect(ext, SIGNAL(setInitialValue(QObject*)), this, SLOT(loadInitialValue())); loadInitialValue(); } KonfiguratorListBox::~KonfiguratorListBox() { delete ext; } void KonfiguratorListBox::loadInitialValue() { KConfigGroup group(krConfig, ext->getConfigGroup()); setList(group.readEntry(ext->getConfigName(), defaultValue)); ext->setChanged(false); } void KonfiguratorListBox::slotApply(QObject *, QString configGroup, QString name) { KConfigGroup(krConfig, configGroup).writeEntry(name, list()); } void KonfiguratorListBox::slotSetDefaults(QObject *) { if (list() != defaultValue) { ext->setChanged(); setList(defaultValue); } } void KonfiguratorListBox::setList(QStringList list) { clear(); addItems(list); } QStringList KonfiguratorListBox::list() { QStringList lst; for (int i = 0; i != count(); i++) lst += item(i)->text(); return lst; } void KonfiguratorListBox::addItem(const QString & item) { if (!list().contains(item)) { KrListWidget::addItem(item); ext->setChanged(); } } void KonfiguratorListBox::removeItem(const QString & item) { QList list = findItems(item, Qt::MatchExactly); for (int i = 0; i != list.count(); i++) delete list[ i ]; if (list.count()) ext->setChanged(); } diff --git a/krusader/Konfigurator/krresulttable.cpp b/krusader/Konfigurator/krresulttable.cpp index 5f261d9e..02289831 100644 --- a/krusader/Konfigurator/krresulttable.cpp +++ b/krusader/Konfigurator/krresulttable.cpp @@ -1,397 +1,396 @@ /***************************************************************************** * Copyright (C) 2005 Dirk Eschler * * 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 "krresulttable.h" #include // QtCore #include // QtGui #include #include // QtWidgets #include #include #include #include "../krservices.h" #include "../Archive/krarchandler.h" using namespace std; #define PS(x) _supported.contains(x)>0 KrResultTable::KrResultTable(QWidget* parent) : QWidget(parent), _numRows(1) { } KrResultTable::~KrResultTable() { } QGridLayout* KrResultTable::initTable() { _grid = new QGridLayout(this); _grid->setColumnStretch(_numColumns - 1, 1); // stretch last column _grid->setContentsMargins(0, 0, 0, 0); _grid->setSpacing(0); // +++ Build and add table header +++ int column = 0; for (QStringList::Iterator it = _tableHeaders.begin(); it != _tableHeaders.end(); ++it) { _label = new QLabel(*it, this); _label->setContentsMargins(5, 5, 5, 5); _grid->addWidget(_label, 0, column); // Set font QFont defFont = QFontDatabase::systemFont(QFontDatabase::GeneralFont); defFont.setPointSize(defFont.pointSize() - 1); defFont.setBold(true); _label->setFont(defFont); ++column; } return _grid; } void KrResultTable::adjustRow(QGridLayout* grid) { int i = 0; QLayoutItem *child; int col = 0; while ((child = grid->itemAt(i)) != 0) { // Add some space between columns child->widget()->setMinimumWidth(child->widget()->sizeHint().width() + 15); // Paint uneven rows in alternate color if (((col / _numColumns) % 2)) { child->widget()->setAutoFillBackground(true); QPalette p = QGuiApplication::palette(); QPalette pal = child->widget()->palette(); pal.setColor(child->widget()->backgroundRole(), p.color(QPalette::Active, QPalette::AlternateBase)); child->widget()->setPalette(pal); } ++i; ++col; } } // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- KrArchiverResultTable::KrArchiverResultTable(QWidget* parent) : KrResultTable(parent) { _supported = KRarcHandler::supportedPackers(); // get list of available packers Archiver* tar = new Archiver("tar", "http://www.gnu.org", PS("tar"), true, true); Archiver* gzip = new Archiver("gzip", "http://www.gnu.org", PS("gzip"), true, true); Archiver* bzip2 = new Archiver("bzip2", "http://www.gnu.org", PS("bzip2"), true, true); Archiver* lzma = new Archiver("lzma", "http://tukaani.org/lzma", PS("lzma"), true, true); Archiver* xz = new Archiver("xz", "http://tukaani.org/xz", PS("xz"), true, true); Archiver* lha = new Archiver("lha", "http://www.gnu.org", PS("lha"), true, true); Archiver* zip = new Archiver("zip", "http://www.info-zip.org", PS("zip"), true, false); Archiver* unzip = new Archiver("unzip", "http://www.info-zip.org", PS("unzip"), false, true); Archiver* arj = new Archiver("arj", "http://www.arjsoftware.com", PS("arj"), true, true); Archiver* unarj = new Archiver("unarj", "http://www.arjsoftware.com", PS("unarj"), false, true); Archiver* unace = new Archiver("unace", "http://www.winace.com", PS("unace"), false, true); Archiver* rar = new Archiver("rar", "http://www.rarsoft.com", PS("rar"), true, true); Archiver* unrar = new Archiver("unrar", "http://www.rarsoft.com", PS("unrar"), false, true); Archiver* rpm = new Archiver("rpm", "http://www.gnu.org", PS("rpm"), false, true); Archiver* dpkg = new Archiver("dpkg", "http://www.dpkg.org", PS("dpkg"), false, true); Archiver* _7z = new Archiver("7z", "http://www.7-zip.org", PS("7z"), true, true); // Special case: arj can unpack, but unarj is preferred if (PS("arj") && PS("unarj")) arj->setIsUnpacker(false); if (PS("arj") && !PS("unarj")) unarj->setNote(i18n("unarj not found, but arj found, which will be used for unpacking")); // Special case: rar can unpack, but unrar is preferred if (PS("rar") && PS("unrar")) rar->setIsUnpacker(false); // Special case: rpm needs cpio for unpacking if (PS("rpm") && !PS("cpio")) rpm->setNote(i18n("rpm found, but cpio not found which is required for unpacking")); _tableHeaders.append(i18n("Name")); _tableHeaders.append(i18n("Found")); _tableHeaders.append(i18n("Packing")); _tableHeaders.append(i18n("Unpacking")); _tableHeaders.append(i18n("Note")); _numColumns = _tableHeaders.size(); _grid = initTable(); addRow(tar, _grid); addRow(gzip, _grid); addRow(bzip2, _grid); addRow(lzma, _grid); addRow(xz, _grid); addRow(lha, _grid); addRow(zip, _grid); addRow(unzip, _grid); addRow(arj, _grid); addRow(unarj, _grid); addRow(unace, _grid); addRow(rar, _grid); addRow(unrar, _grid); addRow(rpm, _grid); addRow(dpkg, _grid); addRow(_7z, _grid); delete tar; delete gzip; delete bzip2; delete lzma; delete xz; delete lha; delete zip; delete unzip; delete arj; delete unarj; delete unace; delete rar; delete unrar; delete rpm; delete dpkg; delete _7z; } KrArchiverResultTable::~KrArchiverResultTable() { } bool KrArchiverResultTable::addRow(SearchObject* search, QGridLayout* grid) { Archiver* arch = dynamic_cast(search); // Name column _label = new KUrlLabel(arch->getWebsite(), arch->getSearchName(), this); _label->setContentsMargins(5, 5, 5, 5); _label->setAlignment(Qt::AlignTop); grid->addWidget(_label, _numRows, 0); connect(_label, SIGNAL(leftClickedUrl(QString)), SLOT(website(QString))); // Found column _label = new QLabel(arch->getPath(), this); _label->setContentsMargins(5, 5, 5, 5); grid->addWidget(_label, _numRows, 1); // Packing column _label = new QLabel(this); _label->setContentsMargins(5, 5, 5, 5); _label->setAlignment(Qt::AlignTop); if (arch->getIsPacker() && arch->getFound()) { _label->setText(i18n("enabled")); QPalette pal = _label->palette(); pal.setColor(_label->foregroundRole(), "darkgreen"); _label->setPalette(pal); } else if (arch->getIsPacker() && !arch->getFound()) { _label->setText(i18n("disabled")); QPalette pal = _label->palette(); pal.setColor(_label->foregroundRole(), "red"); _label->setPalette(pal); } else _label->setText(""); grid->addWidget(_label, _numRows, 2); // Unpacking column _label = new QLabel(this); _label->setContentsMargins(5, 5, 5, 5); _label->setAlignment(Qt::AlignTop); if (arch->getIsUnpacker() && arch->getFound()) { _label->setText(i18n("enabled")); QPalette pal = _label->palette(); pal.setColor(_label->foregroundRole(), "darkgreen"); _label->setPalette(pal); } else if (arch->getIsUnpacker() && !arch->getFound()) { _label->setText(i18n("disabled")); QPalette pal = _label->palette(); pal.setColor(_label->foregroundRole(), "red"); _label->setPalette(pal); } else _label->setText(""); grid->addWidget(_label, _numRows, 3); // Note column _label = new QLabel(arch->getNote(), this); _label->setContentsMargins(5, 5, 5, 5); _label->setAlignment(Qt::AlignTop); _label->setWordWrap(true); // wrap words grid->addWidget(_label, _numRows, 4); // Apply shared design elements adjustRow(_grid); // Ensure the last column takes more space _label->setMinimumWidth(300); ++_numRows; return true; } void KrArchiverResultTable::website(const QString& url) { (void) new KRun(QUrl(url), this); } // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- KrToolResultTable::KrToolResultTable(QWidget* parent) : KrResultTable(parent) { _supported = KrServices::supportedTools(); // get list of available tools QList vecDiff, vecMail, vecRename, vecChecksum; Application* kdiff3 = new Application("kdiff3", "http://kdiff3.sourceforge.net/", KrServices::cmdExist("kdiff3")); Application* kompare = new Application("kompare", "http://www.caffeinated.me.uk/kompare/", KrServices::cmdExist("kompare")); Application* xxdiff = new Application("xxdiff", "http://xxdiff.sourceforge.net/", KrServices::cmdExist("xxdiff")); Application* thunderbird = new Application("thunderbird", "http://www.mozilla.org/", KrServices::cmdExist("thunderbird")); Application* kmail = new Application("kmail", "http://kmail.kde.org/", KrServices::cmdExist("kmail")); Application* krename = new Application("krename", "http://www.krename.net/", KrServices::cmdExist("krename")); Application* md5sum = new Application("md5sum", "http://www.gnu.org/software/textutils/textutils.html", KrServices::cmdExist("md5sum")); vecDiff.push_back(kdiff3); vecDiff.push_back(kompare); vecDiff.push_back(xxdiff); vecMail.push_back(thunderbird); vecMail.push_back(kmail); vecRename.push_back(krename); vecChecksum.push_back(md5sum); ApplicationGroup* diff = new ApplicationGroup(i18n("diff utility"), PS("DIFF"), vecDiff); ApplicationGroup* mail = new ApplicationGroup(i18n("email client"), PS("MAIL"), vecMail); ApplicationGroup* rename = new ApplicationGroup(i18n("batch renamer"), PS("RENAME"), vecRename); ApplicationGroup* checksum = new ApplicationGroup(i18n("checksum utility"), PS("MD5"), vecChecksum); _tableHeaders.append(i18n("Group")); _tableHeaders.append(i18n("Tool")); _tableHeaders.append(i18n("Found")); _tableHeaders.append(i18n("Status")); _numColumns = _tableHeaders.size(); _grid = initTable(); addRow(diff, _grid); addRow(mail, _grid); addRow(rename, _grid); addRow(checksum, _grid); delete thunderbird; delete kmail; delete kompare; delete kdiff3; delete xxdiff; delete krename; delete md5sum; delete diff; delete mail; delete rename; delete checksum; } KrToolResultTable::~KrToolResultTable() { } bool KrToolResultTable::addRow(SearchObject* search, QGridLayout* grid) { ApplicationGroup* appGroup = dynamic_cast(search); QList _apps = appGroup->getAppVec(); // Name column _label = new QLabel(appGroup->getSearchName(), this); _label->setContentsMargins(5, 5, 5, 5); _label->setAlignment(Qt::AlignTop); grid->addWidget(_label, _numRows, 0); // Tool column QWidget* toolBoxWidget = new QWidget(this); QVBoxLayout * toolBox = new QVBoxLayout(toolBoxWidget); for (QList::Iterator it = _apps.begin(); it != _apps.end(); ++it) { KUrlLabel* l = new KUrlLabel((*it)->getWebsite(), (*it)->getAppName(), toolBoxWidget); toolBox->addWidget(l); l->setAlignment(Qt::AlignLeft | Qt::AlignTop); l->setContentsMargins(5, 5, 5, 5); - connect(l, SIGNAL(leftClickedUrl(QString)), - SLOT(website(QString))); + connect(l, QOverload::of(&KUrlLabel::leftClickedUrl), this, &KrToolResultTable::website); } grid->addWidget(toolBoxWidget, _numRows, 1); // Found column QWidget* vboxWidget = new QWidget(this); QVBoxLayout * vbox = new QVBoxLayout(vboxWidget); for (QList::Iterator it = _apps.begin(); it != _apps.end(); ++it) { _label = new QLabel((*it)->getPath(), vboxWidget); _label->setContentsMargins(5, 5, 5, 5); _label->setAlignment(Qt::AlignTop); vbox->addWidget(_label); } grid->addWidget(vboxWidget, _numRows, 2); // Status column _label = new QLabel(this); _label->setContentsMargins(5, 5, 5, 5); _label->setAlignment(Qt::AlignTop); if (appGroup->getFoundGroup()) { _label->setText(i18n("enabled")); QPalette pal = _label->palette(); pal.setColor(_label->foregroundRole(), "darkgreen"); _label->setPalette(pal); } else { _label->setText(i18n("disabled")); QPalette pal = _label->palette(); pal.setColor(_label->foregroundRole(), "red"); _label->setPalette(pal); } grid->addWidget(_label, _numRows, 3); // Apply shared design elements adjustRow(_grid); // Ensure the last column takes more space _label->setMinimumWidth(300); ++_numRows; return true; } void KrToolResultTable::website(const QString& url) { (void) new KRun(QUrl(url), this); } diff --git a/krusader/MountMan/kmountman.cpp b/krusader/MountMan/kmountman.cpp index 7616ceb7..09dc20c6 100644 --- a/krusader/MountMan/kmountman.cpp +++ b/krusader/MountMan/kmountman.cpp @@ -1,465 +1,464 @@ /***************************************************************************** * 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 "kmountman.h" // QtCore #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../krglobal.h" #include "../icon.h" #include "../kractions.h" #include "../defaults.h" #include "../Dialogs/krdialogs.h" #include "../krservices.h" #include "kmountmangui.h" #include "../FileSystem/krpermhandler.h" #ifdef _OS_SOLARIS_ #define FSTAB "/etc/filesystemtab" #else #define FSTAB "/etc/fstab" #endif KMountMan::KMountMan(QWidget *parent) : QObject(), _operational(false), waiting(false), mountManGui(0), parentWindow(parent) { _action = new KToolBarPopupAction(Icon("kr_mountman"), i18n("&MountMan..."), this); connect(_action, &QAction::triggered, this, &KMountMan::mainWindow); connect(_action->menu(), &QMenu::aboutToShow, this, &KMountMan::quickList); _manageAction = _action->menu()->addAction(i18n("Open &MountMan")); connect(_manageAction, &QAction::triggered, this, &KMountMan::mainWindow); _action->menu()->addSeparator(); // added as a precaution, although we use kde services now _operational = KrServices::cmdExist("mount"); network_fs << "nfs" << "smbfs" << "fuse.fusesmb" << "fuse.sshfs"; //TODO: is this list complete ? // list of FS that we don't manage at all invalid_fs << "swap" << "/dev/pts" << "tmpfs" << "devpts" << "sysfs" << "rpc_pipefs" << "usbfs" << "binfmt_misc"; #ifdef BSD invalid_fs << "procfs"; #else invalid_fs << "proc"; #endif // list of FS that we don't allow to mount/unmount nonmount_fs << "supermount"; { KConfigGroup group(krConfig, "Advanced"); QStringList nonmount = group.readEntry("Nonmount Points", _NonMountPoints).split(','); nonmount_fs_mntpoint += nonmount; // simplify the white space for (QStringList::Iterator it = nonmount_fs_mntpoint.begin(); it != nonmount_fs_mntpoint.end(); ++it) { *it = (*it).simplified(); } } } KMountMan::~KMountMan() {} bool KMountMan::invalidFilesystem(QString type) { return (invalid_fs.contains(type) > 0); } // this is an ugly hack, but type can actually be a mountpoint. oh well... bool KMountMan::nonmountFilesystem(QString type, QString mntPoint) { return((nonmount_fs.contains(type) > 0) || (nonmount_fs_mntpoint.contains(mntPoint) > 0)); } bool KMountMan::networkFilesystem(QString type) { return (network_fs.contains(type) > 0); } void KMountMan::mainWindow() { // left as a precaution, although we use kde's services now if (!KrServices::cmdExist("mount")) { KMessageBox::error(0, i18n("Cannot start 'mount'. Check the 'Dependencies' page in konfigurator.")); return; } mountManGui = new KMountManGUI(this); delete mountManGui; /* as KMountManGUI is modal, we can now delete it */ mountManGui = nullptr; /* for sanity */ } QExplicitlySharedDataPointer KMountMan::findInListByMntPoint(KMountPoint::List &lst, QString value) { if (value.length() > 1 && value.endsWith('/')) value = value.left(value.length() - 1); QExplicitlySharedDataPointer m; for (KMountPoint::List::iterator it = lst.begin(); it != lst.end(); ++it) { m = it->data(); QString mntPnt = m->mountPoint(); if (mntPnt.length() > 1 && mntPnt.endsWith('/')) mntPnt = mntPnt.left(mntPnt.length() - 1); if (mntPnt == value) return m; } return QExplicitlySharedDataPointer(); } void KMountMan::jobResult(KJob *job) { waiting = false; if (job->error()) job->uiDelegate()->showErrorMessage(); } void KMountMan::mount(QString mntPoint, bool blocking) { QString udi = findUdiForPath(mntPoint, Solid::DeviceInterface::StorageAccess); if (!udi.isNull()) { Solid::Device device(udi); Solid::StorageAccess *access = device.as(); if (access && !access->isAccessible()) { connect(access, &Solid::StorageAccess::setupDone, this, &KMountMan::slotSetupDone, Qt::UniqueConnection); if (blocking) waiting = true; // prepare to block access->setup(); } } else { KMountPoint::List possible = KMountPoint::possibleMountPoints(KMountPoint::NeedMountOptions); QExplicitlySharedDataPointer m = findInListByMntPoint(possible, mntPoint); if (!((bool)m)) return; if (blocking) waiting = true; // prepare to block // KDE4 doesn't allow mounting devices as user, because they think it's the right behaviour. // I add this patch, as I don't think so. if (geteuid()) { // tries to mount as an user? KProcess proc; proc << KrServices::fullPathName("mount") << mntPoint; proc.start(); if (!blocking) return; proc.waitForFinished(-1); // -1 msec blocks without timeout if (proc.exitStatus() == QProcess::NormalExit && proc.exitCode() == 0) return; } KIO::SimpleJob *job = KIO::mount(false, m->mountType().toLocal8Bit(), m->mountedFrom(), m->mountPoint(), KIO::DefaultFlags); job->setUiDelegate(new KIO::JobUiDelegate()); KIO::getJobTracker()->registerJob(job); - connect(job, SIGNAL(result(KJob*)), this, SLOT(jobResult(KJob*))); + connect(job, &KIO::SimpleJob::result, this, &KMountMan::jobResult); } while (blocking && waiting) { qApp->processEvents(); usleep(1000); } } void KMountMan::unmount(QString mntPoint, bool blocking) { //if working dir is below mountpoint cd to ~ first if(QUrl::fromLocalFile(QDir(mntPoint).canonicalPath()).isParentOf(QUrl::fromLocalFile(QDir::current().canonicalPath()))) QDir::setCurrent(QDir::homePath()); QString udi = findUdiForPath(mntPoint, Solid::DeviceInterface::StorageAccess); if (!udi.isNull()) { Solid::Device device(udi); Solid::StorageAccess *access = device.as(); if (access && access->isAccessible()) { connect(access, &Solid::StorageAccess::teardownDone, this, &KMountMan::slotTeardownDone, Qt::UniqueConnection); access->teardown(); } } else { if (blocking) waiting = true; // prepare to block // KDE4 doesn't allow unmounting devices as user, because they think it's the right behaviour. // I add this patch, as I don't think so. if (geteuid()) { // tries to mount as an user? KProcess proc; proc << KrServices::fullPathName("umount") << mntPoint; proc.start(); if (!blocking) return; proc.waitForFinished(-1); // -1 msec blocks without timeout if (proc.exitStatus() == QProcess::NormalExit && proc.exitCode() == 0) return; } KIO::SimpleJob *job = KIO::unmount(mntPoint, KIO::DefaultFlags); job->setUiDelegate(new KIO::JobUiDelegate()); KIO::getJobTracker()->registerJob(job); - connect(job, SIGNAL(result(KJob*)), this, SLOT(jobResult(KJob*))); + connect(job, &KIO::SimpleJob::result, this, &KMountMan::jobResult); } while (blocking && waiting) { qApp->processEvents(); usleep(1000); } } KMountMan::mntStatus KMountMan::getStatus(QString mntPoint) { QExplicitlySharedDataPointer mountPoint; // 1: is it already mounted KMountPoint::List current = KMountPoint::currentMountPoints(); mountPoint = findInListByMntPoint(current, mntPoint); if ((bool) mountPoint) return MOUNTED; // 2: is it a mount point but not mounted? KMountPoint::List possible = KMountPoint::possibleMountPoints(); mountPoint = findInListByMntPoint(possible, mntPoint); if ((bool) mountPoint) return NOT_MOUNTED; // 3: unknown return DOESNT_EXIST; } void KMountMan::toggleMount(QString mntPoint) { mntStatus status = getStatus(mntPoint); switch (status) { case MOUNTED: unmount(mntPoint); break; case NOT_MOUNTED: mount(mntPoint); break; case DOESNT_EXIST: // do nothing: no-op to make the compiler quiet ;-) break; } } void KMountMan::autoMount(QString path) { KConfigGroup group(krConfig, "Advanced"); if (!group.readEntry("AutoMount", _AutoMount)) return; // auto mount disabled if (getStatus(path) == NOT_MOUNTED) mount(path); } void KMountMan::eject(QString mntPoint) { QString udi = findUdiForPath(mntPoint, Solid::DeviceInterface::OpticalDrive); if (udi.isNull()) return; Solid::Device dev(udi); Solid::OpticalDrive *drive = dev.as(); if (drive == 0) return; //if working dir is below mountpoint cd to ~ first if(QUrl::fromLocalFile(QDir(mntPoint).canonicalPath()).isParentOf(QUrl::fromLocalFile(QDir::current().canonicalPath()))) QDir::setCurrent(QDir::homePath()); - connect(drive, SIGNAL(ejectDone(Solid::ErrorType,QVariant,QString)), - this, SLOT(slotTeardownDone(Solid::ErrorType,QVariant,QString))); + connect(drive, &Solid::OpticalDrive::ejectDone, this, &KMountMan::slotTeardownDone); drive->eject(); } // returns true if the path is an ejectable mount point (at the moment CDROM and DVD) bool KMountMan::ejectable(QString path) { QString udi = findUdiForPath(path, Solid::DeviceInterface::OpticalDisc); if (udi.isNull()) return false; Solid::Device dev(udi); return dev.as() != 0; } bool KMountMan::removable(QString path) { QString udi = findUdiForPath(path, Solid::DeviceInterface::StorageAccess); if (udi.isNull()) return false; return removable(Solid::Device(udi)); } bool KMountMan::removable(Solid::Device d) { if(!d.isValid()) return false; Solid::StorageDrive *drive = d.as(); if(drive) return drive->isRemovable(); else return(removable(d.parent())); } // populate the pop-up menu of the mountman tool-button with actions void KMountMan::quickList() { if (!_operational) { KMessageBox::error(0, i18n("MountMan is not operational. Sorry")); return; } // clear mount / unmount actions for (QAction *action : _action->menu()->actions()) { if (action == _manageAction || action->isSeparator()) { continue; } _action->menu()->removeAction(action); } // create lists of current and possible mount points const KMountPoint::List currentMountPoints = KMountPoint::currentMountPoints(); // create a menu, displaying mountpoints with possible actions for (QExplicitlySharedDataPointer possibleMountPoint : KMountPoint::possibleMountPoints()) { // skip nonmountable file systems if (nonmountFilesystem(possibleMountPoint->mountType(), possibleMountPoint->mountPoint()) || invalidFilesystem(possibleMountPoint->mountType())) { continue; } // does the mountpoint exist in current list? // if so, it can only be umounted, otherwise, it can be mounted bool needUmount = false; for (QExplicitlySharedDataPointer currentMountPoint : currentMountPoints) { if (currentMountPoint->mountPoint() == possibleMountPoint->mountPoint()) { // found -> needs umount needUmount = true; break; } } // add the item to the menu const QString text = QString("%1 %2 (%3)").arg(needUmount ? i18n("Unmount") : i18n("Mount"), possibleMountPoint->mountPoint(), possibleMountPoint->mountedFrom()); QAction *act = _action->menu()->addAction(text); act->setData(QList({ QVariant(needUmount ? KMountMan::ActionType::Unmount : KMountMan::ActionType::Mount), QVariant(possibleMountPoint->mountPoint()) })); } connect(_action->menu(), &QMenu::triggered, this, &KMountMan::delayedPerformAction); } void KMountMan::delayedPerformAction(const QAction *action) { if (!action || !action->data().canConvert>()) { return; } disconnect(_action->menu(), &QMenu::triggered, 0, 0); const QList actData = action->data().toList(); const int actionType = actData[0].toInt(); const QString mountPoint = actData[1].toString(); QTimer::singleShot(0, this, [=] { if (actionType == KMountMan::ActionType::Mount) { mount(mountPoint); } else { unmount(mountPoint); } }); } QString KMountMan::findUdiForPath(QString path, const Solid::DeviceInterface::Type &expType) { KMountPoint::List current = KMountPoint::currentMountPoints(); KMountPoint::List possible = KMountPoint::possibleMountPoints(); QExplicitlySharedDataPointer mp = findInListByMntPoint(current, path); if (!(bool)mp) { mp = findInListByMntPoint(possible, path); if (!(bool)mp) return QString(); } QString dev = QDir(mp->mountedFrom()).canonicalPath(); QList storageDevices = Solid::Device::listFromType(Solid::DeviceInterface::Block); for (int p = storageDevices.count() - 1 ; p >= 0; p--) { Solid::Device device = storageDevices[ p ]; QString udi = device.udi(); Solid::Block * sb = device.as(); if (sb) { QString devb = QDir(sb->device()).canonicalPath(); if (expType != Solid::DeviceInterface::Unknown && !device.isDeviceInterface(expType)) continue; if (devb == dev) return udi; } } return QString(); } QString KMountMan::pathForUdi(QString udi) { Solid::Device device(udi); Solid::StorageAccess *access = device.as(); if(access) return access->filePath(); else return QString(); } void KMountMan::slotTeardownDone(Solid::ErrorType error, QVariant errorData, const QString& /*udi*/) { waiting = false; if (error != Solid::NoError && errorData.isValid()) { KMessageBox::sorry(parentWindow, errorData.toString()); } } void KMountMan::slotSetupDone(Solid::ErrorType error, QVariant errorData, const QString& /*udi*/) { waiting = false; if (error != Solid::NoError && errorData.isValid()) { KMessageBox::sorry(parentWindow, errorData.toString()); } } diff --git a/krusader/Panel/PanelView/krmousehandler.cpp b/krusader/Panel/PanelView/krmousehandler.cpp index 10442448..2c8aa349 100644 --- a/krusader/Panel/PanelView/krmousehandler.cpp +++ b/krusader/Panel/PanelView/krmousehandler.cpp @@ -1,387 +1,387 @@ /***************************************************************************** * 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 "krmousehandler.h" #include "krselectionmode.h" #include "krview.h" #include "krviewitem.h" #include "../defaults.h" #include "../krglobal.h" // QtCore #include // QtWidgets #include #include #include #include #define CANCEL_TWO_CLICK_RENAME {_singleClicked = false;_renameTimer.stop();} KrMouseHandler::KrMouseHandler(KrView * view, int contextMenuShift) : _view(view), _rightClickedItem(0), _contextMenuTimer(), _contextMenuShift(contextMenuShift), _singleClicked(false), _singleClickTime(), _renameTimer(), _dragStartPos(-1, -1), _emptyContextMenu(false), _selectedItemNames() { KConfigGroup grpSvr(krConfig, "Look&Feel"); // decide on single click/double click selection bool singleClickTmp = QApplication::style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick); _singleClick = grpSvr.readEntry("Single Click Selects", _SingleClickSelects) && singleClickTmp; - connect(&_contextMenuTimer, SIGNAL(timeout()), this, SLOT(showContextMenu())); - connect(&_renameTimer, SIGNAL(timeout()), this, SIGNAL(renameCurrentItem())); + connect(&_contextMenuTimer, &QTimer::timeout, this, &KrMouseHandler::showContextMenu); + connect(&_renameTimer, &QTimer::timeout, this, &KrMouseHandler::renameCurrentItem); } bool KrMouseHandler::mousePressEvent(QMouseEvent *e) { _rightClickedItem = _clickedItem = 0; KrViewItem * item = _view->getKrViewItemAt(e->pos()); if (!_view->isFocused()) _view->op()->emitNeedFocus(); if (e->button() == Qt::LeftButton) { _dragStartPos = e->pos(); if (e->modifiers() == Qt::NoModifier) { if (item) { if (KrSelectionMode::getSelectionHandler()->leftButtonSelects()) { if (KrSelectionMode::getSelectionHandler()->leftButtonPreservesSelection()) item->setSelected(!item->isSelected()); else { if (item->isSelected()) _clickedItem = item; else { // clear the current selection _view->changeSelection(KRQuery("*"), false, true); item->setSelected(true); } } } _view->setCurrentKrViewItem(item); } else { // empty space under items clicked if (KrSelectionMode::getSelectionHandler()->leftButtonSelects() && !KrSelectionMode::getSelectionHandler()->leftButtonPreservesSelection()) { // clear the current selection _view->changeSelection(KRQuery("*"), false, true); } } e->accept(); return true; } else if (e->modifiers() == Qt::ControlModifier) { if (item && (KrSelectionMode::getSelectionHandler()->shiftCtrlLeftButtonSelects() || KrSelectionMode::getSelectionHandler()->leftButtonSelects())) { // get current selected item names _selectedItemNames.clear(); _view->getSelectedItems(&_selectedItemNames, false); item->setSelected(!item->isSelected()); // select also the focused item if there are no other selected items KrViewItem * previousItem = _view->getCurrentKrViewItem(); if (previousItem->name() != ".." && _selectedItemNames.empty()) { previousItem->setSelected(true); } } if (item) { _view->setCurrentKrViewItem(item); } e->accept(); return true; } else if (e->modifiers() == Qt::ShiftModifier) { if (item && (KrSelectionMode::getSelectionHandler()->shiftCtrlLeftButtonSelects() || KrSelectionMode::getSelectionHandler()->leftButtonSelects())) { KrViewItem * current = _view->getCurrentKrViewItem(); if (current != 0) _view->selectRegion(item, current, true); } if (item) _view->setCurrentKrViewItem(item); e->accept(); return true; } } if (e->button() == Qt::RightButton) { //dragStartPos = e->pos(); if (e->modifiers() == Qt::NoModifier) { if (item) { if (KrSelectionMode::getSelectionHandler()->rightButtonSelects()) { if (KrSelectionMode::getSelectionHandler()->rightButtonPreservesSelection()) { if (KrSelectionMode::getSelectionHandler()->showContextMenu() >= 0) { _rightClickSelects = !item->isSelected(); _rightClickedItem = item; } item->setSelected(!item->isSelected()); } else { if (item->isSelected()) { _clickedItem = item; } else { // clear the current selection _view->changeSelection(KRQuery("*"), false, true); item->setSelected(true); } } } _view->setCurrentKrViewItem(item); } handleContextMenu(item, e->globalPos()); e->accept(); return true; } else if (e->modifiers() == Qt::ControlModifier) { if (item && (KrSelectionMode::getSelectionHandler()->shiftCtrlRightButtonSelects() || KrSelectionMode::getSelectionHandler()->rightButtonSelects())) { item->setSelected(!item->isSelected()); } if (item) _view->setCurrentKrViewItem(item); e->accept(); return true; } else if (e->modifiers() == Qt::ShiftModifier) { if (item && (KrSelectionMode::getSelectionHandler()->shiftCtrlRightButtonSelects() || KrSelectionMode::getSelectionHandler()->rightButtonSelects())) { KrViewItem * current = _view->getCurrentKrViewItem(); if (current != 0) _view->selectRegion(item, current, true); } if (item) _view->setCurrentKrViewItem(item); e->accept(); return true; } } if (e->button() == Qt::ForwardButton) { _view->op()->emitGoForward(); return true; } if (e->button() == Qt::BackButton) { _view->op()->emitGoBack(); return true; } return false; } bool KrMouseHandler::mouseReleaseEvent(QMouseEvent *e) { if (e->button() == Qt::LeftButton) _dragStartPos = QPoint(-1, -1); KrViewItem * item = _view->getKrViewItemAt(e->pos()); if (item && item == _clickedItem) { if (((e->button() == Qt::LeftButton) && (e->modifiers() == Qt::NoModifier) && (KrSelectionMode::getSelectionHandler()->leftButtonSelects()) && !(KrSelectionMode::getSelectionHandler()->leftButtonPreservesSelection())) || ((e->button() == Qt::RightButton) && (e->modifiers() == Qt::NoModifier) && (KrSelectionMode::getSelectionHandler()->rightButtonSelects()) && !(KrSelectionMode::getSelectionHandler()->rightButtonPreservesSelection()))) { // clear the current selection _view->changeSelection(KRQuery("*"), false, true); item->setSelected(true); } } if (e->button() == Qt::RightButton) { _rightClickedItem = 0; _contextMenuTimer.stop(); } if (_singleClick && e->button() == Qt::LeftButton && e->modifiers() == Qt::NoModifier) { CANCEL_TWO_CLICK_RENAME; e->accept(); if (item == 0) return true; QString tmp = item->name(); _view->op()->emitExecuted(tmp); return true; } else if (!_singleClick && e->button() == Qt::LeftButton) { if (item && e->modifiers() == Qt::NoModifier) { if (_singleClicked && !_renameTimer.isActive() && _singleClickedItem == item) { KSharedConfigPtr config = KSharedConfig::openConfig(); KConfigGroup group(krConfig, "KDE"); int doubleClickInterval = group.readEntry("DoubleClickInterval", 400); int msecsFromLastClick = _singleClickTime.msecsTo(QTime::currentTime()); if (msecsFromLastClick > doubleClickInterval && msecsFromLastClick < 5 * doubleClickInterval) { _singleClicked = false; _renameTimer.setSingleShot(true); _renameTimer.start(doubleClickInterval); return true; } } CANCEL_TWO_CLICK_RENAME; _singleClicked = true; _singleClickedItem = item; _singleClickTime = QTime::currentTime(); return true; } } CANCEL_TWO_CLICK_RENAME; if (e->button() == Qt::MidButton && item != 0) { e->accept(); if (item == 0) return true; _view->op()->emitMiddleButtonClicked(item); return true; } return false; } bool KrMouseHandler::mouseDoubleClickEvent(QMouseEvent *e) { CANCEL_TWO_CLICK_RENAME; KrViewItem * item = _view->getKrViewItemAt(e->pos()); if (_singleClick) return false; if (e->button() == Qt::LeftButton && item != 0) { e->accept(); QString tmp = item->name(); _view->op()->emitExecuted(tmp); return true; } return false; } bool KrMouseHandler::mouseMoveEvent(QMouseEvent *e) { KrViewItem * item = _view->getKrViewItemAt(e->pos()); if ((_singleClicked || _renameTimer.isActive()) && item != _singleClickedItem) CANCEL_TWO_CLICK_RENAME; if (!item) return false; const QString desc = item->description(); _view->op()->emitItemDescription(desc); if (_dragStartPos != QPoint(-1, -1) && (e->buttons() & Qt::LeftButton) && (_dragStartPos - e->pos()).manhattanLength() > QApplication::startDragDistance()) { _view->op()->startDrag(); return true; } if (KrSelectionMode::getSelectionHandler()->rightButtonPreservesSelection() && KrSelectionMode::getSelectionHandler()->rightButtonSelects() && KrSelectionMode::getSelectionHandler()->showContextMenu() >= 0 && e->buttons() == Qt::RightButton) { e->accept(); if (item != _rightClickedItem && item && _rightClickedItem) { _view->selectRegion(item, _rightClickedItem, _rightClickSelects); _rightClickedItem = item; _view->setCurrentKrViewItem(item); _contextMenuTimer.stop(); } return true; } return false; } bool KrMouseHandler::wheelEvent(QWheelEvent *e) { if (!_view->isFocused()) _view->op()->emitNeedFocus(); if (e->modifiers() == Qt::ControlModifier) { if (e->delta() > 0) { _view->zoomIn(); } else { _view->zoomOut(); } e->accept(); return true; } return false; } void KrMouseHandler::showContextMenu() { if (_rightClickedItem) _rightClickedItem->setSelected(true); if (_emptyContextMenu) _view->op()->emitEmptyContextMenu(_contextMenuPoint); else _view->op()->emitContextMenu(_contextMenuPoint); } void KrMouseHandler::handleContextMenu(KrViewItem * it, const QPoint & pos) { if (!_view->isFocused()) _view->op()->emitNeedFocus(); int i = KrSelectionMode::getSelectionHandler()->showContextMenu(); _contextMenuPoint = QPoint(pos.x(), pos.y() - _contextMenuShift); if (i < 0) { if (!it || it->isDummy()) _view->op()->emitEmptyContextMenu(_contextMenuPoint); else { _view->setCurrentKrViewItem(it); _view->op()->emitContextMenu(_contextMenuPoint); } } else if (i > 0) { _emptyContextMenu = !it || it->isDummy(); _contextMenuTimer.setSingleShot(true); _contextMenuTimer.start(i); } } void KrMouseHandler::otherEvent(QEvent * e) { switch (e->type()) { case QEvent::Timer: case QEvent::MouseMove: case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: break; default: CANCEL_TWO_CLICK_RENAME; } } void KrMouseHandler::cancelTwoClickRename() { CANCEL_TWO_CLICK_RENAME; } bool KrMouseHandler::dragEnterEvent(QDragEnterEvent *e) { QList URLs = KUrlMimeData::urlsFromMimeData(e->mimeData()); e->setAccepted(!URLs.isEmpty()); return true; } bool KrMouseHandler::dragMoveEvent(QDragMoveEvent *e) { QList URLs = KUrlMimeData::urlsFromMimeData(e->mimeData()); e->setAccepted(!URLs.isEmpty()); return true; } bool KrMouseHandler::dragLeaveEvent(QDragLeaveEvent * /*e*/) { return false; } bool KrMouseHandler::dropEvent(QDropEvent *e) { _view->op()->emitGotDrop(e); return true; } diff --git a/krusader/Panel/PanelView/krview.cpp b/krusader/Panel/PanelView/krview.cpp index a7f04374..6c96041a 100644 --- a/krusader/Panel/PanelView/krview.cpp +++ b/krusader/Panel/PanelView/krview.cpp @@ -1,1223 +1,1223 @@ /***************************************************************************** * Copyright (C) 2000-2002 Shie Erlich * * Copyright (C) 2000-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 "krview.h" #include "krselectionmode.h" #include "krviewfactory.h" #include "krviewitem.h" #include "../FileSystem/dirlisterinterface.h" #include "../FileSystem/fileitem.h" #include "../FileSystem/krpermhandler.h" #include "../Filter/filterdialog.h" #include "../defaults.h" #include "../filelisticon.h" #include "../krcolorcache.h" #include "../krglobal.h" #include "../krpreviews.h" #include "../viewactions.h" // QtCore #include #include // QtGui #include #include #include #include // QtWidgets #include #include #include #include #include #include #include #define FILEITEM getFileItem() KrView *KrViewOperator::_changedView = 0; KrViewProperties::PropertyType KrViewOperator::_changedProperties = KrViewProperties::NoProperty; // ----------------------------- operator KrViewOperator::KrViewOperator(KrView *view, QWidget *widget) : _view(view), _widget(widget), _massSelectionUpdate(false) { _saveDefaultSettingsTimer.setSingleShot(true); - connect(&_saveDefaultSettingsTimer, SIGNAL(timeout()), SLOT(saveDefaultSettings())); + connect(&_saveDefaultSettingsTimer, &QTimer::timeout, this, &KrViewOperator::saveDefaultSettings); } KrViewOperator::~KrViewOperator() { if(_changedView == _view) saveDefaultSettings(); } void KrViewOperator::startUpdate() { _view->refresh(); } void KrViewOperator::cleared() { _view->clear(); } void KrViewOperator::fileAdded(FileItem *fileitem) { _view->addItem(fileitem); } void KrViewOperator::fileUpdated(FileItem *newFileitem) { _view->updateItem(newFileitem); } void KrViewOperator::startDrag() { QStringList items; _view->getSelectedItems(&items); if (items.empty()) return ; // don't drag an empty thing QPixmap px; if (items.count() > 1 || _view->getCurrentKrViewItem() == 0) px = FileListIcon("document-multiple").pixmap(); // we are dragging multiple items else px = _view->getCurrentKrViewItem()->icon(); emit letsDrag(items, px); } bool KrViewOperator::searchItem(const QString &text, bool caseSensitive, int direction) { KrViewItem * item = _view->getCurrentKrViewItem(); if (!item) { return false; } const QRegExp regeEx(text, caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::Wildcard); if (!direction) { if (regeEx.indexIn(item->name()) == 0) { return true; } direction = 1; } KrViewItem * startItem = item; while (true) { item = (direction > 0) ? _view->getNext(item) : _view->getPrev(item); if (!item) item = (direction > 0) ? _view->getFirst() : _view->getLast(); if (regeEx.indexIn(item->name()) == 0) { _view->setCurrentKrViewItem(item); _view->makeItemVisible(item); return true; } if (item == startItem) { return false; } } } bool KrViewOperator::filterSearch(const QString &text, bool caseSensitive) { _view->_quickFilterMask = QRegExp(text, caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::Wildcard); _view->refresh(); return _view->_count || !_view->_files->numFileItems(); } void KrViewOperator::setMassSelectionUpdate(bool upd) { _massSelectionUpdate = upd; if (!upd) { emit selectionChanged(); _view->redraw(); } } void KrViewOperator::settingsChanged(KrViewProperties::PropertyType properties) { if(!_view->_updateDefaultSettings || _view->_ignoreSettingsChange) return; if(_changedView != _view) saveDefaultSettings(); _changedView = _view; _changedProperties = static_cast(_changedProperties | properties); _saveDefaultSettingsTimer.start(100); } void KrViewOperator::saveDefaultSettings() { _saveDefaultSettingsTimer.stop(); if(_changedView) _changedView->saveDefaultSettings(_changedProperties); _changedProperties = KrViewProperties::NoProperty; _changedView = 0; } // ----------------------------- krview const KrView::IconSizes KrView::iconSizes; KrView::KrView(KrViewInstance &instance, KConfig *cfg) : _config(cfg), _properties(0), _focused(false), _fileIconSize(0), _instance(instance), _files(0), _mainWindow(0), _widget(0), _nameToMakeCurrent(QString()), _previews(0), _updateDefaultSettings(false), _ignoreSettingsChange(false), _count(0), _numDirs(0), _dummyFileItem(0) { } KrView::~KrView() { _instance.m_objects.removeOne(this); delete _previews; _previews = 0; delete _dummyFileItem; _dummyFileItem = 0; if (_properties) qFatal("A class inheriting KrView didn't delete _properties!"); if (_operator) qFatal("A class inheriting KrView didn't delete _operator!"); } void KrView::init(bool enableUpdateDefaultSettings) { // sanity checks: if (!_widget) qFatal("_widget must be set during construction of KrView inheritors"); // ok, continue initProperties(); _operator = createOperator(); setup(); restoreDefaultSettings(); _updateDefaultSettings = enableUpdateDefaultSettings && KConfigGroup(_config, "Startup").readEntry("Update Default Panel Settings", _RememberPos); _instance.m_objects.append(this); } void KrView::initProperties() { const KConfigGroup grpInstance(_config, _instance.name()); const bool displayIcons = grpInstance.readEntry("With Icons", _WithIcons); const KConfigGroup grpSvr(_config, "Look&Feel"); const bool numericPermissions = grpSvr.readEntry("Numeric permissions", _NumericPermissions); int sortOps = 0; if (grpSvr.readEntry("Show Directories First", true)) sortOps |= KrViewProperties::DirsFirst; if(grpSvr.readEntry("Always sort dirs by name", false)) sortOps |= KrViewProperties::AlwaysSortDirsByName; if (!grpSvr.readEntry("Case Sensative Sort", _CaseSensativeSort)) sortOps |= KrViewProperties::IgnoreCase; if (grpSvr.readEntry("Locale Aware Sort", true)) sortOps |= KrViewProperties::LocaleAwareSort; KrViewProperties::SortOptions sortOptions = static_cast(sortOps); KrViewProperties::SortMethod sortMethod = static_cast( grpSvr.readEntry("Sort method", (int)_DefaultSortMethod)); const bool humanReadableSize = grpSvr.readEntry("Human Readable Size", _HumanReadableSize); // see KDE bug #40131 const bool localeAwareCompareIsCaseSensitive = QString("a").localeAwareCompare("B") > 0; QStringList defaultAtomicExtensions; defaultAtomicExtensions += ".tar.gz"; defaultAtomicExtensions += ".tar.bz2"; defaultAtomicExtensions += ".tar.lzma"; defaultAtomicExtensions += ".tar.xz"; defaultAtomicExtensions += ".moc.cpp"; QStringList atomicExtensions = grpSvr.readEntry("Atomic Extensions", defaultAtomicExtensions); for (QStringList::iterator i = atomicExtensions.begin(); i != atomicExtensions.end();) { QString & ext = *i; ext = ext.trimmed(); if (!ext.length()) { i = atomicExtensions.erase(i); continue; } if (!ext.startsWith('.')) ext.insert(0, '.'); ++i; } _properties = new KrViewProperties(displayIcons, numericPermissions, sortOptions, sortMethod, humanReadableSize, localeAwareCompareIsCaseSensitive, atomicExtensions); } void KrView::showPreviews(bool show) { if(show) { if(!_previews) { _previews = new KrPreviews(this); _previews->update(); } } else { delete _previews; _previews = 0; } redraw(); // op()->settingsChanged(KrViewProperties::PropShowPreviews); op()->emitRefreshActions(); } void KrView::updatePreviews() { if(_previews) _previews->update(); } QPixmap KrView::processIcon(const QPixmap &icon, bool dim, const QColor & dimColor, int dimFactor, bool symlink) { QPixmap pixmap = icon; if (symlink) { const QStringList overlays = QStringList() << QString() << "emblem-symbolic-link"; Icon::applyOverlays(&pixmap, overlays); } if(!dim) return pixmap; QImage dimmed = pixmap.toImage(); QPainter p(&dimmed); p.setCompositionMode(QPainter::CompositionMode_SourceIn); p.fillRect(0, 0, icon.width(), icon.height(), dimColor); p.setCompositionMode(QPainter::CompositionMode_SourceOver); p.setOpacity((qreal)dimFactor / (qreal)100); p.drawPixmap(0, 0, icon.width(), icon.height(), pixmap); return QPixmap::fromImage(dimmed, Qt::ColorOnly | Qt::ThresholdDither | Qt::ThresholdAlphaDither | Qt::NoOpaqueDetection ); } QPixmap KrView::getIcon(FileItem *fileitem, bool active, int size/*, KRListItem::cmpColor color*/) { // KConfigGroup ag( krConfig, "Advanced"); ////////////////////////////// QPixmap icon; QString iconName = fileitem->getIcon(); QString cacheName; if(!size) size = _FilelistIconSize.toInt(); QColor dimColor; int dimFactor; bool dim = !active && KrColorCache::getColorCache().getDimSettings(dimColor, dimFactor); if (iconName.isNull()) iconName = ""; cacheName.append(QString::number(size)); if(fileitem->isSymLink()) cacheName.append("LINK_"); if(dim) cacheName.append("DIM_"); cacheName.append(iconName); //QPixmapCache::setCacheLimit( ag.readEntry("Icon Cache Size",_IconCacheSize) ); // first try the cache if (!QPixmapCache::find(cacheName, icon)) { icon = processIcon(Icon(iconName, Icon("unknown")).pixmap(size), dim, dimColor, dimFactor, fileitem->isSymLink()); // insert it into the cache QPixmapCache::insert(cacheName, icon); } return icon; } QPixmap KrView::getIcon(FileItem *fileitem) { if(_previews) { QPixmap icon; if(_previews->getPreview(fileitem, icon, _focused)) return icon; } return getIcon(fileitem, _focused, _fileIconSize); } /** * this function ADDs a list of selected item names into 'names'. * it assumes the list is ready and doesn't initialize it, or clears it */ void KrView::getItemsByMask(QString mask, QStringList* names, bool dirs, bool files) { for (KrViewItem * it = getFirst(); it != 0; it = getNext(it)) { if ((it->name() == "..") || !QDir::match(mask, it->name())) continue; // if we got here, than the item fits the mask if (it->getFileItem()->isDir() && !dirs) continue; // do we need to skip folders? if (!it->getFileItem()->isDir() && !files) continue; // do we need to skip files names->append(it->name()); } } /** * this function ADDs a list of selected item names into 'names'. * it assumes the list is ready and doesn't initialize it, or clears it */ void KrView::getSelectedItems(QStringList *names, bool fallbackToFocused) { for (KrViewItem *it = getFirst(); it != 0; it = getNext(it)) if (it->isSelected() && (it->name() != "..")) names->append(it->name()); if (fallbackToFocused) { // if all else fails, take the current item const QString item = getCurrentItem(); if (names->empty() && !item.isEmpty() && item != "..") { names->append(item); } } } void KrView::getSelectedKrViewItems(KrViewItemList *items) { for (KrViewItem * it = getFirst(); it != 0; it = getNext(it)) if (it->isSelected() && (it->name() != "..")) items->append(it); // if all else fails, take the current item QString item = getCurrentItem(); if (items->empty() && !item.isEmpty() && item != ".." && getCurrentKrViewItem() != 0) { items->append(getCurrentKrViewItem()); } } QString KrView::statistics() { KIO::filesize_t size = calcSize(); KIO::filesize_t selectedSize = calcSelectedSize(); QString tmp; KConfigGroup grp(_config, "Look&Feel"); if(grp.readEntry("Show Size In Bytes", false)) { tmp = i18nc("%1=number of selected items,%2=total number of items, \ %3=filesize of selected items,%4=filesize in Bytes, \ %5=filesize of all items in folder,%6=filesize in Bytes", "%1 out of %2, %3 (%4) out of %5 (%6)", numSelected(), _count, KIO::convertSize(selectedSize), KRpermHandler::parseSize(selectedSize), KIO::convertSize(size), KRpermHandler::parseSize(size)); } else { tmp = i18nc("%1=number of selected items,%2=total number of items, \ %3=filesize of selected items,%4=filesize of all items in folder", "%1 out of %2, %3 out of %4", numSelected(), _count, KIO::convertSize(selectedSize), KIO::convertSize(size)); } // notify if we're running a filtered view if (filter() != KrViewProperties::All) tmp = ">> [ " + filterMask().nameFilter() + " ] " + tmp; return tmp; } bool KrView::changeSelection(const KRQuery& filter, bool select) { KConfigGroup grpSvr(_config, "Look&Feel"); return changeSelection(filter, select, grpSvr.readEntry("Mark Dirs", _MarkDirs), true); } bool KrView::changeSelection(const KRQuery& filter, bool select, bool includeDirs, bool makeVisible) { if (op()) op()->setMassSelectionUpdate(true); KrViewItem *temp = getCurrentKrViewItem(); KrViewItem *firstMatch = 0; for (KrViewItem * it = getFirst(); it != 0; it = getNext(it)) { if (it->name() == "..") continue; if (it->getFileItem()->isDir() && !includeDirs) continue; FileItem * file = it->getMutableFileItem(); // filter::match calls getMimetype which isn't const if (file == 0) continue; if (filter.match(file)) { it->setSelected(select); if (!firstMatch) firstMatch = it; } } if (op()) op()->setMassSelectionUpdate(false); updateView(); if (ensureVisibilityAfterSelect() && temp != 0) { makeItemVisible(temp); } else if (makeVisible && firstMatch != 0) { // if no selected item is visible... KrViewItemList selectedItems; getSelectedKrViewItems(&selectedItems); bool anyVisible = false; for (KrViewItem *item : selectedItems) { if (isItemVisible(item)) { anyVisible = true; break; } } if (!anyVisible) { // ...scroll to fist selected item makeItemVisible(firstMatch); } } redraw(); return firstMatch != 0; // return if any file was selected } void KrView::invertSelection() { if (op()) op()->setMassSelectionUpdate(true); KConfigGroup grpSvr(_config, "Look&Feel"); bool markDirs = grpSvr.readEntry("Mark Dirs", _MarkDirs); KrViewItem *temp = getCurrentKrViewItem(); for (KrViewItem * it = getFirst(); it != 0; it = getNext(it)) { if (it->name() == "..") continue; if (it->getFileItem()->isDir() && !markDirs && !it->isSelected()) continue; it->setSelected(!it->isSelected()); } if (op()) op()->setMassSelectionUpdate(false); updateView(); if (ensureVisibilityAfterSelect() && temp != 0) makeItemVisible(temp); } QString KrView::firstUnmarkedBelowCurrent(const bool skipCurrent) { if (getCurrentKrViewItem() == 0) return QString(); KrViewItem *iterator = getCurrentKrViewItem(); if (skipCurrent) iterator = getNext(iterator); while (iterator && iterator->isSelected()) iterator = getNext(iterator); if (!iterator) { iterator = getPrev(getCurrentKrViewItem()); while (iterator && iterator->isSelected()) iterator = getPrev(iterator); } if (!iterator) return QString(); return iterator->name(); } void KrView::deleteItem(const QString &name, bool onUpdate) { KrViewItem *viewItem = findItemByName(name); if (!viewItem) return; if (_previews && !onUpdate) _previews->deletePreview(viewItem); preDeleteItem(viewItem); if (viewItem->FILEITEM->isDir()) { --_numDirs; } --_count; delete viewItem; if (!onUpdate) op()->emitSelectionChanged(); } void KrView::addItem(FileItem *fileItem, bool onUpdate) { if (isFiltered(fileItem)) return; KrViewItem *viewItem = preAddItem(fileItem); if (!viewItem) return; // not added if (_previews) _previews->updatePreview(viewItem); if (fileItem->isDir()) ++_numDirs; ++_count; if (!onUpdate) { op()->emitSelectionChanged(); } } void KrView::updateItem(FileItem *newFileItem) { // file name did not change const QString name = newFileItem->getName(); // preserve 'current' and 'selection' const bool isCurrent = getCurrentItem() == name; QStringList selectedNames; getSelectedItems(&selectedNames, false); const bool isSelected = selectedNames.contains(name); // delete old file item deleteItem(name, true); if (!isFiltered(newFileItem)) { addItem(newFileItem, true); } if (isCurrent) setCurrentItem(name, false); if (isSelected) setSelected(newFileItem, true); op()->emitSelectionChanged(); } void KrView::clear() { if(_previews) _previews->clear(); _count = _numDirs = 0; delete _dummyFileItem; _dummyFileItem = 0; redraw(); } bool KrView::handleKeyEvent(QKeyEvent *e) { qDebug() << "key event=" << e; switch (e->key()) { case Qt::Key_Enter : case Qt::Key_Return : { if (e->modifiers() & Qt::ControlModifier) // let the panel handle it e->ignore(); else { KrViewItem * i = getCurrentKrViewItem(); if (i == 0) return true; QString tmp = i->name(); op()->emitExecuted(tmp); } return true; } case Qt::Key_QuoteLeft : // Terminal Emulator bugfix if (e->modifiers() == Qt::ControlModifier) { // let the panel handle it e->ignore(); } else { // a normal click - do a lynx-like moving thing // ask krusader to move to the home directory op()->emitGoHome(); } return true; case Qt::Key_Delete : // delete/trash the file (delete with alternative mode is a panel action) // allow only no modifier or KeypadModifier (i.e. Del on a Numeric Keypad) if ((e->modifiers() & ~Qt::KeypadModifier) == Qt::NoModifier) { op()->emitDefaultDeleteFiles(); } return true; case Qt::Key_Insert: { KrViewItem * i = getCurrentKrViewItem(); if (!i) return true; i->setSelected(!i->isSelected()); if (KrSelectionMode::getSelectionHandler()->insertMovesDown()) { KrViewItem * next = getNext(i); if (next) { setCurrentKrViewItem(next); makeItemVisible(next); } } op()->emitSelectionChanged(); return true; } case Qt::Key_Space: { KrViewItem * viewItem = getCurrentKrViewItem(); if (viewItem != 0) { viewItem->setSelected(!viewItem->isSelected()); if (viewItem->getFileItem()->isDir() && KrSelectionMode::getSelectionHandler()->spaceCalculatesDiskSpace()) { op()->emitQuickCalcSpace(viewItem); } if (KrSelectionMode::getSelectionHandler()->spaceMovesDown()) { KrViewItem * next = getNext(viewItem); if (next) { setCurrentKrViewItem(next); makeItemVisible(next); } } op()->emitSelectionChanged(); } return true; } case Qt::Key_Backspace : // Terminal Emulator bugfix case Qt::Key_Left : if (e->modifiers() == Qt::ControlModifier || e->modifiers() == Qt::ShiftModifier || e->modifiers() == Qt::AltModifier) { // let the panel handle it e->ignore(); } else { // a normal click - do a lynx-like moving thing // ask krusader to move up a directory op()->emitDirUp(); } return true; // safety case Qt::Key_Right : if (e->modifiers() == Qt::ControlModifier || e->modifiers() == Qt::ShiftModifier || e->modifiers() == Qt::AltModifier) { // let the panel handle it e->ignore(); } else { // just a normal click - do a lynx-like moving thing KrViewItem *i = getCurrentKrViewItem(); if (i) op()->emitGoInside(i->name()); } return true; case Qt::Key_Up : if (e->modifiers() == Qt::ControlModifier) { // let the panel handle it - jump to the Location Bar e->ignore(); } else { KrViewItem *item = getCurrentKrViewItem(); if (item) { if (e->modifiers() == Qt::ShiftModifier) { item->setSelected(!item->isSelected()); op()->emitSelectionChanged(); } item = getPrev(item); if (item) { setCurrentKrViewItem(item); makeItemVisible(item); } } } return true; case Qt::Key_Down : if (e->modifiers() == Qt::ControlModifier || e->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) { // let the panel handle it - jump to command line e->ignore(); } else { KrViewItem *item = getCurrentKrViewItem(); if (item) { if (e->modifiers() == Qt::ShiftModifier) { item->setSelected(!item->isSelected()); op()->emitSelectionChanged(); } item = getNext(item); if (item) { setCurrentKrViewItem(item); makeItemVisible(item); } } } return true; case Qt::Key_Home: { if (e->modifiers() & Qt::ShiftModifier) { bool select = true; KrViewItem *pos = getCurrentKrViewItem(); if (pos == 0) pos = getLast(); KrViewItem *item = getFirst(); op()->setMassSelectionUpdate(true); while (item) { item->setSelected(select); if (item == pos) select = false; item = getNext(item); } op()->setMassSelectionUpdate(false); } KrViewItem * first = getFirst(); if (first) { setCurrentKrViewItem(first); makeItemVisible(first); } } return true; case Qt::Key_End: if (e->modifiers() & Qt::ShiftModifier) { bool select = false; KrViewItem *pos = getCurrentKrViewItem(); if (pos == 0) pos = getFirst(); op()->setMassSelectionUpdate(true); KrViewItem *item = getFirst(); while (item) { if (item == pos) select = true; item->setSelected(select); item = getNext(item); } op()->setMassSelectionUpdate(false); } else { KrViewItem *last = getLast(); if (last) { setCurrentKrViewItem(last); makeItemVisible(last); } } return true; case Qt::Key_PageDown: { KrViewItem * current = getCurrentKrViewItem(); int downStep = itemsPerPage(); while (downStep != 0 && current) { KrViewItem * newCurrent = getNext(current); if (newCurrent == 0) break; current = newCurrent; downStep--; } if (current) { setCurrentKrViewItem(current); makeItemVisible(current); } return true; } case Qt::Key_PageUp: { KrViewItem * current = getCurrentKrViewItem(); int upStep = itemsPerPage(); while (upStep != 0 && current) { KrViewItem * newCurrent = getPrev(current); if (newCurrent == 0) break; current = newCurrent; upStep--; } if (current) { setCurrentKrViewItem(current); makeItemVisible(current); } return true; } case Qt::Key_Escape: e->ignore(); return true; // otherwise the selection gets lost??!?? // also it is needed by the panel case Qt::Key_A : // mark all if (e->modifiers() == Qt::ControlModifier) { //FIXME: shouldn't there also be a shortcut for unselecting everything ? selectAllIncludingDirs(); return true; } #if __GNUC__ >= 7 [[gnu::fallthrough]]; #endif default: return false; } return false; } void KrView::zoomIn() { int idx = iconSizes.indexOf(_fileIconSize); if(idx >= 0 && (idx+1) < iconSizes.count()) setFileIconSize(iconSizes[idx+1]); } void KrView::zoomOut() { int idx = iconSizes.indexOf(_fileIconSize); if(idx > 0) setFileIconSize(iconSizes[idx-1]); } void KrView::setFileIconSize(int size) { if(iconSizes.indexOf(size) < 0) return; _fileIconSize = size; if(_previews) { _previews->clear(); _previews->update(); } redraw(); op()->emitRefreshActions(); } int KrView::defaultFileIconSize() { KConfigGroup grpSvr(_config, _instance.name()); return grpSvr.readEntry("IconSize", _FilelistIconSize).toInt(); } void KrView::saveDefaultSettings(KrViewProperties::PropertyType properties) { saveSettings(KConfigGroup(_config, _instance.name()), properties); op()->emitRefreshActions(); } void KrView::restoreDefaultSettings() { restoreSettings(KConfigGroup(_config, _instance.name())); } void KrView::saveSettings(KConfigGroup group, KrViewProperties::PropertyType properties) { if(properties & KrViewProperties::PropIconSize) group.writeEntry("IconSize", fileIconSize()); if(properties & KrViewProperties::PropShowPreviews) group.writeEntry("ShowPreviews", previewsShown()); if(properties & KrViewProperties::PropSortMode) saveSortMode(group); if(properties & KrViewProperties::PropFilter) { group.writeEntry("Filter", static_cast(_properties->filter)); group.writeEntry("FilterApplysToDirs", _properties->filterApplysToDirs); if(_properties->filterSettings.isValid()) _properties->filterSettings.save(KConfigGroup(&group, "FilterSettings")); } } void KrView::restoreSettings(KConfigGroup group) { _ignoreSettingsChange = true; doRestoreSettings(group); _ignoreSettingsChange = false; refresh(); } void KrView::doRestoreSettings(KConfigGroup group) { restoreSortMode(group); setFileIconSize(group.readEntry("IconSize", defaultFileIconSize())); showPreviews(group.readEntry("ShowPreviews", false)); _properties->filter = static_cast(group.readEntry("Filter", static_cast(KrViewProperties::All))); _properties->filterApplysToDirs = group.readEntry("FilterApplysToDirs", false); _properties->filterSettings.load(KConfigGroup(&group, "FilterSettings")); _properties->filterMask = _properties->filterSettings.toQuery(); } void KrView::applySettingsToOthers() { for(int i = 0; i < _instance.m_objects.length(); i++) { KrView *view = _instance.m_objects[i]; if(this != view) { view->_ignoreSettingsChange = true; view->copySettingsFrom(this); view->_ignoreSettingsChange = false; } } } void KrView::sortModeUpdated(KrViewProperties::ColumnType sortColumn, bool descending) { if(sortColumn == _properties->sortColumn && descending == (bool) (_properties->sortOptions & KrViewProperties::Descending)) return; int options = _properties->sortOptions; if(descending) options |= KrViewProperties::Descending; else options &= ~KrViewProperties::Descending; _properties->sortColumn = sortColumn; _properties->sortOptions = static_cast(options); // op()->settingsChanged(KrViewProperties::PropSortMode); } bool KrView::drawCurrent() const { return isFocused() || KConfigGroup(_config, "Look&Feel") .readEntry("Always Show Current Item", _AlwaysShowCurrentItem); } void KrView::saveSortMode(KConfigGroup &group) { group.writeEntry("Sort Column", static_cast(_properties->sortColumn)); group.writeEntry("Descending Sort Order", _properties->sortOptions & KrViewProperties::Descending); } void KrView::restoreSortMode(KConfigGroup &group) { int column = group.readEntry("Sort Column", static_cast(KrViewProperties::Name)); bool isDescending = group.readEntry("Descending Sort Order", false); setSortMode(static_cast(column), isDescending); } QString KrView::krPermissionText(const FileItem * fileitem) { QString tmp; switch (fileitem->isReadable()) { case ALLOWED_PERM: tmp+='r'; break; case UNKNOWN_PERM: tmp+='?'; break; case NO_PERM: tmp+='-'; break; } switch (fileitem->isWriteable()) { case ALLOWED_PERM: tmp+='w'; break; case UNKNOWN_PERM: tmp+='?'; break; case NO_PERM: tmp+='-'; break; } switch (fileitem->isExecutable()) { case ALLOWED_PERM: tmp+='x'; break; case UNKNOWN_PERM: tmp+='?'; break; case NO_PERM: tmp+='-'; break; } return tmp; } QString KrView::permissionsText(const KrViewProperties *properties, const FileItem *fileItem) { return properties->numericPermissions ? QString().asprintf("%.4o", fileItem->getMode() & (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)) : fileItem->getPerm(); } QString KrView::sizeText(const KrViewProperties *properties, KIO::filesize_t size) { return properties->humanReadableSize ? KIO::convertSize(size) : KRpermHandler::parseSize(size); } QString KrView::mimeTypeText(FileItem *fileItem) { QMimeType mt = QMimeDatabase().mimeTypeForName(fileItem->getMime()); return mt.isValid() ? mt.comment() : QString(); } bool KrView::isFiltered(FileItem *fileitem) { if (_quickFilterMask.isValid() && _quickFilterMask.indexIn(fileitem->getName()) == -1) return true; bool filteredOut = false; bool isDir = fileitem->isDir(); if (!isDir || (isDir && properties()->filterApplysToDirs)) { switch (properties()->filter) { case KrViewProperties::All : break; case KrViewProperties::Custom : if (!properties()->filterMask.match(fileitem)) filteredOut = true; break; case KrViewProperties::Dirs: if (!isDir) filteredOut = true; break; case KrViewProperties::Files: if (isDir) filteredOut = true; break; default: break; } } return filteredOut; } void KrView::setFiles(DirListerInterface *files) { if(files != _files) { clear(); if(_files) QObject::disconnect(_files, 0, op(), 0); _files = files; } if(!_files) return; QObject::disconnect(_files, 0, op(), 0); QObject::connect(_files, &DirListerInterface::scanDone, op(), &KrViewOperator::startUpdate); QObject::connect(_files, &DirListerInterface::cleared, op(), &KrViewOperator::cleared); QObject::connect(_files, &DirListerInterface::addedFileItem, op(), &KrViewOperator::fileAdded); QObject::connect(_files, &DirListerInterface::updatedFileItem, op(), &KrViewOperator::fileUpdated); } void KrView::setFilter(KrViewProperties::FilterSpec filter, FilterSettings customFilter, bool applyToDirs) { _properties->filter = filter; _properties->filterSettings = customFilter; _properties->filterMask = customFilter.toQuery(); _properties->filterApplysToDirs = applyToDirs; refresh(); } void KrView::setFilter(KrViewProperties::FilterSpec filter) { KConfigGroup cfg(_config, "Look&Feel"); bool rememberSettings = cfg.readEntry("FilterDialogRemembersSettings", _FilterDialogRemembersSettings); bool applyToDirs = rememberSettings ? _properties->filterApplysToDirs : false; switch (filter) { case KrViewProperties::All : break; case KrViewProperties::Custom : { FilterDialog dialog(_widget, i18n("Filter Files"), QStringList(i18n("Apply filter to folders")), false); dialog.checkExtraOption(i18n("Apply filter to folders"), applyToDirs); if(rememberSettings) dialog.applySettings(_properties->filterSettings); dialog.exec(); FilterSettings s(dialog.getSettings()); if(!s.isValid()) // if the user canceled - quit return; _properties->filterSettings = s; _properties->filterMask = s.toQuery(); applyToDirs = dialog.isExtraOptionChecked(i18n("Apply filter to folders")); } break; default: return; } _properties->filterApplysToDirs = applyToDirs; _properties->filter = filter; refresh(); } void KrView::customSelection(bool select) { KConfigGroup grpSvr(_config, "Look&Feel"); bool includeDirs = grpSvr.readEntry("Mark Dirs", _MarkDirs); FilterDialog dialog(0, i18n("Select Files"), QStringList(i18n("Apply selection to folders")), false); dialog.checkExtraOption(i18n("Apply selection to folders"), includeDirs); dialog.exec(); KRQuery query = dialog.getQuery(); // if the user canceled - quit if (query.isNull()) return; includeDirs = dialog.isExtraOptionChecked(i18n("Apply selection to folders")); changeSelection(query, select, includeDirs); } void KrView::refresh() { const QString currentItem = !nameToMakeCurrent().isEmpty() ? // nameToMakeCurrent() : getCurrentItem(); bool scrollToCurrent = !nameToMakeCurrent().isEmpty() || isItemVisible(getCurrentKrViewItem()); setNameToMakeCurrent(QString()); const QModelIndex currentIndex = getCurrentIndex(); const QList selection = selectedUrls(); clear(); if(!_files) return; QList fileItems; // if we are not at the root add the ".." entry if(!_files->isRoot()) { _dummyFileItem = FileItem::createDummy(); fileItems << _dummyFileItem; } foreach(FileItem *fileitem, _files->fileItems()) { if(!fileitem || isFiltered(fileitem)) continue; if(fileitem->isDir()) _numDirs++; _count++; fileItems << fileitem; } populate(fileItems, _dummyFileItem); if(!selection.isEmpty()) setSelectionUrls(selection); if (!currentItem.isEmpty()) { if (currentItem == ".." && _count > 0 && // !_quickFilterMask.isEmpty() && _quickFilterMask.isValid()) { // In a filtered view we should never select the dummy entry if // there are real matches. setCurrentKrViewItem(getNext(getFirst())); } else { setCurrentItem(currentItem, scrollToCurrent, currentIndex); } } else { setCurrentKrViewItem(getFirst()); } updatePreviews(); redraw(); op()->emitSelectionChanged(); } void KrView::setSelected(const FileItem* fileitem, bool select) { if (fileitem == _dummyFileItem) return; if (select) clearSavedSelection(); intSetSelected(fileitem, select); } void KrView::saveSelection() { _savedSelection = selectedUrls(); op()->emitRefreshActions(); } void KrView::restoreSelection() { if(canRestoreSelection()) setSelectionUrls(_savedSelection); } void KrView::clearSavedSelection() { _savedSelection.clear(); op()->emitRefreshActions(); } void KrView::markSameBaseName() { KrViewItem* item = getCurrentKrViewItem(); if (!item) return; KRQuery query(QString("%1.*").arg(item->name(false))); changeSelection(query, true, false); } void KrView::markSameExtension() { KrViewItem* item = getCurrentKrViewItem(); if (!item) return; KRQuery query(QString("*.%1").arg(item->extension())); changeSelection(query, true, false); } diff --git a/krusader/Panel/krerrordisplay.cpp b/krusader/Panel/krerrordisplay.cpp index 774d827d..bdb6de9f 100644 --- a/krusader/Panel/krerrordisplay.cpp +++ b/krusader/Panel/krerrordisplay.cpp @@ -1,67 +1,67 @@ /***************************************************************************** * Copyright (C) 2010 Jan Lepper * * Copyright (C) 2010-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 "krerrordisplay.h" #include #include "krcolorcache.h" KrErrorDisplay::KrErrorDisplay(QWidget *parent) : QLabel(parent), _currentDim(100) { setAutoFillBackground(true); _startColor = QColor(240,150,150); QPalette p(palette()); _targetColor = p.color(QPalette::Window); p.setColor(QPalette::Window, _startColor); setPalette(p); _dimTimer.setSingleShot(true); - connect(&_dimTimer, SIGNAL(timeout()), this, SLOT(slotTimeout())); + connect(&_dimTimer, &QTimer::timeout, this, &KrErrorDisplay::slotTimeout); } void KrErrorDisplay::setText(QString text) { QLabel::setText(text); _currentDim = 100; QPalette p(palette()); p.setColor(QPalette::Window, _startColor); setPalette(p); _dimTimer.start(5000); } void KrErrorDisplay::slotTimeout() { _currentDim -= 2; dim(); if( _currentDim > 0) _dimTimer.start(50); } void KrErrorDisplay::dim() { QPalette p(palette()); p.setColor(QPalette::Window, KrColorCache::dimColor(_startColor, _currentDim, _targetColor)); setPalette(p); } diff --git a/krusader/Panel/krpreviews.cpp b/krusader/Panel/krpreviews.cpp index 95c91ae2..f58282c9 100644 --- a/krusader/Panel/krpreviews.cpp +++ b/krusader/Panel/krpreviews.cpp @@ -1,130 +1,130 @@ /***************************************************************************** * Copyright (C) 2009 Jan Lepper * * 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 "krpreviews.h" #include "krpreviewjob.h" #include "krcolorcache.h" #include "PanelView/krview.h" #include "PanelView/krviewitem.h" #include "../FileSystem/fileitem.h" #include "../defaults.h" #include #define ASSERT(what) if(!what) abort(); KrPreviews::KrPreviews(KrView *view) : _job(0), _view(view) { _dim = KrColorCache::getColorCache().getDimSettings(_dimColor, _dimFactor); - connect(&KrColorCache::getColorCache(), SIGNAL(colorsRefreshed()), SLOT(slotRefreshColors())); + connect(&KrColorCache::getColorCache(), &KrColorCache::colorsRefreshed, this, &KrPreviews::slotRefreshColors); } KrPreviews::~KrPreviews() { clear(); } void KrPreviews::clear() { if(_job) { _job->kill(KJob::EmitResult); _job = 0; } _previews.clear(); _previewsInactive.clear(); } void KrPreviews::update() { if(_job) return; for (KrViewItem *it = _view->getFirst(); it != 0; it = _view->getNext(it)) { if(!_previews.contains(it->getFileItem())) updatePreview(it); } } void KrPreviews::deletePreview(KrViewItem *item) { if(_job) { _job->removeItem(item); } removePreview(item->getFileItem()); } void KrPreviews::updatePreview(KrViewItem *item) { if(!_job) { _job = new KrPreviewJob(this); - connect(_job, SIGNAL(result(KJob*)), SLOT(slotJobResult(KJob*))); + connect(_job, &KrPreviewJob::result, this, &KrPreviews::slotJobResult); _view->op()->emitPreviewJobStarted(_job); } _job->scheduleItem(item); } bool KrPreviews::getPreview(const FileItem *file, QPixmap &pixmap, bool active) { if(active || !_dim) pixmap = _previews.value(file); else pixmap = _previewsInactive.value(file); return !pixmap.isNull(); } void KrPreviews::slotJobResult(KJob *job) { (void) job; _job = 0; } void KrPreviews::slotRefreshColors() { clear(); _dim = KrColorCache::getColorCache().getDimSettings(_dimColor, _dimFactor); update(); } void KrPreviews::addPreview(const FileItem *file, const QPixmap &preview) { QPixmap active, inactive; if(preview.isNull()) { active = KrView::getIcon((FileItem *)file, true, _view->fileIconSize()); if(_dim) inactive = KrView::getIcon((FileItem *)file, false, _view->fileIconSize()); } else { active = KrView::processIcon(preview, false, _dimColor, _dimFactor, file->isSymLink()); if(_dim) inactive = KrView::processIcon(preview, true, _dimColor, _dimFactor, file->isSymLink()); } _previews.insert(file, active); if(_dim) _previewsInactive.insert(file, inactive); } void KrPreviews::removePreview(const FileItem *file) { _previews.remove(file); _previewsInactive.remove(file); } diff --git a/krusader/Panel/krsearchbar.cpp b/krusader/Panel/krsearchbar.cpp index 7e144942..e9b6ced0 100644 --- a/krusader/Panel/krsearchbar.cpp +++ b/krusader/Panel/krsearchbar.cpp @@ -1,445 +1,445 @@ /***************************************************************************** * Copyright (C) 2010 Jan Lepper * * Copyright (C) 2010-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 "krsearchbar.h" #include "PanelView/krview.h" #include "PanelView/krviewitem.h" #include "../FileSystem/dirlisterinterface.h" #include "../defaults.h" #include "../krglobal.h" #include "../icon.h" #include #include #include #include #include #include #include #include #include KrSearchBar::KrSearchBar(KrView *view, QWidget *parent) : QWidget(parent), _view(0), _rightArrowEntersDirFlag(true) { // close button QToolButton *closeButton = new QToolButton(this); closeButton->setAutoRaise(true); closeButton->setIcon(Icon(QStringLiteral("dialog-close"))); closeButton->setToolTip(i18n("Close the search bar")); - connect(closeButton, SIGNAL(clicked()), SLOT(hideBar())); + connect(closeButton, &QToolButton::clicked, this, &KrSearchBar::hideBar); // combo box for changing search mode _modeBox = new QComboBox(this); _modeBox->addItems(QStringList() << i18n("Search") << i18n("Select") << i18n("Filter")); _modeBox->setToolTip(i18n("Change the search mode")); - connect(_modeBox, SIGNAL(currentIndexChanged(int)), SLOT(onModeChange())); + connect(_modeBox, QOverload::of(&QComboBox::currentIndexChanged), this, &KrSearchBar::onModeChange); _currentMode = static_cast(_modeBox->currentIndex()); // combo box for entering search string _textBox = new KComboBox(this); _textBox->setEditable(true); _modeBox->setToolTip(i18n("Enter or select search string")); QStringList savedSearches = KConfigGroup(krConfig, "Private") .readEntry("Predefined Selections", QStringList()); if (savedSearches.count() > 0) _textBox->addItems(savedSearches); _textBox->setCurrentText(""); _textBox->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred)); - connect(_textBox, SIGNAL(currentTextChanged(QString)), SLOT(onSearchChange())); + connect(_textBox, &KComboBox::currentTextChanged, this, &KrSearchBar::onSearchChange); QToolButton *saveSearchBtn = new QToolButton(this); saveSearchBtn->setIcon(Icon("document-save")); saveSearchBtn->setFixedSize(20, 20); saveSearchBtn->setToolTip(i18n("Save the current search string")); - connect(saveSearchBtn, SIGNAL(clicked()), this, SLOT(saveSearchString())); + connect(saveSearchBtn, &QToolButton::clicked, this, &KrSearchBar::saveSearchString); _openSelectDialogBtn = new QToolButton(this); _openSelectDialogBtn->setIcon(Icon("configure")); _openSelectDialogBtn->setFixedSize(20, 20); _openSelectDialogBtn->setToolTip(i18n("Open selection dialog")); QHBoxLayout *layout = new QHBoxLayout(this); layout->setMargin(0); layout->addWidget(closeButton); layout->addWidget(_modeBox); layout->addWidget(_textBox); layout->addWidget(saveSearchBtn); layout->addWidget(_openSelectDialogBtn); _textBox->installEventFilter(this); setView(view); } void KrSearchBar::setView(KrView *view) { if (_view) { _view->widget()->removeEventFilter(this); disconnect(_openSelectDialogBtn, 0, 0, 0); } _view = view; connect(_openSelectDialogBtn, &QToolButton::clicked, [this](){ _view->customSelection(true); }); _view->widget()->installEventFilter(this); } void KrSearchBar::hideBarIfSearching() { if (_currentMode == MODE_SEARCH) hideBar(); } // #### public slots void KrSearchBar::showBar(SearchMode mode) { int index = mode == MODE_DEFAULT ? KConfigGroup(krConfig, "Look&Feel") .readEntry("Default Search Mode", QString::number(KrSearchBar::MODE_SEARCH)) .toInt() : mode; _modeBox->setCurrentIndex(index); show(); _textBox->setFocus(); _rightArrowEntersDirFlag = true; } void KrSearchBar::hideBar() { resetSearch(); if (_textBox->hasFocus()) _view->widget()->setFocus(); hide(); } void KrSearchBar::resetSearch() { _textBox->clearEditText(); indicateMatch(true); } // #### protected slots void KrSearchBar::onModeChange() { if (_currentMode == MODE_FILTER) { _view->op()->filterSearch(QString(), true); // reset filter } _currentMode = static_cast(_modeBox->currentIndex()); onSearchChange(); } void KrSearchBar::onSearchChange() { const QString text = _textBox->currentText(); switch(_currentMode) { case MODE_SEARCH: { const bool anyMatch = _view->op()->searchItem(text, caseSensitive()); indicateMatch(anyMatch); break; } case MODE_SELECT: { _view->unselectAll(); if (!text.isEmpty()) { const bool anyMatch = _view->changeSelection(KRQuery(text, caseSensitive()), true); indicateMatch(anyMatch); } break; } case MODE_FILTER: { const bool anyMatch =_view->op()->filterSearch(text, caseSensitive()); indicateMatch(anyMatch); break; } default: qWarning() << "unexpected search mode: " << _currentMode; } _textBox->setFocus(); } void KrSearchBar::saveSearchString() { KConfigGroup group(krConfig, "Private"); QStringList lst = group.readEntry("Predefined Selections", QStringList()); QString searchString = _textBox->currentText(); if (lst.indexOf(searchString) != -1) { // already saved return; } lst.append(searchString); group.writeEntry("Predefined Selections", lst); _textBox->addItem(searchString); QToolTip::showText(QCursor::pos(), i18n("Saved search text to history")); } // #### protected void KrSearchBar::keyPressEvent(QKeyEvent *event) { const bool handled = handleKeyPressEvent(static_cast(event)); if (handled) { return; } QWidget::keyPressEvent(event); } bool KrSearchBar::eventFilter(QObject *watched, QEvent *event) { if (event->type() != QEvent::ShortcutOverride && watched == _view->widget()) { QKeyEvent *ke = static_cast(event); // overwrite "escape" shortcut if bar is shown if ((ke->key() == Qt::Key_Escape) && (ke->modifiers() == Qt::NoModifier) && !isHidden()) { ke->accept(); handleKeyPressEvent(ke); return true; } } if (event->type() != QEvent::KeyPress) { return false; } qDebug() << "key press event=" << event; QKeyEvent *ke = static_cast(event); auto modifiers = ke->modifiers(); if (watched == _view->widget()) { KConfigGroup grpSv(krConfig, "Look&Feel"); const bool autoShow = grpSv.readEntry("New Style Quicksearch", _NewStyleQuicksearch); if (isHidden() && !autoShow) { return false; } if (!isHidden()) { // view widget has focus but search bar is open and may wants to steal key events const bool handled = handleKeyPressEvent(ke); if (handled) { return true; } } if (isHidden() || // view can handle its own event if user does not want to remove text or... !((ke->key() == Qt::Key_Backspace && !_textBox->currentText().isEmpty()) || // ...insert space in search bar (even if not focused) (ke->key() == Qt::Key_Space && _currentMode == KrSearchBar::MODE_SEARCH))) { const bool handled = _view->handleKeyEvent(ke); if (handled) { return true; } } if (ke->text().isEmpty() || (modifiers != Qt::NoModifier && modifiers != Qt::ShiftModifier && modifiers != Qt::KeypadModifier)) { return false; } // start searching if bar is hidden? if (isHidden()) { if (autoShow) { showBar(); } else { return false; } } // bar is visible and gets the key input _textBox->setFocus(); if (ke->key() == Qt::Key_Backspace) { _textBox->lineEdit()->backspace(); } else { _textBox->setEditText(_textBox->currentText().append(ke->text())); } return true; } else if (watched == _textBox) { const bool handled = handleKeyPressEvent(ke); if (handled) { _view->widget()->setFocus(); return true; } // allow the view to handle (most) key events from the text box if ((modifiers == Qt::NoModifier || modifiers == Qt::KeypadModifier) && ke->key() != Qt::Key_Space && ke->key() != Qt::Key_Backspace && ke->key() != Qt::Key_Left && ke->key() != Qt::Key_Right) { const bool handled = _view->handleKeyEvent(ke); if (handled) { _view->widget()->setFocus(); return true; } } } return false; } // #### private bool KrSearchBar::handleKeyPressEvent(QKeyEvent *ke) { auto modifiers = ke->modifiers(); if (!(modifiers == Qt::NoModifier || modifiers == Qt::KeypadModifier)) { return false; } switch (ke->key()) { case Qt::Key_Escape: { hideBar(); return true; } case Qt::Key_Enter: case Qt::Key_Return: { hideBarIfSearching(); return false; } case Qt::Key_Up: return handleUpDownKeyPress(true); case Qt::Key_Down: return handleUpDownKeyPress(false); case Qt::Key_Left: case Qt::Key_Right: return handleLeftRightKeyPress(ke); case Qt::Key_Insert: { // select current item and jump to next search result KrViewItem * item = _view->getCurrentKrViewItem(); if (item) { item->setSelected(!item->isSelected()); _view->op()->searchItem(_textBox->currentText(), caseSensitive(), 1); } return true; } case Qt::Key_Home: { // jump to first search result KrViewItem * item = _view->getLast(); if (item) { _view->setCurrentKrViewItem(_view->getLast()); _view->op()->searchItem(_textBox->currentText(), caseSensitive(), 1); } return true; } case Qt::Key_End: { // jump to last search result KrViewItem * item = _view->getFirst(); if (item) { _view->setCurrentKrViewItem(_view->getFirst()); _view->op()->searchItem(_textBox->currentText(), caseSensitive(), -1); } return true; } } return false; } bool KrSearchBar::handleUpDownKeyPress(bool up) { if (_currentMode != MODE_SEARCH) { return false; } const bool updownCancel = KConfigGroup(krConfig, "Look&Feel") .readEntry("Up/Down Cancels Quicksearch", false); if (updownCancel) { hideBar(); return false; } const bool anyMatch = _view->op()->searchItem(_textBox->currentText(), caseSensitive(), up ? -1 : 1); indicateMatch(anyMatch); return true; } bool KrSearchBar::handleLeftRightKeyPress(QKeyEvent *ke) { const bool useQuickDirectoryNavigation = KConfigGroup(krConfig, "Look&Feel") .readEntry("Navigation with Right Arrow Quicksearch", true); if (!useQuickDirectoryNavigation) return false; const bool isRight = ke->key() == Qt::Key_Right; if (isRight && _rightArrowEntersDirFlag) { // in case the Right Arrow has been pressed when cursor is in the end of the line if (_textBox->cursorPosition() == _textBox->currentText().length()) // we let the view enter the directory if it's selected return _view->handleKeyEvent(ke); } else { _rightArrowEntersDirFlag = false; } return false; } void KrSearchBar::indicateMatch(bool anyMatch) { KConfigGroup gc(krConfig, "Colors"); QPalette p = QGuiApplication::palette(); QString foreground, background; if (anyMatch) { foreground = "Quicksearch Match Foreground"; background = "Quicksearch Match Background"; } else { foreground = "Quicksearch Non-match Foreground"; background = "Quicksearch Non-match Background"; } QColor fore = Qt::black; QString foreSetting = gc.readEntry(foreground, QString()); if (foreSetting == "KDE default") { fore = p.color(QPalette::Active, QPalette::Text); } else if (!foreSetting.isEmpty()) { fore = gc.readEntry(foreground, fore); } QColor back = anyMatch ? QColor(192, 255, 192) : QColor(255, 192, 192); QString backSetting = gc.readEntry(background, QString()); if (backSetting == "KDE default") { back = p.color(QPalette::Active, QPalette::Base); } else if (!backSetting.isEmpty()) { back = gc.readEntry(background, back); } QPalette pal = palette(); pal.setColor(QPalette::Base, back); pal.setColor(QPalette::Text, fore); _textBox->lineEdit()->setPalette(pal); } bool KrSearchBar::caseSensitive() { KConfigGroup grpSvr(krConfig, "Look&Feel"); return grpSvr.readEntry("Case Sensitive Quicksearch", _CaseSensitiveQuicksearch); } diff --git a/krusader/Panel/listpanelactions.cpp b/krusader/Panel/listpanelactions.cpp index af9bf3f8..9f5cb4fa 100644 --- a/krusader/Panel/listpanelactions.cpp +++ b/krusader/Panel/listpanelactions.cpp @@ -1,219 +1,219 @@ /***************************************************************************** * Copyright (C) 2010 Jan Lepper * * Copyright (C) 2010-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 "listpanelactions.h" #include "listpanel.h" #include "panelfunc.h" #include "PanelView/krviewfactory.h" #include "../krmainwindow.h" #include "../Dialogs/krdialogs.h" #include "../KViewer/krviewer.h" #include "../icon.h" // QtCore #include // QtWidgets #include #include #include ListPanelActions::ListPanelActions(QObject *parent, KrMainWindow *mainWindow) : ActionsBase(parent, mainWindow) { // set view type QSignalMapper *mapper = new QSignalMapper(this); - connect(mapper, SIGNAL(mapped(int)), SLOT(setView(int))); + connect(mapper, QOverload::of(&QSignalMapper::mapped), this, &ListPanelActions::setView); QActionGroup *group = new QActionGroup(this); group->setExclusive(true); QList views = KrViewFactory::registeredViews(); for(int i = 0; i < views.count(); i++) { KrViewInstance *inst = views[i]; QAction *action = new QAction(Icon(inst->iconName()), inst->description(), group); action->setCheckable(true); - connect(action, SIGNAL(triggered()), mapper, SLOT(map())); + connect(action, &QAction::triggered, mapper, QOverload<>::of(&QSignalMapper::map)); mapper->setMapping(action, inst->id()); _mainWindow->actions()->addAction("view" + QString::number(i), action); _mainWindow->actions()->setDefaultShortcut(action, inst->shortcut()); setViewActions.insert(inst->id(), action); } // standard actions actHistoryBackward = stdAction(KStandardAction::Back, _func, SLOT(historyBackward())); actHistoryForward = stdAction(KStandardAction::Forward, _func, SLOT(historyForward())); //FIXME: second shortcut for up: see actDirUp // KStandardAction::up( this, SLOT(dirUp()), actionCollection )->setShortcut(Qt::Key_Backspace); /* Shortcut disabled because of the Terminal Emulator bug. */ actDirUp = stdAction(KStandardAction::Up, _func, SLOT(dirUp())); actHome = stdAction(KStandardAction::Home, _func, SLOT(home())); actCut = stdAction(KStandardAction::Cut, _func, SLOT(cut())); actCut->setText(i18n("Cut to Clipboard")); // removing alternative shift+del shortcut, it is used for the alternative delete files action QList cutShortcuts = actCut->shortcuts(); cutShortcuts.removeAll(QKeySequence(Qt::SHIFT | Qt::Key_Delete)); _mainWindow->actions()->setDefaultShortcuts(actCut, cutShortcuts); actCopy = stdAction(KStandardAction::Copy, _func, SLOT(copyToClipboard())); actCopy->setText(i18n("Copy to Clipboard")); actPaste = stdAction(KStandardAction::Paste, _func, SLOT(pasteFromClipboard())); actPaste->setText(i18n("Paste from Clipboard")); // Fn keys actRenameF2 = action(i18n("Rename"), "edit-rename", Qt::Key_F2, _func, SLOT(rename()) , "F2_Rename"); actViewFileF3 = action(i18n("View File"), 0, Qt::Key_F3, _func, SLOT(view()), "F3_View"); actEditFileF4 = action(i18n("Edit File"), 0, Qt::Key_F4, _func, SLOT(edit()) , "F4_Edit"); actCopyF5 = action(i18n("Copy to other panel"), 0, Qt::Key_F5, _func, SLOT(copyFiles()) , "F5_Copy"); actMoveF6 = action(i18n("Move to other panel"), 0, Qt::Key_F6, _func, SLOT(moveFiles()) , "F6_Move"); actCopyDelayedF5 = action(i18n("Copy delayed..."), 0, Qt::SHIFT + Qt::Key_F5, _func, SLOT(copyFilesDelayed()) , "F5_Copy_Queue"); actMoveDelayedShiftF6 = action(i18n("Move delayed..."), 0, Qt::SHIFT + Qt::Key_F6, _func, SLOT(moveFilesDelayed()) , "F6_Move_Queue"); actNewFolderF7 = action(i18n("New Folder..."), "folder-new", Qt::Key_F7, _func, SLOT(mkdir()) , "F7_Mkdir"); actDeleteF8 = action(i18n("Delete"), "edit-delete", Qt::Key_F8, _func, SLOT(defaultDeleteFiles()) , "F8_Delete"); actTerminalF9 = action(i18n("Start Terminal Here"), "utilities-terminal", Qt::Key_F9, _func, SLOT(terminal()) , "F9_Terminal"); action(i18n("&New Text File..."), "document-new", Qt::SHIFT + Qt::Key_F4, _func, SLOT(editNew()), "edit_new_file"); action(i18n("F3 View Dialog"), 0, Qt::SHIFT + Qt::Key_F3, _func, SLOT(viewDlg()), "F3_ViewDlg"); // file operations action(i18n("Right-click Menu"), 0, Qt::Key_Menu, _gui, SLOT(rightclickMenu()), "rightclick menu"); actProperties = action(i18n("&Properties..."), "document-properties", Qt::ALT + Qt::Key_Return, _func, SLOT(properties()), "properties"); actCompDirs = action(i18n("&Compare Folders"), "kr_comparedirs", Qt::ALT + Qt::SHIFT + Qt::Key_C, _gui, SLOT(compareDirs()), "compare dirs"); actCalculate = action(i18n("Calculate &Occupied Space"), "accessories-calculator", 0, _func, SLOT(calcSpace()), "calculate"); actPack = action(i18n("Pac&k..."), "archive-insert", Qt::ALT + Qt::SHIFT + Qt::Key_P, _func, SLOT(pack()), "pack"); actUnpack = action(i18n("&Unpack..."), "archive-extract", Qt::ALT + Qt::SHIFT + Qt::Key_U, _func, SLOT(unpack()), "unpack"); actCreateChecksum = action(i18n("Create Checksum..."), "document-edit-sign", 0, _func, SLOT(createChecksum()), "create checksum"); actMatchChecksum = action(i18n("Verify Checksum..."), "document-edit-decrypt-verify", 0, _func, SLOT(matchChecksum()), "match checksum"); action(i18n("New Symlink..."), 0, Qt::CTRL + Qt::ALT + Qt::Key_S, _func, SLOT(krlink()), "new symlink"); actTest = action(i18n("T&est Archive"), "archive-extract", Qt::ALT + Qt::SHIFT + Qt::Key_E, _func, SLOT(testArchive()), "test archives"); action(i18n("Alternative Delete"), "edit-delete", Qt::Key_Delete + Qt::CTRL, _func, SLOT(alternativeDeleteFiles()), "alternative delete"); // navigation actRoot = action(i18n("Root"), "folder-red", Qt::CTRL + Qt::Key_Backspace, _func, SLOT(root()), "root"); actCdToOther = action(i18n("Go to Other Panel's Folder"), 0, Qt::CTRL + Qt::Key_Equal, _func, SLOT(cdToOtherPanel()), "cd to other panel"); action(i18n("&Reload"), "view-refresh", Qt::CTRL + Qt::Key_R, _func, SLOT(refresh()), "std_redisplay"); actCancelRefresh = action(i18n("Cancel Refresh of View"), "dialog-cancel", 0, _gui, SLOT(cancelProgress()), "cancel refresh"); actFTPNewConnect = action(i18n("New Net &Connection..."), "network-connect", Qt::CTRL + Qt::Key_N, _func, SLOT(newFTPconnection()), "ftp new connection"); actFTPDisconnect = action(i18n("Disconnect &from Net"), "network-disconnect", Qt::SHIFT + Qt::CTRL + Qt::Key_D, _func, SLOT(FTPDisconnect()), "ftp disconnect"); action(i18n("Sync Panels"), 0, Qt::ALT + Qt::SHIFT + Qt::Key_O, _func, SLOT(syncOtherPanel()), "sync panels"); actJumpBack = action(i18n("Jump Back"), "go-jump", Qt::CTRL + Qt::Key_J, _gui, SLOT(jumpBack()), "jump_back"); actSetJumpBack = action(i18n("Set Jump Back Point"), "go-jump-definition", Qt::CTRL + Qt::SHIFT + Qt::Key_J, _gui, SLOT(setJumpBack()), "set_jump_back"); actSyncBrowse = action(i18n("S&ynchron Folder Changes"), "kr_syncbrowse_off", Qt::ALT + Qt::SHIFT + Qt::Key_Y, _gui, SLOT(toggleSyncBrowse()), "sync browse"); actLocationBar = action(i18n("Go to Location Bar"), 0, Qt::CTRL + Qt::Key_L, _gui, SLOT(editLocation()), "location_bar"); toggleAction(i18n("Toggle Sidebar"), 0, Qt::ALT + Qt::Key_Down, _gui, SLOT(toggleSidebar()), "toggle sidebar"); action(i18n("Bookmarks"), 0, Qt::CTRL + Qt::Key_D, _gui, SLOT(openBookmarks()), "bookmarks"); action(i18n("Left Bookmarks"), 0, 0, this, SLOT(openLeftBookmarks()), "left bookmarks"); action(i18n("Right Bookmarks"), 0, 0, this, SLOT(openRightBookmarks()), "right bookmarks"); action(i18n("History"), 0, Qt::CTRL + Qt::Key_H, _gui, SLOT(openHistory()), "history"); action(i18n("Left History"), 0, Qt::ALT + Qt::CTRL + Qt::Key_Left, this, SLOT(openLeftHistory()), "left history"); action(i18n("Right History"), 0, Qt::ALT + Qt::CTRL + Qt::Key_Right, this, SLOT(openRightHistory()), "right history"); action(i18n("Media"), 0, Qt::CTRL + Qt::Key_M, _gui, SLOT(openMedia()), "media"); action(i18n("Left Media"), 0, Qt::CTRL + Qt::SHIFT + Qt::Key_Left, this, SLOT(openLeftMedia()), "left media"); action(i18n("Right Media"), 0, Qt::CTRL + Qt::SHIFT + Qt::Key_Right, this, SLOT(openRightMedia()), "right media"); // quick search bar action(i18n("Find in folder..."), 0, Qt::CTRL + Qt::Key_F, _gui, SLOT(showSearchBar()), "search bar"); action(i18n("Select in folder..."), 0, Qt::CTRL + Qt::SHIFT + Qt::Key_S, _gui, SLOT(showSearchBarSelection()), "search bar selection"); action(i18n("Filter in folder..."), 0, Qt::CTRL + Qt::Key_I, _gui, SLOT(showSearchBarFilter()), "search bar filter"); // and at last we can set the tool-tips actRoot->setToolTip(i18n("ROOT (/)")); actRenameF2->setToolTip(i18n("Rename file, folder, etc.")); actViewFileF3->setToolTip(i18n("Open file in viewer.")); actEditFileF4->setToolTip(i18n("

Edit file.

" "

The editor can be defined in Konfigurator, " "default is internal editor.

")); actCopyF5->setToolTip(i18n("Copy file from one panel to the other.")); actMoveF6->setToolTip(i18n("Move file from one panel to the other.")); actNewFolderF7->setToolTip(i18n("Create folder in current panel.")); actDeleteF8->setToolTip(i18n("Delete file, folder, etc.")); actTerminalF9->setToolTip(i18n("

Open terminal in current folder.

" "

The terminal can be defined in Konfigurator, " "default is konsole.

")); } void ListPanelActions::activePanelChanged() { _gui.reconnect(activePanel()->gui); _func.reconnect(activePanel()->func); } void ListPanelActions::guiUpdated() { QList actions; foreach(QAction *action, setViewActions.values()) actions << action; static_cast(_mainWindow)->plugActionList("view_actionlist", actions); } inline KrPanel *ListPanelActions::activePanel() { return static_cast(_mainWindow)->activePanel(); } inline KrPanel *ListPanelActions::leftPanel() { return static_cast(_mainWindow)->leftPanel(); } inline KrPanel *ListPanelActions::rightPanel() { return static_cast(_mainWindow)->rightPanel(); } // set view type void ListPanelActions::setView(int id) { activePanel()->gui->changeType(id); } // navigation void ListPanelActions::openLeftBookmarks() { leftPanel()->gui->openBookmarks(); } void ListPanelActions::openRightBookmarks() { rightPanel()->gui->openBookmarks(); } void ListPanelActions::openLeftHistory() { leftPanel()->gui->openHistory(); } void ListPanelActions::openRightHistory() { rightPanel()->gui->openHistory(); } void ListPanelActions::openLeftMedia() { leftPanel()->gui->openMedia(); } void ListPanelActions::openRightMedia() { rightPanel()->gui->openMedia(); } diff --git a/krusader/Panel/listpanelframe.cpp b/krusader/Panel/listpanelframe.cpp index 68b89d61..5ab08240 100644 --- a/krusader/Panel/listpanelframe.cpp +++ b/krusader/Panel/listpanelframe.cpp @@ -1,107 +1,107 @@ /***************************************************************************** * Copyright (C) 2010 Jan Lepper * * Copyright (C) 2010-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 "listpanelframe.h" #include "krcolorcache.h" #include "../krglobal.h" // QtCore #include // QtGui #include #include #include #include ListPanelFrame::ListPanelFrame(QWidget *parent, QString color) : QFrame(parent), color(color) { if(!color.isEmpty()) { colorsChanged(); refreshColors(false); setAutoFillBackground(true); - connect(&KrColorCache::getColorCache(), SIGNAL(colorsRefreshed()), SLOT(colorsChanged())); + connect(&KrColorCache::getColorCache(), &KrColorCache::colorsRefreshed, this, &ListPanelFrame::colorsChanged); } } void ListPanelFrame::dragEnterEvent(QDragEnterEvent *e) { if (acceptDrops()) { QList URLs = KUrlMimeData::urlsFromMimeData(e->mimeData()); e->setAccepted(!URLs.isEmpty()); } else QFrame::dragEnterEvent(e); } void ListPanelFrame::colorsChanged() { QPalette p = QGuiApplication::palette(); QColor windowForeground = p.color(QPalette::Active, QPalette::WindowText); QColor windowBackground = p.color(QPalette::Active, QPalette::Window); KConfigGroup gc(krConfig, "Colors"); QColor fgAct = getColor(gc, color + " Foreground Active", p.color(QPalette::Active, QPalette::HighlightedText), windowForeground); QColor bgAct = getColor(gc, color + " Background Active", p.color(QPalette::Active, QPalette::Highlight), windowBackground); QColor fgInact = getColor(gc, color + " Foreground Inactive", p.color(QPalette::Active, QPalette::Text), windowForeground); QColor bgInact = getColor(gc, color + " Background Inactive", p.color(QPalette::Active, QPalette::Base), windowBackground); palActive = palInactive = palette(); // --- active --- // foreground palActive.setColor(QPalette::WindowText, fgAct); palActive.setColor(QPalette::ButtonText, fgAct); // background palActive.setColor(QPalette::Window, bgAct); palActive.setColor(QPalette::Button, bgAct); // --- inactive --- // foreground palInactive.setColor(QPalette::WindowText, fgInact); palInactive.setColor(QPalette::ButtonText, fgInact); // background palInactive.setColor(QPalette::Window, bgInact); palInactive.setColor(QPalette::Button, bgInact); } void ListPanelFrame::refreshColors(bool active) { if(color.isEmpty()) return; setPalette(active ? palActive : palInactive); } QColor ListPanelFrame::getColor(KConfigGroup &cg, QString name, const QColor &def, const QColor &kdedef) { if (cg.readEntry(name, QString()) == "KDE default") return kdedef; else if(!cg.readEntry(name, QString()).isEmpty()) return cg.readEntry(name, def); return def; } diff --git a/krusader/Panel/panelfunc.cpp b/krusader/Panel/panelfunc.cpp index f9885a90..f8f08655 100644 --- a/krusader/Panel/panelfunc.cpp +++ b/krusader/Panel/panelfunc.cpp @@ -1,1292 +1,1291 @@ /***************************************************************************** * 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 "panelfunc.h" // QtCore #include #include #include #include #include #include // QtGui #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dirhistoryqueue.h" #include "krcalcspacedialog.h" #include "krerrordisplay.h" #include "krsearchbar.h" #include "listpanel.h" #include "listpanelactions.h" #include "PanelView/krview.h" #include "PanelView/krviewitem.h" #include "../krglobal.h" #include "../krslots.h" #include "../kractions.h" #include "../defaults.h" #include "../abstractpanelmanager.h" #include "../krservices.h" #include "../Archive/krarchandler.h" #include "../Archive/packjob.h" #include "../FileSystem/fileitem.h" #include "../FileSystem/virtualfilesystem.h" #include "../FileSystem/krpermhandler.h" #include "../FileSystem/filesystemprovider.h" #include "../FileSystem/sizecalculator.h" #include "../Dialogs/packgui.h" #include "../Dialogs/krdialogs.h" #include "../Dialogs/krpleasewait.h" #include "../Dialogs/krspwidgets.h" #include "../Dialogs/checksumdlg.h" #include "../KViewer/krviewer.h" #include "../MountMan/kmountman.h" QPointer ListPanelFunc::copyToClipboardOrigin; ListPanelFunc::ListPanelFunc(ListPanel *parent) : QObject(parent), panel(parent), fileSystemP(0), urlManuallyEntered(false), _isPaused(true), _refreshAfterPaused(true), _quickSizeCalculator(0) { history = new DirHistoryQueue(panel); delayTimer.setSingleShot(true); - connect(&delayTimer, SIGNAL(timeout()), this, SLOT(doRefresh())); + connect(&delayTimer, &QTimer::timeout, this, &ListPanelFunc::doRefresh); } ListPanelFunc::~ListPanelFunc() { if (fileSystemP) { fileSystemP->deleteLater(); } delete history; if (_quickSizeCalculator) _quickSizeCalculator->deleteLater(); } bool ListPanelFunc::isSyncing(const QUrl &url) { if(otherFunc()->otherFunc() == this && panel->otherPanel()->gui->syncBrowseButton->isChecked() && !otherFunc()->syncURL.isEmpty() && otherFunc()->syncURL == url) return true; return false; } void ListPanelFunc::openFileNameInternal(const QString &name, bool externallyExecutable) { if (name == "..") { dirUp(); return; } FileItem *fileitem = files()->getFileItem(name); if (fileitem == 0) return; QUrl url = files()->getUrl(name); if (fileitem->isDir()) { panel->view->setNameToMakeCurrent(QString()); openUrl(url); return; } QString mime = fileitem->getMime(); QUrl arcPath = browsableArchivePath(name); if (!arcPath.isEmpty()) { bool browseAsDirectory = !externallyExecutable || (KConfigGroup(krConfig, "Archives").readEntry("ArchivesAsDirectories", _ArchivesAsDirectories) && (KRarcHandler::arcSupported(mime) || KrServices::isoSupported(mime))); if (browseAsDirectory) { openUrl(arcPath); return; } } if (externallyExecutable) { if (KRun::isExecutableFile(url, mime)) { runCommand(KShell::quoteArg(url.path())); return; } KService::Ptr service = KMimeTypeTrader::self()->preferredService(mime); if(service) { runService(*service, QList() << url); return; } displayOpenWithDialog(QList() << url); } } QUrl ListPanelFunc::cleanPath(const QUrl &urlIn) { QUrl url = urlIn; url.setPath(QDir::cleanPath(url.path())); if (!url.isValid() || url.isRelative()) { if (url.url() == "~") url = QUrl::fromLocalFile(QDir::homePath()); else if (!url.url().startsWith('/')) { // possible relative URL - translate to full URL url = files()->currentDirectory(); url.setPath(url.path() + '/' + urlIn.path()); } } url.setPath(QDir::cleanPath(url.path())); return url; } void ListPanelFunc::openUrl(const QUrl &url, const QString& nameToMakeCurrent, bool manuallyEntered) { qDebug() << "URL=" << url.toDisplayString() << "; name to current=" << nameToMakeCurrent; if (panel->syncBrowseButton->isChecked()) { //do sync-browse stuff.... if(syncURL.isEmpty()) syncURL = panel->otherPanel()->virtualPath(); QString relative = QDir(panel->virtualPath().path() + '/').relativeFilePath(url.path()); syncURL.setPath(QDir::cleanPath(syncURL.path() + '/' + relative)); panel->otherPanel()->gui->setTabState(ListPanel::TabState::DEFAULT); otherFunc()->openUrlInternal(syncURL, nameToMakeCurrent, false, false); } openUrlInternal(url, nameToMakeCurrent, false, manuallyEntered); } void ListPanelFunc::immediateOpenUrl(const QUrl &url) { openUrlInternal(url, QString(), true, false); } void ListPanelFunc::openUrlInternal(const QUrl &url, const QString& nameToMakeCurrent, bool immediately, bool manuallyEntered) { const QUrl cleanUrl = cleanPath(url); if (panel->isLocked() && !files()->currentDirectory().matches(cleanUrl, QUrl::StripTrailingSlash)) { panel->_manager->newTab(url); urlManuallyEntered = false; return; } urlManuallyEntered = manuallyEntered; const QString currentItem = history->currentUrl().path() == cleanUrl.path() ? history->currentItem() : nameToMakeCurrent; history->add(cleanUrl, currentItem); if(immediately) doRefresh(); else refresh(); } void ListPanelFunc::refresh() { panel->cancelProgress(); delayTimer.start(0); // to avoid qApp->processEvents() deadlock situation } void ListPanelFunc::doRefresh() { delayTimer.stop(); if (_isPaused) { _refreshAfterPaused = true; // simulate refresh panel->slotStartUpdate(true); return; } else { _refreshAfterPaused = false; } const QUrl url = history->currentUrl(); if(!url.isValid()) { panel->slotStartUpdate(true); // refresh the panel urlManuallyEntered = false; return; } panel->cancelProgress(); // if we are not refreshing to current URL const bool isEqualUrl = files()->currentDirectory().matches(url, QUrl::StripTrailingSlash); if (!isEqualUrl) { panel->setCursor(Qt::WaitCursor); panel->view->clearSavedSelection(); } if (panel->fileSystemError) { panel->fileSystemError->hide(); } panel->setNavigatorUrl(url); // may get a new filesystem for this url FileSystem *fileSystem = FileSystemProvider::instance().getFilesystem(url, files()); fileSystem->setParentWindow(krMainWindow); connect(fileSystem, &FileSystem::aboutToOpenDir, &krMtMan, &KMountMan::autoMount, Qt::DirectConnection); if (fileSystem != fileSystemP) { panel->view->setFiles(0); // disconnect older signals disconnect(fileSystemP, 0, panel, 0); fileSystemP->deleteLater(); fileSystemP = fileSystem; // v != 0 so this is safe } else { if (fileSystemP->isRefreshing()) { // TODO remove busy waiting here delayTimer.start(100); /* if filesystem is busy try refreshing later */ return; } } // (re)connect filesystem signals disconnect(files(), 0, panel, 0); connect(files(), &DirListerInterface::scanDone, panel, &ListPanel::slotStartUpdate); connect(files(), &FileSystem::fileSystemInfoChanged, panel, &ListPanel::updateFilesystemStats); connect(files(), &FileSystem::refreshJobStarted, panel, &ListPanel::slotRefreshJobStarted); - connect(files(), SIGNAL(error(QString)), - panel, SLOT(slotFilesystemError(QString))); + connect(files(), &FileSystem::error, panel, &ListPanel::slotFilesystemError); panel->view->setFiles(files()); if (!isEqualUrl || !panel->view->getCurrentKrViewItem()) { // set current item after refresh from history, if there is none yet panel->view->setNameToMakeCurrent(history->currentItem()); } // workaround for detecting panel deletion while filesystem is refreshing QPointer panelSave = panel; // NOTE: this is blocking. Returns false on error or interruption (cancel requested or panel // was deleted) const bool scanned = fileSystemP->refresh(url); if (scanned) { // update the history and address bar, as the actual url might differ from the one requested history->setCurrentUrl(fileSystemP->currentDirectory()); panel->setNavigatorUrl(fileSystemP->currentDirectory()); } else if (!panelSave) { return; } panel->view->setNameToMakeCurrent(QString()); panel->setCursor(Qt::ArrowCursor); // on local file system change the working directory if (files()->isLocal()) QDir::setCurrent(KrServices::urlToLocalPath(files()->currentDirectory())); // see if the open url operation failed, and if so, // put the attempted url in the navigator bar and let the user change it if (!scanned) { if(isSyncing(url)) panel->otherPanel()->gui->syncBrowseButton->setChecked(false); else if(urlManuallyEntered) { panel->setNavigatorUrl(url); if(panel == ACTIVE_PANEL) panel->editLocation(); } } if(otherFunc()->otherFunc() == this) // not true if our tab is not active otherFunc()->syncURL = QUrl(); urlManuallyEntered = false; refreshActions(); } void ListPanelFunc::setPaused(bool paused) { if (paused == _isPaused) return; _isPaused = paused; // TODO: disable refresh() in local file system when paused if (!_isPaused && _refreshAfterPaused) refresh(); } void ListPanelFunc::redirectLink() { if (!files()->isLocal()) { KMessageBox::sorry(krMainWindow, i18n("You can edit links only on local file systems")); return; } FileItem *fileitem = files()->getFileItem(panel->getCurrentName()); if (!fileitem) return; QString file = fileitem->getUrl().path(); QString currentLink = fileitem->getSymDest(); if (currentLink.isEmpty()) { KMessageBox::sorry(krMainWindow, i18n("The current file is not a link, so it cannot be redirected.")); return; } // ask the user for a new destination bool ok = false; QString newLink = QInputDialog::getText(krMainWindow, i18n("Link Redirection"), i18n("Please enter the new link destination:"), QLineEdit::Normal, currentLink, &ok); // if the user canceled - quit if (!ok || newLink == currentLink) return; // delete the current link if (unlink(file.toLocal8Bit()) == -1) { KMessageBox::sorry(krMainWindow, i18n("Cannot remove old link: %1", file)); return; } // try to create a new symlink if (symlink(newLink.toLocal8Bit(), file.toLocal8Bit()) == -1) { KMessageBox:: /* --=={ Patch by Heiner }==-- */sorry(krMainWindow, i18n("Failed to create a new link: %1", file)); return; } } void ListPanelFunc::krlink(bool sym) { if (!files()->isLocal()) { KMessageBox::sorry(krMainWindow, i18n("You can create links only on local file systems")); return; } QString name = panel->getCurrentName(); // ask the new link name.. bool ok = false; QString linkName = QInputDialog::getText(krMainWindow, i18n("New Link"), i18n("Create a new link to: %1", name), QLineEdit::Normal, name, &ok); // if the user canceled - quit if (!ok || linkName == name) return; // if the name is already taken - quit if (files()->getFileItem(linkName) != 0) { KMessageBox::sorry(krMainWindow, i18n("A folder or a file with this name already exists.")); return; } // make link name and target absolute path if (linkName.left(1) != "/") linkName = files()->currentDirectory().path() + '/' + linkName; name = files()->getUrl(name).path(); if (sym) { if (symlink(name.toLocal8Bit(), linkName.toLocal8Bit()) == -1) KMessageBox::sorry(krMainWindow, i18n("Failed to create a new symlink '%1' to: '%2'", linkName, name)); } else { if (link(name.toLocal8Bit(), linkName.toLocal8Bit()) == -1) KMessageBox::sorry(krMainWindow, i18n("Failed to create a new link '%1' to '%2'", linkName, name)); } } void ListPanelFunc::view() { panel->searchBar->hideBarIfSearching(); QString fileName = panel->getCurrentName(); if (fileName.isNull()) return; // if we're trying to view a directory, just exit FileItem *fileitem = files()->getFileItem(fileName); if (!fileitem || fileitem->isDir()) return; if (!fileitem->isReadable()) { KMessageBox::sorry(0, i18n("No permissions to view this file.")); return; } // call KViewer. KrViewer::view(files()->getUrl(fileName)); // nothing more to it! } void ListPanelFunc::viewDlg() { // ask the user for a url to view QUrl dest = KChooseDir::getFile(i18n("Enter a URL to view:"), QUrl(panel->getCurrentName()), panel->virtualPath()); if (dest.isEmpty()) return ; // the user canceled KrViewer::view(dest); // view the file } void ListPanelFunc::terminal() { SLOTS->runTerminal(panel->lastLocalPath()); } void ListPanelFunc::edit() { panel->searchBar->hideBarIfSearching(); KFileItem tmp; if (fileToCreate.isEmpty()) { QString name = panel->getCurrentName(); if (name.isNull()) return; fileToCreate = files()->getUrl(name); } tmp = KFileItem(fileToCreate); if (tmp.isDir()) { KMessageBox::sorry(krMainWindow, i18n("You cannot edit a folder")); fileToCreate = QUrl(); return; } if (!tmp.isReadable()) { KMessageBox::sorry(0, i18n("No permissions to edit this file.")); fileToCreate = QUrl(); return; } KrViewer::edit(fileToCreate); fileToCreate = QUrl(); } void ListPanelFunc::editNew() { if(!fileToCreate.isEmpty()) return; // ask the user for the filename to edit fileToCreate = KChooseDir::getFile(i18n("Enter the filename to edit:"), QUrl(panel->getCurrentName()), panel->virtualPath()); if(fileToCreate.isEmpty()) return ; // the user canceled // if the file exists, edit it instead of creating a new one QFile f(fileToCreate.toLocalFile()); if(f.exists()) { edit(); } else { QTemporaryFile *tempFile = new QTemporaryFile; tempFile->open(); KIO::CopyJob *job = KIO::copy(QUrl::fromLocalFile(tempFile->fileName()), fileToCreate); job->setUiDelegate(0); job->setDefaultPermissions(true); - connect(job, SIGNAL(result(KJob*)), SLOT(slotFileCreated(KJob*))); - connect(job, SIGNAL(result(KJob*)), tempFile, SLOT(deleteLater())); + connect(job, &KIO::CopyJob::result, this, &ListPanelFunc::slotFileCreated); + connect(job, &KIO::CopyJob::result, tempFile, &QTemporaryFile::deleteLater); } } void ListPanelFunc::slotFileCreated(KJob *job) { if(!job->error() || job->error() == KIO::ERR_FILE_ALREADY_EXIST) { KrViewer::edit(fileToCreate); if(KIO::upUrl(fileToCreate).matches(panel->virtualPath(), QUrl::StripTrailingSlash)) refresh(); else if(KIO::upUrl(fileToCreate).matches(panel->otherPanel()->virtualPath(), QUrl::StripTrailingSlash)) otherFunc()->refresh(); } else KMessageBox::sorry(krMainWindow, job->errorString()); fileToCreate = QUrl(); } void ListPanelFunc::copyFiles(bool enqueue, bool move) { panel->searchBar->hideBarIfSearching(); const QStringList fileNames = panel->getSelectedNames(); if (fileNames.isEmpty()) return ; // safety QUrl destination = panel->otherPanel()->virtualPath(); bool fullDestPath = false; if (fileNames.count() == 1 && otherFunc()->files()->type() != FileSystem::FS_VIRTUAL) { FileItem *item = files()->getFileItem(fileNames[0]); if (item && !item->isDir()) { fullDestPath = true; // add original filename to destination destination.setPath(QDir(destination.path()).filePath(item->getUrl().fileName())); } } if (!fullDestPath) { destination = FileSystem::ensureTrailingSlash(destination); } const KConfigGroup group(krConfig, "Advanced"); const bool showDialog = move ? group.readEntry("Confirm Move", _ConfirmMove) : group.readEntry("Confirm Copy", _ConfirmCopy); if (showDialog) { QString operationText; if (move) { operationText = fileNames.count() == 1 ? i18n("Move %1 to:", fileNames.first()) : i18np("Move %1 file to:", "Move %1 files to:", fileNames.count()); } else { operationText = fileNames.count() == 1 ? i18n("Copy %1 to:", fileNames.first()) : i18np("Copy %1 file to:", "Copy %1 files to:", fileNames.count()); } // ask the user for the copy/move dest const KChooseDir::ChooseResult result = KChooseDir::getCopyDir(operationText, destination, panel->virtualPath()); destination = result.url; if (destination.isEmpty()) return ; // the user canceled enqueue = result.enqueue; } const JobMan::StartMode startMode = enqueue && krJobMan->isQueueModeEnabled() ? JobMan::Delay : !enqueue && !krJobMan->isQueueModeEnabled() ? JobMan::Start : JobMan::Enqueue; const QList fileUrls = files()->getUrls(fileNames); if (move) { // after the delete return the cursor to the first unmarked file above the current item panel->prepareToDelete(); } // make sure the user does not overwrite multiple files by mistake if (fileNames.count() > 1) { destination = FileSystem::ensureTrailingSlash(destination); } const KIO::CopyJob::CopyMode mode = move ? KIO::CopyJob::Move : KIO::CopyJob::Copy; FileSystemProvider::instance().startCopyFiles(fileUrls, destination, mode, true, startMode); if(KConfigGroup(krConfig, "Look&Feel").readEntry("UnselectBeforeOperation", _UnselectBeforeOperation)) { panel->view->saveSelection(); panel->view->unselectAll(); } } // called from SLOTS to begin the renaming process void ListPanelFunc::rename() { panel->searchBar->hideBarIfSearching(); panel->view->renameCurrentItem(); } // called by signal itemRenamed() from the view to complete the renaming process void ListPanelFunc::rename(const QString &oldname, const QString &newname) { if (oldname == newname) return ; // do nothing // set current after rename panel->view->setNameToMakeCurrent(newname); // as always - the filesystem do the job files()->rename(oldname, newname); } void ListPanelFunc::mkdir() { // ask the new dir name.. // suggested name is the complete name for the directories // while filenames are suggested without their extension QString suggestedName = panel->getCurrentName(); if (!suggestedName.isEmpty() && !files()->getFileItem(suggestedName)->isDir()) suggestedName = QFileInfo(suggestedName).completeBaseName(); const QString dirName = QInputDialog::getText(krMainWindow, i18n("New folder"), i18n("Folder's name:"), QLineEdit::Normal, suggestedName); const QString firstName = dirName.section('/', 0, 0, QString::SectionIncludeLeadingSep); // if the user canceled or the name was composed of slashes - quit if (!dirName.startsWith('/') && firstName.isEmpty()) { return; } // notify user about existing folder if only single directory was given if (!dirName.contains('/') && files()->getFileItem(firstName)) { // focus the existing directory panel->view->setCurrentItem(firstName); // show error message KMessageBox::sorry(krMainWindow, i18n("A folder or a file with this name already exists.")); return; } // focus new directory when next refresh happens panel->view->setNameToMakeCurrent(firstName); // create new directory (along with underlying directories if necessary) files()->mkDir(dirName); } void ListPanelFunc::defaultOrAlternativeDeleteFiles(bool invert) { const bool trash = KConfigGroup(krConfig, "General").readEntry("Move To Trash", _MoveToTrash); deleteFiles(trash != invert); } void ListPanelFunc::deleteFiles(bool moveToTrash) { panel->searchBar->hideBarIfSearching(); const bool isVFS = files()->type() == FileSystem::FS_VIRTUAL; if (isVFS && files()->isRoot()) { // only virtual deletion possible removeVirtualFiles(); return; } // first get the selected file names list const QStringList fileNames = panel->getSelectedNames(); if (fileNames.isEmpty()) return; // move to trash: only if possible moveToTrash = moveToTrash && files()->canMoveToTrash(fileNames); // now ask the user if he/she is sure: const QList confirmedUrls = confirmDeletion( files()->getUrls(fileNames), moveToTrash, isVFS, false); if (confirmedUrls.isEmpty()) return; // nothing to delete // after the delete return the cursor to the first unmarked // file above the current item; panel->prepareToDelete(); // let the filesystem do the job... files()->deleteFiles(confirmedUrls, moveToTrash); } QList ListPanelFunc::confirmDeletion(const QList &urls, bool moveToTrash, bool virtualFS, bool showPath) { QStringList files; for (QUrl fileUrl : urls) { files.append(showPath ? fileUrl.toDisplayString(QUrl::PreferLocalFile) : fileUrl.fileName()); } const KConfigGroup advancedGroup(krConfig, "Advanced"); if (advancedGroup.readEntry("Confirm Delete", _ConfirmDelete)) { QString s; // text KGuiItem b; // continue button if (moveToTrash) { s = i18np("Do you really want to move this item to the trash?", "Do you really want to move these %1 items to the trash?", files.count()); b = KGuiItem(i18n("&Trash")); } else if (virtualFS) { s = i18np("Do you really want to delete this item physically (not just " "removing it from the virtual items)?", "Do you really want to delete these %1 items physically (not just " "removing them from the virtual items)?", files.count()); b = KStandardGuiItem::del(); } else { s = i18np("Do you really want to delete this item?", "Do you really want to delete these %1 items?", files.count()); b = KStandardGuiItem::del(); } // show message // note: i'm using continue and not yes/no because the yes/no has cancel as default button if (KMessageBox::warningContinueCancelList(krMainWindow, s, files, i18n("Warning"), b) != KMessageBox::Continue) { return QList(); } } // we want to warn the user about non empty dir const bool emptyDirVerify = advancedGroup.readEntry("Confirm Unempty Dir", _ConfirmUnemptyDir); QList toDelete; if (emptyDirVerify) { QSet confirmedFiles = urls.toSet(); for (QUrl fileUrl : urls) { if (!fileUrl.isLocalFile()) { continue; // TODO only local fs supported } const QString filePath = fileUrl.toLocalFile(); QFileInfo fileInfo(filePath); if (fileInfo.isDir() && !fileInfo.isSymLink()) { // read local dir... const QDir dir(filePath); if (!dir.entryList(QDir::AllEntries | QDir::System | QDir::Hidden | QDir::NoDotAndDotDot).isEmpty()) { // ...is not empty, ask user const QString fileString = showPath ? filePath : fileUrl.fileName(); const KMessageBox::ButtonCode result = KMessageBox::warningYesNoCancel( krMainWindow, i18n("

Folder %1 is not empty.

", fileString) + (moveToTrash ? i18n("

Skip this one or trash all?

") : i18n("

Skip this one or delete all?

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

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

All data in the previous archive will be lost.

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

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

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

", PackGUI::filename, PackGUI::type); } if (KMessageBox::warningContinueCancel(krMainWindow, msg, QString(), KStandardGuiItem::overwrite()) == KMessageBox::Cancel) return ; // stop operation } else if (destURL.scheme() == QStringLiteral("virt")) { KMessageBox::error(krMainWindow, i18n("Cannot pack files onto a virtual destination.")); return; } PackJob * job = PackJob::createPacker(files()->currentDirectory(), destURL, fileNames, PackGUI::type, PackGUI::extraProps); job->setUiDelegate(new KIO::JobUiDelegate()); KIO::getJobTracker()->registerJob(job); job->uiDelegate()->setAutoErrorHandlingEnabled(true); if (packToOtherPanel) - connect(job, SIGNAL(result(KJob*)), panel->otherPanel()->func, SLOT(refresh())); + connect(job, &PackJob::result, panel->otherPanel()->func, &ListPanelFunc::refresh); } void ListPanelFunc::testArchive() { const QStringList fileNames = panel->getSelectedNames(); if (fileNames.isEmpty()) return ; // safety TestArchiveJob * job = TestArchiveJob::testArchives(files()->currentDirectory(), fileNames); job->setUiDelegate(new KIO::JobUiDelegate()); KIO::getJobTracker()->registerJob(job); job->uiDelegate()->setAutoErrorHandlingEnabled(true); } void ListPanelFunc::unpack() { const QStringList fileNames = panel->getSelectedNames(); if (fileNames.isEmpty()) return ; // safety QString s; if (fileNames.count() == 1) s = i18n("Unpack %1 to:", fileNames[0]); else s = i18np("Unpack %1 file to:", "Unpack %1 files to:", fileNames.count()); // ask the user for the copy dest QUrl dest = KChooseDir::getDir(s, panel->otherPanel()->virtualPath(), panel->virtualPath()); if (dest.isEmpty()) return ; // the user canceled bool packToOtherPanel = (dest.matches(panel->otherPanel()->virtualPath(), QUrl::StripTrailingSlash)); UnpackJob * job = UnpackJob::createUnpacker(files()->currentDirectory(), dest, fileNames); job->setUiDelegate(new KIO::JobUiDelegate()); KIO::getJobTracker()->registerJob(job); job->uiDelegate()->setAutoErrorHandlingEnabled(true); if (packToOtherPanel) - connect(job, SIGNAL(result(KJob*)), panel->otherPanel()->func, SLOT(refresh())); + connect(job, &UnpackJob::result, panel->otherPanel()->func, &ListPanelFunc::refresh); } void ListPanelFunc::createChecksum() { if (!panel->func->files()->isLocal()) return; // only local, non-virtual files are supported KrViewItemList items; panel->view->getSelectedKrViewItems(&items); QStringList fileNames; for (KrViewItem *item : items) { FileItem *file = panel->func->getFileItem(item); fileNames.append(file->getUrl().fileName()); } if (fileNames.isEmpty()) return; // nothing selected and no valid current file Checksum::startCreationWizard(panel->virtualPath().toLocalFile(), fileNames); } void ListPanelFunc::matchChecksum() { if (!panel->func->files()->isLocal()) return; // only local, non-virtual files are supported FileItem *currentItem = files()->getFileItem(panel->getCurrentName()); const QString checksumFilePath = currentItem ? currentItem->getUrl().toLocalFile() : QString(); Checksum::startVerifyWizard(panel->virtualPath().toLocalFile(), checksumFilePath); } void ListPanelFunc::calcSpace() { QStringList fileNames; panel->view->getSelectedItems(&fileNames); if (fileNames.isEmpty()) { // current file is ".." dummy file panel->view->selectAllIncludingDirs(); panel->view->getSelectedItems(&fileNames); panel->view->unselectAll(); } SizeCalculator *sizeCalculator = createAndConnectSizeCalculator(files()->getUrls(fileNames)); KrCalcSpaceDialog::showDialog(panel, sizeCalculator); } void ListPanelFunc::quickCalcSpace() { const QString currentName = panel->getCurrentName(); if (currentName.isEmpty()) { // current file is ".." dummy, do a verbose calcSpace calcSpace(); return; } if (!_quickSizeCalculator) { _quickSizeCalculator = createAndConnectSizeCalculator(QList()); panel->connectQuickSizeCalculator(_quickSizeCalculator); } _quickSizeCalculator->add(files()->getUrl(currentName)); } SizeCalculator *ListPanelFunc::createAndConnectSizeCalculator(const QList &urls) { SizeCalculator *sizeCalculator = new SizeCalculator(urls); connect(sizeCalculator, &SizeCalculator::calculated, this, &ListPanelFunc::slotSizeCalculated); connect(sizeCalculator, &SizeCalculator::finished, panel, &ListPanel::slotUpdateTotals); connect(this, &ListPanelFunc::destroyed, sizeCalculator, &SizeCalculator::deleteLater); return sizeCalculator; } void ListPanelFunc::slotSizeCalculated(const QUrl &url, KIO::filesize_t size) { KrViewItem *item = panel->view->findItemByUrl(url); if (!item) return; item->setSize(size); item->redraw(); } void ListPanelFunc::FTPDisconnect() { // you can disconnect only if connected! if (files()->isRemote()) { panel->_actions->actFTPDisconnect->setEnabled(false); panel->view->setNameToMakeCurrent(QString()); openUrl(QUrl::fromLocalFile(panel->lastLocalPath())); } } void ListPanelFunc::newFTPconnection() { QUrl url = KRSpWidgets::newFTP(); // if the user canceled - quit if (url.isEmpty()) return; panel->_actions->actFTPDisconnect->setEnabled(true); qDebug() << "URL=" << url.toDisplayString(); openUrl(url); } void ListPanelFunc::properties() { const QStringList names = panel->getSelectedNames(); if (names.isEmpty()) { return ; // no names... } KFileItemList fileItems; for (const QString name : names) { FileItem *fileitem = files()->getFileItem(name); if (!fileitem) { continue; } fileItems.push_back(KFileItem(fileitem->getEntry(), files()->getUrl(name))); } if (fileItems.isEmpty()) return; // Show the properties dialog KPropertiesDialog *dialog = new KPropertiesDialog(fileItems, krMainWindow); connect(dialog, &KPropertiesDialog::applied, this, &ListPanelFunc::refresh); dialog->show(); } void ListPanelFunc::refreshActions() { panel->updateButtons(); if(ACTIVE_PANEL != panel) return; QString protocol = files()->currentDirectory().scheme(); krRemoteEncoding->setEnabled(protocol == "ftp" || protocol == "sftp" || protocol == "fish" || protocol == "krarc"); //krMultiRename->setEnabled( fileSystemType == FileSystem::FS_NORMAL ); // batch rename //krProperties ->setEnabled( fileSystemType == FileSystem::FS_NORMAL || fileSystemType == FileSystem::FS_FTP ); // file properties /* krUnpack->setEnabled(true); // unpack archive krTest->setEnabled(true); // test archive krSelect->setEnabled(true); // select a group by filter krSelectAll->setEnabled(true); // select all files krUnselect->setEnabled(true); // unselect by filter krUnselectAll->setEnabled( true); // remove all selections krInvert->setEnabled(true); // invert the selection krFTPConnect->setEnabled(true); // connect to an ftp krFTPNew->setEnabled(true); // create a new connection krAllFiles->setEnabled(true); // show all files in list krCustomFiles->setEnabled(true); // show a custom set of files krRoot->setEnabled(true); // go all the way up krExecFiles->setEnabled(true); // show only executables */ panel->_actions->setViewActions[panel->panelType]->setChecked(true); panel->_actions->actFTPDisconnect->setEnabled(files()->isRemote()); // allow disconnecting a network session panel->_actions->actCreateChecksum->setEnabled(files()->isLocal()); panel->_actions->actDirUp->setEnabled(!files()->isRoot()); panel->_actions->actRoot->setEnabled(!panel->virtualPath().matches(QUrl::fromLocalFile(ROOT_DIR), QUrl::StripTrailingSlash)); panel->_actions->actHome->setEnabled(!atHome()); panel->_actions->actHistoryBackward->setEnabled(history->canGoBack()); panel->_actions->actHistoryForward->setEnabled(history->canGoForward()); panel->view->op()->emitRefreshActions(); } FileSystem* ListPanelFunc::files() { if (!fileSystemP) fileSystemP = FileSystemProvider::instance().getFilesystem(QUrl::fromLocalFile(ROOT_DIR)); return fileSystemP; } QUrl ListPanelFunc::virtualDirectory() { return _isPaused ? history->currentUrl() : files()->currentDirectory(); } FileItem *ListPanelFunc::getFileItem(const QString &name) { return files()->getFileItem(name); } FileItem *ListPanelFunc::getFileItem(KrViewItem *item) { return files()->getFileItem(item->name()); } void ListPanelFunc::clipboardChanged(QClipboard::Mode mode) { if (mode == QClipboard::Clipboard && this == copyToClipboardOrigin) { disconnect(QApplication::clipboard(), 0, this, 0); copyToClipboardOrigin = 0; } } void ListPanelFunc::copyToClipboard(bool move) { const QStringList fileNames = panel->getSelectedNames(); if (fileNames.isEmpty()) return ; // safety QList fileUrls = files()->getUrls(fileNames); QMimeData *mimeData = new QMimeData; mimeData->setData("application/x-kde-cutselection", move ? "1" : "0"); mimeData->setUrls(fileUrls); if (copyToClipboardOrigin) disconnect(QApplication::clipboard(), 0, copyToClipboardOrigin, 0); copyToClipboardOrigin = this; QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); - connect(QApplication::clipboard(), SIGNAL(changed(QClipboard::Mode)), this, SLOT(clipboardChanged(QClipboard::Mode))); + connect(QApplication::clipboard(), &QClipboard::changed, this, &ListPanelFunc::clipboardChanged); } void ListPanelFunc::pasteFromClipboard() { QClipboard * cb = QApplication::clipboard(); ListPanelFunc *origin = 0; if (copyToClipboardOrigin) { disconnect(QApplication::clipboard(), 0, copyToClipboardOrigin, 0); origin = copyToClipboardOrigin; copyToClipboardOrigin = 0; } bool move = false; const QMimeData *data = cb->mimeData(); if (data->hasFormat("application/x-kde-cutselection")) { QByteArray a = data->data("application/x-kde-cutselection"); if (!a.isEmpty()) move = (a.at(0) == '1'); // true if 1 } QList urls = data->urls(); if (urls.isEmpty()) return; if(origin && KConfigGroup(krConfig, "Look&Feel").readEntry("UnselectBeforeOperation", _UnselectBeforeOperation)) { origin->panel->view->saveSelection(); for(KrViewItem *item = origin->panel->view->getFirst(); item != 0; item = origin->panel->view->getNext(item)) { if (urls.contains(item->getFileItem()->getUrl())) item->setSelected(false); } } files()->addFiles(urls, move ? KIO::CopyJob::Move : KIO::CopyJob::Copy); } ListPanelFunc* ListPanelFunc::otherFunc() { return panel->otherPanel()->func; } void ListPanelFunc::historyGotoPos(int pos) { if(history->gotoPos(pos)) refresh(); } void ListPanelFunc::historyBackward() { if(history->goBack()) refresh(); } void ListPanelFunc::historyForward() { if(history->goForward()) refresh(); } void ListPanelFunc::dirUp() { openUrl(KIO::upUrl(files()->currentDirectory()), files()->currentDirectory().fileName()); } void ListPanelFunc::home() { openUrl(QUrl::fromLocalFile(QDir::homePath())); } void ListPanelFunc::root() { openUrl(QUrl::fromLocalFile(ROOT_DIR)); } void ListPanelFunc::cdToOtherPanel() { openUrl(panel->otherPanel()->virtualPath()); } void ListPanelFunc::syncOtherPanel() { otherFunc()->openUrl(panel->virtualPath()); } bool ListPanelFunc::atHome() { return QUrl::fromLocalFile(QDir::homePath()).matches(panel->virtualPath(), QUrl::StripTrailingSlash); } diff --git a/krusader/Panel/sidebar.cpp b/krusader/Panel/sidebar.cpp index 79c08694..90d5d7d5 100644 --- a/krusader/Panel/sidebar.cpp +++ b/krusader/Panel/sidebar.cpp @@ -1,289 +1,289 @@ /***************************************************************************** * Copyright (C) 2003 Shie Erlich * * Copyright (C) 2003 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 "sidebar.h" #include "krfiletreeview.h" #include "krpanel.h" #include "panelfunc.h" #include "viewactions.h" #include "../defaults.h" #include "../icon.h" #include "../Dialogs/krsqueezedtextlabel.h" #include "../FileSystem/fileitem.h" #include "../FileSystem/filesystem.h" #include "../KViewer/diskusageviewer.h" #include "../KViewer/panelviewer.h" #include "PanelView/krview.h" #include "PanelView/krviewitem.h" // QtCore #include #include // QtWidgets #include #include #include #include Sidebar::Sidebar(QWidget *parent) : QWidget(parent), stack(0), imageFilePreview(0), pjob(0) { QGridLayout * layout = new QGridLayout(this); layout->setContentsMargins(0, 0, 0, 0); // create the label+buttons setup dataLine = new KrSqueezedTextLabel(this); KConfigGroup lg(krConfig, "Look&Feel"); dataLine->setFont(lg.readEntry("Filelist Font", _FilelistFont)); // --- hack: setup colors to be the same as an inactive panel dataLine->setBackgroundRole(QPalette::Window); int sheight = QFontMetrics(dataLine->font()).height() + 4; dataLine->setMaximumHeight(sheight); btns = new QButtonGroup(this); btns->setExclusive(true); - connect(btns, SIGNAL(buttonClicked(int)), this, SLOT(tabSelected(int))); + connect(btns, QOverload::of(&QButtonGroup::buttonClicked), this, &Sidebar::tabSelected); treeBtn = new QToolButton(this); treeBtn->setToolTip(i18n("Tree Panel: a tree view of the local file system")); treeBtn->setIcon(Icon("view-list-tree")); treeBtn->setFixedSize(20, 20); treeBtn->setCheckable(true); btns->addButton(treeBtn, Tree); previewBtn = new QToolButton(this); previewBtn->setToolTip(i18n("Preview Panel: display a preview of the current file")); previewBtn->setIcon(Icon("view-preview")); previewBtn->setFixedSize(20, 20); previewBtn->setCheckable(true); btns->addButton(previewBtn, Preview); viewerBtn = new QToolButton(this); viewerBtn->setToolTip(i18n("View Panel: view the current file")); viewerBtn->setIcon(Icon("zoom-original")); viewerBtn->setFixedSize(20, 20); viewerBtn->setCheckable(true); btns->addButton(viewerBtn, View); duBtn = new QToolButton(this); duBtn->setToolTip(i18n("Disk Usage Panel: view the usage of a folder")); duBtn->setIcon(Icon("kr_diskusage")); duBtn->setFixedSize(20, 20); duBtn->setCheckable(true); btns->addButton(duBtn, DskUsage); layout->addWidget(dataLine, 0, 0); layout->addWidget(treeBtn, 0, 1); layout->addWidget(previewBtn, 0, 2); layout->addWidget(viewerBtn, 0, 3); layout->addWidget(duBtn, 0, 4); // create a widget stack on which to put the parts stack = new QStackedWidget(this); // create the tree part ---------- tree = new KrFileTreeView(stack); tree->setProperty("KrusaderWidgetId", QVariant(Tree)); stack->addWidget(tree); // NOTE: the F2 key press event is caught before it gets to the tree tree->setEditTriggers(QAbstractItemView::EditKeyPressed); // connecting signal to signal connect(tree, &KrFileTreeView::urlActivated, this, &Sidebar::urlActivated); // create the quickview part ------ imageFilePreview = new KImageFilePreview(stack); imageFilePreview->setProperty("KrusaderWidgetId", QVariant(Preview)); stack->addWidget(imageFilePreview); // create the panelview fileViewer = new PanelViewer(stack); fileViewer->setProperty("KrusaderWidgetId", QVariant(View)); // kparts demand too much width QSizePolicy sizePolicy = fileViewer->sizePolicy(); sizePolicy.setHorizontalPolicy(QSizePolicy::Ignored); fileViewer->setSizePolicy(sizePolicy); stack->addWidget(fileViewer); connect(fileViewer, &PanelViewer::openUrlRequest, this, &Sidebar::handleOpenUrlRequest); // create the disk usage view diskusage = new DiskUsageViewer(stack); diskusage->setStatusLabel(dataLine, i18n("Disk Usage:")); diskusage->setProperty("KrusaderWidgetId", QVariant(DskUsage)); stack->addWidget(diskusage); connect(diskusage, &DiskUsageViewer::openUrlRequest, this, &Sidebar::handleOpenUrlRequest); // -------- finish the layout (General one) layout->addWidget(stack, 1, 0, 1, 5); hide(); // for not to open the 3rd hand tool at start (selecting the last used tab) setCurrentPage(0); } Sidebar::~Sidebar() {} void Sidebar::saveSettings(KConfigGroup cfg) const { tree->saveSettings(cfg); } void Sidebar::restoreSettings(const KConfigGroup &cfg) { tree->restoreSettings(cfg); } void Sidebar::setCurrentPage(int id) { QAbstractButton * curr = btns->button(id); if (curr) { curr->click(); } } void Sidebar::show() { QWidget::show(); tabSelected(currentPage()); } void Sidebar::hide() { QWidget::hide(); if (currentPage() == View) fileViewer->closeUrl(); if (currentPage() == DskUsage) diskusage->closeUrl(); } void Sidebar::focusInEvent(QFocusEvent*) { switch (currentPage()) { case Preview: if (!isHidden()) imageFilePreview->setFocus(); break; case View: if (!isHidden() && fileViewer->part() && fileViewer->part()->widget()) fileViewer->part()->widget()->setFocus(); break; case DskUsage: if (!isHidden() && diskusage->getWidget() && diskusage->getWidget()->currentWidget()) diskusage->getWidget()->currentWidget()->setFocus(); break; case Tree: if (!isHidden()) tree->setFocus(); break; } } void Sidebar::handleOpenUrlRequest(const QUrl &url) { QMimeDatabase db; QMimeType mime = db.mimeTypeForUrl(url); if (mime.isValid() && mime.name() == "inode/directory") ACTIVE_PANEL->func->openUrl(url); } void Sidebar::tabSelected(int id) { QUrl url; const FileItem *fileitem = 0; if (ACTIVE_PANEL && ACTIVE_PANEL->view) fileitem = ACTIVE_PANEL->func->files()->getFileItem(ACTIVE_PANEL->view->getCurrentItem()); if(fileitem) url = fileitem->getUrl(); // if tab is tree, set something logical in the data line switch (id) { case Tree: stack->setCurrentWidget(tree); dataLine->setText(i18n("Tree:")); if (!isHidden()) tree->setFocus(); if (ACTIVE_PANEL) tree->setCurrentUrl(ACTIVE_PANEL->virtualPath()); break; case Preview: stack->setCurrentWidget(imageFilePreview); dataLine->setText(i18n("Preview:")); update(fileitem); break; case View: stack->setCurrentWidget(fileViewer); dataLine->setText(i18n("View:")); update(fileitem); if (!isHidden() && fileViewer->part() && fileViewer->part()->widget()) fileViewer->part()->widget()->setFocus(); break; case DskUsage: stack->setCurrentWidget(diskusage); dataLine->setText(i18n("Disk Usage:")); update(fileitem); if (!isHidden() && diskusage->getWidget() && diskusage->getWidget()->currentWidget()) diskusage->getWidget()->currentWidget()->setFocus(); break; } if (id != View) fileViewer->closeUrl(); } // decide which part to update, if at all void Sidebar::update(const FileItem *fileitem) { if (isHidden()) return; QUrl url; if(fileitem) url = fileitem->getUrl(); switch (currentPage()) { case Preview: imageFilePreview->showPreview(url); dataLine->setText(i18n("Preview: %1", url.fileName())); break; case View: if(fileitem && !fileitem->isDir() && fileitem->isReadable()) fileViewer->openUrl(fileitem->getUrl()); else fileViewer->closeUrl(); dataLine->setText(i18n("View: %1", url.fileName())); break; case DskUsage: { if(fileitem && !fileitem->isDir()) url = KIO::upUrl(url); dataLine->setText(i18n("Disk Usage: %1", url.fileName())); diskusage->openUrl(url); } break; case Tree: // nothing to do break; } } void Sidebar::onPanelPathChange(const QUrl &url) { switch (currentPage()) { case Tree: if (url.isLocalFile()) { tree->setCurrentUrl(url); // synchronize panel path with tree path } break; } } diff --git a/krusader/Synchronizer/feedtolistboxdialog.cpp b/krusader/Synchronizer/feedtolistboxdialog.cpp index bf47b965..295ac34b 100644 --- a/krusader/Synchronizer/feedtolistboxdialog.cpp +++ b/krusader/Synchronizer/feedtolistboxdialog.cpp @@ -1,206 +1,206 @@ /***************************************************************************** * 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 "feedtolistboxdialog.h" #include "synchronizer.h" #include "synchronizergui.h" #include "../FileSystem/filesystem.h" #include "../FileSystem/virtualfilesystem.h" #include "../krglobal.h" #include "../krusaderview.h" #include "../panelmanager.h" // QtWidgets #include #include #include #include #include #include #include #include #include #define S_LEFT 0 #define S_RIGHT 1 #define S_BOTH 2 FeedToListBoxDialog::FeedToListBoxDialog(QWidget *parent, Synchronizer *sync, QTreeWidget *syncL, bool equOK) : QDialog(parent), synchronizer(sync), syncList(syncL), equalAllowed(equOK), accepted(false) { setWindowTitle(i18n("Krusader::Feed to listbox")); setWindowModality(Qt::WindowModal); QVBoxLayout *mainLayout = new QVBoxLayout; setLayout(mainLayout); // autodetecting the parameters int selectedNum = 0; int itemNum = 0; int leftExistingNum = 0; int rightExistingNum = 0; QTreeWidgetItemIterator it(syncList); while (*it) { SynchronizerGUI::SyncViewItem *item = (SynchronizerGUI::SyncViewItem *) * it; SynchronizerFileItem *syncItem = item->synchronizerItemRef(); if (syncItem && syncItem->isMarked()) { if (item->isSelected() || syncItem->task() != TT_EQUALS || equalAllowed) { itemNum++; if (item->isSelected()) selectedNum++; if (syncItem->existsInLeft()) leftExistingNum++; if (syncItem->existsInRight()) rightExistingNum++; } } it++; } if (itemNum == 0) { hide(); KMessageBox::error(parent, i18n("No elements to feed.")); return; } // guessing the collection name VirtualFileSystem virtFilesystem; if (!virtFilesystem.scanDir(QUrl("virt:/"))) return; KConfigGroup group(krConfig, "Synchronize"); int listBoxNum = group.readEntry("Feed To Listbox Counter", 1); QString queryName; do { queryName = i18n("Synchronize results") + QString(" %1").arg(listBoxNum++); } while (virtFilesystem.getFileItem(queryName) != 0); group.writeEntry("Feed To Listbox Counter", listBoxNum); // creating the widget QLabel *label = new QLabel(i18n("Here you can name the file collection"), this); mainLayout->addWidget(label); lineEdit = new QLineEdit(this); lineEdit->setText(queryName); lineEdit->setClearButtonEnabled(true); lineEdit->selectAll(); mainLayout->addWidget(lineEdit); QHBoxLayout * hbox = new QHBoxLayout; QLabel *label2 = new QLabel(i18n("Side to feed:"), this); label2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); hbox->addWidget(label2); sideCombo = new QComboBox(this); sideCombo->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); sideCombo->addItem(i18n("Left")); sideCombo->addItem(i18n("Right")); sideCombo->addItem(i18n("Both")); hbox->addWidget(sideCombo); if (leftExistingNum == 0) { sideCombo->setCurrentIndex(1); sideCombo->setEnabled(false); } else if (rightExistingNum == 0) { sideCombo->setCurrentIndex(0); sideCombo->setEnabled(false); } else sideCombo->setCurrentIndex(2); QFrame *line = new QFrame(this); line->setFrameStyle(QFrame::VLine | QFrame::Sunken); line->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); hbox->addWidget(line); cbSelected = new QCheckBox(i18n("Selected files only"), this); cbSelected->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); cbSelected->setEnabled(selectedNum != 0); cbSelected->setChecked(selectedNum != 0); hbox->addWidget(cbSelected); mainLayout->addLayout(hbox); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); mainLayout->addWidget(buttonBox); QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); okButton->setDefault(true); okButton->setShortcut(Qt::CTRL | Qt::Key_Return); - connect(buttonBox, SIGNAL(accepted()), SLOT(slotOk())); - connect(buttonBox, SIGNAL(rejected()), SLOT(reject())); + connect(buttonBox, &QDialogButtonBox::accepted, this, &FeedToListBoxDialog::slotOk); + connect(buttonBox, &QDialogButtonBox::rejected, this, &FeedToListBoxDialog::reject); exec(); } void FeedToListBoxDialog::slotOk() { int side = sideCombo->currentIndex(); bool selected = cbSelected->isChecked(); QString name = lineEdit->text(); QList urlList; QTreeWidgetItemIterator it(syncList); for (;*it; it++) { SynchronizerGUI::SyncViewItem *item = (SynchronizerGUI::SyncViewItem *) * it; SynchronizerFileItem *syncItem = item->synchronizerItemRef(); if (!syncItem || !syncItem->isMarked()) continue; if (selected && !item->isSelected()) continue; if (!equalAllowed && syncItem->task() == TT_EQUALS && (!selected || !item->isSelected())) continue; if ((side == S_BOTH || side == S_LEFT) && syncItem->existsInLeft()) { QString leftDirName = syncItem->leftDirectory().isEmpty() ? "" : syncItem->leftDirectory() + '/'; QUrl leftURL = Synchronizer::fsUrl(synchronizer->leftBaseDirectory() + leftDirName + syncItem->leftName()); urlList.push_back(leftURL); } if ((side == S_BOTH || side == S_RIGHT) && syncItem->existsInRight()) { QString rightDirName = syncItem->rightDirectory().isEmpty() ? "" : syncItem->rightDirectory() + '/'; QUrl leftURL = Synchronizer::fsUrl(synchronizer->rightBaseDirectory() + rightDirName + syncItem->rightName()); urlList.push_back(leftURL); } } QUrl url = QUrl(QString("virt:/") + name); VirtualFileSystem virtFilesystem; if (!virtFilesystem.refresh(url)) { // create directory if it does not exist KMessageBox::error(parentWidget(), i18n("Cannot open %1.", url.toDisplayString())); return; } virtFilesystem.addFiles(urlList); ACTIVE_MNG->slotNewTab(url); accepted = true; accept(); } diff --git a/krusader/krslots.cpp b/krusader/krslots.cpp index 17d371ba..0352f354 100644 --- a/krusader/krslots.cpp +++ b/krusader/krslots.cpp @@ -1,747 +1,747 @@ /***************************************************************************** * 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 "krslots.h" // QtCore #include #include #include #include #include #include // QtGui #include #include // QtWidgets #include #include #include #include #include #include #ifdef __KJSEMBED__ #include #include "KrJS/krjs.h" #endif #include "defaults.h" #include "icon.h" #include "kractions.h" #include "krservices.h" #include "krtrashhandler.h" #include "krusader.h" #include "krusaderview.h" #include "panelmanager.h" #include "ActionMan/actionman.h" #include "BookMan/krbookmarkbutton.h" #include "BookMan/krbookmarkhandler.h" #include "Dialogs/krdialogs.h" #include "Dialogs/krspecialwidgets.h" #include "Dialogs/krspwidgets.h" #include "DiskUsage/diskusagegui.h" #include "FileSystem/fileitem.h" #include "FileSystem/filesystem.h" #include "FileSystem/krquery.h" #include "GUI/dirhistorybutton.h" #include "GUI/kcmdline.h" #include "GUI/kfnkeys.h" #include "GUI/krusaderstatus.h" #include "GUI/mediabutton.h" #include "GUI/terminaldock.h" #include "KViewer/krviewer.h" #include "Konfigurator/konfigurator.h" #include "Locate/locate.h" #include "MountMan/kmountman.h" #include "Panel/PanelView/krselectionmode.h" #include "Panel/PanelView/krview.h" #include "Panel/PanelView/krviewfactory.h" #include "Panel/PanelView/krviewitem.h" #include "Panel/listpanel.h" #include "Panel/panelfunc.h" #include "Panel/sidebar.h" #include "Search/krsearchdialog.h" #include "Search/krsearchmod.h" #include "Splitter/combiner.h" #include "Splitter/splitter.h" #include "Splitter/splittergui.h" #ifdef SYNCHRONIZER_ENABLED #include "Synchronizer/synchronizergui.h" #endif #define ACTIVE_VIEW _mainWindow->activeView() KRslots::KRslots(QObject *parent) : QObject(parent), _mainWindow(krApp) { } void KRslots::sendFileByEmail(const QList &urls) { if (urls.count() == 0) { KMessageBox::error(0, i18n("No selected files to send.")); return; } QString mailProg; QStringList lst = KrServices::supportedTools(); if (lst.contains("MAIL")) mailProg = lst[lst.indexOf("MAIL") + 1]; else { KMessageBox::error(0, i18n("Krusader cannot find a supported mail client. Please install one to your path. Hint: Krusader supports KMail.")); return; } QString subject, separator; foreach(const QUrl &url, urls) { subject += separator + url.fileName(); separator = ','; } subject = i18np("Sending file: %2", "Sending files: %2", urls.count(), subject); KProcess proc; QString executable = QUrl::fromLocalFile(mailProg).fileName(); if (executable == QStringLiteral("kmail")) { proc << mailProg << "--subject" << subject; foreach(const QUrl &url2, urls) proc << "--attach" << url2.toDisplayString(); } else if (executable == QStringLiteral("thunderbird")) { QString param = "attachment=\'"; separator = ""; foreach(const QUrl &url2, urls) { param += separator + url2.toDisplayString(); separator = ','; } param += "\',subject=\'" + subject + "\'"; proc << mailProg << "--compose" << param; } else if (executable == QStringLiteral("evolution")) { QString param = "mailto:?cc=&subject=" + subject + "&attach="; separator = ""; foreach(const QUrl &url2, urls) { param += separator + url2.toDisplayString(); separator = "&attach="; } proc << mailProg << param + ""; } if (!proc.startDetached()) KMessageBox::error(0, i18n("Error executing %1.", mailProg)); } void KRslots::compareContent() { const QStringList lstLeft = LEFT_PANEL->getSelectedNames(); const QStringList lstRight = RIGHT_PANEL->getSelectedNames(); const QStringList lstActive = ACTIVE_PANEL->gui->isLeft() ? lstLeft : lstRight; QUrl name1, name2; if (lstLeft.count() == 1 && lstRight.count() == 1) { // first, see if we've got exactly 1 selected file in each panel: name1 = LEFT_PANEL->func->files()->getUrl(lstLeft[0]); name2 = RIGHT_PANEL->func->files()->getUrl(lstRight[0]); } else if (lstActive.count() == 2) { // next try: are in the current panel exactly 2 files selected? name1 = ACTIVE_PANEL->func->files()->getUrl(lstActive[0]); name2 = ACTIVE_PANEL->func->files()->getUrl(lstActive[1]); } else if (ACTIVE_PANEL->otherPanel()->func->files()->getFileItem(ACTIVE_VIEW->getCurrentItem())) { // next try: is in the other panel a file with the same name? name1 = ACTIVE_PANEL->func->files()->getUrl(ACTIVE_VIEW->getCurrentItem()); name2 = ACTIVE_PANEL->otherPanel()->func->files()->getUrl(ACTIVE_VIEW->getCurrentItem()); } else { // if we got here, then we can't be sure what file to diff KMessageBox::sorry(0, "" + i18n("Do not know which files to compare.") + "

" + i18n("To compare two files by content, you can either:
  • Select one file in the left panel, and one in the right panel.
  • Select exactly two files in the active panel.
  • Make sure there is a file in the other panel, with the same name as the current file in the active panel.
") + "
"); return; } // else implied: all ok, let's call an external program to compare files // but if any of the files isn't local, download it first compareContent(name1, name2); } bool downloadToTemp(const QUrl &url, QString &dest) { QTemporaryFile tmpFile; tmpFile.setAutoRemove(false); if (tmpFile.open()) { dest = tmpFile.fileName(); KIO::Job* job = KIO::file_copy(url, QUrl::fromLocalFile(dest), -1, KIO::Overwrite | KIO::HideProgressInfo); if(!job->exec()) { KMessageBox::error(krApp, i18n("Krusader is unable to download %1", url.fileName())); return false; } return true; } return false; } void KRslots::compareContent(QUrl url1, QUrl url2) { QString diffProg; QStringList lst = KrServices::supportedTools(); if (lst.contains("DIFF")) diffProg = lst[lst.indexOf("DIFF") + 1]; else { KMessageBox::error(0, i18n("Krusader cannot find any of the supported diff-frontends. Please install one to your path. Hint: Krusader supports Kompare, KDiff3 and Xxdiff.")); return; } QString tmp1; QString tmp2; // kdiff3 sucks with spaces if (QUrl::fromLocalFile(diffProg).fileName() == "kdiff3" && !url1.toDisplayString().contains(" ") && !url2.toDisplayString().contains(" ")) { tmp1 = url1.toDisplayString(); tmp2 = url2.toDisplayString(); } else { if (!url1.isLocalFile()) { if (!downloadToTemp(url1, tmp1)) { return; } } else tmp1 = url1.path(); if (!url2.isLocalFile()) { if (!downloadToTemp(url2, tmp2)) { if (tmp1 != url1.path()) QFile::remove(tmp1); return; } } else tmp2 = url2.path(); } KrProcess *p = new KrProcess(tmp1 != url1.path() ? tmp1 : QString(), tmp2 != url2.path() ? tmp2 : QString()); *p << diffProg << tmp1 << tmp2; p->start(); if (!p->waitForStarted()) KMessageBox::error(0, i18n("Error executing %1.", diffProg)); } // GUI toggle slots void KRslots::toggleFnkeys() { if (MAIN_VIEW->fnKeys()->isVisible()) MAIN_VIEW->fnKeys()->hide(); else MAIN_VIEW->fnKeys()->show(); } void KRslots::toggleCmdline() { if (MAIN_VIEW->cmdLine()->isVisible()) MAIN_VIEW->cmdLine()->hide(); else MAIN_VIEW->cmdLine()->show(); } void KRslots::updateStatusbarVisibility() { krApp->statusBar()->setVisible(KrActions::actShowStatusBar->isChecked()); } void KRslots::toggleTerminal() { MAIN_VIEW->setTerminalEmulator(KrActions::actToggleTerminal->isChecked()); } void KRslots::insertFileName(bool fullPath) { QString filename = ACTIVE_VIEW->getCurrentItem(); if (filename.isEmpty()) { return; } if (fullPath) { const QString path = FileSystem::ensureTrailingSlash(ACTIVE_PANEL->virtualPath()) .toDisplayString(QUrl::PreferLocalFile); filename = path + filename; } filename = KrServices::quote(filename); if (MAIN_VIEW->cmdLine()->isVisible() || !MAIN_VIEW->terminalDock()->isTerminalVisible()) { QString current = MAIN_VIEW->cmdLine()->text(); if (current.length() != 0 && !current.endsWith(' ')) current += ' '; MAIN_VIEW->cmdLine()->setText(current + filename); MAIN_VIEW->cmdLine()->setFocus(); } else if (MAIN_VIEW->terminalDock()->isTerminalVisible()) { filename = ' ' + filename + ' '; MAIN_VIEW->terminalDock()->sendInput(filename, false); MAIN_VIEW->terminalDock()->setFocus(); } } void KRslots::refresh(const QUrl &u) { ACTIVE_FUNC->openUrl(u); } void KRslots::runKonfigurator(bool firstTime) { Konfigurator *konfigurator = new Konfigurator(firstTime); - connect(konfigurator, SIGNAL(configChanged(bool)), SLOT(configChanged(bool))); + connect(konfigurator, &Konfigurator::configChanged, this, &KRslots::configChanged); //FIXME - no need to exec konfigurator->exec(); delete konfigurator; } void KRslots::configChanged(bool isGUIRestartNeeded) { krConfig->sync(); if (isGUIRestartNeeded) { krApp->setUpdatesEnabled(false); KConfigGroup group(krConfig, "Look&Feel"); FileItem::loadUserDefinedFolderIcons(group.readEntry("Load User Defined Folder Icons", _UserDefinedFolderIcons)); bool leftActive = ACTIVE_PANEL->gui->isLeft(); MAIN_VIEW->leftManager()->slotRecreatePanels(); MAIN_VIEW->rightManager()->slotRecreatePanels(); if(leftActive) LEFT_PANEL->slotFocusOnMe(); else RIGHT_PANEL->slotFocusOnMe(); MAIN_VIEW->fnKeys()->updateShortcuts(); KrSelectionMode::resetSelectionHandler(); krApp->setUpdatesEnabled(true); } krApp->setTray(); // really ugly, but reload the Fn keys just in case - csaba: any better idea? MAIN_VIEW->fnKeys()->updateShortcuts(); const bool showHidden = KConfigGroup(krConfig, "Look&Feel") .readEntry("Show Hidden", KrActions::actToggleHidden->isChecked()); if (showHidden != KrActions::actToggleHidden->isChecked()) { KrActions::actToggleHidden->setChecked(showHidden); MAIN_VIEW->leftManager()->reloadConfig(); MAIN_VIEW->rightManager()->reloadConfig(); } } void KRslots::showHiddenFiles(bool show) { KConfigGroup group(krConfig, "Look&Feel"); group.writeEntry("Show Hidden", show); MAIN_VIEW->leftManager()->reloadConfig(); MAIN_VIEW->rightManager()->reloadConfig(); } void KRslots::swapPanels() { QUrl leftURL = LEFT_PANEL->virtualPath(); QUrl rightURL = RIGHT_PANEL->virtualPath(); LEFT_PANEL->func->openUrl(rightURL); RIGHT_PANEL->func->openUrl(leftURL); } void KRslots::toggleSwapSides() { MAIN_VIEW->swapSides(); } void KRslots::search() { if (KrSearchDialog::SearchDialog != 0) { KConfigGroup group(krConfig, "Search"); if (group.readEntry("Window Maximized", false)) KrSearchDialog::SearchDialog->showMaximized(); else KrSearchDialog::SearchDialog->showNormal(); KrSearchDialog::SearchDialog->raise(); KrSearchDialog::SearchDialog->activateWindow(); } else KrSearchDialog::SearchDialog = new KrSearchDialog(); } void KRslots::locate() { if (!KrServices::cmdExist("locate")) { KMessageBox::error(krApp, i18n("Cannot find the 'locate' command. Please install the " "findutils-locate package of GNU, or set its dependencies in " "Konfigurator")); return; } if (LocateDlg::LocateDialog != nullptr) { LocateDlg::LocateDialog->showNormal(); LocateDlg::LocateDialog->raise(); LocateDlg::LocateDialog->activateWindow(); LocateDlg::LocateDialog->reset(); } else LocateDlg::LocateDialog = new LocateDlg(krApp); } void KRslots::runTerminal(const QString & dir) { KProcess proc; proc.setWorkingDirectory(dir); KConfigGroup group(krConfig, "General"); QString term = group.readEntry("Terminal", _Terminal); QStringList sepdArgs = KShell::splitArgs(term, KShell::TildeExpand); if (sepdArgs.isEmpty()) { KMessageBox::error(krMainWindow, i18nc("Arg is a string containing the bad quoting.", "Bad quoting in terminal command:\n%1", term)); return; } for (int i = 0; i < sepdArgs.size(); i++) { if (sepdArgs[i] == "%d") { sepdArgs[i] = dir; } } proc << sepdArgs; if (!proc.startDetached()) KMessageBox::sorry(krApp, i18n("Error executing %1.", term)); } void KRslots::homeTerminal() { runTerminal(QDir::homePath()); } void KRslots::multiRename() { QStringList lst = KrServices::supportedTools(); int i = lst.indexOf("RENAME"); if (i == -1) { KMessageBox::sorry(krApp, i18n("Cannot find a batch rename tool.\nYou can get KRename at http://www.krename.net")); return; } QString pathToRename = lst[i+1]; const QStringList names = ACTIVE_PANEL->gui->getSelectedNames(); if (names.isEmpty()) { return; } KProcess proc; proc << pathToRename; for (const QString name: names) { FileItem *file = ACTIVE_FUNC->files()->getFileItem(name); if (!file) continue; const QUrl url = file->getUrl(); // KRename only supports the recursive option combined with a local directory path if (file->isDir() && url.scheme() == "file") { proc << "-r" << url.path(); } else { proc << url.toString(); } } if (!proc.startDetached()) KMessageBox::error(0, i18n("Error executing '%1'.", proc.program().join(" "))); } void KRslots::rootKrusader() { if (KMessageBox::warningContinueCancel( krApp, i18n("Improper operations in root mode can damage your operating system. " "

Furthermore, running UI applications as root is insecure and can " "allow attackers to gain root access."), QString(), KStandardGuiItem::cont(), KStandardGuiItem::cancel(), "Confirm Root Mode", KMessageBox::Notify | KMessageBox::Dangerous) != KMessageBox::Continue) return; if (!KrServices::isExecutable(KDESU_PATH)) { KMessageBox::sorry(krApp, i18n("Cannot start root mode Krusader, %1 not found or not executable. " "Please verify that kde-cli-tools are installed.", QString(KDESU_PATH))); return; } KProcess proc; proc << KDESU_PATH << "-c" << QApplication::instance()->applicationFilePath() + " --left=" + KrServices::quote(LEFT_PANEL->virtualPath().toDisplayString(QUrl::PreferLocalFile)) + " --right=" + KrServices::quote(RIGHT_PANEL->virtualPath().toDisplayString(QUrl::PreferLocalFile)); if (!proc.startDetached()) KMessageBox::error(0, i18n("Error executing %1.", proc.program()[0])); } void KRslots::slotSplit() { const QStringList list = ACTIVE_PANEL->gui->getSelectedNames(); QString name; // first, see if we've got exactly 1 selected file, if not, try the current one if (list.count() == 1) name = list[0]; if (name.isEmpty()) { // if we got here, then one of the panel can't be sure what file to diff KMessageBox::error(0, i18n("Do not know which file to split.")); return; } QUrl fileURL = ACTIVE_FUNC->files()->getUrl(name); if (fileURL.isEmpty()) return; if (ACTIVE_FUNC->files()->getFileItem(name)->isDir()) { KMessageBox::sorry(krApp, i18n("You cannot split a folder.")); return; } const QUrl destDir = ACTIVE_PANEL->otherPanel()->virtualPath(); SplitterGUI splitterGUI(MAIN_VIEW, fileURL, destDir); if (splitterGUI.exec() == QDialog::Accepted) { bool splitToOtherPanel = splitterGUI.getDestinationDir().matches(ACTIVE_PANEL->otherPanel()->virtualPath(), QUrl::StripTrailingSlash); Splitter split(MAIN_VIEW, fileURL, splitterGUI.getDestinationDir(), splitterGUI.overWriteFiles()); split.split(splitterGUI.getSplitSize()); if (splitToOtherPanel) ACTIVE_PANEL->otherPanel()->func->refresh(); } } void KRslots::slotCombine() { const QStringList list = ACTIVE_PANEL->gui->getSelectedNames(); if (list.isEmpty()) { KMessageBox::error(0, i18n("Do not know which files to combine.")); return; } QUrl baseURL; bool unixStyle = false; bool windowsStyle = false; QString commonName; int commonLength = 0; /* checking splitter names */ for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it) { QUrl url = ACTIVE_FUNC->files()->getUrl(*it); if (url.isEmpty()) return; if (ACTIVE_FUNC->files()->getFileItem(*it)->isDir()) { KMessageBox::sorry(krApp, i18n("You cannot combine a folder.")); return; } if (!unixStyle) { QString name = url.fileName(); int extPos = name.lastIndexOf('.'); QString ext = name.mid(extPos + 1); name.truncate(extPos); url = url.adjusted(QUrl::RemoveFilename); url.setPath(url.path() + name); bool isExtInt; ext.toInt(&isExtInt, 10); if (extPos < 1 || ext.isEmpty() || (ext != "crc" && !isExtInt)) { if (windowsStyle) { KMessageBox::error(0, i18n("Not a split file: %1.", url.toDisplayString(QUrl::PreferLocalFile))); return; } unixStyle = true; } else { if (ext != "crc") windowsStyle = true; if (baseURL.isEmpty()) baseURL = url; else if (baseURL != url) { KMessageBox::error(0, i18n("Select only one split file.")); return; } } } if (unixStyle) { bool error = true; do { QString shortName = *it; QChar lastChar = shortName.at(shortName.length() - 1); if (lastChar.isLetter()) { char fillLetter = (lastChar.toUpper() == lastChar) ? 'A' : 'a'; if (commonName.isNull()) { commonLength = shortName.length(); commonName = shortName; while (commonName.length()) { QString shorter = commonName.left(commonName.length() - 1); QString testFile = shorter.leftJustified(commonLength, fillLetter); if (ACTIVE_FUNC->files()->getFileItem(testFile) == 0) break; else { commonName = shorter; baseURL = ACTIVE_PANEL->virtualPath().adjusted(QUrl::StripTrailingSlash); baseURL.setPath(baseURL.path() + '/' + (testFile)); } } error = (commonName == shortName); } else if (commonLength == shortName.length() && shortName.startsWith(commonName)) error = false; } } while (false); if (error) { KMessageBox::error(0, i18n("Not a split file: %1.", url.toDisplayString(QUrl::PreferLocalFile))); return; } } } // ask the user for the copy dest QUrl dest = KChooseDir::getDir(i18n("Combining %1.* to folder:", baseURL.toDisplayString(QUrl::PreferLocalFile)), ACTIVE_PANEL->otherPanel()->virtualPath(), ACTIVE_PANEL->virtualPath()); if (dest.isEmpty()) return ; // the user canceled bool combineToOtherPanel = (dest.matches(ACTIVE_PANEL->otherPanel()->virtualPath(), QUrl::StripTrailingSlash)); Combiner combine(MAIN_VIEW, baseURL, dest, unixStyle); combine.combine(); if (combineToOtherPanel) ACTIVE_PANEL->otherPanel()->func->refresh(); } void KRslots::manageUseractions() { ActionMan actionMan(MAIN_VIEW); } #ifdef SYNCHRONIZER_ENABLED void KRslots::slotSynchronizeDirs(QStringList selected) { SynchronizerGUI *synchronizerDialog = new SynchronizerGUI(MAIN_VIEW, LEFT_PANEL->virtualPath(), RIGHT_PANEL->virtualPath(), selected); synchronizerDialog->show(); // destroyed on close } #endif void KRslots::compareSetup() { for (int i = 0; KrActions::compareArray[i] != 0; i++) if ((*KrActions::compareArray[i])->isChecked()) { KConfigGroup group(krConfig, "Private"); group.writeEntry("Compare Mode", i); break; } } /** called by actions actExec* to choose the built-in command line mode */ void KRslots::execTypeSetup() { for (int i = 0; KrActions::execTypeArray[i] != 0; i++) if ((*KrActions::execTypeArray[i])->isChecked()) { if (*KrActions::execTypeArray[i] == KrActions::actExecTerminalEmbedded) { // if commands are to be executed in the TE, it must be loaded MAIN_VIEW->terminalDock()->initialise(); } KConfigGroup grp(krConfig, "Private"); grp.writeEntry("Command Execution Mode", i); break; } } void KRslots::slotDiskUsage() { DiskUsageGUI *diskUsageDialog = new DiskUsageGUI(ACTIVE_PANEL->virtualPath()); diskUsageDialog->askDirAndShow(); } void KRslots::applicationStateChanged() { if (MAIN_VIEW == 0) { /* CRASH FIX: it's possible that the method is called after destroying the main view */ return; } if(qApp->applicationState() == Qt::ApplicationActive || qApp->applicationState() == Qt::ApplicationInactive) { LEFT_PANEL->panelVisible(); RIGHT_PANEL->panelVisible(); } else { LEFT_PANEL->panelHidden(); RIGHT_PANEL->panelHidden(); } } void KRslots::emptyTrash() { KrTrashHandler::emptyTrash(); } #define OPEN_ID 100001 #define EMPTY_TRASH_ID 100002 void KRslots::trashPopupMenu() { QMenu trashMenu(krApp); QAction * act = trashMenu.addAction(Icon("document-open"), i18n("Open trash bin")); act->setData(QVariant(OPEN_ID)); act = trashMenu.addAction(Icon("trash-empty"), i18n("Empty trash bin")); act->setData(QVariant(EMPTY_TRASH_ID)); int result = -1; QAction *res = trashMenu.exec(QCursor::pos()); if (res && res->data().canConvert ()) result = res->data().toInt(); if (result == OPEN_ID) { ACTIVE_FUNC->openUrl(QUrl(QStringLiteral("trash:/"))); } else if (result == EMPTY_TRASH_ID) { KrTrashHandler::emptyTrash(); } } //shows the JavaScript-Console void KRslots::jsConsole() { #ifdef __KJSEMBED__ if (! krJS) krJS = new KrJS(); krJS->view()->show(); #endif } void KRslots::addBookmark() { krBookMan->bookmarkCurrent(ACTIVE_PANEL->virtualPath()); } void KRslots::cmdlinePopup() { MAIN_VIEW->cmdLine()->popup(); }