File indexing completed on 2024-12-08 11:10:45
0001 // SPDX-License-Identifier: GPL-2.0-or-later 0002 // SPDX-FileCopyrightText: 2007 Dominik Seichter <domseichter@web.de> 0003 0004 #include "krenamefile.h" 0005 0006 #include <kio/previewjob.h> 0007 #include <KJobWidgets> 0008 #include <kio_version.h> 0009 0010 /** A singleton class that loads icons for urls in a synchronous way 0011 */ 0012 class KRenamePreviewProvider 0013 { 0014 0015 public: 0016 /** Get the KRenamePreviewProvider instance. This is a singleton 0017 * as only one KRenamePreviewProvider may exist for one application. 0018 */ 0019 static KRenamePreviewProvider *Instance() 0020 { 0021 if (!s_instance) { 0022 s_instance = new KRenamePreviewProvider(); 0023 } 0024 0025 return s_instance; 0026 } 0027 0028 QPixmap loadIcon(const QUrl &url) 0029 { 0030 return KIO::pixmapForUrl(url); 0031 } 0032 0033 private: 0034 /** Create a KRenamePreviewProvider 0035 */ 0036 KRenamePreviewProvider() 0037 { 0038 } 0039 0040 ~KRenamePreviewProvider() 0041 { 0042 } 0043 0044 private: 0045 static KRenamePreviewProvider *s_instance; 0046 }; 0047 0048 KRenamePreviewProvider *KRenamePreviewProvider::s_instance = nullptr; 0049 0050 const int KRenameFile::DEFAULT_ICON_SIZE = 64; 0051 int KRenameFile::m_iconSize = 0; // read from config file 0052 const char *KRenameFile::EXTRA_DATA_KEY = "KRenameFile::EXTRA_DATA_KEY"; 0053 0054 KRenameFile::KRenameFile(const QUrl &src, ESplitMode eSplitMode, unsigned int dot) 0055 : m_bValid(false), m_error(0), m_manualMode(eManualChangeMode_None) 0056 { 0057 #if KIO_VERSION >= QT_VERSION_CHECK(5, 69, 0) 0058 KIO::StatJob *statJob = KIO::statDetails(src, KIO::StatJob::DestinationSide, KIO::StatDefaultDetails); 0059 #else 0060 KIO::StatJob *statJob = KIO::stat(src, KIO::StatJob::DestinationSide, 2); 0061 #endif 0062 statJob->exec(); 0063 if (statJob->error()) { 0064 return; 0065 } 0066 0067 KFileItem file(statJob->statResult(), src); 0068 0069 m_bValid = file.isReadable(); 0070 m_bDirectory = file.isDir(); 0071 0072 m_fileItem = file; 0073 initFileDescription(m_src, src, eSplitMode, dot); 0074 } 0075 0076 KRenameFile::KRenameFile(const QUrl &src, bool directory, ESplitMode eSplitMode, unsigned int dot) 0077 : m_bDirectory(directory), m_bValid(true), m_error(0), m_manualMode(eManualChangeMode_None) 0078 { 0079 initFileDescription(m_src, src, eSplitMode, dot); 0080 } 0081 0082 KRenameFile::KRenameFile(const KFileItem &item, ESplitMode eSplitMode, unsigned int dot) 0083 : m_bDirectory(item.isDir()), m_bValid(item.isReadable()), m_error(0), m_manualMode(eManualChangeMode_None) 0084 { 0085 m_fileItem = item; 0086 0087 initFileDescription(m_src, item.url(), eSplitMode, dot); 0088 } 0089 0090 KRenameFile::KRenameFile(const KRenameFile &rhs) 0091 { 0092 this->operator=(rhs); 0093 } 0094 0095 const KRenameFile &KRenameFile::operator=(const KRenameFile &rhs) 0096 { 0097 m_bDirectory = rhs.m_bDirectory; 0098 m_src = rhs.m_src; 0099 m_dst = rhs.m_dst; 0100 0101 m_bValid = rhs.m_bValid; 0102 m_icon = rhs.m_icon; 0103 m_error = rhs.m_error; 0104 m_manual = rhs.m_manual; 0105 m_manualMode = rhs.m_manualMode; 0106 0107 return *this; 0108 } 0109 0110 bool KRenameFile::operator==(const KFileItem &item) const 0111 { 0112 return this->fileItem() == item; 0113 } 0114 0115 void KRenameFile::setIconSize(int size) 0116 { 0117 m_iconSize = size; 0118 } 0119 0120 int KRenameFile::iconSize() 0121 { 0122 return m_iconSize; 0123 } 0124 0125 int KRenameFile::getDefaultIconSize() 0126 { 0127 return DEFAULT_ICON_SIZE; 0128 } 0129 0130 void KRenameFile::setCurrentSplitMode(ESplitMode eSplitMode, unsigned int dot) 0131 { 0132 QUrl url = m_src.url; 0133 QString filename = m_src.filename; 0134 if (!m_src.extension.isEmpty()) { 0135 filename = filename + '.' + m_src.extension; 0136 } 0137 0138 url.setPath(m_src.directory + '/' + filename); 0139 0140 this->initFileDescription(m_src, url, eSplitMode, dot); 0141 } 0142 0143 void KRenameFile::initFileDescription(TFileDescription &rDescription, const QUrl &url, 0144 ESplitMode eSplitMode, unsigned int dot) const 0145 { 0146 int splitPos = -1; 0147 QString path = url.path(); 0148 QString file; 0149 0150 if (!m_bValid) { 0151 return; 0152 } 0153 0154 rDescription.url = url; 0155 rDescription.directory = path; 0156 0157 if (!m_bDirectory) { 0158 // split directory/filename 0159 splitPos = path.lastIndexOf('/'); 0160 if (splitPos == -1) { 0161 // only a filename?? can this happen? 0162 file = path; 0163 path.clear(); 0164 } else { 0165 file = path.right(path.length() - splitPos - 1); 0166 path.truncate(splitPos); 0167 } 0168 0169 // split filename.extension 0170 splitPos = -1; 0171 if (eSplitMode == eSplitMode_FirstDot) { 0172 splitPos = file.indexOf('.'); 0173 } else if (eSplitMode == eSplitMode_LastDot) { 0174 splitPos = file.lastIndexOf('.'); 0175 } else if (eSplitMode == eSplitMode_NoExtension) { 0176 splitPos = file.length(); 0177 } else { 0178 if (dot) { 0179 int i = 0; 0180 splitPos = 0; 0181 do { 0182 splitPos = file.indexOf('.', splitPos + 1); 0183 ++i; 0184 } while (i < static_cast<int>(dot) && splitPos != -1); 0185 } else 0186 // if dot == 0, do not take an extension 0187 { 0188 splitPos = file.length(); 0189 } 0190 } 0191 0192 if (splitPos == -1) { 0193 splitPos = file.length(); 0194 } 0195 0196 rDescription.filename = file.left(splitPos); 0197 rDescription.extension = ""; 0198 if (splitPos != file.length()) { 0199 rDescription.extension = file.right(file.length() - splitPos - 1); 0200 } 0201 rDescription.directory = path; 0202 } else { 0203 if (rDescription.directory.endsWith('/')) { 0204 rDescription.directory = rDescription.directory.left(rDescription.directory.length() - 1); 0205 } 0206 0207 int lastSlash = rDescription.directory.lastIndexOf('/'); 0208 rDescription.filename = rDescription.directory.right(rDescription.directory.length() - lastSlash - 1); 0209 rDescription.directory.truncate(lastSlash); 0210 rDescription.extension = ""; 0211 } 0212 0213 /* 0214 qDebug("URL : %s", url.toDisplayString().toLatin1().data() ); 0215 qDebug("Path: %s", rDescription.directory.toLatin1().data()); 0216 qDebug("File: %s", rDescription.filename.toLatin1().data()); 0217 qDebug("Ext : %s", rDescription.extension.toLatin1().data()); 0218 qDebug("Split %i", splitPos ); 0219 qDebug("Dot %i", dot ); 0220 qDebug("====="); 0221 */ 0222 } 0223 0224 void KRenameFile::loadPreviewIcon() 0225 { 0226 m_icon = KRenamePreviewProvider::Instance()->loadIcon(m_src.url); 0227 } 0228 0229 int KRenameFile::dots() const 0230 { 0231 int dots = 0; 0232 0233 dots += m_src.filename.count('.'); 0234 dots += m_src.extension.count('.'); 0235 0236 if (!m_src.extension.isEmpty()) { 0237 ++dots; 0238 } 0239 0240 return dots; 0241 } 0242 0243 const QUrl KRenameFile::srcUrl() const 0244 { 0245 if (m_overrideDir.isNull()) { 0246 return m_src.url; 0247 } else { 0248 QUrl changed = m_src.url; 0249 QString filename = m_src.filename; 0250 if (!m_src.extension.isEmpty()) { 0251 filename += '.'; 0252 filename += m_src.extension; 0253 } 0254 0255 changed.setPath(m_overrideDir + '/' + filename); 0256 return changed; 0257 } 0258 } 0259 0260 const KFileItem &KRenameFile::fileItem() const 0261 { 0262 if (m_fileItem.isNull()) { 0263 // No file item has been constructed 0264 // create one first. 0265 #if KIO_VERSION >= QT_VERSION_CHECK(5, 69, 0) 0266 KIO::StatJob *statJob = KIO::statDetails(m_src.url, KIO::StatJob::DestinationSide, KIO::StatDefaultDetails); 0267 #else 0268 KIO::StatJob *statJob = KIO::stat(m_src.url, KIO::StatJob::DestinationSide, 2); 0269 #endif 0270 statJob->exec(); 0271 if (!statJob->error()) { 0272 KFileItem file(statJob->statResult(), m_src.url); 0273 const_cast<KRenameFile *>(this)->m_fileItem = file; 0274 } 0275 } 0276 0277 /* 0278 // Update extra as often as possible 0279 // As the address is changed through sorting and moving files 0280 // It is only valid if no moving of data has happened! 0281 const_cast<KRenameFile*>(this)->m_fileItem.setExtraData( KRenameFile::EXTRA_DATA_KEY, 0282 const_cast<KRenameFile*>(this) ); 0283 */ 0284 return m_fileItem; 0285 }