diff --git a/src/app/mainWindow.cpp b/src/app/mainWindow.cpp index 79cd025..4c556b9 100644 --- a/src/app/mainWindow.cpp +++ b/src/app/mainWindow.cpp @@ -20,6 +20,7 @@ #include #include #include //::stateChanged() +#include #include //ctor #include //because XMLGUI is poorly designed #include @@ -56,6 +57,102 @@ constexpr auto kSubtitleSelectActionName = "subtitle_channels_select"; namespace Codeine { + class MediaInfoDialog : public KDialogBase + { + TQLabel* m_videoWidth; + TQLabel* m_videoHeight; + TQLabel* m_videoBitRate; + TQLabel* m_audioBits; + TQLabel* m_audioSampleRate; + TQLabel* m_audioBitRate; + + public: + MediaInfoDialog(TQWidget *parent, const TQMap& meta) + : KDialogBase(parent, "meta_data_dialog", true, i18n("Media Information"), Close) + { + TQFrame *widget = makeMainWidget(); + widget->setMinimumWidth(250); + auto layout = new TQVBoxLayout(widget, 0, 4); + auto group = new TQGroupBox(2, Horizontal, i18n("General"), widget); + layout->addWidget(group); + + auto label = new TQLabel(i18n("Title") + ":", group); + auto value = new TQLabel(meta[MetaData::Title], group); + label->setBuddy(value); + + label = new TQLabel(i18n("Artist") + ":", group); + value = new TQLabel(meta[MetaData::Artist], group); + label->setBuddy(value); + + label = new TQLabel(i18n("Album") + ":", group); + value = new TQLabel(meta[MetaData::Album], group); + label->setBuddy(value); + + label = new TQLabel(i18n("Genre") + ":", group); + value = new TQLabel(meta[MetaData::Genre], group); + label->setBuddy(value); + + label = new TQLabel(i18n("Year") + ":", group); + value = new TQLabel(meta[MetaData::Year], group); + label->setBuddy(value); + + label = new TQLabel(i18n("Comment") + ":", group); + value = new TQLabel(meta[MetaData::Comment], group); + label->setBuddy(value); + + group = new TQGroupBox(2, Horizontal, i18n("Video"), widget); + layout->addWidget(group); + + label = new TQLabel(i18n("Bitrate") + ":", group); + m_videoBitRate = new TQLabel(group); + label->setBuddy(m_videoBitRate); + + label = new TQLabel(i18n("Codec") + ":", group); + value = new TQLabel(meta[MetaData::VideoCodec], group); + label->setBuddy(value); + + label = new TQLabel(i18n("Height") + ":", group); + m_videoHeight = new TQLabel(group); + label->setBuddy(m_videoHeight); + + label = new TQLabel(i18n("Width") + ":", group); + m_videoWidth = new TQLabel(group); + label->setBuddy(m_videoWidth); + + group = new TQGroupBox(2, Horizontal, i18n("Audio"), widget); + layout->addWidget(group); + + label = new TQLabel(i18n("Bitrate") + ":", group); + m_audioBitRate = new TQLabel(group); + label->setBuddy(m_audioBitRate); + + label = new TQLabel(i18n("Codec") + ":", group); + value = new TQLabel(meta[MetaData::AudioCodec], group); + label->setBuddy(value); + + label = new TQLabel(i18n("Bit Depth") + ":", group); + m_audioBits = new TQLabel(group); + label->setBuddy(m_audioBits); + + label = new TQLabel(i18n("Sample Rate") + ":", group); + m_audioSampleRate = new TQLabel(group); + label->setBuddy(m_audioSampleRate); + + resize(sizeHint()); + disableResize(); + } + + void setStreamInfo(const TQMap& info) + { + m_videoWidth->setText(info[StreamInfo::VideoWidth] + " px"); + m_videoHeight->setText(info[StreamInfo::VideoHeight] + " px"); + m_videoBitRate->setText(info[StreamInfo::VideoBitRate] + " bps"); + m_audioBits->setText(info[StreamInfo::AudioBits] + "-bit"); + m_audioSampleRate->setText(info[StreamInfo::AudioSampleRate] + " Hz"); + m_audioBitRate->setText(info[StreamInfo::AudioBitRate] + " bps"); + } + }; + /// @see codeine.h TQWidget *mainWindow() { return tdeApp->mainWidget(); } @@ -66,6 +163,7 @@ MainWindow::MainWindow() , m_positionSlider( new Slider( this, 65535 ) ) , m_timeLabel( new TQLabel( " 0:00:00 ", this ) ) , m_titleLabel( new KSqueezedTextLabel( this ) ) + , m_mediaInfoDialog(nullptr) { DEBUG_BLOCK @@ -647,7 +745,13 @@ MainWindow::configure() void MainWindow::streamInformation() { - MessageBox::information( TheStream::information(), i18n("Media Information") ); + if (!m_mediaInfoDialog) + { + TQMap metaData = TheStream::metaData(); + m_mediaInfoDialog = new MediaInfoDialog(this, metaData); + } + m_mediaInfoDialog->setStreamInfo(TheStream::info()); + m_mediaInfoDialog->show(); } void diff --git a/src/app/mainWindow.h b/src/app/mainWindow.h index fbb6be4..3db1f09 100644 --- a/src/app/mainWindow.h +++ b/src/app/mainWindow.h @@ -18,6 +18,7 @@ class VolumeAction; namespace Codeine { class AudioView; + class MediaInfoDialog; class MainWindow : public TDEMainWindow { @@ -72,6 +73,7 @@ namespace Codeine TQLabel *m_titleLabel; TQWidget *m_analyzer; AudioView *m_audioView; + MediaInfoDialog *m_mediaInfoDialog; TQWidgetStack *m_widgetStack; VolumeAction *m_volumeAction; diff --git a/src/app/stateChange.cpp b/src/app/stateChange.cpp index 2418209..1e79bdb 100644 --- a/src/app/stateChange.cpp +++ b/src/app/stateChange.cpp @@ -102,7 +102,6 @@ MainWindow::engineStateChanged( Engine::State state ) } } - /// update statusBar { using namespace Engine; @@ -120,6 +119,16 @@ MainWindow::engineStateChanged( Engine::State state ) m_widgetStack->raiseWidget(m_audioView); } + // Update MediaInfoDialog + if (state == Engine::Empty || state == Engine::TrackEnded || state == Engine::Loaded) + { + if (m_mediaInfoDialog) + { + reinterpret_cast(m_mediaInfoDialog)->deleteLater(); + m_mediaInfoDialog = nullptr; + } + } + /// update position slider switch( state ) diff --git a/src/app/theStream.cpp b/src/app/theStream.cpp index 3f7e35a..09005f9 100644 --- a/src/app/theStream.cpp +++ b/src/app/theStream.cpp @@ -76,69 +76,42 @@ namespace Codeine return url.prettyURL(); } - - static inline TQString - entryHelper( const TQString &plate, const TQString &s1, const TQString &s2 ) + TQMap TheStream::metaData() { - return s2.isEmpty() ? s2 : plate.arg( s1 ).arg( s2 ); - } +#define xmeta(x) xine_get_meta_info(e->m_stream, (x)) - static inline TQString - sectionHelper( const TQString §ionTitle, const TQStringList &entries ) - { - TQString s; + TQMap data; - foreach( entries ) - if( !(*it).isEmpty() ) - s += *it; + data[MetaData::Title] = xmeta(XINE_META_INFO_TITLE); + data[MetaData::Comment] = xmeta(XINE_META_INFO_COMMENT); + data[MetaData::Artist] = xmeta(XINE_META_INFO_ARTIST); + data[MetaData::Genre] = xmeta(XINE_META_INFO_GENRE); + data[MetaData::Album] = xmeta(XINE_META_INFO_ALBUM); + data[MetaData::Year] = xmeta(XINE_META_INFO_YEAR); + data[MetaData::VideoCodec] = xmeta(XINE_META_INFO_VIDEOCODEC); + data[MetaData::AudioCodec] = xmeta(XINE_META_INFO_AUDIOCODEC); - return s.isEmpty() ? s : "

