OSDN Git Service

Merge with stable
[winmerge-jp/winmerge-jp.git] / Src / EditorFilepathBar.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 //    WinMerge:  an interactive diff/merge utility
3 //    Copyright (C) 1997-2000  Thingamahoochie Software
4 //    Author: Dean Grimm
5 //
6 //    This program is free software; you can redistribute it and/or modify
7 //    it under the terms of the GNU General Public License as published by
8 //    the Free Software Foundation; either version 2 of the License, or
9 //    (at your option) any later version.
10 //
11 //    This program is distributed in the hope that it will be useful,
12 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //    GNU General Public License for more details.
15 //
16 //    You should have received a copy of the GNU General Public License
17 //    along with this program; if not, write to the Free Software
18 //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 //
20 /////////////////////////////////////////////////////////////////////////////
21 /** 
22  * @file  DiffList.cpp
23  *
24  * @brief Implementation file for CEditorFilepathBar class
25  */
26
27 #include "stdafx.h"
28 #include "EditorFilepathBar.h"
29
30 #ifdef _DEBUG
31 #define new DEBUG_NEW
32 #undef THIS_FILE
33 static char THIS_FILE[] = __FILE__;
34 #endif
35
36
37 BEGIN_MESSAGE_MAP(CEditorFilePathBar, CDialogBar)
38         ON_NOTIFY_EX (TTN_NEEDTEXT, 0, OnToolTipNotify)
39 END_MESSAGE_MAP()
40
41
42 /**
43  * @brief Constructor.
44  */
45 CEditorFilePathBar::CEditorFilePathBar()
46 : m_pFont(nullptr), m_nPanes(2)
47 {
48 }
49
50 /**
51  * @brief Destructor.
52  */
53 CEditorFilePathBar::~CEditorFilePathBar()
54 {
55 }
56
57 /**
58  * @brief Create the window.
59  * This function subclasses the edit controls.
60  * @param [in] pParentWnd Parent window for edit controls.
61  * @return TRUE if succeeded, FALSE otherwise.
62  */
63 BOOL CEditorFilePathBar::Create(CWnd* pParentWnd)
64 {
65         if (! CDialogBar::Create(pParentWnd, CEditorFilePathBar::IDD, 
66                         CBRS_TOP | CBRS_TOOLTIPS | CBRS_FLYBY, CEditorFilePathBar::IDD))
67                 return FALSE;
68
69         // subclass the two custom edit boxes
70         for (int pane = 0; pane < countof(m_Edit); pane++)
71                 m_Edit[pane].SubClassEdit(IDC_STATIC_TITLE_PANE0 + pane, this);
72
73         return TRUE;
74 };
75
76 void CEditorFilePathBar::SetPaneCount(int nPanes)
77 {
78         m_nPanes = nPanes;
79 }
80
81 /**
82  * @brief Set look of headerbars similar to other window.
83  *
84  * @param [in] pWnd Pointer to window we want to imitate
85  * @return TRUE if parent must recompute layout
86  */
87 BOOL CEditorFilePathBar::LookLikeThisWnd(const CWnd * pWnd)
88 {
89         // Update font. Note that we must delete previous font
90         // before creating a new one.
91         CFont * pFont = pWnd->GetFont();
92         if (pFont)
93         {
94                 m_pFont.reset(new CFont);
95                 if (m_pFont != NULL)
96                 {
97                         LOGFONT lfFont = {0};
98                         if (pFont->GetLogFont(&lfFont))
99                         {
100                                 m_pFont->CreateFontIndirect(&lfFont);
101                                 for (int pane = 0; pane < m_nPanes; pane++)
102                                 {
103                                         m_Edit[pane].SetFont(m_pFont.get());
104                                         m_Edit[pane].SetMargins(4, 4);
105                                 }
106                         }
107                 }
108         }
109
110         // Set same dimensions (than window we imitate)
111         CRect rectNew;
112         pWnd->GetWindowRect(rectNew);
113         CRect rectCurrent;
114         GetWindowRect(rectCurrent);
115         if (rectNew != rectCurrent)
116         {
117                 SetWindowPos(NULL,0,0,rectNew.Width(), rectNew.Height(),
118                         SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE);     
119                 return TRUE;
120         }
121         return FALSE;
122 }
123
124 /** 
125  * @brief Resize both controls to an equal size.
126  */
127 void CEditorFilePathBar::Resize()
128 {
129         if (m_hWnd == NULL)
130                 return;
131
132         WINDOWPLACEMENT infoBar;
133         GetWindowPlacement(&infoBar);
134
135         int widths[3];
136         for (int pane = 0; pane < m_nPanes; pane++)
137                 widths[pane] = (infoBar.rcNormalPosition.right / m_nPanes) - 6;
138         Resize(widths);
139 }
140 /** 
141  * @brief Set widths.
142  * This function resizes both controls to given size. The width is usually
143  * same as the splitter view width.
144  * @param [in] leftWidth Left-side control width.
145  * @param [in] rightWidth Right-side control width.
146  */
147 void CEditorFilePathBar::Resize(int widths[])
148 {
149         if (m_hWnd == NULL)
150                 return;
151
152         // resize left filename
153         CRect rc;
154         int x = 0;
155         GetClientRect(&rc);
156         for (int pane = 0; pane < m_nPanes; pane++)
157         {
158                 CRect rcOld;
159                 m_Edit[pane].GetClientRect(&rcOld);
160                 rc.left = x;
161                 rc.right = x + widths[pane] + 4;
162                 x += widths[pane] + 7;
163                 if (rcOld.Width() != rc.Width())
164                 {
165                         m_Edit[pane].MoveWindow(&rc);
166                         m_Edit[pane].RefreshDisplayText();
167                 }
168         }
169 }
170
171 /**
172  * @brief Called when tooltip is about to be shown.
173  * In this function we set the tooltip text shown.
174  */
175 BOOL CEditorFilePathBar::OnToolTipNotify(UINT id, NMHDR * pTTTStruct, LRESULT * pResult)
176 {
177         if (m_hWnd == NULL)
178                 return FALSE;
179
180         TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pTTTStruct;
181         if (pTTT->uFlags & TTF_IDISHWND)
182         {
183                 // idFrom is actually the HWND of the CEdit 
184                 int nID = ::GetDlgCtrlID((HWND)pTTTStruct->idFrom);
185                 if(nID == IDC_STATIC_TITLE_PANE0 || nID == IDC_STATIC_TITLE_PANE1 || nID == IDC_STATIC_TITLE_PANE2)
186                 {
187                         // compute max width : 97% of application width or 80% or full screen width
188                         CRect rect;
189                         GetWindowRect(rect);
190                         int maxWidth = (int)(rect.Width() * .97);
191                         CRect rectScreen; 
192                         SystemParametersInfo(SPI_GETWORKAREA, 0, rectScreen, 0);
193                         if (rectScreen.Width() * .8 > maxWidth)
194                                 maxWidth = (int)(rectScreen.Width() * .8);
195
196                         // use the tooltip font
197                         HANDLE hFont = (HANDLE) ::SendMessage(pTTTStruct->hwndFrom, WM_GETFONT, 0, 0);
198                         CClientDC tempDC(this);
199                         HANDLE hOldFont = ::SelectObject(tempDC.GetSafeHdc(),hFont);
200
201                         // fill in the returned structure
202                         CFilepathEdit * pItem = static_cast<CFilepathEdit*>(GetDlgItem(nID));
203                         pTTT->lpszText = const_cast<TCHAR *>(pItem->GetUpdatedTipText(&tempDC, maxWidth).c_str());
204
205                         // set old font back
206                         if (hOldFont)
207                                 ::SelectObject(tempDC.GetSafeHdc(),hOldFont);
208
209                         // we must set TTM_SETMAXTIPWIDTH to use \n in tooltips
210                         // just to do the first time, but how to access the tooltip during init ?
211                         ::SendMessage(pTTTStruct->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 5000);
212
213                         return(TRUE);
214                 }
215         }
216         return(FALSE);
217 }
218
219 /** 
220  * @brief Set the path for one side
221  *
222  * @param [in] pane Index (0-based) of pane to update.
223  * @param [in] lpszString New text for pane.
224  */
225 void CEditorFilePathBar::SetText(int pane, const String& sString)
226 {
227         ASSERT (pane >= 0 && pane < countof(m_Edit));
228
229         // Check for NULL since window may be closing..
230         if (m_hWnd == NULL)
231                 return;
232
233         m_Edit[pane].SetOriginalText(sString);
234 }
235
236 /** 
237  * @brief Set the active status for one status (change the appearance)
238  *
239  * @param [in] pane Index (0-based) of pane to update.
240  * @param [in] bActive If TRUE activates pane, FALSE deactivates.
241  */
242 void CEditorFilePathBar::SetActive(int pane, bool bActive)
243 {
244         ASSERT (pane >= 0 && pane < countof(m_Edit));
245
246         // Check for NULL since window may be closing..
247         if (m_hWnd == NULL)
248                 return;
249
250         m_Edit[pane].SetActive(bActive);
251 }