diff --git a/src/qml/MediaTrackMetadataView.qml b/src/qml/MediaTrackMetadataView.qml index 2cc5dad3..23e7524a 100644 --- a/src/qml/MediaTrackMetadataView.qml +++ b/src/qml/MediaTrackMetadataView.qml @@ -1,256 +1,272 @@ /* * Copyright 2017 Alexander Stippich * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Window 2.2 import QtQml.Models 2.2 import QtQuick.Layouts 1.2 import QtGraphicalEffects 1.0 Window { id: trackMetadata property var trackDataHelper property real labelWidth: trackData.width * 0.33 property real metadataWidth: trackData.width * 0.66 signal rejected() LayoutMirroring.enabled: Qt.application.layoutDirection == Qt.RightToLeft LayoutMirroring.childrenInherit: true title: i18nc("Window title for track metadata", "View Details") function updateData() { trackList.clear() - if (trackDataHelper.hasValidTitle) - trackList.append({"name": i18nc("Track title for track metadata view", "Title:"), "content": trackDataHelper.title}) - if (trackDataHelper.hasValidArtist) - trackList.append({"name": i18nc("Track artist for track metadata view", "Artist:"), "content": trackDataHelper.artist}) - if (trackDataHelper.hasValidAlbumName) - trackList.append({"name": i18nc("Album name for track metadata view", "Album:"), "content": trackDataHelper.albumName}) - if (trackDataHelper.hasValidTrackNumber) - trackList.append({"name": i18nc("Track number for track metadata view", "Track Number:"), "content": trackDataHelper.trackNumber.toString()}) - if (trackDataHelper.hasValidDiscNumber) - trackList.append({"name": i18nc("Disc number for track metadata view", "Disc Number:"), "content": trackDataHelper.discNumber.toString()}) - if (trackDataHelper.hasValidAlbumArtist) - trackList.append({"name": i18nc("Album artist for track metadata view", "Album Artist:"), "content": trackDataHelper.albumArtist}) - trackList.append({"name": i18nc("Duration label for track metadata view", "Duration:"), "content": trackDataHelper.duration}) - if (trackDataHelper.hasValidYear) - trackList.append({"name": i18nc("Year label for track metadata view", "Year:"), "content": trackDataHelper.year.toString()}) - if (trackDataHelper.hasValidGenre) - trackList.append({"name": i18nc("Genre label for track metadata view", "Genre:"), "content": trackDataHelper.genre}) - if (trackDataHelper.hasValidComposer) - trackList.append({"name": i18nc("Composer name for track metadata view", "Composer:"), "content": trackDataHelper.composer}) - if (trackDataHelper.hasValidLyricist) - trackList.append({"name": i18nc("Lyricist label for track metadata view", "Lyricist:"), "content": trackDataHelper.lyricist}) - if (trackDataHelper.hasValidBitRate) - trackList.append({"name": i18nc("Bit rate label for track metadata view", "Bit Rate:"), "content": (trackDataHelper.bitRate / 1000) + " " + i18nc("Unit of the bit rate in thousand", "kbit/s")}) - if (trackDataHelper.hasValidSampleRate) - trackList.append({"name": i18nc("Sample Rate label for track metadata view", "Sample Rate:"), "content": trackDataHelper.sampleRate + " " + i18nc("Unit of the sample rate", "Hz")}) - if (trackDataHelper.hasValidChannels) - trackList.append({"name": i18nc("Channels label for track metadata view", "Channels:"), "content": trackDataHelper.channels.toString()}) - if (trackDataHelper.hasValidComment) - trackList.append({"name": i18nc("Comment label for track metadata view", "Comment:"), "content": trackDataHelper.comment}) + if (trackDataHelper.isValid) { + if (trackDataHelper.hasValidTitle) + trackList.append({"name": i18nc("Track title for track metadata view", "Title:"), "content": trackDataHelper.title}) + if (trackDataHelper.hasValidArtist) + trackList.append({"name": i18nc("Track artist for track metadata view", "Artist:"), "content": trackDataHelper.artist}) + if (trackDataHelper.hasValidAlbumName) + trackList.append({"name": i18nc("Album name for track metadata view", "Album:"), "content": trackDataHelper.albumName}) + if (trackDataHelper.hasValidTrackNumber) + trackList.append({"name": i18nc("Track number for track metadata view", "Track Number:"), "content": trackDataHelper.trackNumber.toString()}) + if (trackDataHelper.hasValidDiscNumber) + trackList.append({"name": i18nc("Disc number for track metadata view", "Disc Number:"), "content": trackDataHelper.discNumber.toString()}) + if (trackDataHelper.hasValidAlbumArtist) + trackList.append({"name": i18nc("Album artist for track metadata view", "Album Artist:"), "content": trackDataHelper.albumArtist}) + if (trackDataHelper.hasValidDuration) + trackList.append({"name": i18nc("Duration label for track metadata view", "Duration:"), "content": trackDataHelper.duration}) + if (trackDataHelper.hasValidYear) + trackList.append({"name": i18nc("Year label for track metadata view", "Year:"), "content": trackDataHelper.year.toString()}) + if (trackDataHelper.hasValidGenre) + trackList.append({"name": i18nc("Genre label for track metadata view", "Genre:"), "content": trackDataHelper.genre}) + if (trackDataHelper.hasValidComposer) + trackList.append({"name": i18nc("Composer name for track metadata view", "Composer:"), "content": trackDataHelper.composer}) + if (trackDataHelper.hasValidLyricist) + trackList.append({"name": i18nc("Lyricist label for track metadata view", "Lyricist:"), "content": trackDataHelper.lyricist}) + if (trackDataHelper.hasValidBitRate) + trackList.append({"name": i18nc("Bit rate label for track metadata view", "Bit Rate:"), "content": (trackDataHelper.bitRate / 1000) + " " + i18nc("Unit of the bit rate in thousand", "kbit/s")}) + if (trackDataHelper.hasValidSampleRate) + trackList.append({"name": i18nc("Sample Rate label for track metadata view", "Sample Rate:"), "content": trackDataHelper.sampleRate + " " + i18nc("Unit of the sample rate", "Hz")}) + if (trackDataHelper.hasValidChannels) + trackList.append({"name": i18nc("Channels label for track metadata view", "Channels:"), "content": trackDataHelper.channels.toString()}) + if (trackDataHelper.hasValidComment) + trackList.append({"name": i18nc("Comment label for track metadata view", "Comment:"), "content": trackDataHelper.comment}) + } } function resize() { trackData.Layout.preferredHeight = textSize.height * trackData.count - trackMetadata.height = textSize.height * (trackData.count + 1 + ( trackDataHelper.hasValidRating ? 1 : 0 )) + buttons.height + elisaTheme.layoutHorizontalMargin * 3 + trackMetadata.height = textSize.height * (trackData.count + 1 + ( trackDataHelper.hasValidRating ? 1 : 0 ) + ( !trackDataHelper.isValid ? 1 : 0 ) ) + + buttons.height + elisaTheme.layoutHorizontalMargin * 3 trackMetadata.minimumHeight = trackMetadata.height trackMetadata.maximumHeight = trackMetadata.height trackMetadata.width = (trackDataHelper.hasValidAlbumCover ? elisaTheme.coverImageSize : 0) + labelWidth + metadataWidth + 2 * elisaTheme.layoutHorizontalMargin - trackMetadata.minimumWidth = trackMetadata.width + trackMetadata.minimumWidth = trackDataHelper.isValid ? trackMetadata.width : emptyMetaData.width + elisaTheme.layoutHorizontalMargin * 2 } Connections { target: trackDataHelper onTrackDataChanged: { updateData() resize() } } modality: Qt.NonModal flags: Qt.Dialog | Qt.WindowCloseButtonHint Component.onCompleted: { updateData() resize() } Rectangle { anchors.fill: parent color: myPalette.window ColumnLayout { anchors.fill: parent anchors.margins: elisaTheme.layoutHorizontalMargin spacing: 0 RowLayout { Layout.fillHeight: true Layout.fillWidth: true spacing: 0 Image { source: trackDataHelper.albumCover visible: trackDataHelper.hasValidAlbumCover width: elisaTheme.coverImageSize height: elisaTheme.coverImageSize fillMode: Image.PreserveAspectFit Layout.preferredHeight: height Layout.preferredWidth: width Layout.minimumHeight: height Layout.minimumWidth: width Layout.maximumHeight: height Layout.maximumWidth: width } ColumnLayout { Layout.leftMargin: elisaTheme.layoutHorizontalMargin Layout.fillHeight: true Layout.fillWidth: true spacing: 0 ListView { id: trackData interactive: false Layout.fillWidth: true model: ListModel { id: trackList } onCountChanged: resize() delegate: RowLayout { id: delegateRow spacing: 0 Label { id: metaDataLabels text: name color: myPalette.text horizontalAlignment: Text.AlignRight Layout.preferredWidth: labelWidth Layout.minimumHeight: textSize.height Layout.rightMargin: !LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0 Layout.leftMargin: LayoutMirroring.enabled ? elisaTheme.layoutHorizontalMargin : 0 Component.onCompleted: { if(labelWidth < metaDataLabels.implicitWidth) { labelWidth = metaDataLabels.implicitWidth } } } Label { id: metaData text: content color: myPalette.text horizontalAlignment: Text.AlignLeft elide: Text.ElideRight Layout.preferredWidth: trackMetadata.width - labelWidth - 2 * elisaTheme.layoutHorizontalMargin - (trackDataHelper.hasValidAlbumCover ? elisaTheme.coverImageSize : 0) Layout.fillWidth: true Layout.minimumHeight: textSize.height Component.onCompleted: { if(metadataWidth < metaData.implicitWidth) { if (metaData.implicitWidth > elisaTheme.maximumMetadataWidth) { metadataWidth = elisaTheme.maximumMetadataWidth } else { metadataWidth = metaData.implicitWidth + 1 } } } } } } RowLayout { anchors.margins: 0 spacing: 0 visible: trackDataHelper.hasValidRating Layout.minimumHeight: textSize.height Label { id: ratingText text: i18nc("Rating label for information panel", "Rating:") color: myPalette.text horizontalAlignment: Text.AlignRight Layout.preferredWidth: labelWidth Layout.rightMargin: elisaTheme.layoutHorizontalMargin } TextMetrics { id: textSize font: ratingText.font text: ratingText.text } RatingStar { id: ratingWidget starRating: trackDataHelper.rating readOnly: true starSize: elisaTheme.ratingStarSize Layout.fillWidth: true layer.effect: ColorOverlay { source: ratingWidget color: myPalette.text } } } } } - LabelWithToolTip { + Label { + id: emptyMetaData + text: i18nc("Label when metadata of the track could not be scanned", "Metadata is not available.") + + horizontalAlignment: implicitWidth > trackMetadata.width ? Text.AlignRight : Text.AlignLeft + + Layout.minimumHeight: textSize.height + Layout.preferredWidth: trackMetadata.width * 0.98 - 2 * elisaTheme.layoutHorizontalMargin + Layout.topMargin: elisaTheme.layoutVerticalMargin + visible: !trackDataHelper.isValid + } + + Label { id: trackResource text: trackDataHelper.resourceURI color: myPalette.text font.italic: true elide: Text.ElideLeft horizontalAlignment: implicitWidth > trackMetadata.width ? Text.AlignRight : Text.AlignLeft Layout.minimumHeight: textSize.height Layout.preferredWidth: trackMetadata.width * 0.98 - 2 * elisaTheme.layoutHorizontalMargin Layout.topMargin: elisaTheme.layoutVerticalMargin } DialogButtonBox { id: buttons standardButtons: DialogButtonBox.Close alignment: Qt.AlignRight onRejected: trackMetadata.rejected() Layout.fillWidth: true } } } } diff --git a/src/trackdatahelper.cpp b/src/trackdatahelper.cpp index eda80fa6..9f00799d 100644 --- a/src/trackdatahelper.cpp +++ b/src/trackdatahelper.cpp @@ -1,151 +1,156 @@ /* * Copyright 2018 Alexander Stippich * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "trackdatahelper.h" TrackDataHelper::TrackDataHelper(QObject *parent) : QObject(parent) { } TrackDataHelper::~TrackDataHelper() = default; const MusicAudioTrack &TrackDataHelper::trackData() const { return *this; } void TrackDataHelper::setTrackData(const MusicAudioTrack &track) { MusicAudioTrack::operator=(track); Q_EMIT trackDataChanged(); } QString TrackDataHelper::title() const { if (MusicAudioTrack::title().isEmpty()) { return fileName(); } else { return MusicAudioTrack::title(); } } QString TrackDataHelper::duration() const { QString result; const QTime &trackDuration = MusicAudioTrack::duration(); if (trackDuration.hour() == 0) { result = trackDuration.toString(QStringLiteral("mm:ss")); } else { result = trackDuration.toString(QStringLiteral("h:mm:ss")); } return result; } QString TrackDataHelper::resourceURI() const { return MusicAudioTrack::resourceURI().toDisplayString(QUrl::PreferLocalFile); } QString TrackDataHelper::fileName() const { return MusicAudioTrack::resourceURI().fileName(); } bool TrackDataHelper::hasValidTrackNumber() const { return trackNumber() > -1; } bool TrackDataHelper::hasValidDiscNumber() const { return discNumber() > -1; } bool TrackDataHelper::hasValidChannels() const { return channels() > -1; } bool TrackDataHelper::hasValidBitRate() const { return bitRate() > -1; } bool TrackDataHelper::hasValidSampleRate() const { return sampleRate() > -1; } +bool TrackDataHelper::hasValidDuration() const +{ + return MusicAudioTrack::duration().isValid(); +} + bool TrackDataHelper::hasValidYear() const { return MusicAudioTrack::year() != 0; } bool TrackDataHelper::hasValidRating() const { - return rating() > -1; + return rating() > 0; } bool TrackDataHelper::hasValidTitle() const { return !title().isEmpty(); } bool TrackDataHelper::hasValidArtist() const { return !artist().isEmpty(); } bool TrackDataHelper::hasValidAlbumArtist() const { return !albumArtist().isEmpty(); } bool TrackDataHelper::hasValidAlbumName() const { return !albumName().isEmpty(); } bool TrackDataHelper::hasValidGenre() const { return !genre().isEmpty(); } bool TrackDataHelper::hasValidComposer() const { return !composer().isEmpty(); } bool TrackDataHelper::hasValidLyricist() const { return !lyricist().isEmpty(); } bool TrackDataHelper::hasValidComment() const { return !comment().isEmpty(); } bool TrackDataHelper::hasValidAlbumCover() const { return !albumCover().isEmpty(); } #include "moc_trackdatahelper.cpp" diff --git a/src/trackdatahelper.h b/src/trackdatahelper.h index 03cbf8c0..b2abedad 100644 --- a/src/trackdatahelper.h +++ b/src/trackdatahelper.h @@ -1,240 +1,250 @@ /* * Copyright 2018 Alexander Stippich * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef TRACKDATAHELPER_H #define TRACKDATAHELPER_H #include "elisaLib_export.h" #include #include "musicaudiotrack.h" class ELISALIB_EXPORT TrackDataHelper : public QObject, public MusicAudioTrack { Q_OBJECT Q_PROPERTY(MusicAudioTrack trackData READ trackData WRITE setTrackData NOTIFY trackDataChanged) Q_PROPERTY(QString title READ title NOTIFY trackDataChanged) Q_PROPERTY(bool hasValidTitle READ hasValidTitle NOTIFY trackDataChanged) Q_PROPERTY(QString artist READ artist NOTIFY trackDataChanged) Q_PROPERTY(bool hasValidArtist READ hasValidArtist NOTIFY trackDataChanged) Q_PROPERTY(QString albumName READ albumName NOTIFY trackDataChanged) Q_PROPERTY(bool hasValidAlbumName READ hasValidAlbumName NOTIFY trackDataChanged) Q_PROPERTY(QString albumArtist READ albumArtist NOTIFY trackDataChanged) Q_PROPERTY(bool hasValidAlbumArtist READ hasValidAlbumArtist NOTIFY trackDataChanged) Q_PROPERTY(QString genre READ genre NOTIFY trackDataChanged) Q_PROPERTY(bool hasValidGenre READ hasValidGenre NOTIFY trackDataChanged) Q_PROPERTY(QString composer READ composer NOTIFY trackDataChanged) Q_PROPERTY(bool hasValidComposer READ hasValidComposer NOTIFY trackDataChanged) Q_PROPERTY(QString lyricist READ lyricist NOTIFY trackDataChanged) Q_PROPERTY(bool hasValidLyricist READ hasValidLyricist NOTIFY trackDataChanged) Q_PROPERTY(QString comment READ comment NOTIFY trackDataChanged) Q_PROPERTY(bool hasValidComment READ hasValidComment NOTIFY trackDataChanged) Q_PROPERTY(int year READ year NOTIFY trackDataChanged) Q_PROPERTY(bool hasValidYear READ hasValidYear NOTIFY trackDataChanged) Q_PROPERTY(int trackNumber READ trackNumber NOTIFY trackDataChanged) Q_PROPERTY(bool hasValidTrackNumber READ hasValidTrackNumber NOTIFY trackDataChanged) Q_PROPERTY(int discNumber READ discNumber NOTIFY trackDataChanged) Q_PROPERTY(bool hasValidDiscNumber READ hasValidDiscNumber NOTIFY trackDataChanged) Q_PROPERTY(int channels READ channels NOTIFY trackDataChanged) Q_PROPERTY(bool hasValidChannels READ hasValidChannels NOTIFY trackDataChanged) Q_PROPERTY(int bitRate READ bitRate NOTIFY trackDataChanged) Q_PROPERTY(bool hasValidBitRate READ hasValidBitRate NOTIFY trackDataChanged) Q_PROPERTY(int sampleRate READ sampleRate NOTIFY trackDataChanged) Q_PROPERTY(bool hasValidSampleRate READ hasValidSampleRate NOTIFY trackDataChanged) Q_PROPERTY(QString resourceURI READ resourceURI NOTIFY trackDataChanged) Q_PROPERTY(QString fileName READ fileName NOTIFY trackDataChanged) Q_PROPERTY(QString duration READ duration NOTIFY trackDataChanged) Q_PROPERTY(int rating READ rating NOTIFY trackDataChanged) Q_PROPERTY(bool hasValidRating READ hasValidRating NOTIFY trackDataChanged) Q_PROPERTY(QUrl albumCover READ albumCover NOTIFY trackDataChanged) Q_PROPERTY(bool hasValidAlbumCover READ hasValidAlbumCover NOTIFY trackDataChanged) Q_PROPERTY(qulonglong databaseId READ databaseId NOTIFY trackDataChanged) + Q_PROPERTY(bool hasValidDuration + READ hasValidDuration + NOTIFY trackDataChanged) + + Q_PROPERTY(bool isValid + READ isValid + NOTIFY trackDataChanged) + public: explicit TrackDataHelper(QObject *parent = nullptr); ~TrackDataHelper() override; QString title() const; QString duration() const; QString resourceURI() const; QString fileName() const; const MusicAudioTrack& trackData() const; void setTrackData(const MusicAudioTrack &track); bool hasValidTitle() const; bool hasValidArtist() const; bool hasValidAlbumName() const; bool hasValidAlbumArtist() const; bool hasValidGenre() const; bool hasValidComposer() const; bool hasValidLyricist() const; bool hasValidComment() const; bool hasValidTrackNumber() const; bool hasValidDiscNumber() const; bool hasValidChannels() const; bool hasValidRating() const; bool hasValidBitRate() const; bool hasValidSampleRate() const; + bool hasValidDuration() const; + bool hasValidYear() const; bool hasValidAlbumCover() const; Q_SIGNALS: void trackDataChanged(); public: }; #endif // TRACKDATAHELPER_H