kwave  18.07.70
Kwave::FileContext Class Reference

#include <FileContext.h>

Inheritance diagram for Kwave::FileContext:
Inheritance graph
Collaboration diagram for Kwave::FileContext:
Collaboration graph

Classes

class  UsageGuard
 

Public Slots

int executeCommand (const QString &command)
 

Signals

void sigStatusBarMessage (const QString &message, unsigned int ms)
 
void sigZoomChanged (Kwave::FileContext *context, double zoom)
 
void sigMetaDataChanged (Kwave::MetaDataList meta_data)
 
void sigSelectionChanged (sample_index_t offset, sample_index_t length)
 
void sigUndoRedoInfo (const QString &undo, const QString &redo)
 
void sigVisibleRangeChanged (sample_index_t offset, sample_index_t visible, sample_index_t total)
 
void sigModified ()
 
void destroyed (Kwave::FileContext *context)
 

Public Member Functions

 FileContext (Kwave::App &app)
 
virtual ~FileContext ()
 
bool init (Kwave::TopWidget *top_widget)
 
bool createMainWidget (const QSize &preferred_size)
 
void setParent (Kwave::TopWidget *top_widget)
 
Kwave::Appapp () const
 
QWidget * mainWidget () const
 
Kwave::SignalManagersignalManager () const
 
Kwave::PluginManagerpluginManager () const
 
Kwave::Zoomablezoomable () const
 
bool isEmpty () const
 
bool isActive () const
 
bool isInUse () const
 
QString signalName () const
 
int instanceNr () const
 
QString windowCaption (bool with_modified) const
 
int loadBatch (const QUrl &url)
 
int saveFile ()
 
int saveFileAs (const QString &filename, bool selection=false)
 
bool closeFile ()
 

Protected Member Functions

void use ()
 
void release ()
 

Private Slots

void contextSwitched (Kwave::FileContext *context)
 
void forwardZoomChanged (double zoom)
 
void updatePlaybackPos (sample_index_t offset)
 
void metaDataChanged (Kwave::MetaDataList meta_data)
 
void selectionChanged (sample_index_t offset, sample_index_t length)
 
void setUndoRedoInfo (const QString &undo, const QString &redo)
 
void visibleRangeChanged (sample_index_t offset, sample_index_t visible, sample_index_t total)
 
void modifiedChanged ()
 
void processDelayedCommand ()
 

Private Member Functions

void activated ()
 
void statusBarMessage (const QString &msg, unsigned int ms)
 
int parseCommands (QTextStream &stream)
 
void enqueueCommand (unsigned int delay, const QString &command)
 
int revert ()
 
int delegateCommand (const char *plugin, Kwave::Parser &parser, unsigned int param_count)
 

Private Attributes

QAtomicInt m_use_count
 
Kwave::Appm_application
 
QPointer< Kwave::TopWidgetm_top_widget
 
QPointer< Kwave::MainWidgetm_main_widget
 
QPointer< Kwave::SignalManagerm_signal_manager
 
QPointer< Kwave::PluginManagerm_plugin_manager
 
bool m_active
 
double m_last_zoom
 
sample_index_t m_last_playback_pos
 
QString m_last_status_message_text
 
QElapsedTimer m_last_status_message_timer
 
unsigned int m_last_status_message_ms
 
QString m_last_undo
 
QString m_last_redo
 
int m_instance_nr
 
QTimer m_delayed_command_timer
 
QList< QPair< unsigned int, QString > > m_delayed_command_queue
 

Friends

class App
 
class TopWidget
 
class UsageGuard
 

Detailed Description

Definition at line 55 of file FileContext.h.

Constructor & Destructor Documentation

◆ FileContext()

Kwave::FileContext::FileContext ( Kwave::App app)
explicit

Constructor. Creates a new toplevel window, signal manager, plugin manager and so on.

Parameters
appreference to the Kwave application

Definition at line 69 of file FileContext.cpp.

References Kwave::connect(), m_delayed_command_timer, and processDelayedCommand().

70  :QObject(),
71  m_use_count(1),
72  m_application(app),
73  m_top_widget(Q_NULLPTR),
74  m_main_widget(Q_NULLPTR),
75  m_signal_manager(Q_NULLPTR),
76  m_plugin_manager(Q_NULLPTR),
77  m_active(true),
78  m_last_zoom(0),
83  m_last_undo(QString()),
84  m_last_redo(QString()),
85  m_instance_nr(-1),
88 {
89  m_delayed_command_timer.setSingleShot(true);
90  connect(&m_delayed_command_timer, SIGNAL(timeout()),
91  this, SLOT(processDelayedCommand()));
92 }
QPointer< Kwave::MainWidget > m_main_widget
Definition: FileContext.h:398
QTimer m_delayed_command_timer
Definition: FileContext.h:434
QElapsedTimer m_last_status_message_timer
Definition: FileContext.h:419
QList< QPair< unsigned int, QString > > m_delayed_command_queue
Definition: FileContext.h:437
void processDelayedCommand()
bool connect(Kwave::StreamObject &source, const char *output, Kwave::StreamObject &sink, const char *input)
Definition: Connect.cpp:48
QAtomicInt m_use_count
Definition: FileContext.h:389
sample_index_t m_last_playback_pos
Definition: FileContext.h:413
QPointer< Kwave::PluginManager > m_plugin_manager
Definition: FileContext.h:404
QPointer< Kwave::SignalManager > m_signal_manager
Definition: FileContext.h:401
QString m_last_status_message_text
Definition: FileContext.h:416
unsigned int m_last_status_message_ms
Definition: FileContext.h:422
QPointer< Kwave::TopWidget > m_top_widget
Definition: FileContext.h:395
Kwave::App & m_application
Definition: FileContext.h:392
Here is the call graph for this function:

◆ ~FileContext()

Kwave::FileContext::~FileContext ( )
virtual

Destructor

Definition at line 95 of file FileContext.cpp.

References m_main_widget, m_plugin_manager, m_signal_manager, and m_top_widget.

96 {
97  if (m_main_widget) delete m_main_widget;
98  m_main_widget = Q_NULLPTR;
99 
100  m_top_widget = Q_NULLPTR;
101 
103  m_plugin_manager = Q_NULLPTR;
104 
106  m_signal_manager = Q_NULLPTR;
107 }
QPointer< Kwave::MainWidget > m_main_widget
Definition: FileContext.h:398
QPointer< Kwave::PluginManager > m_plugin_manager
Definition: FileContext.h:404
QPointer< Kwave::SignalManager > m_signal_manager
Definition: FileContext.h:401
QPointer< Kwave::TopWidget > m_top_widget
Definition: FileContext.h:395

Member Function Documentation

◆ activated()

void Kwave::FileContext::activated ( )
private

should be called when this context got active, to update the status bar, toolbar etc.

Definition at line 619 of file FileContext.cpp.

References forwardZoomChanged(), m_last_playback_pos, m_last_redo, m_last_status_message_ms, m_last_status_message_text, m_last_status_message_timer, m_last_undo, m_last_zoom, m_main_widget, m_plugin_manager, m_signal_manager, sigMetaDataChanged(), sigModified(), sigStatusBarMessage(), sigUndoRedoInfo(), sigVisibleRangeChanged(), Kwave::toUint(), and updatePlaybackPos().

Referenced by contextSwitched().

620 {
621  // let our plugin manager be the active one
622  if (m_plugin_manager) m_plugin_manager->setActive();
623 
624  // emit last playback position if playback is running
625  if (m_signal_manager && m_signal_manager->playbackController().running())
627 
628  // emit last zoom factor
630 
631  // erase the status message of the previous context
632  emit sigStatusBarMessage(QString(), 0);
633 
634  // emit our last status bar message if it has not expired
635  if (m_last_status_message_timer.isValid()) {
636  quint64 elapsed = m_last_status_message_timer.elapsed();
637  if (elapsed < m_last_status_message_ms) {
638  unsigned int remaining =
641  } else
642  m_last_status_message_timer.invalidate();
643  } else if (m_last_status_message_ms == 0) {
644  // static message without expiration
645  if (m_last_status_message_text.length()) {
647  }
648  }
649 
650  // emit latest meta data
651  if (m_signal_manager)
652  emit sigMetaDataChanged(m_signal_manager->metaData());
653 
654  // emit latest view range change
656  sample_index_t offset = m_main_widget->visibleOffset();
657  sample_index_t visible = m_main_widget->visibleSamples();
658  sample_index_t total = m_signal_manager->length();
659  emit sigVisibleRangeChanged(offset, visible, total);
660  }
661 
662  // force update of the "modified" state
663  emit sigModified();
664 
665  // emit last undo/redo info
667 
668 }
QPointer< Kwave::MainWidget > m_main_widget
Definition: FileContext.h:398
void forwardZoomChanged(double zoom)
QElapsedTimer m_last_status_message_timer
Definition: FileContext.h:419
void sigMetaDataChanged(Kwave::MetaDataList meta_data)
quint64 sample_index_t
Definition: Sample.h:28
void sigVisibleRangeChanged(sample_index_t offset, sample_index_t visible, sample_index_t total)
sample_index_t m_last_playback_pos
Definition: FileContext.h:413
void sigStatusBarMessage(const QString &message, unsigned int ms)
QPointer< Kwave::PluginManager > m_plugin_manager
Definition: FileContext.h:404
QPointer< Kwave::SignalManager > m_signal_manager
Definition: FileContext.h:401
QString m_last_status_message_text
Definition: FileContext.h:416
void updatePlaybackPos(sample_index_t offset)
unsigned int toUint(T x)
Definition: Utils.h:109
unsigned int m_last_status_message_ms
Definition: FileContext.h:422
void sigUndoRedoInfo(const QString &undo, const QString &redo)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ app()

