25 #include <QApplication> 29 #include <QMutableListIterator> 30 #include <QMutexLocker> 34 #include <KLocalizedString> 35 #include <kxmlgui_version.h> 69 #define CASE_COMMAND(x) } else if (parser.command() == _(x)) { 74 m_parent_widget(parent),
78 m_modified_enabled(true),
81 m_last_selection(0,0),
82 m_last_track_selection(),
84 m_playback_controller(*this),
85 m_undo_enabled(false),
88 m_undo_transaction(Q_NULLPTR),
89 m_undo_transaction_level(0),
90 m_undo_transaction_lock(QMutex::Recursive),
129 QString filename = url.path();
150 qDebug(
"SignalManager::loadFile(%s) - [%s]",
151 DBG(url.toDisplayString()),
DBG(mimetype));
159 qWarning(
"unable to open source: '%s'",
DBG(url.toDisplayString()));
165 meta_data = decoder->metaData();
172 bool streaming = (!info.
length());
186 for (track = 0; track <
tracks; ++track) {
190 qWarning(
"SignalManager::loadFile: out of memory");
195 if (track < tracks)
break;
201 (length) ? length-1 : 0);
205 quint64 resulting_size = info.
tracks() * info.
length() *
207 bool use_src_size = (!resulting_size);
208 if (use_src_size) resulting_size = src.size();
212 QUrl(filename), resulting_size,
216 if (dialog && use_src_size) {
219 dialog, SLOT(setBytePosition(quint64)));
221 dialog, SLOT(setLength(quint64)));
225 dialog, SLOT(setValue(qreal)));
228 &writers, SLOT(cancel()));
233 qWarning(
"decoding failed.");
238 meta_data = decoder->metaData();
245 if (!res && streaming) {
249 if (new_length) new_length++;
270 if (dialog && use_src_size) {
281 qWarning(
"unknown file type");
288 qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
300 if (dialog)
delete dialog;
327 if (!tracks || !len) {
329 i18n(
"Signal is empty, nothing to save."));
333 QString mimetype_name;
335 qDebug(
"SignalManager::save(%s) - [%s] (%d bit, selection=%d)",
347 QList<Kwave::FileProperty> unsupported = encoder->unsupportedProperties(
349 if (!unsupported.isEmpty()) {
350 QString list_of_lost_properties =
_(
"\n");
352 list_of_lost_properties +=
358 i18n(
"Saving in this format will lose the following " 359 "additional file attribute(s):\n" 361 "Do you still want to continue?",
362 list_of_lost_properties),
366 _(
"accept_lose_attributes_on_export")
367 ) != KMessageBox::Continue)
375 QString filename = url.path();
392 const KAboutData about_data = KAboutData::applicationData();
393 QString software = about_data.displayName() +
_(
"-") +
394 about_data.version() +
395 i18n(
"(built with KDE Frameworks %1)",
396 _(KXMLGUI_VERSION_STRING));
404 QDate now(QDate::currentDate());
406 date = date.sprintf(
"%04d-%02d-%02d",
407 now.year(), now.month(), now.day());
408 qDebug(
"adding date tag: '%s'",
DBG(date));
414 QUrl(filename), file_info.
length() * file_info.
tracks() *
415 (file_info.
bits() >> 3),
420 dialog, SLOT(setValue(qreal)),
421 Qt::QueuedConnection);
423 &src, SLOT(cancel()));
426 bool encoded =
false;
454 i18n(
"An error occurred while saving the file."));
462 qApp->processEvents();
466 i18n(
"The file has been truncated and " 467 "might be corrupted."));
475 i18n(
"Sorry, the file type is not supported."));
479 if (!res && !selection) {
487 qDebug(
"SignalManager::save(): res=%d",res);
577 if (url.isValid())
return url.path();
589 QList<unsigned int> list;
592 for (
unsigned int track = 0; track <
tracks; track++) {
612 if (!command.length())
return -EINVAL;
648 i18n(
"Insert Clipboard at position"));
682 rest = (rest >
length) ? (rest-length) : 0;
690 unsigned int count = tracks.count();
726 int index = parser.
toInt();
731 i18n(
"Expand Selection to Label"));
735 if (labels.isEmpty())
return false;
743 if (lp <= selection_left)
745 if ((lp >= selection_right) && (label_right.
isNull())) {
751 selection_left = (label_left.
isNull()) ? 0 :
754 selection_right = (label_right.
isNull()) ?
755 (this->
length() - 1) : label_right.
pos();
766 if (labels.isEmpty())
return false;
769 if (selection_right == 0) {
770 label_right = labels.first();
775 while (it.hasNext()) {
777 if (label.
pos() >= selection_right) {
781 label_right = it.hasNext() ? it.next() :
Kwave::Label();
786 if (label_left.
isNull()) label_left = labels.last();
787 if (label_left.
isNull())
return false;
788 selection_left = label_left.
pos();
791 selection_right = (label_right.
isNull()) ?
792 (this->
length() - 1) : label_right.
pos();
794 (selection_right - selection_left + 1) : 1;
804 if (labels.isEmpty())
return false;
808 if (label.
pos() > selection_left)
810 label_left = label_right;
814 selection_left = (label_left.
isNull()) ? 0 :
817 if (label_right.
isNull()) label_right = labels.first();
818 if (label_right.
isNull())
return false;
819 selection_right = label_right.
pos();
828 unsigned int track = p.
toUInt();
829 if (track >=
tracks())
return -EINVAL;
833 unsigned int track = p.
toUInt();
839 foreach (
unsigned int track,
allTracks())
843 foreach (
unsigned int track,
allTracks())
847 foreach (
unsigned int track,
allTracks())
850 unsigned int track = parser.
toUInt();
851 if (track >=
tracks())
return -EINVAL;
855 unsigned int track = parser.
toUInt();
856 if (track >=
tracks())
return -EINVAL;
860 unsigned int track = parser.
toUInt();
861 if (track >=
tracks())
return -EINVAL;
875 if (info.
name(p) == property) {
877 info.
set(p, QVariant(value));
879 info.
set(p, QVariant());
913 const unsigned int count =
tracks();
914 Q_ASSERT(index <= count);
915 if (index > count) index = count;
925 if (index >= count) {
931 QList<unsigned int>
tracks;
932 for (
unsigned int t = index; t < count; t++) tracks.append(t);
955 const unsigned int count =
tracks();
956 Q_ASSERT(index <= count);
957 if (index > count)
return;
966 QList<unsigned int>
tracks;
967 for (
unsigned int t = index; t < count; t++) tracks.append(t);
1020 if (track == tracks[0]) {
1043 if (track == tracks[0]) {
1067 if (!length || track_list.isEmpty())
return true;
1093 foreach (
unsigned int track, track_list) {
1112 const QList<unsigned int> &track_list)
1114 if (!length)
return true;
1117 unsigned int count = track_list.count();
1118 if (!count)
return true;
1128 foreach (track, track_list) {
1142 if (length > len) length = len;
1143 if (offset >= len) offset = (len) ? (len - 1) : 0;
1144 if ((offset + length) > len) length = len - offset;
1153 unsigned int n_tracks =
tracks();
1154 for (track = 0; track < n_tracks; track++) {
1156 bool new_select = track_list.contains(track);
1157 if (new_select != old_select) {
1167 if (select != old_select) {
1174 const QList<unsigned int> &track_list,
1177 QList<Kwave::Stripe::List>
stripes;
1179 foreach (
unsigned int track, track_list) {
1193 const QList<Kwave::Stripe::List> &
stripes,
1194 const QList<unsigned int> &track_list)
1196 Q_ASSERT(stripes.count() == track_list.count());
1197 if (stripes.count() != track_list.count())
1200 QListIterator<Kwave::Stripe::List> it_s(stripes);
1201 QListIterator<unsigned int> it_t(track_list);
1202 while (it_s.hasNext() && it_t.hasNext()) {
1204 unsigned int t = it_t.next();
1251 Q_ASSERT(selection);
1252 if (selection && selection->
store(*
this)) {
1281 qDebug(
"SignalManager::closeUndoTransaction(): aborted");
1288 Q_ASSERT(undo_action);
1289 if (!undo_action)
continue;
1292 redo_action = undo_action->
undo(*
this,
false);
1295 if (redo_action && (redo_action != undo_action))
1305 qDebug(
"SignalManager::closeUndoTransaction(): empty");
1333 qWarning(
"SignalManager::disableUndo(): undo transaction level=%u",
1391 i18n(
"Not enough memory for saving undo information.") +
1393 i18n(
"Do you want to continue without the possibility to undo?") +
1394 _(
"</b><br><br><i>") +
1395 i18n(
"<b>Hint</b>: you can configure the amount of memory<br>" 1396 "available for undo under '%1'/'%2'.",
1399 _(
"</i></html>"))) == KMessageBox::Continue)
1410 if (undo_action)
delete undo_action;
1440 qint64 needed_size = action->
undoSize();
1441 qint64 needed_mb = needed_size >> 20;
1442 if (needed_mb > limit_mb) {
1461 if (!action->
store(*
this)) {
1478 if (track_list.isEmpty())
return true;
1494 if (undo) size += undo->
undoSize();
1497 if (redo) size += redo->
undoSize();
1511 if (!undo)
continue;
1513 size = (size >= s) ? (size - s) : 0;
1524 if (!redo)
continue;
1526 size = (size >= s) ? (size - s) : 0;
1534 QString undo_name = QString();
1535 QString redo_name = QString();
1543 if (transaction) undo_name = transaction->
description();
1544 if (!undo_name.length()) undo_name = i18n(
"Last Action");
1550 if (transaction) redo_name = transaction->
description();
1551 if (!redo_name.length()) redo_name = i18n(
"Last Action");
1573 if (!undo_transaction)
return;
1584 qint64 redo_size = undo_transaction->
redoSize();
1585 qint64 undo_size = undo_transaction->
undoSize();
1587 if ((redo_size > undo_size) && (redo_size - undo_size > undo_limit)) {
1589 qWarning(
"SignalManager::undo(): not enough memory for redo !");
1597 Q_ASSERT(redo_transaction);
1602 if (!redo_transaction) {
1604 qDebug(
"SignalManager::undo(): redo buffer flushed!");
1608 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1612 while (!undo_transaction->isEmpty()) {
1617 undo_action = undo_transaction->takeLast();
1618 Q_ASSERT(undo_action);
1619 if (!undo_action)
continue;
1622 redo_action = undo_action->
undo(*
this, (redo_transaction != Q_NULLPTR));
1625 if (redo_action != undo_action) {
1631 if (redo_transaction) {
1632 redo_transaction->prepend(redo_action);
1641 Q_ASSERT(undo_transaction->isEmpty());
1642 delete undo_transaction;
1644 if (redo_transaction && (redo_transaction->count() < 1)) {
1646 qWarning(
"SignalManager::undo(): no redo possible");
1647 delete redo_transaction;
1648 redo_transaction = Q_NULLPTR;
1653 if (redo_transaction) {
1657 if (range_modified || tracks_modified) {
1663 Q_ASSERT(redo_action);
1664 if (redo_action) redo_transaction->append(redo_action);
1671 bool stay_modified =
false;
1673 if (!transaction)
continue;
1675 stay_modified =
true;
1679 if (!stay_modified) {
1687 if (redo_transaction)
1703 QApplication::restoreOverrideCursor();
1714 if (!redo_transaction)
return;
1725 qint64 undo_size = redo_transaction->
undoSize();
1726 qint64 redo_size = redo_transaction->
redoSize();
1728 if ((undo_size > redo_size) && (undo_size - redo_size > undo_limit)) {
1730 qWarning(
"SignalManager::redo(): not enough memory for undo !");
1738 Q_ASSERT(undo_transaction);
1743 if (!undo_transaction) {
1751 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1755 bool modified =
false;
1756 while (!redo_transaction->isEmpty()) {
1761 redo_action = redo_transaction->takeFirst();
1764 Q_ASSERT(redo_action);
1765 if (!redo_action)
continue;
1767 undo_action = redo_action->
undo(*
this, (undo_transaction != Q_NULLPTR));
1770 if (redo_action != undo_action) {
1776 if (undo_transaction) {
1777 undo_transaction->append(undo_action);
1786 Q_ASSERT(redo_transaction->isEmpty());
1787 delete redo_transaction;
1789 if (undo_transaction && (undo_transaction->count() < 1)) {
1791 qWarning(
"SignalManager::redo(): no undo possible");
1793 delete undo_transaction;
1813 QApplication::restoreOverrideCursor();
1841 i18n(
"Modify File Info"));
1860 if (label.
pos() == pos)
return label;
1871 if (l == label)
return index;
1879 const QString &
name)
1918 for (index = count - 1; index >= 0; --index) {
1929 if ((index < 0) || (index >= count))
return;
1956 const QString &
name,
1960 if ((index < 0) || (index >=
Kwave::toInt(labels.count())))
2017 if (range_modified || tracks_modified) {
2029 if (tracks_modified && !range_modified)
2031 i18n(
"Manual Track Selection"));
2034 i18n(
"Manual Selection"));
sample_index_t toSampleIndex()
int loadFile(const QUrl &url)
void sigMetaDataChanged(Kwave::MetaDataList meta)
int save(const QUrl &url, bool selection)
void select(sample_index_t offset, sample_index_t length)
bool contains(const FileProperty property) const
qint64 usedUndoRedoMemory()
void deleteTrack(unsigned int index)
void selectRange(sample_index_t offset, sample_index_t length)
QList< Kwave::UndoTransaction * > m_redo_buffer
sample_index_t first() const
void mergeMetaData(const Kwave::MetaDataList &meta_data)
Kwave::Stripe::List stripes(unsigned int track, sample_index_t left=0, sample_index_t right=SAMPLE_INDEX_MAX)
void sigSamplesModified(unsigned int track, sample_index_t offset, sample_index_t length)
Kwave::Track * appendTrack(sample_index_t length, QUuid *uuid)
void sigTrackInserted(unsigned int index, Kwave::Track *track)
void setBytePosition(quint64 pos)
static MemoryManager & instance() Q_DECL_EXPORT
void rememberCurrentSelection()
sample_index_t last() const
static ClipBoard & instance()
bool insertSpace(sample_index_t offset, sample_index_t length, const QList< unsigned int > &track_list)
void closeUndoTransaction()
QString name(FileProperty key) const
bool containsModification() const
QMutex m_undo_transaction_lock
void sigSamplesInserted(unsigned int track, sample_index_t offset, sample_index_t length)
virtual void moveTo(sample_index_t position)
void slotTrackDeleted(unsigned int index, Kwave::Track *track)
void copy(QWidget *widget, Kwave::SignalManager &signal_manager, const QList< unsigned int > &track_list, sample_index_t offset, sample_index_t length)
Kwave::Selection & selection()
void deleteLabel(int index, bool with_undo)
virtual sample_index_t pos() const
bool continueWithoutUndo()
void newSignal(sample_index_t samples, double rate, unsigned int bits, unsigned int tracks)
void setLength(quint64 samples)
void abortUndoTransaction()
Kwave::PlaybackController & playbackController()
bool deleteRange(sample_index_t offset, sample_index_t length, const QList< unsigned int > &track_list)
unsigned int m_undo_transaction_level
static QString mimeTypeOf(const QUrl &url)
bool registerUndoAction(Kwave::UndoAction *action)
void insertTrack(unsigned int index)
bool connect(Kwave::StreamObject &source, const char *output, Kwave::StreamObject &sink, const char *input)
void set(FileProperty key, const QVariant &value)
virtual sample_index_t last() const
void setModified(bool mod)
sample_index_t length() const
void freeUndoMemory(qint64 needed)
void setRate(double rate)
void setFileInfo(const Kwave::FileInfo &new_info, bool with_undo)
sample_index_t m_last_length
QListIterator< Kwave::Label > LabelListIterator
void sigTrackSelectionChanged(bool enabled)
bool trackSelected(unsigned int track)
static int error(QWidget *widget, QString message, QString caption=QString())
void deleteRange(unsigned int track, sample_index_t offset, sample_index_t length)
QList< FileProperty > allKnownProperties() const
sample_index_t length() const
void sigSamplesDeleted(unsigned int track, sample_index_t offset, sample_index_t length)
Kwave::PlaybackController m_playback_controller
int labelIndex(const Kwave::Label &label) const
void startUndoTransaction(const QString &name=QString())
const QMap< FileProperty, QVariant > properties() const
void setLength(sample_index_t length)
void setTracks(unsigned int tracks)
Kwave::MetaDataList m_meta_data
virtual void rename(const QString &name)
bool saveUndoDelete(QList< unsigned int > &track_list, sample_index_t offset, sample_index_t length)
Kwave::Selection m_last_selection
void slotSamplesInserted(unsigned int track, sample_index_t offset, sample_index_t length)
int executeCommand(const QString &command)
static int warningContinueCancel(QWidget *widget, QString message, QString caption=QString(), const QString buttonContinue=QString(), const QString buttonCancel=QString(), const QString &dontAskAgainName=QString())
const QList< unsigned int > allTracks()
unsigned int tracks() const
virtual Kwave::UndoAction * undo(Kwave::SignalManager &manager, bool with_redo)=0
void setBits(unsigned int bits)
Kwave::Label addLabel(sample_index_t pos, const QString &name)
bool paste(QWidget *widget, Kwave::SignalManager &signal_manager, sample_index_t offset, sample_index_t length)
bool startUndoTransaction(Kwave::UndoTransaction *transaction)
Kwave::UndoTransaction * m_undo_transaction
void enableModifiedChange(bool en)
Kwave::Track * insertTrack(unsigned int index, sample_index_t length, QUuid *uuid)
void slotSamplesDeleted(unsigned int track, sample_index_t offset, sample_index_t length)
static Kwave::Decoder * decoder(const QString &mimetype_name)
static Kwave::Encoder * encoder(const QString &mimetype_name)
quint64 undoLimit() const Q_DECL_EXPORT
const QString & firstParam()
unsigned int bits() const
void slotSamplesModified(unsigned int track, sample_index_t offset, sample_index_t length)
Kwave::Label findLabel(sample_index_t pos)
bool modifyLabel(int index, sample_index_t pos, const QString &name, bool with_undo)
SignalManager(QWidget *parent)
void deleteTrack(unsigned int index)
void sigTrackDeleted(unsigned int index, Kwave::Track *track)
const QList< unsigned int > selectedTracks()
unsigned int bits() const
QList< Kwave::UndoTransaction * > m_undo_buffer
void selectTracks(QList< unsigned int > &track_list)
void insertSpace(unsigned int track, sample_index_t offset, sample_index_t length)
void slotTrackInserted(unsigned int index, Kwave::Track *track)
Kwave::Selection m_selection
QList< unsigned int > allTracks()
bool mergeStripes(const Kwave::Stripe::List &stripes, unsigned int track)
QWidget * m_parent_widget
virtual qint64 undoSize()=0
void checkSelectionChange()
bool trackSelected(unsigned int track)
void sigUndoRedoInfo(const QString &undo, const QString &redo)
void selectTrack(unsigned int track, bool select)
sample_index_t offset() const
Kwave::UndoManager m_undo_manager
const QString & nextParam()
virtual bool store(Kwave::SignalManager &manager)=0
void selectTrack(unsigned int track, bool select)
QList< Kwave::Stripe::List > stripes(const QList< unsigned int > &track_list, sample_index_t left=0, sample_index_t right=SAMPLE_INDEX_MAX)
bool mergeStripes(const QList< Kwave::Stripe::List > &stripes, const QList< unsigned int > &track_list)
QList< unsigned int > m_last_track_selection