" + sectionTitle + "

" + s; + return data; + +#undef xmeta } - TQString - TheStream::information() + TQMap TheStream::info() { - #define meta( x ) xine_get_meta_info( e->m_stream, x ) - #define info( x, y ) x.arg( xine_get_stream_info( e->m_stream, y ) ) - #define simple( x ) TQString::number( xine_get_stream_info( e->m_stream, x ) ) - - const TQString plate = "

%1: %2

"; - TQString s; - - s += sectionHelper( i18n("Metadata"), - TQStringList() - << entryHelper( plate, i18n("Title"), meta( XINE_META_INFO_TITLE ) ) - << entryHelper( plate, i18n("Comment"), meta( XINE_META_INFO_COMMENT ) ) - << entryHelper( plate, i18n("Artist"), meta( XINE_META_INFO_ARTIST ) ) - << entryHelper( plate, i18n("Genre"), meta( XINE_META_INFO_GENRE ) ) - << entryHelper( plate, i18n("Album"), meta( XINE_META_INFO_ALBUM ) ) - << entryHelper( plate, i18n("Year"), meta( XINE_META_INFO_YEAR ) ) ); - - s += sectionHelper( i18n("Audio Properties"), - TQStringList() - << entryHelper( plate, i18n("Bitrate"), info( i18n("%1 bps"), XINE_STREAM_INFO_AUDIO_BITRATE ) ) - << entryHelper( plate, i18n("Sample-rate"), info( i18n("%1 Hz"), XINE_STREAM_INFO_AUDIO_SAMPLERATE ) ) ); - - s += sectionHelper( i18n("Technical Information"), - TQStringList() - << entryHelper( plate, i18n("Video Codec"), meta( XINE_META_INFO_VIDEOCODEC ) ) - << entryHelper( plate, i18n("Audio Codec"), meta( XINE_META_INFO_AUDIOCODEC ) ) - << entryHelper( plate, i18n("System Layer"), meta( XINE_META_INFO_SYSTEMLAYER ) ) - << entryHelper( plate, i18n("Input Plugin"), meta( XINE_META_INFO_INPUT_PLUGIN )) - << entryHelper( plate, i18n("CDINDEX_DISCID"), meta( XINE_META_INFO_CDINDEX_DISCID ) ) ); - - TQStringList texts; - texts << "BITRATE" << "SEEKABLE" << "VIDEO_WIDTH" << "VIDEO_HEIGHT" << "VIDEO_RATIO" << "VIDEO_CHANNELS" << "VIDEO_STREAMS" << "VIDEO_BITRATE" << "VIDEO_FOURCC" << "VIDEO_HANDLED" << "FRAME_DURATION" << "AUDIO_CHANNELS" << "AUDIO_BITS" << "-AUDIO_SAMPLERATE" << "-AUDIO_BITRATE" << "AUDIO_FOURCC" << "AUDIO_HANDLED" << "HAS_CHAPTERS" << "HAS_VIDEO" << "HAS_AUDIO" << "-IGNORE_VIDEO" << "-IGNORE_AUDIO" << "-IGNORE_SPU" << "VIDEO_HAS_STILL" << "MAX_AUDIO_CHANNEL" << "MAX_SPU_CHANNEL" << "AUDIO_MODE" << "SKIPPED_FRAMES" << "DISCARDED_FRAMES"; - - s += "

