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