1 /***************************************************************************
2  *      SelectionItem.cpp  -  selection item within a SignalView
3  *                             -------------------
4  *    begin                : Sun Mar 12 2017
5  *    copyright            : (C) 2017 by Thomas Eschenbacher
6  *    email                : Thomas.Eschenbacher@gmx.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include "config.h"
19 
20 #include <QAction>
21 #include <QList>
22 
23 #include "libkwave/Drag.h"
24 #include "libkwave/MultiTrackReader.h"
25 #include "libkwave/SignalManager.h"
26 #include "libkwave/String.h"
27 #include "libkwave/Utils.h"
28 #include "libkwave/undo/UndoTransactionGuard.h"
29 
30 #include "libgui/SelectionItem.h"
31 #include "libgui/SignalView.h"
32 
33 //***************************************************************************
SelectionItem(Kwave::SignalView & view,Kwave::SignalManager & signal_manager)34 Kwave::SelectionItem::SelectionItem(
35     Kwave::SignalView &view,
36     Kwave::SignalManager &signal_manager
37 )
38     :Kwave::ViewItem(view, signal_manager),
39      m_first(signal_manager.selection().first()),
40      m_last(signal_manager.selection().last())
41 {
42 }
43 
44 //***************************************************************************
~SelectionItem()45 Kwave::SelectionItem::~SelectionItem()
46 {
47 }
48 
49 //***************************************************************************
flags() const50 Kwave::ViewItem::Flags Kwave::SelectionItem::flags() const
51 {
52     return Kwave::ViewItem::CanDragAndDrop;
53 }
54 
55 //***************************************************************************
startDragging()56 void Kwave::SelectionItem::startDragging()
57 {
58     const sample_index_t length = m_signal_manager.selection().length();
59     if (!length) return;
60 
61     Kwave::Drag *d = new(std::nothrow) Kwave::Drag(&m_view);
62     Q_ASSERT(d);
63     if (!d) return;
64 
65     const sample_index_t first = m_signal_manager.selection().first();
66     const sample_index_t last  = m_signal_manager.selection().last();
67     const double         rate  = m_signal_manager.rate();
68     const unsigned int   bits  = m_signal_manager.bits();
69 
70     Kwave::MultiTrackReader src(Kwave::SinglePassForward, m_signal_manager,
71                                 m_signal_manager.selectedTracks(), first, last);
72 
73     // create the file info
74     Kwave::MetaDataList meta = m_signal_manager.metaData();
75     Kwave::FileInfo info(meta);
76     info.setLength(last - first + 1);
77     info.setRate(rate);
78     info.setBits(bits);
79     info.setTracks(src.tracks());
80     meta.replace(Kwave::MetaDataList(info));
81 
82     if (!d->encode(&m_view, src, meta)) {
83 	delete d;
84 	return;
85     }
86 
87     // start drag&drop, mode is determined automatically
88     Kwave::UndoTransactionGuard undo(m_signal_manager, i18n("Drag and Drop"));
89     Qt::DropAction drop = d->exec(Qt::CopyAction | Qt::MoveAction);
90 
91     if (drop == Qt::MoveAction) {
92 	// deleting also affects the selection !
93 	const sample_index_t f = m_signal_manager.selection().first();
94 	const sample_index_t l = m_signal_manager.selection().last();
95 	const sample_index_t len = l - f + 1;
96 
97 	// special case: when dropping into the same widget, before
98 	// the previous selection, the previous range has already
99 	// been moved to the right !
100 	sample_index_t src_pos = first;
101 
102 	SignalView *target = qobject_cast<Kwave::SignalView *>(d->target());
103 	if ( (f < src_pos) && target &&
104 	      (target->signalManager() == m_view.signalManager()) ) {
105 	    src_pos += len;
106 	}
107 
108 	m_signal_manager.deleteRange(src_pos, len,
109 	                             m_signal_manager.selectedTracks());
110 
111 	// restore the new selection
112 	m_signal_manager.selectRange((first < f) ? (f - len) : f, len);
113     }
114 }
115 
116 //***************************************************************************
117 //***************************************************************************
118