-/////////////////////////////////////////////////////////////////////////////
-// License (GPLv2+):
-// 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 FileFiltersDlg.cpp
*
#include <vector>
#include "UnicodeString.h"
#include "Merge.h"
+#include "OptionsMgr.h"
+#include "OptionsDef.h"
#include "FileFilterMgr.h"
#include "FileFilterHelper.h"
#include "paths.h"
#include "SharedFilterDlg.h"
#include "TestFilterDlg.h"
#include "FileOrFolderSelect.h"
+#include "UniFile.h"
+#include "Constants.h"
using std::vector;
#ifdef _DEBUG
#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
#endif
/** @brief Template file used when creating new filefilter. */
static const TCHAR FILE_FILTER_TEMPLATE[] = _T("FileFilter.tmpl");
-/** @brief Location for filters specific help to open. */
-static const TCHAR FilterHelpLocation[] = _T("::/htmlhelp/Filters.html");
-
/////////////////////////////////////////////////////////////////////////////
// CFiltersDlg dialog
-IMPLEMENT_DYNCREATE(FileFiltersDlg, CPropertyPage)
+IMPLEMENT_DYNCREATE(FileFiltersDlg, CTrPropertyPage)
/**
* @brief Constructor.
*/
-FileFiltersDlg::FileFiltersDlg() : CPropertyPage(FileFiltersDlg::IDD)
+FileFiltersDlg::FileFiltersDlg() : CTrPropertyPage(FileFiltersDlg::IDD)
{
m_strCaption = theApp.LoadDialogCaption(m_lpszTemplateName).c_str();
m_psp.pszTitle = m_strCaption;
}
-BEGIN_MESSAGE_MAP(FileFiltersDlg, CDialog)
+BEGIN_MESSAGE_MAP(FileFiltersDlg, CTrPropertyPage)
//{{AFX_MSG_MAP(FileFiltersDlg)
ON_BN_CLICKED(IDC_FILTERFILE_EDITBTN, OnFiltersEditbtn)
ON_NOTIFY(NM_DBLCLK, IDC_FILTERFILE_LIST, OnDblclkFiltersList)
* @param [in] fileFilters Array of filters to show in the dialog.
* @note Call this before actually showing the dialog.
*/
-void FileFiltersDlg::SetFilterArray(vector<FileFilterInfo> * fileFilters)
+void FileFiltersDlg::SetFilterArray(const vector<FileFilterInfo>& fileFilters)
{
m_Filters = fileFilters;
}
// Also enable infotips.
m_listFilters.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP);
+ const int lpx = CClientDC(this).GetDeviceCaps(LOGPIXELSX);
+ auto pointToPixel = [lpx](int point) { return MulDiv(point, lpx, 72); };
+
String title = _("Name");
- m_listFilters.InsertColumn(0, title.c_str(), LVCFMT_LEFT, 150);
+ m_listFilters.InsertColumn(0, title.c_str(), LVCFMT_LEFT, pointToPixel(112));
title = _("Description");
- m_listFilters.InsertColumn(1, title.c_str(), LVCFMT_LEFT, 350);
+ m_listFilters.InsertColumn(1, title.c_str(), LVCFMT_LEFT, pointToPixel(262));
title = _("Location");
- m_listFilters.InsertColumn(2, title.c_str(), LVCFMT_LEFT, 350);
+ m_listFilters.InsertColumn(2, title.c_str(), LVCFMT_LEFT, pointToPixel(262));
title = _("<None>");
m_listFilters.InsertItem(1, title.c_str());
m_listFilters.SetItemText(0, 1, title.c_str());
m_listFilters.SetItemText(0, 2, title.c_str());
- const int count = (int) m_Filters->size();
+ const int count = (int) m_Filters.size();
for (int i = 0; i < count; i++)
{
}
/**
+ * @brief Select filter by file path in the listview.
+ * @param [in] path file path
+ */
+void FileFiltersDlg::SelectFilterByFilePath(const String& path)
+{
+ for (size_t i = 0; i < m_Filters.size(); ++i)
+ {
+ if (m_Filters[i].fullpath == path)
+ {
+ SelectFilterByIndex(static_cast<int>(i + 1));
+ break;
+ }
+ }
+}
+
+/**
* @brief Called before dialog is shown.
* @return Always TRUE.
*/
BOOL FileFiltersDlg::OnInitDialog()
{
- theApp.TranslateDialog(m_hWnd);
- CDialog::OnInitDialog();
+ CTrPropertyPage::OnInitDialog();
InitList();
for (int i = 0; i < count; i++)
{
String desc = m_listFilters.GetItemText(i, 2);
- if (string_compare_nocase(desc, m_sFileFilterPath) == 0)
+ if (strutils::compare_nocase(desc, m_sFileFilterPath) == 0)
{
SelectFilterByIndex(i);
}
*/
void FileFiltersDlg::AddToGrid(int filterIndex)
{
- const FileFilterInfo & filterinfo = m_Filters->at(filterIndex);
+ const FileFilterInfo & filterinfo = m_Filters.at(filterIndex);
const int item = filterIndex + 1;
m_listFilters.InsertItem(item, filterinfo.name.c_str());
int sel = m_listFilters.GetNextItem(-1, LVNI_SELECTED);
m_sFileFilterPath = m_listFilters.GetItemText(sel, 2);
+ AfxGetApp()->WriteProfileInt(_T("Settings"), _T("FilterStartPage"), GetParentSheet()->GetActiveIndex());
+
CDialog::OnOK();
}
*/
void FileFiltersDlg::EditFileFilter(const String& path)
{
- theApp.OpenFileToExternalEditor(path);
+ CMergeApp::OpenFileToExternalEditor(path);
}
/**
}
/**
- * @brief Shortcut to enable or disable a control.
- * @param [in] parent Pointer to dialog.
- * @param [in] item Control's resourceID in dialog.
- * @param [in] enable TRUE if item is enabled, FALSE if disabled.
- */
-static void EnableDlgItem(CWnd * parent, int item, bool enable)
-{
- parent->GetDlgItem(item)->EnableWindow(!!enable);
-}
-
-/**
* @brief Is item in list the <None> item?
* @param [in] item Item to test.
* @return true if item is <None> item.
String txtNone = _("<None>");
String txt = m_listFilters.GetItemText(item, 0);
- return (string_compare_nocase(txt, txtNone) == 0);
+ return (strutils::compare_nocase(txt, txtNone) == 0);
}
/**
String txtNone = _("<None>");
String txt = m_listFilters.GetItemText(pNMLV->iItem, 0);
- bool isNone = string_compare_nocase(txt, txtNone) == 0;
+ bool isNone = strutils::compare_nocase(txt, txtNone) == 0;
- EnableDlgItem(this, IDC_FILTERFILE_TEST_BTN, !isNone);
- EnableDlgItem(this, IDC_FILTERFILE_EDITBTN, !isNone);
- EnableDlgItem(this, IDC_FILTERFILE_DELETEBTN, !isNone);
+ EnableDlgItem(IDC_FILTERFILE_TEST_BTN, !isNone);
+ EnableDlgItem(IDC_FILTERFILE_EDITBTN, !isNone);
+ EnableDlgItem(IDC_FILTERFILE_DELETEBTN, !isNone);
}
*pResult = 0;
}
{
LVHITTESTINFO lvhti = {0};
NMLVGETINFOTIP * pInfoTip = reinterpret_cast<NMLVGETINFOTIP*>(pNMHDR);
- ASSERT(pInfoTip);
+ ASSERT(pInfoTip != nullptr);
// Get subitem under mouse cursor
lvhti.pt = m_ptLastMousePos;
{
// Set item text to tooltip
String strText = m_listFilters.GetItemText(lvhti.iItem, lvhti.iSubItem);
- _tcscpy(pInfoTip->pszText, strText.c_str());
+ _tcscpy_s(pInfoTip->pszText, pInfoTip->cchTextMax, strText.c_str());
}
}
}
m_sFileFilterPath = m_listFilters.GetItemText(sel, 2);
// Ensure filter is up-to-date (user probably just edited it)
- theApp.m_pGlobalFileFilter->ReloadUpdatedFilters();
+ auto* pGlobalFileFilter = theApp.GetGlobalFileFilter();
+ pGlobalFileFilter->ReloadUpdatedFilters();
- FileFilterMgr *pMgr = theApp.m_pGlobalFileFilter->GetManager();
+ FileFilterMgr *pMgr = pGlobalFileFilter->GetManager();
FileFilter * pFileFilter = pMgr->GetFilterByPath(m_sFileFilterPath);
- if (!pFileFilter)
+ if (pFileFilter == nullptr)
return;
CTestFilterDlg dlg(this, pFileFilter, pMgr);
*/
void FileFiltersDlg::OnBnClickedFilterfileNewbutton()
{
- String globalPath = theApp.m_pGlobalFileFilter->GetGlobalFilterPathWithCreate();
- String userPath = theApp.m_pGlobalFileFilter->GetUserFilterPathWithCreate();
+ auto* pGlobalFileFilter = theApp.GetGlobalFileFilter();
+ String globalPath = pGlobalFileFilter->GetGlobalFilterPathWithCreate();
+ String userPath = pGlobalFileFilter->GetUserFilterPathWithCreate();
if (globalPath.empty() && userPath.empty())
{
- LangMessageBox(IDS_FILEFILTER_NO_USERFOLDER, MB_ICONSTOP);
+ AfxMessageBox(
+ _("User's filter file folder is not defined!\n\nPlease select filter folder in Options/System.").c_str(), MB_ICONSTOP);
return;
}
// Format path to template file
- String templatePath = paths_ConcatPath(globalPath, FILE_FILTER_TEMPLATE);
+ String templatePath = paths::ConcatPath(globalPath, FILE_FILTER_TEMPLATE);
- if (paths_DoesPathExist(templatePath) != IS_EXISTING_FILE)
+ if (paths::DoesPathExist(templatePath) != paths::IS_EXISTING_FILE)
{
- String msg = string_format_string2(
- _("Cannot find file filter template file!\n\nPlease copy file %1 to WinMerge/Filters -folder:\n%2."),
+ String msg = strutils::format_string2(
+ _("Cannot find file filter template file!\n\nPlease copy file %1 to WinMerge/Filters folder:\n%2."),
FILE_FILTER_TEMPLATE, templatePath);
AfxMessageBox(msg.c_str(), MB_ICONERROR);
return;
if (!globalPath.empty() && !userPath.empty())
{
- path = CSharedFilterDlg::PromptForNewFilter(this, globalPath, userPath);
- if (path.empty()) return;
+ CSharedFilterDlg dlg(
+ GetOptionsMgr()->GetBool(OPT_FILEFILTER_SHARED) ?
+ CSharedFilterDlg::SHARED : CSharedFilterDlg::PRIVATE);
+ if (dlg.DoModal() != IDOK)
+ return;
+ GetOptionsMgr()->SaveOption(OPT_FILEFILTER_SHARED, (dlg.GetSelectedFilterType() == CSharedFilterDlg::SHARED));
+ path = dlg.GetSelectedFilterType() == CSharedFilterDlg::SHARED ? globalPath : userPath;
}
if (path.length())
- path = paths_AddTrailingSlash(path);
+ path = paths::AddTrailingSlash(path);
String s;
- if (SelectFile(GetSafeHwnd(), s, path.c_str(), _("Select filename for new filter"), _("File Filters (*.flt)|*.flt|All Files (*.*)|*.*||"),
- FALSE))
+ if (SelectFile(GetSafeHwnd(), s, false, path.c_str(), _("Select filename for new filter"),
+ _("File Filters (*.flt)|*.flt|All Files (*.*)|*.*||")))
{
// Fix file extension
TCHAR file[_MAX_FNAME] = {0};
TCHAR ext[_MAX_EXT] = {0};
TCHAR dir[_MAX_DIR] = {0};
TCHAR drive[_MAX_DRIVE] = {0};
- _tsplitpath(s.c_str(), drive, dir, file, ext);
- if (_tcslen(ext) == 0)
+ _tsplitpath_s(s.c_str(), drive, _MAX_DRIVE, dir, _MAX_DIR, file, _MAX_FNAME, ext, _MAX_EXT);
+ if (ext[0] == '\0')
{
s += FileFilterExt;
}
// Open-dialog asks about overwriting, so we can overwrite filter file
// user has already allowed it.
- if (!CopyFile(templatePath.c_str(), s.c_str(), FALSE))
+ UniMemFile fileIn;
+ UniStdioFile fileOut;
+ if (!fileIn.OpenReadOnly(templatePath) || !fileOut.OpenCreate(s))
{
- String msg = string_format_string1(
+ String msg = strutils::format_string1(
_( "Cannot copy filter template file to filter folder:\n%1\n\nPlease make sure the folder exists and is writable."),
templatePath);
AfxMessageBox(msg.c_str(), MB_ICONERROR);
return;
}
+ String lines;
+ fileIn.ReadStringAll(lines);
+ strutils::replace(lines, _T("${name}"), file);
+ fileOut.WriteString(lines);
+ fileIn.Close();
+ fileOut.Close();
+
EditFileFilter(s);
- FileFilterMgr *pMgr = theApp.m_pGlobalFileFilter->GetManager();
- int retval = pMgr->AddFilter(s.c_str());
+ FileFilterMgr *pMgr = pGlobalFileFilter->GetManager();
+ int retval = pMgr->AddFilter(s);
if (retval == FILTER_OK)
{
// Remove all from filterslist and re-add so we can update UI
String selected;
- m_Filters->clear();
- theApp.m_pGlobalFileFilter->LoadAllFileFilters();
- theApp.m_pGlobalFileFilter->GetFileFilters(m_Filters, selected);
+ pGlobalFileFilter->LoadAllFileFilters();
+ m_Filters = pGlobalFileFilter->GetFileFilters(selected);
UpdateFiltersList();
+ SelectFilterByFilePath(s);
}
}
}
{
path = m_listFilters.GetItemText(sel, 2);
- String sConfirm = string_format_string1(_("Are you sure you want to delete\n\n%1 ?"), path);
+ String sConfirm = strutils::format_string1(_("Are you sure you want to delete\n\n%1 ?"), path);
int res = AfxMessageBox(sConfirm.c_str(), MB_ICONWARNING | MB_YESNO);
if (res == IDYES)
{
if (DeleteFile(path.c_str()))
{
- FileFilterMgr *pMgr = theApp.m_pGlobalFileFilter->GetManager();
+ auto* pGlobalFileFilter = theApp.GetGlobalFileFilter();
+ FileFilterMgr *pMgr = pGlobalFileFilter->GetManager();
pMgr->RemoveFilter(path);
// Remove all from filterslist and re-add so we can update UI
String selected;
- m_Filters->clear();
- theApp.m_pGlobalFileFilter->GetFileFilters(m_Filters, selected);
+ m_Filters = pGlobalFileFilter->GetFileFilters(selected);
UpdateFiltersList();
}
else
{
- String msg = string_format_string1(
+ String msg = strutils::format_string1(
_("Failed to delete the filter file:\n%1\n\nMaybe the file is read-only?"),
path);
AfxMessageBox(msg.c_str(), MB_ICONSTOP);
*/
void FileFiltersDlg::UpdateFiltersList()
{
- int count = (int) m_Filters->size();
+ int count = (int) m_Filters.size();
m_listFilters.DeleteAllItems();
*/
void FileFiltersDlg::OnBnClickedFilterfileInstall()
{
+ auto* pGlobalFileFilter = theApp.GetGlobalFileFilter();
String s;
String path;
- String userPath = theApp.m_pGlobalFileFilter->GetUserFilterPathWithCreate();
- if (SelectFile(GetSafeHwnd(), s, path.c_str(), _("Locate filter file to install"), _("File Filters (*.flt)|*.flt|All Files (*.*)|*.*||"),
- TRUE))
+ if (SelectFile(GetSafeHwnd(), s, true, path.c_str(),_("Locate filter file to install"),
+ _("File Filters (*.flt)|*.flt|All Files (*.*)|*.*||")))
{
- userPath = paths_ConcatPath(userPath, paths_FindFileName(s));
+ String userPath = pGlobalFileFilter->GetUserFilterPathWithCreate();
+ userPath = paths::ConcatPath(userPath, paths::FindFileName(s));
if (!CopyFile(s.c_str(), userPath.c_str(), TRUE))
{
// If file already exists, ask from user
// If user wants to, overwrite existing filter
- if (paths_DoesPathExist(userPath) == IS_EXISTING_FILE)
+ if (paths::DoesPathExist(userPath) == paths::IS_EXISTING_FILE)
{
int res = LangMessageBox(IDS_FILEFILTER_OVERWRITE, MB_YESNO |
MB_ICONWARNING);
}
else
{
- FileFilterMgr *pMgr = theApp.m_pGlobalFileFilter->GetManager();
- pMgr->AddFilter(userPath.c_str());
+ FileFilterMgr *pMgr = pGlobalFileFilter->GetManager();
+ pMgr->AddFilter(userPath);
// Remove all from filterslist and re-add so we can update UI
String selected;
- m_Filters->clear();
- theApp.m_pGlobalFileFilter->GetFileFilters(m_Filters, selected);
+ m_Filters = pGlobalFileFilter->GetFileFilters(selected);
UpdateFiltersList();
+ SelectFilterByFilePath(userPath);
}
}
}