Kwave::App& Kwave::FileContext::app ( ) const
inline

returns a reference to the application instance

Definition at line 93 of file FileContext.h.

Referenced by Kwave::MainWidget::resizeEvent().

93 { return m_application; }
Kwave::App & m_application
Definition: FileContext.h:392
Here is the caller graph for this function:

◆ closeFile()

bool Kwave::FileContext::closeFile ( )

Closes the current file. If the file has been modified and the user wanted to cancel the close operation, the file will not get closed and the function returns with false.

Returns
true if closing is allowed, false if canceled

Definition at line 1060 of file FileContext.cpp.

References Kwave::App::GUI_MDI, Kwave::App::GUI_SDI, Kwave::App::GUI_TAB, Kwave::App::guiType(), m_application, m_main_widget, m_plugin_manager, m_signal_manager, m_top_widget, saveFile(), and Kwave::MessageBox::warningYesNoCancel().

Referenced by Kwave::TopWidget::closeAllSubWindows(), Kwave::MainWidget::closeEvent(), executeCommand(), Kwave::TopWidget::loadFile(), and Kwave::TopWidget::newWindow().

1061 {
1062  Kwave::FileContext::UsageGuard _keep(this);
1063 
1064  if (m_plugin_manager && !m_plugin_manager->canClose())
1065  {
1066  qWarning("FileContext::closeFile() - currently not possible, "\
1067  "a plugin is running :-(");
1068  return false;
1069  }
1070 
1071  if (m_signal_manager && m_signal_manager->isModified()) {
1073  i18n("This file has been modified.\nDo you want to save it?"));
1074  if (res == KMessageBox::Cancel) return false;
1075  if (res == KMessageBox::Yes) {
1076  // user decided to save
1077  res = saveFile();
1078  qDebug("FileContext::closeFile()::saveFile, res=%d",res);
1079  if (res) return false;
1080  }
1081  }
1082 
1083  // close all plugins that still might use the current signal
1084  if (m_plugin_manager) {
1085  m_plugin_manager->stopAllPlugins();
1086  m_plugin_manager->signalClosed();
1087  }
1088 
1089  if (m_signal_manager) m_signal_manager->close();
1090 
1091  switch (m_application.guiType()) {
1092  case Kwave::App::GUI_MDI: /* FALLTHROUGH */
1093  case Kwave::App::GUI_TAB:
1094  // close the main widget
1095  if (m_main_widget) delete m_main_widget;
1096  break;
1097  case Kwave::App::GUI_SDI:
1098  break;
1099  }
1100 
1101  return true;
1102 }
QPointer< Kwave::MainWidget > m_main_widget
Definition: FileContext.h:398
GuiType guiType() const
Definition: App.h:119
static int warningYesNoCancel(QWidget *widget, QString message, QString caption=QString(), const QString buttonYes=QString(), const QString buttonNo=QString(), const QString &dontAskAgainName=QString())
Definition: MessageBox.cpp:104
QPointer< Kwave::PluginManager > m_plugin_manager
Definition: FileContext.h:404
QPointer< Kwave::SignalManager > m_signal_manager
Definition: FileContext.h:401
QPointer< Kwave::TopWidget > m_top_widget
Definition: FileContext.h:395
Kwave::App & m_application
Definition: FileContext.h:392
Here is the call graph for this function:
Here is the caller graph for this function:

◆ contextSwitched

void Kwave::FileContext::contextSwitched ( Kwave::FileContext context)
privateslot

called when the current file context has changed

Parameters
contextthe new file context (can be "this")

Definition at line 605 of file FileContext.cpp.

References activated(), and m_active.

Referenced by setParent().

