Merge brnach 'stable-1.2'
This commit is contained in:
@@ -42,8 +42,6 @@ AutomatableModel::AutomatableModel( DataType type,
|
||||
Model( parent, displayName, defaultConstructed ),
|
||||
m_dataType( type ),
|
||||
m_scaleType( Linear ),
|
||||
m_value( val ),
|
||||
m_initValue( val ),
|
||||
m_minValue( min ),
|
||||
m_maxValue( max ),
|
||||
m_step( step ),
|
||||
@@ -59,6 +57,7 @@ AutomatableModel::AutomatableModel( DataType type,
|
||||
m_hasSampleExactData( false )
|
||||
|
||||
{
|
||||
m_value = fittedValue( val );
|
||||
setInitValue( val );
|
||||
}
|
||||
|
||||
@@ -523,14 +522,8 @@ float AutomatableModel::controllerValue( int frameOffset ) const
|
||||
|
||||
ValueBuffer * AutomatableModel::valueBuffer()
|
||||
{
|
||||
// if we've already calculated the valuebuffer this period, return the cached buffer
|
||||
if( m_lastUpdatedPeriod == s_periodCounter )
|
||||
{
|
||||
return m_hasSampleExactData
|
||||
? &m_valueBuffer
|
||||
: NULL;
|
||||
}
|
||||
QMutexLocker m( &m_valueBufferMutex );
|
||||
// if we've already calculated the valuebuffer this period, return the cached buffer
|
||||
if( m_lastUpdatedPeriod == s_periodCounter )
|
||||
{
|
||||
return m_hasSampleExactData
|
||||
@@ -626,6 +619,7 @@ void AutomatableModel::setInitValue( const float value )
|
||||
m_initValue = fittedValue( value );
|
||||
bool journalling = testAndSetJournalling( false );
|
||||
setValue( value );
|
||||
m_oldValue = m_value;
|
||||
setJournalling( journalling );
|
||||
emit initValueChanged( value );
|
||||
}
|
||||
|
||||
@@ -501,6 +501,20 @@ void Mixer::clear()
|
||||
|
||||
|
||||
|
||||
void Mixer::clearNewPlayHandles()
|
||||
{
|
||||
requestChangeInModel();
|
||||
for( LocklessListElement * e = m_newPlayHandles.popList(); e; )
|
||||
{
|
||||
LocklessListElement * next = e->next;
|
||||
m_newPlayHandles.free( e );
|
||||
e = next;
|
||||
}
|
||||
doneChangeInModel();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// removes all play-handles. this is necessary, when the song is stopped ->
|
||||
// all remaining notes etc. would be played until their end
|
||||
void Mixer::clearInternal()
|
||||
|
||||
@@ -86,6 +86,7 @@ Song::Song() :
|
||||
m_playing( false ),
|
||||
m_paused( false ),
|
||||
m_loadingProject( false ),
|
||||
m_isCancelled( false ),
|
||||
m_playMode( Mode_None ),
|
||||
m_length( 0 ),
|
||||
m_patternToPlay( NULL ),
|
||||
@@ -1068,7 +1069,7 @@ void Song::loadProject( const QString & fileName )
|
||||
}
|
||||
}
|
||||
|
||||
while( !node.isNull() )
|
||||
while( !node.isNull() && !isCancelled() )
|
||||
{
|
||||
if( node.isElement() )
|
||||
{
|
||||
@@ -1127,6 +1128,13 @@ void Song::loadProject( const QString & fileName )
|
||||
|
||||
emit projectLoaded();
|
||||
|
||||
if( isCancelled() )
|
||||
{
|
||||
m_isCancelled = false;
|
||||
createNewProject();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( hasErrors())
|
||||
{
|
||||
if ( gui )
|
||||
@@ -1272,7 +1280,7 @@ void Song::saveControllerStates( QDomDocument & doc, QDomElement & element )
|
||||
void Song::restoreControllerStates( const QDomElement & element )
|
||||
{
|
||||
QDomNode node = element.firstChild();
|
||||
while( !node.isNull() )
|
||||
while( !node.isNull() && !isCancelled() )
|
||||
{
|
||||
Controller * c = Controller::create( node.toElement(), this );
|
||||
Q_ASSERT( c != NULL );
|
||||
|
||||
@@ -33,12 +33,14 @@
|
||||
#include "AutomationTrack.h"
|
||||
#include "BBTrack.h"
|
||||
#include "BBTrackContainer.h"
|
||||
#include "embed.h"
|
||||
#include "TrackContainer.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "Song.h"
|
||||
|
||||
#include "GuiApplication.h"
|
||||
#include "MainWindow.h"
|
||||
#include "TextFloat.h"
|
||||
|
||||
TrackContainer::TrackContainer() :
|
||||
Model( NULL ),
|
||||
@@ -110,6 +112,14 @@ void TrackContainer::loadSettings( const QDomElement & _this )
|
||||
QEventLoop::AllEvents, 100 );
|
||||
if( pd->wasCanceled() )
|
||||
{
|
||||
if ( gui )
|
||||
{
|
||||
TextFloat::displayMessage( tr( "Loading cancelled" ),
|
||||
tr( "Project loading was cancelled." ),
|
||||
embed::getIconPixmap( "project_file", 24, 24 ),
|
||||
2000 );
|
||||
}
|
||||
Engine::getSong()->loadingCancelled();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -615,7 +615,7 @@ char * MidiApple::getFullName(MIDIEndpointRef &endpoint_ref)
|
||||
char * deviceName = getName(device);
|
||||
char * endPointName = getName(endpoint_ref);
|
||||
qDebug("device name='%s' endpoint name='%s'",deviceName,endPointName);
|
||||
char * fullName = (char *)malloc(strlen(deviceName) + strlen(endPointName)+1);
|
||||
char * fullName = (char *)malloc(strlen(deviceName) + strlen(":") + strlen(endPointName)+1);
|
||||
sprintf(fullName, "%s:%s", deviceName,endPointName);
|
||||
return fullName;
|
||||
}
|
||||
|
||||
@@ -327,6 +327,16 @@ void AutomationPatternView::paintEvent( QPaintEvent * )
|
||||
|
||||
float *values = m_pat->valuesAfter( it.key() );
|
||||
|
||||
float nextValue;
|
||||
if( m_pat->progressionType() == AutomationPattern::DiscreteProgression )
|
||||
{
|
||||
nextValue = it.value();
|
||||
}
|
||||
else
|
||||
{
|
||||
nextValue = ( it + 1 ).value();
|
||||
}
|
||||
|
||||
QPainterPath path;
|
||||
QPointF origin = QPointF( x_base + it.key() * ppTick, 0.0f );
|
||||
path.moveTo( origin );
|
||||
@@ -340,7 +350,7 @@ void AutomationPatternView::paintEvent( QPaintEvent * )
|
||||
path.lineTo( QPointF( x, value ) );
|
||||
|
||||
}
|
||||
path.lineTo( x_base + ( ( it + 1 ).key() ) * ppTick, values[ ( it + 1 ).key() - 1 - it.key() ] );
|
||||
path.lineTo( x_base + ( ( it + 1 ).key() ) * ppTick, nextValue );
|
||||
path.lineTo( x_base + ( ( it + 1 ).key() ) * ppTick, 0.0f );
|
||||
path.lineTo( origin );
|
||||
|
||||
|
||||
@@ -382,6 +382,10 @@ void FxMixerView::deleteChannel(int index)
|
||||
// remember selected line
|
||||
int selLine = m_currentFxLine->channelIndex();
|
||||
|
||||
// in case the deleted channel is soloed or the remaining
|
||||
// channels will be left in a muted state
|
||||
Engine::fxMixer()->clearChannel(index);
|
||||
|
||||
// delete the real channel
|
||||
Engine::fxMixer()->deleteChannel(index);
|
||||
|
||||
|
||||
@@ -33,7 +33,12 @@
|
||||
|
||||
MainApplication::MainApplication(int& argc, char** argv) :
|
||||
QApplication(argc, argv),
|
||||
m_queuedFile() {}
|
||||
m_queuedFile()
|
||||
{
|
||||
#if defined(LMMS_BUILD_WIN32) && QT_VERSION >= 0x050000
|
||||
installNativeEventFilter(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool MainApplication::event(QEvent* event)
|
||||
{
|
||||
@@ -64,6 +69,7 @@ bool MainApplication::event(QEvent* event)
|
||||
}
|
||||
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
// This can be moved into nativeEventFilter once Qt4 support has been dropped
|
||||
bool MainApplication::winEventFilter(MSG* msg, long* result)
|
||||
{
|
||||
switch(msg->message)
|
||||
@@ -85,4 +91,16 @@ bool MainApplication::winEventFilter(MSG* msg, long* result)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
bool MainApplication::nativeEventFilter(const QByteArray& eventType,
|
||||
void* message, long* result)
|
||||
{
|
||||
if(eventType == "windows_generic_MSG")
|
||||
{
|
||||
return winEventFilter(static_cast<MSG *>(message), result);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QShortcut>
|
||||
#include <QLibrary>
|
||||
#include <QSplitter>
|
||||
#include <QUrl>
|
||||
#include <QWhatsThis>
|
||||
@@ -64,6 +65,21 @@
|
||||
|
||||
#include "lmmsversion.h"
|
||||
|
||||
#if !defined(LMMS_BUILD_WIN32) && !defined(LMMS_BULID_APPLE) && !defined(LMMS_BUILD_HAIKU)
|
||||
//Work around an issue on KDE5 as per https://bugs.kde.org/show_bug.cgi?id=337491#c21
|
||||
void disableAutoKeyAccelerators(QWidget* mainWindow)
|
||||
{
|
||||
using DisablerFunc = void(*)(QWidget*);
|
||||
QLibrary kf5WidgetsAddon("KF5WidgetsAddons", 5);
|
||||
DisablerFunc setNoAccelerators =
|
||||
reinterpret_cast<DisablerFunc>(kf5WidgetsAddon.resolve("_ZN19KAcceleratorManager10setNoAccelEP7QWidget"));
|
||||
if(setNoAccelerators)
|
||||
{
|
||||
setNoAccelerators(mainWindow);
|
||||
}
|
||||
kf5WidgetsAddon.unload();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
MainWindow::MainWindow() :
|
||||
@@ -76,6 +92,9 @@ MainWindow::MainWindow() :
|
||||
m_metronomeToggle( 0 ),
|
||||
m_session( Normal )
|
||||
{
|
||||
#if !defined(LMMS_BUILD_WIN32) && !defined(LMMS_BULID_APPLE) && !defined(LMMS_BUILD_HAIKU)
|
||||
disableAutoKeyAccelerators(this);
|
||||
#endif
|
||||
setAttribute( Qt::WA_DeleteOnClose );
|
||||
|
||||
QWidget * main_widget = new QWidget( this );
|
||||
@@ -836,8 +855,8 @@ void MainWindow::createNewProjectFromTemplate( QAction * _idx )
|
||||
ConfigManager::inst()->factoryTemplatesDir() :
|
||||
ConfigManager::inst()->userTemplateDir();
|
||||
|
||||
Engine::getSong()->createNewProjectFromTemplate(
|
||||
dirBase + _idx->text() + ".mpt" );
|
||||
const QString f = dirBase + _idx->text().replace("&&", "&") + ".mpt";
|
||||
Engine::getSong()->createNewProjectFromTemplate(f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -888,7 +907,7 @@ void MainWindow::updateRecentlyOpenedProjectsMenu()
|
||||
}
|
||||
|
||||
m_recentlyOpenedProjectsMenu->addAction(
|
||||
embed::getIconPixmap( "project_file" ), *it );
|
||||
embed::getIconPixmap( "project_file" ), it->replace("&", "&&") );
|
||||
#ifdef LMMS_BUILD_APPLE
|
||||
m_recentlyOpenedProjectsMenu->actions().last()->setIconVisibleInMenu(false); // QTBUG-44565 workaround
|
||||
m_recentlyOpenedProjectsMenu->actions().last()->setIconVisibleInMenu(true);
|
||||
@@ -904,12 +923,11 @@ void MainWindow::updateRecentlyOpenedProjectsMenu()
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::openRecentlyOpenedProject( QAction * _action )
|
||||
{
|
||||
if ( mayChangeProject(true) )
|
||||
{
|
||||
const QString & f = _action->text();
|
||||
const QString f = _action->text().replace("&&", "&");
|
||||
setCursor( Qt::WaitCursor );
|
||||
Engine::getSong()->loadProject( f );
|
||||
setCursor( Qt::ArrowCursor );
|
||||
@@ -1500,7 +1518,7 @@ void MainWindow::fillTemplatesMenu()
|
||||
{
|
||||
m_templatesMenu->addAction(
|
||||
embed::getIconPixmap( "project_file" ),
|
||||
( *it ).left( ( *it ).length() - 4 ) );
|
||||
( *it ).left( ( *it ).length() - 4 ).replace("&", "&&") );
|
||||
#ifdef LMMS_BUILD_APPLE
|
||||
m_templatesMenu->actions().last()->setIconVisibleInMenu(false); // QTBUG-44565 workaround
|
||||
m_templatesMenu->actions().last()->setIconVisibleInMenu(true);
|
||||
|
||||
@@ -518,16 +518,13 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
|
||||
// loop through whole time-map...
|
||||
while( it != time_map.end() )
|
||||
{
|
||||
MidiTime len = 4;
|
||||
|
||||
// and check whether the user clicked on an
|
||||
// existing value
|
||||
if( pos_ticks >= it.key() &&
|
||||
len > 0 &&
|
||||
( it+1==time_map.end() ||
|
||||
pos_ticks <= (it+1).key() ) &&
|
||||
( pos_ticks<= it.key() + MidiTime::ticksPerTact() *4 / m_ppt ) &&
|
||||
level <= it.value() )
|
||||
level == it.value() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -1379,13 +1376,13 @@ void AutomationEditor::paintEvent(QPaintEvent * pe )
|
||||
float *values = m_pattern->valuesAfter( it.key() );
|
||||
|
||||
float nextValue;
|
||||
if ( m_pattern->valuesAfter( ( it + 1 ).key() ) != NULL )
|
||||
if( m_pattern->progressionType() == AutomationPattern::DiscreteProgression )
|
||||
{
|
||||
nextValue = *( m_pattern->valuesAfter( ( it + 1 ).key() ) );
|
||||
nextValue = it.value();
|
||||
}
|
||||
else
|
||||
{
|
||||
nextValue = values[ ( it + 1 ).key() - it.key() -1 ];
|
||||
nextValue = ( it + 1 ).value();
|
||||
}
|
||||
|
||||
p.setRenderHints( QPainter::Antialiasing, true );
|
||||
|
||||
Reference in New Issue
Block a user