kwave  18.07.70
Kwave::SaveBlocksPlugin Class Reference

#include <SaveBlocksPlugin.h>

Inheritance diagram for Kwave::SaveBlocksPlugin:
Inheritance graph
Collaboration diagram for Kwave::SaveBlocksPlugin:
Collaboration graph

Classes

struct  BlockInfo
 

Public Types

enum  numbering_mode_t { CONTINUE = 0, START_AT_ONE = 1 }
 

Signals

void sigNewExample (const QString &example)
 
- Signals inherited from Kwave::Plugin
void sigRunning (Kwave::Plugin *plugin)
 
void sigDone (Kwave::Plugin *plugin)
 
void sigClosed (Kwave::Plugin *p)
 
void sigCommand (const QString &command)
 
void setProgressText (const QString &text)
 

Public Member Functions

 SaveBlocksPlugin (QObject *parent, const QVariantList &args)
 
virtual ~SaveBlocksPlugin () Q_DECL_OVERRIDE
 
virtual QStringList * setup (QStringList &previous_params) Q_DECL_OVERRIDE
 
virtual int start (QStringList &params) Q_DECL_OVERRIDE
 
- Public Member Functions inherited from Kwave::Plugin
 Plugin (QObject *parent, const QVariantList &args)
 
virtual ~Plugin () Q_DECL_OVERRIDE
 
virtual QString name () const
 
virtual QString description () const
 
virtual QString progressText ()
 
virtual bool canClose () const
 
bool isRunning () const
 
bool shouldStop () const
 
virtual void load (QStringList &params)
 
virtual void unload ()
 
virtual int stop ()
 
virtual void run (QStringList params)
 
Kwave::PluginManagermanager () const
 
Kwave::SignalManagersignalManager ()
 
QWidget * parentWidget () const
 
QString signalName ()
 
virtual sample_index_t signalLength ()
 
virtual double signalRate ()
 
virtual const QList< unsigned int > selectedTracks ()
 
virtual sample_index_t selection (QList< unsigned int > *tracks=Q_NULLPTR, sample_index_t *left=Q_NULLPTR, sample_index_t *right=Q_NULLPTR, bool expand_if_empty=false)
 
virtual void selectRange (sample_index_t offset, sample_index_t length)
 
virtual void migrateToActiveContext ()
 
- Public Member Functions inherited from Kwave::Runnable
virtual ~Runnable ()
 

Protected Member Functions

int interpreteParameters (QStringList &params)
 
void scanBlocksToSave (const QString &base, bool selection_only)
 
QString createFileName (const QString &base, const QString &ext, const QString &pattern, unsigned int index, int count, int total)
 
unsigned int firstIndex (const QString &path, const QString &base, const QString &ext, const QString &pattern, Kwave::SaveBlocksPlugin::numbering_mode_t mode, unsigned int count)
 
QString findBase (const QString &filename, const QString &pattern)
 
QString firstFileName (const QString &filename, const QString &pattern, numbering_mode_t mode, bool selection_only)
 
- Protected Member Functions inherited from Kwave::Plugin
int execute (QStringList &params)
 
void emitCommand (const QString &command)
 
void use ()
 
void setPluginManager (Kwave::PluginManager *new_plugin_manager)
 
virtual void run_wrapper (const QVariant &params) Q_DECL_OVERRIDE
 

Private Slots

void updateExample (const QString &filename, const QString &pattern, Kwave::SaveBlocksPlugin::numbering_mode_t mode, bool selection_only)
 

Private Member Functions

QString createDisplayList (const QStringList &list, unsigned int max_entries) const
 

Private Attributes

QUrl m_url
 
QString m_pattern
 
numbering_mode_t m_numbering_mode
 
bool m_selection_only
 
QList< BlockInfom_block_info
 

Additional Inherited Members

- Public Slots inherited from Kwave::Plugin
virtual void setProgressDialogEnabled (bool enable)
 
virtual void updateProgress (qreal progress)
 
virtual void cancel ()
 
virtual void close ()
 
void release ()
 

Detailed Description

Definition at line 33 of file SaveBlocksPlugin.h.

Member Enumeration Documentation

◆ numbering_mode_t

mode for numbering the output files

Enumerator
CONTINUE 
START_AT_ONE 

Definition at line 64 of file SaveBlocksPlugin.h.

Constructor & Destructor Documentation

◆ SaveBlocksPlugin()

Kwave::SaveBlocksPlugin::SaveBlocksPlugin ( QObject *  parent,
const QVariantList &  args 
)

Constructor

Parameters
parentreference to our plugin manager
argsargument list [unused]

Definition at line 47 of file SaveBlocksPlugin.cpp.

◆ ~SaveBlocksPlugin()

Kwave::SaveBlocksPlugin::~SaveBlocksPlugin ( )
virtual

Destructor

Definition at line 56 of file SaveBlocksPlugin.cpp.

57 {
58 }

Member Function Documentation

◆ createDisplayList()

QString Kwave::SaveBlocksPlugin::createDisplayList ( const QStringList &  list,
unsigned int  max_entries 
) const
private

internal helper to create a string that contains a HTML formated list of file names or directories

Parameters
lista list of file names or directories
max_entriesmaximum number of entries to render
Returns
the list as a single string, separated by "\<br\>"

Definition at line 159 of file SaveBlocksPlugin.cpp.

References _.

Referenced by start().

