Skip to content

Commit 36f350c

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

File tree

3 files changed

+74
-43
lines changed

3 files changed

+74
-43
lines changed

src/fheroes2/dialog/dialog_selectfile.cpp

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <memory>
3232
#include <sstream>
3333
#include <string>
34+
#include <tuple>
3435
#include <utility>
3536
#include <vector>
3637

@@ -115,6 +116,26 @@ namespace
115116
textInput.drawInRoi( field.x + 4 + ( maxFileNameWidth - textInput.width() ) / 2, field.y + 4, output, field );
116117
}
117118

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

352-
if ( it != lists.end() ) {
353-
listbox.SetCurrent( std::distance( lists.begin(), it ) );
373+
if ( it != lists.cend() ) {
374+
listbox.SetCurrent( std::distance( lists.cbegin(), it ) );
354375
}
355376
else {
356377
if ( !isEditing ) {
@@ -485,22 +506,32 @@ namespace
485506
}
486507
else if ( le.MouseClickLeft( buttonSort.area() ) ) {
487508
const int currentId = listbox.getCurrentId();
509+
std::string lastChoice{};
510+
uint32_t lastChoiceTimestamp{};
511+
if ( currentId >= 0 && static_cast<size_t>( currentId ) < lists.size() ) {
512+
lastChoice = lists[currentId].filename;
513+
lastChoiceTimestamp = lists[currentId].timestamp;
514+
}
488515

489516
settings.changeSaveFileSortingMethod();
490517
sortMapInfos( lists );
491518
listUpdated = true;
492519

493520
// 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-
521+
if ( !lastChoice.empty() ) {
497522
MapsFileInfoList::const_iterator it = lists.cbegin();
498-
for ( ; it != lists.end(); ++it ) {
499-
if ( it->filename == lastChoice ) {
500-
break;
501-
}
523+
MapsFileInfoList::const_iterator end = lists.cend();
524+
const SaveFileSortingMethod sortingMethod = settings.GetSaveFileSortingMethod();
525+
526+
if ( sortingMethod == SaveFileSortingMethod::TIMESTAMP ) {
527+
std::tie( it, end ) = std::equal_range( lists.cbegin(), lists.cend(), lastChoiceTimestamp, CompareByTimestamp() );
528+
it = std::find_if( it, end, [&lastChoice]( const Maps::FileInfo & info ) { return info.filename == lastChoice; } );
502529
}
503-
if ( it != lists.cend() ) {
530+
else {
531+
it = std::lower_bound( lists.cbegin(), lists.cend(), lastChoice, CompareByFilename() );
532+
}
533+
534+
if ( it != end ) {
504535
const int newId = static_cast<int>( std::distance( lists.cbegin(), it ) );
505536
if ( newId != currentId ) {
506537
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)