Ticket #2978: natsort-2978.patch

File natsort-2978.patch, 9.5 KB (added by Marcu, 6 years ago)
  • src/interface/LocalListView.cpp

     
    2121#include "filelist_statusbar.h"
    2222#include "sizeformatting.h"
    2323#include "timeformatting.h"
     24#include "natsortalg.h"
    2425
    2526#ifdef _DEBUG
    2627#define new DEBUG_NEW
     
    811812
    812813    virtual bool operator()(int a, int b) const = 0;
    813814
    814     #define CMP(f, data1, data2) \
    815         {\
    816             int res = f(data1, data2);\
    817             if (res == -1)\
    818                 return true;\
    819             else if (res == 1)\
    820                 return false;\
    821         }
     815   
    822816
    823     #define CMP_LESS(f, data1, data2) \
    824         {\
    825             int res = f(data1, data2);\
    826             if (res == -1)\
    827                 return true;\
    828             else\
    829                 return false;\
    830         }
    831 
    832817    inline int CmpDir(const CLocalFileData &data1, const CLocalFileData &data2) const
    833818    {
    834819        switch (m_dirSortMode)
     
    871856
    872857    inline int CmpName(const CLocalFileData &data1, const CLocalFileData &data2) const
    873858    {
    874 #ifdef __WXMSW__
    875         return data1.name.CmpNoCase(data2.name);
    876 #else
    877         return data1.name.Cmp(data2.name);
    878 #endif
     859        return NaturalSort(data1.name, data2.name);
    879860    }
    880861
    881862    inline int CmpSize(const CLocalFileData &data1, const CLocalFileData &data2) const
  • src/interface/LocalTreeView.cpp

     
    2020#include "volume_enumerator.h"
    2121#endif
    2222
     23#include "natsortalg.h"
     24
    2325class CTreeItemData : public wxTreeItemData
    2426{
    2527public:
     
    702704
    703705static bool sortfunc(const wxString& a, const wxString& b)
    704706{
    705 #ifdef __WXMSW__
    706     return b.CmpNoCase(a) > 0;
    707 #else
    708     return b.Cmp(a) > 0;
    709 #endif
     707    return NaturalSort(a, b)<0;
    710708}
    711709
    712710void CLocalTreeView::Refresh()
     
    908906
    909907int CLocalTreeView::OnCompareItems(const wxTreeItemId& item1, const wxTreeItemId& item2)
    910908{
    911     wxString label1 = GetItemText(item1);
    912     wxString label2 = GetItemText(item2);
    913 #ifdef __WXMSW__
    914     return label1.CmpNoCase(label2);
    915 #else
    916     return label1.Cmp(label2);
    917 #endif
     909    return NaturalSort(GetItemText(item1), GetItemText(item2));
    918910}
    919911
    920912void CLocalTreeView::OnStateChange(CState* pState, enum t_statechange_notifications notification, const wxString& data, const void* data2)
  • src/interface/Makefile.am

     
    2020        buildinfo.cpp \
    2121        chmoddialog.cpp \
    2222        clearprivatedata.cpp \
     23        natsortalg.cpp \
    2324        cmdline.cpp \
    2425        commandqueue.cpp \
    2526        conditionaldialog.cpp \
     
    131132         buildinfo.h \
    132133         chmoddialog.h \
    133134         clearprivatedata.h \
     135         natsortalg.h \
    134136         cmdline.h \
    135137         commandqueue.h \
    136138         conditionaldialog.h \
  • src/interface/natsortalg.cpp

     
     1#include "natsortalg.h"
     2
     3#ifdef __WXMSW__
     4bool WinSorter::instanceFlag = false;
     5WinSorter* WinSorter::single = NULL;
     6HMODULE WinSorter::shlwapiDLL = NULL;
     7PFN_StrCmpLogicalW WinSorter::StrCmpLogicalW = NULL;
     8
     9
     10WinSorter* WinSorter::getInstance()
     11{
     12    if(! instanceFlag)
     13    {
     14        single = new WinSorter();
     15        instanceFlag = true;
     16        return single;
     17    }
     18    else
     19    {
     20        return single;
     21    }
     22}
     23
     24int WinSorter::sort(const wxString& a, const wxString& b)
     25{
     26    if(StrCmpLogicalW != NULL)
     27        return StrCmpLogicalW( a.wc_str(), b.wc_str());
     28    else
     29        return a.CmpNoCase(b);
     30}
     31#endif
     32
     33int NaturalSort(const wxString& left, const wxString& right)
     34{
     35    int compare = 0;
     36
     37#ifdef __WXMSW__
     38
     39    compare = WinSorter::getInstance()->sort(left,right);
     40
     41#else
     42
     43    bool sort_last_1, sort_last_2;
     44    sort_last_1 = left[0] == SORT_LAST_CHAR1 || left[0] == SORT_LAST_CHAR2;
     45    sort_last_2 = right[0] == SORT_LAST_CHAR1 || right[0] == SORT_LAST_CHAR2;
     46
     47    if (sort_last_1 && !sort_last_2)
     48    {
     49        compare = +1;
     50    }
     51    else if (!sort_last_1 && sort_last_2)
     52    {
     53        compare = -1;
     54    }
     55    else
     56    {
     57        char* left_collation_key = g_utf8_collate_key_for_filename (left.mb_str(), -1);
     58        char* right_collation_key = g_utf8_collate_key_for_filename (right.mb_str(), -1);
     59        if(left_collation_key != NULL && right_collation_key != NULL)
     60        {
     61            compare = strcmp(left_collation_key, right_collation_key);
     62            g_free(left_collation_key);
     63            g_free(right_collation_key);
     64        }
     65        else
     66        {
     67            compare = left.Cmp(right);
     68        }
     69    }
     70#endif
     71
     72    return compare;
     73}
  • src/interface/natsortalg.h

     
     1#ifndef __NATSORTALG_H__
     2#define __NATSORTALG_H__
     3
     4#include <wx/string.h>
     5
     6#ifdef __WXMSW__
     7#include "shlwapi.h"
     8#else
     9#include <glib.h>
     10#endif
     11
     12/* On Linux, files that start with these characters sort after files that don't. */
     13#define SORT_LAST_CHAR1 '.'
     14#define SORT_LAST_CHAR2 '#'
     15
     16#define CMP(f, data1, data2) \
     17        {\
     18        int res = f(data1, data2);\
     19        if (res < 0)\
     20        return true;\
     21            else if (res > 0)\
     22            return false;\
     23        }
     24
     25#define CMP_LESS(f, data1, data2) \
     26        {\
     27        int res = f(data1, data2);\
     28        if (res < 0)\
     29        return true;\
     30            else\
     31            return false;\
     32        }
     33
     34#ifdef __WXMSW__
     35typedef int (* PFN_StrCmpLogicalW)(LPCWSTR,LPCWSTR);
     36class WinSorter
     37{
     38private:
     39    static bool instanceFlag;
     40    static HMODULE shlwapiDLL;
     41    static PFN_StrCmpLogicalW StrCmpLogicalW;
     42   
     43
     44    static WinSorter *single;
     45    WinSorter()
     46    {
     47        shlwapiDLL = LoadLibrary(L"shlwapi.dll");
     48        if ( shlwapiDLL )
     49            StrCmpLogicalW = (PFN_StrCmpLogicalW) GetProcAddress(shlwapiDLL, "StrCmpLogicalW");
     50    }
     51public:
     52    static WinSorter* getInstance();
     53    int sort( const wxString& a, const wxString& b );
     54    ~WinSorter()
     55    {
     56        instanceFlag = false;
     57        if(shlwapiDLL)
     58            FreeLibrary( shlwapiDLL );
     59    }
     60};
     61#endif
     62
     63int NaturalSort(const wxString& left, const wxString& right);
     64
     65
     66#endif //__NATSORTALG_H__
  • src/interface/RemoteListView.cpp

     
    2424#include "commctrl.h"
    2525#endif
    2626
     27#include "natsortalg.h"
     28
    2729#ifdef _DEBUG
    2830#define new DEBUG_NEW
    2931#endif
     
    906908    {
    907909    }
    908910
    909     #define CMP(f, data1, data2) \
    910         {\
    911             int res = f(data1, data2);\
    912             if (res == -1)\
    913                 return true;\
    914             else if (res == 1)\
    915                 return false;\
    916         }
    917 
    918     #define CMP_LESS(f, data1, data2) \
    919         {\
    920             int res = f(data1, data2);\
    921             if (res == -1)\
    922                 return true;\
    923             else\
    924                 return false;\
    925         }
    926 
    927911    inline int CmpDir(const CDirentry &data1, const CDirentry &data2) const
    928912    {
    929913        switch (m_dirSortMode)
     
    966950
    967951    inline int CmpName(const CDirentry &data1, const CDirentry &data2) const
    968952    {
    969 #ifdef __WXMSW__
    970         return data1.name.CmpNoCase(data2.name);
    971 #else
    972         return data1.name.Cmp(data2.name);
    973 #endif
     953        return NaturalSort(data1.name, data2.name);
    974954    }
    975955
    976956    inline int CmpSize(const CDirentry &data1, const CDirentry &data2) const
  • src/interface/RemoteTreeView.cpp

     
    1111#include "queue.h"
    1212#include "QueueView.h"
    1313#include "themeprovider.h"
     14#include "natsortalg.h"
    1415
    1516#ifdef _DEBUG
    1617#define new DEBUG_NEW
     
    557558
    558559static bool sortfunc(const wxString& a, const wxString& b)
    559560{
    560     int cmp = a.CmpNoCase(b);
    561 
    562     if (!cmp)
    563         cmp = a.Cmp(b);
    564 
    565     return cmp < 0;
     561    return NaturalSort(a, b)<0;
    566562}
    567563
    568 
    569564void CRemoteTreeView::RefreshItem(wxTreeItemId parent, const CDirectoryListing& listing, bool will_select_parent)
    570565{
    571566    SetItemImages(parent, false);
     
    699694
    700695int CRemoteTreeView::OnCompareItems(const wxTreeItemId& item1, const wxTreeItemId& item2)
    701696{
    702     wxString label1 = GetItemText(item1);
    703     wxString label2 = GetItemText(item2);
    704 
    705     int cmp = label1.CmpNoCase(label2);
    706     if (cmp)
    707         return cmp;
    708     return label1.Cmp(label2);
     697    return NaturalSort(GetItemText(item1), GetItemText(item2))<0;
    709698}
    710699
    711700void CRemoteTreeView::OnItemExpanding(wxTreeEvent& event)
  • src/interface/search.cpp

     
    1212#include "sizeformatting.h"
    1313#include "timeformatting.h"
    1414#include "window_state_manager.h"
     15#include "natsortalg.h"
    1516
    1617class CSearchFileData : public CGenericFileData
    1718{
     
    6869    {
    6970    }
    7071
    71     #define CMP(f, data1, data2) \
    72         {\
    73             int res = f(data1, data2);\
    74             if (res == -1)\
    75                 return true;\
    76             else if (res == 1)\
    77                 return false;\
    78         }
    79 
    80     #define CMP_LESS(f, data1, data2) \
    81         {\
    82             int res = f(data1, data2);\
    83             if (res == -1)\
    84                 return true;\
    85             else\
    86                 return false;\
    87         }
    88 
    8972    inline int CmpDir(const CDirentry &data1, const CDirentry &data2) const
    9073    {
    9174        switch (m_dirSortMode)
     
    128111
    129112    inline int CmpName(const CDirentry &data1, const CDirentry &data2) const
    130113    {
    131 #ifdef __WXMSW__
    132         return data1.name.CmpNoCase(data2.name);
    133 #else
    134         return data1.name.Cmp(data2.name);
    135 #endif
     114        return NaturalSort(data1.name, data2.name);
    136115    }
    137116
    138117    inline int CmpSize(const CDirentry &data1, const CDirentry &data2) const