OSDN Git Service

crystaledit: Use GetProfile*()/WriteProfile*() to read and write the registry wheneve...
[winmerge-jp/winmerge-jp.git] / Src / FilepathEdit.cpp
index 2e862c5..10c19c1 100644 (file)
@@ -2,29 +2,13 @@
 //    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  FilePathEdit.cpp
  *
  * @brief Implementation of the CFilepathEdit class.
  */
-// ID line follows -- this is updated by SVN
-// $Id: FilepathEdit.cpp 6500 2009-02-25 13:36:26Z kimmov $
 
 #include "stdafx.h"
 #include "FilepathEdit.h"
 #include "ClipBoard.h"
 #include "Shlwapi.h"
 #include "paths.h"
-#include <algorithm>
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
 #endif
 
-static int FormatFilePathForDisplayWidth(CDC * pDC, int maxWidth, CString & sFilepath);
+static int FormatFilePathForDisplayWidth(CDC * pDC, int maxWidth, String & sFilepath);
 
 BEGIN_MESSAGE_MAP(CFilepathEdit, CEdit)
        ON_WM_CONTEXTMENU()
        ON_WM_CTLCOLOR_REFLECT()
+       ON_WM_NCPAINT()
+       ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
 END_MESSAGE_MAP()
 
 
@@ -62,21 +45,21 @@ END_MESSAGE_MAP()
  * - out: formatted string
  * @return Number of lines path is splitted to.
  */
