libyui-ncurses  2.57.2
NCTableSort.cc
1 /*
2  Copyright (C) 2020 SUSE LLC
3  This library is free software; you can redistribute it and/or modify
4  it under the terms of the GNU Lesser General Public License as
5  published by the Free Software Foundation; either version 2.1 of the
6  License, or (at your option) version 3.0 of the License. This library
7  is distributed in the hope that it will be useful, but WITHOUT ANY
8  WARRANTY; without even the implied warranty of MERCHANTABILITY or
9  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10  License for more details. You should have received a copy of the GNU
11  Lesser General Public License along with this library; if not, write
12  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
13  Floor, Boston, MA 02110-1301 USA
14 */
15 
16 
17 #define YUILogComponent "ncurses"
18 #include <yui/YUILog.h>
19 #include <yui/YTableItem.h>
20 
21 #include "NCTableSort.h"
22 #include "NCTable.h"
23 
24 
25 /**
26  * Support classes for sorting by column in a table for use in an NCTablePad
27  **/
28 
29 void
30 NCTableSortDefault::sort( YItemIterator begin, YItemIterator end )
31 {
32  // yuiMilestone() << "Sorting by col #" << sortCol()
33  // << " reverse: " << std::boolalpha << reverse() << endl;
34 
35  std::stable_sort( begin, end,
36  Compare( sortCol(), reverse() ) );
37 }
38 
39 
40 bool
41 NCTableSortDefault::Compare::operator() ( YItem * item1,
42  YItem * item2 ) const
43 {
44  std::wstring w1 = smartSortKey( item1 );
45  std::wstring w2 = smartSortKey( item2 );
46 
47  bool ok1, ok2;
48  long long number1 = toNumber( w1, &ok1 );
49  long long number2 = toNumber( w2, &ok2 );
50 
51  if ( ok1 && ok2 )
52  {
53  // Both are numbers
54  return !_reverse ? number1 < number2 : number1 > number2;
55  }
56  else if ( ok1 && !ok2 )
57  {
58  // int < string
59  return true;
60  }
61  else if ( !ok1 && ok2 )
62  {
63  // string > int
64  return false;
65  }
66  else
67  {
68  // compare strings using collating information
69  int result = std::wcscoll( w1.c_str(), w2.c_str() );
70 
71  return !_reverse ? result < 0 : result > 0;
72  }
73 }
74 
75 
76 long long
77 NCTableSortDefault::Compare::toNumber( const std::wstring & str, bool * ok ) const
78 {
79  try
80  {
81  *ok = true;
82  return std::stoll( str );
83  }
84  catch (...)
85  {
86  *ok = false;
87  return 0;
88  }
89 }
90 
91 
92 std::wstring
93 NCTableSortDefault::Compare::smartSortKey( YItem * item ) const
94 {
95  std::wstring empty;
96 
97  if ( ! item )
98  return empty;
99 
100  YTableItem * tableItem = dynamic_cast<YTableItem *>( item );
101 
102  if ( ! tableItem )
103  return empty;
104 
105  YTableCell * tableCell = tableItem->cell( _sortCol );
106 
107  if ( ! tableCell )
108  return empty;
109 
110  NCstring result;
111 
112  if ( tableCell->hasSortKey() )
113  result = NCstring( tableCell->sortKey() );
114  else
115  result = NCstring( tableCell->label() );
116 
117  return result.str();
118 }
119 
NCstring
A string with an optional hot key.
Definition: NCstring.h:36
NCTableSortDefault::sort
virtual void sort(YItemIterator begin, YItemIterator end) override
Support classes for sorting by column in a table for use in an NCTablePad.
Definition: NCTableSort.cc:30