1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
3  * http://www.gnu.org/licenses/lgpl-3.0.html
4  *
5  * $Revision: 10635 $
6  * $Id: cbtreectrl.cpp 10635 2015-12-29 16:30:36Z fuscated $
7  * $HeadURL: svn://svn.code.sf.net/p/codeblocks/code/branches/release-20.xx/src/sdk/cbtreectrl.cpp $
8  */
9 
10 #include "sdk_precomp.h"
11 
12 #ifndef CB_PRECOMP
13     #include <wx/event.h>
14     #include <wx/filename.h>
15     #include <wx/gdicmn.h> // wxPoint
16     #include <wx/string.h>
17     #include <wx/treebase.h> // wxTreeItemId
18 
19     #include "cbproject.h" // FileTreeData
20     #include "projectfile.h"
21 #endif
22 
IMPLEMENT_DYNAMIC_CLASS(cbTreeCtrl,wxTreeCtrl)23 IMPLEMENT_DYNAMIC_CLASS(cbTreeCtrl, wxTreeCtrl)
24 
25 BEGIN_EVENT_TABLE(cbTreeCtrl, wxTreeCtrl)
26 #ifndef __WXMSW__
27     EVT_RIGHT_DOWN(cbTreeCtrl::OnRightClick)
28 #endif // !__WXMSW__
29     EVT_KEY_DOWN(cbTreeCtrl::OnKeyDown)
30 END_EVENT_TABLE()
31 
32 cbTreeCtrl::cbTreeCtrl() : wxTreeCtrl()
33 {
34     Compare = &filesSort;
35 }
36 
cbTreeCtrl(wxWindow * parent,int id)37 cbTreeCtrl::cbTreeCtrl(wxWindow* parent, int id) :
38     wxTreeCtrl(parent, id, wxDefaultPosition, wxDefaultSize,
39                wxTR_EDIT_LABELS | wxTR_HAS_BUTTONS | wxTR_MULTIPLE | wxBORDER_NONE)
40 {
41     Compare = &filesSort;
42 }
43 
SetCompareFunction(const int ptvs)44 void cbTreeCtrl::SetCompareFunction(const int ptvs)
45 {
46     // sort list of files
47     if ( !(ptvs & ptvsUseFolders) && (ptvs & ptvsHideFolderName) )
48         Compare = &filesSortNameOnly;
49     else
50         Compare = &filesSort;
51 }
52 
GetPrevVisible(const wxTreeItemId & item) const53 wxTreeItemId cbTreeCtrl::GetPrevVisible(const wxTreeItemId& item) const
54 {
55     wxTreeItemId previous = GetPrevSibling(item);
56     if (previous.IsOk())
57     {
58         while (ItemHasChildren(previous) && IsExpanded(previous))
59         {
60             wxTreeItemId child = GetLastChild(previous);
61             if (!child.IsOk())
62                 break;
63             else
64                 previous = child;
65         }
66     }
67     else
68         previous = GetItemParent(item);
69     return previous;
70 }
71 
72 #ifndef __WXMSW__
73 /*
74     Under wxGTK, wxTreeCtrl is not sending an EVT_COMMAND_RIGHT_CLICK
75     event when right-clicking on the client area.
76 */
OnRightClick(wxMouseEvent & event)77 void cbTreeCtrl::OnRightClick(wxMouseEvent& event)
78 {
79     int flags;
80     HitTest(wxPoint(event.GetX(), event.GetY()), flags);
81     if (flags & (wxTREE_HITTEST_ABOVE | wxTREE_HITTEST_BELOW | wxTREE_HITTEST_NOWHERE))
82     {
83         // "proxy" the call
84         wxCommandEvent e(wxEVT_COMMAND_RIGHT_CLICK, GetID());
85         wxPostEvent(GetParent(), e);
86     }
87     else
88         event.Skip();
89 }
90 #endif // !__WXMSW__
91 /*
92     Under all platforms there is no reaction when pressing "ENTER".
93     Expected would be e.g. to open the file in an editor.
94 */
OnKeyDown(wxKeyEvent & event)95 void cbTreeCtrl::OnKeyDown(wxKeyEvent& event)
96 {
97     // Don't care about special key combinations
98     if (event.GetModifiers()!=wxMOD_NONE)
99     {
100         event.Skip();
101         return;
102     }
103 
104     wxArrayTreeItemIds selections;
105     // Don't care if no selection has been made
106     if ( GetSelections(selections)<1 )
107     {
108         event.Skip();
109         return;
110     }
111 
112     long         keycode = event.GetKeyCode();
113     wxTreeItemId itemId  = selections[0];
114     // Don't care if item is invalid
115     if ( !itemId.IsOk() )
116     {
117         event.Skip();
118         return;
119     }
120 
121     switch (keycode)
122     {
123         case WXK_RETURN:
124         case WXK_NUMPAD_ENTER:
125         {
126             wxTreeEvent te = wxTreeEvent(wxEVT_COMMAND_TREE_ITEM_ACTIVATED, this, itemId);
127             wxPostEvent(this, te);
128             break;
129         }
130         default:
131             event.Skip();
132     }
133 }
134 
filesSort(const ProjectFile * arg1,const ProjectFile * arg2)135 /*static*/ int cbTreeCtrl::filesSort(const ProjectFile* arg1, const ProjectFile* arg2)
136 {
137     if (arg1 && arg2)
138         return wxStricmp(arg1->file.GetFullPath(), arg2->file.GetFullPath());
139     return 0;
140 }
141 
filesSortNameOnly(const ProjectFile * arg1,const ProjectFile * arg2)142 /*static*/ int cbTreeCtrl::filesSortNameOnly(const ProjectFile* arg1, const ProjectFile* arg2)
143 {
144     if (arg1 && arg2)
145         return wxStricmp(arg1->file.GetFullName(), arg2->file.GetFullName());
146     return 0;
147 }
148 
OnCompareItems(const wxTreeItemId & item1,const wxTreeItemId & item2)149 int cbTreeCtrl::OnCompareItems(const wxTreeItemId& item1, const wxTreeItemId& item2)
150 {
151     return Compare(((FileTreeData*)GetItemData(item1))->GetProjectFile(), ((FileTreeData*)GetItemData(item2))->GetProjectFile());
152 }
153