Skip to content

Commit fd07389

Browse files
committed
Added find by the correct sort method
1 parent 9fba7c3 commit fd07389

File tree

3 files changed

+73
-43
lines changed

3 files changed

+73
-43
lines changed

src/fheroes2/dialog/dialog_selectfile.cpp

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,26 @@ namespace
115115
textInput.drawInRoi( field.x + 4 + ( maxFileNameWidth - textInput.width() ) / 2, field.y + 4, output, field );
116116
}
117117

118+
struct CompareByTimestamp
119+
{
120+
bool operator()( const Maps::FileInfo & info, uint32_t timestamp ) const
121+
{
122+
return info.timestamp > timestamp;
123+
}
124+
bool operator()( uint32_t timestamp, const Maps::FileInfo & info ) const
125+
{
126+
return timestamp > info.timestamp;
127+
}
128+
};
129+
130+
struct CompareByFilename
131+
{
132+
bool operator()( const Maps::FileInfo & info, const std::string & filename ) const
133+
{
134+
return Maps::CaseInsensitiveCompare( info.filename, filename );
135+
}
136+
};
137+
118138
class FileInfoListBox : public Interface::ListBox<Maps::FileInfo>
119139
{
120140
public:
@@ -341,16 +361,16 @@ namespace
341361
if ( !lastfile.empty() ) {
342362
filename = System::GetStem( lastfile );
343363
charInsertPos = filename.size();
344-
345-
MapsFileInfoList::iterator it = lists.begin();
346-
for ( ; it != lists.end(); ++it ) {
347-
if ( it->filename == lastfile ) {
348-
break;
349-
}
364+
MapsFileInfoList::const_iterator it;
365+
if ( settings.GetSaveFileSortingMethod() == SaveFileSortingMethod::FILENAME ) {
366+
it = std::lower_bound( lists.cbegin(), lists.cend(), lastfile, CompareByFilename() );
367+
}
368+
else {
369+
it = std::find_if( it, lists.cend(), [&lastfile]( const Maps::FileInfo & info ) { return info.filename == lastfile; } );
350370
}
351371

352-
if ( it != lists.end() ) {
353-
listbox.SetCurrent( std::distance( lists.begin(), it ) );
372+
if ( it != lists.cend() ) {
373+
listbox.SetCurrent( std::distance( lists.cbegin(), it ) );
354374
}
355375
else {
356376
if ( !isEditing ) {
@@ -485,22 +505,32 @@ namespace
485505
}
486506
else if ( le.MouseClickLeft( buttonSort.area() ) ) {
487507
const int currentId = listbox.getCurrentId();
508+
std::string lastChoice{};
509+
uint32_t lastChoiceTimestamp{};
510+
if ( currentId >= 0 && static_cast<size_t>( currentId ) < lists.size() ) {
511+
lastChoice = lists[currentId].filename;
512+
lastChoiceTimestamp = lists[currentId].timestamp;
513+
}
488514

489515
settings.changeSaveFileSortingMethod();
490516
sortMapInfos( lists );
491517
listUpdated = true;
492518

493519
// re-select the last selected file if any, unless we're typing in the list box
494-
if ( !filename.empty() && !isListboxSelected ) {
495-
const std::string lastChoice = System::concatPath( Game::GetSaveDir(), filename + Game::GetSaveFileExtension() );
496-
520+
if ( !lastChoice.empty() ) {
497521
MapsFileInfoList::const_iterator it = lists.cbegin();
498-
for ( ; it != lists.end(); ++it ) {
499-
if ( it->filename == lastChoice ) {
500-
break;
501-
}
522+
MapsFileInfoList::const_iterator end = lists.cend();
523+
const SaveFileSortingMethod sortingMethod = settings.GetSaveFileSortingMethod();
524+
525+
if ( sortingMethod == SaveFileSortingMethod::TIMESTAMP ) {
526+
std::tie( it, end ) = std::equal_range( lists.cbegin(), lists.cend(), lastChoiceTimestamp, CompareByTimestamp() );
527+
it = std::find_if( it, end, [&lastChoice]( const Maps::FileInfo & info ) { return info.filename == lastChoice; } );
502528
}
503-
if ( it != lists.cend() ) {
529+
else {
530+
it = std::lower_bound( lists.cbegin(), lists.cend(), lastChoice, CompareByFilename() );
531+
}
532+
533+
if ( it != end ) {
504534
const int newId = static_cast<int>( std::distance( lists.cbegin(), it ) );
505535
if ( newId != currentId ) {
506536
listbox.SetCurrent( newId );

src/fheroes2/maps/maps_fileinfo.cpp

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
#include <cstring>
2929
#include <functional>
3030
#include <list>
31-
#include <locale>
3231
#include <map>
3332
#include <sstream>
3433
#include <type_traits>
@@ -59,32 +58,6 @@ namespace
5958
const size_t mapNameLength = 16;
6059
const size_t mapDescriptionLength = 200;
6160

62-
template <typename CharType>
63-
bool CaseInsensitiveCompare( const std::basic_string<CharType> & lhs, const std::basic_string<CharType> & rhs )
64-
{
65-
typename std::basic_string<CharType>::const_iterator li = lhs.begin();
66-
typename std::basic_string<CharType>::const_iterator ri = rhs.begin();
67-
68-
while ( li != lhs.end() && ri != rhs.end() ) {
69-
const CharType lc = std::tolower( *li, std::locale() );
70-
const CharType rc = std::tolower( *ri, std::locale() );
71-
72-
++li;
73-
++ri;
74-
75-
if ( lc < rc ) {
76-
return true;
77-
}
78-
if ( lc > rc ) {
79-
return false;
80-
}
81-
// the chars are "equal", so proceed to check the next pair
82-
}
83-
84-
// we came to the end of either (or both) strings, left is "smaller" if it was shorter:
85-
return li == lhs.end() && ri != rhs.end();
86-
}
87-
8861
// This function returns an unsorted array. It is a caller responsibility to take care of sorting if needed.
8962
MapsFileInfoList getValidMaps( const ListFiles & mapFiles, const uint8_t humanPlayerCount, const bool isForEditor, const bool isOriginalMapFormat )
9063
{

src/fheroes2/maps/maps_fileinfo.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <algorithm>
2727
#include <array>
2828
#include <cstdint>
29+
#include <locale>
2930
#include <optional>
3031
#include <string>
3132
#include <type_traits>
@@ -234,6 +235,32 @@ namespace Maps
234235

235236
OStreamBase & operator<<( OStreamBase & stream, const FileInfo & fi );
236237
IStreamBase & operator>>( IStreamBase & stream, FileInfo & fi );
238+
239+
template <typename CharType>
240+
bool CaseInsensitiveCompare( const std::basic_string<CharType> & lhs, const std::basic_string<CharType> & rhs )
241+
{
242+
typename std::basic_string<CharType>::const_iterator li = lhs.begin();
243+
typename std::basic_string<CharType>::const_iterator ri = rhs.begin();
244+
245+
while ( li != lhs.end() && ri != rhs.end() ) {
246+
const CharType lc = std::tolower( *li, std::locale() );
247+
const CharType rc = std::tolower( *ri, std::locale() );
248+
249+
++li;
250+
++ri;
251+
252+
if ( lc < rc ) {
253+
return true;
254+
}
255+
if ( lc > rc ) {
256+
return false;
257+
}
258+
// the chars are "equal", so proceed to check the next pair
259+
}
260+
261+
// we came to the end of either (or both) strings, left is "smaller" if it was shorter:
262+
return li == lhs.end() && ri != rhs.end();
263+
}
237264
}
238265

239266
using MapsFileInfoList = std::vector<Maps::FileInfo>;

0 commit comments

Comments
 (0)