606 {
607  Kwave::FileContext::UsageGuard _keep(this);
608 
609  if (context == this) {
610  if (!m_active) {
611  m_active = true;
612  activated();
613  }
614  } else
615  m_active = false;
616 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ createMainWidget()

bool Kwave::FileContext::createMainWidget ( const QSize &  preferred_size)

create a main widget, within the MDI area or toplevel widget in case of SDI interface

Parameters
preferred_sizepreferred size of the main widget
Returns
true if successful, false if failed

Definition at line 127 of file FileContext.cpp.

References Kwave::connect(), executeCommand(), forwardZoomChanged(), m_main_widget, m_signal_manager, m_top_widget, sigVisibleRangeChanged(), sigZoomChanged(), and visibleRangeChanged().

Referenced by Kwave::TopWidget::init(), Kwave::TopWidget::insertContext(), and Kwave::TopWidget::newWindow().

128 {
129  Q_ASSERT(!m_main_widget);
130 
131  // create the main widget
132  m_main_widget = new(std::nothrow) Kwave::MainWidget(
133  m_top_widget, *this, preferred_size
134  );
135  Q_ASSERT(m_main_widget);
136  if (!m_main_widget) return false;
137  if (!(m_main_widget->isOK())) {
138  delete m_main_widget;
139  m_main_widget = Q_NULLPTR;
140  return false;
141  }
142 
143  // connect the main widget
144  connect(&(m_signal_manager->playbackController()),
145  SIGNAL(sigSeekDone(sample_index_t)),
146  m_main_widget, SLOT(scrollTo(sample_index_t)));
147  connect(m_main_widget, SIGNAL(sigCommand(QString)),
148  this, SLOT(executeCommand(QString)));
149  connect(m_main_widget, SIGNAL(sigZoomChanged(double)),
150  this, SLOT(forwardZoomChanged(double)));
155 
156  return true;
157 }
QPointer< Kwave::MainWidget > m_main_widget
Definition: FileContext.h:398
void forwardZoomChanged(double zoom)
void sigZoomChanged(Kwave::FileContext *context, double zoom)
quint64 sample_index_t
Definition: Sample.h:28
void sigVisibleRangeChanged(sample_index_t offset, sample_index_t visible, sample_index_t total)
bool connect(Kwave::StreamObject &source, const char *output, Kwave::StreamObject &sink, const char *input)
Definition: Connect.cpp:48
QPointer< Kwave::SignalManager > m_signal_manager
Definition: FileContext.h:401
void visibleRangeChanged(sample_index_t offset, sample_index_t visible, sample_index_t total)
QPointer< Kwave::TopWidget > m_top_widget
Definition: FileContext.h:395
int executeCommand(const QString &command)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ delegateCommand()

int Kwave::FileContext::delegateCommand ( const char *  plugin,
Kwave::Parser parser,
unsigned int  param_count 
)
private

delegate a command to a plugin

Parameters
pluginname of a plugin to delegate the command to
parserthe parser with the parts of the command
param_countrequired number of parameters

Definition at line 296 of file FileContext.cpp.

References _, Kwave::Parser::command(), Kwave::Parser::count(), m_plugin_manager, and Kwave::Parser::remainingParams().

Referenced by executeCommand().

299 {
300  if (!m_plugin_manager) return -1;
301  if (parser.count() != param_count) return -EINVAL;
302 
303  QStringList params;
304  params.append(parser.command());
305  params.append(parser.remainingParams());
306  int result = m_plugin_manager->setupPlugin(_(plugin), params);
307  if (result > 0) result = 0;
308  return result;
309 }
QPointer< Kwave::PluginManager > m_plugin_manager
Definition: FileContext.h:404
#define _(m)
Definition: memcpy.c:66
QStringList remainingParams()
Definition: Parser.cpp:189
unsigned int count() const
Definition: Parser.h:75
QString command()
Definition: Parser.h:47
Here is the call graph for this function:
Here is the caller graph for this function:

◆ destroyed

void Kwave::FileContext::destroyed ( Kwave::FileContext context)
signal

emitted when the context is about to be destroyed (in the context of it's destructor)

◆ enqueueCommand()

void Kwave::FileContext::enqueueCommand ( unsigned int  delay,
const QString &  command 
)
private

enqueues a command for later execution

Parameters
delaymilliseconds to wait before execution
commandthe command to execute

Definition at line 795 of file FileContext.cpp.

References m_delayed_command_queue, m_delayed_command_timer, and use().

Referenced by executeCommand().

797 {
798  use();
799 
801  QPair<unsigned int, QString>(delay, command)
802  );
803  if (!m_delayed_command_timer.isActive())
804  m_delayed_command_timer.start(delay);
805 }
QTimer m_delayed_command_timer
Definition: FileContext.h:434
QList< QPair< unsigned int, QString > > m_delayed_command_queue
Definition: FileContext.h:437
Here is the call graph for this function:
Here is the caller graph for this function:

◆ executeCommand

int Kwave::FileContext::executeCommand ( const QString &  command)
slot

Execute a Kwave text command

Parameters
commanda text command
Returns
zero if succeeded or negative error code if failed

Definition at line 312 of file FileContext.cpp.

References _, CASE_COMMAND, closeFile(), Kwave::Parser::command(), Kwave::Parser::commandList(), Kwave::Parser::count(), DBG, delegateCommand(), enqueueCommand(), Kwave::CommandHandler::executeCommand(), Kwave::Parser::firstParam(), Kwave::Parser::hasMultipleCommands(), Kwave::Logger::Info, loadBatch(), Kwave::Logger::log(), m_delayed_command_queue, m_main_widget, m_plugin_manager, m_top_widget, name, Kwave::Parser::nextParam(), Kwave::Parser::remainingParams(), revert(), saveFile(), and saveFileAs().

Referenced by createMainWidget(), Kwave::TopWidget::forwardCommand(), init(), Kwave::TopWidget::loadFile(), parseCommands(), and processDelayedCommand().

313 {
314  Kwave::FileContext::UsageGuard _keep(this);
315 
316  int result = 0;
317  bool use_recorder = true;
318  QString command = line;
319 
320 // qDebug("Kwave::FileContext[%p]::executeCommand(%s)", this, DBG(command));
321 
322  Q_ASSERT(m_plugin_manager);
323  Q_ASSERT(m_top_widget);
324  if (!m_plugin_manager || !m_top_widget) return -ENOMEM;
325 
326  if (!command.length()) return 0; // empty line -> nothing to do
327  if (command.trimmed().startsWith(_("#")))
328  return 0; // only a comment
329 
330  // special case: if the command contains ";" it is a list of
331  // commands -> macro !
332  Kwave::Parser parse_list(command);
333  if (parse_list.hasMultipleCommands()) {
334  QStringList macro = parse_list.commandList();
335  foreach (const QString &it, macro) {
336  result = executeCommand(_("nomacro:") + it);
337  Q_ASSERT(!result);
338  if (result) {
339  qWarning("macro execution of '%s' failed: %d",
340  DBG(it), result);
341  return result; // macro failed :-(
342  }
343 
344  // wait until the command has completed !
345  m_plugin_manager->sync();
346  }
347  return result;
348  }
349 
350  // check if the macro recorder has to be disabled for this command
351  if (command.startsWith(_("nomacro:"))) {
352  use_recorder = false;
353  command = command.mid(QString(_("nomacro:")).length());
354  }
355 
356  // expand variables
357  if (command.contains(_("${"))) {
358  // current language
359  if (command.contains(_("${LANG}"))) {
360  QLocale locale;
361  if (!m_main_widget.isNull()) locale = m_main_widget->locale();
362  QString lang = locale.name().split(_("-")).at(0);
363  command.replace(_("${LANG}"), lang);
364  }
365  }
366 
367  // log all commands to the log file if enabled
368  Kwave::Logger::log(this, Kwave::Logger::Info, _("CMD: ") + line);
369 
370  // parse one single command
371  Kwave::Parser parser(command);
372  QString cmd = parser.command();
373 
374  // exclude menu commands from the recorder
375  if (cmd == _("menu")) use_recorder = false;
376 
377  // only record plugin:execute, not plugin without parameters
378  if (cmd == _("plugin")) use_recorder = false;
379 
380  // let through all commands that handle zoom/view or playback like fwd/rew
381  bool allow_always =
382  (cmd == _("playback")) ||
383  cmd.startsWith(_("view:")) ||
384  cmd.startsWith(_("playback:")) ||
385  cmd.startsWith(_("select_track:")) ||
386  (cmd == _("close")) ||
387  (cmd == _("quit")) ||
388  (cmd == _("window:screenshot")) ||
389  (cmd == _("window:sendkey"))
390  ;
391 
392  // all others only if no plugin is currently running
393  if (!allow_always && m_plugin_manager->onePluginRunning())
394  {
395  qWarning("FileContext::executeCommand('%s') - currently not possible, "
396  "a plugin is running :-(",
397  DBG(cmd));
398  return -1;
399  }
400 
401  if (use_recorder) {
402  // append the command to the macro recorder
403  // @TODO macro recording...
404  qDebug("# %s ", DBG(command));
405  }
406 
407  if ((result = m_top_widget->executeCommand(command)) != ENOSYS)
408  return result;
409 
410  if (false) {
411  CASE_COMMAND("close")
412  result = closeFile() ? 0 : 1;
413  CASE_COMMAND("delayed")
414  if (parser.count() != 2)
415  return -EINVAL;
416  unsigned int delay = parser.firstParam().toUInt();
417  QString delayed_cmd = parser.nextParam();
418  enqueueCommand(delay, delayed_cmd);
419  result = 0;
420  CASE_COMMAND("loadbatch")
421  result = loadBatch(QUrl(parser.nextParam()));
422  CASE_COMMAND("plugin")
423  QString name(parser.firstParam());
424  QStringList params(parser.remainingParams());
425  qDebug("FileContext::executeCommand(): loading plugin '%s'", DBG(name));
426  qDebug("FileContext::executeCommand(): with %d parameter(s)",
427  params.count());
428  result = m_plugin_manager->executePlugin(
429  name, params.count() ? &params : Q_NULLPTR);
430  CASE_COMMAND("plugin:execute")
431  QString name(parser.firstParam());
432  QStringList params(parser.remainingParams());
433  result = m_plugin_manager->executePlugin(name, &params);
434  CASE_COMMAND("plugin:setup")
435  QString name(parser.firstParam());
436  QStringList params(parser.remainingParams());
437  result = m_plugin_manager->setupPlugin(name, params);
438  if (result > 0) result = 0;
440  result = revert();
441  CASE_COMMAND("save")
442  result = saveFile();
443  CASE_COMMAND("saveas")
444  result = saveFileAs(parser.nextParam(), false);
445  CASE_COMMAND("saveselect")
446  result = saveFileAs(QString(), true);
447  CASE_COMMAND("sync")
448  while (!m_delayed_command_queue.isEmpty()) {
449  qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
450  }
451  result = 0;
452  CASE_COMMAND("window:click")
453  result = delegateCommand("debug", parser, 3);
454  CASE_COMMAND("window:close")
455  result = delegateCommand("debug", parser, 1);
456  CASE_COMMAND("window:mousemove")
457  result = delegateCommand("debug", parser, 3);
458  CASE_COMMAND("window:resize")
459  result = delegateCommand("debug", parser, 3);
460  CASE_COMMAND("window:sendkey")
461  result = delegateCommand("debug", parser, 2);
462  CASE_COMMAND("window:screenshot")
463  result = delegateCommand("debug", parser, 2);
464  } else {
465  // pass the command to the layer below (main widget)
466  Kwave::CommandHandler *layer_below = m_main_widget;
467  result = (layer_below) ? layer_below->executeCommand(command) : -ENOSYS;
468  }
469 
470  return result;
471 }
int loadBatch(const QUrl &url)
QPointer< Kwave::MainWidget > m_main_widget
Definition: FileContext.h:398
QList< QPair< unsigned int, QString > > m_delayed_command_queue
Definition: FileContext.h:437
void enqueueCommand(unsigned int delay, const QString &command)
#define CASE_COMMAND(x)
Definition: FileContext.cpp:54
const char name[16]
Definition: memcpy.c:510
QPointer< Kwave::PluginManager > m_plugin_manager
Definition: FileContext.h:404
#define _(m)
Definition: memcpy.c:66
#define DBG(qs)
Definition: String.h:55
bool isEmpty() const
Definition: FileContext.h:117
static void Q_DECL_EXPORT log(const QObject *sender, LogLevel level, const QString &msg)
Definition: Logger.cpp:103
virtual int executeCommand(const QString &command)=0
FileContext(Kwave::App &app)
Definition: FileContext.cpp:69
int saveFileAs(const QString &filename, bool selection=false)
QPointer< Kwave::TopWidget > m_top_widget
Definition: FileContext.h:395
int executeCommand(const QString &command)
int delegateCommand(const char *plugin, Kwave::Parser &parser, unsigned int param_count)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ forwardZoomChanged

void Kwave::FileContext::forwardZoomChanged ( double  zoom)
privateslot

emits a sigZoomChanged(this, zoom) when the zoom has changed in the m_main_widget

Definition at line 474 of file FileContext.cpp.

References m_last_zoom, and sigZoomChanged().

Referenced by activated(), and createMainWidget().

475 {
476  m_last_zoom = zoom;
477  emit sigZoomChanged(this, zoom);
478 }
void sigZoomChanged(Kwave::FileContext *context, double zoom)
Here is the caller graph for this function:

◆ init()

bool Kwave::FileContext::init ( Kwave::TopWidget top_widget)

initializes the instance

Parameters
top_widgetpointer to the toplevel widget
Returns
true if successful

Definition at line 160 of file FileContext.cpp.

References _, Kwave::connect(), Kwave::MessageBox::error(), executeCommand(), m_plugin_manager, m_signal_manager, m_top_widget, metaDataChanged(), modifiedChanged(), parseCommands(), selectionChanged(), setParent(), setUndoRedoInfo(), Kwave::Splash::showMessage(), sigMetaDataChanged(), sigModified(), sigUndoRedoInfo(), statusBarMessage(), and updatePlaybackPos().

Referenced by Kwave::TopWidget::newFileContext().

161 {
162  Kwave::FileContext::UsageGuard _keep(this);
163 
164  m_top_widget = top_widget;
165  Q_ASSERT(m_top_widget);
166  if (!m_top_widget) return false;
167 
168  m_signal_manager = new(std::nothrow)
170  Q_ASSERT(m_signal_manager);
171  if (!m_signal_manager) return false;
172 
173  m_plugin_manager = new(std::nothrow)
175  Q_ASSERT(m_plugin_manager);
176  if (!m_plugin_manager) return false;
177 
178  // connect the signal manager
180  this, SLOT(metaDataChanged(Kwave::MetaDataList)));
181  connect(&(m_signal_manager->selection()),
182  SIGNAL(changed(sample_index_t,sample_index_t)),
183  this,
185  connect(m_signal_manager, SIGNAL(sigUndoRedoInfo(const QString&,
186  const QString&)),
187  this, SLOT(setUndoRedoInfo(QString,QString)));
189  this, SLOT(modifiedChanged()));
190 
191  // connect the plugin manager
192  connect(m_plugin_manager, SIGNAL(sigCommand(QString)),
193  this, SLOT(executeCommand(QString)));
194 
195  // connect the playback controller
196  connect(&(m_signal_manager->playbackController()),
197  SIGNAL(sigPlaybackPos(sample_index_t)),
198  this, SLOT(updatePlaybackPos(sample_index_t)));
199 
200  setParent(top_widget);
201 
202  Kwave::Splash::showMessage(i18n("Scanning plugins..."));
203  m_plugin_manager->searchPluginModules();
204 
205  // load the menu from file
206  QFile menufile(QStandardPaths::locate(
207  QStandardPaths::GenericDataLocation,
208  _("kwave/menus.config")
209  ));
210  menufile.open(QIODevice::ReadOnly);
211  QTextStream stream(&menufile);
212  Q_ASSERT(!stream.atEnd());
213  if (!stream.atEnd()) parseCommands(stream);
214  menufile.close();
215 
216  // now we are initialized, load all plugins
217  Kwave::Splash::showMessage(i18n("Loading plugins..."));
218  statusBarMessage(i18n("Loading plugins..."), 0);
219  if (!m_plugin_manager->loadAllPlugins()) {
220  statusBarMessage(i18n("Failed"), 1000);
221  QApplication::restoreOverrideCursor();
222  Kwave::MessageBox::error(top_widget,
223  i18n("Kwave has not been properly installed. "\
224  "No plugins found!")
225  );
226  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
227  return false;
228  }
229  statusBarMessage(i18n("Ready"), 1000);
230 
231  return true;
232 }
int parseCommands(QTextStream &stream)
static void showMessage(const QString &message)
Definition: Splash.cpp:115
void setParent(Kwave::TopWidget *top_widget)
void sigMetaDataChanged(Kwave::MetaDataList meta_data)
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
void metaDataChanged(Kwave::MetaDataList meta_data)
void selectionChanged(sample_index_t offset, sample_index_t length)
void statusBarMessage(const QString &msg, unsigned int ms)
static int error(QWidget *widget, QString message, QString caption=QString())
Definition: MessageBox.cpp:126
void setUndoRedoInfo(const QString &undo, const QString &redo)
QPointer< Kwave::PluginManager > m_plugin_manager
Definition: FileContext.h:404
QPointer< Kwave::SignalManager > m_signal_manager
Definition: FileContext.h:401
void updatePlaybackPos(sample_index_t offset)
#define _(m)
Definition: memcpy.c:66
QPointer< Kwave::TopWidget > m_top_widget
Definition: FileContext.h:395
int executeCommand(const QString &command)
void sigUndoRedoInfo(const QString &undo, const QString &redo)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ instanceNr()

