From dfc5d701ea9c19ec5736f942bb3cdee5b8834338 Mon Sep 17 00:00:00 2001 From: shenleban tongying Date: Wed, 26 Apr 2023 03:37:46 -0400 Subject: [PATCH] fix(autoGroupByFolder): prepend upper level folder name when two groups share same name but in different folder --- src/ui/groups_widgets.cc | 76 ++++++++++++++++++++++++++++++----- website/docs/manage_groups.md | 16 ++++++++ 2 files changed, 81 insertions(+), 11 deletions(-) diff --git a/src/ui/groups_widgets.cc b/src/ui/groups_widgets.cc index 98f39a18..aa2eaeb1 100644 --- a/src/ui/groups_widgets.cc +++ b/src/ui/groups_widgets.cc @@ -780,6 +780,12 @@ void DictGroupsWidget::addAutoGroupsByFolders() return; } + auto cdUpWentWrong = [ this ]( const QString & path ) { + QMessageBox::warning( this, + tr( "Auto group by folder failed." ), + tr( "The parent directory of %1 can be reached." ).arg( path ) ); + }; + if ( QMessageBox::information( this, tr( "Confirmation" ), tr( "Are you sure you want to generate a set of groups " @@ -790,26 +796,74 @@ void DictGroupsWidget::addAutoGroupsByFolders() return; } - QMultiMap< QString, sptr< Dictionary::Class > > dictMap; + // Map from dict to ContainerFolder's parent + QMap< sptr< Dictionary::Class >, QString > dictToContainerFolder; for ( const auto & dict : *activeDicts ) { - QString dictFolder = dict->getContainingFolder(); + QDir c = dict->getContainingFolder(); - if ( dictFolder.isEmpty() ) { - continue; + if ( !c.cdUp() ) { + cdUpWentWrong( c.absolutePath() ); + return; } - QDir dir = dictFolder; - if ( dir.cdUp() ) { - dictMap.insert( dir.dirName(), dict ); + dictToContainerFolder.insert( dict, c.absolutePath() ); + } + + /* + Check for duplicated ContainerFolder's parent folder names, and prepend the upper parent's name. + + . + ├─epistularum + │ └─Japanese <- Group + │ └─DictA <- Dict Files's container folder + | └─ DictA Files + ├─Mastameta + │ └─Japanese <- Group + | └─DictB <- Dict Files's container folder + | └─ DictB Files + + will be grouped into epistularum/Japanese and Mastameta/Japanese + */ + + // set a dirname to true if there are duplications like `epistularum/Japanese` and `Mastameta/Japanese` + QHash< QString, bool > dirNeedPrepend{}; + + for ( const auto & path : dictToContainerFolder.values() ) { + auto dir = QDir( path ); + if ( dirNeedPrepend.contains( dir.dirName() ) ) { + dirNeedPrepend[ dir.dirName() ] = true; } else { - qWarning() << "Cannot auto group because parent folder cannot be reached: " << dir; - continue; + dirNeedPrepend.insert( dir.dirName(), false ); } } - for ( const auto & group : dictMap.uniqueKeys() ) { + // map from GroupName to dicts + QMultiMap< QString, sptr< Dictionary::Class > > groupToDicts; + + for ( const auto & dict : dictToContainerFolder.keys() ) { + QDir path = dictToContainerFolder[ dict ]; + QString groupName; + if ( !dirNeedPrepend[ path.dirName() ] ) { + groupName = path.dirName(); + } + else { + QString directFolder = path.dirName(); + if ( !path.cdUp() ) { + cdUpWentWrong( path.absolutePath() ); + return; + } + QString upperFolder = path.dirName(); + groupName = upperFolder + "/" + directFolder; + } + + groupToDicts.insert( groupName, dict ); + } + + // create and insert groups + // modifying user's groups begins here + for ( const auto & group : groupToDicts.uniqueKeys() ) { if ( count() != 0 ) { setCurrentIndex( count() - 1 ); } @@ -817,7 +871,7 @@ void DictGroupsWidget::addAutoGroupsByFolders() addUniqueGroup( group ); DictListModel * model = getCurrentModel(); - for ( auto dict : dictMap.values( group ) ) { + for ( const auto& dict : groupToDicts.values( group ) ) { model->addRow( QModelIndex(), dict ); } } diff --git a/website/docs/manage_groups.md b/website/docs/manage_groups.md index 657be0e2..6c3e30e9 100644 --- a/website/docs/manage_groups.md +++ b/website/docs/manage_groups.md @@ -35,4 +35,20 @@ For example, the structure below will be auto grouped into two groups: └── zim ├── Wikipedia_ru.slob └── Wikipedia.zim +``` + +Note that if two groups share the same name but in different folder, then upper level's folder name will be prepended with group name. The Example below will be grouped into `epistularum/Japanese` and `Mastameta/Japanese`. + +More levels of folder nesting are not supported. + +``` +. +├─epistularum +│ └─Japanese <- Group +│ └─DictA <- Dict Files's container folder +| └─ DictA Files +├─Mastameta +│ └─Japanese <- Group +| └─DictB <- Dict Files's container folder +| └─ DictB Files ``` \ No newline at end of file