OSDN Git Service

2005-03-04 Perry
authorPerry Rapp <elsapo@users.sourceforge.net>
Fri, 4 Mar 2005 02:20:58 +0000 (02:20 +0000)
committerPerry Rapp <elsapo@users.sourceforge.net>
Fri, 4 Mar 2005 02:20:58 +0000 (02:20 +0000)
 PATCH: [ 1156253 ] Fix filter helper handling of new filters
 BUG: [ 1153018 ] Create new filter, now cannot find it
  Src: FileFilterHelper.cpp FileFilterHelper.h FileFiltersDlg.cpp Merge.cpp
   Merge.h paths.cpp paths.h

Src/FileFilterHelper.cpp
Src/FileFilterHelper.h
Src/FileFiltersDlg.cpp
Src/Merge.cpp
Src/Merge.h
Src/paths.cpp
Src/paths.h
Src/readme.txt

index 73b4052..12f235b 100644 (file)
 #include "FileFilterHelper.h"
 #include "RegExp.h"
 #include "Coretools.h"
+#include "paths.h"
+
 
 FileFilterHelper::FileFilterHelper()
 {
-       m_fileFilterMgr = NULL;
+       m_fileFilterMgr = new FileFilterMgr;
        m_bUseMask = TRUE;
 }
 
-/** 
- * @brief Return filtermanager used.
- */
-FileFilterMgr * FileFilterHelper::GetManager()
+FileFilterHelper::~FileFilterHelper()
 {
-       return m_fileFilterMgr;
+       delete m_fileFilterMgr;
 }
 
+
 /** 
- * @brief Set filtermanager used.
+ * @brief Return filtermanager used.
  */
-void FileFilterHelper::SetManager(FileFilterMgr * pFilterManager)
+FileFilterMgr * FileFilterHelper::GetManager()
 {
-       if (pFilterManager != NULL)
-               m_fileFilterMgr = pFilterManager;
+       return m_fileFilterMgr;
 }
 
 /** @brief Store current filter (if filter manager validates the name) */
@@ -361,6 +360,21 @@ void FileFilterHelper::ReloadUpdatedFilters()
 }
 
 /**
+ * @ brief Returns true if directory exists or successfully created
+ * Tries to create multiple directories if needed
+ */
+static bool
+EnsureDirectoryExists(const CString & sPath)
+{
+       // paths_CanUse will 
+       if (paths_CreateIfNeeded(sPath))
+               return true;
+       else
+               return false;
+
+}
+
+/**
  * @brief Load any known file filters
  * @todo Preserve filter selection? How?
  */
@@ -377,18 +391,40 @@ void FileFilterHelper::LoadAllFileFilters()
        LoadFileFilterDirPattern(patternsLoaded, sPattern);
 
        // Application data path in user profile directory
-       if (GetAppDataPath(sPattern))
+       CString sAppPath;
+       if (GetAppDataPath(sAppPath))
        {
-               sPattern += _T("\\WinMerge\\Filters\\*.flt");
-               LoadFileFilterDirPattern(patternsLoaded, sPattern);
+               CString sPath = sAppPath + _T("\\WinMerge\\Filters");
+               TestCandidateFilterPath(sPath);
+               LoadFileFilterDirPattern(patternsLoaded, sPath + _T("\\*.flt"));
        }
+
        // User profile local & roaming settings
        CString sProfile;
        if (GetUserProfilePath(sProfile))
        {
-               sPattern = sProfile + _T("\\Local Settings\\Application Data\\WinMerge\\Filters\\*.flt");
-               LoadFileFilterDirPattern(patternsLoaded, sPattern);
-               sPattern = sProfile + _T("\\Application Data\\WinMerge\\Filters\\*.flt");
-               LoadFileFilterDirPattern(patternsLoaded, sPattern);
+               CString sPath = sProfile + _T("\\Local Settings\\Application Data\\WinMerge\\Filters");
+               TestCandidateFilterPath(sPath);
+               LoadFileFilterDirPattern(patternsLoaded, sPath + _T("\\*.flt"));
+
+               sPath = sProfile + _T("\\Application Data\\WinMerge\\Filters");
+               TestCandidateFilterPath(sPath);
+               LoadFileFilterDirPattern(patternsLoaded, sPath + _T("\\*.flt"));
+       }
+}
+
+/**
+ * @brief Store as path for new file filters, if we still need one and this path exists
+ */
+void
+FileFilterHelper::TestCandidateFilterPath(const CString & sPath)
+{
+       if (m_sNewFileFilterPath.IsEmpty())
+       {
+               if (EnsureDirectoryExists(sPath))
+               {
+                       m_sNewFileFilterPath = sPath;
+               }
        }
 }