162 {
163  if (!max_entries || list.isEmpty()) return QString();
164 
165  QString retval;
166  unsigned int count = 0;
167 
168  foreach (const QString &entry, list) {
169  if (count == 0) // first entry
170  retval = _("<br><br>");
171  if (count < max_entries)
172  retval += entry + _("<br>");
173  else if (count == max_entries)
174  retval += i18n("...") + _("<br>");
175 
176  if (++count > max_entries)
177  break;
178  }
179 
180  return retval;
181 }
#define _(m)
Definition: memcpy.c:66
Here is the caller graph for this function:

◆ createFileName()

QString Kwave::SaveBlocksPlugin::createFileName ( const QString &  base,
const QString &  ext,
const QString &  pattern,
unsigned int  index,
int  count,
int  total 
)
protected

create a filename (without extension) out of a given base name, pattern, index and count

Parameters
basethe base name, without indices, extension etc...
extthe extension (zero-length is allowed)
patternthe pattern for creating the filename
indexthe index of the current file
countthe number of files to save
totalthe highest index to save (first + count - 1)
Returns
the name of the file, escaped

Definition at line 497 of file SaveBlocksPlugin.cpp.

References _, Kwave::Parser::escapeForFileName(), Kwave::FileInfo::flags(), Kwave::FileInfo::FP_FORMAT_NUMERIC, Kwave::FileInfo::fromName(), Kwave::FileInfo::get(), Kwave::INF_UNKNOWN, m_block_info, and Kwave::Plugin::signalManager().

Referenced by firstFileName(), firstIndex(), and start().

500 {
501  QString p = QRegExp::escape(pattern);
502  QString nr;
503 
504  // format the "index" parameter
505  QRegExp rx_nr(_("(\\\\\\[%(\\d*)nr\\\\\\])"), Qt::CaseInsensitive);
506  while (rx_nr.indexIn(p) >= 0) {
507  QString format = rx_nr.cap(1);
508  format = format.mid(2, format.length() - 6);
509  QString ex = _("(\\\\\\[") + format + _("nr\\\\\\])");
510  QRegExp rx(ex, Qt::CaseInsensitive);
511  format += _("u");
512  p.replace(rx, nr.sprintf(format.toLatin1(), index));
513  }
514 
515  // format the "count" parameter
516  QRegExp rx_count(_("(\\\\\\[%\\d*count\\\\\\])"), Qt::CaseInsensitive);
517  while (rx_count.indexIn(p) >= 0) {
518  if (count >= 0) {
519  QString format = rx_count.cap(1);
520  format = format.mid(2, format.length() - 9);
521  QString ex = _("(\\\\\\[") + format + _("count\\\\\\])");
522  QRegExp rx(ex, Qt::CaseInsensitive);
523  format += _("u");
524  p.replace(rx, nr.sprintf(format.toLatin1(), count));
525  } else {
526  p.replace(rx_count, _("(\\d+)"));
527  }
528  }
529 
530  // format the "total" parameter
531  QRegExp rx_total(_("(\\\\\\[%\\d*total\\\\\\])"), Qt::CaseInsensitive);
532  while (rx_total.indexIn(p) >= 0) {
533  if (total >= 0) {
534  QString format = rx_total.cap(1);
535  format = format.mid(2, format.length() - 9);
536  QString ex = _("(\\\\\\[") + format + _("total\\\\\\])");
537  QRegExp rx(ex, Qt::CaseInsensitive);
538  format += _("u");
539  p.replace(rx, nr.sprintf(format.toLatin1(), total));
540  } else {
541  p.replace(rx_total, _("(\\d+)"));
542  }
543  }
544 
545  // format the "filename" parameter
546  QRegExp rx_filename(_("\\\\\\[%filename\\\\\\]"), Qt::CaseInsensitive);
547  if (rx_filename.indexIn(p) >= 0) {
548  p.replace(rx_filename, QRegExp::escape(base));
549  }
550 
551  // support for file info
552  QRegExp rx_fileinfo(
553  _("\\\\\\[%(\\d*)fileinfo\\\\\\{([\\w\\s]+)\\\\\\}\\\\\\]"),
554  Qt::CaseInsensitive
555  );
556  Kwave::FileInfo info(signalManager().metaData());
557  while (rx_fileinfo.indexIn(p) >= 0) {
558  const QString format = rx_fileinfo.cap(1);
559  const QString id = rx_fileinfo.cap(2);
560  QString value;
561  FileProperty property = info.fromName(id);
562  if (property != Kwave::INF_UNKNOWN) {
563  QVariant val = info.get(property);
564  if (!val.isNull()) {
565  // we have a property value
566  value = val.toString();
567 
568  // check for format (desired minimum string length)
569  bool ok = false;
570  int len = format.toUInt(&ok);
571  if ((len > 0) && ok) {
572  Kwave::FileInfo::Flags flags = info.flags(property);
574  // numeric format, pad with leading zeros or spaces
575  QString pad = (format.startsWith(QLatin1Char('0'))) ?
576  _("0") : _(" ");
577  while (value.length() < len)
578  value = pad + value;
579  } else {
580  // string format, pad with trailing spaces
581  while (value.length() < len)
582  value = value + _(" ");
583  }
584  }
585  value = Kwave::Parser::escapeForFileName(value);
586  }
587  }
588 
589  QString ex(_("(\\\\\\[%") + format + _("fileinfo\\\\\\{") + id +
590  _("\\\\\\}\\\\\\])"));
591  QRegExp rx(ex, Qt::CaseInsensitive);
592  p.replace(rx, value);
593  }
594 
595  // format the "title" parameter
596  QRegExp rx_title(_("\\\\\\[%title\\\\\\]"), Qt::CaseInsensitive);
597  if (rx_title.indexIn(p) >= 0) {
598  QString title;
599  int idx = (index - 1) - (total - count);
600  if ((idx >= 0) && (idx < m_block_info.count()))
601  title = m_block_info[idx].m_title;
602  if (title.length()) {
603  title = Kwave::Parser::escapeForFileName(title);
604  p.replace(rx_title, title);
605  }
606  }
607 
608  if (ext.length()) p += _(".") + ext;
609 
610  // sanitize the filename/path, make sure that there are no spaces
611  // before and after all path separators
612  QString sep = _("/");
613  QRegExp rx_sep(_("\\s*") + sep + _("\\s*"));
614  p.replace(rx_sep, sep);
615 
616  return p;
617 }
QList< BlockInfo > m_block_info
Kwave::SignalManager & signalManager()
Definition: Plugin.cpp:444
static QString escapeForFileName(const QString &text)
Definition: Parser.cpp:295
#define _(m)
Definition: memcpy.c:66
FileProperty
Definition: FileInfo.h:45
Here is the call graph for this function:
Here is the caller graph for this function:

