diff --git a/ChangeLog b/ChangeLog index 876ee30cb5..17d049e110 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,44 @@ +2005-12-14 Tobias Doerffel + + * src/core/file_browser.cpp: + display text-float while loading sample for preview + + * plugins/audio_file_processor/audio_file_processor.cpp: + fixed bug which caused LMMS to crash when playing notes on + audio-file-processor, which was created out of preset containing link + to file which doesn't exist + + * src/core/song_editor.cpp: + use text-floats instead of status-bar + + * src/core/lmms_main_win.cpp: + removed status-bar + + * plugins/vestige/vestige.cpp: + show text-float while loading plugin + + * include/text_float.h: + * src/widgets/text_float.cpp: + heavy improvements on text-float-widget which is now also able to + display messages with title and pixmap and offers two static methods + for displaying a certain message + + * src/tracks/channel_track.cpp: + set project modified after accepting drops of presets/plugins + + * include/instrument_play_handle.h: + check for m_instrument being NULL because play-handle might be + invalidated and thus crash when referencing NULL-ptr + + * most files: + continued improving Qt4-support + +2005-12-13 Tobias Doerffel + + * most files: + made LMMS compatible with Qt4 again after heavy development under Qt3 + led to incompatibility with Qt4 + 2005-12-11 Tobias Doerffel * src/core/lmms_main_win.cpp: diff --git a/README b/README index bb5d69fb2d..36df111bee 100644 --- a/README +++ b/README @@ -48,7 +48,7 @@ least 500 MHz, but for really enjoying LMMS less than 1 GHz makes no sense... Required libraries are: - multithreaded version of Qt 3.0 (at least 3.2 recommended) or higher (tested - up to 4.0.0) with devel-files + up to 4.0.1) with devel-files Optional, but strongly recommended: - JACK with devel-files diff --git a/configure.in b/configure.in index f0c95e79b2..0d4dce4401 100644 --- a/configure.in +++ b/configure.in @@ -2,8 +2,8 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.50) -AC_INIT(lmms, 0.1.1-cvs20051213, tobydox/at/users.sourceforge.net) -AM_INIT_AUTOMAKE(lmms, 0.1.1-cvs20051213) +AC_INIT(lmms, 0.1.1-cvs20051214, tobydox/at/users.sourceforge.net) +AM_INIT_AUTOMAKE(lmms, 0.1.1-cvs20051214) AM_CONFIG_HEADER(config.h) diff --git a/include/instrument_play_handle.h b/include/instrument_play_handle.h index 3c9fbf7502..5e7df39459 100644 --- a/include/instrument_play_handle.h +++ b/include/instrument_play_handle.h @@ -46,7 +46,10 @@ public: inline virtual void play( void ) { - m_instrument->play(); + if( m_instrument != NULL ) + { + m_instrument->play(); + } } inline virtual bool done( void ) const @@ -56,7 +59,7 @@ public: inline virtual void checkValidity( void ) { - if( !m_instrument->valid() ) + if( m_instrument != NULL && !m_instrument->valid() ) { m_instrument = NULL; } diff --git a/include/nstate_button.h b/include/nstate_button.h index b27e81f0d7..cafb249b9a 100644 --- a/include/nstate_button.h +++ b/include/nstate_button.h @@ -48,6 +48,7 @@ #include "tool_button.h" + class nStateButton : public toolButton { Q_OBJECT @@ -80,7 +81,7 @@ protected: private: - vvector > m_states; + vvector > m_states; QString m_generalToolTip; int m_curState; diff --git a/include/song_editor.h b/include/song_editor.h index c21aebf757..091208c3eb 100644 --- a/include/song_editor.h +++ b/include/song_editor.h @@ -54,6 +54,7 @@ class lcdSpinBox; class lmmsMainWin; class pattern; class projectNotes; +class textFloat; class timeLine; class toolButton; @@ -281,7 +282,8 @@ private: QSlider * m_masterVolumeSlider; QSlider * m_masterPitchSlider; - + textFloat * m_mvsStatus; + textFloat * m_mpsStatus; toolButton * m_addBBTrackButton; toolButton * m_addSampleTrackButton; diff --git a/include/text_float.h b/include/text_float.h index d213b10e58..431276376f 100644 --- a/include/text_float.h +++ b/include/text_float.h @@ -31,10 +31,12 @@ #ifdef QT4 #include +#include #else #include +#include #endif @@ -47,19 +49,36 @@ public: { } + void setTitle( const QString & _title ); void setText( const QString & _text ); + void setPixmap( const QPixmap & _pixmap ); void reparent( QWidget * _new_parent ); void setVisibilityTimeOut( int _msecs ); + static textFloat * displayMessage( const QString & _msg, + int _timeout = 2000, + QWidget * _parent = NULL, + int _add_y_margin = 0 ); + static textFloat * displayMessage( const QString & _title, + const QString & _msg, + const QPixmap & _pixmap = + QPixmap(), + int _timeout = 2000, + QWidget * _parent = NULL ); + + protected: virtual void paintEvent( QPaintEvent * _me ); + virtual void mousePressEvent( QMouseEvent * _me ); private: + QString m_title; QString m_text; + QPixmap m_pixmap; } ; diff --git a/include/tool_button.h b/include/tool_button.h index 8eee8f5376..c4639bbe85 100644 --- a/include/tool_button.h +++ b/include/tool_button.h @@ -53,6 +53,8 @@ public: m_colorStandard( s_stdColor ), m_colorHighlighted( s_hlColor ) { + // setup colors + leaveEvent( NULL ); } ~toolButton(); @@ -66,6 +68,7 @@ public: { m_colorHighlighted = _color; } + #ifndef QT4 inline void setIcon( const QPixmap & _icon ) { @@ -73,6 +76,7 @@ public: } #endif + protected: virtual void enterEvent( QEvent * _ev ); virtual void leaveEvent( QEvent * _ev ); diff --git a/plugins/audio_file_processor/audio_file_processor.cpp b/plugins/audio_file_processor/audio_file_processor.cpp index d9547b7154..040fbcb28a 100644 --- a/plugins/audio_file_processor/audio_file_processor.cpp +++ b/plugins/audio_file_processor/audio_file_processor.cpp @@ -389,7 +389,6 @@ void audioFileProcessor::playNote( notePlayHandle * _n ) const float note_freq = getChannelTrack()->frequency( _n ) / ( mixer::inst()->sampleRate() / DEFAULT_SAMPLE_RATE ); - if( m_sampleBuffer.play( buf, _n->totalFramesPlayed(), frames, note_freq, m_loopButton->isChecked(), @@ -586,8 +585,16 @@ void audioFileProcessor::endKnobChanged( float _new_value ) { if( _new_value > m_startKnob->value() ) { - m_sampleBuffer.setEndFrame( static_cast( _new_value * + if( _new_value * m_sampleBuffer.frames() >= 1.0f ) + { + m_sampleBuffer.setEndFrame( static_cast( + _new_value * m_sampleBuffer.frames() ) - 1 ); + } + else + { + m_sampleBuffer.setEndFrame( 0 ); + } } else { diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index a48084d1a2..99c5a01b1d 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -58,7 +58,7 @@ #include "tooltip.h" #include "spc_bg_hndl_widget.h" #include "vestige.h" - +#include "text_float.h" #include "embed.cpp" @@ -190,9 +190,15 @@ void vestigeInstrument::setParameter( const QString & _param, closePlugin(); m_pluginDLL = _value; + textFloat * tf = textFloat::displayMessage( + tr( "Loading plugin" ), + tr( "Please wait while loading VST-plugin..." ), + PLUGIN_NAME::getIconPixmap( "logo", 24, 24 ), + 0 ); m_plugin = new remoteVSTPlugin( m_pluginDLL ); if( m_plugin->failed() ) { + delete tf; QMessageBox::information( this, tr( "Failed loading VST-plugin" ), tr( "The VST-plugin %1 could not " @@ -219,6 +225,7 @@ void vestigeInstrument::setParameter( const QString & _param, }*/ m_plugin->showEditor(); update(); + delete tf; } } diff --git a/src/core/file_browser.cpp b/src/core/file_browser.cpp index 80baea5547..0eecdc7885 100644 --- a/src/core/file_browser.cpp +++ b/src/core/file_browser.cpp @@ -51,6 +51,7 @@ #include "debug.h" #include "gui_templates.h" #include "instrument.h" +#include "text_float.h" @@ -211,10 +212,22 @@ void fileBrowser::itemPressed( int _btn, QListViewItem * i, const QPoint &, int } if( f->type() == fileItem::SAMPLE_FILE ) { + textFloat * tf = textFloat::displayMessage( + tr( "Loading sample" ), + tr( "Please wait, loading sample for " + "preview..." ), + embed::getIconPixmap( "sound_file", + 24, 24 ), 0 ); +#ifdef QT4 + qApp->processEvents( QEventLoop::AllEvents ); +#else + qApp->processEvents(); +#endif samplePlayHandle * s = new samplePlayHandle( f->fullName() ); s->setDoneMayReturnTrue( FALSE ); m_previewPlayHandle = s; + delete tf; } else if( f->type() == fileItem::PRESET_FILE ) { diff --git a/src/core/song_editor.cpp b/src/core/song_editor.cpp index ea375509af..dacfb1d1ff 100644 --- a/src/core/song_editor.cpp +++ b/src/core/song_editor.cpp @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -88,6 +87,7 @@ #include "tooltip.h" #include "tool_button.h" #include "cpuload_widget.h" +#include "text_float.h" #include "debug.h" @@ -202,11 +202,11 @@ songEditor::songEditor() : #ifdef QT4 m_masterVolumeSlider = new QSlider( Qt::Vertical, tb ); m_masterVolumeSlider->setRange( 0, 200 ); - m_masterVolumeSlider->setPageStep( 10 ); + m_masterVolumeSlider->setPageStep( 1 ); m_masterVolumeSlider->setValue( 100 ); m_masterVolumeSlider->setTickPosition( QSlider::TicksLeft ); #else - m_masterVolumeSlider = new QSlider( 0, 200, 10, 100, Qt::Vertical, tb ); + m_masterVolumeSlider = new QSlider( 0, 200, 1, 100, Qt::Vertical, tb ); m_masterVolumeSlider->setTickPosition( QSlider::Left ); #endif m_masterVolumeSlider->setFixedSize( 26, 60 ); @@ -222,6 +222,8 @@ songEditor::songEditor() : connect( m_masterVolumeSlider, SIGNAL( sliderReleased() ), this, SLOT( masterVolumeReleased() ) ); + m_mvsStatus = new textFloat( m_masterVolumeSlider ); + lmmsMainWin::inst()->addWidgetToToolBar( master_vol_lbl ); lmmsMainWin::inst()->addWidgetToToolBar( m_masterVolumeSlider ); @@ -253,6 +255,8 @@ songEditor::songEditor() : connect( m_masterPitchSlider, SIGNAL( sliderReleased() ), this, SLOT( masterPitchReleased() ) ); + m_mpsStatus = new textFloat( m_masterPitchSlider ); + lmmsMainWin::inst()->addWidgetToToolBar( master_pitch_lbl ); lmmsMainWin::inst()->addWidgetToToolBar( m_masterPitchSlider ); @@ -619,6 +623,12 @@ void songEditor::wheelEvent( QWheelEvent * _we ) void songEditor::masterVolumeChanged( int _new_val ) { + if( m_mvsStatus->isShown() == FALSE ) + { + masterVolumeMoved( _new_val ); + m_mvsStatus->reparent( m_masterVolumeSlider ); + m_mvsStatus->setVisibilityTimeOut( 1000 ); + } mixer::inst()->setMasterGain( 2.0f - _new_val / 100.0f ); setModified(); } @@ -628,6 +638,8 @@ void songEditor::masterVolumeChanged( int _new_val ) void songEditor::masterVolumePressed( void ) { + m_mvsStatus->reparent( m_masterVolumeSlider ); + m_mvsStatus->show(); masterVolumeMoved( m_masterVolumeSlider->value() ); } @@ -636,9 +648,8 @@ void songEditor::masterVolumePressed( void ) void songEditor::masterVolumeMoved( int _new_val ) { - lmmsMainWin::inst()->statusBar()->showMessage( tr( - "Master output volume:" ) + - " " + QString::number( 200 - _new_val ) + "%" ); + m_mvsStatus->setText( tr( "Master output volume: %1%" ).arg( 200 - + _new_val ) ); } @@ -646,7 +657,7 @@ void songEditor::masterVolumeMoved( int _new_val ) void songEditor::masterVolumeReleased( void ) { - lmmsMainWin::inst()->statusBar()->clearMessage(); + m_mvsStatus->hide(); } @@ -654,6 +665,12 @@ void songEditor::masterVolumeReleased( void ) void songEditor::masterPitchChanged( int _new_val ) { + if( m_mpsStatus->isShown() == FALSE ) + { + masterPitchMoved( _new_val ); + m_mpsStatus->reparent( m_masterPitchSlider ); + m_mpsStatus->setVisibilityTimeOut( 1000 ); + } setModified(); } @@ -662,6 +679,8 @@ void songEditor::masterPitchChanged( int _new_val ) void songEditor::masterPitchPressed( void ) { + m_mpsStatus->reparent( m_masterPitchSlider ); + m_mpsStatus->show(); masterPitchMoved( m_masterPitchSlider->value() ); } @@ -670,9 +689,8 @@ void songEditor::masterPitchPressed( void ) void songEditor::masterPitchMoved( int _new_val ) { - lmmsMainWin::inst()->statusBar()->showMessage( tr( - "Master output pitch:" ) + - " " + QString::number( -_new_val ) + " " + tr( "semitones" ) ); + m_mpsStatus->setText( tr( "Master pitch: %1 semitones").arg( + -_new_val ) ); } @@ -681,7 +699,7 @@ void songEditor::masterPitchMoved( int _new_val ) void songEditor::masterPitchReleased( void ) { - lmmsMainWin::inst()->statusBar()->clearMessage(); + m_mpsStatus->hide(); } @@ -1501,15 +1519,19 @@ bool songEditor::saveProject( void ) { m_modified = FALSE; - lmmsMainWin::inst()->statusBar()->showMessage( - tr( "%1 saved." ).arg( m_fileName ), - 3000 ); + textFloat::displayMessage( tr( "Project saved" ), + tr( "The project %1 is now saved." + ).arg( m_fileName ), + embed::getIconPixmap( "project_save", 24, 24 ), + 2000 ); lmmsMainWin::inst()->resetWindowTitle( "" ); } else { - lmmsMainWin::inst()->statusBar()->showMessage( - tr( "Project NOT saved." ), 3000 ); + textFloat::displayMessage( tr( "Project NOT saved." ), + tr( "The project %1 could not be saved!" ).arg( + m_fileName ), + embed::getIconPixmap( "error" ), 4000 ); return( FALSE ); } return( TRUE ); @@ -1536,25 +1558,24 @@ bool FASTCALL songEditor::saveProjectAs( const QString & _file_name ) + void songEditor::importProject( void ) { #ifdef QT4 - QFileDialog ofd( this, tr( "Import file" ), "", + QFileDialog ofd( this, tr( "Import file" ), "", tr( "MIDI-files (*.mid)" ) ); #else - QFileDialog ofd( QString::null, - tr( "MIDI-files (*.mid)" ), + QFileDialog ofd( QString::null, tr( "MIDI-files (*.mid)" ), this, "", TRUE ); - ofd.setWindowTitle( tr( "Import file" ) ); + ofd.setWindowTitle( tr( "Import file" ) ); #endif - ofd.setDirectory( configManager::inst()->projectsDir() ); - ofd.setFileMode( QFileDialog::ExistingFiles ); - if( ofd.exec () == QDialog::Accepted && - !ofd.selectedFiles().isEmpty() ) - { - midiFile mf( ofd.selectedFiles()[0] ); - mf.importToTrackContainer( this ); - } + ofd.setDirectory( configManager::inst()->projectsDir() ); + ofd.setFileMode( QFileDialog::ExistingFiles ); + if( ofd.exec () == QDialog::Accepted && !ofd.selectedFiles().isEmpty() ) + { + midiFile mf( ofd.selectedFiles()[0] ); + mf.importToTrackContainer( this ); + } } @@ -1636,9 +1657,6 @@ void songEditor::exportProject( void ) - - - void songEditor::saveSettings( QDomDocument & _doc, QDomElement & _parent ) { trackContainer::saveSettings( _doc, _parent ); diff --git a/src/lib/mmp.cpp b/src/lib/mmp.cpp index 2f81bba990..725f0c8f11 100644 --- a/src/lib/mmp.cpp +++ b/src/lib/mmp.cpp @@ -227,7 +227,7 @@ bool multimediaProject::writeFile( const QString & _fn, bool _overwrite_check ) songEditor::tr( "Could not write file " "%1. You probably are " "not permitted to " - "write to this file. " + "write to this file.\n" "Please make sure you " "have write-access to " "the file and try " diff --git a/src/lib/sample_buffer.cpp b/src/lib/sample_buffer.cpp index f982bad509..67df4a7a47 100644 --- a/src/lib/sample_buffer.cpp +++ b/src/lib/sample_buffer.cpp @@ -171,7 +171,14 @@ void sampleBuffer::update( bool _keep_settings ) { m_frames = m_origFrames; m_startFrame = 0; - m_endFrame = m_frames-1; + if( m_frames > 0 ) + { + m_endFrame = m_frames - 1; + } + else + { + m_endFrame = 0; + } } } else if( m_audioFile != "" ) @@ -217,7 +224,14 @@ void sampleBuffer::update( bool _keep_settings ) { // update frame-variables m_startFrame = 0; - m_endFrame = m_frames - 1; + if( m_frames > 0 ) + { + m_endFrame = m_frames - 1; + } + else + { + m_endFrame = 0; + } } // following code transforms int-samples into @@ -262,23 +276,19 @@ m_data[frame][chnl] = buf[idx] * fac; else { m_data = new sampleFrame[1]; - memset( m_data, 0, sizeof( *m_data ) * 1 ); -/* for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl ) - { - m_data[0][chnl] = 0.0f; - }*/ + memset( m_data, 0, sizeof( *m_data ) ); m_frames = 1; + m_startFrame = 0; + m_endFrame = 1; } } else { m_data = new sampleFrame[1]; memset( m_data, 0, sizeof( *m_data ) * 1 ); -/* for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl ) - { - m_data[0][chnl] = 0.0f; - }*/ m_frames = 1; + m_startFrame = 0; + m_endFrame = 1; } m_dataMutex.unlock(); @@ -582,13 +592,6 @@ bool FASTCALL sampleBuffer::play( sampleFrame * _ab, Uint32 _start_frame, { return( FALSE ); } - // this holds the number of the first frame to play - const Uint32 play_frame = m_startFrame + ( _start_frame % - total_frames_for_current_pitch ); - - // this holds the number of remaining frames in current loop - Uint32 frames_for_loop = total_frames_for_current_pitch - - ( play_frame - m_startFrame ); // do we have frames left?? this is only important when not in // looping-mode because in looping-mode we loop to start-frame... @@ -597,6 +600,14 @@ bool FASTCALL sampleBuffer::play( sampleFrame * _ab, Uint32 _start_frame, return( FALSE ); } + // this holds the number of the first frame to play + const Uint32 play_frame = m_startFrame + ( _start_frame % + total_frames_for_current_pitch ); + + // this holds the number of remaining frames in current loop + Uint32 frames_for_loop = total_frames_for_current_pitch - + ( play_frame - m_startFrame ); + // make sure, data isn't accessed in any other way (e.g. deleting // of this buffer...) m_dataMutex.lock(); diff --git a/src/widgets/cpuload_widget.cpp b/src/widgets/cpuload_widget.cpp index 3a553b4f55..d1df6989fc 100644 --- a/src/widgets/cpuload_widget.cpp +++ b/src/widgets/cpuload_widget.cpp @@ -57,7 +57,7 @@ cpuloadWidget::cpuloadWidget( QWidget * _parent ) : connect( &m_updateTimer, SIGNAL( timeout() ), this, SLOT( updateCpuLoad() ) ); - m_updateTimer.start( 100 ); // update player control at 10 fps + m_updateTimer.start( 100 ); // update cpu-load at 10 fps #ifndef QT4 setBackgroundMode( NoBackground ); @@ -76,32 +76,19 @@ cpuloadWidget::~cpuloadWidget() void cpuloadWidget::paintEvent( QPaintEvent * ) { -/* if( m_changed == TRUE ) - { - m_changed = FALSE; - - // background - bitBlt( &m_temp, 0, 0, &m_background, 0, 0, width(), height(), - CopyROP ); - - // leds - bitBlt( &m_temp, 23, 3, &m_leds, 0, 0, - ( m_leds.width() * m_currentLoad / 300 ) * 3, - m_leds.height(), CopyROP ); - } - bitBlt( this, 0, 0, &m_temp, 0, 0, width(), height(), CopyROP );*/ if( m_changed == TRUE ) { m_changed = FALSE; QPainter p( &m_temp ); - // background p.drawPixmap( 0, 0, m_background ); + // as load-indicator consists of small 2-pixel wide leds with + // 1 pixel spacing, we have to make sure, only whole leds are + // shown which we achieve by the following formula int w = ( m_leds.width() * m_currentLoad / 300 ) * 3; if( w > 0 ) { - // leds p.drawPixmap( 23, 3, m_leds, 0, 0, w, m_leds.height() ); } @@ -116,9 +103,13 @@ void cpuloadWidget::paintEvent( QPaintEvent * ) void cpuloadWidget::updateCpuLoad() { // smooth load-values a bit - m_currentLoad = ( m_currentLoad + mixer::inst()->cpuLoad() ) / 2; - m_changed = TRUE; - update(); + Uint8 new_load = ( m_currentLoad + mixer::inst()->cpuLoad() ) / 2; + if( new_load != m_currentLoad ) + { + m_currentLoad = new_load; + m_changed = TRUE; + update(); + } } diff --git a/src/widgets/nstate_button.cpp b/src/widgets/nstate_button.cpp index 371c04a58e..0a25c6c68d 100644 --- a/src/widgets/nstate_button.cpp +++ b/src/widgets/nstate_button.cpp @@ -52,7 +52,6 @@ nStateButton::~nStateButton() { while( m_states.size() ) { - delete m_states.front().first; m_states.erase( m_states.begin() ); } } @@ -62,7 +61,7 @@ nStateButton::~nStateButton() void nStateButton::addState( const QPixmap & _pm, const QString & _tooltip ) { - m_states.push_back( qMakePair( new QPixmap( _pm ), _tooltip ) ); + m_states.push_back( qMakePair( _pm, _tooltip ) ); // first inserted pixmap? if( m_states.size() == 1 ) { @@ -88,11 +87,9 @@ void nStateButton::changeState( int _n ) m_generalToolTip; toolTip::add( this, _tooltip ); - setIcon( *m_states[m_curState].first ); + setIcon( m_states[m_curState].first ); emit changedState( m_curState ); - -/* update();*/ } } diff --git a/src/widgets/text_float.cpp b/src/widgets/text_float.cpp index eec6ed4dfd..a027bcc740 100644 --- a/src/widgets/text_float.cpp +++ b/src/widgets/text_float.cpp @@ -52,7 +52,9 @@ textFloat::textFloat( QWidget * _parent ) : , "textFloat", WStyle_Customize | WStyle_NoBorder | WStyle_StaysOnTop #endif ), - m_text( "" ) + m_title( "" ), + m_text( "" ), + m_pixmap() { #ifndef QT4 setBackgroundMode( Qt::NoBackground ); @@ -66,8 +68,39 @@ textFloat::textFloat( QWidget * _parent ) : +void textFloat::setTitle( const QString & _title ) +{ + m_title = _title; + repaint(); +} + + + + +void textFloat::setText( const QString & _text ) +{ + m_text = _text; + repaint(); +} + + + + +void textFloat::setPixmap( const QPixmap & _pixmap ) +{ + m_pixmap = _pixmap; + repaint(); +} + + + + void textFloat::reparent( QWidget * _new_parent ) { + if( _new_parent == NULL ) + { + return; + } QPoint position = _new_parent->pos(); // Get position and reparent to either top level or dialog @@ -112,6 +145,56 @@ void textFloat::setVisibilityTimeOut( int _msecs ) +textFloat * textFloat::displayMessage( const QString & _msg, int _timeout, + QWidget * _parent, int _add_y_margin ) +{ +#ifdef QT4 + QWidget * mw = QApplication::activeWindow(); +#else + QWidget * mw = qApp->mainWidget(); +#endif + textFloat * tf = new textFloat( ( _parent == NULL ) ? mw : _parent ); + if( _parent != NULL ) + { + tf->move( _parent->mapTo( _parent->topLevelWidget(), + QPoint( 0, 0 ) ) + + QPoint( _parent->width() + 2, 0 ) ); + } + else + { + tf->move( 32, mw->height() - 24 - _add_y_margin ); + } + tf->setText( _msg ); + tf->show(); + if( _timeout > 0 ) + { +#ifdef QT4 + tf->setAttribute( Qt::WA_DeleteOnClose, TRUE ); +#else + tf->setWFlags( tf->getWFlags() | Qt::WDestructiveClose ); +#endif + QTimer::singleShot( _timeout, tf, SLOT( close() ) ); + } + return( tf ); +} + + + + +textFloat * textFloat::displayMessage( const QString & _title, + const QString & _msg, + const QPixmap & _pixmap, + int _timeout, QWidget * _parent ) +{ + textFloat * tf = displayMessage( _msg, _timeout, _parent, 16 ); + tf->setTitle( _title ); + tf->setPixmap( _pixmap ); + return( tf ); +} + + + + void textFloat::paintEvent( QPaintEvent * _pe ) { #ifdef QT4 @@ -121,18 +204,50 @@ void textFloat::paintEvent( QPaintEvent * _pe ) QPainter p( &draw_pm ); #endif p.setPen( QColor( 0, 0, 0 ) ); - p.setBrush( QColor( 255, 255, 255 ) ); + p.setBrush( QColor( 224, 224, 224 ) ); p.setFont( pointSize<8>( p.font() ) ); QFontMetrics metrics( p.fontMetrics() ); QRect textBound = metrics.boundingRect( m_text ); - + if( m_title != "" ) + { + QFont f = p.font(); + f.setBold( TRUE ); + int title_w = QFontMetrics( f ).boundingRect( m_title ).width(); + if( title_w > textBound.width() ) + { + textBound.setWidth( textBound.width() + title_w ); + } + textBound.setHeight( textBound.height() * 2 + 10 ); + } + if( m_pixmap.isNull() == FALSE ) + { + textBound.setWidth( textBound.width() + m_pixmap.width() + 10 ); + } resize( textBound.width() + 5, textBound.height() + 5 ); p.drawRect( rect() ); p.setPen( Qt::black ); - p.drawText( 2, 10, m_text ); + // small message? + if( m_title == "" ) + { + p.drawText( 2, 10, m_text ); + } + else + { + int text_x = 2; + if( m_pixmap.isNull() == FALSE ) + { + p.drawPixmap( 5, 5, m_pixmap ); + text_x += m_pixmap.width() + 8; + } + p.drawText( text_x, 28, m_text ); + QFont f = p.font(); + f.setBold( TRUE ); + p.setFont( f ); + p.drawText( text_x, 12, m_title ); + } #ifndef QT4 bitBlt( this, rect().topLeft(), &draw_pm ); @@ -142,10 +257,9 @@ void textFloat::paintEvent( QPaintEvent * _pe ) -void textFloat::setText( const QString & _text ) +void textFloat::mousePressEvent( QMouseEvent * ) { - m_text = _text; - repaint(); + close(); }