4 // Tree control used for the survey tree.
6 // Copyright (C) 2001, Mark R. Shinwell.
7 // Copyright (C) 2001-2003,2005,2006,2016,2018 Olly Betts
8 // Copyright (C) 2005 Martin Green
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "aventreectrl.h"
32 enum { STATE_NONE
= 0, STATE_VISIBLE
};
35 static const char *none_xpm
[] = {
36 /* columns rows colors chars-per-pixel */
58 static const char *visible_xpm
[] = {
59 /* columns rows colors chars-per-pixel */
81 BEGIN_EVENT_TABLE(AvenTreeCtrl
, wxTreeCtrl
)
82 EVT_MOTION(AvenTreeCtrl::OnMouseMove
)
83 EVT_LEAVE_WINDOW(AvenTreeCtrl::OnLeaveWindow
)
84 EVT_TREE_SEL_CHANGED(-1, AvenTreeCtrl::OnSelChanged
)
85 EVT_TREE_ITEM_ACTIVATED(-1, AvenTreeCtrl::OnItemActivated
)
86 EVT_CHAR(AvenTreeCtrl::OnKeyPress
)
87 EVT_TREE_ITEM_MENU(-1, AvenTreeCtrl::OnMenu
)
88 EVT_MENU(menu_SURVEY_SHOW_ALL
, AvenTreeCtrl::OnRestrict
)
89 EVT_MENU(menu_SURVEY_RESTRICT
, AvenTreeCtrl::OnRestrict
)
90 EVT_MENU(menu_SURVEY_HIDE
, AvenTreeCtrl::OnHide
)
91 EVT_MENU(menu_SURVEY_SHOW
, AvenTreeCtrl::OnShow
)
92 EVT_MENU(menu_SURVEY_HIDE_SIBLINGS
, AvenTreeCtrl::OnHideSiblings
)
93 EVT_TREE_STATE_IMAGE_CLICK(-1, AvenTreeCtrl::OnStateClick
)
96 AvenTreeCtrl::AvenTreeCtrl(MainFrm
* parent
, wxWindow
* window_parent
) :
97 wxTreeCtrl(window_parent
, -1),
101 m_BackgroundColour(),
105 wxImageList
* img_list
= new wxImageList(15, 15, 2);
106 img_list
->Add(wxBitmap(none_xpm
));
107 img_list
->Add(wxBitmap(visible_xpm
));
108 AssignStateImageList(img_list
);
111 #define TREE_MASK (wxTREE_HITTEST_ONITEMLABEL | wxTREE_HITTEST_ONITEMRIGHT)
113 void AvenTreeCtrl::OnMouseMove(wxMouseEvent
& event
)
115 if (m_Enabled
&& !m_Parent
->Animating()) {
117 wxTreeItemId pos
= HitTest(event
.GetPosition(), flags
);
118 if (!(flags
& TREE_MASK
)) {
119 pos
= wxTreeItemId();
121 if (pos
== m_LastItem
) return;
123 m_Parent
->DisplayTreeInfo(GetItemData(pos
));
125 m_Parent
->DisplayTreeInfo();
130 void AvenTreeCtrl::SetHere(wxTreeItemId pos
)
132 if (pos
== m_LastItem
) return;
134 if (m_LastItem
.IsOk()) {
135 SetItemBackgroundColour(m_LastItem
, m_BackgroundColour
);
138 m_BackgroundColour
= GetItemBackgroundColour(pos
);
139 SetItemBackgroundColour(pos
, wxColour(180, 180, 180));
144 void AvenTreeCtrl::OnLeaveWindow(wxMouseEvent
&)
146 if (m_LastItem
.IsOk()) {
147 SetItemBackgroundColour(m_LastItem
, m_BackgroundColour
);
148 m_LastItem
= wxTreeItemId();
150 m_Parent
->DisplayTreeInfo();
153 void AvenTreeCtrl::SetEnabled(bool enabled
)
158 void AvenTreeCtrl::OnSelChanged(wxTreeEvent
& e
)
163 void AvenTreeCtrl::OnItemActivated(wxTreeEvent
& e
)
165 if (!m_Enabled
) return;
167 m_Parent
->TreeItemSelected(GetItemData(e
.GetItem()));
170 void AvenTreeCtrl::OnMenu(wxTreeEvent
& e
)
173 const TreeData
* data
= static_cast<const TreeData
*>(GetItemData(e
.GetItem()));
175 menu_item
= e
.GetItem();
179 /* TRANSLATORS: In aven's survey tree, right-clicking on the root
180 * gives a pop-up menu and this is an option (but only enabled if
181 * the view is restricted to a subsurvey). It reloads the current
182 * survey file with the who survey visible.
184 menu
.Append(menu_SURVEY_SHOW_ALL
, wmsg(/*Show all*/245));
185 if (m_Parent
->GetSurvey().empty())
186 menu
.Enable(menu_SURVEY_SHOW_ALL
, false);
188 } else if (data
->GetLabel()) {
189 // Station: name is data->GetLabel()->GetText()
193 /* TRANSLATORS: In aven's survey tree, right-clicking on a survey
194 * name gives a pop-up menu and this is an option. It reloads the
195 * current survey file with the view restricted to the survey
198 menu
.Append(menu_SURVEY_RESTRICT
, wmsg(/*Hide others*/246));
199 menu
.AppendSeparator();
200 menu
.Append(menu_SURVEY_HIDE
, wmsg(/*&Hide*/407));
201 menu
.Append(menu_SURVEY_SHOW
, wmsg(/*&Show*/409));
202 menu
.Append(menu_SURVEY_HIDE_SIBLINGS
, wmsg(/*Hide si&blings*/388));
203 switch (GetItemState(menu_item
)) {
204 case STATE_VISIBLE
: // Currently shown.
205 menu
.Enable(menu_SURVEY_SHOW
, false);
208 case STATE_HIDDEN
: // Currently hidden.
209 menu
.Enable(menu_SURVEY_RESTRICT
, false);
210 menu
.Enable(menu_SURVEY_HIDE
, false);
211 menu
.Enable(menu_SURVEY_HIDE_SIBLINGS
, false);
215 menu
.Enable(menu_SURVEY_HIDE
, false);
216 menu
.Enable(menu_SURVEY_HIDE_SIBLINGS
, false);
226 bool AvenTreeCtrl::GetSelectionData(wxTreeItemData
** data
) const
235 wxTreeItemId id
= GetSelection();
237 *data
= GetItemData(id
);
240 return id
.IsOk() && *data
;
243 void AvenTreeCtrl::UnselectAll()
246 wxTreeCtrl::UnselectAll();
249 void AvenTreeCtrl::DeleteAllItems()
252 m_LastItem
= wxTreeItemId();
254 wxTreeCtrl::DeleteAllItems();
256 filter
.SetSeparator(m_Parent
->GetSeparator());
259 void AvenTreeCtrl::OnKeyPress(wxKeyEvent
&e
)
261 switch (e
.GetKeyCode()) {
263 m_Parent
->ClearTreeSelection();
266 wxTreeItemId id
= GetSelection();
268 if (ItemHasChildren(id
)) {
269 // If on a branch, expand/contract it.
270 if (IsExpanded(id
)) {
276 // If on a station, centre on it by selecting it twice.
277 m_Parent
->TreeItemSelected(GetItemData(id
));
278 m_Parent
->TreeItemSelected(GetItemData(id
));
283 case WXK_LEFT
: case WXK_RIGHT
: case WXK_UP
: case WXK_DOWN
:
284 case WXK_HOME
: case WXK_END
: case WXK_PAGEUP
: case WXK_PAGEDOWN
:
288 // Pass key event to MainFrm which will pass to GfxCore which will
289 // pass to GUIControl.
290 m_Parent
->OnKeyPress(e
);
295 void AvenTreeCtrl::OnRestrict(wxCommandEvent
& e
)
297 m_Parent
->RestrictTo(menu_data
? menu_data
->GetSurvey() : wxString());
300 void AvenTreeCtrl::OnHide(wxCommandEvent
& e
)
302 // Shouldn't be available for the root item.
304 // Hide should be disabled unless the item is explicitly shown.
305 wxASSERT(GetItemState(menu_item
) == STATE_VISIBLE
);
306 SetItemState(menu_item
, STATE_NONE
);
307 filter
.remove(menu_data
->GetSurvey());
310 // Show siblings if not already shown or hidden.
311 wxTreeItemId i
= menu_item
;
312 while ((i
= GetPrevSibling(i
)).IsOk()) {
313 if (GetItemState(i
) == wxTREE_ITEMSTATE_NONE
)
317 while ((i
= GetNextSibling(i
)).IsOk()) {
318 if (GetItemState(i
) == wxTREE_ITEMSTATE_NONE
)
323 m_Parent
->ForceFullRedraw();
326 void AvenTreeCtrl::OnShow(wxCommandEvent
& e
)
328 // Shouldn't be available for the root item.
330 // Show should be disabled for an explicitly shown item.
331 wxASSERT(GetItemState(menu_item
) != STATE_VISIBLE
);
333 SetItemState(menu_item
, STATE_VISIBLE
);
334 filter
.add(menu_data
->GetSurvey());
335 // Hide siblings if not already shown or hidden.
336 wxTreeItemId i
= menu_item
;
337 while ((i
= GetPrevSibling(i
)).IsOk()) {
338 if (GetItemState(i
) == wxTREE_ITEMSTATE_NONE
)
339 SetItemState(i
, STATE_NONE
);
342 while ((i
= GetNextSibling(i
)).IsOk()) {
343 if (GetItemState(i
) == wxTREE_ITEMSTATE_NONE
)
344 SetItemState(i
, STATE_NONE
);
347 m_Parent
->ForceFullRedraw();
350 void AvenTreeCtrl::OnHideSiblings(wxCommandEvent
& e
)
352 // Shouldn't be available for the root item.
355 SetItemState(menu_item
, STATE_VISIBLE
);
356 filter
.add(menu_data
->GetSurvey());
358 wxTreeItemId i
= menu_item
;
359 while ((i
= GetPrevSibling(i
)).IsOk()) {
360 const TreeData
* data
= static_cast<const TreeData
*>(GetItemData(i
));
361 filter
.remove(data
->GetSurvey());
362 SetItemState(i
, STATE_NONE
);
365 while ((i
= GetNextSibling(i
)).IsOk()) {
366 const TreeData
* data
= static_cast<const TreeData
*>(GetItemData(i
));
367 filter
.remove(data
->GetSurvey());
368 SetItemState(i
, STATE_NONE
);
371 m_Parent
->ForceFullRedraw();
374 void AvenTreeCtrl::OnStateClick(wxTreeEvent
& e
)
376 auto item
= e
.GetItem();
377 const TreeData
* data
= static_cast<const TreeData
*>(GetItemData(item
));
378 if (GetItemState(item
) == STATE_VISIBLE
) {
379 filter
.remove(data
->GetSurvey());
380 SetItemState(item
, STATE_NONE
);
382 filter
.add(data
->GetSurvey());
383 SetItemState(item
, STATE_VISIBLE
);
386 m_Parent
->ForceFullRedraw();