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