◆ findBase()

QString Kwave::SaveBlocksPlugin::findBase ( const QString &  filename,
const QString &  pattern 
)
protected

Find out the base name out of a given file name, using a given filename pattern. If the given file name is already produced (matched) by this pattern, the base name will be cut out of the file name.

Parameters
filenamethe file name to check
patternthe selected filename pattern
Returns
the base name of the file, without path and extension

Definition at line 648 of file SaveBlocksPlugin.cpp.

References _, and Kwave::Plugin::name().

Referenced by firstFileName(), setup(), and start().

650 {
651  QFileInfo file(filename);
652  QString name = file.fileName();
653  QString base = file.completeBaseName();
654  QString ext = file.suffix();
655 
656  // convert the pattern into a regular expression in order to check if
657  // the current name already is produced by the current pattern
658  // \[%[0-9]?nr\] -> \d+
659  // \[%[0-9]?count\] -> \d+
660  // \[%[0-9]?total\] -> \d+
661  // \[%filename\] -> base
662  // \[%fileinfo\] -> .
663  // \[%title\] -> .
664  QRegExp rx_nr(_("\\\\\\[%\\d*nr\\\\\\]"), Qt::CaseInsensitive);
665  QRegExp rx_count(_("\\\\\\[%\\d*count\\\\\\]"), Qt::CaseInsensitive);
666  QRegExp rx_total(_("\\\\\\[%\\d*total\\\\\\]"), Qt::CaseInsensitive);
667  QRegExp rx_filename(_("\\\\\\[%filename\\\\\\]"), Qt::CaseInsensitive);
668  QRegExp rx_fileinfo(_("\\\\\\[%fileinfo\\\\\\]"), Qt::CaseInsensitive);
669  QRegExp rx_title(_("\\\\\\[%title\\\\\\]"), Qt::CaseInsensitive);
670 
671  QString p = QRegExp::escape(pattern);
672  int idx_nr = rx_nr.indexIn(p);
673  int idx_count = rx_count.indexIn(p);
674  int idx_total = rx_total.indexIn(p);
675  int idx_filename = rx_filename.indexIn(p);
676  int idx_fileinfo = rx_fileinfo.indexIn(p);
677  int idx_title = rx_fileinfo.indexIn(p);
678  p.replace(rx_nr, _("(\\d+)"));
679  p.replace(rx_count, _("(\\d+)"));
680  p.replace(rx_total, _("(\\d+)"));
681  p.replace(rx_filename, _("(.+)"));
682  p.replace(rx_fileinfo, _("(.+)"));
683  p.replace(rx_title, _("(.+)"));
684 
685  int max = 0;
686  for (int i = 0; i < pattern.length(); i++) {
687  if (idx_nr == max) max++;
688  if (idx_count == max) max++;
689  if (idx_total == max) max++;
690  if (idx_filename == max) max++;
691  if (idx_fileinfo == max) max++;
692  if (idx_title == max) max++;
693 
694  if (idx_nr > max) idx_nr--;
695  if (idx_count > max) idx_count--;
696  if (idx_total > max) idx_total--;
697  if (idx_filename > max) idx_filename--;
698  if (idx_fileinfo > max) idx_fileinfo--;
699  if (idx_title > max) idx_title--;
700  }
701 
702  if (ext.length()) p += _(".") + ext;
703  QRegExp rx_current(p, Qt::CaseInsensitive);
704  if (rx_current.indexIn(name) >= 0) {
705  // filename already produced by this pattern
706  base = rx_current.cap(idx_filename + 1);
707  }
708 
709  return base;
710 }
virtual QString name() const
Definition: Plugin.cpp:196
#define _(m)
Definition: memcpy.c:66
Here is the call graph for this function:
Here is the caller graph for this function:

◆ firstFileName()

QString Kwave::SaveBlocksPlugin::firstFileName ( const QString &  filename,
const QString &  pattern,
numbering_mode_t  mode,
bool  selection_only 
)
protected

determines the first file name that matches the given filename, pattern, mode and selection

Parameters
filenamethe currently selected filename
patternthe selected filename pattern
modethe numbering mode
selection_onlyif true: save only the selection
Returns
name of the first file, escaped

Definition at line 713 of file SaveBlocksPlugin.cpp.

References createFileName(), findBase(), firstIndex(), m_block_info, and scanBlocksToSave().

Referenced by updateExample().

