Commit 9319d4a1 authored by Urs Fleisch's avatar Urs Fleisch
Browse files

mark changed tag fields and filenames with mid background color

parent b42102e2
......@@ -344,11 +344,13 @@ ConfigDialog::ConfigDialog(QWidget* parent, QString& caption) :
#endif
if (saveGroupBox) {
m_preserveTimeCheckBox = new QCheckBox(i18n("&Preserve file timestamp"), saveGroupBox);
m_markChangesCheckBox = new QCheckBox(i18n("&Mark changes"), saveGroupBox);
#if QT_VERSION >= 0x040000
QHBoxLayout* hbox = new QHBoxLayout;
hbox->setMargin(2);
hbox->addWidget(m_preserveTimeCheckBox);
saveGroupBox->setLayout(hbox);
QVBoxLayout* vbox = new QVBoxLayout;
vbox->setMargin(2);
vbox->addWidget(m_preserveTimeCheckBox);
vbox->addWidget(m_markChangesCheckBox);
saveGroupBox->setLayout(vbox);
#endif
vlayout->addWidget(saveGroupBox);
}
......@@ -543,6 +545,7 @@ void ConfigDialog::setConfig(const FormatConfig* fnCfg,
m_markTruncationsCheckBox->setChecked(miscCfg->m_markTruncations);
m_totalNumTracksCheckBox->setChecked(miscCfg->m_enableTotalNumberOfTracks);
m_preserveTimeCheckBox->setChecked(miscCfg->m_preserveTime);
m_markChangesCheckBox->setChecked(miscCfg->m_markChanges);
m_onlyCustomGenresCheckBox->setChecked(miscCfg->m_onlyCustomGenres);
m_genresEdit->setStrings(miscCfg->m_customGenres);
m_commandsTable->setCommandList(miscCfg->m_contextMenuCommands);
......@@ -624,6 +627,7 @@ void ConfigDialog::getConfig(FormatConfig* fnCfg,
miscCfg->m_markTruncations = m_markTruncationsCheckBox->isChecked();
miscCfg->m_enableTotalNumberOfTracks = m_totalNumTracksCheckBox->isChecked();
miscCfg->m_preserveTime = m_preserveTimeCheckBox->isChecked();
miscCfg->m_markChanges = m_markChangesCheckBox->isChecked();
miscCfg->m_onlyCustomGenres = m_onlyCustomGenresCheckBox->isChecked();
m_genresEdit->getStrings(miscCfg->m_customGenres);
m_commandsTable->getCommandList(miscCfg->m_contextMenuCommands);
......
......@@ -131,6 +131,8 @@ protected slots:
private:
/** Preserve timestamp checkbox */
QCheckBox* m_preserveTimeCheckBox;
/** Mark changes checkbox */
QCheckBox* m_markChangesCheckBox;
/** Mark truncated fields checkbox */
QCheckBox* m_markTruncationsCheckBox;
/** ID3v1 text encodings */
......
......@@ -137,7 +137,7 @@ void FlacFile::readTags(bool force)
m_pictures.clear();
int pictureNr = 0;
#endif
markTag2Changed(false);
markTag2Unchanged();
m_fileRead = true;
QCM_QCString fnIn = QFile::encodeName(getDirInfo()->getDirname() + QDir::separator() + currentFilename());
m_fileInfo.read(0); // just to start invalid
......@@ -339,12 +339,12 @@ bool FlacFile::writeTags(bool force, bool* renamed, bool preserve)
#ifdef HAVE_FLAC_PICTURE
if ((commentsSet || pictureSet) &&
m_chain->write(!pictureRemoved, preserve)) {
markTag2Changed(false);
markTag2Unchanged();
}
#else
if (commentsSet &&
m_chain->write(true, preserve)) {
markTag2Changed(false);
markTag2Unchanged();
}
#endif
else {
......@@ -395,7 +395,7 @@ bool FlacFile::setFrameV2(const Frame& frame)
if (it != m_pictures.end()) {
*it = frame;
PictureFrame::setDescription(*it, frame.getValue());
markTag2Changed();
markTag2Changed(Frame::FT_Picture);
return true;
}
}
......@@ -421,7 +421,7 @@ bool FlacFile::addFrameV2(Frame& frame)
PictureFrame::setDescription(frame, frame.getValue());
frame.setIndex(m_pictures.size());
m_pictures.push_back(frame);
markTag2Changed();
markTag2Changed(Frame::FT_Picture);
return true;
}
return OggFile::addFrameV2(frame);
......@@ -445,7 +445,7 @@ bool FlacFile::deleteFrameV2(const Frame& frame)
PictureList::iterator it = m_pictures.at(index);
m_pictures.erase(it);
#endif
markTag2Changed();
markTag2Changed(Frame::FT_Picture);
return true;
}
}
......@@ -461,7 +461,7 @@ void FlacFile::deleteFramesV2(const FrameFilter& flt)
{
if (flt.areAllEnabled() || flt.isEnabled(Frame::FT_Picture)) {
m_pictures.clear();
markTag2Changed();
markTag2Changed(Frame::FT_Picture);
}
OggFile::deleteFramesV2(flt);
}
......
......@@ -1475,7 +1475,7 @@ bool FrameList::editFrame(Frame& frame)
}
if (result && m_file) {
if (m_file->setFrameV2(frame)) {
m_file->markTag2Changed();
m_file->markTag2Changed(frame.getType());
}
}
return result;
......@@ -1529,7 +1529,7 @@ bool FrameList::addFrame(bool edit)
if (edit) {
if (!editFrame(m_frame)) {
m_file->deleteFrameV2(m_frame);
m_file->markTag2Changed(false);
m_file->markTag2Unchanged();
return false;
}
}
......
......@@ -312,6 +312,67 @@ void FrameItemDelegate::setModelData(
#else
/** QCheckTableItem with control of background color. */
class NameTableItem : public QCheckTableItem {
public:
/**
* Constructor.
* @param table table
* @param text text
*/
NameTableItem(QTable* table, const QString& text) :
QCheckTableItem(table, text), m_colored(false) {}
/**
* Destructor.
*/
virtual ~NameTableItem();
/**
* Set background colored.
* @param en true to enable
*/
void setBackgroundColored(bool en) { m_colored = en; }
/**
* Paint item.
*
* @param p painter
* @param cg color group
* @param cr rectangle
* @param selected true if highlighted
*/
virtual void paint(QPainter* p, const QColorGroup& cg, const QRect& cr,
bool selected);
private:
bool m_colored;
};
/**
* Destructor.
*/
NameTableItem::~NameTableItem() {}
/**
* Paint item.
*
* @param p painter
* @param cg color group
* @param cr rectangle
* @param selected true if highlighted
*/
void NameTableItem::paint(QPainter* p, const QColorGroup& cg, const QRect& cr,
bool selected)
{
QColorGroup g(cg);
if (m_colored) {
g.setColor(QColorGroup::Base, cg.mid());
}
QCheckTableItem::paint(p, g, cr, selected);
}
/** QTableItem subclass to align everything (also numbers) left. */
class ValueTableItem : public QTableItem {
public:
......@@ -664,7 +725,7 @@ void GenreTableItem::setColorRed(bool en)
#if QT_VERSION >= 0x040000
FrameTable::FrameTable(QWidget* parent, bool id3v1) :
QTableWidget(parent), m_cursorRow(-1), m_cursorColumn(-1),
m_markedRows(0), m_setCheckBoxes(true), m_id3v1(id3v1)
m_markedRows(0), m_changedFrames(0), m_setCheckBoxes(true), m_id3v1(id3v1)
{
setColumnCount(CI_NumColumns);
setSelectionMode(SingleSelection);
......@@ -687,7 +748,8 @@ FrameTable::FrameTable(QWidget* parent, bool id3v1) :
#else
FrameTable::FrameTable(QWidget* parent, bool id3v1) :
QTable(parent), m_cursorRow(-1), m_cursorColumn(-1),
m_markedRows(0), m_id3v1(id3v1), m_resizeTable(false), m_updateGenres(false)
m_markedRows(0), m_changedFrames(0), m_id3v1(id3v1), m_resizeTable(false),
m_updateGenres(false)
{
setNumCols(CI_NumColumns);
setSelectionMode(NoSelection);
......@@ -699,7 +761,7 @@ FrameTable::FrameTable(QWidget* parent, bool id3v1) :
if (id3v1) {
setMinimumHeight((Frame::FT_LastV1Frame + 1) * (rowHeight(0) + 1));
}
setItem(0, CI_Enable, new QCheckTableItem(this, i18n("Track Number")));
setItem(0, CI_Enable, new NameTableItem(this, i18n("Track Number")));
adjustColumn(CI_Enable);
setColumnStretchable(CI_Value, true);
removeRow(0);
......@@ -762,6 +824,16 @@ void FrameTable::framesToTable()
setItem(row, CI_Enable, twi);
}
twi->setCheckState(m_setCheckBoxes ? Qt::Checked : Qt::Unchecked);
bool frameChanged =
(static_cast<unsigned>((*it).getType()) < sizeof(m_changedFrames) * 8 &&
(m_changedFrames & (1 << (*it).getType())) != 0);
#if QT_VERSION >= 0x040200
twi->setBackground(frameChanged ? QApplication::palette().mid() : Qt::NoBrush);
#elif QT_VERSION >= 0x040000
twi->setBackgroundColor(frameChanged ?
QApplication::palette().mid().color() :
QApplication::palette().base().color());
#endif
int type;
if (m_id3v1) {
......@@ -812,19 +884,22 @@ void FrameTable::framesToTable()
setNumRows(m_frames.size());
int row = 0;
QTableItem* ti;
QCheckTableItem* cti;
NameTableItem* nti;
for (FrameCollection::const_iterator it = m_frames.begin();
it != m_frames.end();
++it) {
if ((ti = item(row, CI_Enable)) != 0 &&
(cti = dynamic_cast<QCheckTableItem*>(ti)) != 0) {
(nti = dynamic_cast<NameTableItem*>(ti)) != 0) {
ti->setText(getDisplayName((*it).getName()));
} else {
cti = new QCheckTableItem(this, getDisplayName((*it).getName()));
setItem(row, CI_Enable, cti);
nti = new NameTableItem(this, getDisplayName((*it).getName()));
setItem(row, CI_Enable, nti);
}
if (cti) {
cti->setChecked(m_setCheckBoxes);
if (nti) {
nti->setChecked(m_setCheckBoxes);
nti->setBackgroundColored(
static_cast<unsigned>((*it).getType()) < sizeof(m_changedFrames) * 8 &&
(m_changedFrames & (1 << (*it).getType())) != 0);
}
int type;
......
......@@ -72,6 +72,12 @@ public:
*/
void markRows(unsigned char rowMask) { m_markedRows = rowMask; }
/**
* Mark changed frames.
* @param frameMask mask with bits of frame types to mark
*/
void markChangedFrames(unsigned long frameMask) { m_changedFrames = frameMask; }
/**
* Set all check boxes on or off.
* Will take effect when framesToTable() is called.
......@@ -163,6 +169,7 @@ private:
int m_cursorRow;
int m_cursorColumn;
unsigned char m_markedRows;
unsigned long m_changedFrames;
bool m_setCheckBoxes;
const bool m_id3v1;
FrameCollection m_frames;
......
......@@ -175,8 +175,8 @@ Id3Form::Id3Form(QWidget* parent)
filenameGroupBoxLayout->setMargin(margin);
filenameGroupBoxLayout->setSpacing(spacing);
QLabel* nameLabel = new QLabel(i18n("Name:"), filenameGroupBox);
filenameGroupBoxLayout->addWidget(nameLabel, 0, 0);
m_nameLabel = new QLabel(i18n("Name:"), filenameGroupBox);
filenameGroupBoxLayout->addWidget(m_nameLabel, 0, 0);
m_nameLineEdit = new QLineEdit(filenameGroupBox);
filenameGroupBoxLayout->addWidget(m_nameLineEdit, 0, 1);
......@@ -305,8 +305,8 @@ Id3Form::Id3Form(QWidget* parent)
0, 0, 0, 2);
}
QLabel* nameLabel = new QLabel(i18n("Name:"), filenameGroupBox);
filenameGroupBoxLayout->addWidget(nameLabel, 1, 0);
m_nameLabel = new QLabel(i18n("Name:"), filenameGroupBox);
filenameGroupBoxLayout->addWidget(m_nameLabel, 1, 0);
m_nameLineEdit = new QLineEdit(filenameGroupBox);
filenameGroupBoxLayout->addWidget(m_nameLineEdit, 1, 1);
......@@ -659,6 +659,26 @@ void Id3Form::nameLineEditChanged(const QString& txt)
formatLineEdit(m_nameLineEdit, txt, &theApp->s_fnFormatCfg);
}
/**
* Mark the filename as changed.
* @param en true to mark as changed
*/
void Id3Form::markChangedFilename(bool en)
{
#if QT_VERSION >= 0x040000
if (en) {
QPalette changedPalette(m_nameLabel->palette());
changedPalette.setBrush(QPalette::Active, QPalette::Window, changedPalette.mid());
m_nameLabel->setPalette(changedPalette);
} else {
m_nameLabel->setPalette(QPalette());
}
m_nameLabel->setAutoFillBackground(en);
#else
m_nameLabel->setBackgroundMode(en ? PaletteMid : PaletteBackground);
#endif
}
/**
* Format string within line edit.
*
......
......@@ -162,6 +162,12 @@ public:
*/
void setFilenameEditEnabled(bool en) { m_nameLineEdit->setEnabled(en); }
/**
* Mark the filename as changed.
* @param en true to mark as changed
*/
void markChangedFilename(bool en);
/**
* Set details info text.
*
......@@ -450,6 +456,7 @@ private:
FileList* m_fileListBox;
QComboBox* m_formatComboBox;
QLabel* m_nameLabel;
QLineEdit* m_nameLineEdit;
QLabel* m_detailsLabel;
#if QT_VERSION >= 0x040000
......
......@@ -2140,6 +2140,11 @@ void Kid3App::slotSettingsConfigure()
if (!s_miscCfg.m_markTruncations) {
m_view->frameTableV1()->markRows(0);
}
if (!s_miscCfg.m_markChanges) {
m_view->frameTableV1()->markChangedFrames(0);
m_view->frameTableV2()->markChangedFrames(0);
m_view->markChangedFilename(false);
}
setTextEncodings();
#if QT_VERSION < 0x040000
m_view->frameTableV1()->triggerUpdateGenres();
......@@ -2792,6 +2797,13 @@ void Kid3App::updateGuiControls()
if (s_miscCfg.m_markTruncations) {
m_view->frameTableV1()->markRows(single_v2_file->getTruncationFlags());
}
if (s_miscCfg.m_markChanges) {
m_view->frameTableV1()->markChangedFrames(
single_v2_file->getChangedFramesV1());
m_view->frameTableV2()->markChangedFrames(
single_v2_file->getChangedFramesV2());
m_view->markChangedFilename(single_v2_file->isFilenameChanged());
}
}
else {
m_view->setFilenameEditEnabled(false);
......@@ -2802,6 +2814,11 @@ void Kid3App::updateGuiControls()
if (s_miscCfg.m_markTruncations) {
m_view->frameTableV1()->markRows(0);
}
if (s_miscCfg.m_markChanges) {
m_view->frameTableV1()->markChangedFrames(0);
m_view->frameTableV2()->markChangedFrames(0);
m_view->markChangedFilename(false);
}
}
m_view->frameTableV1()->setAllCheckBoxes(num_files_selected == 1);
m_view->frameTableV1()->framesToTable();
......
......@@ -301,7 +301,7 @@ void M4aFile::readTags(bool force)
{
if (force || !m_fileRead) {
m_metadata.clear();
markTag2Changed(false);
markTag2Unchanged();
m_fileRead = true;
QCM_QCString fnIn = QFile::encodeName(
getDirInfo()->getDirname() + QDir::separator() + currentFilename());
......@@ -540,7 +540,7 @@ bool M4aFile::writeTags(bool force, bool* renamed, bool preserve)
if (ok) {
// without this, old tags stay in the file marked as free
MP4Optimize(fn);
markTag2Changed(false);
markTag2Unchanged();
}
// restore time stamp
......@@ -574,7 +574,7 @@ void M4aFile::deleteFramesV2(const FrameFilter& flt)
{
if (flt.areAllEnabled()) {
m_metadata.clear();
markTag2Changed();
markTag2Changed(Frame::FT_UnknownFrame);
} else {
bool changed = false;
for (MetadataMap::iterator it = m_metadata.begin();
......@@ -594,7 +594,7 @@ void M4aFile::deleteFramesV2(const FrameFilter& flt)
}
}
if (changed) {
markTag2Changed();
markTag2Changed(Frame::FT_UnknownFrame);
}
}
}
......@@ -626,8 +626,10 @@ QString M4aFile::getTextField(const QString& name) const
*
* @param name name
* @param value value, "" to remove, QString::null to do nothing
* @param type frame type
*/
void M4aFile::setTextField(const QString& name, const QString& value)
void M4aFile::setTextField(const QString& name, const QString& value,
Frame::Type type)
{
if (m_fileRead && !value.isNull()) {
QByteArray str = value.QCM_toUtf8();
......@@ -635,11 +637,11 @@ void M4aFile::setTextField(const QString& name, const QString& value)
if (it != m_metadata.end()) {
if (QString::fromUtf8((*it).data(), (*it).size()) != value) {
*it = str;
markTag2Changed();
markTag2Changed(type);
}
} else {
m_metadata.insert(name, str);
markTag2Changed();
markTag2Changed(type);
}
}
}
......@@ -751,7 +753,7 @@ QString M4aFile::getGenreV2()
*/
void M4aFile::setTitleV2(const QString& str)
{
setTextField("\251nam", str);
setTextField("\251nam", str, Frame::FT_Title);
}
/**
......@@ -761,7 +763,7 @@ void M4aFile::setTitleV2(const QString& str)
*/
void M4aFile::setArtistV2(const QString& str)
{
setTextField("\251ART", str);
setTextField("\251ART", str, Frame::FT_Artist);
}
/**
......@@ -771,7 +773,7 @@ void M4aFile::setArtistV2(const QString& str)
*/
void M4aFile::setAlbumV2(const QString& str)
{
setTextField("\251alb", str);
setTextField("\251alb", str, Frame::FT_Album);
}
/**
......@@ -781,7 +783,7 @@ void M4aFile::setAlbumV2(const QString& str)
*/
void M4aFile::setCommentV2(const QString& str)
{
setTextField("\251cmt", str);
setTextField("\251cmt", str, Frame::FT_Comment);
}
/**
......@@ -792,7 +794,8 @@ void M4aFile::setCommentV2(const QString& str)
void M4aFile::setYearV2(int num)
{
if (num >= 0) {
setTextField("\251day", num != 0 ? QString::number(num) : "");
setTextField("\251day", num != 0 ? QString::number(num) : "",
Frame::FT_Date);
}
}
......@@ -815,7 +818,7 @@ void M4aFile::setTrackNumV2(int num)
} else {
str = "";
}
setTextField("trkn", str);
setTextField("trkn", str, Frame::FT_Track);
}
}
......@@ -829,10 +832,10 @@ void M4aFile::setGenreV2(const QString& str)
if (str != getGenreV2()) {
int genreNum = Genres::getNumber(str);
if (genreNum != 255) {
setTextField("gnre", str);
setTextField("gnre", str, Frame::FT_Genre);
m_metadata.remove("\251gen");
} else {
setTextField("\251gen", str);
setTextField("\251gen", str, Frame::FT_Genre);
m_metadata.remove("gnre");
}
}
......@@ -930,11 +933,11 @@ bool M4aFile::setFrameV2(const Frame& frame)
QByteArray str = frame.getValue().QCM_toUtf8();
if (*it != str) {
*it = str;
markTag2Changed();
markTag2Changed(frame.getType());
}
} else {
if (PictureFrame::getData(frame, *it)) {
markTag2Changed();
markTag2Changed(Frame::FT_Picture);
}
}
return true;
......@@ -970,7 +973,7 @@ bool M4aFile::addFrameV2(Frame& frame)
} else {
m_metadata[name] = frame.getValue().QCM_toUtf8();
}
markTag2Changed();
markTag2Changed(type);
return true;
}
......@@ -987,7 +990,7 @@ bool M4aFile::deleteFrameV2(const Frame& frame)
MetadataMap::iterator it = m_metadata.find(name);
if (it != m_metadata.end()) {
m_metadata.erase(it);
markTag2Changed();
markTag2Changed(frame.getType());
return true;
}
......
......@@ -318,8 +318,10 @@ private:
*
* @param name name
* @param value value, "" to remove, QString::null to do nothing
* @param type frame type
*/
void setTextField(const QString& name, const QString& value);
void setTextField(const QString& name, const QString& value,
Frame::Type type);
/** true if file has been read. */
bool m_fileRead;
......
......@@ -100,6 +100,7 @@ MiscConfig::MiscConfig(const QString& group) :
m_markTruncations(true),
m_enableTotalNumberOfTracks(false),
m_preserveTime(false),
m_markChanges(true),
m_commentName(s_defaultCommentName),
m_nameFilter(""),
m_formatText(s_defaultFnFmtList[0]),
......@@ -149,6 +150,7 @@ void MiscConfig::writeToConfig(
cfg.writeEntry("MarkTruncations", m_markTruncations);
cfg.writeEntry("EnableTotalNumberOfTracks", m_enableTotalNumberOfTracks);
cfg.writeEntry("PreserveTime", m_preserveTime);
cfg.writeEntry("MarkChanges", m_markChanges);
cfg.writeEntry("CommentName", m_commentName);
cfg.writeEntry("SplitterSizes", m_splitterSizes);
cfg.writeEntry("VSplitterSizes", m_vSplitterSizes);
......@@ -191,6 +193,7 @@ void MiscConfig::writeToConfig(
config->QCM_writeEntry("/MarkTruncations", m_markTruncations);
config->QCM_writeEntry("/EnableTotalNumberOfTracks", m_enableTotalNumberOfTracks);
config->QCM_writeEntry("/PreserveTime", m_preserveTime);
config->QCM_writeEntry("/MarkChanges", m_markChanges);
config->QCM_writeEntry("/CommentName", m_commentName);
#if QT_VERSION >= 0x040000
......@@ -273,6 +276,7 @@ void MiscConfig::readFromConfig(
m_markTruncations = cfg.KCM_readBoolEntry("MarkTruncations", m_markTruncations);
m_enableTotalNumberOfTracks = cfg.KCM_readBoolEntry("EnableTotalNumberOfTracks", m_enableTotalNumberOfTracks);
m_preserveTime = cfg.KCM_readBoolEntry("PreserveTime", m_preserveTime);
m_markChanges = cfg.KCM_readBoolEntry("MarkChanges", m_markChanges);
m_commentName = cfg.readEntry("CommentName", s_defaultCommentName);
m_formatText =
cfg.readEntry("FormatText2", s_defaultFnFmtList[0]);
......@@ -314,6 +318,7 @@ void MiscConfig::readFromConfig(
m_markTruncations = config->QCM_readBoolEntry("/MarkTruncations", m_markTruncations);
m_enableTotalNumberOfTracks = config->QCM_readBoolEntry("/EnableTotalNumberOfTracks", m_enableTotalNumberOfTracks);
m_preserveTime = config->QCM_readBoolEntry("/PreserveTime", m_preserveTime);
m_markChanges = config->QCM_readBoolEntry("/MarkChanges", m_markChanges);
m_commentName = config->QCM_readEntry("/CommentName", s_defaultCommentName);
m_formatText =
......
......@@ -162,6 +162,8 @@ public:
bool m_enableTotalNumberOfTracks;
/** true to preserve file time stamps */
bool m_preserveTime;
/** true to mark changed fields */
bool m_markChanges;
/** field name used for Vorbis comment entries */
QString m_commentName;
/** filter of file names to be opened */
......
......@@ -104,26 +104,26 @@ void Mp3File::readTags(bool force)
if (force && m_tagV1) {
m_tagV1->Clear();
m_tagV1->Link(fn, ID3TT_ID3V1);
markTag1Changed(false);
markTag1Unchanged();
}
if (!m_tagV1) {
m_tagV1 = new ID3_Tag;
if (m_tagV1) {