1 | /*************************************************************************** |
2 | kfilereplacelib.cpp - File library |
3 | ------------------- |
4 | begin : lun mai 3 20:19:52 CEST 1999 |
5 | |
6 | copyright : (C) 1999 by François Dupoux |
7 | (C) 2003 Andras Mantia <amantia@kde.org> |
8 | (C) 2004 Emiliano Gulmini <emi_barbarossa@yahoo.it> |
9 | email : dupoux@dupoux.com |
10 | |
11 | ***************************************************************************/ |
12 | |
13 | /*************************************************************************** |
14 | * * |
15 | * This program is free software; you can redistribute it and/or modify * |
16 | * it under the terms of the GNU General Public License as published by * |
17 | * the Free Software Foundation; either version 2 of the License, or * |
18 | * (at your option) any later version. * |
19 | * * |
20 | ***************************************************************************/ |
21 | |
22 | //QT |
23 | #include <qstringlist.h> |
24 | #include <qwidget.h> |
25 | #include <q3listview.h> |
26 | #include <qfileinfo.h> |
27 | #include <qpixmap.h> |
28 | |
29 | //KDE |
30 | #include <kdebug.h> |
31 | #include <kmessagebox.h> |
32 | #include <k3listview.h> |
33 | #include <kiconloader.h> |
34 | |
35 | //needed for malloc/free |
36 | #include <stdlib.h> |
37 | |
38 | // local |
39 | #include "kfilereplacelib.h" |
40 | |
41 | /** |
42 | Format a path, from a path and a filename, or another sub-path (avoid double '/' risks) |
43 | Parameters::.....* basePath: fist path (can be "/" if root, or "/usr/bin/" or "/usr/bin" for example) |
44 | .................* fileName: second path (can be "/doc/html/", or "doc/html/" or "doc/html/index.html" for example) |
45 | Return values:...* Full valid path (without double "/") |
46 | */ |
47 | QString KFileReplaceLib::formatFullPath(const QString& basePath, const QString &fileName) |
48 | { |
49 | QString fullPath = basePath; |
50 | QString fname = fileName; |
51 | |
52 | if (fname.startsWith('/')) // skip beginning '/' |
53 | fname = fname.remove(0,1); |
54 | |
55 | if (fullPath.endsWith('/')) |
56 | fullPath.append(fname); |
57 | else |
58 | fullPath.append('/'+fname); |
59 | |
60 | return fullPath; |
61 | } |
62 | |
63 | /** |
64 | Add an extension to a filename, or a filepath |
65 | Parameters::.....* fileName: filename or filepath (it can have already the extension) |
66 | .................* extension: extension to add without "." (ex: "html", "kfr") |
67 | Return values:...* Filename / Filepath with the extension |
68 | */ |
69 | QString KFileReplaceLib::addExtension(const QString& fileName, const QString& extension) |
70 | { |
71 | QString fullExtension = "." ; |
72 | QString fname = fileName; |
73 | |
74 | fullExtension.append(extension); |
75 | |
76 | // filename cannot contain ".ext" ==> Add it |
77 | if(fname.length() <= fullExtension.length()) |
78 | fname.append(fullExtension); |
79 | else // filename can contain ".ext" |
80 | { |
81 | if (fname.right(fullExtension.length()) != fullExtension) |
82 | fname.append(fullExtension); |
83 | } |
84 | |
85 | return fname; |
86 | } |
87 | |
88 | QString KFileReplaceLib::formatFileSize(double size) |
89 | { |
90 | QString stringSize; |
91 | |
92 | if(size < 10000) |
93 | { |
94 | const int asInt = (int) size; |
95 | stringSize = i18np("1 byte" , "%1 bytes" , asInt); |
96 | } |
97 | else |
98 | { |
99 | stringSize = KGlobal::locale()->formatByteSize(size, 2); |
100 | } |
101 | return stringSize; |
102 | } |
103 | |
104 | void KFileReplaceLib::convertOldToNewKFRFormat(const QString& fileName, K3ListView* stringView) |
105 | { |
106 | //this method convert old format in new XML-based format |
107 | typedef struct |
108 | { |
109 | char pgm[13]; // Must be "KFileReplace" : like MZ for EXE files |
110 | int stringNumber; // Number of strings in file |
111 | char reserved[64]; // Reserved for future use |
112 | } ; |
113 | |
114 | KFRHeader head; |
115 | |
116 | FILE* f = fopen(QFile::encodeName(fileName),"rb" ); |
117 | int err = fread(&head, sizeof(KFRHeader), 1, f); |
118 | QString pgm(head.pgm); |
119 | |
120 | if(!f || (err != 1) || (pgm != "KFileReplace" )) |
121 | { |
122 | KMessageBox::error(0, i18n("<qt>Cannot open the file <b>%1</b> and load the string list. This file seems not to be a valid old kfr file or it is broken.</qt>" , fileName)); |
123 | return ; |
124 | } |
125 | |
126 | stringView->clear(); |
127 | |
128 | int oldTextSize, |
129 | newTextSize, |
130 | errors = 0, |
131 | stringSize; |
132 | QStringList l; |
133 | |
134 | int i ; |
135 | for (i=0; i < head.stringNumber; i++) |
136 | { |
137 | errors += (fread(&oldTextSize, sizeof(int), 1, f)) != 1; |
138 | errors += (fread(&newTextSize, sizeof(int), 1, f)) != 1; |
139 | if(errors > 0) |
140 | KMessageBox::error(0, i18n("Cannot read data." )); |
141 | else |
142 | { |
143 | stringSize = ((oldTextSize > newTextSize) ? oldTextSize : newTextSize) + 2; |
144 | char* oldString = (char*) malloc(stringSize+10), |
145 | * newString = (char*) malloc(stringSize+10); |
146 | if (oldString == 0 || newString == 0) |
147 | KMessageBox::error(0, i18n("Out of memory." )); |
148 | else |
149 | { |
150 | memset(oldString, 0, stringSize); |
151 | memset(newString,0, stringSize); |
152 | |
153 | if (fread(oldString, oldTextSize, 1, f) != 1) |
154 | KMessageBox::error(0, i18n("Cannot read data." )); |
155 | else |
156 | { |
157 | if (newTextSize > 0) // If there is a Replace text |
158 | { |
159 | if (fread(newString, newTextSize, 1, f) != 1) |
160 | KMessageBox::error(0, i18n("Cannot read data." )); |
161 | else |
162 | { |
163 | Q3ListViewItem* lvi = new Q3ListViewItem(stringView); |
164 | lvi->setText(0,oldString); |
165 | lvi->setText(1,newString); |
166 | |
167 | } |
168 | } |
169 | } |
170 | } |
171 | if(newString) |
172 | free(newString); |
173 | if(oldString) |
174 | free(oldString); |
175 | } |
176 | } |
177 | fclose(f); |
178 | return ; |
179 | } |
180 | |
181 | bool KFileReplaceLib::isAnAccessibleFile(const QString& filePath, const QString& fileName, RCOptions* info) |
182 | { |
183 | QString bkExt = info->m_backupExtension; |
184 | if(fileName == ".." || fileName == "." || (!bkExt.isEmpty() && fileName.right(bkExt.length()) == bkExt)) |
185 | return false; |
186 | |
187 | QFileInfo fi; |
188 | if(filePath.isEmpty()) |
189 | fi.setFile(fileName); |
190 | else |
191 | fi.setFile(filePath+'/'+fileName); |
192 | |
193 | if(fi.isDir()) |
194 | return true; |
195 | |
196 | int minSize = info->m_minSize, |
197 | maxSize = info->m_maxSize; |
198 | QString minDate = info->m_minDate, |
199 | maxDate = info->m_maxDate, |
200 | dateAccess = info->m_dateAccess; |
201 | |
202 | // Avoid files that not match access date requirements |
203 | QString last = "unknown" ; |
204 | if(dateAccess == "Last Writing Access" ) |
205 | last = fi.lastModified().toString(Qt::ISODate); |
206 | if(dateAccess == "Last Reading Access" ) |
207 | last = fi.lastRead().toString(Qt::ISODate); |
208 | |
209 | if(last != "unknown" ) |
210 | { |
211 | if(minDate != "unknown" && maxDate != "unknown" ) |
212 | { //If out of range then exit |
213 | if((minDate > last) || (maxDate < last)) |
214 | return false; |
215 | } |
216 | else |
217 | { |
218 | if(minDate != "unknown" ) |
219 | { //If out of range then exit |
220 | if(minDate > last) |
221 | return false; |
222 | } |
223 | else |
224 | { |
225 | if(maxDate != "unknown" ) |
226 | //If out of range then exit |
227 | if(maxDate < last) |
228 | return false; |
229 | } |
230 | } |
231 | } |
232 | // Avoid files that not match size requirements |
233 | int size = fi.size(); |
234 | if(maxSize != FileSizeOption && minSize != FileSizeOption) |
235 | if(size > (maxSize*1024) || size < (minSize*1024)) |
236 | return false; |
237 | |
238 | // Avoid files that not match ownership requirements |
239 | if(info->m_ownerUserIsChecked) |
240 | { |
241 | QString fileOwnerUser; |
242 | if(info->m_ownerUserType == "Name" ) |
243 | fileOwnerUser = fi.owner(); |
244 | else |
245 | fileOwnerUser = QString::number(fi.ownerId(),10); |
246 | |
247 | if(info->m_ownerUserBool == "Equals To" ) |
248 | { |
249 | if(info->m_ownerUserValue != fileOwnerUser) |
250 | return false; |
251 | } |
252 | else |
253 | { |
254 | if(info->m_ownerUserValue == fileOwnerUser) |
255 | return false; |
256 | } |
257 | } |
258 | |
259 | if(info->m_ownerGroupIsChecked) |
260 | { |
261 | QString fileOwnerGroup; |
262 | if(info->m_ownerGroupType == "Name" ) |
263 | fileOwnerGroup = fi.group(); |
264 | else |
265 | fileOwnerGroup = QString::number(fi.groupId(),10); |
266 | if(info->m_ownerGroupBool == "Equals To" ) |
267 | { |
268 | if(info->m_ownerGroupValue != fileOwnerGroup) |
269 | return false; |
270 | } |
271 | else |
272 | { |
273 | if(info->m_ownerGroupValue == fileOwnerGroup) |
274 | return false; |
275 | } |
276 | } |
277 | |
278 | //If we are here then all requirements have been verified |
279 | return true; |
280 | } |
281 | |
282 | void KFileReplaceLib::setIconForFileEntry(Q3ListViewItem* item, const QString &path) |
283 | { |
284 | QFileInfo fi(path); |
285 | QString extension = fi.completeSuffix(), |
286 | baseName = fi.baseName(); |
287 | |
288 | KeyValueMap extensionMap; |
289 | |
290 | extensionMap["a" ] = "binary" ; |
291 | extensionMap["am" ] = "shellscript" ; |
292 | extensionMap["bz" ] = "zip" ; |
293 | extensionMap["bz2" ] = "zip" ; |
294 | extensionMap["c" ] = "source_c" ; |
295 | extensionMap["cc" ] = "source_cpp" ; |
296 | extensionMap["cpp" ] = "source_cpp" ; |
297 | extensionMap["eml" ] = "message" ; |
298 | extensionMap["exe" ] = "exec_wine" ; |
299 | extensionMap["gz" ] = "zip" ; |
300 | extensionMap["h" ] = "source_h" ; |
301 | extensionMap["htm" ] = "html" ; |
302 | extensionMap["html" ] = "html" ; |
303 | extensionMap["in" ] = "shellscript" ; |
304 | extensionMap["java" ] = "source_java" ; |
305 | extensionMap["jpg" ] = "image" ; |
306 | extensionMap["kfr" ] = "html" ; |
307 | extensionMap["kmdr" ] = "widget_doc" ; |
308 | extensionMap["kwd" ] = "kword_kwd" ; |
309 | extensionMap["log" ] = "log" ; |
310 | extensionMap["moc" ] = "source_moc" ; |
311 | extensionMap["mp3" ] = "sound" ; |
312 | extensionMap["o" ] = "source_o" ; |
313 | extensionMap["pdf" ] = "pdf" ; |
314 | extensionMap["php" ] = "source_php" ; |
315 | extensionMap["py" ] = "source_py" ; |
316 | extensionMap["pl" ] = "source_pl" ; |
317 | extensionMap["p" ] = "source_p" ; |
318 | extensionMap["ps" ] = "postscript" ; |
319 | extensionMap["png" ] = "image" ; |
320 | extensionMap["sa" ] = "binary" ; |
321 | extensionMap["sh" ] = "shellscript" ; |
322 | extensionMap["so" ] = "binary" ; |
323 | extensionMap["tar" ] = "tar" ; |
324 | extensionMap["tex" ] = "tex" ; |
325 | extensionMap["tgz" ] = "tgz" ; |
326 | extensionMap["txt" ] = "txt" ; |
327 | extensionMap["ui" ] = "widget_doc" ; |
328 | extensionMap["uml" ] = "umbrellofile" ; |
329 | extensionMap["wav" ] = "sound" ; |
330 | extensionMap["xml" ] = "html" ; |
331 | extensionMap["xpm" ] = "image" ; |
332 | |
333 | KeyValueMap::Iterator itExtensionMap; |
334 | |
335 | for(itExtensionMap = extensionMap.begin(); itExtensionMap != extensionMap.end(); ++itExtensionMap) |
336 | { |
337 | if(extension == itExtensionMap.key()) |
338 | { |
339 | item->setPixmap(0,SmallIcon(itExtensionMap.data())); |
340 | return; |
341 | } |
342 | } |
343 | |
344 | KeyValueMap baseNameMap; |
345 | |
346 | baseNameMap["configure" ] = "shellscript" ; |
347 | baseNameMap["core" ] = "core" ; |
348 | baseNameMap["makefile" ] = "make" ; |
349 | baseNameMap["readme" ] = "readme" ; |
350 | baseNameMap["README" ] = "readme" ; |
351 | baseNameMap["Readme" ] = "readme" ; |
352 | baseNameMap["TODO" ] = "txt" ; |
353 | |
354 | KeyValueMap::Iterator itBaseNameMap; |
355 | |
356 | for(itBaseNameMap = baseNameMap.begin(); itBaseNameMap != baseNameMap.end(); ++itBaseNameMap) |
357 | { |
358 | if(baseName == itBaseNameMap.key()) |
359 | { |
360 | item->setPixmap(0,SmallIcon(itBaseNameMap.data())); |
361 | return; |
362 | } |
363 | } |
364 | } |
365 | |