716 {
717  QFileInfo file(filename);
718  QString path = file.absolutePath();
719  QString ext = file.suffix();
720  QString base = findBase(filename, pattern);
721 
722  // now we have a new name, base and extension
723  // -> find out the numbering, min/max etc...
724  scanBlocksToSave(base, selection_only);
725  unsigned int count = m_block_info.count();
726  unsigned int first = firstIndex(path, base, ext, pattern, mode, count);
727  unsigned int total = first + count - 1;
728 
729  // create the complete filename, including extension but without path
730  return createFileName(base, ext, pattern, first, count, total);
731 }
QString createFileName(const QString &base, const QString &ext, const QString &pattern, unsigned int index, int count, int total)
QList< BlockInfo > m_block_info
QString findBase(const QString &filename, const QString &pattern)
unsigned int firstIndex(const QString &path, const QString &base, const QString &ext, const QString &pattern, Kwave::SaveBlocksPlugin::numbering_mode_t mode, unsigned int count)
void scanBlocksToSave(const QString &base, bool selection_only)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ firstIndex()

unsigned int Kwave::SaveBlocksPlugin::firstIndex ( const QString &  path,
const QString &  base,
const QString &  ext,
const QString &  pattern,
Kwave::SaveBlocksPlugin::numbering_mode_t  mode,
unsigned int  count 
)
protected

determines the index of the first file name that matches the given filename, pattern and mode

Parameters
paththe directory for saving
basethe base name, without indices, extension etc...
extthe extension (zero-length is allowed)
patternthe pattern for creating the filename
modethe numbering mode
countthe total number of files
Returns
the index of the first file, [1...count+X]

Definition at line 620 of file SaveBlocksPlugin.cpp.

References _, CONTINUE, createFileName(), Kwave::Plugin::name(), and START_AT_ONE.

Referenced by firstFileName(), and start().

623 {
624  unsigned int first = 1;
625  switch (mode) {
626  case START_AT_ONE:
627  first = 1;
628  break;
629  case CONTINUE: {
630  QDir dir(path, _("*"));
631  QStringList files;
632  files = dir.entryList();
633  for (unsigned int i = first; i < (first + count); i++) {
634  QString name = createFileName(base, ext, pattern, i, -1, -1);
635  QRegExp rx(_("^(") + name + _(")$"),
636  Qt::CaseInsensitive);
637  QStringList matches = files.filter(rx);
638  if (matches.count() > 0) first = i + 1;
639  }
640  break;
641  }
642  }
643 
644  return first;
645 }
QString createFileName(const QString &base, const QString &ext, const QString &pattern, unsigned int index, int count, int total)
virtual QString name() const
Definition: Plugin.cpp:196
#define _(m)
Definition: memcpy.c:66
Here is the call graph for this function:
Here is the caller graph for this function:

◆ interpreteParameters()

int Kwave::SaveBlocksPlugin::interpreteParameters ( QStringList &  params)
protected

reads values from the parameter list

Definition at line 409 of file SaveBlocksPlugin.cpp.

References CONTINUE, m_numbering_mode, m_pattern, m_selection_only, m_url, START_AT_ONE, and Kwave::Parser::unescape().

Referenced by setup(), and start().

410 {
411  bool ok;
412  QString param;
413 
414  // evaluate the parameter list
415  if (params.count() != 4) {
416  return -EINVAL;
417  }
418 
419  // the selected URL
420  m_url = QUrl::fromUserInput(Kwave::Parser::unescape(params[0]));
421  if (!m_url.isValid()) return -EINVAL;
422 
423  // filename pattern
424  m_pattern = Kwave::Parser::unescape(params[1]);
425  if (!m_pattern.length()) return -EINVAL;
426 
427  // numbering mode
428  param = params[2];
429  int mode = param.toInt(&ok);
430  Q_ASSERT(ok);
431  if (!ok) return -EINVAL;
432  if ((mode != CONTINUE) &&
433  (mode != START_AT_ONE)) return -EINVAL;
434  m_numbering_mode = static_cast<numbering_mode_t>(mode);
435 
436  // flag: save only the selection
437  param = params[3];
438  m_selection_only = (param.toUInt(&ok) != 0);
439  Q_ASSERT(ok);
440  if (!ok) return -EINVAL;
441 
442  return 0;
443 }
numbering_mode_t m_numbering_mode
static QString unescape(const QString &text)
Definition: Parser.cpp:314
Here is the call graph for this function:
Here is the caller graph for this function:

◆ scanBlocksToSave()

void Kwave::SaveBlocksPlugin::scanBlocksToSave ( const QString &  base,
bool  selection_only 
)
protected

determines the blocks which should be saved, including start position, length and title.

Parameters
basethe base name, without indices, extension etc...
selection_onlyif true, save only selected blocks

Definition at line 446 of file SaveBlocksPlugin.cpp.

References Kwave::FileInfo::get(), Kwave::INF_NAME, Kwave::MetaData::isNull(), m_block_info, Kwave::SaveBlocksPlugin::BlockInfo::m_length, Kwave::SaveBlocksPlugin::BlockInfo::m_start, Kwave::SaveBlocksPlugin::BlockInfo::m_title, Kwave::Label::name(), Kwave::Label::pos(), Kwave::Plugin::selection(), Kwave::Plugin::signalLength(), and Kwave::Plugin::signalManager().

Referenced by firstFileName(), setup(), and start().

