@@ -83,7 +83,10 @@ public HashSet<int> Start(ApplicationData applicationData)
8383 return selectedIndexes ;
8484 }
8585
86- foreach ( GridViewRow gvr in _itemSource . GridViewRowList )
86+ // Ensure that only items that are marked AND not filtered out
87+ // get returned (See Issue #121)
88+ List < GridViewRow > itemList = GridViewHelpers . FilterData ( _itemSource . GridViewRowList , _filterField . Text . ToString ( ) ) ;
89+ foreach ( GridViewRow gvr in itemList )
8790 {
8891 if ( gvr . IsMarked )
8992 {
@@ -122,7 +125,8 @@ private GridViewDataSource LoadData()
122125 return new GridViewDataSource ( items ) ;
123126 }
124127
125- private void ApplyFilter ( ) {
128+ private void ApplyFilter ( )
129+ {
126130 List < GridViewRow > itemList = GridViewHelpers . FilterData ( _itemSource . GridViewRowList , _applicationData . Filter ?? string . Empty ) ;
127131 // Set the ListView to show only the subset defined by the filter
128132 _listView . Source = new GridViewDataSource ( itemList ) ;
@@ -151,50 +155,72 @@ private Window CreateTopLevelWindow()
151155 Width = Dim . Fill ( _applicationData . MinUI ? - 1 : 0 ) ,
152156 Height = Dim . Fill ( _applicationData . MinUI ? - 1 : 1 )
153157 } ;
154-
155- if ( _applicationData . MinUI ) {
158+
159+ if ( _applicationData . MinUI )
160+ {
156161 win . Border . BorderStyle = BorderStyle . None ;
157- }
158-
162+ }
163+
159164 Application . Top . Add ( win ) ;
160165 return win ;
161166 }
162167
163168 private void AddStatusBar ( bool visible )
164169 {
165- var statusBar = new StatusBar (
166- _applicationData . OutputMode != OutputModeOption . None
167- ? new StatusItem [ ]
170+ var statusItems = new List < StatusItem > ( ) ;
171+ if ( _applicationData . OutputMode != OutputModeOption . None )
172+ {
173+ // Use Key.Unknown for SPACE with no delegate because ListView already
174+ // handles SPACE
175+ statusItems . Add ( new StatusItem ( Key . Unknown , "~SPACE~ Select Item" , null ) ) ;
176+ }
177+
178+ if ( _applicationData . OutputMode == OutputModeOption . Multiple )
179+ {
180+ statusItems . Add ( new StatusItem ( Key . A | Key . CtrlMask , "~CTRL-A~ Select All" , ( ) =>
181+ {
182+ // This selects only the items that match the Filter
183+ var gvds = _listView . Source as GridViewDataSource ;
184+ gvds . GridViewRowList . ForEach ( i => i . IsMarked = true ) ;
185+ _listView . SetNeedsDisplay ( ) ;
186+ } ) ) ;
187+
188+ // Ctrl-D is commonly used in GUIs for select-none
189+ statusItems . Add ( new StatusItem ( Key . D | Key . CtrlMask , "~CTRL-D~ Select None" , ( ) =>
190+ {
191+ // This un-selects only the items that match the Filter
192+ var gvds = _listView . Source as GridViewDataSource ;
193+ gvds . GridViewRowList . ForEach ( i => i . IsMarked = false ) ;
194+ _listView . SetNeedsDisplay ( ) ;
195+ } ) ) ;
196+ }
197+
198+ if ( _applicationData . OutputMode != OutputModeOption . None )
199+ {
200+ statusItems . Add ( new StatusItem ( Key . Enter , "~ENTER~ Accept" , ( ) =>
201+ {
202+ if ( Application . Top . MostFocused == _listView )
168203 {
169- // Use Key.Unknown for SPACE with no delegate because ListView already
170- // handles SPACE
171- new StatusItem ( Key . Unknown , "~SPACE~ Mark Item" , null ) ,
172- new StatusItem ( Key . Enter , "~ENTER~ Accept" , ( ) =>
204+ // If nothing was explicitly marked, we return the item that was selected
205+ // when ENTER is pressed in Single mode. If something was previously selected
206+ // (using SPACE) then honor that as the single item to return
207+ if ( _applicationData . OutputMode == OutputModeOption . Single &&
208+ _itemSource . GridViewRowList . Find ( i => i . IsMarked ) == null )
173209 {
174- if ( Application . Top . MostFocused == _listView )
175- {
176- // If nothing was explicitly marked, we return the item that was selected
177- // when ENTER is pressed in Single mode. If something was previously selected
178- // (using SPACE) then honor that as the single item to return
179- if ( _applicationData . OutputMode == OutputModeOption . Single &&
180- _itemSource . GridViewRowList . Find ( i => i . IsMarked ) == null )
181- {
182- _listView . MarkUnmarkRow ( ) ;
183- }
184- Accept ( ) ;
185- }
186- else if ( Application . Top . MostFocused == _filterField )
187- {
188- _listView . SetFocus ( ) ;
189- }
190- } ) ,
191- new StatusItem ( Key . Esc , "~ESC~ Close" , ( ) => Close ( ) )
210+ _listView . MarkUnmarkRow ( ) ;
211+ }
212+ Accept ( ) ;
192213 }
193- : new StatusItem [ ]
214+ else if ( Application . Top . MostFocused == _filterField )
194215 {
195- new StatusItem ( Key . Esc , "~ESC~ Close" , ( ) => Close ( ) )
216+ _listView . SetFocus ( ) ;
196217 }
197- ) ;
218+ } ) ) ;
219+ }
220+
221+ statusItems . Add ( new StatusItem ( Key . Esc , "~ESC~ Close" , ( ) => Close ( ) ) ) ;
222+
223+ var statusBar = new StatusBar ( statusItems . ToArray ( ) ) ;
198224 statusBar . Visible = visible ;
199225 Application . Top . Add ( statusBar ) ;
200226 }
@@ -222,7 +248,6 @@ private void CalculateColumnWidths(List<string> gridHeaders)
222248 {
223249 listViewColumnWidths [ index ] = len ;
224250 }
225-
226251 index ++ ;
227252 }
228253 }
@@ -264,6 +289,13 @@ private void AddFilter(Window win)
264289 Width = Dim . Fill ( ) - _filterLabel . Text . Length
265290 } ;
266291
292+ // TextField captures Ctrl-A (select all text) and Ctrl-D (delete backwards)
293+ // In OCGV these are used for select-all/none of items. Selecting items is more
294+ // common than editing the filter field so we turn them off in the filter textview.
295+ // BACKSPACE still works for delete backwards
296+ _filterField . ClearKeybinding ( Key . A | Key . CtrlMask ) ;
297+ _filterField . ClearKeybinding ( Key . D | Key . CtrlMask ) ;
298+
267299 var filterErrorLabel = new Label ( string . Empty )
268300 {
269301 X = Pos . Right ( _filterLabel ) + 1 ,
@@ -329,7 +361,8 @@ private void AddHeaders(Window win, List<string> gridHeaders)
329361 }
330362 }
331363
332- if ( ! _applicationData . MinUI ) {
364+ if ( ! _applicationData . MinUI )
365+ {
333366 var headerLine = new Label ( headerLineText . ToString ( ) )
334367 {
335368 X = 0 ,
@@ -346,7 +379,7 @@ private void AddListView(Window win)
346379 if ( ! _applicationData . MinUI )
347380 {
348381 _listView . Y = Pos . Bottom ( _filterLabel ) + 3 ; // 1 for space, 1 for header, 1 for header underline
349- }
382+ }
350383 else
351384 {
352385 _listView . Y = 1 ; // 1 for space, 1 for header, 1 for header underline
0 commit comments