+
index 79db855..19b2609 100644 (file)
@@ -66,6 +66,10 @@ public:
 /**
  * @brief Helper class for using filefilters.
  *
+ * A FileFilterHelper object is the owner of any active mask, and of the file filter manager
+ * This is kind of a File Filter SuperManager, taking care of both inline filters from strings
+ *  and loaded file filters (the latter handled by its internal file filter manager)
+ *
  * This class is mainly for handling two ways to filter files in WinMerge:
  * - File masks: *.ext lists (*.cpp *.h etc)
  * - File filters: regular expression rules in separate files
@@ -79,10 +83,10 @@ class FileFilterHelper : public IDiffFilter
 {
 public:
        FileFilterHelper();
+       ~FileFilterHelper();
 
        FileFilterMgr * GetManager();
-       void SetManager(FileFilterMgr * pFilterManager);
-       CString GetFileFilterPath() const { return m_sFileFilterPath; }
+       CString GetNewFileFilterPath() const { return m_sNewFileFilterPath; }
        void SetFileFilterPath(LPCTSTR szFileFilterPath);
        void EditFileFilter(LPCTSTR szFileFilterPath);
        void GetFileFilters(FILEFILTER_INFOLIST * filters, CString & selected) const;
@@ -107,6 +111,8 @@ public:
 
 protected:
        CString ParseExtensions(CString extensions);
+       void TestCandidateFilterPath(const CString & sPath);
+
 
 private:
        FileFilter * m_currentFilter;     /*< Currently selected filefilter */
@@ -114,6 +120,7 @@ private:
        CString m_sFileFilterPath;        /*< Path to current filter */
        CString m_sMask;   /*< File mask (if defined) "*.cpp *.h" etc */
        BOOL m_bUseMask;   /*< If TRUE file mask is used, filter otherwise */
+       CString m_sNewFileFilterPath;    /*< Path where new filters should be created */
 
        CRegExp m_rgx;     /*< Compiled file mask regular expression */
 };
index aaabcdd..b3d5dea 100644 (file)
@@ -351,19 +351,10 @@ void FileFiltersDlg::OnBnClickedFilterfileNewbutton()
        TCHAR drive[_MAX_DRIVE] = {0};
 
        VERIFY(title.LoadString(IDS_FILEFILTER_SAVENEW));
-       path = theApp.m_globalFileFilter.GetFileFilterPath();
+       path = theApp.m_globalFileFilter.GetNewFileFilterPath();
+       if (path.GetLength() && path[path.GetLength()-1] != '\\')
+               path += '\\';
 
-       // Drop filename and extension
-       _tsplitpath(path, drive, dir, NULL, NULL);
-       if (_tcslen(drive) > 0 )
-       {
-               path = drive;
-               path += dir;
-       }
-       else
-       {
-               path = dir;
-       }
        
        tmplPath = path + FILE_FILTER_TEMPLATE;
        
index cf12215..7afd33f 100644 (file)
@@ -42,7 +42,6 @@
 #include "logfile.h"
 #include "coretools.h"
 #include "paths.h"
-#include "FileFilterMgr.h"
 #include "FileFilterHelper.h"
 #include "Plugins.h"
 #include "DirScan.h" // for DirScan_InitializeDefaultCodepage
@@ -83,7 +82,6 @@ CMergeApp::CMergeApp() :
 , m_pDiffTemplate(0)
 , m_pDirTemplate(0)
 , m_lang(IDR_MAINFRAME, IDR_MAINFRAME)
-, m_fileFilterMgr(0)
 {
        // TODO: add construction code here,
        // Place all significant initialization in InitInstance
@@ -582,7 +580,6 @@ void CMergeApp::OnViewLanguage()
 
 int CMergeApp::ExitInstance() 
 {
-       delete m_fileFilterMgr;
        delete m_mainThreadScripts;
        return CWinApp::ExitInstance();
 }
@@ -669,10 +666,6 @@ BOOL CMergeApp::OnIdle(LONG lCount)
 /** @brief Load any known file filters */
 void CMergeApp::InitializeFileFilters()
 {
-       if (!m_fileFilterMgr)
-               m_fileFilterMgr = new FileFilterMgr;
-
-       m_globalFileFilter.SetManager(m_fileFilterMgr);
        m_globalFileFilter.LoadAllFileFilters();
 }
 
index e46efe3..f203bb3 100644 (file)
@@ -38,7 +38,6 @@
 #include "languageselect.h"
 #include "FileFilterHelper.h"
 
-class FileFilterMgr;
 struct FileFilter;
 class CAssureScriptsForThread;
 class CMainFrame;
@@ -93,7 +92,6 @@ protected:
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
 private:
-       FileFilterMgr * m_fileFilterMgr;
        CAssureScriptsForThread * m_mainThreadScripts;
 };
 
