1111
1212using namespace MOShared ;
1313using namespace MOBase ;
14+ namespace fs = std::filesystem;
1415
1516// if there are more than 50 selected items in the conflict tree, don't bother
1617// checking whether menu items apply to them, just show all of them
@@ -110,7 +111,7 @@ bool ConflictsTab::canHandleUnmanaged() const
110111 return true ;
111112}
112113
113- void ConflictsTab::changeItemsVisibility (QTreeView* tree, bool visible )
114+ void ConflictsTab::hideItems (QTreeView* tree)
114115{
115116 bool changed = false ;
116117 bool stop = false ;
@@ -119,19 +120,16 @@ void ConflictsTab::changeItemsVisibility(QTreeView* tree, bool visible)
119120
120121 // logging
121122 {
122- const QString action = (visible ? " unhiding" : " hiding" );
123-
124123 QString files;
125124 if (n > max_small_selection)
126125 files = " a lot of" ;
127126 else
128127 files = QString (" %1" ).arg (n);
129128
130- log::debug (" {} {} conflict files" , action , files);
129+ log::debug (" hiding {} conflict files" , files);
131130 }
132131
133- QFlags<FileRenamer::RenameFlags> flags =
134- (visible ? FileRenamer::UNHIDE : FileRenamer::HIDE);
132+ QFlags<FileRenamer::RenameFlags> flags = FileRenamer::HIDE;
135133
136134 if (n > 1 ) {
137135 flags |= FileRenamer::MULTIPLE;
@@ -158,25 +156,13 @@ void ConflictsTab::changeItemsVisibility(QTreeView* tree, bool visible)
158156 return false ;
159157 }
160158
161- auto result = FileRenamer::RESULT_CANCEL;
162-
163- if (visible) {
164- if (!item->canUnhide ()) {
165- log::debug (" cannot unhide {}, skipping" , item->relativeName ());
166- return true ;
167- }
168-
169- result = unhideFile (renamer, item->fileName ());
170-
171- } else {
172- if (!item->canHide ()) {
173- log::debug (" cannot hide {}, skipping" , item->relativeName ());
174- return true ;
175- }
176-
177- result = hideFile (renamer, item->fileName ());
159+ if (!item->canHide ()) {
160+ log::debug (" cannot hide {}, skipping" , item->relativeName ());
161+ return true ;
178162 }
179163
164+ auto result = hideFile (renamer, item->fileName ());
165+
180166 switch (result) {
181167 case FileRenamer::RESULT_OK: {
182168 // will trigger a refresh at the end
@@ -199,7 +185,7 @@ void ConflictsTab::changeItemsVisibility(QTreeView* tree, bool visible)
199185 return true ;
200186 });
201187
202- log::debug (" {} conflict files done" , (visible ? " unhiding " : " hiding " ) );
188+ log::debug (" hiding conflict files done" );
203189
204190 if (changed) {
205191 log::debug (" triggering refresh" );
@@ -351,21 +337,12 @@ void ConflictsTab::showContextMenu(const QPoint& pos, QTreeView* tree)
351337 // hide
352338 if (actions.hide ) {
353339 connect (actions.hide , &QAction::triggered, [&] {
354- changeItemsVisibility (tree, false );
340+ hideItems (tree);
355341 });
356342
357343 menu.addAction (actions.hide );
358344 }
359345
360- // unhide
361- if (actions.unhide ) {
362- connect (actions.unhide , &QAction::triggered, [&] {
363- changeItemsVisibility (tree, true );
364- });
365-
366- menu.addAction (actions.unhide );
367- }
368-
369346 if (!menu.isEmpty ()) {
370347 if (actions.open || actions.preview || actions.runHooked ) {
371348 // bold the first option
@@ -386,7 +363,6 @@ ConflictsTab::Actions ConflictsTab::createMenuActions(QTreeView* tree)
386363 }
387364
388365 bool enableHide = true ;
389- bool enableUnhide = true ;
390366 bool enableRun = true ;
391367 bool enableOpen = true ;
392368 bool enablePreview = true ;
@@ -421,7 +397,6 @@ ConflictsTab::Actions ConflictsTab::createMenuActions(QTreeView* tree)
421397 }
422398
423399 enableHide = item->canHide ();
424- enableUnhide = item->canUnhide ();
425400 enableRun = item->canRun ();
426401 enableOpen = item->canOpen ();
427402 enablePreview = item->canPreview (plugin ());
@@ -443,19 +418,14 @@ ConflictsTab::Actions ConflictsTab::createMenuActions(QTreeView* tree)
443418 if (n <= max_small_selection) {
444419 // if the number of selected items is low, checking them to accurately
445420 // show the menu items is worth it
446- enableHide = false ;
447- enableUnhide = false ;
421+ enableHide = false ;
448422
449423 forEachInSelection (tree, [&](const ConflictItem* item) {
450424 if (item->canHide ()) {
451425 enableHide = true ;
452426 }
453427
454- if (item->canUnhide ()) {
455- enableUnhide = true ;
456- }
457-
458- if (enableHide && enableUnhide && enableGoto) {
428+ if (enableHide && enableGoto) {
459429 // found all, no need to check more
460430 return false ;
461431 }
@@ -487,11 +457,6 @@ ConflictsTab::Actions ConflictsTab::createMenuActions(QTreeView* tree)
487457 actions.hide = new QAction (tr (" &Hide" ), parentWidget ());
488458 actions.hide ->setEnabled (enableHide);
489459
490- // note that it is possible for hidden files to appear if they override other
491- // hidden files from another mod
492- actions.unhide = new QAction (tr (" &Unhide" ), parentWidget ());
493- actions.unhide ->setEnabled (enableUnhide);
494-
495460 if (enableGoto && n == 1 ) {
496461 const auto * item =
497462 model->getItem (static_cast <std::size_t >(modelSel.indexes ()[0 ].row ()));
@@ -633,8 +598,39 @@ bool GeneralConflictsTab::update()
633598
634599 if (m_tab->origin () != nullptr ) {
635600 const auto rootPath = m_tab->mod ().absolutePath ();
601+ std::set<const DirectoryEntry*> checkedDirs;
636602
637603 for (const auto & file : m_tab->origin ()->getFiles ()) {
604+ if (QString::fromStdWString (file->getName ())
605+ .endsWith (ModInfo::s_HiddenExt, Qt::CaseInsensitive)) {
606+ // skip hidden file conflicts
607+ continue ;
608+ } else {
609+ const DirectoryEntry* parent = file->getParent ();
610+ auto hidden = false ;
611+ // iterate on all parent directory entries to check for .mohiddden
612+ while (parent != nullptr ) {
613+ auto insertResult = checkedDirs.insert (parent);
614+
615+ if (insertResult.second == false ) {
616+ // if already present break as we can assume to have checked the parents as
617+ // well
618+ break ;
619+ } else {
620+ if (QString::fromStdWString (parent->getName ())
621+ .endsWith (ModInfo::s_HiddenExt, Qt::CaseInsensitive)) {
622+ hidden = true ;
623+ break ;
624+ }
625+ parent = parent->getParent ();
626+ }
627+ }
628+ if (hidden) {
629+ // skip hidden file conflicts
630+ continue ;
631+ }
632+ }
633+
638634 // careful: these two strings are moved into createXItem() below
639635 QString relativeName =
640636 QDir::fromNativeSeparators (ToQString (file->getRelativePath ()));
@@ -954,8 +950,38 @@ void AdvancedConflictsTab::update()
954950
955951 const auto & files = m_tab->origin ()->getFiles ();
956952 m_model->reserve (files.size ());
953+ std::set<const DirectoryEntry*> checkedDirs;
957954
958955 for (const auto & file : files) {
956+ if (QString::fromStdWString (file->getName ())
957+ .endsWith (ModInfo::s_HiddenExt, Qt::CaseInsensitive)) {
958+ // skip hidden file conflicts
959+ continue ;
960+ } else {
961+ const DirectoryEntry* parent = file->getParent ();
962+ auto hidden = false ;
963+ // iterate on all parent directory entries to check for .mohiddden
964+ while (parent != nullptr ) {
965+ auto insertResult = checkedDirs.insert (parent);
966+
967+ if (insertResult.second == false ) {
968+ // if already present break as we can assume to have checked the parents as
969+ // well
970+ break ;
971+ } else {
972+ if (QString::fromStdWString (parent->getName ())
973+ .endsWith (ModInfo::s_HiddenExt, Qt::CaseInsensitive)) {
974+ hidden = true ;
975+ break ;
976+ }
977+ parent = parent->getParent ();
978+ }
979+ }
980+ if (hidden) {
981+ // skip hidden file conflicts
982+ continue ;
983+ }
984+ }
959985 // careful: these two strings are moved into createItem() below
960986 QString relativeName =
961987 QDir::fromNativeSeparators (ToQString (file->getRelativePath ()));
0 commit comments