File indexing completed on 2024-05-05 05:04:04

0001 /*
0002  *  Preview dialog
0003  *
0004  *  SPDX-FileCopyrightText: 2023 Alexander Reinholdt <alexander.reinholdt@kdemail.net>
0005  *  SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 // application specific includes
0009 #include "smb4kpreviewdialog.h"
0010 #include "core/smb4kclient.h"
0011 #include "core/smb4ksettings.h"
0012 #include "smb4khomesuserdialog.h"
0013 
0014 // Qt includes
0015 #include <QDialogButtonBox>
0016 #include <QMap>
0017 #include <QVBoxLayout>
0018 
0019 // KDE includes
0020 #include <KConfigGroup>
0021 #include <KLocalizedString>
0022 #include <KWindowConfig>
0023 #include <QToolBar>
0024 #include <QWindow>
0025 // #include <KIO/OpenUrlJob>
0026 
0027 Smb4KPreviewDialog::Smb4KPreviewDialog(QWidget *parent)
0028     : QDialog(parent)
0029 {
0030     setWindowTitle(i18n("Preview Dialog"));
0031     setAttribute(Qt::WA_DeleteOnClose, true);
0032 
0033     QVBoxLayout *layout = new QVBoxLayout(this);
0034 
0035     m_listWidget = new QListWidget(this);
0036     m_listWidget->setSelectionMode(QListWidget::SingleSelection);
0037     connect(m_listWidget, &QListWidget::itemActivated, this, &Smb4KPreviewDialog::slotItemActivated);
0038 
0039     layout->addWidget(m_listWidget);
0040 
0041     QToolBar *toolBar = new QToolBar(this);
0042     toolBar->setToolButtonStyle(Qt::ToolButtonFollowStyle);
0043     toolBar->setProperty("otherToolbar", true);
0044 
0045     m_reloadAction = new KDualAction(toolBar);
0046     m_reloadAction->setObjectName(QStringLiteral("reload_action"));
0047     m_reloadAction->setInactiveText(i18n("Reload"));
0048     m_reloadAction->setInactiveIcon(KDE::icon(QStringLiteral("view-refresh")));
0049     m_reloadAction->setActiveText(i18n("Abort"));
0050     m_reloadAction->setActiveIcon(KDE::icon(QStringLiteral("process-stop")));
0051     m_reloadAction->setActive(false);
0052     m_reloadAction->setAutoToggle(false);
0053     connect(m_reloadAction, &KDualAction::triggered, this, &Smb4KPreviewDialog::slotReloadActionTriggered);
0054 
0055     toolBar->addAction(m_reloadAction);
0056 
0057     m_upAction = toolBar->addAction(KDE::icon(QStringLiteral("go-up")), i18n("Up"), this, &Smb4KPreviewDialog::slotUpActionTriggered);
0058     m_upAction->setObjectName(QStringLiteral("up_action"));
0059     m_upAction->setEnabled(false);
0060 
0061     toolBar->addSeparator();
0062 
0063     m_urlComboBox = new KUrlComboBox(KUrlComboBox::Directories, toolBar);
0064     m_urlComboBox->setEditable(false);
0065     connect(m_urlComboBox, &KUrlComboBox::urlActivated, this, &Smb4KPreviewDialog::slotUrlActivated);
0066 
0067     toolBar->addWidget(m_urlComboBox);
0068 
0069     layout->addWidget(toolBar);
0070 
0071     QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
0072     m_closeButton = buttonBox->addButton(QDialogButtonBox::Close);
0073     m_closeButton->setShortcut(QKeySequence::Close);
0074     m_closeButton->setDefault(true);
0075     connect(m_closeButton, &QPushButton::clicked, this, &Smb4KPreviewDialog::slotCloseButtonClicked);
0076 
0077     layout->addWidget(buttonBox);
0078 
0079     setMinimumWidth(sizeHint().width() > 350 ? sizeHint().width() : 350);
0080 
0081     create();
0082 
0083     KConfigGroup dialogGroup(Smb4KSettings::self()->config(), QStringLiteral("PreviewDialog"));
0084     QSize dialogSize;
0085 
0086     if (dialogGroup.exists()) {
0087         KWindowConfig::restoreWindowSize(windowHandle(), dialogGroup);
0088         dialogSize = windowHandle()->size();
0089     } else {
0090         dialogSize = sizeHint();
0091     }
0092 
0093     resize(dialogSize); // workaround for QTBUG-40584
0094 
0095     connect(Smb4KClient::self(), &Smb4KClient::files, this, &Smb4KPreviewDialog::slotPreviewResults);
0096     connect(Smb4KClient::self(), &Smb4KClient::aboutToStart, this, &Smb4KPreviewDialog::slotAdjustReloadAction);
0097     connect(Smb4KClient::self(), &Smb4KClient::finished, this, &Smb4KPreviewDialog::slotAdjustReloadAction);
0098 }
0099 
0100 Smb4KPreviewDialog::~Smb4KPreviewDialog()
0101 {
0102 }
0103 
0104 bool Smb4KPreviewDialog::setShare(SharePtr share)
0105 {
0106     if (share->isPrinter()) {
0107         return false;
0108     }
0109 
0110     if (share->isHomesShare()) {
0111         QPointer<Smb4KHomesUserDialog> homesUserDialog = new Smb4KHomesUserDialog(this);
0112         bool proceed = false;
0113 
0114         if (homesUserDialog->setShare(share)) {
0115             // We want to get a return value here, so we use exec()
0116             if (homesUserDialog->exec() == QDialog::Accepted) {
0117                 proceed = true;
0118             }
0119         }
0120 
0121         delete homesUserDialog;
0122 
0123         if (!proceed) {
0124             return false;
0125         }
0126     }
0127 
0128     m_share = share;
0129 
0130     setWindowTitle(i18n("Preview of %1", m_share->displayString()));
0131 
0132     loadPreview(m_share);
0133 
0134     return true;
0135 }
0136 
0137 void Smb4KPreviewDialog::loadPreview(const NetworkItemPtr &networkItem)
0138 {
0139     QStringList urls = m_urlComboBox->urls();
0140 
0141     if (!urls.contains(networkItem->url().toDisplayString())) {
0142         urls << networkItem->url().toDisplayString();
0143     }
0144 
0145     m_urlComboBox->setUrls(urls);
0146     m_urlComboBox->setUrl(networkItem->url());
0147 
0148     m_currentItem = networkItem;
0149 
0150     Smb4KClient::self()->lookupFiles(networkItem);
0151 }
0152 
0153 void Smb4KPreviewDialog::slotCloseButtonClicked()
0154 {
0155     KConfigGroup dialogGroup(Smb4KSettings::self()->config(), QStringLiteral("PreviewDialog"));
0156     KWindowConfig::saveWindowSize(windowHandle(), dialogGroup);
0157 
0158     accept();
0159 }
0160 
0161 void Smb4KPreviewDialog::slotItemActivated(QListWidgetItem *item)
0162 {
0163     Smb4KFile file = item->data(Qt::UserRole).value<Smb4KFile>();
0164 
0165     if (file.isDirectory()) {
0166         FilePtr fileItem = FilePtr(new Smb4KFile(file));
0167         loadPreview(fileItem);
0168     } else {
0169         // KIO::OpenUrlJob *job = new KIO::OpenUrlJob(file.url());
0170         // job->setFollowRedirections(false);
0171         // job->setAutoDelete(true);
0172         // job->start();
0173     }
0174 }
0175 
0176 void Smb4KPreviewDialog::slotPreviewResults(const QList<FilePtr> &files)
0177 {
0178     if (!files.first()->url().toString().startsWith(m_share->url().toString())) {
0179         return;
0180     }
0181 
0182     if (m_listWidget->count() != 0) {
0183         m_listWidget->clear();
0184     }
0185 
0186     QMap<QString, QListWidgetItem *> sortingMap;
0187 
0188     for (const FilePtr &file : files) {
0189         QVariant variant = QVariant::fromValue(*file.data());
0190 
0191         QListWidgetItem *item = new QListWidgetItem();
0192         item->setText(file->name());
0193         item->setIcon(file->icon());
0194         item->setData(Qt::UserRole, variant);
0195 
0196         if (file->isDirectory()) {
0197             sortingMap[QStringLiteral("00_") + file->name()] = item;
0198         } else {
0199             sortingMap[QStringLiteral("01_") + file->name()] = item;
0200         }
0201     }
0202 
0203     QMapIterator<QString, QListWidgetItem *> it(sortingMap);
0204 
0205     while (it.hasNext()) {
0206         it.next();
0207         m_listWidget->addItem(it.value());
0208     }
0209 
0210     m_upAction->setEnabled(!m_currentItem->url().matches(m_share->url(), QUrl::StripTrailingSlash));
0211 }
0212 
0213 void Smb4KPreviewDialog::slotReloadActionTriggered(bool checked)
0214 {
0215     Q_UNUSED(checked);
0216 
0217     if (!m_reloadAction->isActive()) {
0218         FilePtr file = FilePtr(new Smb4KFile(QUrl(m_urlComboBox->currentText())));
0219         file->setUserName(m_share->userName());
0220         file->setPassword(m_share->password());
0221         file->setDirectory(true);
0222 
0223         loadPreview(file);
0224     } else {
0225         Smb4KClient::self()->abort();
0226     }
0227 }
0228 
0229 void Smb4KPreviewDialog::slotUpActionTriggered()
0230 {
0231     if (!m_currentItem->url().matches(m_share->url(), QUrl::StripTrailingSlash)) {
0232         QUrl url = m_currentItem->url().adjusted(QUrl::StripTrailingSlash); // Do not merge with the line below (See code for KIO::upUrl())
0233         url = url.adjusted(QUrl::RemoveFilename);
0234 
0235         FilePtr file = FilePtr(new Smb4KFile(url));
0236         file->setUserName(m_share->userName());
0237         file->setPassword(m_share->password());
0238         file->setDirectory(true);
0239 
0240         loadPreview(file);
0241     }
0242 }
0243 
0244 void Smb4KPreviewDialog::slotUrlActivated(const QUrl &url)
0245 {
0246     Q_UNUSED(url);
0247 
0248     NetworkItemPtr networkItem;
0249 
0250     if (url.matches(m_share->url(), QUrl::RemoveUserInfo | QUrl::StripTrailingSlash)) {
0251         networkItem = m_share;
0252     } else {
0253         FilePtr file = FilePtr(new Smb4KFile(url));
0254         file->setUserName(m_share->userName());
0255         file->setPassword(m_share->password());
0256         file->setDirectory(true);
0257 
0258         networkItem = file;
0259     }
0260 
0261     loadPreview(networkItem);
0262 }
0263 
0264 void Smb4KPreviewDialog::slotAdjustReloadAction(const NetworkItemPtr &item, int type)
0265 {
0266     if (m_currentItem->url().matches(item->url(), QUrl::StripTrailingSlash) && type == LookupFiles) {
0267         m_reloadAction->setActive(!m_reloadAction->isActive());
0268     }
0269 }