Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

utils.cpp

Go to the documentation of this file.
00001 /* 00002 * wxChecksums 00003 * Copyright (C) 2003-2004 Julien Couot 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU General Public License 00007 * as published by the Free Software Foundation; either version 2 00008 * of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 */ 00019 00020 /** 00021 * \file utils.cpp 00022 * Various utility functions. 00023 */ 00024 00025 //--------------------------------------------------------------------------- 00026 // For compilers that support precompilation, includes "wx.h". 00027 #include <wx/wxprec.h> 00028 00029 #ifdef __BORLANDC__ 00030 #pragma hdrstop 00031 #endif 00032 00033 #ifndef WX_PRECOMP 00034 // Include your minimal set of headers here, or wx.h 00035 #include <wx/wx.h> 00036 #endif 00037 #include <wx/datetime.h> 00038 #include <wx/dir.h> 00039 #include <wx/filename.h> 00040 #include <wx/tokenzr.h> 00041 00042 #include <climits> 00043 00044 // Include the Windows API header at the end prevents some problems that can 00045 // occur at the linking procedure. 00046 #if defined(__WXMSW__) 00047 #include <windows.h> 00048 #include <winbase.h> 00049 #include <winnls.h> 00050 #include <winuser.h> 00051 #include <wx/msw/private.h> 00052 #endif // __WXMSW__ 00053 00054 #include "utils.hpp" 00055 #include "comdefs.hpp" 00056 #include "dlgProgress.hpp" 00057 #include "osdep.hpp" 00058 00059 #include "compat.hpp" 00060 //--------------------------------------------------------------------------- 00061 00062 /// The C++ standard namespace. 00063 using namespace std; 00064 00065 00066 /** 00067 * Compares two file names. 00068 * 00069 * Under Windows the comparison is case insensitive. 00070 * 00071 * @param fn1 First file name. 00072 * @param fn2 Second file name. 00073 * @return A negative value if <CODE>f1 < f2</CODE>, a positive value if 00074 * <CODE>f1 > f2</CODE>, <CODE>0</CODE> if <CODE>f1 == f2</CODE>. 00075 */ 00076 int compareFileName(const wxString& fn1, const wxString& fn2) 00077 { 00078 int res; 00079 #if defined(__WXMSW__) 00080 res = CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, fn1.c_str(), -1, fn2.c_str(), -1) - CSTR_EQUAL; 00081 #else 00082 res = fn1.Cmp(fn2); 00083 #endif // __WXMSW__ 00084 00085 return res; 00086 } 00087 //--------------------------------------------------------------------------- 00088 00089 00090 /** 00091 * Convert progress bar counter values. 00092 * 00093 * For getFilesInSubdirectories() and getFilesInSubdirectoriesRec() internal 00094 * usage only. 00095 * 00096 * @param pc Progress bar value. 00097 * @param mn Minimum value. 00098 * @param mx Maximal value. 00099 */ 00100 static int FilesInSubdirectoriesCounterConverter(const double pc, const int mn, const int mx) 00101 { 00102 int cpval = static_cast<int>(pc); 00103 if (cpval < mn) cpval = mn; 00104 if (cpval > mx) cpval = mx; 00105 00106 return cpval; 00107 } 00108 //--------------------------------------------------------------------------- 00109 00110 00111 /** 00112 * Find all the files in the subdirectories from a list of files and directories. 00113 * 00114 * For internal usage only. 00115 * 00116 * @param lFiles List of files and directories to search into. 00117 * @param res Array of string where all the founded files will to stored. 00118 * All files present in lFiles will be copied (but not the 00119 * directories). 00120 * @param filesSize Will contains the total size of the parsed files. 00121 * @param matchPatterns Optionnal matching patterns for files' names. 00122 * @param depth Maximal depth of recursion. 00123 * @param lt Last time when the dialog has been updated. 00124 * @param dlgProgress Progress dialog. 00125 * @param cp Current position for the progress bar. 00126 * @param cpMax Maximal position for the progress bar. 00127 * @return <CODE>true</CODE> on success, <CODE>false</CODE> on failure or if 00128 * the user has canceled. 00129 */ 00130 static bool getFilesInSubdirectoriesRec(const wxArrayString& lFiles, wxArrayString& res, 00131 BytesDisplayer& filesSize, 00132 const wxArrayString& matchPatterns, 00133 const unsigned int depth, 00134 wxDateTime& lt, 00135 dlgProgress& dlgProgress, double cp, 00136 double cpMax) 00137 { 00138 if (lFiles.IsEmpty()) // to avoid div by 0 in initialization of incrByFile. 00139 return true; 00140 if (depth == 0) 00141 return true; 00142 00143 wxDateTime ct; // current time 00144 wxTimeSpan timeSpan(0, 0, 0, UPDATE_PROGRESS_DLG); 00145 bool cont = true; // continue ? 00146 double incrByFile = (cpMax - cp) / static_cast<double>(lFiles.GetCount()); 00147 const wxChar pathSeparator = wxFileName::GetPathSeparator(); 00148 bool matched; 00149 00150 for (size_t i = 0; i < lFiles.GetCount() && cont; i++) 00151 { 00152 // Show information 00153 ct = wxDateTime::UNow(); 00154 if (ct.IsLaterThan(lt)) 00155 { 00156 int cpval = FilesInSubdirectoriesCounterConverter(cp, 0, SHRT_MAX - 2); 00157 cont = dlgProgress.Update(cpval, lFiles[i]); 00158 ::wxYield(); 00159 lt = ct + timeSpan; 00160 } 00161 00162 // Pause ? 00163 while (dlgProgress.isPaused()) 00164 ::wxYield(); 00165 00166 if (::wxDirExists(lFiles[i])) 00167 // Explore the directory 00168 { 00169 if (depth > 1) 00170 // Don't explore the directory if it isn't needed. 00171 { 00172 wxArrayString files; 00173 wxDir dir(lFiles[i]); 00174 wxFileName dirName; 00175 wxFileName fn; 00176 dirName.AssignDir(lFiles[i]); 00177 if (dir.IsOpened()) 00178 { 00179 wxString f; 00180 bool found = dir.GetFirst(&f, wxEmptyString, wxDIR_FILES | wxDIR_DIRS | wxDIR_HIDDEN); 00181 while (found) 00182 { 00183 fn = dirName; 00184 fn.SetFullName(f); 00185 files.Add(fn.GetFullPath()); 00186 found = dir.GetNext(&f); 00187 } 00188 cont = getFilesInSubdirectoriesRec(files, res, filesSize, matchPatterns, depth - 1, lt, dlgProgress, cp, cp + incrByFile); 00189 } 00190 } 00191 } 00192 else // match the file 00193 { 00194 if (matchPatterns.IsEmpty()) 00195 matched = true; 00196 else 00197 { 00198 matched = false; 00199 size_t c = 0; 00200 while (!matched && c < matchPatterns.GetCount()) 00201 { 00202 matched = ::wxMatchWild(matchPatterns[c], lFiles[i], false); 00203 c++; 00204 } 00205 } 00206 00207 if (matched) 00208 { 00209 res.Add(lFiles[i]); 00210 wxCOff_t fs; 00211 if ((fs = wxCGetFileLength(lFiles[i])) != static_cast<wxCOff_t>(wxInvalidOffset)) 00212 filesSize += static_cast<double>(fs); 00213 } 00214 } 00215 00216 cp += incrByFile; 00217 } 00218 00219 return cont; 00220 } 00221 //--------------------------------------------------------------------------- 00222 00223 00224 /** 00225 * Find all the files in the subdirectories from a list of files and directories. 00226 * 00227 * A matching pattern can be speficied. Wildcards are <CODE>*</CODE> and 00228 * <CODE>?</CODE>. <CODE>*</CODE> subtitutes one or more characters, 00229 * <CODE>?</CODE> one character.<BR> 00230 * Matching patterns are separated by the <CODE>;</CODE> character.<BR> 00231 * If no matching patterns are given, all the files will be matched. 00232 * 00233 * The depth of recursion can be <CODE>0</CODE> for no limit, 00234 * <CODE>1</CODE> for the given directories, <CODE>2</CODE> for the given 00235 * directories and their subdirectories, etc... 00236 * 00237 * @param lFiles List of files and directories to search into. 00238 * @param res Array of string where all the founded files will to stored. 00239 * All files present in lFiles will be copied (but not the 00240 * directories). 00241 * @param filesSize Will contains the total size of the parsed files. 00242 * @param matchPattern Optionnal matching pattern for files' names. 00243 * @param maxDepth Maximal depth of recursion. 00244 * @return <CODE>true</CODE> on success, <CODE>false</CODE> on failure or if 00245 * the user has canceled. 00246 */ 00247 bool getFilesInSubdirectories(const wxArrayString& lFiles, wxArrayString& res, 00248 BytesDisplayer& filesSize, 00249 const wxString& matchPattern, 00250 unsigned int maxDepth) 00251 { 00252 if (lFiles.IsEmpty()) 00253 return true; 00254 00255 dlgProgress dlgProgress(_("Searching files"), _("Beginning..."), SHRT_MAX - 1, NULL, 00256 wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME); 00257 00258 // Get the matching patterns 00259 wxArrayString matchPatterns; 00260 wxStringTokenizer tkz(matchPattern, wxT(";"), wxTOKEN_STRTOK); 00261 while (tkz.HasMoreTokens()) 00262 { 00263 wxString token = tkz.GetNextToken(); 00264 00265 if (!wxFileName::IsCaseSensitive()) 00266 GetAllTokenCases(token, matchPatterns); 00267 else 00268 matchPatterns.Add(token); 00269 } 00270 00271 unsigned int depth = (maxDepth == 0 || maxDepth == UINT_MAX) ? UINT_MAX : maxDepth + 1; 00272 wxTimeSpan timeSpan(0, 0, 0, UPDATE_PROGRESS_DLG); 00273 wxDateTime lt = wxDateTime::UNow() - timeSpan; // last time 00274 bool cont; // continue ? 00275 00276 cont = getFilesInSubdirectoriesRec(lFiles, res, filesSize, matchPatterns, 00277 depth, lt, dlgProgress, 0.0, 00278 static_cast<double>(SHRT_MAX - 2)); 00279 00280 dlgProgress.Update(SHRT_MAX - 1, _("Finished")); 00281 00282 return cont; 00283 } 00284 //--------------------------------------------------------------------------- 00285 00286 00287 /** 00288 * Gets the application's name. 00289 * 00290 * @param addVersion If <CODE>true</CODE>, add the version number + special. 00291 * @return The application's name. 00292 */ 00293 wxString getAppName(bool addVersion) 00294 { 00295 wxString res; 00296 00297 if (addVersion) 00298 { 00299 res.Printf(wxT("%s v%d.%d.%d"), wxT(APP_NAME), APP_MAJOR_VER, APP_MINOR_VER, APP_SUBVER); 00300 wxString special(wxT(APP_SPECIAL)); 00301 if (!special.empty()) 00302 res += wxString::Format(wxT(" (%s)"), special.c_str()); 00303 } 00304 else 00305 res = wxT(APP_NAME); 00306 00307 return res; 00308 } 00309 //--------------------------------------------------------------------------- 00310 00311 00312 /** 00313 * Convert a <CODE>wxColour</CODE> value to a <CODE>long</CODE> value. 00314 * 00315 * @param value The value to convert. 00316 * @return The value converted to a <CODE>long</CODE> value. 00317 */ 00318 long wxColourToLong(const wxColour& value) 00319 { 00320 long res; 00321 00322 res = (static_cast<long>(value.Red()) << 16) | 00323 (static_cast<long>(value.Green()) << 8) | 00324 (static_cast<long>(value.Blue())); 00325 return res; 00326 } 00327 //--------------------------------------------------------------------------- 00328 00329 00330 /** 00331 * Convert a <CODE>long</CODE> value to a <CODE>wxColour</CODE> value. 00332 * 00333 * @param value The value to convert. 00334 * @return The value converted to a <CODE>wxColour</CODE> value. 00335 */ 00336 wxColour longTowxColour(long value) 00337 { 00338 wxColour res(static_cast<unsigned char>((value & 0xFF0000) >> 16), 00339 static_cast<unsigned char>((value & 0x00FF00) >> 8), 00340 static_cast<unsigned char>((value & 0x0000FF))); 00341 00342 return res; 00343 } 00344 //--------------------------------------------------------------------------- 00345 00346 00347 /** 00348 * Convert the specified character to the lower case. 00349 * 00350 * @param s String that contains the character to lower. 00351 * @param idx Index in <CODE>s</CODE> of the character to lower. 00352 */ 00353 void ToLower(wxString& s, size_t idx) 00354 { 00355 if (idx < s.size()) 00356 { 00357 wxString t = s[idx]; 00358 t.LowerCase(); 00359 wxChar c = t.GetChar(0); 00360 s[idx] = c; 00361 } 00362 } 00363 //--------------------------------------------------------------------------- 00364 00365 00366 /** 00367 * Convert the specified character to the upper case. 00368 * 00369 * @param s String that contains the character to upper. 00370 * @param idx Index in <CODE>s</CODE> of the character to upper. 00371 */ 00372 void ToUpper(wxString& s, size_t idx) 00373 { 00374 if (idx < s.size()) 00375 { 00376 wxString t = s[idx]; 00377 t.UpperCase(); 00378 wxChar c = t.GetChar(0); 00379 s[idx] = c; 00380 } 00381 } 00382 //--------------------------------------------------------------------------- 00383 00384 00385 /** 00386 * Get the given token with all the possible cases. Result is added to tk. 00387 * 00388 * @param token Token to get with all the possible cases. 00389 * @param tk Arary of string when the tokens will be added. 00390 * @param p Current position in the token (only for internal recursivity). 00391 */ 00392 void GetAllTokenCases(wxString token, wxArrayString& tk, size_t p) 00393 { 00394 if (p == token.size()) 00395 { 00396 if (tk.Index(token, true) == wxNOT_FOUND) 00397 tk.Add(token); 00398 return; 00399 } 00400 00401 ToUpper(token, p); 00402 GetAllTokenCases(token, tk, p + 1); 00403 ToLower(token, p); 00404 GetAllTokenCases(token, tk, p + 1); 00405 } 00406 //---------------------------------------------------------------------------

Generated on Sun May 30 13:37:45 2004 for wxChecksums by doxygen 1.3.7