OSDN Git Service

autoit.cpp - Macros >> User 1 ..... Variable >> User 2 (#749) (2)
[winmerge-jp/winmerge-jp.git] / Src / FileOrFolderSelect.cpp
index d6d1bff..c76f30a 100644 (file)
@@ -2,52 +2,25 @@
 //    WinMerge:  an interactive diff/merge utility
 //    Copyright (C) 1997-2000  Thingamahoochie Software
 //    Author: Dean Grimm
-//
-//    This program is free software; you can redistribute it and/or modify
-//    it under the terms of the GNU General Public License as published by
-//    the Free Software Foundation; either version 2 of the License, or
-//    (at your option) any later version.
-//
-//    This program is distributed in the hope that it will be useful,
-//    but WITHOUT ANY WARRANTY; without even the implied warranty of
-//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//    GNU General Public License for more details.
-//
-//    You should have received a copy of the GNU General Public License
-//    along with this program; if not, write to the Free Software
-//    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-//
+//    SPDX-License-Identifier: GPL-2.0-or-later
 /////////////////////////////////////////////////////////////////////////////
 /** 
  * @file  FileOrFolderSelect.cpp
  *
  * @brief Implementation of the file and folder selection routines.
  */
-// ID line follows -- this is updated by SVN
-// $Id: FileOrFolderSelect.cpp 6569 2009-03-15 14:33:03Z kimmov $
 
+#include "pch.h"
 #include <windows.h>
+#include "FileOrFolderSelect.h"
+#pragma warning (push)                 // prevent "warning C4091: 'typedef ': ignored on left of 'tagGPFIDL_FLAGS' when no variable is declared"
+#pragma warning (disable:4091) // VC bug when using XP enabled toolsets.
 #include <shlobj.h>
+#pragma warning (pop)
 #include <sys/stat.h>
-#include "UnicodeString.h"
 #include "Environment.h"
-#include "FileOrFolderSelect.h"
 #include "paths.h"
 #include "MergeApp.h"
-#include "resource.h"
-
-// VC 6 headers don't define these constants for folder browse dialog
-// so define them here. Copied from shlobj.h
-#ifndef BIF_EDITBOX
-#define BIF_EDITBOX            0x0010   // Add an editbox to the dialog
-#endif
-#ifndef BIF_NEWDIALOGSTYLE
-#define BIF_NEWDIALOGSTYLE     0x0040   // Use the new dialog layout with the ability to resize
-                                        // Caller needs to call OleInitialize() before using this API
-#endif
-#ifndef BIF_USENEWUI
-#define BIF_USENEWUI           (BIF_NEWDIALOGSTYLE | BIF_EDITBOX)
-#endif
 
 static int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam,
                LPARAM lpData);
@@ -62,7 +35,7 @@ static String LastSelectedFolder;
  * file or folder to open or file to save. The last parameter @p is_open selects
  * between open or save modes. Biggest difference is that in save-mode Windows
  * asks if user wants to override existing file.
- * @param [in] parent Handle to parent window. Can be a NULL, but then
+ * @param [in] parent Handle to parent window. Can be `nullptr`, but then
  *     CMainFrame is used which can cause modality problems.
  * @param [out] path Selected path is returned in this string
  * @param [in] initialPath Initial path (and file) shown when dialog is opened
@@ -70,19 +43,20 @@ static String LastSelectedFolder;
  * @param [in] filterid 0 or STRING ID for filter string
  *     - 0 means "All files (*.*)". Note the string formatting!
  * @param [in] is_open Selects Open/Save -dialog (mode).
- * @note Be careful when setting @p parent to NULL as there are potential
+ * @note Be careful when setting @p parent to `nullptr` as there are potential
  * modality problems with this. Dialog can be lost behind other windows!
  * @param [in] defaultExtension Extension to append if user doesn't provide one
  */
