File indexing completed on 2024-04-28 05:45:03
0001 /* 0002 * SPDX-FileCopyrightText: 2011 Peter Penz <peter.penz19@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kfileitemlistwidget.h" 0008 #include "kfileitemlistview.h" 0009 #include "kfileitemmodel.h" 0010 #include "kitemlistview.h" 0011 0012 #include "dolphin_contentdisplaysettings.h" 0013 0014 #include <KFormat> 0015 #include <KLocalizedString> 0016 0017 #include <QGraphicsScene> 0018 #include <QGraphicsView> 0019 #include <QMimeDatabase> 0020 0021 KFileItemListWidgetInformant::KFileItemListWidgetInformant() 0022 : KStandardItemListWidgetInformant() 0023 { 0024 } 0025 0026 KFileItemListWidgetInformant::~KFileItemListWidgetInformant() 0027 { 0028 } 0029 0030 QString KFileItemListWidgetInformant::itemText(int index, const KItemListView *view) const 0031 { 0032 Q_ASSERT(qobject_cast<KFileItemModel *>(view->model())); 0033 KFileItemModel *fileItemModel = static_cast<KFileItemModel *>(view->model()); 0034 0035 const KFileItem item = fileItemModel->fileItem(index); 0036 return item.text(); 0037 } 0038 0039 bool KFileItemListWidgetInformant::itemIsLink(int index, const KItemListView *view) const 0040 { 0041 Q_ASSERT(qobject_cast<KFileItemModel *>(view->model())); 0042 KFileItemModel *fileItemModel = static_cast<KFileItemModel *>(view->model()); 0043 0044 const KFileItem item = fileItemModel->fileItem(index); 0045 return item.isLink(); 0046 } 0047 0048 QString KFileItemListWidgetInformant::roleText(const QByteArray &role, const QHash<QByteArray, QVariant> &values) const 0049 { 0050 QString text; 0051 const QVariant roleValue = values.value(role); 0052 QLocale local; 0053 KFormat formatter(local); 0054 0055 // Implementation note: In case if more roles require a custom handling 0056 // use a hash + switch for a linear runtime. 0057 0058 auto formatDate = [formatter, local](const QDateTime &time) { 0059 if (ContentDisplaySettings::useShortRelativeDates()) { 0060 return formatter.formatRelativeDateTime(time, QLocale::ShortFormat); 0061 } else { 0062 return local.toString(time, QLocale::ShortFormat); 0063 } 0064 }; 0065 0066 if (role == "size") { 0067 if (values.value("isDir").toBool()) { 0068 if (!roleValue.isNull() && roleValue != -1) { 0069 // The item represents a directory. 0070 if (ContentDisplaySettings::directorySizeCount() || roleValue == -2 /* size is invalid */) { 0071 // Show the number of sub directories instead of the file size of the directory. 0072 const int count = values.value("count").toInt(); 0073 text = i18ncp("@item:intable", "%1 item", "%1 items", count); 0074 } else { 0075 // if we have directory size available 0076 const KIO::filesize_t size = roleValue.value<KIO::filesize_t>(); 0077 text = formatter.formatByteSize(size); 0078 } 0079 } 0080 } else { 0081 const KIO::filesize_t size = roleValue.value<KIO::filesize_t>(); 0082 text = formatter.formatByteSize(size); 0083 } 0084 } else if (role == "modificationtime" || role == "creationtime" || role == "accesstime") { 0085 bool ok; 0086 const long long time = roleValue.toLongLong(&ok); 0087 if (ok && time != -1) { 0088 const QDateTime dateTime = QDateTime::fromSecsSinceEpoch(time); 0089 text = formatDate(dateTime); 0090 } 0091 } else if (role == "deletiontime" || role == "imageDateTime") { 0092 const QDateTime dateTime = roleValue.toDateTime(); 0093 if (dateTime.isValid()) { 0094 text = formatDate(dateTime); 0095 } 0096 } else if (role == "dimensions") { 0097 const auto dimensions = roleValue.toSize(); 0098 if (dimensions.isValid()) { 0099 text = i18nc("width × height", "%1 × %2", dimensions.width(), dimensions.height()); 0100 } 0101 } else if (role == "permissions") { 0102 const auto permissions = roleValue.value<QVariantList>(); 0103 0104 switch (ContentDisplaySettings::usePermissionsFormat()) { 0105 case ContentDisplaySettings::EnumUsePermissionsFormat::SymbolicFormat: 0106 text = permissions.at(0).toString(); 0107 break; 0108 case ContentDisplaySettings::EnumUsePermissionsFormat::NumericFormat: 0109 text = QString::number(permissions.at(1).toInt(), 8); 0110 break; 0111 case ContentDisplaySettings::EnumUsePermissionsFormat::CombinedFormat: 0112 text = QLatin1String("%1 (%2)").arg(permissions.at(0).toString()).arg(permissions.at(1).toInt(), 0, 8); 0113 break; 0114 } 0115 } else { 0116 text = KStandardItemListWidgetInformant::roleText(role, values); 0117 } 0118 0119 return text; 0120 } 0121 0122 QFont KFileItemListWidgetInformant::customizedFontForLinks(const QFont &baseFont) const 0123 { 0124 // The customized font should be italic if the file is a symbolic link. 0125 QFont font(baseFont); 0126 font.setItalic(true); 0127 return font; 0128 } 0129 0130 KFileItemListWidget::KFileItemListWidget(KItemListWidgetInformant *informant, QGraphicsItem *parent) 0131 : KStandardItemListWidget(informant, parent) 0132 { 0133 } 0134 0135 KFileItemListWidget::~KFileItemListWidget() 0136 { 0137 } 0138 0139 KItemListWidgetInformant *KFileItemListWidget::createInformant() 0140 { 0141 return new KFileItemListWidgetInformant(); 0142 } 0143 0144 bool KFileItemListWidget::isRoleRightAligned(const QByteArray &role) const 0145 { 0146 return role == "size" || role == "permissions"; 0147 } 0148 0149 bool KFileItemListWidget::isHidden() const 0150 { 0151 return data().value("isHidden").toBool(); 0152 } 0153 0154 QFont KFileItemListWidget::customizedFont(const QFont &baseFont) const 0155 { 0156 // The customized font should be italic if the file is a symbolic link. 0157 QFont font(baseFont); 0158 font.setItalic(data().value("isLink").toBool()); 0159 return font; 0160 } 0161 0162 int KFileItemListWidget::selectionLength(const QString &text) const 0163 { 0164 // Select the text without MIME-type extension 0165 int selectionLength = text.length(); 0166 0167 // If item is a directory, use the whole text length for 0168 // selection (ignore all points) 0169 if (data().value("isDir").toBool()) { 0170 return selectionLength; 0171 } 0172 0173 QMimeDatabase db; 0174 const QString extension = db.suffixForFileName(text); 0175 if (extension.isEmpty()) { 0176 // For an unknown extension just exclude the extension after 0177 // the last point. This does not work for multiple extensions like 0178 // *.tar.gz but usually this is anyhow a known extension. 0179 selectionLength = text.lastIndexOf(QLatin1Char('.')); 0180 0181 // If no point could be found, use whole text length for selection. 0182 if (selectionLength < 1) { 0183 selectionLength = text.length(); 0184 } 0185 0186 } else { 0187 selectionLength -= extension.length() + 1; 0188 } 0189 0190 return selectionLength; 0191 } 0192 0193 void KFileItemListWidget::hoverSequenceStarted() 0194 { 0195 KFileItemListView *view = listView(); 0196 0197 if (!view) { 0198 return; 0199 } 0200 0201 const QUrl itemUrl = data().value("url").toUrl(); 0202 0203 view->setHoverSequenceState(itemUrl, 0); 0204 } 0205 0206 void KFileItemListWidget::forceUpdate() 0207 { 0208 updateAdditionalInfoTextColor(); 0209 // icon layout does not include the icons in the item selection rectangle 0210 // so its icon does not need updating 0211 if (listView()->itemLayout() != KStandardItemListView::ItemLayout::IconsLayout) { 0212 invalidateIconCache(); 0213 } 0214 update(); 0215 } 0216 0217 void KFileItemListWidget::hoverSequenceIndexChanged(int sequenceIndex) 0218 { 0219 KFileItemListView *view = listView(); 0220 0221 if (!view) { 0222 return; 0223 } 0224 0225 const QUrl itemUrl = data().value("url").toUrl(); 0226 0227 view->setHoverSequenceState(itemUrl, sequenceIndex); 0228 0229 // Force-update the displayed icon 0230 invalidateIconCache(); 0231 update(); 0232 } 0233 0234 void KFileItemListWidget::hoverSequenceEnded() 0235 { 0236 KFileItemListView *view = listView(); 0237 0238 if (!view) { 0239 return; 0240 } 0241 0242 view->setHoverSequenceState(QUrl(), 0); 0243 } 0244 0245 KFileItemListView *KFileItemListWidget::listView() 0246 { 0247 return dynamic_cast<KFileItemListView *>(parentItem()); 0248 } 0249 0250 #include "moc_kfileitemlistwidget.cpp"