int Kwave::FileContext::instanceNr ( ) const
inline

returns the instance of the loaded file or -1

Definition at line 136 of file FileContext.h.

Referenced by Kwave::TopWidget::openFiles().

136 { return m_instance_nr; }
Here is the caller graph for this function:

◆ isActive()

bool Kwave::FileContext::isActive ( ) const
inline

Returns whether this context is active or not.

Return values
trueif the context is active
falseif the context is inactive

Definition at line 124 of file FileContext.h.

Referenced by metaDataChanged(), modifiedChanged(), Kwave::MainWidget::resizeEvent(), selectionChanged(), setUndoRedoInfo(), statusBarMessage(), and visibleRangeChanged().

124 { return m_active; }
Here is the caller graph for this function:

◆ isEmpty()

bool Kwave::FileContext::isEmpty ( ) const
inline

Returns whether this context is empty (has a main widget) or not.

Return values
trueif the context is empty
falseif the context has a main widget

Definition at line 117 of file FileContext.h.

Referenced by Kwave::TopWidget::newWindow(), and Kwave::App::switchGuiType().

117 { return m_main_widget.isNull(); }
QPointer< Kwave::MainWidget > m_main_widget
Definition: FileContext.h:398
Here is the caller graph for this function:

◆ isInUse()

bool Kwave::FileContext::isInUse ( ) const

Returns true it this context has a signal (file is loaded) or the context is executing a script

Definition at line 823 of file FileContext.cpp.

References m_signal_manager, and m_use_count.

Referenced by Kwave::TopWidget::detachAllContexts().

824 {
825  if (m_use_count >= 2) return true;
826  return (m_signal_manager && !m_signal_manager->isEmpty());
827 }
QAtomicInt m_use_count
Definition: FileContext.h:389
QPointer< Kwave::SignalManager > m_signal_manager
Definition: FileContext.h:401
Here is the caller graph for this function:

◆ loadBatch()

int Kwave::FileContext::loadBatch ( const QUrl &  url)

Loads a batch file into memory, parses and executes all commands in it.

Parameters
urlURL of the macro (batch file) to be loaded

Definition at line 863 of file FileContext.cpp.

References parseCommands().

Referenced by executeCommand(), Kwave::TopWidget::loadFile(), and Kwave::MainWidget::loadLabels().

864 {
865  Kwave::FileContext::UsageGuard _keep(this);
866 
867  // open the URL, read-only mode is enough
868  QFile file(url.path());
869  if (!file.open(QIODevice::ReadOnly)) {
870  qWarning("unable to open source in read-only mode!");
871  return -EIO;
872  }
873 
874  // use a text stream for parsing the commands
875  QTextStream stream(&file);
876  int result = parseCommands(stream);
877  file.close();
878 
879  return result;
880 }
int parseCommands(QTextStream &stream)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mainWidget()

QWidget * Kwave::FileContext::mainWidget ( ) const

returns a pointer to the main widget of this context

Definition at line 271 of file FileContext.cpp.

References m_main_widget.

Referenced by Kwave::TopWidget::init(), Kwave::TopWidget::insertContext(), and parseCommands().

272 {
273  return static_cast<QWidget *>(m_main_widget);
274 }
QPointer< Kwave::MainWidget > m_main_widget
Definition: FileContext.h:398
Here is the caller graph for this function:

◆ metaDataChanged

void Kwave::FileContext::metaDataChanged ( Kwave::MetaDataList  meta_data)
privateslot

Called when the meta data of the current signal has changed

Parameters
meta_datathe new meta data, after the change

Definition at line 521 of file FileContext.cpp.

References Kwave::App::GUI_SDI, Kwave::App::guiType(), isActive(), m_application, m_instance_nr, m_main_widget, name, Kwave::App::openFiles(), sigMetaDataChanged(), signalName(), and windowCaption().

Referenced by init().

