diff --git a/krusader/Dialogs/krmaskchoice.cpp b/krusader/Dialogs/krmaskchoice.cpp
index 3a810eb1..442e5057 100644
--- a/krusader/Dialogs/krmaskchoice.cpp
+++ b/krusader/Dialogs/krmaskchoice.cpp
@@ -1,151 +1,152 @@
/*****************************************************************************
* Copyright (C) 2000 Shie Erlich *
* Copyright (C) 2000 Rafi Yanai *
* Copyright (C) 2004-2020 Krusader Krew [https://krusader.org] *
* *
* This file is part of Krusader [https://krusader.org]. *
* *
* Krusader is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 2 of the License, or *
* (at your option) any later version. *
* *
* Krusader is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with Krusader. If not, see [http://www.gnu.org/licenses/]. *
*****************************************************************************/
#include "krmaskchoice.h"
// QtCore
#include
// QtWidgets
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "../GUI/krlistwidget.h"
+#include "../compat.h"
/**
* Constructs a KrMaskChoice which is a child of 'parent', with the
* name 'name' and widget flags set to 'f'
*
* The dialog will by default be modeless, unless you set 'modal' to
* TRUE to construct a modal dialog.
*/
KrMaskChoice::KrMaskChoice(QWidget* parent)
: QDialog(parent)
{
setModal(true);
resize(401, 314);
setWindowTitle(i18n("Choose Files"));
auto* MainLayout = new QVBoxLayout(this);
auto* HeaderLayout = new QHBoxLayout();
MainLayout->addLayout(HeaderLayout);
PixmapLabel1 = new QLabel(this);
PixmapLabel1->setScaledContents(true);
PixmapLabel1->setMaximumSize(QSize(31, 31));
HeaderLayout->addWidget(PixmapLabel1);
label = new QLabel(this);
label->setText(i18n("Select the following files:"));
HeaderLayout->addWidget(label);
selection = new KComboBox(this);
selection->setEditable(true);
selection->setInsertPolicy(QComboBox::InsertAtTop);
selection->setAutoCompletion(true);
MainLayout->addWidget(selection);
auto* GroupBox1 = new QGroupBox(this);
GroupBox1->setTitle(i18n("Predefined Selections"));
MainLayout->addWidget(GroupBox1);
auto* gbLayout = new QHBoxLayout(GroupBox1);
preSelections = new KrListWidget(GroupBox1);
preSelections->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
preSelections->setWhatsThis(i18n("A predefined selection is a file-mask which you often use.\nSome examples are: \"*.c, *.h\", \"*.c, *.o\", etc.\nYou can add these masks to the list by typing them and pressing the Add button.\nDelete removes a predefined selection and Clear removes all of them.\nNotice that the line in which you edit the mask has its own history, you can scroll it, if needed."));
gbLayout->addWidget(preSelections);
auto* vbox = new QVBoxLayout();
gbLayout->addLayout(vbox);
PushButton7 = new QPushButton(GroupBox1);
PushButton7->setText(i18n("Add"));
PushButton7->setToolTip(i18n("Adds the selection in the line-edit to the list"));
vbox->addWidget(PushButton7);
PushButton7_2 = new QPushButton(GroupBox1);
PushButton7_2->setText(i18n("Delete"));
PushButton7_2->setToolTip(i18n("Delete the marked selection from the list"));
vbox->addWidget(PushButton7_2);
PushButton7_3 = new QPushButton(GroupBox1);
PushButton7_3->setText(i18n("Clear"));
PushButton7_3->setToolTip(i18n("Clears the entire list of selections"));
vbox->addWidget(PushButton7_3);
vbox->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Expanding));
QDialogButtonBox* ButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
MainLayout->addWidget(ButtonBox);
// signals and slots connections
connect(ButtonBox, &QDialogButtonBox::rejected, this, &KrMaskChoice::reject);
connect(ButtonBox, &QDialogButtonBox::accepted, this, &KrMaskChoice::accept);
connect(PushButton7, &QPushButton::clicked, this, &KrMaskChoice::addSelection);
connect(PushButton7_2, &QPushButton::clicked, this, &KrMaskChoice::deleteSelection);
connect(PushButton7_3, &QPushButton::clicked, this, &KrMaskChoice::clearSelections);
- connect(selection, QOverload::of(&KComboBox::activated), selection, &KComboBox::setEditText);
+ connect(selection, QOverload::of(&KComboBox::QCOMBOBOX_ACTIVATED), selection, &KComboBox::setEditText);
connect(selection->lineEdit(), &QLineEdit::returnPressed, this, &KrMaskChoice::accept);
connect(preSelections, &KrListWidget::currentItemChanged, this, &KrMaskChoice::currentItemChanged);
connect(preSelections, &KrListWidget::itemActivated, this, &KrMaskChoice::acceptFromList);
}
/*
* Destroys the object and frees any allocated resources
*/
KrMaskChoice::~KrMaskChoice()
{
// no need to delete child widgets, Qt does it all for us
}
void KrMaskChoice::addSelection()
{
qWarning("KrMaskChoice::addSelection(): Not implemented yet!");
}
void KrMaskChoice::clearSelections()
{
qWarning("KrMaskChoice::clearSelections(): Not implemented yet!");
}
void KrMaskChoice::deleteSelection()
{
qWarning("KrMaskChoice::deleteSelection(): Not implemented yet!");
}
void KrMaskChoice::acceptFromList(QListWidgetItem *)
{
qWarning("KrMaskChoice::acceptFromList(QListWidgetItem *): Not implemented yet!");
}
void KrMaskChoice::currentItemChanged(QListWidgetItem *)
{
qWarning("KrMaskChoice::currentItemChanged(QListWidgetItem *): Not implemented yet!");
}
diff --git a/krusader/Dialogs/newftpgui.cpp b/krusader/Dialogs/newftpgui.cpp
index 294936a3..53af81ba 100644
--- a/krusader/Dialogs/newftpgui.cpp
+++ b/krusader/Dialogs/newftpgui.cpp
@@ -1,203 +1,204 @@
/*****************************************************************************
* Copyright (C) 2002 Shie Erlich *
* Copyright (C) 2002 Rafi Yanai *
* Copyright (C) 2009 Fathi Boudra *
* Copyright (C) 2004-2020 Krusader Krew [https://krusader.org] *
* *
* This file is part of Krusader [https://krusader.org]. *
* *
* Krusader is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 2 of the License, or *
* (at your option) any later version. *
* *
* Krusader is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with Krusader. If not, see [http://www.gnu.org/licenses/]. *
*****************************************************************************/
#include "newftpgui.h"
// QtCore
#include
#include
// QtGui
#include
// QtWidgets
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "../krglobal.h"
#include "../icon.h"
+#include "../compat.h"
#define SIZE_MINIMUM QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)
const QStringList sProtocols = QStringList()
<< QStringLiteral("ftp") << QStringLiteral("ftps")
<< QStringLiteral("sftp")
<< QStringLiteral("fish") << QStringLiteral("nfs")
<< QStringLiteral("smb") << QStringLiteral("webdav")
<< QStringLiteral("svn") << QStringLiteral("svn+file")
<< QStringLiteral("svn+http") << QStringLiteral("svn+https")
<< QStringLiteral("svn+ssh");
/**
* Constructs a newFTPGUI which is a child of 'parent',
* with the name 'name' and widget flags set to 'f'
*/
newFTPGUI::newFTPGUI(QWidget* parent) : QDialog(parent)
{
setModal(true);
setWindowTitle(i18n("New Network Connection"));
resize(500, 240);
auto *mainLayout = new QVBoxLayout;
setLayout(mainLayout);
QSizePolicy policy(QSizePolicy::Preferred, QSizePolicy::Preferred);
policy.setHeightForWidth(sizePolicy().hasHeightForWidth());
setSizePolicy(policy);
iconLabel = new QLabel(this);
iconLabel->setPixmap(Icon("network-wired").pixmap(32));
iconLabel->setSizePolicy(SIZE_MINIMUM);
aboutLabel = new QLabel(i18n("About to connect to..."), this);
QFont font(aboutLabel->font());
font.setBold(true);
aboutLabel->setFont(font);
protocolLabel = new QLabel(i18n("Protocol:"), this);
hostLabel = new QLabel(i18n("Host:"), this);
portLabel = new QLabel(i18n("Port:"), this);
prefix = new KComboBox(this);
prefix->setObjectName(QString::fromUtf8("protocol"));
prefix->setSizePolicy(SIZE_MINIMUM);
url = new KrHistoryComboBox(this);
url->setMaxCount(50);
url->setMinimumContentsLength(10);
const QStringList availableProtocols = KProtocolInfo::protocols();
for (const QString& protocol : sProtocols) {
if (availableProtocols.contains(protocol))
prefix->addItem(protocol + QStringLiteral("://"));
}
// load the history and completion list after creating the history combo
KConfigGroup group(krConfig, "Private");
QStringList list = group.readEntry("newFTP Completion list", QStringList());
url->completionObject()->setItems(list);
list = group.readEntry("newFTP History list", QStringList());
url->setHistoryItems(list);
// Select last used protocol
const QString lastUsedProtocol = group.readEntry("newFTP Protocol", QString());
if(!lastUsedProtocol.isEmpty()) {
prefix->setCurrentItem(lastUsedProtocol);
}
port = new QSpinBox(this);
port->setMaximum(65535);
port->setValue(21);
port->setSizePolicy(SIZE_MINIMUM);
usernameLabel = new QLabel(i18n("Username:"), this);
username = new KLineEdit(this);
passwordLabel = new QLabel(i18n("Password:"), this);
password = new KLineEdit(this);
password->setEchoMode(QLineEdit::Password);
auto *horizontalLayout = new QHBoxLayout();
horizontalLayout->addWidget(iconLabel);
horizontalLayout->addWidget(aboutLabel);
auto *gridLayout = new QGridLayout();
gridLayout->addWidget(protocolLabel, 0, 0, 1, 1);
gridLayout->addWidget(hostLabel, 0, 1, 1, 1);
gridLayout->addWidget(portLabel, 0, 2, 1, 1);
gridLayout->addWidget(prefix, 1, 0, 1, 1);
gridLayout->addWidget(url, 1, 1, 1, 1);
gridLayout->addWidget(port, 1, 2, 1, 1);
gridLayout->addWidget(usernameLabel, 2, 0, 1, 1);
gridLayout->addWidget(username, 3, 0, 1, 3);
gridLayout->addWidget(passwordLabel, 4, 0, 1, 1);
gridLayout->addWidget(password, 5, 0, 1, 3);
auto *widgetLayout = new QGridLayout();
widgetLayout->addLayout(horizontalLayout, 0, 0, 1, 1);
widgetLayout->addLayout(gridLayout, 1, 0, 1, 1);
mainLayout->addLayout(widgetLayout);
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
mainLayout->addWidget(buttonBox);
QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
okButton->setText(i18n("&Connect"));
okButton->setDefault(true);
okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
connect(buttonBox, &QDialogButtonBox::accepted, this, &newFTPGUI::accept);
connect(buttonBox, &QDialogButtonBox::rejected, this, &newFTPGUI::reject);
- connect(prefix, QOverload::of(&KComboBox::activated), this, &newFTPGUI::slotTextChanged);
- connect(url, QOverload::of(&KrHistoryComboBox::activated), url, &KrHistoryComboBox::addToHistory);
+ connect(prefix, QOverload::of(&KComboBox::QCOMBOBOX_ACTIVATED), this, &newFTPGUI::slotTextChanged);
+ connect(url, QOverload::of(&KrHistoryComboBox::QCOMBOBOX_ACTIVATED), url, &KrHistoryComboBox::addToHistory);
if(!lastUsedProtocol.isEmpty()) {
// update the port field
slotTextChanged(lastUsedProtocol);
}
setTabOrder(url, username);
setTabOrder(username, password);
setTabOrder(password, prefix);
}
/**
* Destroys the object and frees any allocated resources
*/
newFTPGUI::~newFTPGUI()
{
// no need to delete child widgets, Qt does it all for us
}
void newFTPGUI::slotTextChanged(const QString &string)
{
if (string.startsWith(QLatin1String("ftp")) ||
string.startsWith(QLatin1String("sftp")) ||
string.startsWith(QLatin1String("fish"))) {
if (port->value() == 21 || port->value() == 22) {
port->setValue(string.startsWith(QLatin1String("ftp")) ? 21 : 22);
}
port->setEnabled(true);
} else {
port->setEnabled(false);
}
}
/**
* Main event handler. Reimplemented to handle application font changes
*/
bool newFTPGUI::event(QEvent *ev)
{
bool ret = QDialog::event(ev);
if (ev->type() == QEvent::ApplicationFontChange) {
QFont font(aboutLabel->font());
font.setBold(true);
aboutLabel->setFont(font);
}
return ret;
}
diff --git a/krusader/Dialogs/packguibase.cpp b/krusader/Dialogs/packguibase.cpp
index 9f4d4a9e..8b6abd79 100644
--- a/krusader/Dialogs/packguibase.cpp
+++ b/krusader/Dialogs/packguibase.cpp
@@ -1,495 +1,496 @@
/*****************************************************************************
* Copyright (C) 2000 Shie Erlich *
* Copyright (C) 2000 Rafi Yanai *
* Copyright (C) 2004-2020 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 "../defaults.h"
#include "../krglobal.h"
#include "../icon.h"
+#include "../compat.h"
#include "../GUI/krhistorycombobox.h"
/*
* Constructs a PackGUIBase which is a child of 'parent', with the
* name 'name' and widget flags set to 'f'
*
* The dialog will by default be modeless, unless you set 'modal' to
* TRUE to construct a modal dialog.
*/
PackGUIBase::PackGUIBase(QWidget* parent)
: QDialog(parent), expanded(false)
{
KConfigGroup group(krConfig, "Archives");
setModal(true);
resize(430, 140);
setWindowTitle(i18n("Pack"));
grid = new QGridLayout(this);
grid->setSpacing(6);
grid->setContentsMargins(11, 11, 11, 11);
hbox = new QHBoxLayout;
hbox->setSpacing(6);
hbox->setContentsMargins(0, 0, 0, 0);
TextLabel3 = new QLabel(this);
TextLabel3->setText(i18n("To archive"));
hbox->addWidget(TextLabel3);
nameData = new QLineEdit(this);
hbox->addWidget(nameData);
typeData = new QComboBox(this);
typeData->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed));
- connect(typeData, QOverload::of(&QComboBox::activated), this, &PackGUIBase::checkConsistency);
+ connect(typeData, QOverload::of(&QComboBox::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);
auto* spacer = new QSpacerItem(48, 20, QSizePolicy::Fixed, QSizePolicy::Fixed);
hbox_2->addItem(spacer);
grid->addLayout(hbox_2, 2, 0);
hbox_3 = new QHBoxLayout;
hbox_3->setSpacing(6);
hbox_3->setContentsMargins(0, 0, 0, 0);
PixmapLabel1 = new QLabel(this);
PixmapLabel1->setPixmap(Icon("package-x-generic").pixmap(32));
PixmapLabel1->setScaledContents(true);
PixmapLabel1->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
hbox_3->addWidget(PixmapLabel1);
TextLabel1 = new QLabel(this);
TextLabel1->setText(i18n("Pack"));
hbox_3->addWidget(TextLabel1);
grid->addLayout(hbox_3, 0, 0);
hbox_4 = new QHBoxLayout;
hbox_4->setSpacing(6);
hbox_4->setContentsMargins(0, 0, 0, 0);
auto* spacer_3 = new QSpacerItem(20, 26, QSizePolicy::Fixed, QSizePolicy::Expanding);
hbox_4->addItem(spacer_3);
grid->addLayout(hbox_4, 3, 0);
advancedWidget = new QWidget(this);
hbox_5 = new QGridLayout(advancedWidget);
hbox_5->setSpacing(6);
hbox_5->setContentsMargins(0, 0, 0, 0);
auto *compressLayout = new QVBoxLayout;
compressLayout->setSpacing(6);
compressLayout->setContentsMargins(0, 0, 0, 0);
multipleVolume = new QCheckBox(i18n("Multiple volume archive"), advancedWidget);
connect(multipleVolume, &QCheckBox::toggled, this, &PackGUIBase::checkConsistency);
compressLayout->addWidget(multipleVolume, 0, nullptr);
auto * volumeHbox = new QHBoxLayout;
auto* spacer_5 = new QSpacerItem(20, 26, QSizePolicy::Fixed, QSizePolicy::Fixed);
volumeHbox->addItem(spacer_5);
TextLabel7 = new QLabel(i18n("Size:"), advancedWidget);
volumeHbox->addWidget(TextLabel7);
volumeSpinBox = new QSpinBox(advancedWidget);
volumeSpinBox->setMinimum(1);
volumeSpinBox->setMaximum(9999);
volumeSpinBox->setValue(1440);
volumeHbox->addWidget(volumeSpinBox);
volumeUnitCombo = new QComboBox(advancedWidget);
volumeUnitCombo->addItem("B");
volumeUnitCombo->addItem("KB");
volumeUnitCombo->addItem("MB");
volumeUnitCombo->setCurrentIndex(1);
volumeHbox->addWidget(volumeUnitCombo);
compressLayout->addLayout(volumeHbox);
int level = group.readEntry("Compression level", _defaultCompressionLevel);
setCompressionLevel = new QCheckBox(i18n("Set compression level"), advancedWidget);
if (level != _defaultCompressionLevel)
setCompressionLevel->setChecked(true);
connect(setCompressionLevel, &QCheckBox::toggled, this, &PackGUIBase::checkConsistency);
compressLayout->addWidget(setCompressionLevel, 0, nullptr);
auto * sliderHbox = new QHBoxLayout;
auto* spacer_6 = new QSpacerItem(20, 26, QSizePolicy::Fixed, QSizePolicy::Fixed);
sliderHbox->addItem(spacer_6);
QWidget * sliderVBoxWidget = new QWidget(advancedWidget);
auto *sliderVBox = new QVBoxLayout(sliderVBoxWidget);
compressionSlider = new QSlider(Qt::Horizontal, sliderVBoxWidget);
compressionSlider->setMinimum(1);
compressionSlider->setMaximum(9);
compressionSlider->setPageStep(1);
compressionSlider->setValue(level);
compressionSlider->setTickPosition(QSlider::TicksBelow);
sliderVBox->addWidget(compressionSlider);
QWidget * minmaxWidget = new QWidget(sliderVBoxWidget);
sliderVBox->addWidget(minmaxWidget);
auto * minmaxHbox = new QHBoxLayout(minmaxWidget);
minLabel = new QLabel(i18n("MIN"), minmaxWidget);
maxLabel = new QLabel(i18n("MAX"), minmaxWidget);
maxLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
minmaxHbox->addWidget(minLabel);
minmaxHbox->addWidget(maxLabel);
sliderHbox->addWidget(sliderVBoxWidget);
compressLayout->addLayout(sliderHbox);
compressLayout->addStretch(0);
hbox_5->addLayout(compressLayout, 0, 0);
QFrame *vline = new QFrame(advancedWidget);
vline->setFrameStyle(QFrame::VLine | QFrame::Sunken);
vline->setMinimumWidth(20);
hbox_5->addWidget(vline, 0, 1);
auto * passwordGrid = new QGridLayout;
passwordGrid->setSpacing(6);
passwordGrid->setContentsMargins(0, 0, 0, 0);
TextLabel4 = new QLabel(advancedWidget);
TextLabel4->setText(i18n("Password"));
passwordGrid->addWidget(TextLabel4, 0, 0);
password = new QLineEdit(advancedWidget);
password->setEchoMode(QLineEdit::Password);
connect(password, &QLineEdit::textChanged, this, &PackGUIBase::checkConsistency);
passwordGrid->addWidget(password, 0, 1);
TextLabel6 = new QLabel(advancedWidget);
TextLabel6->setText(i18n("Again"));
passwordGrid->addWidget(TextLabel6, 1, 0);
passwordAgain = new QLineEdit(advancedWidget);
passwordAgain->setEchoMode(QLineEdit::Password);
connect(passwordAgain, &QLineEdit::textChanged, this, &PackGUIBase::checkConsistency);
passwordGrid->addWidget(passwordAgain, 1, 1);
auto *consistencyHbox = new QHBoxLayout;
auto* spacer_cons = new QSpacerItem(48, 20, QSizePolicy::Expanding, QSizePolicy::Fixed);
consistencyHbox->addItem(spacer_cons);
passwordConsistencyLabel = new QLabel(advancedWidget);
consistencyHbox->addWidget(passwordConsistencyLabel);
passwordGrid->addLayout(consistencyHbox, 2, 0, 1, 2);
encryptHeaders = new QCheckBox(i18n("Encrypt headers"), advancedWidget);
passwordGrid->addWidget(encryptHeaders, 3, 0, 1, 2);
auto* spacer_psw = new QSpacerItem(20, 20, QSizePolicy::Fixed, QSizePolicy::Expanding);
passwordGrid->addItem(spacer_psw, 4, 0);
hbox_5->addLayout(passwordGrid, 0, 2);
hbox_7 = new QHBoxLayout;
hbox_7->setSpacing(6);
hbox_7->setContentsMargins(0, 0, 0, 0);
TextLabel8 = new QLabel(i18n("Command line switches:"), advancedWidget);
TextLabel8->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
hbox_7->addWidget(TextLabel8);
commandLineSwitches = new KrHistoryComboBox(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);
auto* spacer_2 = new QSpacerItem(140, 20, QSizePolicy::Expanding, QSizePolicy::Fixed);
hbox_6->addItem(spacer_2);
okButton = new QPushButton(this);
KStandardGuiItem::assign(okButton, KStandardGuiItem::Ok);
okButton->setDefault(true);
hbox_6->addWidget(okButton);
cancelButton = new QPushButton(this);
KStandardGuiItem::assign(cancelButton, KStandardGuiItem::Cancel);
hbox_6->addWidget(cancelButton);
grid->addLayout(hbox_6, 6, 0);
// signals and slots connections
connect(okButton, &QPushButton::clicked, this, &PackGUIBase::accept);
connect(advancedButton, &QPushButton::clicked, this, &PackGUIBase::expand);
connect(cancelButton, &QPushButton::clicked, this, &PackGUIBase::reject);
connect(browseButton, &QToolButton::clicked, this, &PackGUIBase::browse);
}
/*
* Destroys the object and frees any allocated resources
*/
PackGUIBase::~PackGUIBase()
{
// no need to delete child widgets, Qt does it all for us
}
void PackGUIBase::browse()
{
qWarning("PackGUIBase::browse(): Not implemented yet!");
}
void PackGUIBase::expand()
{
expanded = !expanded;
advancedButton->setText(expanded ? i18n("&Advanced <<") : i18n("&Advanced >>"));
if (expanded)
advancedWidget->show();
else {
advancedWidget->hide();
layout()->activate();
QSize minSize = minimumSize();
resize(width(), minSize.height());
}
show();
}
void PackGUIBase::checkConsistency()
{
QPalette p = QGuiApplication::palette();
QPalette pal = passwordConsistencyLabel->palette();
if (password->text().isEmpty() && passwordAgain->text().isEmpty()) {
pal.setColor(passwordConsistencyLabel->foregroundRole(), p.color(QPalette::Active, QPalette::Text));
passwordConsistencyLabel->setText(i18n("No password specified"));
} else if (password->text() == passwordAgain->text()) {
pal.setColor(passwordConsistencyLabel->foregroundRole(), p.color(QPalette::Active, QPalette::Text));
passwordConsistencyLabel->setText(i18n("The passwords are equal"));
} else {
pal.setColor(passwordConsistencyLabel->foregroundRole(), Qt::red);
passwordConsistencyLabel->setText(i18n("The passwords are different"));
}
passwordConsistencyLabel->setPalette(pal);
QString packer = typeData->currentText();
bool passworded = false;
if (packer == "7z" || packer == "rar" || packer == "zip" || packer == "arj")
passworded = true;
passwordConsistencyLabel->setEnabled(passworded);
password->setEnabled(passworded);
passwordAgain->setEnabled(passworded);
TextLabel4->setEnabled(passworded);
TextLabel6->setEnabled(passworded);
encryptHeaders->setEnabled(packer == "rar");
multipleVolume->setEnabled(packer == "rar" || packer == "arj");
bool volumeEnabled = multipleVolume->isEnabled() && multipleVolume->isChecked();
volumeSpinBox->setEnabled(volumeEnabled);
volumeUnitCombo->setEnabled(volumeEnabled);
TextLabel7->setEnabled(volumeEnabled);
/* TODO */
setCompressionLevel->setEnabled(packer == "rar" || packer == "arj" || packer == "zip" ||
packer == "7z");
bool sliderEnabled = setCompressionLevel->isEnabled() && setCompressionLevel->isChecked();
compressionSlider->setEnabled(sliderEnabled);
minLabel->setEnabled(sliderEnabled);
maxLabel->setEnabled(sliderEnabled);
}
bool PackGUIBase::extraProperties(QMap & inMap)
{
inMap.clear();
KConfigGroup group(krConfig, "Archives");
if (password->isEnabled() && passwordAgain->isEnabled()) {
if (password->text() != passwordAgain->text()) {
KMessageBox::error(this, i18n("Cannot pack, the passwords are different."));
return false;
}
if (!password->text().isEmpty()) {
inMap[ "Password" ] = password->text();
if (encryptHeaders->isEnabled() && encryptHeaders->isChecked())
inMap[ "EncryptHeaders" ] = '1';
}
}
if (multipleVolume->isEnabled() && multipleVolume->isChecked()) {
KIO::filesize_t size = volumeSpinBox->value();
switch (volumeUnitCombo->currentIndex()) {
case 2:
size *= 1000;
#if __GNUC__ >= 7
[[gnu::fallthrough]];
#endif
case 1:
size *= 1000;
default:
break;
}
if (size < 10000) {
KMessageBox::error(this, i18n("Invalid volume size."));
return false;
}
QString sbuffer;
sbuffer.asprintf("%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);
inMap[ "CommandLineSwitches" ] = cmdArgs;
}
return true;
}
diff --git a/krusader/Filter/generalfilter.cpp b/krusader/Filter/generalfilter.cpp
index e86d4d43..c5431edc 100644
--- a/krusader/Filter/generalfilter.cpp
+++ b/krusader/Filter/generalfilter.cpp
@@ -1,666 +1,667 @@
/*****************************************************************************
* Copyright (C) 2003 Shie Erlich *
* Copyright (C) 2003 Rafi Yanai *
* Copyright (C) 2003 Csaba Karai *
* Copyright (C) 2004-2020 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"
+#include "../compat.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(nullptr), fltTabs(tabs)
{
auto *filterLayout = new QGridLayout(this);
filterLayout->setSpacing(6);
filterLayout->setContentsMargins(11, 11, 11, 11);
this->properties = properties;
// Options for name filtering
auto *nameGroup = new QGroupBox(this);
nameGroup->setTitle(i18n("File Name"));
auto *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 KrHistoryComboBox(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, 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
auto *profileHandler = new QGroupBox(this);
profileHandler->setTitle(i18n("&Profile handler"));
auto *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);
auto *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);
auto *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, &KrHistoryComboBox::setEnabled);
}
middleLayout->addWidget(searchGroupBox);
}
filterLayout->addLayout(middleLayout, 1, 0);
// Options for containing text
auto *containsGroup = new QGroupBox(this);
containsGroup->setTitle(i18n("Containing text"));
auto *containsLayout = new QGridLayout(containsGroup);
containsLayout->setAlignment(Qt::AlignTop);
containsLayout->setSpacing(6);
containsLayout->setContentsMargins(11, 11, 11, 11);
auto *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 KrHistoryComboBox(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.
auto *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);
auto *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);
auto* 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);
auto *recurseLayout = new QHBoxLayout();
recurseLayout->setSpacing(6);
recurseLayout->setContentsMargins(0, 0, 0, 0);
auto* 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++) {
auto *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, QOverload::of(&KrHistoryComboBox::activated), searchFor, &KrHistoryComboBox::addToHistory);
- connect(containsText, QOverload::of(&KrHistoryComboBox::activated), containsText, &KrHistoryComboBox::addToHistory);
+ connect(searchFor, QOverload::of(&KrHistoryComboBox::QCOMBOBOX_ACTIVATED), searchFor, &KrHistoryComboBox::addToHistory);
+ connect(containsText, QOverload::of(&KrHistoryComboBox::QCOMBOBOX_ACTIVATED), containsText, &KrHistoryComboBox::addToHistory);
// 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(const QString& name)
{
QCheckBox *option = extraOptions[name];
return option ? option->isChecked() : false;
}
void GeneralFilter::checkExtraOption(const 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)
{
auto *excludeCheckBox = new QCheckBox(this);
excludeCheckBox->setText(i18n("Exclude Folder Names"));
excludeCheckBox->setToolTip(i18n("Filters out specified folder names from the results."));
excludeCheckBox->setChecked(static_cast(group.readEntry("ExcludeFolderNamesUse", 0)));
return excludeCheckBox;
}
KrHistoryComboBox *GeneralFilter::createExcludeComboBox(const KConfigGroup &group)
{
auto *excludeComboBox = new KrHistoryComboBox(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 != nullptr)
profileManager->overwriteProfile(item->text());
}
void GeneralFilter::slotRemoveBtnClicked()
{
QListWidgetItem *item = profileListBox->currentItem();
if (item != nullptr) {
profileManager->deleteProfile(item->text());
refreshProfileListBox();
}
}
void GeneralFilter::slotProfileDoubleClicked(QListWidgetItem *item)
{
if (item != nullptr) {
QString profileName = item->text();
profileManager->loadProfile(profileName);
fltTabs->close(true);
}
}
void GeneralFilter::slotLoadBtnClicked()
{
QListWidgetItem *item = profileListBox->currentItem();
if (item != nullptr)
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 == nullptr)
return;
auto *regAct = dynamic_cast(act);
if (regAct == nullptr)
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/Panel/panelfunc.cpp b/krusader/Panel/panelfunc.cpp
index 07f6a822..14ee11e0 100644
--- a/krusader/Panel/panelfunc.cpp
+++ b/krusader/Panel/panelfunc.cpp
@@ -1,1407 +1,1407 @@
/*****************************************************************************
* Copyright (C) 2000 Shie Erlich *
* Copyright (C) 2000 Rafi Yanai *
* Copyright (C) 2004-2020 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
#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"
-
+#include "../compat.h"
QPointer ListPanelFunc::copyToClipboardOrigin;
ListPanelFunc::ListPanelFunc(ListPanel *parent) : QObject(parent),
panel(parent), fileSystemP(nullptr), urlManuallyEntered(false),
_isPaused(true), _refreshAfterPaused(true), _quickSizeCalculator(nullptr)
{
history = new DirHistoryQueue(panel);
delayTimer.setSingleShot(true);
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 == nullptr)
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 (mime == QLatin1String("application/x-desktop")) {
KDesktopFileActions::runWithStartup(url, url.isLocalFile(), QByteArray());
return;
}
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;
panel->view->setNameToMakeCurrent(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(nullptr);
// disconnect older signals
disconnect(fileSystemP, nullptr, panel, nullptr);
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(), nullptr, panel, nullptr);
connect(files(), &DirListerInterface::scanDone, panel, &ListPanel::slotStartUpdate);
connect(files(), &FileSystem::fileSystemInfoChanged, panel, &ListPanel::updateFilesystemStats);
connect(files(), &FileSystem::refreshJobStarted, panel, &ListPanel::slotRefreshJobStarted);
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) != nullptr) {
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(nullptr, 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::editFile(const QUrl &filePath)
{
panel->searchBar->hideBarIfSearching();
QUrl editPath;
if (!filePath.isEmpty()) {
editPath = filePath;
} else {
const QString name = panel->getCurrentName();
if (name.isNull())
return;
editPath = files()->getUrl(name);
}
if (editPath.isLocalFile()) {
const KFileItem fileToEdit = KFileItem(editPath);
if (fileToEdit.isDir()) {
KMessageBox::sorry(krMainWindow, i18n("You cannot edit a folder"));
return;
}
if (!fileToEdit.isReadable()) {
KMessageBox::sorry(nullptr, i18n("No permissions to edit this file."));
return;
}
KrViewer::edit(editPath);
} else {
KIO::StatJob* statJob = KIO::stat(editPath, KIO::HideProgressInfo);
connect(statJob, &KIO::StatJob::result, this, &ListPanelFunc::slotStatEdit);
}
}
void ListPanelFunc::askEditFile()
{
// ask the user for the filename to edit
const QUrl filePath = KChooseDir::getFile(i18n("Enter the filename to edit:"),
QUrl(panel->getCurrentName()), panel->virtualPath());
if (filePath.isEmpty()) {
return; // the user canceled
}
if (filePath.isLocalFile()) {
// if the file exists, edit it instead of creating a new one
QFile file(filePath.toLocalFile());
if (file.exists()) {
editFile(filePath);
return;
} else {
// simply create a local file
// also because KIO::CopyJob::setDefaultPermissions does not work
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
file.open(QIODevice::NewOnly);
#else
file.open(QIODevice::WriteOnly);
#endif
file.close();
slotFileCreated(nullptr, filePath);
return;
}
} else {
KIO::StatJob* statJob = KIO::stat(filePath, KIO::HideProgressInfo);
connect(statJob, &KIO::StatJob::result, this, &ListPanelFunc::slotStatEdit);
}
}
void ListPanelFunc::slotStatEdit(KJob* job)
{
if (!job)
return;
const KIO::StatJob *statJob = dynamic_cast(job);
const QUrl &url = statJob->url();
if (job->error()) {
if (job->error() == KIO::ERR_DOES_NOT_EXIST) {
// create a new file
auto *tempFile = new QTemporaryFile;
tempFile->setAutoRemove(false); // done below
tempFile->open(); // create file
KIO::CopyJob *job = KIO::copy(QUrl::fromLocalFile(tempFile->fileName()), url);
job->setUiDelegate(nullptr);
job->setDefaultPermissions(true);
connect(job, &KIO::CopyJob::result, this, [=](KJob *job) { slotFileCreated(job, url); });
connect(job, &KIO::CopyJob::result, tempFile, &QTemporaryFile::deleteLater);
return;
} else {
KMessageBox::error(nullptr, job->errorString());
return;
}
}
if (statJob->statResult().isDir()) {
KMessageBox::sorry(nullptr, i18n("You cannot edit a folder"));
return;
}
KrViewer::edit(url);
}
void ListPanelFunc::slotFileCreated(KJob *job, const QUrl filePath)
{
if (!job || (!job->error() || job->error() == KIO::ERR_FILE_ALREADY_EXIST)) {
KrViewer::edit(filePath);
if (KIO::upUrl(filePath).matches(panel->virtualPath(), QUrl::StripTrailingSlash)) {
refresh();
}
if (KIO::upUrl(filePath).matches(panel->otherPanel()->virtualPath(), QUrl::StripTrailingSlash)) {
otherFunc()->refresh();
}
} else {
KMessageBox::sorry(krMainWindow, job->errorString());
}
}
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()
{
QDialog dialog;
dialog.setModal(true);
dialog.setWindowTitle(i18n("New Folder"));
QVBoxLayout layout;
dialog.setLayout(&layout);
QLabel comboBoxLabel(i18n("Folder's name:"));
layout.addWidget(&comboBoxLabel);
KrHistoryComboBox comboBox(&dialog);
comboBox.setMaxCount(50);
comboBox.setMinimumContentsLength(30); // Ensure that the window title is fully seen
layout.addWidget(&comboBox);
QDialogButtonBox buttonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel, &dialog);
layout.addWidget(&buttonBox);
layout.setSizeConstraint(QLayout::SetFixedSize);
connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
- connect(&comboBox, QOverload::of(&KrHistoryComboBox::activated),
+ connect(&comboBox, QOverload::of(&KrHistoryComboBox::QCOMBOBOX_ACTIVATED),
&comboBox, &KrHistoryComboBox::addToHistory);
// ------------------------------------------------------------------------
// load the history and completion list after creating the KrHistoryComboBox
// in the configuration file: the group where the configuration is saved
const QString confGroup = "Private";
KConfigGroup group(krConfig, confGroup);
const QString entryName = "NewFolder";
// in the configuration file: the key where the completion list is saved
const QString completionListKey = entryName + " Completion list";
QStringList list = group.readEntry(completionListKey, QStringList());
comboBox.completionObject()->setItems(list);
// in the configuration file: the key where the history list is saved
const QString historyListKey = entryName + " History list";
list = group.readEntry(historyListKey, QStringList());
comboBox.setHistoryItems(list);
// ------------------------------------------------------------------------
// the suggested name is the complete name for the folders,
// while filenames are suggested without their extension
QString suggestedName = panel->getCurrentName();
if (!suggestedName.isEmpty() && !files()->getFileItem(suggestedName)->isDir())
suggestedName = QFileInfo(suggestedName).completeBaseName();
comboBox.setEditText(suggestedName);
comboBox.lineEdit()->selectAll();
// ask the name of the new folder
const auto dialogResult = dialog.exec();
const QString dirName = comboBox.currentText();
if (dialogResult == QDialog::Accepted)
comboBox.addToHistory(dirName);
// save the history and completion list
list = comboBox.completionObject()->items();
group.writeEntry(completionListKey, list);
list = comboBox.historyItems();
group.writeEntry(historyListKey, list);
if (dialogResult != QDialog::Accepted)
return;
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 the user about an existing folder if only a single directory was given
if (!dirName.contains('/') && files()->getFileItem(firstName)) {
// focus the existing directory
panel->view->setCurrentItem(firstName);
// show an 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 (const 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;
for (const QUrl& fileUrl : urls) {
confirmedFiles.insert(fileUrl);
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.values();
} 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;
auto *fileSystem = dynamic_cast(files());
fileSystem->remove(fileNames);
}
void ListPanelFunc::goInside(const QString& name)
{
openFileNameInternal(name, false);
}
void ListPanelFunc::runCommand(const QString& cmd)
{
qDebug() << "command=" << cmd;
const QString workdir = panel->virtualPath().isLocalFile() ?
panel->virtualPath().path() : QDir::homePath();
if(!KRun::runCommand(cmd, krMainWindow, workdir))
KMessageBox::error(nullptr, i18n("Could not start %1", cmd));
}
void ListPanelFunc::runService(const KService &service, const 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(nullptr, i18n("%1 cannot open %2", service.name(), KrServices::toStringList(urls).join(", ")));
}
void ListPanelFunc::displayOpenWithDialog(const 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 = krArcMan.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, &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, &UnpackJob::result, panel->otherPanel()->func, &ListPanelFunc::refresh);
}
void ListPanelFunc::createChecksum()
{
if (!panel->func->files()->isLocal())
return; // only local, non-virtual files are supported
const KrViewItemList items = panel->view->getSelectedKrViewItems();
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)
{
auto *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
auto *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(), nullptr, this, nullptr);
copyToClipboardOrigin = nullptr;
}
}
void ListPanelFunc::copyToClipboard(bool move)
{
const QStringList fileNames = panel->getSelectedNames();
if (fileNames.isEmpty())
return ; // safety
QList fileUrls = files()->getUrls(fileNames);
auto *mimeData = new QMimeData;
mimeData->setData("application/x-kde-cutselection", move ? "1" : "0");
mimeData->setUrls(fileUrls);
if (copyToClipboardOrigin)
disconnect(QApplication::clipboard(), nullptr, copyToClipboardOrigin, nullptr);
copyToClipboardOrigin = this;
QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard);
connect(QApplication::clipboard(), &QClipboard::changed, this, &ListPanelFunc::clipboardChanged);
}
void ListPanelFunc::pasteFromClipboard()
{
QClipboard * cb = QApplication::clipboard();
ListPanelFunc *origin = nullptr;
if (copyToClipboardOrigin) {
disconnect(QApplication::clipboard(), nullptr, copyToClipboardOrigin, nullptr);
origin = copyToClipboardOrigin;
copyToClipboardOrigin = nullptr;
}
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 != nullptr; 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/compat.h b/krusader/compat.h
index d65dab0f..2613a98e 100644
--- a/krusader/compat.h
+++ b/krusader/compat.h
@@ -1,51 +1,65 @@
/*****************************************************************************
* Copyright (C) 2019-2020 Krusader Krew [https://krusader.org] *
* *
* This file is part of Krusader [https://krusader.org]. *
* *
* Krusader is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 2 of the License, or *
* (at your option) any later version. *
* *
* Krusader is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with Krusader. If not, see [http://www.gnu.org/licenses/]. *
*****************************************************************************/
#ifndef _COMPAT_H_
#define _COMPAT_H_
#include
#if KIO_VERSION >= QT_VERSION_CHECK(5, 48, 0)
#define UDS_ENTRY_INSERT(A, B) UDSEntry::fastInsert((A), (B));
#else
#define UDS_ENTRY_INSERT(A, B) UDSEntry::insert((A), (B));
#endif
+/**
+ * QComboBox::activated(const QString &text) was made obsoleted in QT 5.15 in
+ * favor of QComboBox::textActivated(const QString &text)
+ *
+ * https://doc.qt.io/qt-5.15/qcombobox-obsolete.html#activated-1
+ *
+ * This can be removed when the qt minimum version required will be >= 5.14
+ */
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+ #define QCOMBOBOX_ACTIVATED textActivated
+#else
+ #define QCOMBOBOX_ACTIVATED activated
+#endif
+
/**
* QFontMetrics::width(const QString&, int) was made obsoleted in QT 5.11 in
* favor of QFontMetrics::horizontalAdvance(const QString &, int)
*
* https://doc.qt.io/archives/qt-5.11/qfontmetrics-obsolete.html#width
*
* This can be removed when the qt minimum version required will be >= 5.11
*/
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
#define QFONTMETRICS_WIDTH(A) horizontalAdvance(A)
#else
#define QFONTMETRICS_WIDTH(A) width(A)
#endif
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
#define SET_TAB_STOP_DISTANCE(X) setTabStopDistance(X)
#else
#define SET_TAB_STOP_DISTANCE(X) setTabStopWidth(X)
#endif
#endif