448 {
449  sample_index_t selection_left, selection_right;
450 
451  sample_index_t block_start;
452  sample_index_t block_end = 0;
453  QString block_title;
454  Kwave::LabelList labels(signalManager().metaData());
455  Kwave::LabelListIterator it(labels);
456  Kwave::Label label = (it.hasNext()) ? it.next() : Kwave::Label();
457 
458  if (selection_only) {
459  selection(Q_NULLPTR, &selection_left, &selection_right, true);
460  } else {
461  selection_left = 0;
462  selection_right = signalLength() - 1;
463  }
464 
465  // get the title of the whole file, in case that a block does not have
466  // an own title
467  FileInfo info(signalManager().metaData());
468  QString file_title = info.get(INF_NAME).toString();
469 
470  // fallback: if there is no INF_NAME either, fall back to the file
471  // name as last resort
472  if (!file_title.length()) file_title = base;
473 
474  m_block_info.clear();
475  QString prev_title;
476  for (;;) {
477  block_start = block_end;
478  block_end = (label.isNull()) ? signalLength() : label.pos();
479  block_title = prev_title;
480  prev_title = (label.isNull()) ? file_title : label.name();
481 
482  if ((block_end > selection_left) && (block_start <= selection_right)) {
483  BlockInfo block;
484  block.m_start = block_start;
485  block.m_length = block_end - block_start;
486  block.m_title = block_title;
487  if (!block.m_title.length()) block.m_title = file_title;
488  m_block_info.append(block);
489  }
490 
491  if (label.isNull()) break;
492  label = (it.hasNext()) ? it.next() : Kwave::Label();
493  }
494 }
QList< BlockInfo > m_block_info
Kwave::SignalManager & signalManager()
Definition: Plugin.cpp:444
virtual sample_index_t pos() const
Definition: Label.cpp:56
quint64 sample_index_t
Definition: Sample.h:28
QListIterator< Kwave::Label > LabelListIterator
Definition: LabelList.h:76
virtual bool isNull() const
Definition: MetaData.cpp:69
virtual QString name() const
Definition: Label.cpp:74
virtual sample_index_t signalLength()
Definition: Plugin.cpp:462
virtual sample_index_t selection(QList< unsigned int > *tracks=Q_NULLPTR, sample_index_t *left=Q_NULLPTR, sample_index_t *right=Q_NULLPTR, bool expand_if_empty=false)
Definition: Plugin.cpp:480
Here is the call graph for this function:
Here is the caller graph for this function:

◆ setup()

QStringList * Kwave::SaveBlocksPlugin::setup ( QStringList &  previous_params)
virtual

Shows a file saving dialog and emits a command for saving the blocks when OK has been pressed.

See also
Kwave::Plugin::setup

Reimplemented from Kwave::Plugin.

Definition at line 61 of file SaveBlocksPlugin.cpp.

References _, Kwave::connect(), Kwave::Plugin::description(), Kwave::Plugin::emitCommand(), Kwave::CodecManager::encodingFilter(), Kwave::Parser::escape(), findBase(), interpreteParameters(), m_numbering_mode, m_pattern, m_selection_only, m_url, Kwave::Plugin::name(), Kwave::Plugin::parentWidget(), scanBlocksToSave(), Kwave::Plugin::selection(), Kwave::Plugin::signalLength(), Kwave::Plugin::signalName(), sigNewExample(), and updateExample().