522 {
523  // find out the instance ID
524  if (m_instance_nr == -1) {
525  // build a list of all currently open files/instances (including this)
526  QList<Kwave::App::FileAndInstance> files = m_application.openFiles();
527 
528  // filter out all instances of our file name
529  QString our_name = signalName();
530  QList<int> existing_instances;
531  foreach (const Kwave::App::FileAndInstance &it, files) {
532  const QString &name = it.first;
533  int inst = it.second;
534  if (name == our_name) existing_instances.append(inst);
535  }
536 
537  // remove our own entry
538  if (existing_instances.contains(m_instance_nr))
539  existing_instances.removeOne(m_instance_nr);
540 
541  // find an empty slot
542  if (!existing_instances.isEmpty())
543  while (existing_instances.contains(m_instance_nr))
544  m_instance_nr = (m_instance_nr != -1) ? (m_instance_nr + 1) : 2;
545  }
546 
547  if (isActive()) {
548  // we are active -> emit the meta data immediately
549  emit sigMetaDataChanged(meta_data);
550  } // else: we are inactive -> emit the meta data later, when activated
551 
552  // update the caption of the sub window
554  m_main_widget->setWindowTitle(windowCaption(true));
555 }
bool isActive() const
Definition: FileContext.h:124
QPointer< Kwave::MainWidget > m_main_widget
Definition: FileContext.h:398
void sigMetaDataChanged(Kwave::MetaDataList meta_data)
QList< FileAndInstance > openFiles() const
Definition: App.cpp:294
QString windowCaption(bool with_modified) const
const char name[16]
Definition: memcpy.c:510
QString signalName() const
GuiType guiType() const
Definition: App.h:119
QPair< QString, int > FileAndInstance
Definition: App.h:60
Kwave::App & m_application
Definition: FileContext.h:392
Here is the call graph for this function:
Here is the caller graph for this function:

◆ modifiedChanged

void Kwave::FileContext::modifiedChanged ( )
privateslot

called if the signal now or no longer is modified

Definition at line 592 of file FileContext.cpp.

References Kwave::App::GUI_SDI, Kwave::App::guiType(), isActive(), m_application, m_main_widget, sigModified(), and windowCaption().

Referenced by init().

593 {
594  if (isActive()) {
595  // we are active -> emit the modified state immediately
596  emit sigModified();
597  } // else: we are inactive -> emit the modified state later, when activated
598 
599  // update the caption of our main widget
601  m_main_widget->setWindowTitle(windowCaption(true));
602 }
bool isActive() const
Definition: FileContext.h:124
QPointer< Kwave::MainWidget > m_main_widget
Definition: FileContext.h:398
QString windowCaption(bool with_modified) const
GuiType guiType() const
Definition: App.h:119
Kwave::App & m_application
Definition: FileContext.h:392
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parseCommands()

int Kwave::FileContext::parseCommands ( QTextStream &  stream)
private

Parses a text stream line by line and executes each line as a command until all commands are done or the first one fails.

Parameters
streama QTextStream to read from
Returns
zero if successful, non-zero error code if a command failed

Definition at line 671 of file FileContext.cpp.

References _, CASE_COMMAND, Kwave::Parser::command(), DBG, executeCommand(), Kwave::Parser::firstParam(), Kwave::label_t::hits, m_plugin_manager, m_top_widget, mainWidget(), name, Kwave::label_t::pos, and Kwave::MessageBox::questionYesNo().

Referenced by init(), and loadBatch().

672 {
673  Kwave::FileContext::UsageGuard _keep(this);
674 
675  int result = 0;
676  QMap<QString, label_t> labels;
677 
678  // set hourglass cursor
679  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
680 
681  QString label; // label, jump target of a "GOTO"
682  while (!stream.atEnd() && !result) {
683  QString line = stream.readLine().simplified();
684  if (line.startsWith(_("#"))) continue; // skip comments
685  if (!line.length()) continue; // skip empty lines
686 
687  if (line.endsWith(QLatin1Char(':'))) {
688  // this line seems to be a "label"
689  QString name = line.left(line.length() - 1).simplified();
690  if (!labels.contains(name)) {
691  // qDebug("new label '%s' at %llu", DBG(name), stream.pos());
692  label_t label_pos;
693  label_pos.pos = stream.pos();
694  label_pos.hits = 0;
695  labels[name] = label_pos;
696  }
697 
698  // special handling for a label at the end of the file
699  if (label.length() && (label == name)) {
700  // label found
701  label = QString();
702  }
703  continue;
704  }
705 
706  Kwave::Parser parser(line);
707 
708  // the "GOTO" command
709  if ( !label.length() &&
710  (line.split(QLatin1Char(' ')).at(0) == _("GOTO")) ) {
711  label = line.split(QLatin1Char(' ')).at(1).simplified();
712  }
713 
714  // jump to a label, scan/seek mode
715  if (label.length()) {
716  if (labels.contains(label)) {
717  labels[label].hits++;
718  qDebug(">>> GOTO '%s' @ offset %llu (pass #%d)", DBG(label),
719  labels[label].pos,
720  labels[label].hits
721  );
722  stream.seek(labels[label].pos);
723 
724  // reset the label to search for
725  label = QString();
726  }
727  // else: maybe the label will follow somewhere below,
728  // scan forward...
729  continue;
730  }
731 
732  // synchronize before the command
733  if (m_plugin_manager)
734  m_plugin_manager->sync();
735 
736  // the "msgbox" command (useful for debugging)
737  if (false) { ;
738  CASE_COMMAND("msgbox")
739  QApplication::restoreOverrideCursor();
740  result = (Kwave::MessageBox::questionYesNo(mainWidget(),
741  parser.firstParam()) == KMessageBox::Yes) ? 0 : 1;
742  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
743  continue;
744  }
745 
746  // prevent this command from being re-added to the macro recorder
747  if (!line.startsWith(_("nomacro:"), Qt::CaseInsensitive))
748  line.prepend(_("nomacro:"));
749 
750  // process the command in the current context
751  // NOTE: this could theoretically also be a command that modifies
752  // or even deletes the current context!
753  result = EAGAIN;
754  Kwave::FileContext *current_ctx = (m_top_widget) ?
755  m_top_widget->currentContext() : Q_NULLPTR;
756  if (current_ctx && (current_ctx != this))
757  result = m_top_widget->forwardCommand(line);
758 
759  // If the call returned with EAGAIN, then the context in duty is
760  // different from this instance but not yet completely set up.
761  // In that case this context is still responsible for executing the
762  // current command.
763  if (result == EAGAIN)
764  result = executeCommand(line);
765 
766  if (result)
767  qDebug(">>> '%s' - result=%d", DBG(line), result);
768 
769  qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
770 
771  // synchronize after the command
772  if (m_plugin_manager)
773  m_plugin_manager->sync();
774 
775  // special handling of the "quit" command
776  if (parser.command() == _("quit")) {
777  result = ECANCELED;
778  break;
779  }
780  }
781 
782  if (label.length()) {
783  // oops, if we get here then we have searched for a non-exising label
784  qWarning("label '%s' not found", DBG(label));
785  result = -ENOENT;
786  }
787 
788  // remove hourglass
789  QApplication::restoreOverrideCursor();
790 
791  return result;
792 }
Definition: App.h:33
#define CASE_COMMAND(x)
Definition: FileContext.cpp:54
const char name[16]
Definition: memcpy.c:510
QPointer< Kwave::PluginManager > m_plugin_manager
Definition: FileContext.h:404
QWidget * mainWidget() const
#define _(m)
Definition: memcpy.c:66
#define DBG(qs)
Definition: String.h:55
FileContext(Kwave::App &app)
Definition: FileContext.cpp:69
QPointer< Kwave::TopWidget > m_top_widget
Definition: FileContext.h:395
int executeCommand(const QString &command)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pluginManager()

Kwave::PluginManager * Kwave::FileContext::pluginManager ( ) const

returns a pointer to the plugin manager of this context

Definition at line 284 of file FileContext.cpp.

References m_plugin_manager.

Referenced by Kwave::TopWidget::forwardCommand(), Kwave::MainWidget::MainWidget(), and Kwave::MainWidget::~MainWidget().

285 {
286  return m_plugin_manager;
287 }
QPointer< Kwave::PluginManager > m_plugin_manager
Definition: FileContext.h:404
Here is the caller graph for this function:

◆ processDelayedCommand

void Kwave::FileContext::processDelayedCommand ( )
privateslot

process the next delayed command from m_delayed_command_queue

Definition at line 808 of file FileContext.cpp.

References executeCommand(), m_delayed_command_queue, m_delayed_command_timer, and release().

Referenced by FileContext().

809 {
810  if (m_delayed_command_queue.isEmpty()) return;
811 
812  QPair<unsigned int, QString> current = m_delayed_command_queue.takeFirst();
813  executeCommand(current.second);
814  if (m_delayed_command_queue.isEmpty()) return;
815 
816  QPair<unsigned int, QString> next = m_delayed_command_queue.first();
817  m_delayed_command_timer.start(next.first);
818 
819  release();
820 }
QTimer m_delayed_command_timer
Definition: FileContext.h:434
QList< QPair< unsigned int, QString > > m_delayed_command_queue
Definition: FileContext.h:437
int executeCommand(const QString &command)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ release()

void Kwave::FileContext::release ( )
protected

decrements the usage count of this context, and if it has reached zero this instance will be deleted (delayed)

Definition at line 117 of file FileContext.cpp.

References m_use_count.

Referenced by Kwave::TopWidget::detachAllContexts(), Kwave::TopWidget::insertContext(), Kwave::TopWidget::newWindow(), processDelayedCommand(), Kwave::TopWidget::subWindowDeleted(), and Kwave::App::switchGuiType().

