From d4e06b76962198eb64e6c2826d4695248102037c Mon Sep 17 00:00:00 2001 From: Vincent Reher Date: Sat, 5 Mar 2022 15:14:32 -0800 Subject: [PATCH] Replace listview's binary "Case Insensitive Sort" option with 3 mutually exclusive options: 1. Unicode based (AB...ab) 2. Unicode based, case insensitive (aAbB) 2. Locale based This resolves issue #252. Signed-off-by: Vincent Reher --- konqueror/listview/konq_detailedlistview.rc | 10 +-- konqueror/listview/konq_infolistview.rc | 10 +-- konqueror/listview/konq_listview.cpp | 71 +++++++++++++++++++-- konqueror/listview/konq_listview.h | 8 +++ konqueror/listview/konq_listviewitems.cpp | 10 +-- konqueror/listview/konq_listviewwidget.cpp | 12 +--- konqueror/listview/konq_listviewwidget.h | 3 +- konqueror/listview/konq_textview.rc | 10 +-- konqueror/listview/konq_treeview.rc | 10 +-- libkonq/CMakeLists.txt | 1 + libkonq/Makefile.am | 3 +- libkonq/konq_propsview.cpp | 27 +++++++- libkonq/konq_propsview.h | 5 ++ libkonq/konq_sort_constants.h | 13 ++++ libkonq/konq_string_compare.h | 51 +++++++++++++++ 15 files changed, 204 insertions(+), 40 deletions(-) create mode 100644 libkonq/konq_sort_constants.h create mode 100644 libkonq/konq_string_compare.h diff --git a/konqueror/listview/konq_detailedlistview.rc b/konqueror/listview/konq_detailedlistview.rc index 79059c6d4..06c9bc318 100644 --- a/konqueror/listview/konq_detailedlistview.rc +++ b/konqueror/listview/konq_detailedlistview.rc @@ -1,5 +1,5 @@ - + &Edit Selection @@ -24,12 +24,14 @@ - Sort + &Sort + + + + - - diff --git a/konqueror/listview/konq_infolistview.rc b/konqueror/listview/konq_infolistview.rc index 451eb5785..60f511b1f 100644 --- a/konqueror/listview/konq_infolistview.rc +++ b/konqueror/listview/konq_infolistview.rc @@ -1,5 +1,5 @@ - + &Edit Selection @@ -24,12 +24,14 @@ - Sort + &Sort + + + + - - diff --git a/konqueror/listview/konq_listview.cpp b/konqueror/listview/konq_listview.cpp index f8307e84c..5a06068ca 100644 --- a/konqueror/listview/konq_listview.cpp +++ b/konqueror/listview/konq_listview.cpp @@ -48,6 +48,8 @@ #include #include +#include + KonqListViewFactory::KonqListViewFactory() { s_instance = 0; @@ -929,19 +931,50 @@ void KonqListView::setupActions() m_paShowDot = new TDEToggleAction( i18n( "Show &Hidden Files" ), 0, this, TQT_SLOT( slotShowDot() ), actionCollection(), "show_dot" ); // m_paShowDot->setCheckedState(i18n("Hide &Hidden Files")); + m_paCaseInsensitive = new TDEToggleAction(i18n("Case Insensitive Sort"), 0, this, TQT_SLOT(slotCaseInsensitive()),actionCollection(), "sort_caseinsensitive" ); m_paSortAlternate = new TDEAction( i18n( "&Alternate Sort Order" ), CTRL+Key_S, this, - TQT_SLOT( slotSortAlternate() ), actionCollection(), "alternate_sort_order"); + TQT_SLOT( slotSortAlternate() ), actionCollection(), "alternate_sort_order"); + m_paSortAlternate->setToolTip( i18n( "Sort by PREVIOUS sort column" ) ); m_paSortReverse = new TDEAction( i18n( "&Reverse Sort Order" ), CTRL+Key_R, this, TQT_SLOT( slotSortReverse() ), actionCollection(), "reverse_sort_order"); - - m_paDisplayDirectoriesFirst = new TDEToggleAction( i18n("Group &Directories First"), 0, this, + m_paSortReverse->setToolTip( i18n( "Reverse sort order of current sort column" ) ); + + /* + Build View->Sort submenu interface to properties + SortOrder, SortDirsFirst & SortHiddenFirst + */ + TextSortOrder initialOrder = m_pProps->getSortOrder(); + + m_paOrderUnicodeUnmodified = new TDEToggleAction( i18n( "&Unicode based" ), ALT+Key_1, this, + TQT_SLOT( slotOrderUnicodeUnmodified() ), actionCollection(), "order_unicode_based" ); + m_paOrderUnicodeUnmodified->setToolTip( i18n( "Strict numeric Unicode based order" ) ); + m_paOrderUnicodeUnmodified->setChecked( initialOrder == UNICODE_UNMODIFIED ); + + m_paOrderUnicodeCaseInsensitive = new TDEToggleAction( i18n( "Unicode based, &case insensitive" ), ALT+Key_2, this, + TQT_SLOT( slotOrderUnicodeCaseInsensitive() ), actionCollection(), "order_unicode_based_case_insensitive" ); + m_paOrderUnicodeCaseInsensitive->setToolTip( i18n( "Unicode based order but with lower/upper case ASCII letters adjacent" ) ); + m_paOrderUnicodeCaseInsensitive->setChecked(initialOrder == UNICODE_CASEINSENSITIVE); + + m_paOrderLocale = new TDEToggleAction( i18n( "&Locale based" ), ALT+Key_3, this, + TQT_SLOT( slotOrderLocale() ), actionCollection(), "order_locale_based" ); + m_paOrderLocale->setToolTip( i18n( "Locale based order, usually \"friendly\"" ) ); + m_paOrderLocale->setChecked(initialOrder == LOCALE_UNMODIFIED); + + // Convert above 3 checkbox menu items into single 3-way radio button menu item + m_paOrderUnicodeUnmodified->setExclusiveGroup( "sortOrder" ); + m_paOrderUnicodeCaseInsensitive->setExclusiveGroup( "sortOrder" ); + m_paOrderLocale->setExclusiveGroup( "sortOrder" ); + + m_paDisplayDirectoriesFirst = new TDEToggleAction( i18n("Group &Directories First"), CTRL+SHIFT+Key_F, this, TQT_SLOT(slotToggleDisplayDirectoriesFirst()), actionCollection(), "group_directories_first"); - m_paDisplayDirectoriesFirst->setChecked(m_pProps->isHiddenFirst()); + m_paDisplayDirectoriesFirst->setToolTip( i18n( "Always display directories before non-directories" ) ); + m_paDisplayDirectoriesFirst->setChecked(m_pProps->isDirsFirst()); - m_paDisplayHiddenFirst = new TDEToggleAction( i18n("Group &Hidden First"), 0, this, + m_paDisplayHiddenFirst = new TDEToggleAction( i18n("Group &Hidden First"), CTRL+SHIFT+Key_H, this, TQT_SLOT(slotToggleDisplayHiddenFirst()), actionCollection(), "group_hidden_first"); + m_paDisplayHiddenFirst->setToolTip( i18n( "Always display hidden files before non-hidden files" ) ); m_paDisplayHiddenFirst->setChecked(m_pProps->isHiddenFirst()); newIconSize( TDEIcon::SizeSmall /* default size */ ); @@ -955,6 +988,32 @@ void KonqListView::slotSelectionChanged() // m_paInvertSelection->setEnabled( itemSelected ); } -#include "konq_listview.moc" +void KonqListView::slotOrderUnicodeUnmodified() +{ + TextSortOrder sortOrder = UNICODE_UNMODIFIED ; + kdDebug(1202) << "Setting name order = " << sortOrder << endl; + m_pProps->setSortOrder( sortOrder ); + m_pListView->m_sortOrder = sortOrder; + m_pListView->sort(); +} +void KonqListView::slotOrderUnicodeCaseInsensitive() +{ + TextSortOrder sortOrder = UNICODE_CASEINSENSITIVE; + kdDebug(1202) << "Setting name order = " << sortOrder << endl; + m_pProps->setSortOrder( sortOrder ); + m_pListView->m_sortOrder = sortOrder; + m_pListView->sort(); +} + +void KonqListView::slotOrderLocale() +{ + TextSortOrder sortOrder = LOCALE_UNMODIFIED; + kdDebug(1202) << "Setting name order = " << sortOrder << endl; + m_pProps->setSortOrder( sortOrder ); + m_pListView->m_sortOrder = sortOrder; + m_pListView->sort(); +} + +#include "konq_listview.moc" diff --git a/konqueror/listview/konq_listview.h b/konqueror/listview/konq_listview.h index 666ae7743..fc72f6e87 100644 --- a/konqueror/listview/konq_listview.h +++ b/konqueror/listview/konq_listview.h @@ -130,8 +130,12 @@ protected slots: void slotSaveColumnWidths(); // delayed void slotHeaderClicked(int sec); + void slotOrderUnicodeUnmodified(); + void slotOrderUnicodeCaseInsensitive(); + void slotOrderLocale(); void slotToggleDisplayDirectoriesFirst(); void slotToggleDisplayHiddenFirst(); + void slotSortAlternate(); void slotSortReverse(); @@ -197,6 +201,10 @@ private: TDEToggleAction *m_paShowPermissions; TDEToggleAction *m_paShowURL; + TDEToggleAction *m_paOrderUnicodeUnmodified; + TDEToggleAction *m_paOrderUnicodeCaseInsensitive; + TDEToggleAction *m_paOrderLocale; + TDEToggleAction *m_paDisplayDirectoriesFirst; TDEToggleAction *m_paDisplayHiddenFirst; }; diff --git a/konqueror/listview/konq_listviewitems.cpp b/konqueror/listview/konq_listviewitems.cpp index cf4322ef0..1766a0b0b 100644 --- a/konqueror/listview/konq_listviewitems.cpp +++ b/konqueror/listview/konq_listviewitems.cpp @@ -19,6 +19,7 @@ #include "konq_listview.h" #include +#include "konq_string_compare.h" #include #include #include @@ -303,11 +304,10 @@ int KonqBaseListViewItem::compare( TQListViewItem* item, int col, bool ascending break; } } - if ( m_pListViewWidget->caseInsensitiveSort() ) - return text( col ).lower().localeAwareCompare( k->text( col ).lower() ); - else { - return m_pListViewWidget->m_pSettings->caseSensitiveCompare( text( col ), k->text( col ) ); - } + + /* If we reach here, we are comparing text columns (e.g file name). */ + + return stringCompare( m_pListViewWidget->m_sortOrder, text( col ), k->text( col ) ); } void KonqListViewItem::paintCell( TQPainter *_painter, const TQColorGroup & _cg, int _column, int _width, int _alignment ) diff --git a/konqueror/listview/konq_listviewwidget.cpp b/konqueror/listview/konq_listviewwidget.cpp index 4c89f529d..ef70fe949 100644 --- a/konqueror/listview/konq_listviewwidget.cpp +++ b/konqueror/listview/konq_listviewwidget.cpp @@ -100,6 +100,7 @@ KonqBaseListViewWidget::KonqBaseListViewWidget( KonqListView *parent, TQWidget * ,m_bAscending(true) ,m_itemFound(false) ,m_restored(false) + ,m_sortOrder(0) ,m_filenameColumn(0) ,m_itemToGoTo("") ,m_backgroundTimer(0) @@ -1211,11 +1212,7 @@ bool KonqBaseListViewWidget::openURL( const KURL &url ) { m_pBrowserView->newIconSize( m_pBrowserView->m_pProps->iconSize() ); m_pBrowserView->m_paShowDot->setChecked( m_pBrowserView->m_pProps->isShowingDotFiles() ); - if ( m_pBrowserView->m_paCaseInsensitive->isChecked() != m_pBrowserView->m_pProps->isCaseInsensitiveSort() ) { - m_pBrowserView->m_paCaseInsensitive->setChecked( m_pBrowserView->m_pProps->isCaseInsensitiveSort() ); - // This is in case openURL returned all items synchronously. - sort(); - } + m_sortOrder = m_pBrowserView->m_pProps->getSortOrder(); // It has to be "viewport()" - this is what KonqDirPart's slots act upon, // and otherwise we get a color/pixmap in the square between the scrollbars. @@ -1571,11 +1568,6 @@ void KonqBaseListViewWidget::slotUpdateBackground() } } -bool KonqBaseListViewWidget::caseInsensitiveSort() const -{ - return m_pBrowserView->m_pProps->isCaseInsensitiveSort(); -} - // based on isExecuteArea from tdelistview.cpp int KonqBaseListViewWidget::executeArea( TQListViewItem *_item ) { diff --git a/konqueror/listview/konq_listviewwidget.h b/konqueror/listview/konq_listviewwidget.h index 613f012b3..a8a06408b 100644 --- a/konqueror/listview/konq_listviewwidget.h +++ b/konqueror/listview/konq_listviewwidget.h @@ -137,7 +137,6 @@ public: void setAscending( bool b ) { m_bAscending = b; } bool ascending() const { return m_bAscending; } - bool caseInsensitiveSort() const; virtual void paintEmptyArea( TQPainter *p, const TQRect &r ); @@ -260,6 +259,8 @@ protected: bool m_itemFound:1; bool m_restored:1; + TextSortOrder m_sortOrder; + int m_filenameColumn; int m_filenameColumnWidth; diff --git a/konqueror/listview/konq_textview.rc b/konqueror/listview/konq_textview.rc index 20b20f451..e29a0293b 100644 --- a/konqueror/listview/konq_textview.rc +++ b/konqueror/listview/konq_textview.rc @@ -1,5 +1,5 @@ - + &Edit Selection @@ -13,12 +13,14 @@ &View - Sort + &Sort + + + + - - diff --git a/konqueror/listview/konq_treeview.rc b/konqueror/listview/konq_treeview.rc index 711f267be..9ef045785 100644 --- a/konqueror/listview/konq_treeview.rc +++ b/konqueror/listview/konq_treeview.rc @@ -1,5 +1,5 @@ - + &Edit Selection @@ -24,12 +24,14 @@ - Sort + &Sort + + + + - - diff --git a/libkonq/CMakeLists.txt b/libkonq/CMakeLists.txt index e774a81bb..c1780780d 100644 --- a/libkonq/CMakeLists.txt +++ b/libkonq/CMakeLists.txt @@ -43,6 +43,7 @@ install( FILES konq_historymgr.h konq_historycomm.h konq_pixmapprovider.h kivdirectoryoverlay.h kivfreespaceoverlay.h konq_faviconmgr.h konq_xmlguiclient.h konqbookmarkmanager.h konq_filetip.h + konq_sort_constants.h konq_string_compare.h DESTINATION ${INCLUDE_INSTALL_DIR} ) diff --git a/libkonq/Makefile.am b/libkonq/Makefile.am index 3290c3e85..3c3897155 100644 --- a/libkonq/Makefile.am +++ b/libkonq/Makefile.am @@ -52,7 +52,8 @@ include_HEADERS = konq_popupmenu.h knewmenu.h \ konq_pixmapprovider.h \ kivdirectoryoverlay.h \ kivfreespaceoverlay.h \ - konq_faviconmgr.h konq_xmlguiclient.h konqbookmarkmanager.h konq_filetip.h + konq_faviconmgr.h konq_xmlguiclient.h konqbookmarkmanager.h konq_filetip.h \ + konq_sort_constants.h konq_string_compare.h if include_ARTS diff --git a/libkonq/konq_propsview.cpp b/libkonq/konq_propsview.cpp index af7a65eae..f72aee191 100644 --- a/libkonq/konq_propsview.cpp +++ b/libkonq/konq_propsview.cpp @@ -34,6 +34,8 @@ #include +#include "konq_sort_constants.h" + static TQPixmap wallpaperPixmap( const TQString & _wallpaper ) { TQString key = "wallpapers/"; @@ -65,10 +67,11 @@ static TQPixmap wallpaperPixmap( const TQString & _wallpaper ) struct KonqPropsView::Private { TQStringList* previewsToShow; + TextSortOrder textSortOrder; bool previewsEnabled:1; bool caseInsensitiveSort:1; - bool hiddenfirst:1; bool dirsfirst:1; + bool hiddenfirst:1; bool descending:1; TQString sortcriterion; }; @@ -91,6 +94,7 @@ KonqPropsView::KonqPropsView( TDEInstance * instance, KonqPropsView * defaultPro m_iIconSize = config->readNumEntry( "IconSize", 0 ); m_iItemTextPos = config->readNumEntry( "ItemTextPos", TQIconView::Bottom ); d->sortcriterion = config->readEntry( "SortingCriterion", "sort_nci" ); + d->textSortOrder = (TextSortOrder) config->readNumEntry( "TextSortOrder", 1 ); d->dirsfirst = config->readBoolEntry( "SortDirsFirst", true ); d->hiddenfirst = config->readBoolEntry( "SortHiddenFirst", true ); d->descending = config->readBoolEntry( "SortDescending", false ); @@ -140,6 +144,11 @@ bool KonqPropsView::isCaseInsensitiveSort() const return d->caseInsensitiveSort; } +TextSortOrder KonqPropsView::getSortOrder() const +{ + return d->textSortOrder; +} + bool KonqPropsView::isDirsFirst() const { return d->dirsfirst; @@ -206,6 +215,7 @@ bool KonqPropsView::enterDir( const KURL & dir ) m_iIconSize = m_defaultProps->iconSize(); m_iItemTextPos = m_defaultProps->itemTextPos(); d->sortcriterion = m_defaultProps->sortCriterion(); + d->textSortOrder = m_defaultProps->getSortOrder(); d->dirsfirst = m_defaultProps->isDirsFirst(); d->hiddenfirst = m_defaultProps->isHiddenFirst(); d->descending = m_defaultProps->isDescending(); @@ -226,6 +236,7 @@ bool KonqPropsView::enterDir( const KURL & dir ) m_iIconSize = config->readNumEntry( "IconSize", m_iIconSize ); m_iItemTextPos = config->readNumEntry( "ItemTextPos", m_iItemTextPos ); d->sortcriterion = config->readEntry( "SortingCriterion" , d->sortcriterion ); + d->textSortOrder = (TextSortOrder) config->readNumEntry( "TextSortOrder", d->textSortOrder ); d->dirsfirst = config->readBoolEntry( "SortDirsFirst", d->dirsfirst ); d->hiddenfirst = config->readBoolEntry( "SortHiddenFirst", d->hiddenfirst ); d->descending = config->readBoolEntry( "SortDescending", d->descending ); @@ -324,6 +335,20 @@ void KonqPropsView::setSortCriterion( const TQString &criterion ) } } +void KonqPropsView::setSortOrder( TextSortOrder order) +{ + d->textSortOrder = order; + if ( m_defaultProps && !m_bSaveViewPropertiesLocally ) { + m_defaultProps->setSortOrder( order ); + } + else if (currentConfig()) + { + TDEConfigGroupSaver cgs(currentConfig(), currentGroup()); + currentConfig()->writeEntry( "TextSortOrder", d->textSortOrder ); + currentConfig()->sync(); + } +} + void KonqPropsView::setDirsFirst( bool first) { d->dirsfirst = first; diff --git a/libkonq/konq_propsview.h b/libkonq/konq_propsview.h index 84ffcf029..132c53a55 100644 --- a/libkonq/konq_propsview.h +++ b/libkonq/konq_propsview.h @@ -26,6 +26,8 @@ #include #include +#include "konq_sort_constants.h" + class TDEInstance; class TDEConfigBase; class TDEConfig; @@ -90,6 +92,9 @@ public: void setSortCriterion( const TQString &criterion ); const TQString& sortCriterion() const; + void setSortOrder( TextSortOrder order); + TextSortOrder getSortOrder() const; + void setDirsFirst ( bool first ); bool isDirsFirst() const; diff --git a/libkonq/konq_sort_constants.h b/libkonq/konq_sort_constants.h new file mode 100644 index 000000000..f6c695b19 --- /dev/null +++ b/libkonq/konq_sort_constants.h @@ -0,0 +1,13 @@ +#ifndef KONQ_SORT_CONSTANTS_H +#define KONQ_SORT_CONSTANTS_H + +typedef unsigned short TextSortOrder; + // Can't use name 'SortOrder' because that's part of TQt + +enum { + UNICODE_UNMODIFIED = 0, + LOCALE_UNMODIFIED = 1, + UNICODE_CASEINSENSITIVE = 2, +} TextSortOrders; + +#endif // KONQ_SORT_CONSTANTS_H diff --git a/libkonq/konq_string_compare.h b/libkonq/konq_string_compare.h new file mode 100644 index 000000000..8d17d409f --- /dev/null +++ b/libkonq/konq_string_compare.h @@ -0,0 +1,51 @@ +#ifndef KONQ_STRING_COMPARE_H +#define KONQ_STRING_COMPARE_H + +#include "konq_sort_constants.h" + +static inline int stringCompare( + const TextSortOrder sortorder, + const TQString& a, + const TQString& b +) +{ + // Our caller probably determined sortorder from KonqPropsView::getSortOrder() + // but we have a reasonable fallback position for bogus values. + + switch(sortorder) { + + case UNICODE_UNMODIFIED: + /* + * Strictly character code(point) numeric comparison as defined + * by the Unicode Standard that is backward compatible with the + * the ASCII standard. + . */ + return a.compare( b ); + break; + + case UNICODE_CASEINSENSITIVE: + /* + * This is the traditional "case-insensitive" variation on character + * code order that ensures that ASCII lowercase and uppercase alphabetic + * characters are are grouped together instead of being separated by + * non-alphabetic ASCII characters [ \ ] ^ _ ` + */ + return a.lower().compare( b.lower() ); + break; + + case LOCALE_UNMODIFIED: + /* + * This is the pure locale-aware comparison as defined by ICU. + * Note: if LC_COLLATE == 'C' or 'Posix', this will produce same + * result as UNICODE_UNMODIFIED. + */ + return a.localeAwareCompare( b ); + break; + + default: // Treat as UNICODE_UNMODIFIED + return a.compare( b ); + break; + } +} + +#endif // KONQ_STRING_COMPARE_H