File indexing completed on 2024-05-05 17:56:54

0001 /*
0002     SPDX-FileCopyrightText: 2004 Csaba Karai <krusader@users.sourceforge.net>
0003     SPDX-FileCopyrightText: 2004-2022 Krusader Krew <https://krusader.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "dulistview.h"
0009 #include "../FileSystem/krpermhandler.h"
0010 #include "../icon.h"
0011 #include "../krglobal.h"
0012 
0013 // QtCore
0014 #include <QMimeDatabase>
0015 #include <QMimeType>
0016 // QtGui
0017 #include <QFontMetrics>
0018 #include <QKeyEvent>
0019 #include <QMouseEvent>
0020 // QtWidgets
0021 #include <QHeaderView>
0022 
0023 #include <KConfigCore/KSharedConfig>
0024 #include <KI18n/KLocalizedString>
0025 
0026 #include "../compat.h"
0027 
0028 DUListView::DUListView(DiskUsage *usage)
0029     : KrTreeWidget(usage)
0030     , diskUsage(usage)
0031 {
0032     setAllColumnsShowFocus(true);
0033     setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
0034     setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
0035     setRootIsDecorated(true);
0036     setIndentation(10);
0037     setItemsExpandable(true);
0038 
0039     QStringList labels;
0040     labels << i18n("Name");
0041     labels << i18n("Percent");
0042     labels << i18n("Total size");
0043     labels << i18n("Own size");
0044     labels << i18n("Type");
0045     labels << i18n("Date");
0046     labels << i18n("Permissions");
0047     labels << i18n("Owner");
0048     labels << i18n("Group");
0049     setHeaderLabels(labels);
0050 
0051     header()->setSectionResizeMode(QHeaderView::Interactive);
0052 
0053     KConfigGroup group(krConfig, diskUsage->getConfigGroup());
0054 
0055     if (group.hasKey("D State"))
0056         header()->restoreState(group.readEntry("D State", QByteArray()));
0057     else {
0058         int defaultSize = QFontMetrics(font()).horizontalAdvance("W");
0059 
0060         setColumnWidth(0, defaultSize * 20);
0061         setColumnWidth(1, defaultSize * 5);
0062         setColumnWidth(2, defaultSize * 10);
0063         setColumnWidth(3, defaultSize * 10);
0064         setColumnWidth(4, defaultSize * 10);
0065         setColumnWidth(5, defaultSize * 10);
0066         setColumnWidth(6, defaultSize * 6);
0067         setColumnWidth(7, defaultSize * 5);
0068         setColumnWidth(8, defaultSize * 5);
0069     }
0070 
0071     header()->setSortIndicatorShown(true);
0072     sortItems(2, Qt::AscendingOrder);
0073 
0074     connect(diskUsage, &DiskUsage::enteringDirectory, this, &DUListView::slotDirChanged);
0075     connect(diskUsage, &DiskUsage::clearing, this, &DUListView::clear);
0076     connect(diskUsage, &DiskUsage::changed, this, &DUListView::slotChanged);
0077     connect(diskUsage, &DiskUsage::deleted, this, &DUListView::slotDeleted);
0078 
0079     connect(this, &DUListView::itemRightClicked, this, &DUListView::slotRightClicked);
0080     connect(this, &DUListView::itemExpanded, this, &DUListView::slotExpanded);
0081 }
0082 
0083 DUListView::~DUListView()
0084 {
0085     KConfigGroup group(krConfig, diskUsage->getConfigGroup());
0086     group.writeEntry("D State", header()->saveState());
0087 }
0088 
0089 void DUListView::addDirectory(Directory *dirEntry, QTreeWidgetItem *parent)
0090 {
0091     QTreeWidgetItem *lastItem = nullptr;
0092 
0093     if (parent == nullptr && !(dirEntry->parent() == nullptr)) {
0094         lastItem = new QTreeWidgetItem(this);
0095         lastItem->setText(0, "..");
0096         lastItem->setIcon(0, Icon("go-up"));
0097         lastItem->setFlags(Qt::ItemIsEnabled);
0098     }
0099 
0100     for (Iterator<File> it = dirEntry->iterator(); it != dirEntry->end(); ++it) {
0101         File *item = *it;
0102 
0103         QMimeDatabase db;
0104         QMimeType mt = db.mimeTypeForName(item->mime());
0105         QString mime;
0106         if (mt.isValid())
0107             mime = mt.comment();
0108 
0109         time_t tma = item->time();
0110         struct tm *t = localtime((time_t *)&tma);
0111         QDateTime tmp(QDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday), QTime(t->tm_hour, t->tm_min));
0112         QString date = QLocale().toString(tmp, QLocale::ShortFormat);
0113 
0114         QString totalSize = KrPermHandler::parseSize(item->size()) + ' ';
0115         QString ownSize = KrPermHandler::parseSize(item->ownSize()) + ' ';
0116         QString percent = item->percent();
0117 
0118         if (lastItem == nullptr && parent == nullptr)
0119             lastItem =
0120                 new DUListViewItem(diskUsage, item, this, item->name(), percent, totalSize, ownSize, mime, date, item->perm(), item->owner(), item->group());
0121         else if (lastItem == nullptr)
0122             lastItem =
0123                 new DUListViewItem(diskUsage, item, parent, item->name(), percent, totalSize, ownSize, mime, date, item->perm(), item->owner(), item->group());
0124         else if (parent == nullptr)
0125             lastItem = new DUListViewItem(diskUsage,
0126                                           item,
0127                                           this,
0128                                           lastItem,
0129                                           item->name(),
0130                                           percent,
0131                                           totalSize,
0132                                           ownSize,
0133                                           mime,
0134                                           date,
0135                                           item->perm(),
0136                                           item->owner(),
0137                                           item->group());
0138         else
0139             lastItem = new DUListViewItem(diskUsage,
0140                                           item,
0141                                           parent,
0142                                           lastItem,
0143                                           item->name(),
0144                                           percent,
0145                                           totalSize,
0146                                           ownSize,
0147                                           mime,
0148                                           date,
0149                                           item->perm(),
0150                                           item->owner(),
0151                                           item->group());
0152 
0153         if (item->isExcluded())
0154             lastItem->setHidden(true);
0155 
0156         lastItem->setIcon(0, diskUsage->getIcon(item->mime()));
0157 
0158         if (item->isDir() && !item->isSymLink())
0159             lastItem->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
0160     }
0161 
0162     if (topLevelItemCount() > 0) {
0163         setCurrentItem(topLevelItem(0));
0164     }
0165 }
0166 
0167 void DUListView::slotDirChanged(Directory *dirEntry)
0168 {
0169     clear();
0170     addDirectory(dirEntry, nullptr);
0171 }
0172 
0173 File *DUListView::getCurrentFile()
0174 {
0175     QTreeWidgetItem *item = currentItem();
0176 
0177     if (item == nullptr || item->text(0) == "..")
0178         return nullptr;
0179 
0180     return (dynamic_cast<DUListViewItem *>(item))->getFile();
0181 }
0182 
0183 void DUListView::slotChanged(File *item)
0184 {
0185     void *itemPtr = diskUsage->getProperty(item, "ListView-Ref");
0186     if (itemPtr == nullptr)
0187         return;
0188 
0189     auto *duItem = (DUListViewItem *)itemPtr;
0190     duItem->setHidden(item->isExcluded());
0191     duItem->setText(1, item->percent());
0192     duItem->setText(2, KrPermHandler::parseSize(item->size()) + ' ');
0193     duItem->setText(3, KrPermHandler::parseSize(item->ownSize()) + ' ');
0194 }
0195 
0196 void DUListView::slotDeleted(File *item)
0197 {
0198     void *itemPtr = diskUsage->getProperty(item, "ListView-Ref");
0199     if (itemPtr == nullptr)
0200         return;
0201 
0202     auto *duItem = (DUListViewItem *)itemPtr;
0203     delete duItem;
0204 }
0205 
0206 void DUListView::slotRightClicked(QTreeWidgetItem *item, const QPoint &pos)
0207 {
0208     File *file = nullptr;
0209 
0210     if (item && item->text(0) != "..")
0211         file = (dynamic_cast<DUListViewItem *>(item))->getFile();
0212 
0213     diskUsage->rightClickMenu(pos, file);
0214 }
0215 
0216 bool DUListView::doubleClicked(QTreeWidgetItem *item)
0217 {
0218     if (item) {
0219         if (item->text(0) != "..") {
0220             File *fileItem = (dynamic_cast<DUListViewItem *>(item))->getFile();
0221             if (fileItem->isDir())
0222                 diskUsage->changeDirectory(dynamic_cast<Directory *>(fileItem));
0223             return true;
0224         } else {
0225             auto *upDir = const_cast<Directory *>(diskUsage->getCurrentDir()->parent());
0226 
0227             if (upDir)
0228                 diskUsage->changeDirectory(upDir);
0229             return true;
0230         }
0231     }
0232     return false;
0233 }
0234 
0235 void DUListView::mouseDoubleClickEvent(QMouseEvent *e)
0236 {
0237     if (e || e->button() == Qt::LeftButton) {
0238         QPoint vp = viewport()->mapFromGlobal(e->globalPos());
0239         QTreeWidgetItem *item = itemAt(vp);
0240 
0241         if (doubleClicked(item))
0242             return;
0243     }
0244     KrTreeWidget::mouseDoubleClickEvent(e);
0245 }
0246 
0247 void DUListView::keyPressEvent(QKeyEvent *e)
0248 {
0249     switch (e->key()) {
0250     case Qt::Key_Return:
0251     case Qt::Key_Enter:
0252         if (doubleClicked(currentItem()))
0253             return;
0254         break;
0255     case Qt::Key_Left:
0256     case Qt::Key_Right:
0257     case Qt::Key_Up:
0258     case Qt::Key_Down:
0259         if (e->modifiers() == Qt::ShiftModifier) {
0260             e->ignore();
0261             return;
0262         }
0263         break;
0264     case Qt::Key_Delete:
0265         e->ignore();
0266         return;
0267     }
0268     KrTreeWidget::keyPressEvent(e);
0269 }
0270 
0271 void DUListView::slotExpanded(QTreeWidgetItem *item)
0272 {
0273     if (item == nullptr || item->text(0) == "..")
0274         return;
0275 
0276     if (item->childCount() == 0) {
0277         File *fileItem = (dynamic_cast<DUListViewItem *>(item))->getFile();
0278         if (fileItem->isDir())
0279             addDirectory(dynamic_cast<Directory *>(fileItem), item);
0280     }
0281 }