62 {
63  // try to interpret the previous parameters
64  interpreteParameters(previous_params);
65 
66  // create the setup dialog
67  sample_index_t selection_left = 0;
68  sample_index_t selection_right = 0;
69  selection(Q_NULLPTR, &selection_left, &selection_right, false);
70 
71  // enable the "selection only" checkbox only if there is something
72  // selected but not everything
73  bool selected_something = (selection_left != selection_right);
74  bool selected_all = ((selection_left == 0) &&
75  (selection_right + 1 >= signalLength()));
76  bool enable_selection_only = selected_something && !selected_all;
77 
78  QString filename = m_url.path();
79  QString base = findBase(filename, m_pattern);
80  scanBlocksToSave(base, m_selection_only && enable_selection_only);
81 
82  QPointer<Kwave::SaveBlocksDialog> dialog =
83  new(std::nothrow) Kwave::SaveBlocksDialog(
84  _("kfiledialog:///kwave_save_blocks"),
86  parentWidget(),
87  QUrl::fromUserInput(signalName()),
88  _("*.wav"),
89  m_pattern,
92  enable_selection_only
93  );
94  if (!dialog) return Q_NULLPTR;
95 
96  // connect the signals/slots from the plugin and the dialog
97  connect(dialog, SIGNAL(sigSelectionChanged(QString,
99  this, SLOT(updateExample(QString,QString,
101  connect(this, SIGNAL(sigNewExample(QString)),
102  dialog, SLOT(setNewExample(QString)));
103 
104  dialog->setWindowTitle(description());
105  dialog->emitUpdate();
106  if (dialog->exec() != QDialog::Accepted) {
107  delete dialog;
108  return Q_NULLPTR;
109  }
110 
111  QStringList *list = new(std::nothrow) QStringList();
112  Q_ASSERT(list);
113  if (list) {
114  // user has pressed "OK"
115  QString pattern;
116 
117  QUrl url = dialog->selectedUrl();
118  if (url.isEmpty()) {
119  delete dialog;
120  delete list;
121  return Q_NULLPTR;
122  }
123  QString name = url.path();
124  QFileInfo path(name);
125 
126  // add the correct extension if necessary
127  if (!path.suffix().length()) {
128  QString ext = dialog->selectedExtension();
129  QStringList extensions = ext.split(_(" "));
130  ext = extensions.first();
131  name += ext.mid(1);
132  path = name;
133  url.setPath(name);
134  }
135 
136  name = Kwave::Parser::escape(name);
137  pattern = Kwave::Parser::escape(dialog->pattern());
138  int mode = static_cast<int>(dialog->numberingMode());
139  bool selection_only = (enable_selection_only) ?
140  dialog->selectionOnly() : m_selection_only;
141 
142  *list << name;
143  *list << pattern;
144  *list << QString::number(mode);
145  *list << QString::number(selection_only);
146 
147  emitCommand(_("plugin:execute(saveblocks,") +
148  name + _(",") + pattern + _(",") +
149  QString::number(mode) + _(",") +
150  QString::number(selection_only) + _(")")
151  );
152  }
153 
154  if (dialog) delete dialog;
155  return list;
156 }
static QString encodingFilter()
void emitCommand(const QString &command)
Definition: Plugin.cpp:510
numbering_mode_t m_numbering_mode
QString findBase(const QString &filename, const QString &pattern)
void updateExample(const QString &filename, const QString &pattern, Kwave::SaveBlocksPlugin::numbering_mode_t mode, bool selection_only)
QWidget * parentWidget() const
Definition: Plugin.cpp:450
virtual QString name() const
Definition: Plugin.cpp:196
quint64 sample_index_t
Definition: Sample.h:28
bool connect(Kwave::StreamObject &source, const char *output, Kwave::StreamObject &sink, const char *input)
Definition: Connect.cpp:48
virtual sample_index_t signalLength()
Definition: Plugin.cpp:462
QString signalName()
Definition: Plugin.cpp:456
int interpreteParameters(QStringList &params)
#define _(m)
Definition: memcpy.c:66
void sigNewExample(const QString &example)
static QString escape(const QString &text)
Definition: Parser.cpp:277
virtual QString description() const
Definition: Plugin.cpp:202
void scanBlocksToSave(const QString &base, bool selection_only)
virtual sample_index_t selection(QList< unsigned int > *tracks=Q_NULLPTR, sample_index_t *left=Q_NULLPTR, sample_index_t *right=Q_NULLPTR, bool expand_if_empty=false)
Definition: Plugin.cpp:480
Here is the call graph for this function:

◆ sigNewExample

void Kwave::SaveBlocksPlugin::sigNewExample ( const QString &  example)
signal

emitted by updateExample to update the filename preview

Referenced by setup(), and updateExample().

Here is the caller graph for this function:

◆ start()

int Kwave::SaveBlocksPlugin::start ( QStringList &  params)
virtual

Saves the files, using the settings made in "setup()"

See also
Kwave::Plugin::start()

Reimplemented from Kwave::Plugin.

Definition at line 184 of file SaveBlocksPlugin.cpp.

References _, createDisplayList(), createFileName(), DBG, Kwave::CodecManager::encoder(), findBase(), firstIndex(), Kwave::FileInfo::get(), Kwave::INF_NAME, interpreteParameters(), Kwave::MetaData::isNull(), m_block_info, m_numbering_mode, m_pattern, m_selection_only, m_url, Kwave::SignalManager::metaData(), Kwave::CodecManager::mimeTypeOf(), Kwave::Plugin::name(), Kwave::Plugin::parentWidget(), Kwave::Label::pos(), Kwave::FileInfo::properties(), Kwave::MetaDataList::replace(), scanBlocksToSave(), Kwave::Plugin::selection(), Kwave::Plugin::selectRange(), Kwave::FileInfo::set(), Kwave::Plugin::signalLength(), Kwave::Plugin::signalManager(), Kwave::Parser::unescape(), Kwave::Encoder::unsupportedProperties(), Kwave::MessageBox::warningContinueCancel(), and Kwave::MessageBox::warningYesNo().

185 {
186  qDebug("SaveBlocksPlugin::start()");
187 
188  // interpret the parameters
189  int result = interpreteParameters(params);
190  if (result) return result;
191 
192  QString filename = m_url.path();
193  QFileInfo file(filename);
194  QString path = file.absolutePath();
195  QString ext = file.suffix();
196  QString base = findBase(filename, m_pattern);
197  QByteArray sep("/");
198 
199  // determine the selection settings
200  sample_index_t selection_left = 0;
201  sample_index_t selection_right = 0;
202  selection(Q_NULLPTR, &selection_left, &selection_right, false);
203 
204  bool selected_something = (selection_left != selection_right);
205  bool selected_all = ( (selection_left == 0) &&
206  ((selection_right + 1) >= signalLength()) );
207  bool enable_selection_only = selected_something && !selected_all;
208  bool selection_only = enable_selection_only && m_selection_only;
209  if (!selection_only) {
210  selection_left = 0;
211  selection_right = signalLength() - 1;
212  }
213 
214  // get the index range
215  scanBlocksToSave(base, selection_only);
216  unsigned int count = m_block_info.count();
217  unsigned int first = firstIndex(path, base, ext, m_pattern,
218  m_numbering_mode, count);
219 
220 // qDebug("m_url = '%s'", m_url.prettyURL().local8Bit().data());
221 // qDebug("m_pattern = '%s'", m_pattern.local8Bit().data());
222 // qDebug("m_numbering_mode = %d", (int)m_numbering_mode);
223 // qDebug("selection_only = %d", selection_only);
224 // qDebug("indices = %u...%u (count=%u)", first, first+count-1,count);
225 
226  // remember the original file info and determine the list of unsupported
227  // properties, we need that later to avoid that the signal manager
228  // complains on saving each and every block, again and again...
229  const Kwave::FileInfo orig_file_info(signalManager().metaData());
230  Kwave::FileInfo file_info(orig_file_info);
231  QList<Kwave::FileProperty> unsupported_properties;
232  {
233  QString mimetype = Kwave::CodecManager::mimeTypeOf(m_url);
234  Kwave::Encoder *encoder = Kwave::CodecManager::encoder(mimetype);
235  if (encoder) {
236  unsupported_properties = encoder->unsupportedProperties(
237  file_info.properties().keys());
238  delete encoder;
239  }
240  }
241 
242  // iterate over all blocks to check for overwritten files and missing dirs
243  QStringList overwritten_files;
244  QStringList missing_dirs;
245  for (unsigned int i = first; i < (first + count); i++) {
246  QString name = createFileName(base, ext, m_pattern, i, count,
247  first + count - 1);
248  QString display_name = Kwave::Parser::unescape(name);
249 
250  // split the name into directory and file name
251  name = QString::fromLatin1(QUrl::toPercentEncoding(display_name, sep));
252  QUrl url = m_url.adjusted(QUrl::RemoveFilename);
253  url.setPath(url.path(QUrl::FullyEncoded) + name, QUrl::StrictMode);
254 
255  QString p = url.path();
256  QFileInfo fi(p);
257 
258  // check for potentially overwritten file
259  if (fi.exists())
260  overwritten_files += Kwave::Parser::unescape(display_name);
261 
262  // check for missing subdirectory
263  if (!fi.dir().exists()) {
264  QString missing_dir = fi.absolutePath();
265  if (!missing_dirs.contains(missing_dir))
266  missing_dirs += missing_dir;
267  }
268  }
269 
270  // inform about overwritten files
271  if (!overwritten_files.isEmpty()) {
272  // ask the user for confirmation if he really wants to overwrite...
274  _("<html>") +
275  i18n("This would overwrite the following file(s): %1" \
276  "Do you really want to continue?",
277  createDisplayList(overwritten_files, 5)) +
278  _("</html>") ) != KMessageBox::Yes)
279  {
280  return -1;
281  }
282  }
283 
284  // handle missing directories
285  if (!missing_dirs.isEmpty()) {
286  // ask the user if he wants to continue and create the directory
288  i18n("The following directories do not exist: %1"
289  "Do you want to create them and continue?",
290  createDisplayList(missing_dirs, 5)),
291  QString(),
292  QString(),
293  QString(),
294  _("saveblocks_create_missing_dirs")
295  ) != KMessageBox::Continue)
296  {
297  return -1;
298  }
299 
300  // create all missing directories
301  QUrl base_url = m_url.adjusted(QUrl::RemoveFilename);
302  foreach (const QString &missing, missing_dirs) {
303  QUrl url(base_url);
304  url.setPath(
305  base_url.path(QUrl::FullyEncoded) +
306  QString::fromLatin1(QUrl::toPercentEncoding(missing)),
307  QUrl::StrictMode
308  );
309  QString p = url.path();
310  QDir dir;
311  if (!dir.mkpath(p))
312  qWarning("creating path '%s' failed", DBG(p));
313  }
314  }
315 
316  // save the current selection, we have to restore it afterwards!
317  sample_index_t saved_selection_left = 0;
318  sample_index_t saved_selection_right = 0;
319  selection(Q_NULLPTR, &saved_selection_left, &saved_selection_right, false);
320 
321  // now we can loop over all blocks and save them
322  sample_index_t block_start;
323  sample_index_t block_end = 0;
324  Kwave::LabelList labels(signalManager().metaData());
325  Kwave::LabelListIterator it(labels);
326  Kwave::Label label = it.hasNext() ? it.next() : Kwave::Label();
327 
328  for (unsigned int index = first;;) {
329  block_start = block_end;
330  block_end = (label.isNull()) ? signalLength() : label.pos();
331 
332  if ((selection_left < block_end) && (selection_right > block_start)) {
333  // found a block to save...
334  Q_ASSERT(index < first + count);
335 
336  sample_index_t left = block_start;
337  sample_index_t right = block_end - 1;
338  if (left < selection_left) left = selection_left;
339  if (right > selection_right) right = selection_right;
340  Q_ASSERT(right > left);
341  if (right <= left) break; // zero-length ?
342 
343  // select the range of samples
344  selectRange(left, right - left + 1);
345 
346  // determine the filename
347  QString name = createFileName(base, ext, m_pattern, index, count,
348  first + count - 1);
349  name = Kwave::Parser::unescape(name);
350  // use URL encoding for the filename
351  name = QString::fromLatin1(QUrl::toPercentEncoding(name, sep));
352  QUrl url = m_url.adjusted(QUrl::RemoveFilename);
353  url.setPath(url.path(QUrl::FullyEncoded) + name, QUrl::StrictMode);
354 
355  // enter the title of the block into the meta data if supported
356  if (!unsupported_properties.contains(INF_NAME)) {
357  QString title = orig_file_info.get(INF_NAME).toString();
358  int idx = index - first;
359  if ((idx >= 0) && (idx < m_block_info.count())) {
360  QString block_title = m_block_info[idx].m_title;
361  if (block_title.length())
362  title = title + _(", ") + block_title;
363  }
364  file_info.set(INF_NAME, QVariant(title));
366  Kwave::MetaDataList(file_info));
367  }
368 
369  qDebug("saving %9lu...%9lu -> '%s'",
370  static_cast<unsigned long int>(left),
371  static_cast<unsigned long int>(right),
372  DBG(url.toDisplayString()));
373  if (signalManager().save(url, true) < 0)
374  break;
375 
376  // if there were unsupported properties, the user might have been
377  // asked whether it is ok to continue or not. If he answered with
378  // "Cancel", we do not reach this point, otherwise we can continue
379  // and prevent any further annoying questions by removing all
380  // unsupported file info before the next run...
381  if ((index == first) && !unsupported_properties.isEmpty()) {
382  foreach (const Kwave::FileProperty &p, unsupported_properties) {
383  file_info.set(p, QVariant());
384  }
386  Kwave::MetaDataList(file_info));
387  }
388 
389  // increment the index for the next filename
390  index++;
391  }
392  if (label.isNull()) break;
393  label = (it.hasNext()) ? it.next() : Kwave::Label();
394  }
395 
396  // restore the original file info
398  Kwave::MetaDataList(orig_file_info));
399 
400  // restore the previous selection
401  selectRange(saved_selection_left,
402  (saved_selection_left != saved_selection_right) ?
403  (saved_selection_right - saved_selection_left + 1) : 0);
404 
405  return result;
406 }
QString createFileName(const QString &base, const QString &ext, const QString &pattern, unsigned int index, int count, int total)
numbering_mode_t m_numbering_mode
QList< BlockInfo > m_block_info
QString findBase(const QString &filename, const QString &pattern)
QWidget * parentWidget() const
Definition: Plugin.cpp:450
Kwave::MetaDataList & metaData()
Kwave::SignalManager & signalManager()
Definition: Plugin.cpp:444
virtual QString name() const
Definition: Plugin.cpp:196
virtual sample_index_t pos() const
Definition: Label.cpp:56
quint64 sample_index_t
Definition: Sample.h:28
static QString mimeTypeOf(const QUrl &url)
QListIterator< Kwave::Label > LabelListIterator
Definition: LabelList.h:76
static QString unescape(const QString &text)
Definition: Parser.cpp:314
virtual QList< Kwave::FileProperty > unsupportedProperties(const QList< Kwave::FileProperty > &properties_to_check)
Definition: Encoder.cpp:27
virtual bool isNull() const
Definition: MetaData.cpp:69
QString createDisplayList(const QStringList &list, unsigned int max_entries) const
virtual void replace(const MetaDataList &list)
unsigned int firstIndex(const QString &path, const QString &base, const QString &ext, const QString &pattern, Kwave::SaveBlocksPlugin::numbering_mode_t mode, unsigned int count)
virtual sample_index_t signalLength()
Definition: Plugin.cpp:462
static int warningYesNo(QWidget *widget, QString message, QString caption=QString(), const QString buttonYes=QString(), const QString buttonNo=QString(), const QString &dontAskAgainName=QString())
Definition: MessageBox.cpp:93
int interpreteParameters(QStringList &params)
static int warningContinueCancel(QWidget *widget, QString message, QString caption=QString(), const QString buttonContinue=QString(), const QString buttonCancel=QString(), const QString &dontAskAgainName=QString())
Definition: MessageBox.cpp:115
virtual void selectRange(sample_index_t offset, sample_index_t length)
Definition: Plugin.cpp:504
static Kwave::Encoder * encoder(const QString &mimetype_name)
#define _(m)
Definition: memcpy.c:66
#define DBG(qs)
Definition: String.h:55
FileProperty
Definition: FileInfo.h:45
void scanBlocksToSave(const QString &base, bool selection_only)
virtual sample_index_t selection(QList< unsigned int > *tracks=Q_NULLPTR, sample_index_t *left=Q_NULLPTR, sample_index_t *right=Q_NULLPTR, bool expand_if_empty=false)
Definition: Plugin.cpp:480
Here is the call graph for this function:

