File indexing completed on 2023-12-03 05:04:27

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/smb4khomesshareshandler.h"
0012 #include "core/smb4ksettings.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 group(Smb4KSettings::self()->config(), "PreviewDialog");
0084     QSize dialogSize;
0085 
0086     if (group.exists()) {
0087         KWindowConfig::restoreWindowSize(windowHandle(), group);
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         if (!Smb4KHomesSharesHandler::self()->specifyUser(share, true)) {
0112             return false;
0113         }
0114     }
0115 
0116     m_share = share;
0117 
0118     setWindowTitle(i18n("Preview of %1", m_share->displayString()));
0119 
0120     loadPreview(m_share);
0121 
0122     return true;
0123 }
0124 
0125 void Smb4KPreviewDialog::loadPreview(const NetworkItemPtr &networkItem)
0126 {
0127     QStringList urls = m_urlComboBox->urls();
0128 
0129     if (!urls.contains(networkItem->url().toDisplayString())) {
0130         urls << networkItem->url().toDisplayString();
0131     }
0132 
0133     m_urlComboBox->setUrls(urls);
0134     m_urlComboBox->setUrl(networkItem->url());
0135 
0136     m_currentItem = networkItem;
0137 
0138     Smb4KClient::self()->lookupFiles(networkItem);
0139 }
0140 
0141 void Smb4KPreviewDialog::slotCloseButtonClicked()
0142 {
0143     KConfigGroup group(Smb4KSettings::self()->config(), "PreviewDialog");
0144     KWindowConfig::saveWindowSize(windowHandle(), group);
0145 
0146     accept();
0147 }
0148 
0149 void Smb4KPreviewDialog::slotItemActivated(QListWidgetItem *item)
0150 {
0151     Smb4KFile file = item->data(Qt::UserRole).value<Smb4KFile>();
0152 
0153     if (file.isDirectory()) {
0154         FilePtr fileItem = FilePtr(new Smb4KFile(file));
0155         loadPreview(fileItem);
0156     } else {
0157         // KIO::OpenUrlJob *job = new KIO::OpenUrlJob(file.url());
0158         // job->setFollowRedirections(false);
0159         // job->setAutoDelete(true);
0160         // job->start();
0161     }
0162 }
0163 
0164 void Smb4KPreviewDialog::slotPreviewResults(const QList<FilePtr> &files)
0165 {
0166     if (m_listWidget->count() != 0) {
0167         m_listWidget->clear();
0168     }
0169 
0170     QMap<QString, QListWidgetItem *> sortingMap;
0171 
0172     for (const FilePtr &file : files) {
0173         QVariant variant = QVariant::fromValue(*file.data());
0174 
0175         QListWidgetItem *item = new QListWidgetItem();
0176         item->setText(file->name());
0177         item->setIcon(file->icon());
0178         item->setData(Qt::UserRole, variant);
0179 
0180         if (file->isDirectory()) {
0181             sortingMap[QStringLiteral("00_") + file->name()] = item;
0182         } else {
0183             sortingMap[QStringLiteral("01_") + file->name()] = item;
0184         }
0185     }
0186 
0187     QMapIterator<QString, QListWidgetItem *> it(sortingMap);
0188 
0189     while (it.hasNext()) {
0190         it.next();
0191         m_listWidget->addItem(it.value());
0192     }
0193 
0194     m_upAction->setEnabled(!m_currentItem->url().matches(m_share->url(), QUrl::StripTrailingSlash));
0195 }
0196 
0197 void Smb4KPreviewDialog::slotReloadActionTriggered(bool checked)
0198 {
0199     Q_UNUSED(checked);
0200 
0201     if (!m_reloadAction->isActive()) {
0202         FilePtr file = FilePtr(new Smb4KFile(QUrl(m_urlComboBox->currentText())));
0203         file->setUserName(m_share->userName());
0204         file->setPassword(m_share->password());
0205         file->setDirectory(true);
0206 
0207         loadPreview(file);
0208     } else {
0209         Smb4KClient::self()->abort();
0210     }
0211 }
0212 
0213 void Smb4KPreviewDialog::slotUpActionTriggered()
0214 {
0215     if (!m_currentItem->url().matches(m_share->url(), QUrl::StripTrailingSlash)) {
0216         QUrl url = m_currentItem->url().adjusted(QUrl::StripTrailingSlash); // Do not merge with the line below (See code for KIO::upUrl())
0217         url = url.adjusted(QUrl::RemoveFilename);
0218 
0219         FilePtr file = FilePtr(new Smb4KFile(url));
0220         file->setUserName(m_share->userName());
0221         file->setPassword(m_share->password());
0222         file->setDirectory(true);
0223 
0224         loadPreview(file);
0225     }
0226 }
0227 
0228 void Smb4KPreviewDialog::slotUrlActivated(const QUrl &url)
0229 {
0230     Q_UNUSED(url);
0231 
0232     NetworkItemPtr networkItem;
0233 
0234     if (url.matches(m_share->url(), QUrl::RemoveUserInfo | QUrl::StripTrailingSlash)) {
0235         networkItem = m_share;
0236     } else {
0237         FilePtr file = FilePtr(new Smb4KFile(url));
0238         file->setUserName(m_share->userName());
0239         file->setPassword(m_share->password());
0240         file->setDirectory(true);
0241 
0242         networkItem = file;
0243     }
0244 
0245     loadPreview(networkItem);
0246 }
0247 
0248 void Smb4KPreviewDialog::slotAdjustReloadAction(const NetworkItemPtr &item, int type)
0249 {
0250     if (m_currentItem->url().matches(item->url(), QUrl::StripTrailingSlash) && type == LookupFiles) {
0251         m_reloadAction->setActive(!m_reloadAction->isActive());
0252     }
0253 }