Skip to content

Commit 5ffcd21

Browse files
committed
Content selector: Cut down on unnecessary dataChanged calls (#8478)
setData shouldn't do dataChanged calls setCheckState already does setCheckState should emit dataChanged for downstream dependencies unconditionally setCheckState shouldn't emit dataChanged for upstream dependencies that weren't enabled
1 parent b7a48e1 commit 5ffcd21

File tree

1 file changed

+26
-71
lines changed

1 file changed

+26
-71
lines changed

components/contentselector/model/contentmodel.cpp

Lines changed: 26 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,6 @@ bool ContentSelectorModel::ContentModel::setData(const QModelIndex& index, const
251251
return false;
252252

253253
EsmFile* file = item(index.row());
254-
QString fileName = file->fileName();
255-
bool success = false;
256-
257254
switch (role)
258255
{
259256
case Qt::EditRole:
@@ -267,65 +264,23 @@ bool ContentSelectorModel::ContentModel::setData(const QModelIndex& index, const
267264
file->setFileProperty(EsmFile::FileProperty_GameFile, list.at(i));
268265

269266
emit dataChanged(index, index);
270-
271-
success = true;
267+
return true;
272268
}
273-
break;
274-
275269
case Qt::UserRole + 1:
276270
{
277-
success = (flags(index) & Qt::ItemIsEnabled);
278-
279-
if (success)
280-
{
281-
success = setCheckState(file, value.toBool());
282-
emit dataChanged(index, index);
283-
}
271+
return isEnabled(index) && setCheckState(file, value.toBool());
284272
}
285-
break;
286-
287273
case Qt::CheckStateRole:
288274
{
289275
int checkValue = value.toInt();
290-
bool setState = false;
291-
if (file->builtIn() || file->fromAnotherConfigFile())
292-
{
293-
setState = false;
294-
success = false;
295-
}
296-
else if (checkValue == Qt::Checked && !mCheckedFiles.contains(file))
297-
{
298-
setState = true;
299-
success = true;
300-
}
301-
else if (checkValue == Qt::Checked && mCheckedFiles.contains(file))
302-
setState = true;
303-
else if (checkValue == Qt::Unchecked)
304-
setState = true;
305-
306-
if (setState)
307-
{
308-
setCheckState(file, success);
309-
emit dataChanged(index, index);
310-
}
311-
else
312-
return success;
313-
314-
for (EsmFile* file2 : mFiles)
315-
{
316-
if (file2->gameFiles().contains(fileName, Qt::CaseInsensitive))
317-
{
318-
QModelIndex idx = indexFromItem(file2);
319-
emit dataChanged(idx, idx);
320-
}
321-
}
322-
323-
success = true;
276+
if (checkValue == Qt::Checked)
277+
return mCheckedFiles.contains(file) || setCheckState(file, true);
278+
if (checkValue == Qt::Unchecked)
279+
return !mCheckedFiles.contains(file) || setCheckState(file, false);
324280
}
325-
break;
326281
}
327282

328-
return success;
283+
return false;
329284
}
330285

331286
bool ContentSelectorModel::ContentModel::insertRows(int position, int rows, const QModelIndex& parent)
@@ -715,6 +670,7 @@ void ContentSelectorModel::ContentModel::setContentList(const QStringList& fileL
715670
{
716671
// setCheckState already gracefully handles builtIn and fromAnotherConfigFile
717672
// as necessary, move plug-ins in visible list to match sequence of supplied filelist
673+
// FIXME: setCheckState also does tons of other things which we don't want to happen
718674
int filePosition = indexFromItem(file).row();
719675
if (filePosition < previousPosition)
720676
{
@@ -805,38 +761,37 @@ bool ContentSelectorModel::ContentModel::setCheckState(const EsmFile* file, bool
805761
else
806762
mCheckedFiles.erase(file);
807763

808-
emit dataChanged(indexFromItem(file), indexFromItem(file));
764+
QModelIndex fileIndex = indexFromItem(file);
765+
emit dataChanged(fileIndex, fileIndex);
809766

767+
// FIXME: this should not happen per-file.
768+
// Consider not hiding files if their game is disabled so that this is completely unnecessary.
810769
if (file->isGameFile())
811770
refreshModel();
812771

813-
// if we're checking an item, ensure all "upstream" files (dependencies) are checked as well.
772+
// Check "upstream" files (dependencies) if the file is checked,
773+
// uncheck downstream files if the file is unchecked.
774+
// Update the data for downstream files unconditionally (load order warnings).
775+
// FIXME: downstream files of toggled upstream/downstream files should be updated, but that would be slow.
814776
if (checkState)
815777
{
816778
for (const QString& upstreamName : file->gameFiles())
817779
{
818780
const EsmFile* upstreamFile = item(upstreamName);
819-
820-
if (!upstreamFile)
781+
if (upstreamFile == nullptr || !mCheckedFiles.insert(upstreamFile).second)
821782
continue;
822-
823-
mCheckedFiles.insert(upstreamFile);
824-
825-
emit dataChanged(indexFromItem(upstreamFile), indexFromItem(upstreamFile));
783+
QModelIndex upstreamIndex = indexFromItem(upstreamFile);
784+
emit dataChanged(upstreamIndex, upstreamIndex);
826785
}
827786
}
828-
// otherwise, if we're unchecking an item (or the file is a game file) ensure all downstream files are unchecked.
829-
else
787+
for (const EsmFile* otherFile : mFiles)
830788
{
831-
for (const EsmFile* downstreamFile : mFiles)
832-
{
833-
if (downstreamFile->gameFiles().contains(file->fileName(), Qt::CaseInsensitive))
834-
{
835-
mCheckedFiles.erase(downstreamFile);
836-
837-
emit dataChanged(indexFromItem(downstreamFile), indexFromItem(downstreamFile));
838-
}
839-
}
789+
if (!otherFile->gameFiles().contains(file->fileName(), Qt::CaseInsensitive))
790+
continue;
791+
if (!checkState)
792+
mCheckedFiles.erase(otherFile);
793+
QModelIndex otherIndex = indexFromItem(otherFile);
794+
emit dataChanged(otherIndex, otherIndex);
840795
}
841796

842797
// Need to manually let Bloodmoon entry know if Tribunal is checked/unchecked

0 commit comments

Comments
 (0)