Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Library: add overview column #14140

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
f08a206
(fix) WOverview: render progress of analysis triggered by WTrackMenu/…
ronso0 Sep 25, 2024
b6ba762
add Overview column
ninomp Sep 25, 2016
222be47
Overview column: cleanup, performance fixes, TrackId instead of row etc.
ronso0 Sep 24, 2024
b96775d
Overview: move renderers to WaveformOverviewRenderer
ronso0 Sep 7, 2024
54684e3
Overview column: use same type as in decks, use scale factor
ronso0 Sep 8, 2024
d093c7c
Overview column: set waveform colors in <Library> node
ronso0 Sep 24, 2024
48150af
Overview column: update when type is changed in preferences
ronso0 Sep 24, 2024
ae7fa54
WaveformOverviewRenderer: no singleton anymore, all static
ronso0 Sep 24, 2024
f7eeb11
Overview: move type declaration to src/waveform/overviews/overviewtype.h
ronso0 Sep 24, 2024
15a15fa
Overview column: simplify waveform updates via Track/TrackDAO ...
ronso0 Sep 24, 2024
1f0d791
Overview column: use mono-mixdown mode, painted bottom -> top
ronso0 Sep 26, 2024
bbf6394
Overview column: normalize/scale, update all when options change
ronso0 Sep 26, 2024
d226e96
overview waveform: move renderer and type declaration
ronso0 Sep 27, 2024
f74d56d
OverviewCache: make cache clearing on Normalize/Gain change safer
ronso0 Sep 28, 2024
c0a6d38
OverviewDelegate: implement lazy loading like in CoverArtDelegate
ronso0 Sep 28, 2024
d644456
Overview: clean up includes and assertions
ronso0 Jan 8, 2025
5b9dd52
fixup! Overview column: simplify waveform updates via Track/TrackDAO ...
ronso0 Jan 9, 2025
a114021
AnalyzerWaveform: tio -> pTrack
ronso0 Jan 9, 2025
f76a51b
fixup! Overview column: simplify waveform updates via Track/TrackDAO ...
ronso0 Jan 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,7 @@ add_library(
src/library/missing_hidden/hiddentablemodel.cpp
src/library/missing_hidden/missingtablemodel.cpp
src/library/mixxxlibraryfeature.cpp
src/library/overviewcache.cpp
src/library/parser.cpp
src/library/parsercsv.cpp
src/library/parserm3u.cpp
Expand Down Expand Up @@ -1248,6 +1249,7 @@ add_library(
src/library/tabledelegates/keydelegate.cpp
src/library/tabledelegates/locationdelegate.cpp
src/library/tabledelegates/multilineeditdelegate.cpp
src/library/tabledelegates/overviewdelegate.cpp
src/library/tabledelegates/previewbuttondelegate.cpp
src/library/tabledelegates/stardelegate.cpp
src/library/tabledelegates/stareditor.cpp
Expand Down Expand Up @@ -1470,11 +1472,13 @@ add_library(
src/util/workerthreadscheduler.cpp
src/util/xml.cpp
src/waveform/guitick.cpp
src/waveform/overviewtype.cpp
src/waveform/renderers/glwaveformrenderbackground.cpp
src/waveform/renderers/glvsynctestrenderer.cpp
src/waveform/renderers/waveformmark.cpp
src/waveform/renderers/waveformmarkrange.cpp
src/waveform/renderers/waveformmarkset.cpp
src/waveform/renderers/waveformoverviewrenderer.cpp
src/waveform/renderers/waveformrenderbackground.cpp
src/waveform/renderers/waveformrenderbeat.cpp
src/waveform/renderers/waveformrendererabstract.cpp
Expand Down
4 changes: 4 additions & 0 deletions res/skins/Deere/library.xml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@
<Library>
<ShowButtonText>false</ShowButtonText>
<TrackTableBackgroundColorOpacity>0.175</TrackTableBackgroundColorOpacity>
<!-- Colors for the render modes of the Overview column -->
<!-- For the overview column we only set the signal color,
other colors are the defaults. -->
<SignalColor><Variable name="SignalColor"/></SignalColor>
</Library>

</Children>
Expand Down
2 changes: 1 addition & 1 deletion res/skins/Deere/preview_deck.xml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
<SignalRGBHighColor></SignalRGBHighColor>
<SignalRGBMidColor></SignalRGBMidColor>
<SignalRGBLowColor></SignalRGBLowColor>
<SignalColor>#FF8000</SignalColor>
<SignalColor><Variable name="SignalColor"/></SignalColor>
<PlayPosColor>#00FF00</PlayPosColor>
<ShowCueTimes>false</ShowCueTimes>
<DefaultMark>
Expand Down
2 changes: 1 addition & 1 deletion res/skins/Deere/sampler_controls_row.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<SignalRGBHighColor></SignalRGBHighColor>
<SignalRGBMidColor></SignalRGBMidColor>
<SignalRGBLowColor></SignalRGBLowColor>
<SignalColor>#FF8000</SignalColor>
<SignalColor><Variable name="SignalColor"/></SignalColor>
<PlayPosColor>#00FF00</PlayPosColor>
<ShowCueTimes>false</ShowCueTimes>
<DefaultMark>
Expand Down
3 changes: 3 additions & 0 deletions res/skins/Deere/skin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@
<SetVariable name="VerticalStretchButtonMaximumSize">22,-1</SetVariable>
<SetVariable name="VerticalStretchButtonSizePolicy">f,me</SetVariable>

<!-- Signal color for waveform overview in preview deck, samplers and library -->
<SetVariable name="SignalColor">#FF8000</SetVariable>

<!-- The waveforms (zoomed and overview) use a lot of memory. They appear in multiple places in
main_decks.xml, left_deck.xml, and right_deck.xml, so define them in singletons. This makes
toggling between 2/4 decks and stacked/split waveforms slower, but it makes Mixxx startup
Expand Down
4 changes: 4 additions & 0 deletions res/skins/LateNight/library.xml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@
<Library>
<ShowButtonText>false</ShowButtonText>
<TrackTableBackgroundColorOpacity>0.175</TrackTableBackgroundColorOpacity>
<!-- Colors for the render modes of the Overview column -->
<!-- For the overview column we only set the signal color,
other colors are the defaults. -->
<SignalColor><Variable name="SignalColor_12"/></SignalColor>
</Library>

</Children>
Expand Down
2 changes: 1 addition & 1 deletion res/skins/Shade/deck_overview.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<SignalHighColor></SignalHighColor>
<SignalMidColor></SignalMidColor>
<SignalLowColor></SignalLowColor>
<SignalColor>#191F24</SignalColor>
<SignalColor><Variable name="SignalColor"/></SignalColor>
<PlayPosColor>#00FF00</PlayPosColor>
<EndOfTrackColor>#EA0000</EndOfTrackColor>
<PassthroughLabelColor><Variable name="PassthroughLabelColor"/></PassthroughLabelColor>
Expand Down
2 changes: 1 addition & 1 deletion res/skins/Shade/preview_deck.xml
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@
<SignalHighColor></SignalHighColor>
<SignalMidColor></SignalMidColor>
<SignalLowColor></SignalLowColor>
<SignalColor>#191F24</SignalColor>
<SignalColor><Variable name="SignalColor"/></SignalColor>
<PlayPosColor>#00FF00</PlayPosColor>
<ShowCueTimes>false</ShowCueTimes>
<DefaultMark>
Expand Down
2 changes: 1 addition & 1 deletion res/skins/Shade/sampler.xml
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@
<SignalHighColor></SignalHighColor>
<SignalMidColor></SignalMidColor>
<SignalLowColor></SignalLowColor>
<SignalColor>#191F24</SignalColor>
<SignalColor><Variable name="SignalColor"/></SignalColor>
<PlayPosColor>#00FF00</PlayPosColor>
<ShowCueTimes>false</ShowCueTimes>
<DefaultMark>
Expand Down
18 changes: 11 additions & 7 deletions res/skins/Shade/skin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,17 @@
<Layout>vertical</Layout>

<Children>

<!-- Signal color for waveform overview in preview deck, samplers and library -->
<SetVariable name="SignalColor">#191F24</SetVariable>
<SetVariable name="PassthroughLabelColor">#55F764</SetVariable>
<!-- Shade has overview and waveform very close, so it would be redundant and distracting
to paint the 'Passthrough' labels on both with an alarming color.
This is the regular background color, so the label will be invisible: -->
<SetVariable name="PassthroughLabelColorWaveform">#8d98a3</SetVariable>
<!-- This is slightly brighter that the background: -->
<!-- <SetVariable name="PassthroughLabelColorWaveform">#9fabb7</SetVariable> -->

<!--
############################################################################################
############################################################################################
Expand All @@ -284,13 +295,6 @@
############################################################################################
############################################################################################
-->
<SetVariable name="PassthroughLabelColor">#55F764</SetVariable>
<!-- Shade has overview and waveform very close, so it would be redundant and distracting
to paint the 'Passthrough' labels on both with an alarming color.
This is the regular background color, so the label will be invisible: -->
<SetVariable name="PassthroughLabelColorWaveform">#8d98a3</SetVariable>
<!-- This is slightly brighter that the background: -->
<!-- <SetVariable name="PassthroughLabelColorWaveform">#9fabb7</SetVariable> -->

<SingletonDefinition>
<ObjectName>Overview1</ObjectName>
Expand Down
2 changes: 1 addition & 1 deletion res/skins/Tango/decks/preview_deck.xml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ Variables:
<Size>1me,34f</Size>
<Group><Variable name="group"/></Group>
<BgColor>#151515</BgColor>
<SignalColor>#bababa</SignalColor>
<SignalColor><Variable name="SignalColor"/></SignalColor>
<PlayPosColor>#FF4300</PlayPosColor>
<PlayedOverlayColor><Variable name="PlayedOverlayColor"/></PlayedOverlayColor>
<MarkerColor>#00FF00</MarkerColor>
Expand Down
4 changes: 4 additions & 0 deletions res/skins/Tango/library.xml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ Description:
<FgColor>#eece33</FgColor>
<ShowButtonText>false</ShowButtonText>
<TrackTableBackgroundColorOpacity>0.2</TrackTableBackgroundColorOpacity>
<!-- Colors for the render modes of the Overview column -->
<!-- For the overview column we only set the signal color,
other colors are the defaults. -->
<SignalColor><Variable name="SignalColor"/></SignalColor>
</Library>
</Children>
</WidgetGroup><!-- /Library Table -->
Expand Down
2 changes: 1 addition & 1 deletion res/skins/Tango/mic_aux_sampler/sampler.xml
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ Variables:
<SizePolicy>me,min</SizePolicy>
<Group><Variable name="group"/></Group>
<BgColor>#151515</BgColor>
<SignalColor>#bababa</SignalColor>
<SignalColor><Variable name="SignalColor"/></SignalColor>
<PlayPosColor>#FF4300</PlayPosColor>
<PlayedOverlayColor><Variable name="PlayedOverlayColor"/></PlayedOverlayColor>
<ShowCueTimes>false</ShowCueTimes>
Expand Down
2 changes: 2 additions & 0 deletions res/skins/Tango/skin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@
<SetVariable name="SignalBgColor_34">#19260B</SetVariable>
<SetVariable name="SpinnyCoverColor_12">purple</SetVariable>
<SetVariable name="SpinnyCoverColor_34">green</SetVariable>
<!-- Signal color for waveform overview in decks 1/2, preview deck, samplers and library -->
<SetVariable name="SignalColor">#bababa</SetVariable>

<!--################################################################
Singleton definitions #######################################
Expand Down
29 changes: 16 additions & 13 deletions src/analyzer/analyzerwaveform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ bool AnalyzerWaveform::initialize(const AnalyzerTrack& track,
sampleRate, frameLength, mainWaveformSampleRate, summaryWaveformSamples, stemCount));

// Now, that the Waveform memory is initialized, we can set set them to
// the TIO. Be aware that other threads of Mixxx can touch them from
// the track. Be aware that other threads of Mixxx can touch them from
// now.
track.getTrack()->setWaveform(m_waveform);
track.getTrack()->setWaveformSummary(m_waveformSummary);
Expand All @@ -98,16 +98,16 @@ bool AnalyzerWaveform::initialize(const AnalyzerTrack& track,
return true;
}

bool AnalyzerWaveform::shouldAnalyze(TrackPointer tio) const {
ConstWaveformPointer pTrackWaveform = tio->getWaveform();
ConstWaveformPointer pTrackWaveformSummary = tio->getWaveformSummary();
bool AnalyzerWaveform::shouldAnalyze(TrackPointer pTrack) const {
ConstWaveformPointer pTrackWaveform = pTrack->getWaveform();
ConstWaveformPointer pTrackWaveformSummary = pTrack->getWaveformSummary();
ConstWaveformPointer pLoadedTrackWaveform;
ConstWaveformPointer pLoadedTrackWaveformSummary;
#ifdef __STEM__
bool isStemTrack = !tio->getStemInfo().isEmpty();
bool isStemTrack = !pTrack->getStemInfo().isEmpty();
#endif

TrackId trackId = tio->getId();
TrackId trackId = pTrack->getId();
bool missingWaveform = pTrackWaveform.isNull();
bool missingWavesummary = pTrackWaveformSummary.isNull();

Expand Down Expand Up @@ -162,10 +162,10 @@ bool AnalyzerWaveform::shouldAnalyze(TrackPointer tio) const {
if (!missingWaveform && !missingWavesummary) {
kLogger.debug() << "loadStored - Stored waveform loaded";
if (pLoadedTrackWaveform) {
tio->setWaveform(pLoadedTrackWaveform);
pTrack->setWaveform(pLoadedTrackWaveform);
}
if (pLoadedTrackWaveformSummary) {
tio->setWaveformSummary(pLoadedTrackWaveformSummary);
pTrack->setWaveformSummary(pLoadedTrackWaveformSummary);
}
return false;
}
Expand Down Expand Up @@ -321,15 +321,14 @@ void AnalyzerWaveform::cleanup() {
m_waveformSummaryData = nullptr;
}

void AnalyzerWaveform::storeResults(TrackPointer tio) {
void AnalyzerWaveform::storeResults(TrackPointer pTrack) {
// Force completion to waveform size
if (m_waveform) {
m_waveform->setSaveState(Waveform::SaveState::SavePending);
m_waveform->setCompletion(m_waveform->getDataSize());
m_waveform->setVersion(WaveformFactory::currentWaveformVersion());
m_waveform->setDescription(WaveformFactory::currentWaveformDescription());
}
tio->setWaveform(m_waveform);

// Force completion to waveform size
if (m_waveformSummary) {
Expand All @@ -338,7 +337,6 @@ void AnalyzerWaveform::storeResults(TrackPointer tio) {
m_waveformSummary->setVersion(WaveformFactory::currentWaveformSummaryVersion());
m_waveformSummary->setDescription(WaveformFactory::currentWaveformSummaryDescription());
}
tio->setWaveformSummary(m_waveformSummary);

#ifdef TEST_HEAT_MAP
test_heatMap->save("heatMap.png");
Expand All @@ -349,11 +347,16 @@ void AnalyzerWaveform::storeResults(TrackPointer tio) {
// and then it is not called. The other analyzers have signals which control
// the update of their data.
m_analysisDao.saveTrackAnalyses(
tio->getId(),
pTrack->getId(),
m_waveform,
m_waveformSummary);

kLogger.debug() << "Waveform generation for track" << tio->getId() << "done"
// Set waveforms on track AFTER they'been written to disk in order to have
// a consistency when OverviewCache asks AnalysisDAO for a waveform summary.
pTrack->setWaveform(m_waveform);
pTrack->setWaveformSummary(m_waveformSummary);

kLogger.debug() << "Waveform generation for track" << pTrack->getId() << "done"
<< m_timer.elapsed().debugSecondsWithUnit();
}

Expand Down
7 changes: 7 additions & 0 deletions src/coreservices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "library/coverartcache.h"
#include "library/library.h"
#include "library/library_prefs.h"
#include "library/overviewcache.h"
#include "library/trackcollection.h"
#include "library/trackcollectionmanager.h"
#include "mixer/playerinfo.h"
Expand Down Expand Up @@ -372,6 +373,12 @@ void CoreServices::initialize(QApplication* pApp) {
m_pPlayerManager.get(),
m_pRecordingManager.get());

OverviewCache* pOverviewCache = OverviewCache::createInstance(pConfig, m_pDbConnectionPool);
connect(&(m_pTrackCollectionManager->internalCollection()->getTrackDAO()),
&TrackDAO::waveformSummaryUpdated,
pOverviewCache,
&OverviewCache::onTrackSummaryChanged);

// Binding the PlayManager to the Library may already trigger
// loading of tracks which requires that the GlobalTrackCache has
// been created. Otherwise Mixxx might hang when accessing
Expand Down
9 changes: 9 additions & 0 deletions src/library/analysis/analysisfeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,15 @@ void AnalysisFeature::analyzeTracks(const QList<AnalyzerScheduledTrack>& tracks)
&TrackAnalysisScheduler::finished,
this,
&AnalysisFeature::onTrackAnalysisSchedulerFinished);
// Forward the signal to be picked up by Library.
// Used by WOverview to render the re-analysis progress of loaded tracks.
// This is the equivalent to PlayerManager's progress signal fired for
// analysis triggered by loading a track.
connect(m_pTrackAnalysisScheduler.get(),
&TrackAnalysisScheduler::trackProgress,
this,
&AnalysisFeature::trackProgress,
Qt::DirectConnection);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not use a direct connection here, this may cause headaches later. See my other comment.


emit analysisActive(true);
}
Expand Down
1 change: 1 addition & 0 deletions src/library/analysis/analysisfeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class AnalysisFeature : public LibraryFeature {

signals:
void analysisActive(bool bActive);
void trackProgress(TrackId trackId, AnalyzerProgress progress);

public slots:
void activate() override;
Expand Down
2 changes: 2 additions & 0 deletions src/library/basesqltablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,8 @@ bool BaseSqlTableModel::setTrackValueForColumn(
pTrack->setBpmLocked(value.toBool());
} else {
// We never should get up to this point!
// Might happen editing read-only column values, so make sure to return
// the read-only flags for those in BaseTrackTableModel::readWriteFlags().
qWarning() << "Column"
<< columnNameForFieldIndex(column)
<< "is not editable!";
Expand Down
32 changes: 30 additions & 2 deletions src/library/basetracktablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "library/tabledelegates/keydelegate.h"
#include "library/tabledelegates/locationdelegate.h"
#include "library/tabledelegates/multilineeditdelegate.h"
#include "library/tabledelegates/overviewdelegate.h"
#include "library/tabledelegates/previewbuttondelegate.h"
#include "library/tabledelegates/stardelegate.h"
#include "library/trackcollection.h"
Expand Down Expand Up @@ -71,6 +72,7 @@ const QStringList kDefaultTableColumns = {
LIBRARYTABLE_TITLE,
LIBRARYTABLE_TRACKNUMBER,
LIBRARYTABLE_YEAR,
LIBRARYTABLE_WAVESUMMARYHEX,
};

inline QSqlDatabase cloneDatabase(
Expand Down Expand Up @@ -256,6 +258,9 @@ void BaseTrackTableModel::initHeaderProperties() {
ColumnCache::COLUMN_TRACKLOCATIONSTABLE_LOCATION,
tr("Location"),
defaultColumnWidth() * 6);
setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_WAVESUMMARYHEX,
tr("Overview"),
defaultColumnWidth() * 8);
setHeaderProperties(
ColumnCache::COLUMN_LIBRARYTABLE_PREVIEW,
tr("Preview"),
Expand Down Expand Up @@ -517,7 +522,7 @@ QAbstractItemDelegate* BaseTrackTableModel::delegateForColumn(
new CoverArtDelegate(pTableView);
// WLibraryTableView -> CoverArtDelegate
connect(pTableView,
&WLibraryTableView::onlyCachedCoverArt,
&WLibraryTableView::onlyCachedCoversAndOverviews,
pCoverArtDelegate,
&CoverArtDelegate::slotInhibitLazyLoading);
// CoverArtDelegate -> BaseTrackTableModel
Expand All @@ -528,6 +533,17 @@ QAbstractItemDelegate* BaseTrackTableModel::delegateForColumn(
return pCoverArtDelegate;
} else if (index == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_KEY)) {
return new KeyDelegate(pTableView);
} else if (index == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_WAVESUMMARYHEX)) {
auto* pOverviewDelegate = new OverviewDelegate(pTableView);
connect(pOverviewDelegate,
&OverviewDelegate::overviewRowsChanged,
this,
&BaseTrackTableModel::slotRefreshOverviewRows);
connect(pTableView,
&WLibraryTableView::onlyCachedCoversAndOverviews,
pOverviewDelegate,
&OverviewDelegate::slotInhibitLazyLoading);
return pOverviewDelegate;
}
return nullptr;
}
Expand Down Expand Up @@ -1090,7 +1106,8 @@ Qt::ItemFlags BaseTrackTableModel::readWriteFlags(
column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_FILETYPE) ||
column == fieldIndex(ColumnCache::COLUMN_TRACKLOCATIONSTABLE_LOCATION) ||
column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_REPLAYGAIN) ||
column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_SAMPLERATE)) {
column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_SAMPLERATE) ||
column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_WAVESUMMARYHEX)) {
return readOnlyFlags(index);
}

Expand Down Expand Up @@ -1192,6 +1209,17 @@ void BaseTrackTableModel::slotRefreshCoverRows(
emitDataChangedForMultipleRowsInColumn(rows, column);
}

void BaseTrackTableModel::slotRefreshOverviewRows(const QList<int>& rows) {
if (rows.isEmpty()) {
return;
}
const int column = fieldIndex(LIBRARYTABLE_WAVESUMMARYHEX);
VERIFY_OR_DEBUG_ASSERT(column >= 0) {
return;
}
emitDataChangedForMultipleRowsInColumn(rows, column);
}

void BaseTrackTableModel::slotRefreshAllRows() {
select();
}
Expand Down
Loading
Loading