1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <wx/dataview.h>
21 #include <wxdataviewctrl_helpers.h>
22 
GetPrevItem(wxDataViewCtrl const & aView,wxDataViewItem const & aItem)23 wxDataViewItem GetPrevItem( wxDataViewCtrl const& aView, wxDataViewItem const& aItem )
24 {
25     auto prevItem = GetPrevSibling( aView, aItem );
26 
27     if( !prevItem.IsOk() )
28     {
29         prevItem = aView.GetModel()->GetParent( aItem );
30     }
31     else if( aView.IsExpanded( prevItem ) )
32     {
33         wxDataViewItemArray children;
34         aView.GetModel()->GetChildren( prevItem, children );
35         prevItem = children[children.size() - 1];
36     }
37 
38     return prevItem;
39 }
40 
41 
GetNextItem(wxDataViewCtrl const & aView,wxDataViewItem const & aItem)42 wxDataViewItem GetNextItem( wxDataViewCtrl const& aView, wxDataViewItem const& aItem )
43 {
44     wxDataViewItem nextItem;
45     wxDataViewItem invalid;
46 
47     if( !aItem.IsOk() )
48     {
49         // No selection. Select the first.
50         wxDataViewItemArray children;
51         aView.GetModel()->GetChildren( aItem, children );
52 
53         if( children.size() )
54             return children[0];
55 
56         return invalid;
57     }
58 
59     if( aView.IsExpanded( aItem ) )
60     {
61         wxDataViewItemArray children;
62         aView.GetModel()->GetChildren( aItem, children );
63 
64         if( children.size() )
65             return children[0];
66 
67         return invalid;
68     }
69     else
70     {
71         // Walk up levels until we find one that has a next sibling.
72         for( wxDataViewItem walk = aItem; walk.IsOk(); walk = aView.GetModel()->GetParent( walk ) )
73         {
74             nextItem = GetNextSibling( aView, walk );
75 
76             if( nextItem.IsOk() )
77                 break;
78         }
79     }
80 
81     return nextItem;
82 }
83 
84 
GetPrevSibling(wxDataViewCtrl const & aView,wxDataViewItem const & aItem)85 wxDataViewItem GetPrevSibling( wxDataViewCtrl const& aView, wxDataViewItem const& aItem )
86 {
87     wxDataViewItemArray siblings;
88     wxDataViewItem      invalid;
89     wxDataViewItem      parent = aView.GetModel()->GetParent( aItem );
90 
91     aView.GetModel()->GetChildren( parent, siblings );
92 
93     for( size_t i = 0; i < siblings.size(); ++i )
94     {
95         if( siblings[i] == aItem )
96         {
97             if( i == 0 )
98                 return invalid;
99             else
100                 return siblings[i - 1];
101         }
102     }
103 
104     return invalid;
105 }
106 
107 
GetNextSibling(wxDataViewCtrl const & aView,wxDataViewItem const & aItem)108 wxDataViewItem GetNextSibling( wxDataViewCtrl const& aView, wxDataViewItem const& aItem )
109 {
110     wxDataViewItemArray siblings;
111     wxDataViewItem      invalid;
112     wxDataViewItem      parent = aView.GetModel()->GetParent( aItem );
113 
114     aView.GetModel()->GetChildren( parent, siblings );
115 
116     for( size_t i = 0; i < siblings.size(); ++i )
117     {
118         if( siblings[i] == aItem )
119         {
120             if( i == siblings.size() - 1 )
121                 return invalid;
122             else
123                 return siblings[i + 1];
124         }
125     }
126 
127     return invalid;
128 }
129