Accept empty fields in the edit tags dialog. Fixes issue #251.

This commit is contained in:
David Sansome 2010-04-27 17:19:07 +00:00
parent 3f360d254f
commit 0579b18850
7 changed files with 163 additions and 39 deletions

View File

@ -76,6 +76,7 @@ set(CLEMENTINE-SOURCES
libraryplaylistitem.cpp
scopedtransaction.cpp
playlistundocommands.cpp
spinbox.cpp
)
# Header files that have Q_OBJECT in
@ -138,6 +139,7 @@ set(CLEMENTINE-MOC-HEADERS
equalizer.h
equalizerslider.h
stickyslider.h
spinbox.h
)
# lists of engine source files

View File

@ -20,15 +20,12 @@
#include <QtDebug>
const char* EditTagDialog::kHintText = QT_TR_NOOP("[click to edit]");
EditTagDialog::EditTagDialog(QWidget* parent)
: QDialog(parent)
{
ui_.setupUi(this);
QString hint_text(tr("[click to edit]"));
ui_.album->SetHint(hint_text);
ui_.artist->SetHint(hint_text);
ui_.genre->SetHint(hint_text);
}
bool EditTagDialog::SetSongs(const SongList &s) {
@ -40,14 +37,20 @@ bool EditTagDialog::SetSongs(const SongList &s) {
}
songs_ = songs;
if (songs.count() == 0)
return false;
// Don't allow editing of fields that don't make sense for multiple items
ui_.title->setEnabled(songs.count() == 1);
ui_.track->setEnabled(songs.count() == 1);
ui_.comment->setEnabled(songs.count() == 1);
if (songs.count() == 0)
return false;
else if (songs.count() == 1) {
common_artist_ = songs[0].artist();
common_album_ = songs[0].album();
common_genre_ = songs[0].genre();
common_year_ = songs[0].year();
if (songs.count() == 1) {
const Song& song = songs[0];
ui_.title->setText(song.title());
@ -59,6 +62,10 @@ bool EditTagDialog::SetSongs(const SongList &s) {
ui_.comment->setPlainText(song.comment());
ui_.filename->setText(song.filename());
ui_.artist->ClearHint();
ui_.album->ClearHint();
ui_.genre->ClearHint();
} else {
// Find any fields that are common to all items
@ -66,26 +73,30 @@ bool EditTagDialog::SetSongs(const SongList &s) {
ui_.track->clear();
ui_.comment->clear();
QString artist(songs[0].artist());
QString album(songs[0].album());
QString genre(songs[0].genre());
int year = songs[0].year();
foreach (const Song& song, songs) {
if (artist != song.artist())
artist = QString::null;
if (album != song.album())
album = QString::null;
if (genre != song.genre())
genre = QString::null;
if (year != song.year())
year = -1;
if (common_artist_ != song.artist()) {
common_artist_ = QString::null;
ui_.artist->SetHint(kHintText);
}
if (common_album_ != song.album()) {
common_album_ = QString::null;
ui_.album->SetHint(kHintText);
}
if (common_genre_ != song.genre()) {
common_genre_ = QString::null;
ui_.genre->SetHint(kHintText);
}
if (common_year_ != song.year())
common_year_ = -1;
}
ui_.artist->setText(artist);
ui_.album->setText(album);
ui_.genre->setText(genre);
ui_.year->setValue(year);
ui_.artist->setText(common_artist_);
ui_.album->setText(common_album_);
ui_.genre->setText(common_genre_);
ui_.year->setValue(common_year_);
ui_.filename->setText(tr("Editing %n tracks", "", songs.count()));
}
@ -102,19 +113,23 @@ void EditTagDialog::accept() {
foreach (const Song& old, songs_) {
Song song(old);
if (ui_.title->isEnabled() && !ui_.title->text().isEmpty())
song.set_title(ui_.title->text());
if (ui_.artist->isEnabled() && !ui_.artist->text().isEmpty())
song.set_artist(ui_.artist->text());
if (ui_.album->isEnabled() && !ui_.album->text().isEmpty())
song.set_album(ui_.album->text());
if (ui_.genre->isEnabled() && !ui_.genre->text().isEmpty())
song.set_genre(ui_.genre->text());
int track = ui_.track->text().isEmpty() ? -1 : ui_.track->value();
int year = ui_.year->text().isEmpty() ? -1 : ui_.year->value();
if (ui_.title->isEnabled())
song.set_title(ui_.title->text());
if (ui_.artist->isEnabled() && !(common_artist_.isNull() && ui_.artist->text().isEmpty()))
song.set_artist(ui_.artist->text());
if (ui_.album->isEnabled() && !(common_album_.isNull() && ui_.album->text().isEmpty()))
song.set_album(ui_.album->text());
if (ui_.genre->isEnabled() && !(common_genre_.isNull() && ui_.genre->text().isEmpty()))
song.set_genre(ui_.genre->text());
if (ui_.year->isEnabled() && !(common_year_ == -1 && year == -1))
song.set_year(year);
if (ui_.year->isEnabled())
song.set_year(ui_.year->value());
if (ui_.track->isEnabled())
song.set_track(ui_.track->value());
song.set_track(track);
if (ui_.comment->isEnabled())
song.set_comment(ui_.comment->toPlainText());

View File

@ -30,6 +30,8 @@ class EditTagDialog : public QDialog {
public:
EditTagDialog(QWidget* parent = 0);
static const char* kHintText;
bool SetSongs(const SongList& songs);
void SetTagCompleter(Library* library);
@ -43,6 +45,11 @@ class EditTagDialog : public QDialog {
Ui::EditTagDialog ui_;
SongList songs_;
QString common_artist_;
QString common_album_;
QString common_genre_;
int common_year_;
};
#endif // EDITTAGDIALOG_H

View File

@ -87,7 +87,7 @@
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSpinBox" name="track">
<widget class="SpinBox" name="track">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -116,7 +116,7 @@
</widget>
</item>
<item>
<widget class="QSpinBox" name="year">
<widget class="SpinBox" name="year">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -157,7 +157,7 @@
<widget class="QLineEdit" name="filename">
<property name="styleSheet">
<string notr="true">QLineEdit {
background-color: transparent;
background-color: transparent;
}</string>
</property>
<property name="frame">
@ -194,6 +194,11 @@
<extends>QLineEdit</extends>
<header>lineedit.h</header>
</customwidget>
<customwidget>
<class>SpinBox</class>
<extends>QSpinBox</extends>
<header>spinbox.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>buttonBox</tabstop>

View File

@ -28,6 +28,7 @@ class LineEdit : public QLineEdit {
QString GetHint() const { return hint_; }
void SetHint(const QString& hint);
void ClearHint() { SetHint(QString()); }
void paintEvent(QPaintEvent* e);

49
src/spinbox.cpp Normal file
View File

@ -0,0 +1,49 @@
/* This file is part of Clementine.
Clementine is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Clementine 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#include "spinbox.h"
#include <QtDebug>
SpinBox::SpinBox(QWidget *parent)
: QSpinBox(parent),
empty_value_(0)
{
}
int SpinBox::valueFromText(const QString &text) const {
if (text.isEmpty())
return empty_value_;
return QSpinBox::valueFromText(text);
}
QString SpinBox::textFromValue(int val) const {
if (val == empty_value_)
return "";
return QSpinBox::textFromValue(val);
}
void SpinBox::fixup(QString &str) const {
if (str.isEmpty())
return;
QSpinBox::fixup(str);
}
QValidator::State SpinBox::validate(QString &input, int &pos) const {
if (input.isEmpty())
return QValidator::Acceptable;
return QSpinBox::validate(input, pos);
}

45
src/spinbox.h Normal file
View File

@ -0,0 +1,45 @@
/* This file is part of Clementine.
Clementine is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Clementine 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SPINBOX_H
#define SPINBOX_H
#include <QSpinBox>
// A spinbox that accepts the empty string as input
class SpinBox : public QSpinBox {
Q_OBJECT
Q_PROPERTY(int empty_value READ empty_value WRITE set_empty_value);
public:
SpinBox(QWidget *parent = 0);
// The empty_value must still be within the range of the spinbox.
// Defaults to 0
int empty_value() const { return empty_value_; }
void set_empty_value(int v) { empty_value_ = v; }
protected:
int valueFromText(const QString &text) const;
QString textFromValue(int val) const;
void fixup(QString &str) const;
QValidator::State validate(QString &input, int &pos) const;
private:
int empty_value_;
};
#endif // SPINBOX_H