◆ updateExample

void Kwave::SaveBlocksPlugin::updateExample ( const QString &  filename,
const QString &  pattern,
Kwave::SaveBlocksPlugin::numbering_mode_t  mode,
bool  selection_only 
)
privateslot

called whenever the selection has changed and a new example has to be shown.

Parameters
filenamethe currently selected filename, including path
patternthe selected filename pattern
modethe numbering mode
selection_onlyif true: save only the selection

Definition at line 734 of file SaveBlocksPlugin.cpp.

References firstFileName(), sigNewExample(), and Kwave::Parser::unescape().

Referenced by setup().

737 {
738  QString example = firstFileName(filename, pattern, mode, selection_only);
739  emit sigNewExample(Kwave::Parser::unescape(example));
740 }
QString firstFileName(const QString &filename, const QString &pattern, numbering_mode_t mode, bool selection_only)
static QString unescape(const QString &text)
Definition: Parser.cpp:314
void sigNewExample(const QString &example)
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ m_block_info

QList<BlockInfo> Kwave::SaveBlocksPlugin::m_block_info
private

list of all blocks to save

Definition at line 192 of file SaveBlocksPlugin.h.

Referenced by createFileName(), firstFileName(), scanBlocksToSave(), and start().

◆ m_numbering_mode

numbering_mode_t Kwave::SaveBlocksPlugin::m_numbering_mode
private

mode for numbering the output files

Definition at line 186 of file SaveBlocksPlugin.h.

Referenced by interpreteParameters(), setup(), and start().

◆ m_pattern

QString Kwave::SaveBlocksPlugin::m_pattern
private

expression with the filename pattern

Definition at line 183 of file SaveBlocksPlugin.h.

Referenced by interpreteParameters(), setup(), and start().

◆ m_selection_only

bool Kwave::SaveBlocksPlugin::m_selection_only
private

if true, only save stuff within the selection

Definition at line 189 of file SaveBlocksPlugin.h.

Referenced by interpreteParameters(), setup(), and start().

◆ m_url

QUrl Kwave::SaveBlocksPlugin::m_url
private

the URL of the first file (user selection)

Definition at line 180 of file SaveBlocksPlugin.h.

Referenced by interpreteParameters(), setup(), and start().


The documentation for this class was generated from the following files: