kwave  18.07.70
Kwave::SignalWidget Class Reference

#include <SignalWidget.h>

Inheritance diagram for Kwave::SignalWidget:
Inheritance graph
Collaboration diagram for Kwave::SignalWidget:
Collaboration graph

Public Slots

void requestRepaint (Kwave::SignalView *view)
 
void forwardCommand (const QString &command)
 

Signals

void sigRepaint ()
 
void selectedTimeInfo (sample_index_t offset, sample_index_t length, double rate)
 
void sigCommand (const QString &command)
 
void sigCursorChanged (sample_index_t pos)
 

Public Member Functions

 SignalWidget (QWidget *parent, Kwave::SignalManager *signal_manager, QVBoxLayout *upper_dock, QVBoxLayout *lower_dock)
 
virtual ~SignalWidget () Q_DECL_OVERRIDE
 
void setZoomAndOffset (double zoom, sample_index_t offset)
 
int mapToViewPort (const QPoint &pos) const
 
int visibleWidth () const
 
virtual void insertView (Kwave::SignalView *view, QWidget *controls) Q_DECL_OVERRIDE
 
- Public Member Functions inherited from Kwave::ViewManager
virtual ~ViewManager ()
 

Protected Slots

virtual void contextMenuEvent (QContextMenuEvent *e) Q_DECL_OVERRIDE
 

Protected Member Functions

virtual void wheelEvent (QWheelEvent *event) Q_DECL_OVERRIDE
 

Private Slots

void repaintTimerElapsed ()
 
void slotTrackInserted (unsigned int index, Kwave::Track *track)
 
void slotTrackDeleted (unsigned int index, Kwave::Track *track)
 
void contextMenuEditUndo ()
 
void contextMenuEditRedo ()
 
void contextMenuEditCut ()
 
void contextMenuEditCopy ()
 
void contextMenuEditPaste ()
 
void contextMenuSaveSelection ()
 
void contextMenuSelectionExpandToLabels ()
 
void contextMenuSelectionNextLabels ()
 
void contextMenuSelectionPrevLabels ()
 
void updateMinimumHeight ()
 

Private Member Functions

void setVerticalZoom (double zoom)
 
void insertRow (int index, Kwave::SignalView *view, QWidget *controls)
 
void deleteRow (int index)
 

Private Attributes

Kwave::SignalManagerm_signal_manager
 
QList< QPointer< Kwave::SignalView > > m_views
 
QGridLayout m_layout
 
QPointer< QVBoxLayout > m_upper_dock
 
QPointer< QVBoxLayout > m_lower_dock
 
sample_index_t m_offset
 
double m_zoom
 
double m_vertical_zoom
 
QTimer m_repaint_timer
 
QQueue< QPointer< Kwave::SignalView > > m_repaint_queue
 

Detailed Description

The SignalWidget class is responsible for displaying and managing the views that belong to a signal.

Definition at line 75 of file SignalWidget.h.

Constructor & Destructor Documentation

◆ SignalWidget()

Kwave::SignalWidget::SignalWidget ( QWidget *  parent,
Kwave::SignalManager signal_manager,
QVBoxLayout *  upper_dock,
QVBoxLayout *  lower_dock 
)

Constructor

Parameters
parentparent widget
signal_managersignal manager of the file context
upper_docklayout of the upper docking area
lower_docklayout of the lower docking area

Definition at line 83 of file SignalWidget.cpp.

References Kwave::connect(), m_layout, m_repaint_timer, m_signal_manager, repaintTimerElapsed(), slotTrackDeleted(), and slotTrackInserted().

87  :QWidget(parent),
88  m_signal_manager(signal_manager),
89  m_views(),
90  m_layout(this),
91  m_upper_dock(upper_dock),
92  m_lower_dock(lower_dock),
93  m_offset(0),
94  m_zoom(0.0),
95  m_vertical_zoom(1.0),
97 {
98 // qDebug("SignalWidget::SignalWidget()");
99 
100  // connect to the signal manager's signals
102 
103  connect(sig, SIGNAL(sigTrackInserted(uint,Kwave::Track*)),
104  this, SLOT(slotTrackInserted(uint,Kwave::Track*)));
105  connect(sig, SIGNAL(sigTrackDeleted(uint,Kwave::Track*)),
106  this, SLOT(slotTrackDeleted(uint,Kwave::Track*)));
107 
108  // use a timer for limiting the repaint rate
109  m_repaint_timer.setSingleShot(true);
110  connect(&m_repaint_timer, SIGNAL(timeout()),
111  this, SLOT(repaintTimerElapsed()));
112 
113 // // -- accelerator keys for 1...9 --
114 // for (int i = 0; i < 10; i++) {
115 // Kwave::ShortcutWrapper *shortcut =
116 // new Kwave::ShortcutWrapper(this, tbl_keys[i], i);
117 // connect(shortcut, SIGNAL(activated(int)),
118 // this, SLOT(parseKey(int)));
119 // }
120 
121  setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
122 
123  m_layout.setColumnStretch(0, 0);
124  m_layout.setColumnStretch(1, 100);
125  m_layout.setMargin(0);
126  m_layout.setVerticalSpacing(3);
127  setLayout(&m_layout);
128  m_layout.activate();
129 }
QList< QPointer< Kwave::SignalView > > m_views
Definition: SignalWidget.h:270
bool connect(Kwave::StreamObject &source, const char *output, Kwave::StreamObject &sink, const char *input)
Definition: Connect.cpp:48
void slotTrackInserted(unsigned int index, Kwave::Track *track)
QPointer< QVBoxLayout > m_upper_dock
Definition: SignalWidget.h:276
QGridLayout m_layout
Definition: SignalWidget.h:273
sample_index_t m_offset
Definition: SignalWidget.h:285
void slotTrackDeleted(unsigned int index, Kwave::Track *track)
QPointer< QVBoxLayout > m_lower_dock
Definition: SignalWidget.h:279
Kwave::SignalManager * m_signal_manager
Definition: SignalWidget.h:262
Here is the call graph for this function:

