hydrogen 1.2.3
SoundLibraryPropertiesDialog.cpp
Go to the documentation of this file.
1/*
2 * Hydrogen
3 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4 * Copyright(c) 2008-2024 The hydrogen development team [hydrogen-devel@lists.sourceforge.net]
5 *
6 * http://www.hydrogen-music.org
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (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
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see https://www.gnu.org/licenses
20 *
21 */
22
23#include <QtGui>
24#include <QtWidgets>
25
26#include "../HydrogenApp.h"
27#include "../CommonStrings.h"
28
30#include "../InstrumentRack.h"
31#include "SoundLibraryPanel.h"
33#include <core/Hydrogen.h>
36
37namespace H2Core
38{
39
40SoundLibraryPropertiesDialog::SoundLibraryPropertiesDialog( QWidget* pParent, std::shared_ptr<Drumkit> pDrumkit, bool bDrumkitNameLocked )
41 : QDialog( pParent )
42 , m_pDrumkit( pDrumkit )
43 , m_bDrumkitNameLocked( bDrumkitNameLocked )
44 , m_sNewImagePath( "" )
45{
46 setObjectName( "SoundLibraryPropertiesDialog" );
47
48 setupUi( this );
49
50 auto pPref = Preferences::get_instance();
51 auto pCommonStrings = HydrogenApp::get_instance()->getCommonStrings();
52
53 setWindowTitle( tr( "SoundLibrary Properties" ) );
54 adjustSize();
55 setMinimumSize( width(), height() );
56
57 setupLicenseComboBox( licenseComboBox );
58 connect( licenseComboBox, SIGNAL( currentIndexChanged( int ) ),
59 this, SLOT( licenseComboBoxChanged( int ) ) );
60 setupLicenseComboBox( imageLicenseComboBox );
61 connect( imageLicenseComboBox, SIGNAL( currentIndexChanged( int ) ),
62 this, SLOT( imageLicenseComboBoxChanged( int ) ) );
63
64 bool bDrumkitWritable = false;
65 //display the current drumkit infos into the qlineedit
66 if ( pDrumkit != nullptr ){
67
68 auto drumkitType = Filesystem::determineDrumkitType(
69 pDrumkit->get_path() );
70 if ( drumkitType == Filesystem::DrumkitType::User ||
72 bDrumkitWritable = true;
73 }
74
75 nameTxt->setText( pDrumkit->get_name() );
76
77 if ( bDrumkitNameLocked ) {
78 nameTxt->setIsActive( false );
79 nameTxt->setToolTip( tr( "Altering the name of a drumkit would result in the creation of a new one. To do so, you need to load the drumkit (if you haven't done so already) using right click > load and select Drumkits > Save As in the main menu" ) );
80 }
81
82 authorTxt->setText( QString( pDrumkit->get_author() ) );
83 infoTxt->append( QString( pDrumkit->get_info() ) );
84
85 License license = pDrumkit->get_license();
86 licenseComboBox->setCurrentIndex( static_cast<int>( license.getType() ) );
87 licenseStringTxt->setText( license.getLicenseString() );
88
89 imageText->setText( QString( pDrumkit->get_image() ) );
90
91 License imageLicense = pDrumkit->get_image_license();
92 imageLicenseComboBox->setCurrentIndex( static_cast<int>( imageLicense.getType() ) );
93 imageLicenseStringTxt->setText( imageLicense.getLicenseString() );
94 }
95
96 if ( licenseComboBox->currentIndex() == static_cast<int>( License::Unspecified ) ) {
97 licenseStringLbl->hide();
98 licenseStringTxt->hide();
99 }
100 if ( imageLicenseComboBox->currentIndex() == static_cast<int>( License::Unspecified ) ) {
101 imageLicenseStringLbl->hide();
102 imageLicenseStringTxt->hide();
103 }
104
105 licenseComboBox->setToolTip( pCommonStrings->getLicenseComboToolTip() );
106 licenseStringLbl->setText( pCommonStrings->getLicenseStringLbl() );
107 licenseStringTxt->setToolTip( pCommonStrings->getLicenseStringToolTip() );
108 imageLicenseComboBox->setToolTip( pCommonStrings->getLicenseComboToolTip() );
109 imageLicenseStringLbl->setText( pCommonStrings->getLicenseStringLbl() );
110 imageLicenseStringTxt->setToolTip( pCommonStrings->getLicenseStringToolTip() );
111
112 // In case the drumkit name is not locked/the dialog is used as
113 // "Save As" nothing needs to be disabled.
114 if ( ! bDrumkitWritable && bDrumkitNameLocked ) {
115 QString sToolTip = tr( "The current drumkit is read-only. Please use Drumkits > Save As in the main menu to create a new one first." );
116
117 // The drumkit is read-only. Thus we won't support altering
118 // any of its properties.
119 authorTxt->setIsActive( false );
120 authorTxt->setToolTip( sToolTip );
121 infoTxt->setEnabled( false );
122 infoTxt->setReadOnly( true );
123 infoTxt->setToolTip( sToolTip );
124 licenseComboBox->setIsActive( false );
125 licenseComboBox->setToolTip( sToolTip );
126 licenseStringTxt->setIsActive( false );
127 licenseStringTxt->setToolTip( sToolTip );
128 imageText->setIsActive( false );
129 imageText->setToolTip( sToolTip );
130 imageLicenseComboBox->setIsActive( false );
131 imageLicenseComboBox->setToolTip( sToolTip );
132 imageLicenseStringTxt->setIsActive( false );
133 imageLicenseStringTxt->setToolTip( sToolTip );
134 saveBtn->setIsActive( false );
135 saveBtn->setToolTip( sToolTip );
136 imageBrowsePushButton->setIsActive( false );
137 imageBrowsePushButton->setToolTip( sToolTip );
138
139 // Rather dirty fix to align the design of the QTextEdit to
140 // the coloring of our custom QLineEdits.
141 infoTxt->setStyleSheet( QString( "\
142QTextEdit { \
143 color: %1; \
144 background-color: %2; \
145}" )
146 .arg( pPref->getColorTheme()->m_windowTextColor.name() )
147 .arg( pPref->getColorTheme()->m_windowColor.name() ) );
148
149 }
150
151 saveBtn->setFixedFontSize( 12 );
152 saveBtn->setSize( QSize( 70, 23 ) );
153 saveBtn->setBorderRadius( 3 );
154 m_cancelBtn->setFixedFontSize( 12 );
155 m_cancelBtn->setSize( QSize( 70, 23 ) );
156 m_cancelBtn->setBorderRadius( 3 );
157 imageBrowsePushButton->setFixedFontSize( 12 );
158 imageBrowsePushButton->setBorderRadius( 3 );
159 imageBrowsePushButton->setSize( QSize( 70, 23 ) );
160
161 contentTable->setColumnCount( 4 );
162 contentTable->setHorizontalHeaderLabels( QStringList() <<
163 tr( "Instrument" ) <<
164 tr( "Component" ) <<
165 tr( "Sample" ) <<
166 tr( "License" ) );
167 contentTable->verticalHeader()->hide();
168 contentTable->horizontalHeader()->setStretchLastSection( true );
169
170 contentTable->setColumnWidth( 0, 160 );
171 contentTable->setColumnWidth( 1, 80 );
172 contentTable->setColumnWidth( 2, 210 );
173
175}
176
177
183
184
187{
188 if ( m_pDrumkit != nullptr &&
189 ! m_pDrumkit->get_image().isEmpty() ) {
190 QString sImage = m_pDrumkit->get_path() + "/" + m_pDrumkit->get_image();
191 updateImage( sImage );
192 }
193 else {
194 drumkitImageLabel->hide();
195 }
196}
197
200 auto pSong = H2Core::Hydrogen::get_instance()->getSong();
201
202 if ( m_pDrumkit == nullptr ){
203 return;
204 }
205
206 auto contentVector = m_pDrumkit->summarizeContent();
207
208 if ( contentVector.size() > 0 ) {
209 contentTable->show();
210 contentLabel->show();
211 contentTable->setRowCount( contentVector.size() );
212
213 int nFirstMismatchRow = -1;
214
215 for ( int ii = 0; ii < contentVector.size(); ++ ii ) {
216 const auto ccontent = contentVector[ ii ];
217
218 QLineEdit* pInstrumentItem = new QLineEdit( ccontent->m_sInstrumentName );
219 pInstrumentItem->setEnabled( false );
220 pInstrumentItem->setToolTip( ccontent->m_sInstrumentName );
221 QLineEdit* pComponentItem = new QLineEdit( ccontent->m_sComponentName );
222 pComponentItem->setEnabled( false );
223 pComponentItem->setToolTip( ccontent->m_sComponentName );
224 QLineEdit* pSampleItem = new QLineEdit( ccontent->m_sSampleName );
225 pSampleItem->setEnabled( false );
226 pSampleItem->setToolTip( ccontent->m_sSampleName );
227 QLineEdit* pLicenseItem =
228 new QLineEdit( ccontent->m_license.getLicenseString() );
229 pLicenseItem->setEnabled( false );
230 pLicenseItem->setToolTip( ccontent->m_license.getLicenseString() );
231
232 // In case of a license mismatch we highlight the row
233 if ( ccontent->m_license != m_pDrumkit->get_license() ) {
234 QString sRed = QString( "color: %1; background-color: %2" )
235 .arg( pPref->getColorTheme()->m_buttonRedColor.name() )
236 .arg( pPref->getColorTheme()->m_windowColor.name() );
237 pInstrumentItem->setStyleSheet( sRed );
238 pComponentItem->setStyleSheet( sRed );
239 pSampleItem->setStyleSheet( sRed );
240 pLicenseItem->setStyleSheet( sRed );
241
242 if ( nFirstMismatchRow == -1 ) {
243 nFirstMismatchRow = ii;
244 }
245 }
246
247 contentTable->setCellWidget( ii, 0, pInstrumentItem );
248 contentTable->setCellWidget( ii, 1, pComponentItem );
249 contentTable->setCellWidget( ii, 2, pSampleItem );
250 contentTable->setCellWidget( ii, 3, pLicenseItem );
251 }
252
253 // In case of a mismatch scroll into view
254 if ( nFirstMismatchRow != -1 ) {
255 contentTable->showRow( nFirstMismatchRow );
256 }
257 }
258 else {
259 contentTable->hide();
260 contentLabel->hide();
261 }
262}
263
265
266 licenseStringTxt->setText( License::LicenseTypeToQString(
267 static_cast<License::LicenseType>( licenseComboBox->currentIndex() ) ) );
268
269 if ( licenseComboBox->currentIndex() == static_cast<int>( License::Unspecified ) ) {
270 licenseStringLbl->hide();
271 licenseStringTxt->hide();
272 }
273 else {
274 licenseStringLbl->show();
275 licenseStringTxt->show();
276 }
277
279}
280
282
283 imageLicenseStringTxt->setText( License::LicenseTypeToQString(
284 static_cast<License::LicenseType>( imageLicenseComboBox->currentIndex() ) ) );
285
286 if ( imageLicenseComboBox->currentIndex() == static_cast<int>( License::Unspecified ) ) {
287 imageLicenseStringLbl->hide();
288 imageLicenseStringTxt->hide();
289 }
290 else {
291 imageLicenseStringLbl->show();
292 imageLicenseStringTxt->show();
293 }
294}
295
297{
298 QPixmap *pPixmap = new QPixmap ( filename );
299
300 // Check whether the loading worked.
301 if ( pPixmap->isNull() ) {
302 ERRORLOG( QString( "Unable to load pixmap from [%1]" ).arg( filename ) );
303 drumkitImageLabel->hide();
304 return;
305 }
306
307 // scale the image down to fit if required
308 int x = (int) drumkitImageLabel->size().width();
309 int y = drumkitImageLabel->size().height();
310 float labelAspect = (float) x / y;
311 float imageAspect = (float) pPixmap->width() / pPixmap->height();
312
313 if ( ( x < pPixmap->width() ) || ( y < pPixmap->height() ) )
314 {
315 if ( labelAspect >= imageAspect )
316 {
317 // image is taller or the same as label frame
318 *pPixmap = pPixmap->scaledToHeight( y );
319 }
320 else
321 {
322 // image is wider than label frame
323 *pPixmap = pPixmap->scaledToWidth( x );
324 }
325 }
326 drumkitImageLabel->setPixmap(*pPixmap);
327 drumkitImageLabel->show();
328
329}
330
332{
333 if ( m_pDrumkit == nullptr ) {
334 return;
335 }
336
337 // Try to get the drumkit directory and open file browser
338 QString sDrumkitDir = m_pDrumkit->get_path();
339
340 QString sFilePath = QFileDialog::getOpenFileName(this, tr("Open Image"), sDrumkitDir, tr("Image Files (*.png *.jpg *.jpeg)"));
341
342 // If cancel was clicked just abort
343 if ( sFilePath == nullptr || sFilePath.isEmpty() ) {
344 return;
345 }
346
347 m_sNewImagePath = sFilePath;
348
349 QFileInfo fileInfo( sFilePath );
350 QString sFileName( fileInfo.fileName() );
351 imageText->setText( sFileName );
352
353 updateImage( sFilePath );
354}
355
357{
358 if ( m_pDrumkit == nullptr ) {
359 return;
360 }
361
362 auto pHydrogen = Hydrogen::get_instance();
363 auto pSong = pHydrogen->getSong();
364 auto pCommonStrings = HydrogenApp::get_instance()->getCommonStrings();
365
366 // Sanity checks.
367 //
368 // Check whether the license strings from the line edits comply to
369 // the license types selected in the combo boxes.
370 License licenseCheck( licenseStringTxt->text() );
371 if ( static_cast<int>(licenseCheck.getType()) != licenseComboBox->currentIndex() ) {
372 if ( QMessageBox::warning( this, "Hydrogen",
373 tr( "Specified drumkit License String does not comply with the license selected in the combo box." ),
374 QMessageBox::Ok | QMessageBox::Cancel,
375 QMessageBox::Cancel )
376 == QMessageBox::Cancel ) {
377 WARNINGLOG( QString( "Abort, since drumkit License String [%1] does not comply to selected License Type [%2]" )
378 .arg( licenseStringTxt->text() )
380 static_cast<License::LicenseType>(licenseComboBox->currentIndex()) ) ) );
381 return;
382 }
383 }
384 License imageLicenseCheck( imageLicenseStringTxt->text() );
385 if ( static_cast<int>(imageLicenseCheck.getType()) !=
386 imageLicenseComboBox->currentIndex() ) {
387 if ( QMessageBox::warning( this, "Hydrogen",
388 tr( "Specified image License String does not comply with the license selected in the combo box." ),
389 QMessageBox::Ok | QMessageBox::Cancel,
390 QMessageBox::Cancel )
391 == QMessageBox::Cancel ) {
392 WARNINGLOG( QString( "Abort, since drumkit image License String [%1] does not comply to selected License Type [%2]" )
393 .arg( imageLicenseStringTxt->text() )
395 static_cast<License::LicenseType>(imageLicenseComboBox->currentIndex()) ) ) );
396 return;
397 }
398 }
399
400 //check the name and set the drumkitinfo to current drumkit
401 if ( nameTxt->text().isEmpty() ){
402 QMessageBox::warning( this, "Hydrogen", tr( "The name of the drumkit must not be left empty" ) );
403 return;
404 }
405
406 QString sNewLicenseString( licenseStringTxt->text() );
407 if ( licenseComboBox->currentIndex() ==
408 static_cast<int>(License::Unspecified) ) {
409 sNewLicenseString = "";
410 }
411 License newLicense( sNewLicenseString );
412 newLicense.setCopyrightHolder( m_pDrumkit->get_author() );
413
414 QString sNewImageLicenseString( imageLicenseStringTxt->text() );
415 if ( imageLicenseComboBox->currentIndex() ==
416 static_cast<int>(License::Unspecified) ) {
417 sNewImageLicenseString = "";
418 }
419 License newImageLicense( sNewImageLicenseString );
420 newImageLicense.setCopyrightHolder( m_pDrumkit->get_author() );
421
422 const QString sOldPath = m_pDrumkit->get_path();
423 if ( m_pDrumkit->get_name() != nameTxt->text() ) {
424 m_pDrumkit->set_name( nameTxt->text() );
426 nameTxt->text() );
427 }
428 m_pDrumkit->set_author( authorTxt->text() );
429 m_pDrumkit->set_info( infoTxt->toHtml() );
430
431 // Only update the license in case it changed (in order to not
432 // overwrite an attribution).
433 if ( m_pDrumkit->get_license() != newLicense ) {
434 m_pDrumkit->set_license( newLicense );
435 }
436
438 ERRORLOG( "User cancelled dialog due to licensing issues." );
439 return;
440 }
441
442 // Will contain image which should be removed. To keep the previous image,
443 // this string should be empty.
444 QString sOldImagePath;
445 if ( imageText->text() != m_pDrumkit->get_image() ) {
446 int nRes = QMessageBox::information( this, "Hydrogen",
447 tr( "Delete previous drumkit image" )
448 .append( QString( " [%1]" ).arg( m_pDrumkit->get_image() ) ),
449 QMessageBox::Yes | QMessageBox::No );
450 if ( nRes == QMessageBox::Yes ) {
451 sOldImagePath = QString( "%1/%2" ).arg( sOldPath )
452 .arg( m_pDrumkit->get_image() );
453 }
454 m_pDrumkit->set_image( imageText->text() );
455 }
456
457 if ( m_pDrumkit->get_image_license() != newImageLicense ) {
458 m_pDrumkit->set_image_license( newImageLicense );
459 }
460
461 QApplication::setOverrideCursor(Qt::WaitCursor);
462
463 // Write new properties to disk.
464 if ( ! m_pDrumkit->save() ) {
465 QApplication::restoreOverrideCursor();
466 QMessageBox::information( this, "Hydrogen", tr ( "Saving of this drumkit failed."));
467 ERRORLOG( "Saving of this drumkit failed." );
468 return;
469 }
470
471 // Copy the selected image into the drumkit folder (in case a file outside
472 // of it was selected.)
473 if ( ! m_sNewImagePath.isEmpty() ) {
474 QFileInfo fileInfo( m_sNewImagePath );
475
476 if ( fileInfo.dir().absolutePath() != m_pDrumkit->get_path() ) {
477 INFOLOG( QString( "Copying [%1] into [%2]" ).arg( m_sNewImagePath )
478 .arg( m_pDrumkit->get_path() ) );
479 const QString sTargetPath =
480 QString( "%1/%2" ).arg( m_pDrumkit->get_path() )
481 .arg( fileInfo.fileName() );
482 // Logging is done in file_copy.
483 Filesystem::file_copy( m_sNewImagePath, sTargetPath, true, false );
484 }
485 }
486
487 if ( ! sOldImagePath.isEmpty() ) {
488 Filesystem::rm( sOldImagePath, false, false );
489 }
490
491 pHydrogen->getSoundLibraryDatabase()->updateDrumkits();
492
493 QApplication::restoreOverrideCursor();
494
495 accept();
496
497}
498
499}
#define INFOLOG(x)
Definition Object.h:237
#define WARNINGLOG(x)
Definition Object.h:238
#define ERRORLOG(x)
Definition Object.h:239
static bool file_copy(const QString &src, const QString &dst, bool overwrite=false, bool bSilent=false)
copy a source file to a destination
static DrumkitType determineDrumkitType(const QString &sPath)
static QString usr_drumkits_dir()
returns user drumkits path
static bool rm(const QString &path, bool recursive=false, bool bSilent=false)
remove a path
@ SessionReadWrite
Kit was loaded via a NSM session, OSC command, or CLI option, only persist for the current Hydrogen s...
@ User
Kit was installed by the user, is automatically loaded, and most probably writable.
std::shared_ptr< Song > getSong() const
Get the current song.
Definition Hydrogen.h:122
static Hydrogen * get_instance()
Returns the current Hydrogen instance __instance.
Definition Hydrogen.h:83
Wrapper class to help Hydrogen deal with the license information specified in a drumkit.
Definition License.h:48
LicenseType
A couple of recognized licenses.
Definition License.h:58
@ Unspecified
No license set yet.
Definition License.h:74
LicenseType getType() const
Definition License.h:143
void setCopyrightHolder(const QString &sCopyrightHolder)
Definition License.h:152
QString getLicenseString() const
Definition License.h:146
static QString LicenseTypeToQString(LicenseType license)
Definition License.h:155
static Preferences * get_instance()
Returns a pointer to the current Preferences singleton stored in __instance.
SoundLibraryPropertiesDialog(QWidget *pParent, std::shared_ptr< Drumkit > pDrumkit, bool bDrumkitNameLocked)
void showEvent(QShowEvent *e) override
On showing the dialog (after layout sizes have been applied), load the drumkit image if any.
static HydrogenApp * get_instance()
Returns the instance of HydrogenApp class.
std::shared_ptr< CommonStrings > getCommonStrings()
static bool checkDrumkitLicense(std::shared_ptr< H2Core::Drumkit > pDrumkit)
void setupLicenseComboBox(QComboBox *pComboBox)