-BOOL SelectFile(HWND parent, String& path, LPCTSTR initialPath /*=NULL*/,
-               const String& stitle /*=_T("")*/, const String& sfilter /*=_T("")*/,
-               BOOL is_open /*=TRUE*/, LPCTSTR defaultExtension /*=NULL*/)
+bool SelectFile(HWND parent, String& path, bool is_open /*= true*/,
+               LPCTSTR initialPath /*= nullptr*/, const String& stitle /*=_T("")*/,
+               const String& sfilter /*=_T("")*/, LPCTSTR defaultExtension /*= nullptr*/)
 {
        path.clear(); // Clear output param
 
        // This will tell common file dialog what to show
        // and also this will hold its return value
-       TCHAR sSelectedFile[MAX_PATH] = {0};
+       TCHAR sSelectedFile[MAX_PATH_FULL] = {0};
+       String sInitialDir;
 
        // check if specified path is a file
        if (initialPath && initialPath[0])
@@ -90,11 +64,16 @@ BOOL SelectFile(HWND parent, String& path, LPCTSTR initialPath /*=NULL*/,
                // If initial path info includes a file
                // we put the bare filename into sSelectedFile
                // so the common file dialog will start up with that file selected
-               if (paths_DoesPathExist(initialPath) == IS_EXISTING_FILE)
+               if (paths::DoesPathExist(initialPath) == paths::IS_EXISTING_FILE)
                {
                        String temp;
-                       paths_SplitFilename(initialPath, 0, &temp, 0);
+                       paths::SplitFilename(initialPath, 0, &temp, 0);
                        lstrcpy(sSelectedFile, temp.c_str());
+                       sInitialDir = paths::GetParentPath(initialPath);
+               }
+               else
+               {
+                       sInitialDir = initialPath;
                }
        }
 
@@ -102,34 +81,34 @@ BOOL SelectFile(HWND parent, String& path, LPCTSTR initialPath /*=NULL*/,
        if (sfilter.empty())
                filters = _("All Files (*.*)|*.*||");
        if (stitle.empty())
-               title = _("Open");
+       {
+               title = is_open ? _("Open") : _("Save As");
+       }
 
        // Convert extension mask from MFC style separators ('|')
        //  to Win32 style separators ('\0')
        LPTSTR filtersStr = &*filters.begin();
        ConvertFilter(filtersStr);
 
-       OPENFILENAME_NT4 ofn;
-       memset(&ofn, 0, sizeof(ofn));
-       ofn.lStructSize = sizeof(ofn);
+       OPENFILENAME_NT4 ofn = { sizeof OPENFILENAME_NT4 };
        ofn.hwndOwner = parent;
        ofn.lpstrFilter = filtersStr;
-       ofn.lpstrCustomFilter = NULL;
+       ofn.lpstrCustomFilter = nullptr;
        ofn.nFilterIndex = 1;
        ofn.lpstrFile = sSelectedFile;
-       ofn.nMaxFile = MAX_PATH;
-       ofn.lpstrInitialDir = initialPath;
+       ofn.nMaxFile = MAX_PATH_FULL;
+       ofn.lpstrInitialDir = sInitialDir.empty() ? nullptr : sInitialDir.c_str();
        ofn.lpstrTitle = title.c_str();
-       ofn.lpstrFileTitle = NULL;
+       ofn.lpstrFileTitle = nullptr;
        if (defaultExtension)
                ofn.lpstrDefExt = defaultExtension;
        ofn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR;
 
-       BOOL bRetVal = FALSE;
+       bool bRetVal = false;
        if (is_open)
-               bRetVal = GetOpenFileName((OPENFILENAME *)&ofn);
+               bRetVal = !!GetOpenFileName((OPENFILENAME *)&ofn);
        else
-               bRetVal = GetSaveFileName((OPENFILENAME *)&ofn);
+               bRetVal = !!GetSaveFileName((OPENFILENAME *)&ofn);
        // common file dialog populated sSelectedFile variable's buffer
 
        if (bRetVal)
@@ -143,26 +122,25 @@ BOOL SelectFile(HWND parent, String& path, LPCTSTR initialPath /*=NULL*/,
  * @param [out] path Selected path is returned in this string
  * @param [in] root_path Initial path shown when dialog is opened
  * @param [in] titleid Resource string ID for dialog title.
- * @param [in] hwndOwner Handle to owner window or NULL
- * @return TRUE if valid folder selected (not cancelled)
+ * @param [in] hwndOwner Handle to owner window or `nullptr`
+ * @return `true` if valid folder selected (not cancelled)
  */
-BOOL SelectFolder(String& path, LPCTSTR root_path /*=NULL*/, 
+bool SelectFolder(String& path, LPCTSTR root_path /*= nullptr*/, 
                        const String& stitle /*=_T("")*/, 
-                       HWND hwndOwner /*=NULL*/) 
+                       HWND hwndOwner /*= nullptr*/) 
 {
        BROWSEINFO bi;
-       LPMALLOC pMalloc;
        LPITEMIDLIST pidl;
-       TCHAR szPath[MAX_PATH] = {0};
-       BOOL bRet = FALSE;
+       TCHAR szPath[MAX_PATH_FULL] = {0};
+       bool bRet = false;
        String title = stitle;
-       if (root_path == NULL)
+       if (root_path == nullptr)
                LastSelectedFolder.clear();
        else
                LastSelectedFolder = root_path;
 
        bi.hwndOwner = hwndOwner;
-       bi.pidlRoot = NULL;  // Start from desktop folder
+       bi.pidlRoot = nullptr;  // Start from desktop folder
        bi.pszDisplayName = szPath;
        bi.lpszTitle = title.c_str();
        bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI | BIF_VALIDATE;
@@ -170,18 +148,14 @@ BOOL SelectFolder(String& path, LPCTSTR root_path /*=NULL*/,
        bi.lParam = (LPARAM)root_path;
 
        pidl = SHBrowseForFolder(&bi);
-
-       if (pidl)
+       if (pidl != nullptr)
        {
                if (SHGetPathFromIDList(pidl, szPath))
                {
                        path = szPath;
-                       bRet = TRUE;
+                       bRet = true;
                }
-
-               SHGetMalloc(&pMalloc);
-               pMalloc->Free(pidl);
-               pMalloc->Release();
+               CoTaskMemFree(pidl);
        }
        return bRet;
 }
@@ -195,21 +169,21 @@ static int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam,
        // Look for BFFM_INITIALIZED
        if (uMsg == BFFM_INITIALIZED)
        {
-               if (lpData)
+               if (lpData != NULL)
                        SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData);
                else
                        SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)LastSelectedFolder.c_str());
        }
        else if (uMsg == BFFM_VALIDATEFAILED)
        {
-               String strMessage = (TCHAR *)lParam;
-               strMessage += _T("\83t\83H\83\8b\83_\82Í\91\8dÝ\82µ\82Ü\82¹\82ñ\81B\8dì\90¬\82µ\82Ü\82·\82©?");
-               int answer = MessageBox(hwnd, strMessage.c_str(), _T("\83t\83H\83\8b\83_\82Ì\8dì\90¬"), MB_YESNO);
+               String strMessage = 
+                       strutils::format_string1(_("%1 does not exist. Do you want to create it?"), (TCHAR *)lParam);
+               int answer = MessageBox(hwnd, strMessage.c_str(), nullptr, MB_YESNO);
                if (answer == IDYES)
                {
-                       if (!paths_CreateIfNeeded((TCHAR*)lParam))
+                       if (!paths::CreateIfNeeded((TCHAR*)lParam))
                        {
-                               MessageBox(hwnd, _T("\83t\83H\83\8b\83_\82Ì\8dì\90¬\82É\8e¸\94s\82µ\82Ü\82µ\82½"), _T("\83t\83H\83\8b\83_\82Ì\8dì\90¬"), MB_OK | MB_ICONWARNING);
+                               MessageBox(hwnd, _("Failed to create folder.").c_str(), nullptr, MB_OK | MB_ICONWARNING);
                        }
                }
                return 1;
@@ -225,30 +199,30 @@ static int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam,
  * - If existing filename is selected return it
  * - If filename in (CFileDialog) editbox and current folder doesn't form
  * a valid path to file, return current folder.
- * @param [in] parent Handle to parent window. Can be a NULL, but then
+ * @param [in] parent Handle to parent window. Can be `nullptr`, but then
  *     CMainFrame is used which can cause modality problems.
  * @param [out] path Selected folder/filename
  * @param [in] initialPath Initial file or folder shown/selected.
- * @return TRUE if user choosed a file/folder, FALSE if user canceled dialog.
+ * @return `true` if user choosed a file/folder, `false` if user canceled dialog.
  */
-BOOL SelectFileOrFolder(HWND parent, String& path, LPCTSTR initialPath /*=NULL*/)
+bool SelectFileOrFolder(HWND parent, String& path, LPCTSTR initialPath /*= nullptr*/)
 {
        String title = _("Open");
 
        // This will tell common file dialog what to show
        // and also this will hold its return value
-       TCHAR sSelectedFile[MAX_PATH];
+       TCHAR sSelectedFile[MAX_PATH_FULL];
 
        // check if specified path is a file
-       if (initialPath && initialPath[0])
+       if (initialPath!=nullptr && initialPath[0] != '\0')
        {
                // If initial path info includes a file
                // we put the bare filename into sSelectedFile
                // so the common file dialog will start up with that file selected
-               if (paths_DoesPathExist(initialPath) == IS_EXISTING_FILE)
+               if (paths::DoesPathExist(initialPath) == paths::IS_EXISTING_FILE)
                {
                        String temp;
-                       paths_SplitFilename(initialPath, 0, &temp, 0);
+                       paths::SplitFilename(initialPath, 0, &temp, 0);
                        lstrcpy(sSelectedFile, temp.c_str());
                }
        }
@@ -266,33 +240,29 @@ BOOL SelectFileOrFolder(HWND parent, String& path, LPCTSTR initialPath /*=NULL*/
        dirSelTag += _T("."); // Treat it as filename
        lstrcpy(sSelectedFile, dirSelTag.c_str()); // What is assignment above good for?
 
-       OPENFILENAME_NT4 ofn;
-       memset(&ofn, 0, sizeof(ofn));
-       ofn.lStructSize = sizeof(ofn);
+       OPENFILENAME_NT4 ofn = { sizeof OPENFILENAME_NT4 };
        ofn.hwndOwner = parent;
        ofn.lpstrFilter = filtersStr;
-       ofn.lpstrCustomFilter = NULL;
+       ofn.lpstrCustomFilter = nullptr;
        ofn.nFilterIndex = 1;
        ofn.lpstrFile = sSelectedFile;
-       ofn.nMaxFile = MAX_PATH;
+       ofn.nMaxFile = MAX_PATH_FULL;
        ofn.lpstrInitialDir = initialPath;
        ofn.lpstrTitle = title.c_str();
-       ofn.lpstrFileTitle = NULL;
+       ofn.lpstrFileTitle = nullptr;
        ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_NOTESTFILECREATE | OFN_NOCHANGEDIR;
 
-       BOOL bRetVal = GetOpenFileName((OPENFILENAME *)&ofn);
+       bool bRetVal = !!GetOpenFileName((OPENFILENAME *)&ofn);
 
        if (bRetVal)
        {
                path = sSelectedFile;
-               struct _stati64 statBuffer;
-               int nRetVal = _tstati64(path.c_str(), &statBuffer);
-               if (nRetVal == -1)
+               if (paths::DoesPathExist(path) == paths::DOES_NOT_EXIST)
                {
                        // We have a valid folder name, but propably garbage as a filename.
                        // Return folder name
-                       String folder = paths_GetPathOnly(sSelectedFile);
-                       path = paths_AddTrailingSlash(folder);
+                       String folder = paths::GetPathOnly(sSelectedFile);
+                       path = paths::AddTrailingSlash(folder);
                }
        }
        return bRetVal;
@@ -312,7 +282,8 @@ BOOL SelectFileOrFolder(HWND parent, String& path, LPCTSTR initialPath /*=NULL*/
  */
 static void ConvertFilter(LPTSTR filterStr)
 {
-       while (TCHAR *ch = _tcschr(filterStr, '|'))
+       TCHAR *ch;
+       while ( (ch = _tcschr(filterStr, '|')) != nullptr)
        {
                filterStr = ch + 1;
                *ch = '\0';