1 /*
2 * EffectSelectDialog.cpp - dialog to choose effect plugin
3 *
4 * Copyright (c) 2006-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
5 *
6 * This file is part of LMMS - https://lmms.io
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program (see COPYING); if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301 USA.
22 *
23 */
24
25 #include "EffectSelectDialog.h"
26
27 #include "ui_EffectSelectDialog.h"
28
29 #include "gui_templates.h"
30 #include "embed.h"
31 #include "PluginFactory.h"
32
33 #include <QLabel>
34
35
EffectSelectDialog(QWidget * _parent)36 EffectSelectDialog::EffectSelectDialog( QWidget * _parent ) :
37 QDialog( _parent ),
38 ui( new Ui::EffectSelectDialog ),
39 m_sourceModel(),
40 m_model(),
41 m_descriptionWidget( NULL )
42 {
43 ui->setupUi( this );
44
45 setWindowIcon( embed::getIconPixmap( "setup_audio" ) );
46
47 // query effects
48
49 EffectKeyList subPluginEffectKeys;
50
51 for (const Plugin::Descriptor* desc: pluginFactory->descriptors(Plugin::Effect))
52 {
53 if( desc->subPluginFeatures )
54 {
55 desc->subPluginFeatures->listSubPluginKeys(
56 // as iterators are always stated to be not
57 // equal with pointers, we dereference the
58 // iterator and take the address of the item,
59 // so we're on the safe side and the compiler
60 // likely will reduce that to just "it"
61 desc,
62 subPluginEffectKeys );
63 }
64 else
65 {
66 m_effectKeys << EffectKey( desc, desc->name );
67
68 }
69 }
70
71 m_effectKeys += subPluginEffectKeys;
72
73 // and fill our source model
74 m_sourceModel.setHorizontalHeaderItem( 0, new QStandardItem( tr( "Name" ) ) );
75 m_sourceModel.setHorizontalHeaderItem( 1, new QStandardItem( tr( "Type" ) ) );
76 int row = 0;
77 for( EffectKeyList::ConstIterator it = m_effectKeys.begin();
78 it != m_effectKeys.end(); ++it )
79 {
80 QString name;
81 QString type;
82 if( ( *it ).desc->subPluginFeatures )
83 {
84 name = ( *it ).name;
85 type = ( *it ).desc->displayName;
86 }
87 else
88 {
89 name = ( *it ).desc->displayName;
90 type = "LMMS";
91 }
92 m_sourceModel.setItem( row, 0, new QStandardItem( name ) );
93 m_sourceModel.setItem( row, 1, new QStandardItem( type ) );
94 ++row;
95 }
96
97 // setup filtering
98 m_model.setSourceModel( &m_sourceModel );
99 m_model.setFilterCaseSensitivity( Qt::CaseInsensitive );
100
101 connect( ui->filterEdit, SIGNAL( textChanged( const QString & ) ),
102 &m_model, SLOT( setFilterFixedString( const QString & ) ) );
103 connect( ui->filterEdit, SIGNAL( textChanged( const QString & ) ),
104 this, SLOT( updateSelection() ) );
105 connect( ui->filterEdit, SIGNAL( textChanged( const QString & ) ),
106 SLOT( sortAgain() ) );
107
108 ui->pluginList->setModel( &m_model );
109
110 // setup selection model
111 QItemSelectionModel * selectionModel = new QItemSelectionModel( &m_model );
112 ui->pluginList->setSelectionModel( selectionModel );
113 connect( selectionModel, SIGNAL( currentRowChanged( const QModelIndex &,
114 const QModelIndex & ) ),
115 SLOT( rowChanged( const QModelIndex &, const QModelIndex & ) ) );
116 connect( ui->pluginList, SIGNAL( doubleClicked( const QModelIndex & ) ),
117 SLOT( acceptSelection() ) );
118
119 // try to accept current selection when pressing "OK"
120 connect( ui->buttonBox, SIGNAL( accepted() ),
121 this, SLOT( acceptSelection() ) );
122
123 #if QT_VERSION >= 0x050000
124 #define setResizeMode setSectionResizeMode
125 ui->filterEdit->setClearButtonEnabled( true );
126 #endif
127 ui->pluginList->verticalHeader()->setResizeMode(
128 QHeaderView::ResizeToContents );
129 ui->pluginList->verticalHeader()->hide();
130 ui->pluginList->horizontalHeader()->setResizeMode( 0,
131 QHeaderView::Stretch );
132 ui->pluginList->horizontalHeader()->setResizeMode( 1,
133 QHeaderView::ResizeToContents );
134 ui->pluginList->sortByColumn( 0, Qt::AscendingOrder );
135 #if QT_VERSION >= 0x050000
136 #undef setResizeMode
137 #endif
138
139 updateSelection();
140 show();
141 }
142
143
144
145
~EffectSelectDialog()146 EffectSelectDialog::~EffectSelectDialog()
147 {
148 delete ui;
149 }
150
151
152
153
instantiateSelectedPlugin(EffectChain * _parent)154 Effect * EffectSelectDialog::instantiateSelectedPlugin( EffectChain * _parent )
155 {
156 if( !m_currentSelection.name.isEmpty() && m_currentSelection.desc )
157 {
158 return Effect::instantiate( m_currentSelection.desc->name,
159 _parent, &m_currentSelection );
160 }
161 return NULL;
162 }
163
164
165
166
acceptSelection()167 void EffectSelectDialog::acceptSelection()
168 {
169 if( m_currentSelection.isValid() )
170 {
171 accept();
172 }
173 }
174
175
176
177
rowChanged(const QModelIndex & _idx,const QModelIndex &)178 void EffectSelectDialog::rowChanged( const QModelIndex & _idx,
179 const QModelIndex & )
180 {
181 delete m_descriptionWidget;
182 m_descriptionWidget = NULL;
183
184 if( m_model.mapToSource( _idx ).row() < 0 )
185 {
186 // invalidate current selection
187 m_currentSelection = Plugin::Descriptor::SubPluginFeatures::Key();
188 }
189 else
190 {
191 m_currentSelection = m_effectKeys[m_model.mapToSource( _idx ).row()];
192 }
193 if( m_currentSelection.desc )
194 {
195 m_descriptionWidget = new QWidget;
196
197 QHBoxLayout *hbox = new QHBoxLayout( m_descriptionWidget );
198
199 Plugin::Descriptor const & descriptor = *( m_currentSelection.desc );
200
201 if ( descriptor.logo )
202 {
203 QLabel *logoLabel = new QLabel( m_descriptionWidget );
204 logoLabel->setPixmap( descriptor.logo->pixmap() );
205 logoLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
206
207 hbox->addWidget( logoLabel );
208 hbox->setAlignment( logoLabel, Qt::AlignTop);
209 }
210
211 QWidget *textualInfoWidget = new QWidget( m_descriptionWidget );
212
213 hbox->addWidget(textualInfoWidget);
214
215 QVBoxLayout * textWidgetLayout = new QVBoxLayout( textualInfoWidget);
216 textWidgetLayout->setMargin( 4 );
217 textWidgetLayout->setSpacing( 0 );
218
219 if ( m_currentSelection.desc->subPluginFeatures )
220 {
221 QWidget *subWidget = new QWidget(textualInfoWidget);
222 QVBoxLayout * subLayout = new QVBoxLayout( subWidget );
223 subLayout->setMargin( 4 );
224 subLayout->setSpacing( 0 );
225 m_currentSelection.desc->subPluginFeatures->
226 fillDescriptionWidget( subWidget, &m_currentSelection );
227 for( QWidget * w : subWidget->findChildren<QWidget *>() )
228 {
229 if( w->parent() == subWidget )
230 {
231 subLayout->addWidget( w );
232 }
233 }
234
235 textWidgetLayout->addWidget(subWidget);
236 }
237 else
238 {
239 QLabel *label = new QLabel(m_descriptionWidget);
240 QString labelText = "<p><b>" + tr("Name") + ":</b> " + QString::fromUtf8(descriptor.displayName) + "</p>";
241 labelText += "<p><b>" + tr("Description") + ":</b> " + qApp->translate( "pluginBrowser", descriptor.description ) + "</p>";
242 labelText += "<p><b>" + tr("Author") + ":</b> " + QString::fromUtf8(descriptor.author) + "</p>";
243
244 label->setText(labelText);
245 textWidgetLayout->addWidget(label);
246 }
247
248 ui->scrollArea->setWidget( m_descriptionWidget );
249 m_descriptionWidget->show();
250 }
251 }
252
253
254
255
sortAgain()256 void EffectSelectDialog::sortAgain()
257 {
258 ui->pluginList->setSortingEnabled( ui->pluginList->isSortingEnabled() );
259 }
260
261
262
263
updateSelection()264 void EffectSelectDialog::updateSelection()
265 {
266 // no valid selection anymore due to changed filter?
267 if( ui->pluginList->selectionModel()->selection().size() <= 0 )
268 {
269 // then select our first item
270 ui->pluginList->selectionModel()->select( m_model.index( 0, 0 ),
271 QItemSelectionModel::ClearAndSelect
272 | QItemSelectionModel::Rows );
273 rowChanged( m_model.index( 0, 0 ), QModelIndex() );
274 }
275 }
276
277
278
279
280
281