Other

"; - for( uint x = 0; x <= 28; ++x ) - s += entryHelper( plate, texts[x], simple( x ) ); - - #undef meta - #undef info - #undef simple - - return s; +#define xinfo(x) TQString::number(xine_get_stream_info(e->m_stream, (x))) + + TQMap data; + + data[StreamInfo::VideoWidth] = xinfo(XINE_STREAM_INFO_VIDEO_WIDTH); + data[StreamInfo::VideoHeight] = xinfo(XINE_STREAM_INFO_VIDEO_HEIGHT); + data[StreamInfo::VideoBitRate] = xinfo(XINE_STREAM_INFO_VIDEO_BITRATE); + data[StreamInfo::AudioBits] = xinfo(XINE_STREAM_INFO_AUDIO_BITS); + data[StreamInfo::AudioSampleRate] = xinfo(XINE_STREAM_INFO_AUDIO_SAMPLERATE); + data[StreamInfo::AudioBitRate] = xinfo(XINE_STREAM_INFO_AUDIO_BITRATE); + + return data; + +#undef xinfo } #undef e diff --git a/src/app/theStream.h b/src/app/theStream.h index 7679a10..f616862 100644 --- a/src/app/theStream.h +++ b/src/app/theStream.h @@ -20,11 +20,37 @@ namespace Codeine { + enum class MetaData + { + Title = 0, + Comment, + Artist, + Genre, + Album, + Year, + VideoCodec, + AudioCodec, + }; + + enum class StreamInfo + { + VideoWidth = 0, + VideoHeight, + VideoBitRate, + AudioBits, + AudioSampleRate, + AudioBitRate + }; + class TheStream { CODEINE_NO_EXPORT( TheStream ) public: + + static TQMap metaData(); + static TQMap info(); + static const KURL &url(); static bool canSeek(); @@ -38,7 +64,6 @@ namespace Codeine static int audioChannel(); static TQString prettyTitle(); - static TQString information(); static inline bool hasProfile() { return TDEGlobal::config()->hasGroup( url().prettyURL() ); }