File indexing completed on 2024-05-12 05:09:25
0001 /*************************************************************************** 0002 Copyright (C) 2006-2009 Robby Stephenson <robby@periapsis.org> 0003 ***************************************************************************/ 0004 0005 /*************************************************************************** 0006 * * 0007 * This program is free software; you can redistribute it and/or * 0008 * modify it under the terms of the GNU General Public License as * 0009 * published by the Free Software Foundation; either version 2 of * 0010 * the License or (at your option) version 3 or any later version * 0011 * accepted by the membership of KDE e.V. (or its successor approved * 0012 * by the membership of KDE e.V.), which shall act as a proxy * 0013 * defined in Section 14 of version 3 of the license. * 0014 * * 0015 * This program is distributed in the hope that it will be useful, * 0016 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0018 * GNU General Public License for more details. * 0019 * * 0020 * You should have received a copy of the GNU General Public License * 0021 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 0022 * * 0023 ***************************************************************************/ 0024 0025 #include "updateentries.h" 0026 #include "fieldcommand.h" 0027 #include "modifyentries.h" 0028 #include "../collection.h" 0029 #include "../utils/mergeconflictresolver.h" 0030 0031 #include <KLocalizedString> 0032 0033 namespace { 0034 0035 class OverWriteResolver : public Tellico::Merge::ConflictResolver { 0036 public: 0037 OverWriteResolver(bool overwrite_) : m_overWrite(overwrite_) {}; 0038 Tellico::Merge::ConflictResolver::Result resolve(Tellico::Data::EntryPtr, 0039 Tellico::Data::EntryPtr, 0040 Tellico::Data::FieldPtr, 0041 const QString& value1 = QString(), 0042 const QString& value2 = QString()) Q_DECL_OVERRIDE { 0043 Q_UNUSED(value1); 0044 Q_UNUSED(value2); 0045 return m_overWrite ? Tellico::Merge::ConflictResolver::KeepSecond : Tellico::Merge::ConflictResolver::KeepFirst; 0046 } 0047 0048 private: 0049 Q_DISABLE_COPY(OverWriteResolver) 0050 bool m_overWrite; 0051 }; 0052 0053 } 0054 0055 using Tellico::Command::UpdateEntries; 0056 0057 namespace Tellico { 0058 namespace Command { 0059 0060 class MergeEntries : public QUndoCommand { 0061 public: 0062 MergeEntries(QUndoCommand* updater, Data::EntryPtr currEntry_, Data::EntryPtr newEntry_, bool overWrite_) 0063 : QUndoCommand(updater) 0064 , m_currEntry(currEntry_) 0065 , m_newEntry(newEntry_) 0066 , m_orphanEntry(new Data::Entry(*currEntry_)) 0067 , m_overWrite(overWrite_) { 0068 // we merge the entries here instead of in redo() because this 0069 // command is never called without also calling ModifyEntries() 0070 // which takes care of copying the entry values 0071 // Data::Document::mergeEntry(currEntry_, newEntry_, overWrite_); 0072 } 0073 0074 virtual void redo() Q_DECL_OVERRIDE { 0075 OverWriteResolver res(m_overWrite); 0076 Tellico::Merge::mergeEntry(m_currEntry, m_newEntry, &res); 0077 } 0078 virtual void undo() Q_DECL_OVERRIDE {} // does nothing 0079 Data::EntryPtr orphanEntry() const { return m_orphanEntry; } 0080 0081 private: 0082 Data::EntryPtr m_currEntry; 0083 Data::EntryPtr m_newEntry; 0084 Data::EntryPtr m_orphanEntry; 0085 bool m_overWrite; 0086 }; 0087 } 0088 } 0089 0090 UpdateEntries::UpdateEntries(Tellico::Data::CollPtr coll_, Tellico::Data::EntryPtr oldEntry_, Tellico::Data::EntryPtr newEntry_, bool overWrite_) 0091 : QUndoCommand(i18nc("Modify (Entry Title)", "Modify %1", newEntry_->title())) 0092 , m_coll(coll_) 0093 , m_oldEntry(oldEntry_) 0094 , m_newEntry(newEntry_) 0095 , m_overWrite(overWrite_) 0096 { 0097 } 0098 0099 void UpdateEntries::redo() { 0100 if(childCount() == 0) { 0101 // add commands 0102 // do this here instead of the constructor because several UpdateEntries may be in one command 0103 // and I don't want to add new fields multiple times 0104 0105 auto p = Tellico::Merge::mergeFields(m_coll, 0106 m_newEntry->collection()->fields(), 0107 Data::EntryList() << m_newEntry); 0108 Data::FieldList modifiedFields = p.first; 0109 Data::FieldList addedFields = p.second; 0110 0111 QStringList updatedFields; 0112 0113 foreach(Data::FieldPtr field, modifiedFields) { 0114 if(m_coll->hasField(field->name())) { 0115 new FieldCommand(this, FieldCommand::FieldModify, m_coll, 0116 field, m_coll->fieldByName(field->name())); 0117 } 0118 updatedFields << field->name(); 0119 } 0120 0121 foreach(Data::FieldPtr field, addedFields) { 0122 new FieldCommand(this, FieldCommand::FieldAdd, m_coll, field); 0123 updatedFields << field->name(); 0124 } 0125 0126 // MergeEntries copies values from m_newEntry into m_oldEntry 0127 // m_oldEntry is in the current collection 0128 // m_newEntry isn't... 0129 MergeEntries* cmd = new MergeEntries(this, m_oldEntry, m_newEntry, m_overWrite); 0130 // cmd->orphanEntry() returns a copy of m_oldEntry before values were merged 0131 // m_oldEntry has new values 0132 // in the ModifyEntries command, the second entry should be owned by the current 0133 // collection and contain the updated values 0134 // the first one is not owned by current collection 0135 new ModifyEntries(this, m_coll, Data::EntryList() << cmd->orphanEntry(), Data::EntryList() << m_oldEntry, updatedFields); 0136 } 0137 // calls redo() on all child commands 0138 QUndoCommand::redo(); 0139 }