118 {
119  Q_ASSERT(int(m_use_count) > 0);
120  if (m_use_count.deref() == false) {
121  disconnect();
122  deleteLater();
123  }
124 }
QAtomicInt m_use_count
Definition: FileContext.h:389
Here is the caller graph for this function:

◆ revert()

int Kwave::FileContext::revert ( )
private

Discards all changes to the current file and loads it again.

Returns
zero if succeeded or error code

Definition at line 883 of file FileContext.cpp.

References m_signal_manager, m_top_widget, signalName(), and Kwave::MessageBox::warningContinueCancel().

Referenced by executeCommand().

884 {
885  Kwave::FileContext::UsageGuard _keep(this);
886 
887  QUrl url(signalName());
888  if (!url.isValid() || !m_signal_manager) return -EINVAL;
889 
890  if (m_signal_manager->isModified()) {
892  i18n("This file has been modified, changes will be lost.\n"
893  "Do you want to continue?"));
894  if (res == KMessageBox::Cancel) return ECANCELED;
895  }
896 
897  return m_signal_manager->loadFile(url);
898 }
QString signalName() const
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
QPointer< Kwave::SignalManager > m_signal_manager
Definition: FileContext.h:401
QPointer< Kwave::TopWidget > m_top_widget
Definition: FileContext.h:395
Here is the call graph for this function:
Here is the caller graph for this function:

◆ saveFile()

int Kwave::FileContext::saveFile ( )

Saves the current file.

Returns
zero if succeeded, non-zero if failed

Definition at line 901 of file FileContext.cpp.

References m_signal_manager, NEW_FILENAME, saveFileAs(), and signalName().

Referenced by closeFile(), and executeCommand().

902 {
903  if (!m_signal_manager) return -EINVAL;
904 
905  int res = 0;
906 
907  if (signalName() != NEW_FILENAME) {
908  QUrl url;
909  url = QUrl(signalName());
910  res = m_signal_manager->save(url, false);
911 
912  // if saving in current format is not possible (no encoder),
913  // then try to "save/as" instead...
914  if (res == -EINVAL) res = saveFileAs(QString(), false);
915  } else res = saveFileAs(QString(), false);
916 
917  return res;
918 }
#define NEW_FILENAME
Definition: SignalManager.h:46
QString signalName() const
QPointer< Kwave::SignalManager > m_signal_manager
Definition: FileContext.h:401
int saveFileAs(const QString &filename, bool selection=false)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ saveFileAs()

int Kwave::FileContext::saveFileAs ( const QString &  filename,
bool  selection = false 
)

Opens a dialog for saving the current file.

Parameters
filenamethe name of the new file or empty string to open the File/SaveAs dialog
selectionif set to true, only the current selection will be saved
Returns
zero if succeeded, non-zero if failed

Definition at line 921 of file FileContext.cpp.

References _, Kwave::App::addRecentFile(), DBG, Kwave::CodecManager::encoder(), Kwave::CodecManager::encodingFilter(), Kwave::CodecBase::extensions(), Kwave::INF_FILENAME, Kwave::INF_MIMETYPE, m_application, m_plugin_manager, m_signal_manager, m_top_widget, Kwave::CodecManager::mimeTypeOf(), name, Kwave::FileDialog::SaveFile, Kwave::FileDialog::selectedUrl(), Kwave::FileInfo::set(), signalName(), and Kwave::MessageBox::warningYesNo().

Referenced by executeCommand(), and saveFile().

922 {
923  if (!m_signal_manager) return -EINVAL;
924 
925  QString name = filename;
926  QUrl url;
927  int res = 0;
928 
929  if (name.length()) {
930  /* name given -> take it */
931  url = QUrl(name);
932  } else {
933  /*
934  * no name given -> show the File/SaveAs dialog...
935  */
936  QUrl current_url;
937  current_url = QUrl(signalName());
938 
939  QString what = Kwave::CodecManager::mimeTypeOf(current_url);
941  QString extension; // = "*.wav";
942  if (!encoder) {
943  // no extension selected yet, use mime type from file info
944  QString mime_type = Kwave::FileInfo(
945  m_signal_manager->metaData()).get(
946  Kwave::INF_MIMETYPE).toString();
947  encoder = Kwave::CodecManager::encoder(mime_type);
948  if (encoder) {
949  QStringList extensions = encoder->extensions(mime_type);
950  if (!extensions.isEmpty()) {
951  QString ext = extensions.first().split(_(" ")).first();
952  if (ext.length()) {
953  extension = ext;
954  QString new_filename = current_url.fileName();
955  new_filename += extension.mid(1); // remove the "*"
956  current_url = current_url.adjusted(QUrl::RemoveFilename);
957  current_url.setPath(current_url.path() + new_filename);
958  }
959  }
960  }
961  }
962 
963  QString filter = Kwave::CodecManager::encodingFilter();
964  QPointer<Kwave::FileDialog> dlg = new(std::nothrow)Kwave::FileDialog(
965  _("kfiledialog:///kwave_save_as"),
967  filter, m_top_widget, current_url, extension
968  );
969  if (!dlg) return 0;
970  dlg->setWindowTitle(i18n("Save As"));
971  if (dlg->exec() != QDialog::Accepted) {
972  delete dlg;
973  return -1;
974  }
975 
976  url = dlg->selectedUrl();
977  if (url.isEmpty()) {
978  delete dlg;
979  return 0;
980  }
981 
982  QString new_name = url.path();
983  QFileInfo path(new_name);
984 
985  // add the correct extension if necessary
986  if (!path.suffix().length()) {
987  QString ext = dlg->selectedExtension();
988  QStringList extensions = ext.split(_(" "));
989  ext = extensions.first();
990  new_name += ext.mid(1);
991  path = new_name;
992  url.setPath(new_name);
993  }
994 
995  delete dlg;
996  }
997 
998  // check if the file exists and ask before overwriting it
999  // if it is not the old filename
1000  name = url.path();
1001  if ((url.toDisplayString() != QUrl(signalName()).toDisplayString()) &&
1002  (QFileInfo(name).exists()))
1003  {
1004  if (Kwave::MessageBox::warningYesNo(m_top_widget,
1005  i18n("The file '%1' already exists.\n"
1006  "Do you really want to overwrite it?", name)) !=
1007  KMessageBox::Yes)
1008  {
1009  return -1;
1010  }
1011  }
1012 
1013  // maybe we now have a new mime type
1014  QString previous_mimetype_name =
1015  Kwave::FileInfo(m_signal_manager->metaData()).get(
1016  Kwave::INF_MIMETYPE).toString();
1017 
1018  QString new_mimetype_name = Kwave::CodecManager::mimeTypeOf(url);
1019 
1020  if (new_mimetype_name != previous_mimetype_name) {
1021  // saving to a different mime type
1022  // now we have to do as if the mime type and file name
1023  // has already been selected to satisfy the fileinfo
1024  // plugin
1025  qDebug("TopWidget::saveAs(%s) - [%s] (previous:'%s')",
1026  DBG(url.toDisplayString()), DBG(new_mimetype_name),
1027  DBG(previous_mimetype_name) );
1028 
1029  // set the new mimetype
1030  Kwave::FileInfo info(m_signal_manager->metaData());
1031  info.set(Kwave::INF_MIMETYPE, new_mimetype_name);
1032 
1033  // set the new filename
1034  info.set(Kwave::INF_FILENAME, url.toDisplayString());
1035  m_signal_manager->setFileInfo(info, false);
1036 
1037  // now call the fileinfo plugin with the new filename and
1038  // mimetype
1039  res = (m_plugin_manager) ?
1040  m_plugin_manager->setupPlugin(_("fileinfo"), QStringList())
1041  : -1;
1042 
1043  // restore the mime type and the filename
1044  info = Kwave::FileInfo(m_signal_manager->metaData());
1045  info.set(Kwave::INF_MIMETYPE, previous_mimetype_name);
1046  info.set(Kwave::INF_FILENAME, url.toDisplayString());
1047  m_signal_manager->setFileInfo(info, false);
1048  }
1049 
1050  // now we have a file name -> do the "save" operation
1051  if (!res) res = m_signal_manager->save(url, selection);
1052 
1053  // if saving was successful, add the file to the list of recent files
1054  if (!res) m_application.addRecentFile(signalName());
1055 
1056  return res;
1057 }
static QString encodingFilter()
QUrl selectedUrl() const
Definition: FileDialog.cpp:253
static QString mimeTypeOf(const QUrl &url)
void set(FileProperty key, const QVariant &value)
Definition: FileInfo.cpp:363
const char name[16]
Definition: memcpy.c:510
QString signalName() const
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
QPointer< Kwave::PluginManager > m_plugin_manager
Definition: FileContext.h:404
QPointer< Kwave::SignalManager > m_signal_manager
Definition: FileContext.h:401
static Kwave::Encoder * encoder(const QString &mimetype_name)
#define _(m)
Definition: memcpy.c:66
#define DBG(qs)
Definition: String.h:55
void addRecentFile(const QString &filename)
Definition: App.cpp:202
virtual QStringList extensions(const QString &mimetype_name) const
Definition: CodecBase.cpp:115
QPointer< Kwave::TopWidget > m_top_widget
Definition: FileContext.h:395
Kwave::App & m_application
Definition: FileContext.h:392
Here is the call graph for this function:
Here is the caller graph for this function:

◆ selectionChanged

void Kwave::FileContext::selectionChanged ( sample_index_t  offset,
sample_index_t  length 
)
privateslot

Called when the number of selected samples has changed.

Parameters
offsetindex of the first selected sample
lengthnumber of selected samples

Definition at line 558 of file FileContext.cpp.

References isActive(), and sigSelectionChanged().

Referenced by init().

560 {
561  if (isActive()) {
562  // we are active -> emit the selection change immediately
563  emit sigSelectionChanged(offset, length);
564  } // else: we are inactive -> not of interest / ignore
565 }
bool isActive() const
Definition: FileContext.h:124
void sigSelectionChanged(sample_index_t offset, sample_index_t length)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ setParent()

void Kwave::FileContext::setParent ( Kwave::TopWidget top_widget)

migrate this context to a different toplevel widget

Parameters
top_widgetpointer to the new toplevel widget

Definition at line 235 of file FileContext.cpp.

References Kwave::connect(), contextSwitched(), m_active, m_main_widget, m_plugin_manager, m_signal_manager, and m_top_widget.

Referenced by Kwave::TopWidget::detachAllContexts(), init(), Kwave::TopWidget::insertContext(), and Kwave::App::switchGuiType().

236 {
237  if (m_top_widget) {
239 
240  // disconnect all old signal/slot relationships
241  disconnect(m_plugin_manager, SIGNAL(sigProgress(QString)),
242  old, SLOT(showInSplashSreen(QString)));
243  disconnect(old, SIGNAL(sigFileContextSwitched(Kwave::FileContext*)),
244  this, SLOT(contextSwitched(Kwave::FileContext*)));
245 
246  if (m_signal_manager) m_signal_manager->setParentWidget(Q_NULLPTR);
247  if (m_plugin_manager) m_plugin_manager->setParentWidget(Q_NULLPTR);
248  if (m_main_widget) m_main_widget->setParent(Q_NULLPTR);
249 
250  m_active = false;
251  }
252 
253  // set the new top widget
254  m_top_widget = top_widget;
255 
256  if (m_top_widget) {
257  QWidget *top = m_top_widget;
258 
259  connect(top, SIGNAL(sigFileContextSwitched(Kwave::FileContext*)),
260  this, SLOT(contextSwitched(Kwave::FileContext*)));
261  connect(m_plugin_manager, SIGNAL(sigProgress(QString)),
262  top, SLOT(showInSplashSreen(QString)));
263 
264  if (m_signal_manager) m_signal_manager->setParentWidget(m_top_widget);
265  if (m_plugin_manager) m_plugin_manager->setParentWidget(m_top_widget);
266  if (m_main_widget) m_main_widget->setParent(m_top_widget);
267  }
268 }
QPointer< Kwave::MainWidget > m_main_widget
Definition: FileContext.h:398
bool connect(Kwave::StreamObject &source, const char *output, Kwave::StreamObject &sink, const char *input)
Definition: Connect.cpp:48
QPointer< Kwave::PluginManager > m_plugin_manager
Definition: FileContext.h:404
QPointer< Kwave::SignalManager > m_signal_manager
Definition: FileContext.h:401
QPointer< Kwave::TopWidget > m_top_widget
Definition: FileContext.h:395
void contextSwitched(Kwave::FileContext *context)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ setUndoRedoInfo

void Kwave::FileContext::setUndoRedoInfo ( const QString &  undo,
const QString &  redo 
)
privateslot

Called when the undo or redo action has changed.

Parameters
undodescription of the last undo action
redodescription of the last redo action

Definition at line 568 of file FileContext.cpp.

References isActive(), m_last_redo, m_last_undo, and sigUndoRedoInfo().

Referenced by init().

570 {
571  m_last_undo = undo;
572  m_last_redo = redo;
573 
574  if (isActive()) {
575  // we are active -> emit the undo/redo info immediately
576  emit sigUndoRedoInfo(undo, redo);
577  } // else: we are inactive -> emit the undo/redo info later, when activated
578 }
bool isActive() const
Definition: FileContext.h:124
void sigUndoRedoInfo(const QString &undo, const QString &redo)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sigMetaDataChanged

void Kwave::FileContext::sigMetaDataChanged ( Kwave::MetaDataList  meta_data)
signal

emitted when the meta data of the current signal has changed

Parameters
meta_datathe new meta data, after the change

Referenced by activated(), init(), and metaDataChanged().

Here is the caller graph for this function:

◆ sigModified

void Kwave::FileContext::sigModified ( )
signal

Emitted if the signal changes from non-modified to modified state or vice-versa.

Referenced by activated(), init(), and modifiedChanged().

Here is the caller graph for this function:

◆ signalManager()

◆ signalName()

QString Kwave::FileContext::signalName ( ) const

returns the name of the signal

Definition at line 830 of file FileContext.cpp.

References m_signal_manager.

Referenced by metaDataChanged(), Kwave::TopWidget::openFiles(), revert(), saveFile(), saveFileAs(), Kwave::MainWidget::saveLabels(), Kwave::TopWidget::updateMenu(), and windowCaption().

831 {
832  return (m_signal_manager) ? m_signal_manager->signalName() : QString();
833 }
QPointer< Kwave::SignalManager > m_signal_manager
Definition: FileContext.h:401
Here is the caller graph for this function:

◆ sigSelectionChanged

void Kwave::FileContext::sigSelectionChanged ( sample_index_t  offset,
sample_index_t  length 
)
signal

emits a change in the selected range.

Parameters
offsetindex of the first selected items
lengthnumber of selected items

Referenced by selectionChanged().

Here is the caller graph for this function:

◆ sigStatusBarMessage

void Kwave::FileContext::sigStatusBarMessage ( const QString &  message,
unsigned int  ms 
)
signal

emitted when there is a status bar message to show

Parameters
messagethe status bar message, already localized
msthe time in milliseconds to show the message

Referenced by activated(), and statusBarMessage().

Here is the caller graph for this function:

◆ sigUndoRedoInfo

void Kwave::FileContext::sigUndoRedoInfo ( const QString &  undo,
const QString &  redo 
)
signal

Emitted if the state or description of undo/redo has changed. If undo or redo is unavailable the description will be zero.

Referenced by activated(), init(), and setUndoRedoInfo().

Here is the caller graph for this function:

◆ sigVisibleRangeChanged

void Kwave::FileContext::sigVisibleRangeChanged ( sample_index_t  offset,
sample_index_t  visible,
sample_index_t  total 
)
signal

emitted when the visible range has changed

Referenced by activated(), createMainWidget(), and visibleRangeChanged().

Here is the caller graph for this function:

◆ sigZoomChanged

void Kwave::FileContext::sigZoomChanged ( Kwave::FileContext context,
double  zoom 
)
signal

emitted when the zoom factor of the corresponding main widget has changed

Parameters
contextcontains "this"
zoomnew zoom factor

Referenced by createMainWidget(), and forwardZoomChanged().

Here is the caller graph for this function:

◆ statusBarMessage()

void Kwave::FileContext::statusBarMessage ( const QString &  msg,
unsigned int  ms 
)
private

Show a message in the status bar

Parameters
msgthe status bar message, already localized
msthe time in milliseconds to show the message

Definition at line 481 of file FileContext.cpp.

References isActive(), m_last_status_message_ms, m_last_status_message_text, m_last_status_message_timer, and sigStatusBarMessage().

Referenced by init(), and updatePlaybackPos().

482 {
485  if (ms)
487  else
488  m_last_status_message_timer.invalidate();
489 
490  if (isActive())
491  emit sigStatusBarMessage(msg, ms);
492 }
bool isActive() const
Definition: FileContext.h:124
QElapsedTimer m_last_status_message_timer
Definition: FileContext.h:419
void sigStatusBarMessage(const QString &message, unsigned int ms)
QString m_last_status_message_text
Definition: FileContext.h:416
unsigned int m_last_status_message_ms
Definition: FileContext.h:422
Here is the call graph for this function:
Here is the caller graph for this function:

◆ updatePlaybackPos

void Kwave::FileContext::updatePlaybackPos ( sample_index_t  offset)
privateslot

Called when the playback position has changed

Parameters
offsetthe current playback position [samples]

Definition at line 495 of file FileContext.cpp.

References m_last_playback_pos, m_main_widget, m_plugin_manager, m_signal_manager, Kwave::ms2string(), Kwave::samples2string(), Kwave::Zoomable::scrollTo(), statusBarMessage(), and zoomable().

