File indexing completed on 2024-04-28 17:06:25

0001 /*
0002     SPDX-FileCopyrightText: 2003 Shie Erlich <erlich@users.sourceforge.net>
0003     SPDX-FileCopyrightText: 2003 Rafi Yanai <yanai@users.sourceforge.net>
0004     SPDX-FileCopyrightText: 2004-2022 Krusader Krew <https://krusader.org>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 #include "sidebar.h"
0010 
0011 #include "../Dialogs/krsqueezedtextlabel.h"
0012 #include "../FileSystem/fileitem.h"
0013 #include "../FileSystem/filesystem.h"
0014 #include "../KViewer/diskusageviewer.h"
0015 #include "../KViewer/panelviewer.h"
0016 #include "../compat.h"
0017 #include "../defaults.h"
0018 #include "../icon.h"
0019 #include "PanelView/krview.h"
0020 #include "PanelView/krviewitem.h"
0021 #include "krfiletreeview.h"
0022 #include "krpanel.h"
0023 #include "panelfunc.h"
0024 #include "viewactions.h"
0025 
0026 // QtCore
0027 #include <QMimeDatabase>
0028 #include <QMimeType>
0029 // QtWidgets
0030 #include <QAbstractItemView>
0031 #include <QGridLayout>
0032 
0033 #include <KConfigCore/KSharedConfig>
0034 #include <KI18n/KLocalizedString>
0035 
0036 Sidebar::Sidebar(QWidget *parent)
0037     : QWidget(parent)
0038     , stack(nullptr)
0039     , imageFilePreview(nullptr)
0040     , pjob(nullptr)
0041 {
0042     auto *layout = new QGridLayout(this);
0043     layout->setContentsMargins(0, 0, 0, 0);
0044 
0045     // create the label+buttons setup
0046     dataLine = new KrSqueezedTextLabel(this);
0047     KConfigGroup lg(krConfig, "Look&Feel");
0048     dataLine->setFont(lg.readEntry("Filelist Font", _FilelistFont));
0049     // --- hack: setup colors to be the same as an inactive panel
0050     dataLine->setBackgroundRole(QPalette::Window);
0051     int sheight = QFontMetrics(dataLine->font()).height() + 4;
0052     dataLine->setMaximumHeight(sheight);
0053 
0054     btns = new QButtonGroup(this);
0055     btns->setExclusive(true);
0056     connect(btns, QOverload<int>::of(&QButtonGroup::QBUTTONGROUP_BUTTONCLICKED), this, &Sidebar::tabSelected);
0057 
0058     treeBtn = new QToolButton(this);
0059     treeBtn->setToolTip(i18n("Tree Panel: a tree view of the local file system"));
0060     treeBtn->setIcon(Icon("view-list-tree"));
0061     treeBtn->setFixedSize(20, 20);
0062     treeBtn->setCheckable(true);
0063     btns->addButton(treeBtn, Tree);
0064 
0065     previewBtn = new QToolButton(this);
0066     previewBtn->setToolTip(i18n("Preview Panel: display a preview of the current file"));
0067     previewBtn->setIcon(Icon("view-preview"));
0068     previewBtn->setFixedSize(20, 20);
0069     previewBtn->setCheckable(true);
0070     btns->addButton(previewBtn, Preview);
0071 
0072     viewerBtn = new QToolButton(this);
0073     viewerBtn->setToolTip(i18n("View Panel: view the current file"));
0074     viewerBtn->setIcon(Icon("zoom-original"));
0075     viewerBtn->setFixedSize(20, 20);
0076     viewerBtn->setCheckable(true);
0077     btns->addButton(viewerBtn, View);
0078 
0079     duBtn = new QToolButton(this);
0080     duBtn->setToolTip(i18n("Disk Usage Panel: view the usage of a folder"));
0081     duBtn->setIcon(Icon("kr_diskusage"));
0082     duBtn->setFixedSize(20, 20);
0083     duBtn->setCheckable(true);
0084     btns->addButton(duBtn, DskUsage);
0085 
0086     layout->addWidget(dataLine, 0, 0);
0087     layout->addWidget(treeBtn, 0, 1);
0088     layout->addWidget(previewBtn, 0, 2);
0089     layout->addWidget(viewerBtn, 0, 3);
0090     layout->addWidget(duBtn, 0, 4);
0091 
0092     // create a widget stack on which to put the parts
0093     stack = new QStackedWidget(this);
0094 
0095     // create the tree part ----------
0096     tree = new KrFileTreeView(stack);
0097     tree->setProperty("KrusaderWidgetId", QVariant(Tree));
0098     stack->addWidget(tree);
0099     // NOTE: the F2 key press event is caught before it gets to the tree
0100     tree->setEditTriggers(QAbstractItemView::EditKeyPressed);
0101     // connecting signal to signal
0102     connect(tree, &KrFileTreeView::urlActivated, this, &Sidebar::urlActivated);
0103 
0104     // create the quickview part ------
0105     imageFilePreview = new KImageFilePreview(stack);
0106     imageFilePreview->setProperty("KrusaderWidgetId", QVariant(Preview));
0107     stack->addWidget(imageFilePreview);
0108 
0109     // create the panelview
0110     fileViewer = new PanelViewer(stack);
0111     fileViewer->setProperty("KrusaderWidgetId", QVariant(View));
0112     // kparts demand too much width
0113     QSizePolicy sizePolicy = fileViewer->sizePolicy();
0114     sizePolicy.setHorizontalPolicy(QSizePolicy::Ignored);
0115     fileViewer->setSizePolicy(sizePolicy);
0116     stack->addWidget(fileViewer);
0117     connect(fileViewer, &PanelViewer::openUrlRequest, this, &Sidebar::handleOpenUrlRequest);
0118 
0119     // create the disk usage view
0120     diskusage = new DiskUsageViewer(stack);
0121     diskusage->setStatusLabel(dataLine, i18n("Disk Usage:"));
0122     diskusage->setProperty("KrusaderWidgetId", QVariant(DskUsage));
0123     stack->addWidget(diskusage);
0124     connect(diskusage, &DiskUsageViewer::openUrlRequest, this, &Sidebar::handleOpenUrlRequest);
0125 
0126     // -------- finish the layout (General one)
0127     layout->addWidget(stack, 1, 0, 1, 5);
0128 
0129     hide(); // for not to open the 3rd hand tool at start (selecting the last used tab)
0130     setCurrentPage(0);
0131 }
0132 
0133 Sidebar::~Sidebar() = default;
0134 
0135 void Sidebar::saveSettings(const KConfigGroup &cfg) const
0136 {
0137     tree->saveSettings(cfg);
0138 }
0139 
0140 void Sidebar::restoreSettings(const KConfigGroup &cfg)
0141 {
0142     tree->restoreSettings(cfg);
0143 }
0144 
0145 void Sidebar::setCurrentPage(int id)
0146 {
0147     QAbstractButton *curr = btns->button(id);
0148     if (curr) {
0149         curr->click();
0150     }
0151 }
0152 
0153 void Sidebar::show()
0154 {
0155     QWidget::show();
0156     tabSelected(currentPage());
0157 }
0158 
0159 void Sidebar::hide()
0160 {
0161     QWidget::hide();
0162     if (currentPage() == View)
0163         fileViewer->closeUrl();
0164     if (currentPage() == DskUsage)
0165         diskusage->closeUrl();
0166 }
0167 
0168 void Sidebar::focusInEvent(QFocusEvent *)
0169 {
0170     switch (currentPage()) {
0171     case Preview:
0172         if (!isHidden())
0173             imageFilePreview->setFocus();
0174         break;
0175     case View:
0176         if (!isHidden() && fileViewer->part() && fileViewer->part()->widget())
0177             fileViewer->part()->widget()->setFocus();
0178         break;
0179     case DskUsage:
0180         if (!isHidden() && diskusage->getWidget() && diskusage->getWidget()->currentWidget())
0181             diskusage->getWidget()->currentWidget()->setFocus();
0182         break;
0183     case Tree:
0184         if (!isHidden())
0185             tree->setFocus();
0186         break;
0187     }
0188 }
0189 
0190 void Sidebar::handleOpenUrlRequest(const QUrl &url)
0191 {
0192     QMimeDatabase db;
0193     QMimeType mime = db.mimeTypeForUrl(url);
0194     if (mime.isValid() && mime.name() == "inode/directory")
0195         ACTIVE_PANEL->func->openUrl(url);
0196 }
0197 
0198 void Sidebar::tabSelected(int id)
0199 {
0200     QUrl url;
0201     const FileItem *fileitem = nullptr;
0202     if (ACTIVE_PANEL && ACTIVE_PANEL->view)
0203         fileitem = ACTIVE_PANEL->func->files()->getFileItem(ACTIVE_PANEL->view->getCurrentItem());
0204     if (fileitem)
0205         url = fileitem->getUrl();
0206 
0207     // if tab is tree, set something logical in the data line
0208     switch (id) {
0209     case Tree:
0210         stack->setCurrentWidget(tree);
0211         dataLine->setText(i18n("Tree:"));
0212         if (!isHidden())
0213             tree->setFocus();
0214         if (ACTIVE_PANEL)
0215             tree->setCurrentUrl(ACTIVE_PANEL->virtualPath());
0216         break;
0217     case Preview:
0218         stack->setCurrentWidget(imageFilePreview);
0219         dataLine->setText(i18n("Preview:"));
0220         update(fileitem);
0221         break;
0222     case View:
0223         stack->setCurrentWidget(fileViewer);
0224         dataLine->setText(i18n("View:"));
0225         update(fileitem);
0226         if (!isHidden() && fileViewer->part() && fileViewer->part()->widget())
0227             fileViewer->part()->widget()->setFocus();
0228         break;
0229     case DskUsage:
0230         stack->setCurrentWidget(diskusage);
0231         dataLine->setText(i18n("Disk Usage:"));
0232         update(fileitem);
0233         if (!isHidden() && diskusage->getWidget() && diskusage->getWidget()->currentWidget())
0234             diskusage->getWidget()->currentWidget()->setFocus();
0235         break;
0236     }
0237     if (id != View)
0238         fileViewer->closeUrl();
0239 }
0240 
0241 // decide which part to update, if at all
0242 void Sidebar::update(const FileItem *fileitem)
0243 {
0244     if (isHidden())
0245         return;
0246 
0247     QUrl url;
0248     if (fileitem)
0249         url = fileitem->getUrl();
0250 
0251     switch (currentPage()) {
0252     case Preview:
0253         imageFilePreview->showPreview(url);
0254         dataLine->setText(i18n("Preview: %1", url.fileName()));
0255         break;
0256     case View:
0257         if (fileitem && !fileitem->isDir() && fileitem->isReadable())
0258             fileViewer->openUrl(fileitem->getUrl());
0259         else
0260             fileViewer->closeUrl();
0261         dataLine->setText(i18n("View: %1", url.fileName()));
0262         break;
0263     case DskUsage: {
0264         if (fileitem && !fileitem->isDir())
0265             url = KIO::upUrl(url);
0266         dataLine->setText(i18n("Disk Usage: %1", url.fileName()));
0267         diskusage->openUrl(url);
0268     } break;
0269     case Tree: // nothing to do
0270         break;
0271     }
0272 }
0273 
0274 void Sidebar::onPanelPathChange(const QUrl &url)
0275 {
0276     switch (currentPage()) {
0277     case Tree:
0278         if (url.isLocalFile()) {
0279             tree->setCurrentUrl(url); // synchronize panel path with tree path
0280         }
0281         break;
0282     }
0283 }