-int FormatFilePathForDisplayWidth(CDC * pDC, int maxWidth, String & sFilepath)
+static int FormatFilePathForDisplayWidth(CDC * pDC, int maxWidth, String & sFilepath)
 {
-       int iBegin = 0;
+       size_t iBegin = 0;
        int nLines = 1;
        
-       while (1)
+       while (true)
        {
                String line;
 
                // find the next truncation point
-               int iEndMin = 0;
-               int iEndMax = sFilepath.length() - iBegin + 1;
+               size_t iEndMin = 0;
+               size_t iEndMax = sFilepath.length() - iBegin + 1;
                while(1)
                {
-                       int iEnd = (iEndMin + iEndMax) / 2;
+                       size_t iEnd = (iEndMin + iEndMax) / 2;
                        if (iEnd == iEndMin)
                                break;
                        line = sFilepath.substr(iBegin, iEnd);
@@ -96,7 +79,7 @@ int FormatFilePathForDisplayWidth(CDC * pDC, int maxWidth, String & sFilepath)
 
                // truncate the text to the previous "\" if possible
                line = sFilepath.substr(iBegin, iEndMin);
-               int lastSlash = line.rfind('\\');
+               size_t lastSlash = line.rfind('\\');
                if (lastSlash != String::npos)
                        iEndMin = lastSlash + 1;
 
@@ -115,7 +98,7 @@ int FormatFilePathForDisplayWidth(CDC * pDC, int maxWidth, String & sFilepath)
 CFilepathEdit::CFilepathEdit()
  : m_crBackGnd(RGB(255, 255, 255))
  , m_crText(RGB(0,0,0))
- , m_bActive(FALSE)
+ , m_bActive(false)
 {
 }
 
@@ -123,24 +106,15 @@ CFilepathEdit::CFilepathEdit()
  * @brief Subclass the control.
  * @param [in] nID ID of the control to subclass.
  * @param [in] pParent Parent control of the control to subclass.
- * @return TRUE if succeeded, FALSE otherwise.
+ * @return `true` if succeeded, `false` otherwise.
  */
-BOOL CFilepathEdit::SubClassEdit(UINT nID, CWnd* pParent)
+bool CFilepathEdit::SubClassEdit(UINT nID, CWnd* pParent)
 {
-       m_bActive = FALSE;
+       m_bActive = false;
        return SubclassDlgItem(nID, pParent);
 };
 
 /**
- * @brief Return the control's original text.
- * @return Control's original text.
- */
-void CFilepathEdit::GetOriginalText(String& rString) const
-{              
-       rString = m_sOriginalText;
-}
-
-/**
  * @brief Set the text to show in the control.
  * This function sets the text (original text) to show in the control.
  * The control may modify the text for displaying in the GUI.
@@ -186,7 +160,7 @@ void CFilepathEdit::RefreshDisplayText()
        CRect rect;
        GetRect(rect);
        // take GetBuffer (lenght +3) to count for ellipsis
-       std::vector<TCHAR> tmp(line.length() + 3);
+       std::vector<TCHAR> tmp(line.length() + 4);
        std::copy(line.begin(), line.end(), tmp.begin());
        PathCompactPath(lDC.GetSafeHdc(), &tmp[0],      rect.Width());
        line = &tmp[0];
@@ -224,9 +198,9 @@ const String& CFilepathEdit::GetUpdatedTipText(CDC * pDC, int maxWidth)
  *
  * @note The standard Copy function works with the (compacted) windowText 
  */
-void CFilepathEdit::CustomCopy(int iBegin, int iEnd /*=-1*/)
+void CFilepathEdit::CustomCopy(size_t iBegin, size_t iEnd /*=-1*/)
 {
-       if (iEnd == -1)
+       if (iEnd == String::npos)
                iEnd = m_sOriginalText.length();
 
        PutToClipboard(m_sOriginalText.substr(iBegin, iEnd - iBegin), m_hWnd);
@@ -253,12 +227,12 @@ void CFilepathEdit::OnContextMenu(CWnd*, CPoint point)
                theApp.TranslateMenu(menu.m_hMenu);
 
                BCMenu* pPopup = static_cast<BCMenu *>(menu.GetSubMenu(0));
-               ASSERT(pPopup != NULL);
+               ASSERT(pPopup != nullptr);
 
                DWORD sel = GetSel();
                if (HIWORD(sel) == LOWORD(sel))
                        pPopup->EnableMenuItem(ID_EDITOR_COPY, MF_GRAYED);
-               if (paths_EndsWithSlash(m_sOriginalText))
+               if (paths::EndsWithSlash(m_sOriginalText))
                        // no filename, we have to disable the unwanted menu entry
                        pPopup->EnableMenuItem(ID_EDITOR_COPY_FILENAME, MF_GRAYED);
 
@@ -270,7 +244,7 @@ void CFilepathEdit::OnContextMenu(CWnd*, CPoint point)
                        TPM_NONOTIFY  | TPM_RETURNCMD, point.x, point.y, AfxGetMainWnd());
 
                // compute the beginning of the text to copy (in OriginalText)
-               int iBegin = 0;
+               size_t iBegin = 0;
                switch (command)
                {
                case ID_EDITOR_COPY:
@@ -302,18 +276,62 @@ void CFilepathEdit::OnContextMenu(CWnd*, CPoint point)
        }
 }
 
+static COLORREF GetDarkenColor(COLORREF a, double r)
+{
+       const int R = static_cast<int>(GetRValue(a) * r);
+       const int G = static_cast<int>(GetGValue(a) * r);
+       const int B = static_cast<int>(GetBValue(a) * r);
+       return RGB(R, G, B);
+}
+
+void CFilepathEdit::OnNcPaint()
+{
+       CWindowDC dc(this);
+       CRect rect;
+       const int margin = 4;
+       GetWindowRect(rect);
+       rect.OffsetRect(-rect.TopLeft());
+       dc.FillSolidRect(CRect(rect.left, rect.top, rect.left + margin, rect.bottom), GetDarkenColor(m_crBackGnd, 0.98));
+       dc.FillSolidRect(CRect(rect.left, rect.top, rect.left + 1, rect.bottom), GetDarkenColor(m_crBackGnd, 0.96));
+       dc.FillSolidRect(CRect(rect.right - margin, rect.top, rect.right, rect.bottom), m_crBackGnd);
+       dc.FillSolidRect(CRect(rect.left + 1, rect.top, rect.right, rect.top + margin), GetDarkenColor(m_crBackGnd, 0.98));
+       dc.FillSolidRect(CRect(rect.left, rect.top, rect.right, rect.top + 1), GetDarkenColor(m_crBackGnd, 0.96));
+       dc.FillSolidRect(CRect(rect.left + margin, rect.bottom - margin, rect.right, rect.bottom), m_crBackGnd);
+}
+
+void CFilepathEdit::OnEditCopy()
+{
+       int nStartChar, nEndChar;
+       GetSel(nStartChar, nEndChar);
+       if (nStartChar == nEndChar)
+               SetSel(0, -1);
+       Copy();
+       if (nStartChar == nEndChar)
+               SetSel(nStartChar, nEndChar);
+}
+
+BOOL CFilepathEdit::PreTranslateMessage(MSG *pMsg)
+{
+       if (pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
+       {
+               if (::TranslateAccelerator (m_hWnd, static_cast<CFrameWnd *>(AfxGetMainWnd())->GetDefaultAccelerator(), pMsg))
+                       return TRUE;
+       }
+       return CEdit::PreTranslateMessage(pMsg);
+}
+
 /**
  * @brief Set the control to look active/inactive.
  * This function sets control to look like an active control. We don't
  * have real focus on this control, but editor pane below it. However
  * for user this active look informs which editor pane is active.
- * @param [in] bActive If TRUE set control look like active control.
+ * @param [in] bActive If `true` set control look like active control.
  */
 void CFilepathEdit::SetActive(bool bActive)
 {
        m_bActive = bActive;
 
-       if (m_hWnd == NULL)
+       if (m_hWnd == nullptr)
                return;
 
        CRect rcWnd;
@@ -329,6 +347,7 @@ void CFilepathEdit::SetActive(bool bActive)
                SetTextColor(::GetSysColor(COLOR_INACTIVECAPTIONTEXT));
                SetBackColor(::GetSysColor(COLOR_INACTIVECAPTION));
        }
+       RedrawWindow(nullptr, nullptr, RDW_FRAME | RDW_INVALIDATE);
 }
 
 /**
@@ -342,7 +361,7 @@ void CFilepathEdit::SetActive(bool bActive)
 HBRUSH CFilepathEdit::CtlColor(CDC* pDC, UINT nCtlColor) 
 {
        UNUSED_ALWAYS(nCtlColor);
-       // Return a non-NULL brush if the parent's 
+       // Return a non-`nullptr` brush if the parent's 
        //handler should not be called
 
        //set text color