index ffb73db..9540fc9 100644 (file)
@@ -73,6 +73,21 @@ void paths_normalize(CString & sPath)
 }
 
 /**
+ * @brief Get canonical name of directory & return true, if it exists
+ */
+static bool GetDirName(const CString & sDir, CString& sName)
+{
+       // (Couldn't get info for just the directory from CFindFile)
+       WIN32_FIND_DATA ffd;
+       HANDLE h = FindFirstFile(sDir, &ffd);
+       if (h == INVALID_HANDLE_VALUE)
+               return false;
+       sName = ffd.cFileName;
+       FindClose(h);
+       return true;
+}
+
+/**
  * Convert path to canonical long path (ie, with ~ short names expanded)
  * Expand any environment strings
  * If path does not exist, make canonical the part that does exist, and leave the rest as is
@@ -156,10 +171,8 @@ CString paths_GetLongPath(const CString & sPath)
                // advance to next component (or set ptr==0 to flag end)
                ptr = (end ? end+1 : 0);
 
-               // (Couldn't get info for just the directory from CFindFile)
-               WIN32_FIND_DATA ffd;
-               HANDLE h = FindFirstFile(sTemp, &ffd);
-               if (h == INVALID_HANDLE_VALUE)
+               CString sNextName;
+               if (!GetDirName(sTemp, sNextName))
                {
                        sLong = sTemp;
                        if (ptr)
@@ -169,17 +182,88 @@ CString paths_GetLongPath(const CString & sPath)
                        return sLong;
                }
                sLong += '\\';
-               sLong += ffd.cFileName;
-               if (dst == DIRSLASH && !ptr &&
-                       (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+               sLong += sNextName;
+               if (dst == DIRSLASH && !ptr)
                {
                        sLong += '\\';
                }
-               FindClose(h);
        }
        return sLong;
 }
 
+/**
+ * @brief Return true if path exists or if we successfully create it
+ * Expand any environment strings
+ * Create missing parts (as far as possible)
+ */
+bool paths_CreateIfNeeded(const CString & sPath)
+{
+       if (sPath.IsEmpty()) return false;
+
+       CString sTemp;
+       if (GetDirName(sPath, sTemp)) return true;
+
+       if (sPath.GetLength() >= _MAX_PATH) return false;
+
+       // Expand environment variables:
+       // Convert "%userprofile%\My Documents" to "C:\Documents and Settings\username\My Documents"
+       TCHAR fullPath[_MAX_PATH] = _T("");
+       if (!_tcschr(sPath, '%') || !ExpandEnvironmentStrings(sPath, fullPath, _MAX_PATH))
+       {
+               _tcscpy(fullPath, sPath);
+       }
+       // Now fullPath holds our desired path
+
+       CString sLong;
+       TCHAR *ptr = fullPath;
+       TCHAR *end = NULL;
+
+       // Skip to \ position     d:\abcd or \\host\share\abcd
+       // indicated by ^           ^                    ^
+       if (_tcslen(ptr) > 2)
+               end = _tcschr(fullPath+2, _T('\\'));
+       if (end && !_tcsnicmp(fullPath, _T("\\\\"),2))
+               end = _tcschr(end+1, _T('\\'));
+
+       if (!end) return false;
+
+       // check that first component exists
+       *end = 0;
+       if (!GetDirName(fullPath, sTemp))
+               return false;
+       *end = '\\';
+
+       ptr = end+1;
+
+       while (ptr)
+       {
+               end = _tcschr(ptr, '\\');
+               // zero-terminate current component
+               // (if we're at end, its already zero-terminated)
+               if (end)
+                       *end = 0;
+
+               // advance to next component (or set ptr==0 to flag end)
+               ptr = (end ? end+1 : 0);
+
+               CString sNextName;
+               if (!GetDirName(fullPath, sNextName))
+               {
+                       // try to create directory, and then double-check its existence
+                       if (!CreateDirectory(fullPath, 0)
+                               || !GetDirName(fullPath, sNextName))
+                       {
+                               return false;
+                       }
+               }
+               // if not finished, restore directory string we're working in
+               if (ptr)
+                       *end = '\\';
+       }
+       return true;
+}
+
+
 /** 
  * @brief Return folder for temporary files.
  */
index 1832105..16e7b3c 100644 (file)
@@ -15,6 +15,7 @@ typedef enum { DIRSLASH, NODIRSLASH } DIRSLASH_TYPE;
 PATH_EXISTENCE paths_DoesPathExist(LPCTSTR szPath);
 void paths_normalize(CString & sPath);
 CString paths_GetLongPath(const CString & sPath);
+bool paths_CreateIfNeeded(const CString & sPath);
 LPCTSTR paths_GetTempPath();
 PATH_EXISTENCE GetPairComparability(LPCTSTR pszLeft, LPCTSTR pszRight);
 CString ExpandShortcut(const CString &inFile);
index 1d9a948..9ff00ba 100644 (file)
@@ -1,3 +1,9 @@
+2005-03-04 Perry
+ PATCH: [ 1156253 ] Fix filter helper handling of new filters
+ BUG: [ 1153018 ] Create new filter, now cannot find it
+  Src: FileFilterHelper.cpp FileFilterHelper.h FileFiltersDlg.cpp Merge.cpp
+   Merge.h paths.cpp paths.h
+
 2005-03-03 Kimmo
  PATCH: [ 1155319 ] Select font for dir compare view
   Src: DirView.cpp DirView.h MainFrm.cpp MainFrm.h Merge.rc OptionsDef.h