Referenced by activated(), and init().

496 {
497  if (!m_plugin_manager) return;
498  if (!m_main_widget) return;
499 
500  bool playing = m_signal_manager->playbackController().running();
501  if (!playing) return;
502 
503  QString txt;
504  double rate = m_plugin_manager->signalRate();
505  if (rate > 0) {
506  double ms = static_cast<double>(offset) * 1E3 / rate;
507  txt = i18n("Playback: %1", Kwave::ms2string(ms));
508  } else {
509  txt = i18n("Playback: %1 samples", Kwave::samples2string(offset));
510  }
511 
512  statusBarMessage(txt, 2000);
513 
514  // make sure that the current playback position is visible
515  m_last_playback_pos = offset;
516  Kwave::Zoomable *z = zoomable();
517  if (z) z->scrollTo(offset);
518 }
QPointer< Kwave::MainWidget > m_main_widget
Definition: FileContext.h:398
QString Q_DECL_EXPORT ms2string(double ms, int precision=6)
Definition: Utils.cpp:66
QString Q_DECL_EXPORT samples2string(sample_index_t samples)
Definition: Utils.cpp:98
void statusBarMessage(const QString &msg, unsigned int ms)
sample_index_t m_last_playback_pos
Definition: FileContext.h:413
virtual void scrollTo(sample_index_t pos)=0
Kwave::Zoomable * zoomable() const
QPointer< Kwave::PluginManager > m_plugin_manager
Definition: FileContext.h:404
QPointer< Kwave::SignalManager > m_signal_manager
Definition: FileContext.h:401
Here is the call graph for this function:
Here is the caller graph for this function:

◆ use()

void Kwave::FileContext::use ( )
protected

increments the usage count of this context, prevents it from being deleted

Definition at line 110 of file FileContext.cpp.

References m_use_count.

Referenced by enqueueCommand().

111 {
112  Q_ASSERT(int(m_use_count) > 0);
113  m_use_count.ref();
114 }
QAtomicInt m_use_count
Definition: FileContext.h:389
Here is the caller graph for this function:

◆ visibleRangeChanged

void Kwave::FileContext::visibleRangeChanged ( sample_index_t  offset,
sample_index_t  visible,
sample_index_t  total 
)
privateslot

Called after changes of the currently visible view range

Parameters
offsetindex of the first visible sample
visiblenumber of visible samples
totallength of the whole signal

Definition at line 581 of file FileContext.cpp.

References isActive(), and sigVisibleRangeChanged().

Referenced by createMainWidget().

584 {
585  if (isActive()) {
586  // we are active -> emit the view info immediately
587  emit sigVisibleRangeChanged(offset, visible, total);
588  } // else: we are inactive -> emit the view info later, when activated
589 }
bool isActive() const
Definition: FileContext.h:124
void sigVisibleRangeChanged(sample_index_t offset, sample_index_t visible, sample_index_t total)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ windowCaption()

QString Kwave::FileContext::windowCaption ( bool  with_modified) const

returns a string suitable as window caption

Parameters
with_modifiedif true, include the "modified" state

Definition at line 836 of file FileContext.cpp.

References Kwave::App::GUI_SDI, Kwave::App::guiType(), m_application, m_instance_nr, m_signal_manager, name, and signalName().

Referenced by Kwave::TopWidget::executeCommand(), Kwave::TopWidget::insertContext(), metaDataChanged(), modifiedChanged(), Kwave::TopWidget::updateCaption(), and Kwave::TopWidget::updateMenu().

837 {
838  QString name = signalName();
839 
840  // shortcut if no file loaded
841  if (!name.length()) return QString();
842 
843  // if not in SDI mode we have to take care of multiple instances on our
844  // own and append a " <n>" manually !
846  if (m_instance_nr != -1)
847  name = i18nc(
848  "for window title: "
849  "%1 = Name of the file, "
850  "%2 = Instance number when opened multiple times",
851  "%1 <%2>", name, m_instance_nr);
852 
853  if (with_modified) {
854  bool modified = (m_signal_manager) ?
855  m_signal_manager->isModified() : false;
856  if (modified)
857  return i18nc("%1 = Path to modified file", "* %1 (modified)", name);
858  }
859  return name;
860 }
const char name[16]
Definition: memcpy.c:510
QString signalName() const
GuiType guiType() const
Definition: App.h:119
QPointer< Kwave::SignalManager > m_signal_manager
Definition: FileContext.h:401
Kwave::App & m_application
Definition: FileContext.h:392
Here is the call graph for this function:
Here is the caller graph for this function:

◆ zoomable()

Kwave::Zoomable * Kwave::FileContext::zoomable ( ) const

Returns a pointer to a GUI element that receives zoom info (the MainWidget)

Definition at line 290 of file FileContext.cpp.

References m_main_widget.

Referenced by Kwave::ZoomToolBar::selectZoom(), Kwave::ZoomToolBar::setZoomInfo(), and updatePlaybackPos().

291 {
292  return m_main_widget;
293 }
QPointer< Kwave::MainWidget > m_main_widget
Definition: FileContext.h:398
Here is the caller graph for this function:

Friends And Related Function Documentation

◆ App

friend class App
friend

Definition at line 177 of file FileContext.h.

◆ TopWidget

friend class TopWidget
friend

Definition at line 178 of file FileContext.h.

◆ UsageGuard

friend class UsageGuard
friend

Definition at line 179 of file FileContext.h.

Member Data Documentation

◆ m_active

bool Kwave::FileContext::m_active
private

if true, this context is active, otherwise it is inactive

Definition at line 407 of file FileContext.h.

Referenced by contextSwitched(), and setParent().

◆ m_application

Kwave::App& Kwave::FileContext::m_application
private

reference to the global Kwave application object

Definition at line 392 of file FileContext.h.

Referenced by closeFile(), metaDataChanged(), modifiedChanged(), saveFileAs(), and windowCaption().

◆ m_delayed_command_queue

QList< QPair<unsigned int, QString> > Kwave::FileContext::m_delayed_command_queue
private

queue for delayed execution of commands

Definition at line 437 of file FileContext.h.

Referenced by enqueueCommand(), executeCommand(), and processDelayedCommand().

◆ m_delayed_command_timer

QTimer Kwave::FileContext::m_delayed_command_timer
private

timer for delayed commands

Definition at line 434 of file FileContext.h.

Referenced by enqueueCommand(), FileContext(), and processDelayedCommand().

◆ m_instance_nr

int Kwave::FileContext::m_instance_nr
private

instance of the loaded file or -1

Definition at line 431 of file FileContext.h.

Referenced by metaDataChanged(), and windowCaption().

◆ m_last_playback_pos

sample_index_t Kwave::FileContext::m_last_playback_pos
private

last playback position, only valid if playback is running

Definition at line 413 of file FileContext.h.

Referenced by activated(), and updatePlaybackPos().

◆ m_last_redo

QString Kwave::FileContext::m_last_redo
private

name of the last redo action

Definition at line 428 of file FileContext.h.

Referenced by activated(), and setUndoRedoInfo().

◆ m_last_status_message_ms

unsigned int Kwave::FileContext::m_last_status_message_ms
private

number of milliseconds the status message should be shown

Definition at line 422 of file FileContext.h.

Referenced by activated(), and statusBarMessage().

◆ m_last_status_message_text

QString Kwave::FileContext::m_last_status_message_text
private

last status bar message

Definition at line 416 of file FileContext.h.

Referenced by activated(), and statusBarMessage().

◆ m_last_status_message_timer

QElapsedTimer Kwave::FileContext::m_last_status_message_timer
private

time when the last status message has been shown

Definition at line 419 of file FileContext.h.

Referenced by activated(), and statusBarMessage().

◆ m_last_undo

QString Kwave::FileContext::m_last_undo
private

name of the last undo action

Definition at line 425 of file FileContext.h.

Referenced by activated(), and setUndoRedoInfo().

◆ m_last_zoom

double Kwave::FileContext::m_last_zoom
private

last zoom factor

Definition at line 410 of file FileContext.h.

Referenced by activated(), and forwardZoomChanged().

◆ m_main_widget

QPointer<Kwave::MainWidget> Kwave::FileContext::m_main_widget
private

◆ m_plugin_manager

QPointer<Kwave::PluginManager> Kwave::FileContext::m_plugin_manager
private

◆ m_signal_manager

QPointer<Kwave::SignalManager> Kwave::FileContext::m_signal_manager
private

◆ m_top_widget

QPointer<Kwave::TopWidget> Kwave::FileContext::m_top_widget
private

instance of our toplevel window

Definition at line 395 of file FileContext.h.

Referenced by closeFile(), createMainWidget(), executeCommand(), init(), parseCommands(), revert(), saveFileAs(), setParent(), and ~FileContext().

◆ m_use_count

QAtomicInt Kwave::FileContext::m_use_count
private

usage counter [0...n]

Definition at line 389 of file FileContext.h.

Referenced by isInUse(), release(), and use().


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