◆ ~SignalWidget()

Kwave::SignalWidget::~SignalWidget ( )
virtual

Destructor

Definition at line 132 of file SignalWidget.cpp.

133 {
134 }

Member Function Documentation

◆ contextMenuEditCopy

void Kwave::SignalWidget::contextMenuEditCopy ( )
inlineprivateslot

context menu: "edit/copy"

Definition at line 182 of file SignalWidget.h.

References _.

Referenced by contextMenuEvent().

182 { forwardCommand(_("copy()")); }
#define _(m)
Definition: memcpy.c:66
void forwardCommand(const QString &command)
Here is the caller graph for this function:

◆ contextMenuEditCut

void Kwave::SignalWidget::contextMenuEditCut ( )
inlineprivateslot

context menu: "edit/cut"

Definition at line 179 of file SignalWidget.h.

References _.

Referenced by contextMenuEvent().

179 { forwardCommand(_("cut()")); }
#define _(m)
Definition: memcpy.c:66
void forwardCommand(const QString &command)
Here is the caller graph for this function:

◆ contextMenuEditPaste

void Kwave::SignalWidget::contextMenuEditPaste ( )
inlineprivateslot

context menu: "edit/paste"

Definition at line 185 of file SignalWidget.h.

References _.

Referenced by contextMenuEvent().

185 {forwardCommand(_("paste()")); }
#define _(m)
Definition: memcpy.c:66
void forwardCommand(const QString &command)
Here is the caller graph for this function:

◆ contextMenuEditRedo

void Kwave::SignalWidget::contextMenuEditRedo ( )
inlineprivateslot

context menu: "edit/redo"

Definition at line 176 of file SignalWidget.h.

References _.

Referenced by contextMenuEvent().

176 { forwardCommand(_("redo()")); }
#define _(m)
Definition: memcpy.c:66
void forwardCommand(const QString &command)
Here is the caller graph for this function:

◆ contextMenuEditUndo

void Kwave::SignalWidget::contextMenuEditUndo ( )
inlineprivateslot

context menu: "edit/undo"

Definition at line 173 of file SignalWidget.h.

References _.

Referenced by contextMenuEvent().

173 { forwardCommand(_("undo()")); }
#define _(m)
Definition: memcpy.c:66
void forwardCommand(const QString &command)
Here is the caller graph for this function:

◆ contextMenuEvent

void Kwave::SignalWidget::contextMenuEvent ( QContextMenuEvent *  e)
protectedvirtualslot

Handler for context menus

Definition at line 177 of file SignalWidget.cpp.

References _, Kwave::SignalManager::canRedo(), Kwave::SignalManager::canUndo(), Kwave::connect(), contextMenuEditCopy(), contextMenuEditCut(), contextMenuEditPaste(), contextMenuEditRedo(), contextMenuEditUndo(), contextMenuSaveSelection(), contextMenuSelectionExpandToLabels(), contextMenuSelectionNextLabels(), contextMenuSelectionPrevLabels(), forwardCommand(), Kwave::ClipBoard::instance(), Kwave::SignalManager::isEmpty(), Kwave::Selection::length(), m_signal_manager, m_views, Kwave::SignalManager::metaData(), Kwave::SignalManager::selection(), and sigCommand().

178 {
179  Q_ASSERT(e);
180 
181  bool have_signal = m_signal_manager && !m_signal_manager->isEmpty();
182  if (!have_signal)return;
183  bool have_selection = (m_signal_manager->selection().length() > 1);
184  bool have_labels =
185  !(Kwave::LabelList(m_signal_manager->metaData()).isEmpty());
186 
187  QMenu *context_menu = new QMenu(this);
188  Q_ASSERT(context_menu);
189  if (!context_menu) return;
190 
191  /* menu items common to all cases */
192 
193  // undo
194  QAction *action;
195  action = context_menu->addAction(
196  QIcon::fromTheme(_("edit-undo")),
197  i18n("&Undo"), this, SLOT(contextMenuEditUndo()),
198  Qt::CTRL + Qt::Key_Z);
199  Q_ASSERT(action);
200  if (!action) return;
201  if (!m_signal_manager->canUndo())
202  action->setEnabled(false);
203 
204  // redo
205  action = context_menu->addAction(
206  QIcon::fromTheme(_("edit-redo")),
207  i18n("&Redo"), this, SLOT(contextMenuEditRedo()),
208  Qt::CTRL + Qt::Key_Y);
209  Q_ASSERT(action);
210  if (!action) return;
211  if (!m_signal_manager->canRedo())
212  action->setEnabled(false);
213  context_menu->addSeparator();
214 
215  // cut/copy/paste
216  QAction *action_cut = context_menu->addAction(
217  QIcon::fromTheme(_("edit-cut")),
218  i18n("Cu&t"), this, SLOT(contextMenuEditCut()),
219  Qt::CTRL + Qt::Key_X);
220  QAction *action_copy = context_menu->addAction(
221  QIcon::fromTheme(_("edit-copy")),
222  i18n("&Copy"), this, SLOT(contextMenuEditCopy()),
223  Qt::CTRL + Qt::Key_C);
224  QAction *action_paste = context_menu->addAction(
225  QIcon::fromTheme(_("edit-paste")),
226  i18n("&Paste"), this, SLOT(contextMenuEditPaste()),
227  Qt::CTRL + Qt::Key_V);
228  context_menu->addSeparator();
229  if (action_cut) action_cut->setEnabled(have_selection);
230  if (action_copy) action_copy->setEnabled(have_selection);
231  if (action_paste)
232  action_paste->setEnabled(!Kwave::ClipBoard::instance().isEmpty());
233 
234  int mouse_x = mapFromGlobal(e->globalPos()).x();
235  int mouse_y = mapFromGlobal(e->globalPos()).y();
236  if (mouse_x < 0) mouse_x = 0;
237  if (mouse_y < 0) mouse_y = 0;
238  if (mouse_x >= width()) mouse_x = width() - 1;
239  if (mouse_y >= height()) mouse_y = height() - 1;
240 
241 
242  QMenu *submenu_select = context_menu->addMenu(i18n("Selection"));
243  Q_ASSERT(submenu_select);
244  if (!submenu_select) return;
245 
246  // Selection / &Save
247  QAction *action_select_save = submenu_select->addAction(
248  QIcon::fromTheme(_("document-save")),
249  i18n("&Save..."), this, SLOT(contextMenuSaveSelection()));
250  Q_ASSERT(action_select_save);
251  if (!action_select_save) return;
252  action_select_save->setEnabled(have_selection);
253 
254  // Selection / &Expand to labels
255  QAction *action_select_expand_to_labels = submenu_select->addAction(
256  i18n("&Expand to Labels"), this,
257  SLOT(contextMenuSelectionExpandToLabels()), Qt::Key_E);
258  Q_ASSERT(action_select_expand_to_labels);
259  if (!action_select_expand_to_labels) return;
260  action_select_expand_to_labels->setEnabled(have_labels);
261 
262  // Selection / to next labels
263  QAction *action_select_next_labels = submenu_select->addAction(
264  i18n("To Next Labels"), this,
266  Qt::SHIFT + Qt::CTRL + Qt::Key_N);
267  Q_ASSERT(action_select_next_labels);
268  if (!action_select_next_labels) return;
269  action_select_next_labels->setEnabled(have_labels);
270 
271  // Selection / to previous labels
272  QAction *action_select_prev_labels = submenu_select->addAction(
273  i18n("To Previous Labels"), this,
275  Qt::SHIFT + Qt::CTRL + Qt::Key_P);
276  Q_ASSERT(action_select_prev_labels);
277  if (!action_select_prev_labels) return;
278  action_select_prev_labels->setEnabled(have_labels);
279 
280  // find out whether there was a click within a signal view
281  QSharedPointer<Kwave::ViewItem> item(Q_NULLPTR);
282  foreach (QPointer<Kwave::SignalView> view, m_views) {
283  // map the rect of the view to our coordinate system
284  const QRect view_rect = QRect(
285  view->mapToParent(view->rect().topLeft()),
286  view->mapToParent(view->rect().bottomRight()));
287 
288  // check: mouse click was into that view?
289  if (view_rect.contains(mouse_x, mouse_y)) {
290  // map mouse click position to coordinate system of the view
291  QPoint pos = view->mapFromParent(QPoint(mouse_x, mouse_y));
292 
293  // give the view the chance to extend the context menu
294  view->handleContextMenu(pos, context_menu);
295 
296  // try to find a view item at these coordinates
297  item = view->findItem(pos);
298 
299  // if found, give the item the chance to extend the context menu
300  if (!item.isNull()) {
301  connect(item.data(), SIGNAL(sigCommand(QString)),
302  this, SLOT(forwardCommand(QString)));
303  item->appendContextMenu(context_menu);
304  }
305 
306  // we process only one view, views cannot overlap!
307  break;
308  }
309  }
310 
311  context_menu->exec(QCursor::pos());
312  delete context_menu;
313 }
QList< QPointer< Kwave::SignalView > > m_views
Definition: SignalWidget.h:270
void sigCommand(const QString &command)
bool canRedo() const
void contextMenuSaveSelection()
Definition: SignalWidget.h:188
static ClipBoard & instance()
Definition: ClipBoard.cpp:39
Kwave::MetaDataList & metaData()
void contextMenuSelectionPrevLabels()
Definition: SignalWidget.h:203
Kwave::Selection & selection()
bool connect(Kwave::StreamObject &source, const char *output, Kwave::StreamObject &sink, const char *input)
Definition: Connect.cpp:48
sample_index_t length() const
Definition: Selection.h:66
bool canUndo() const
#define _(m)
Definition: memcpy.c:66
Kwave::SignalManager * m_signal_manager
Definition: SignalWidget.h:262
void forwardCommand(const QString &command)
void contextMenuSelectionNextLabels()
Definition: SignalWidget.h:198
void contextMenuSelectionExpandToLabels()
Definition: SignalWidget.h:193
Here is the call graph for this function:

◆ contextMenuSaveSelection

void Kwave::SignalWidget::contextMenuSaveSelection ( )
inlineprivateslot

context menu: "save selection"

Definition at line 188 of file SignalWidget.h.

References _.

Referenced by contextMenuEvent().

188  {
189  forwardCommand(_("saveselect()"));
190  }
#define _(m)
Definition: memcpy.c:66
void forwardCommand(const QString &command)
Here is the caller graph for this function:

◆ contextMenuSelectionExpandToLabels

void Kwave::SignalWidget::contextMenuSelectionExpandToLabels ( )
inlineprivateslot

context menu: "expand to labels"

Definition at line 193 of file SignalWidget.h.

References _.

Referenced by contextMenuEvent().

193  {
194  forwardCommand(_("expandtolabel()"));
195  }
#define _(m)
Definition: memcpy.c:66
void forwardCommand(const QString &command)
Here is the caller graph for this function:

◆ contextMenuSelectionNextLabels

void Kwave::SignalWidget::contextMenuSelectionNextLabels ( )
inlineprivateslot

context menu: "select next labels"

Definition at line 198 of file SignalWidget.h.

References _.

Referenced by contextMenuEvent().

198  {
199  forwardCommand(_("selectnextlabels()"));
200  }
#define _(m)
Definition: memcpy.c:66
void forwardCommand(const QString &command)
Here is the caller graph for this function:

◆ contextMenuSelectionPrevLabels

void Kwave::SignalWidget::contextMenuSelectionPrevLabels ( )
inlineprivateslot

context menu: "select previous labels"

Definition at line 203 of file SignalWidget.h.

References _.

Referenced by contextMenuEvent().

203  {
204  forwardCommand(_("selectprevlabels()"));
205  }
#define _(m)
Definition: memcpy.c:66
void forwardCommand(const QString &command)
Here is the caller graph for this function:

◆ deleteRow()

void Kwave::SignalWidget::deleteRow ( int  index)
private

delete a row in the m_layout, shifting all following rows back to the start by one

Parameters
indexthe index if the row

Definition at line 416 of file SignalWidget.cpp.

References m_layout.

Referenced by slotTrackDeleted().

417 {
418  const int rows = m_layout.rowCount();
419  const int cols = m_layout.columnCount();
420 
421  if (index >= rows)
422  return;
423 
424  // update the layout: move all items from this row to the previous
425  for (int row = index; row < (rows - 1); row++) {
426  for (int col = 0; col < cols; col++) {
427  QLayoutItem *item = m_layout.itemAtPosition(row + 1, col);
428  if (item) {
429  m_layout.removeItem(item);
430  m_layout.addItem(item, row, col);
431  }
432  }
433  }
434 }
QGridLayout m_layout
Definition: SignalWidget.h:273
Here is the caller graph for this function:

◆ forwardCommand

void Kwave::SignalWidget::forwardCommand ( const QString &  command)
slot

forward a sigCommand to the next layer

Definition at line 145 of file SignalWidget.cpp.

References sigCommand().

Referenced by contextMenuEvent().

146 {
147  emit sigCommand(command);
148 }
void sigCommand(const QString &command)
Here is the caller graph for this function:

◆ insertRow()

void Kwave::SignalWidget::insertRow ( int  index,
Kwave::SignalView view,
QWidget *  controls 
)
private

insert a row in the m_layout, shifting all following rows to the end by one

Parameters
indexthe index if the row
viewa view widget, must not be null
controlsa widget with controls, can be null

Definition at line 375 of file SignalWidget.cpp.

References Kwave::SignalView::addSibling(), and m_layout.

Referenced by insertView().

377 {
378  const int rows = m_layout.rowCount();
379  const int cols = m_layout.columnCount();
380 
381  // update the layout: move all items from the index on to the next row
382  for (int row = rows; row > index; row--) {
383  for (int col = 0; col < cols; col++) {
384  QLayoutItem *item = m_layout.itemAtPosition(row - 1, col);
385  if (item) {
386  m_layout.removeItem(item);
387  m_layout.addItem(item, row, col);
388  }
389  }
390  }
391 
392  // add the widget to the layout
393  m_layout.addWidget(view, index, 1);
394 
395  if (controls) {
396  // add the controls to the layout
397  m_layout.addWidget(controls, index, 0);
398 
399  // associate the controls to the view, so that when the view
400  // gets removed/deleted, the controls get removed as well
401  view->addSibling(controls);
402 
403  m_layout.activate();
404  // NOTE: QLayout::activate() does not really activate the layout
405  // synchronously as expected. Instead it posts an event to
406  // invalidate the layout of it's parent widget.
407  // Unfortunately we need reliable geometry information
408  // already *now*, which forces us to do the event loop
409  // right here.
410  qApp->processEvents(QEventLoop::ExcludeUserInputEvents |
411  QEventLoop::ExcludeSocketNotifiers);
412  }
413 }
virtual void addSibling(QWidget *widget)
Definition: SignalView.cpp:107
QGridLayout m_layout
Definition: SignalWidget.h:273
Here is the call graph for this function:
Here is the caller graph for this function:

◆ insertView()

void Kwave::SignalWidget::insertView ( Kwave::SignalView view,
QWidget *  controls 
)
virtual

Insert a new signal view into this widget (or the upper/lower dock area.

Parameters
viewthe signal view, must not be a null pointer
controlsa widget with controls, optionally, can be null

Implements Kwave::ViewManager.

Definition at line 437 of file SignalWidget.cpp.

References Kwave::SignalView::AboveTrackBottom, Kwave::SignalView::AboveTrackTop, Kwave::SignalView::BelowTrackBottom, Kwave::SignalView::BelowTrackTop, Kwave::SignalView::Bottom, Kwave::connect(), insertRow(), Kwave::SignalView::LowerDockBottom, Kwave::SignalView::LowerDockTop, m_layout, m_lower_dock, m_offset, m_upper_dock, m_vertical_zoom, m_views, m_zoom, Kwave::SignalView::preferredLocation(), requestRepaint(), Kwave::SignalView::setVerticalZoom(), Kwave::SignalView::setZoomAndOffset(), sigCommand(), sigCursorChanged(), Kwave::SignalView::Top, Kwave::SignalView::track(), updateMinimumHeight(), Kwave::SignalView::UpperDockBottom, and Kwave::SignalView::UpperDockTop.

Referenced by slotTrackInserted().

439 {
440  Q_ASSERT(m_upper_dock);
441  Q_ASSERT(m_lower_dock);
442  Q_ASSERT(view);
443  if (!m_upper_dock || !m_lower_dock) return;
444  if (!view) return;
445 
446  // set initial vertical zoom
448 
449  // find the proper row to insert the track view
450  int index = 0;
451  int track = (view) ? view->track() : -1;
452  const Kwave::SignalView::Location where = view->preferredLocation();
453  switch (where) {
455  // upper dock area, top
456  index = 0;
457  m_upper_dock->insertWidget(0, view);
458  Q_ASSERT(!controls);
459  break;
460  }
462  // upper dock area, bottom
463  index = m_upper_dock->count();
464  m_upper_dock->addWidget(view);
465  Q_ASSERT(!controls);
466  break;
467  }
468  case Kwave::SignalView::Top: {
469  // central layout, above all others
470  index = m_upper_dock->count();
471  int row = 0;
472  insertRow(row, view, controls);
473  break;
474  }
476  // above the corresponding track, start of group
477  index = m_upper_dock->count();
478  int row = 0;
479  for (;index < m_views.count(); ++row, ++index) {
480  if (m_views[index]->track() >= track) break; // reached top
481  if (m_views[index]->preferredLocation() >=
483  }
484  insertRow(row, view, controls);
485  break;
486  }
488  // above the corresponding track, end of group
489  index = m_upper_dock->count();
490  int row = 0;
491  for (;index < m_views.count(); ++row, ++index) {
492  if (m_views[index]->track() < track) continue; // too early
493  if (m_views[index]->track() != track) break; // next track
494  if (m_views[index]->preferredLocation() !=
496  }
497  insertRow(row, view, controls);
498  break;
499  }
501  // below the corresponding track, start of group
502  index = m_upper_dock->count();
503  int row = 0;
504  for (;index < m_views.count(); ++row, ++index) {
505  if (m_views[index]->track() < track) continue; // too early
506  if (m_views[index]->track() != track) break; // next track
507  if (m_views[index]->preferredLocation() >=
509  }
510  insertRow(row, view, controls);
511  break;
512  }
514  // below the corresponding track, end of group
515  index = m_upper_dock->count();
516  int row = 0;
517  for (;index < m_views.count(); ++row, ++index) {
518  if (m_views[index]->track() < track) continue; // too early
519  if (m_views[index]->track() != track) break; // next track
520  if (m_views[index]->preferredLocation() >=
522  }
523  insertRow(row, view, controls);
524  break;
525  }
527  // below all others
528  int row = m_layout.rowCount();
529  index = m_upper_dock->count() + row;
530  insertRow(row, view, controls);
531  break;
532  }
534  // lower dock area, top
535  index = m_upper_dock->count() + m_layout.rowCount();
536  m_lower_dock->insertWidget(0, view);
537  Q_ASSERT(!controls);
538  break;
539  }
541  // lower dock area, bottom
542  index = m_upper_dock->count() + m_layout.rowCount() +
543  m_lower_dock->count();
544  m_lower_dock->addWidget(view);
545  Q_ASSERT(!controls);
546  break;
547  }
548 
549  // insert the view into the list of views
550  Q_ASSERT(index >= 0);
551  Q_ASSERT(index < m_upper_dock->count() + m_layout.rowCount() +
552  m_lower_dock->count());
553  m_views.insert(index, view);
554 
555  // initially set the current view info
557 
558  // connect all signals
559  connect(view, SIGNAL(sigCommand(QString)),
560  this, SIGNAL(sigCommand(QString)),
561  Qt::QueuedConnection);
562 
563  connect(view, SIGNAL(sigNeedRepaint(Kwave::SignalView*)),
564  this, SLOT(requestRepaint(Kwave::SignalView*)));
565 
566  connect(view, SIGNAL(contentSizeChanged()),
567  this, SLOT(updateMinimumHeight()));
568  connect(view, SIGNAL(destroyed(QObject*)),
569  this, SLOT(updateMinimumHeight()));
570  connect(view, SIGNAL(sigCursorChanged(sample_index_t)),
571  this, SIGNAL(sigCursorChanged(sample_index_t)));
572  connect(this, SIGNAL(sigCursorChanged(sample_index_t)),
573  view, SLOT(showCursor(sample_index_t)));
574 
576 }
QList< QPointer< Kwave::SignalView > > m_views
Definition: SignalWidget.h:270
void insertRow(int index, Kwave::SignalView *view, QWidget *controls)
void sigCommand(const QString &command)
void requestRepaint(Kwave::SignalView *view)
quint64 sample_index_t
Definition: Sample.h:28
virtual void setVerticalZoom(double zoom)
Definition: SignalView.cpp:137
bool connect(Kwave::StreamObject &source, const char *output, Kwave::StreamObject &sink, const char *input)
Definition: Connect.cpp:48
QPointer< QVBoxLayout > m_upper_dock
Definition: SignalWidget.h:276
QGridLayout m_layout
Definition: SignalWidget.h:273
sample_index_t m_offset
Definition: SignalWidget.h:285
void sigCursorChanged(sample_index_t pos)
QPointer< QVBoxLayout > m_lower_dock
Definition: SignalWidget.h:279
int track() const
Definition: SignalView.h:105
virtual void setZoomAndOffset(double zoom, sample_index_t offset)
Definition: SignalView.cpp:119
Location preferredLocation() const
Definition: SignalView.h:95
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mapToViewPort()

int Kwave::SignalWidget::mapToViewPort ( const QPoint &  pos) const

Returns the x coordinate of an absolute pixel position to a relative coordinate within the viewport area (without controls)

Definition at line 361 of file SignalWidget.cpp.

References m_layout, and m_views.

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

362 {
363  if (m_views.isEmpty()) return mapFromGlobal(pos).x(); // if empty
364  return mapFromGlobal(pos).x() - m_layout.cellRect(0, 1).left();
365 }
QList< QPointer< Kwave::SignalView > > m_views
Definition: SignalWidget.h:270
QGridLayout m_layout
Definition: SignalWidget.h:273
Here is the caller graph for this function:

◆ repaintTimerElapsed

void Kwave::SignalWidget::repaintTimerElapsed ( )
privateslot

called when the repaint timer has elapsed, to refresh all views that have requested a repaint and are in the repaint queue

Definition at line 166 of file SignalWidget.cpp.

References m_repaint_queue, and Kwave::SignalView::refresh().

Referenced by SignalWidget().

167 {
168  while (!m_repaint_queue.isEmpty())
169  {
170  Kwave::SignalView *view = m_repaint_queue.dequeue();
171  if (!view) continue;
172  view->refresh();
173  }
174 }
QQueue< QPointer< Kwave::SignalView > > m_repaint_queue
Definition: SignalWidget.h:297
virtual void refresh()
Definition: SignalView.cpp:101
Here is the call graph for this function:
Here is the caller graph for this function:

◆ requestRepaint

void Kwave::SignalWidget::requestRepaint ( Kwave::SignalView view)
slot

can be called by views to request a repaint, synchronized and throttled through our repaint timer

Definition at line 151 of file SignalWidget.cpp.

References m_repaint_queue, m_repaint_timer, and REPAINT_INTERVAL.

Referenced by insertView().

152 {
153  // add the view to the repaint queue (if not already there)
154  if (!m_repaint_queue.contains(view))
155  m_repaint_queue.enqueue(view);
156 
157  if (!m_repaint_timer.isActive()) {
158  // start the repaint timer
160  }
161  // else: repainting is inhibited -> wait until the
162  // repaint timer is elapsed
163 }
QQueue< QPointer< Kwave::SignalView > > m_repaint_queue
Definition: SignalWidget.h:297
#define REPAINT_INTERVAL
Here is the caller graph for this function:

◆ selectedTimeInfo

void Kwave::SignalWidget::selectedTimeInfo ( sample_index_t  offset,
sample_index_t  length,
double  rate 
)
signal

Emits the offset and length of the current selection and the sample rate for converting it into milliseconds

Parameters
offsetindex of the first selected sample
lengthnumber of selected samples
ratesample rate

◆ setVerticalZoom()

void Kwave::SignalWidget::setVerticalZoom ( double  zoom)
private

propagates the vertical zoom to all views

Definition at line 341 of file SignalWidget.cpp.

References m_vertical_zoom, m_views, VERTICAL_ZOOM_MAX, and VERTICAL_ZOOM_MIN.

Referenced by wheelEvent().

342 {
343  if (zoom > VERTICAL_ZOOM_MAX) zoom = VERTICAL_ZOOM_MAX;
344  if (zoom < VERTICAL_ZOOM_MIN) zoom = VERTICAL_ZOOM_MIN;
345  if (qFuzzyCompare(zoom, m_vertical_zoom)) return; // no change
346 
347  // take over the zoom factor
348  m_vertical_zoom = zoom;
349 
350  // propagate the zoom to all views
351  foreach (QPointer<Kwave::SignalView> view, m_views)
352  if (view) view->setVerticalZoom(m_vertical_zoom);
353 
354  // get back the maximum zoom set by the views
355  foreach (QPointer<Kwave::SignalView> view, m_views)
356  if (view && view->verticalZoom() > m_vertical_zoom)
357  m_vertical_zoom = view->verticalZoom();
358 }
#define VERTICAL_ZOOM_MAX
QList< QPointer< Kwave::SignalView > > m_views
Definition: SignalWidget.h:270
#define VERTICAL_ZOOM_MIN
Here is the caller graph for this function:

◆ setZoomAndOffset()

void Kwave::SignalWidget::setZoomAndOffset ( double  zoom,
sample_index_t  offset 
)

sets new zoom factor and offset

Parameters
zoomthe new zoom factor in pixels/sample
offsetthe index of the first visible sample

Definition at line 137 of file SignalWidget.cpp.

References m_views.

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

138 {
139  Q_ASSERT(zoom >= 0.0);
140  foreach (QPointer<Kwave::SignalView> view, m_views)
141  view->setZoomAndOffset(zoom, offset);
142 }
QList< QPointer< Kwave::SignalView > > m_views
Definition: SignalWidget.h:270
Here is the caller graph for this function:

◆ sigCommand

void Kwave::SignalWidget::sigCommand ( const QString &  command)
signal

Emits a command to be processed by the next higher instance.

Referenced by contextMenuEvent(), forwardCommand(), and insertView().

Here is the caller graph for this function:

◆ sigCursorChanged

void Kwave::SignalWidget::sigCursorChanged ( sample_index_t  pos)
signal

emitted to request update of the cursor

Referenced by insertView().

Here is the caller graph for this function:

◆ sigRepaint

void Kwave::SignalWidget::sigRepaint ( )
signal

child views can connected to this signal to synchronize repaints

◆ slotTrackDeleted

void Kwave::SignalWidget::slotTrackDeleted ( unsigned int  index,
Kwave::Track track 
)
privateslot

Connected to the signal's sigTrackDeleted.

Parameters
indexnumeric index of the deleted track
trackreference to the deleted track
See also
Signal::sigTrackInserted

Definition at line 612 of file SignalWidget.cpp.

References deleteRow(), m_layout, m_views, Kwave::SignalView::setTrack(), Kwave::toInt(), and Kwave::SignalView::track().

Referenced by SignalWidget().

614 {
615  Q_UNUSED(track);
616 
617  // loop over all views, delete those that are bound to this track
618  // and adjust the index of the following ones
619  bool empty = true;
620  QMutableListIterator<QPointer<Kwave::SignalView> > it(m_views);
621  while (it.hasNext()) {
622  Kwave::SignalView *view = it.next();
623  if (view->track() == Kwave::toInt(index)) {
624  it.remove();
625  delete view;
626  } else if (view->track() > Kwave::toInt(index)) {
627  view->setTrack(view->track() - 1);
628  empty = false;
629  } else if (view->track() != -1) {
630  empty = false;
631  }
632  }
633 
634  // find out if there are any empty rows in the grid now
635  const int rows = m_layout.rowCount();
636  const int cols = m_layout.columnCount();
637  for (int row = 0; row < rows; row++) {
638  bool row_is_empty = true;
639  for (int col = 0; col < cols; col++) {
640  QLayoutItem *item = m_layout.itemAtPosition(row, col);
641  if (item) {
642  row_is_empty = false;
643  break;
644  }
645  }
646  if (row_is_empty) deleteRow(row);
647  }
648 
649  // if there are only views with track() == -1, we are empty,
650  // in that case delete the rest (all views)
651  if (empty) {
652  while (!m_views.isEmpty())
653  delete m_views.takeFirst();
654  }
655 }
QList< QPointer< Kwave::SignalView > > m_views
Definition: SignalWidget.h:270
int toInt(T x)
Definition: Utils.h:127
QGridLayout m_layout
Definition: SignalWidget.h:273
virtual void setTrack(int track)
Definition: SignalView.cpp:113
void deleteRow(int index)
int track() const
Definition: SignalView.h:105
Here is the call graph for this function:
Here is the caller graph for this function:

◆ slotTrackInserted

void Kwave::SignalWidget::slotTrackInserted ( unsigned int  index,
Kwave::Track track 
)
privateslot

Connected to the signal's sigTrackInserted.

Parameters
indexnumeric index of the inserted track
trackreference to the inserted track
See also
Signal::sigTrackInserted

Definition at line 579 of file SignalWidget.cpp.

References insertView(), m_signal_manager, m_views, Kwave::SignalView::setTrack(), and Kwave::toInt().

Referenced by SignalWidget().

581 {
582  Q_ASSERT(track);
583  if (!track) return;
584 
585  // create a container widget for the track controls
586  QWidget *controls = new QWidget(Q_NULLPTR);
587  Q_ASSERT(controls);
588  if (!controls) return;
589 
590  // create a new view for the track's signal
591  Kwave::SignalView *new_view = new Kwave::TrackView(
592  this, controls, m_signal_manager, track);
593  Q_ASSERT(new_view);
594  if (!new_view) {
595  delete controls;
596  return;
597  }
598 
599  // loop over all views and adjust the track index of the following ones
600  foreach (QPointer<Kwave::SignalView> view, m_views) {
601  if (view->track() >= Kwave::toInt(index))
602  view->setTrack(view->track() + 1);
603  }
604 
605  // assign the view to the new track
606  new_view->setTrack(index);
607 
608  insertView(new_view, controls);
609 }
QList< QPointer< Kwave::SignalView > > m_views
Definition: SignalWidget.h:270
virtual void insertView(Kwave::SignalView *view, QWidget *controls) Q_DECL_OVERRIDE
int toInt(T x)
Definition: Utils.h:127
virtual void setTrack(int track)
Definition: SignalView.cpp:113
Kwave::SignalManager * m_signal_manager
Definition: SignalWidget.h:262
Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateMinimumHeight

void Kwave::SignalWidget::updateMinimumHeight ( )
privateslot

updates the minimum height of the widget according to the number of rows

Definition at line 658 of file SignalWidget.cpp.

References m_layout.

Referenced by insertView().

659 {
660  int height = 0;
661 
662  const int rows = m_layout.rowCount();
663  const int cols = m_layout.columnCount();
664  for (int row = 0; row < rows; row++) {
665  int h = 0;
666  for (int col = 0; col < cols; col++) {
667  QLayoutItem *item = m_layout.itemAtPosition(row, col);
668  QWidget *widget = (item) ? item->widget() : Q_NULLPTR;
669  if (widget) {
670  int min_height = widget->minimumSize().height();
671  if (min_height > h) h = min_height;
672  }
673  }
674  height += h;
675  }
676  if (rows > 1) height += (rows - 1) * m_layout.verticalSpacing();
677 
678  setMinimumHeight(height);
679 }
QGridLayout m_layout
Definition: SignalWidget.h:273
Here is the caller graph for this function:

◆ visibleWidth()

int Kwave::SignalWidget::visibleWidth ( ) const

Returns the width of the viewport with the signal (without controls)

Returns
width of the signal area [pixels]

Definition at line 368 of file SignalWidget.cpp.

References m_layout, and m_views.

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

369 {
370  if (m_views.isEmpty()) return width(); // if empty
371  return m_layout.cellRect(0, 1).width();
372 }
QList< QPointer< Kwave::SignalView > > m_views
Definition: SignalWidget.h:270
QGridLayout m_layout
Definition: SignalWidget.h:273
Here is the caller graph for this function:

◆ wheelEvent()

void Kwave::SignalWidget::wheelEvent ( QWheelEvent *  event)
protectedvirtual

slot for mouse wheel events, used for vertical zoom

Definition at line 316 of file SignalWidget.cpp.

References m_vertical_zoom, setVerticalZoom(), and VERTICAL_ZOOM_STEP_FACTOR.

317 {
318  if (!event) return;
319 
320  // we currently are only interested in <Alt> + <WheelUp/Down>
321  if (event->modifiers() != Qt::AltModifier) {
322  event->ignore();
323  return;
324  }
325 
326  if (event->delta() > 0) {
327  // zoom in
329  event->accept();
330  } else if (event->delta() < 0) {
331  // zoom out
333  event->accept();
334  } else {
335  // no change
336  event->ignore();
337  }
338 }
void setVerticalZoom(double zoom)
#define VERTICAL_ZOOM_STEP_FACTOR
Here is the call graph for this function:

Member Data Documentation

◆ m_layout

QGridLayout Kwave::SignalWidget::m_layout
private

the central layout with the views

Definition at line 273 of file SignalWidget.h.

Referenced by deleteRow(), insertRow(), insertView(), mapToViewPort(), SignalWidget(), slotTrackDeleted(), updateMinimumHeight(), and visibleWidth().

◆ m_lower_dock

QPointer<QVBoxLayout> Kwave::SignalWidget::m_lower_dock
private

layout of the lower docking area

Definition at line 279 of file SignalWidget.h.

Referenced by insertView().

◆ m_offset

sample_index_t Kwave::SignalWidget::m_offset
private

Offset from which signal is being displayed. This is equal to the index of the first visible sample.

Definition at line 285 of file SignalWidget.h.

Referenced by insertView().

◆ m_repaint_queue

QQueue< QPointer<Kwave::SignalView> > Kwave::SignalWidget::m_repaint_queue
private

queue with pointers to all signal views that need a repaint

Definition at line 297 of file SignalWidget.h.

Referenced by repaintTimerElapsed(), and requestRepaint().

◆ m_repaint_timer

QTimer Kwave::SignalWidget::m_repaint_timer
private

timer for limiting the number of repaints per second

Definition at line 294 of file SignalWidget.h.

Referenced by requestRepaint(), and SignalWidget().

◆ m_signal_manager

Kwave::SignalManager* Kwave::SignalWidget::m_signal_manager
private

the signal manager of the corresponding context

Definition at line 262 of file SignalWidget.h.

Referenced by contextMenuEvent(), SignalWidget(), and slotTrackInserted().

◆ m_upper_dock

QPointer<QVBoxLayout> Kwave::SignalWidget::m_upper_dock
private

layout of the upper docking area

Definition at line 276 of file SignalWidget.h.

Referenced by insertView().

◆ m_vertical_zoom

double Kwave::SignalWidget::m_vertical_zoom
private

vertical zoom factor

Definition at line 291 of file SignalWidget.h.

Referenced by insertView(), setVerticalZoom(), and wheelEvent().

◆ m_views

QList< QPointer<Kwave::SignalView> > Kwave::SignalWidget::m_views
private

list of signal views. Contains one entry for each signal view, starting with the ones in m_upper_dock, then the ones in m_layout, and at the end the ones from m_lower_dock. The list is sorted in the order of the appearance in the GUI.

Definition at line 270 of file SignalWidget.h.

Referenced by contextMenuEvent(), insertView(), mapToViewPort(), setVerticalZoom(), setZoomAndOffset(), slotTrackDeleted(), slotTrackInserted(), and visibleWidth().

◆ m_zoom

double Kwave::SignalWidget::m_zoom
private

number of samples per pixel

Definition at line 288 of file SignalWidget.h.

Referenced by insertView().


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