3131#include < coreplugin/ProjectTimeline.h>
3232#include < coreplugin/ProjectWindowInterface.h>
3333
34+ #include < dspxmodel/Clip.h>
35+ #include < dspxmodel/ClipSequence.h>
36+ #include < dspxmodel/ClipTime.h>
3437#include < dspxmodel/Model.h>
3538#include < dspxmodel/SelectionModel.h>
3639#include < dspxmodel/Timeline.h>
@@ -142,15 +145,25 @@ namespace Audio {
142145 const auto model = document->model ();
143146 Q_ASSERT (model);
144147
145- auto timeline = model->timeline ();
146- if (config.timeRange () == AudioExporterConfig::TR_LoopSection && timeline->isLoopEnabled () && timeline->loopLength () > 0 ) {
147- return {timeline->loopStart (), timeline->loopLength ()};
148+ switch (config.timeRange ()) {
149+ case AudioExporterConfig::TR_All:
150+ break ;
151+ case AudioExporterConfig::TR_LoopSection: {
152+ auto timeline = model->timeline ();
153+ if (timeline->isLoopEnabled () && timeline->loopLength () > 0 ) {
154+ return {timeline->loopStart (), timeline->loopLength ()};
155+ }
156+ break ;
157+ }
158+ case AudioExporterConfig::TR_Custom:
159+ return {parameter.rangeStart (), parameter.rangeLength ()};
148160 }
149161
150- auto projectTimeline = windowHandle->projectTimeline ();
151- Q_ASSERT (projectTimeline);
152- // TODO change `rangeHint` to the real project length (类似ProjectWindowInterface::boundTimelineRangeHint,但是只考虑最远的剪辑)
153- return {0 , projectTimeline->rangeHint ()};
162+ return {0 , std::ranges::max (std::views::transform (model->tracks ()->items (), [](dspx::Track *track) {
163+ return track->clips ()->size () == 0 ? 0 : std::ranges::max (std::views::transform (track->clips ()->asRange (), [](dspx::Clip *clip) {
164+ return clip->position () + clip->time ()->clipLen ();
165+ }));
166+ }))};
154167 }
155168
156169 QList<int > AudioExporterPrivate::sourceIndexes (bool *ok) const {
@@ -186,7 +199,7 @@ namespace Audio {
186199 break ;
187200 }
188201 case AudioExporterConfig::SO_Custom:
189- indexes = config .source ();
202+ indexes = parameter .source ();
190203 for (const auto index : indexes) {
191204 if (index < 0 || index >= trackList.size ()) {
192205 if (ok) {
@@ -308,11 +321,12 @@ namespace Audio {
308321
309322 bool sourcesOk = true ;
310323 const auto indexes = sourceIndexes (&sourcesOk);
311- if (!sourcesOk || indexes.isEmpty ()) {
324+ const auto isMixed = config.mixingOption () == AudioExporterConfig::MO_Mixed;
325+ if (!sourcesOk || (!isMixed && indexes.isEmpty ())) {
312326 preflightWarnings |= AudioExporter::PW_NoFile;
313327 }
314328
315- if (indexes.isEmpty ()) {
329+ if (!sourcesOk || (!isMixed && indexes.isEmpty () )) {
316330 if (oldWarnings != preflightWarnings) {
317331 Q_EMIT q->preflightWarningsChanged ();
318332 }
@@ -323,7 +337,7 @@ namespace Audio {
323337 }
324338
325339 const auto directory = QDir (projectDirectory ()).absoluteFilePath (config.fileDirectory ());
326- if (config. mixingOption () == AudioExporterConfig::MO_Mixed ) {
340+ if (isMixed ) {
327341 auto fileName = config.fileName ();
328342 if (!resolveTemplate (fileName)) {
329343 preflightWarnings |= AudioExporter::PW_UnrecognizedTemplate;
@@ -458,6 +472,21 @@ namespace Audio {
458472 d->refreshPreflight ();
459473 }
460474
475+ AudioExporterParameter AudioExporter::parameter () const {
476+ Q_D (const AudioExporter);
477+ return d->parameter ;
478+ }
479+
480+ void AudioExporter::setParameter (const AudioExporterParameter ¶meter) {
481+ Q_D (AudioExporter);
482+ if (d->parameter == parameter) {
483+ return ;
484+ }
485+ d->parameter = parameter;
486+ Q_EMIT parameterChanged ();
487+ d->refreshPreflight ();
488+ }
489+
461490 AudioExporter::PreflightWarnings AudioExporter::preflightWarnings () const {
462491 Q_D (const AudioExporter);
463492 return d->preflightWarnings ;
@@ -534,7 +563,8 @@ namespace Audio {
534563
535564 bool sourcesOk = true ;
536565 const auto sourceIndexes = d->sourceIndexes (&sourcesOk);
537- if (!sourcesOk || sourceIndexes.isEmpty () || d->fileList .isEmpty ()) {
566+ if (!sourcesOk || d->fileList .isEmpty () ||
567+ (d->config .mixingOption () != AudioExporterConfig::MO_Mixed && sourceIndexes.isEmpty ())) {
538568 d->setError (InvalidSource, tr (" No file will be exported. Please check if any source is selected." ));
539569 return R_Fail;
540570 }
@@ -705,6 +735,10 @@ namespace Audio {
705735 Q_EMIT runtimeWarningAdded (message, sourceIndex);
706736 }
707737
738+ AudioExporterPrivate *AudioExporterPrivate::of (AudioExporter *q) {
739+ return q->d_func ();
740+ }
741+
708742}
709743
710744#include " moc_AudioExporter.cpp"
0 commit comments