1 #include "infocreator.hpp"
2
3 #include <algorithm>
4
5 #include <QLabel>
6 #include <QUuid>
7
8 #include <components/misc/stringops.hpp>
9
10 #include "../../model/doc/document.hpp"
11
12 #include "../../model/world/data.hpp"
13 #include "../../model/world/commands.hpp"
14 #include "../../model/world/columns.hpp"
15 #include "../../model/world/idtable.hpp"
16 #include "../../model/world/idcompletionmanager.hpp"
17
18 #include "../widget/droplineedit.hpp"
19
getId() const20 std::string CSVWorld::InfoCreator::getId() const
21 {
22 std::string id = Misc::StringUtils::lowerCase (mTopic->text().toUtf8().constData());
23
24 std::string unique = QUuid::createUuid().toByteArray().data();
25
26 unique.erase (std::remove (unique.begin(), unique.end(), '-'), unique.end());
27
28 unique = unique.substr (1, unique.size()-2);
29
30 return id + '#' + unique;
31 }
32
configureCreateCommand(CSMWorld::CreateCommand & command) const33 void CSVWorld::InfoCreator::configureCreateCommand (CSMWorld::CreateCommand& command) const
34 {
35 CSMWorld::IdTable& table = dynamic_cast<CSMWorld::IdTable&> (*getData().getTableModel (getCollectionId()));
36
37 CSMWorld::CloneCommand* cloneCommand = dynamic_cast<CSMWorld::CloneCommand*> (&command);
38 if (getCollectionId() == CSMWorld::UniversalId::Type_TopicInfos)
39 {
40 if (!cloneCommand)
41 {
42 command.addValue (table.findColumnIndex(CSMWorld::Columns::ColumnId_Topic), mTopic->text());
43 command.addValue (table.findColumnIndex(CSMWorld::Columns::ColumnId_Rank), -1);
44 command.addValue (table.findColumnIndex(CSMWorld::Columns::ColumnId_Gender), -1);
45 command.addValue (table.findColumnIndex(CSMWorld::Columns::ColumnId_PcRank), -1);
46 }
47 else
48 {
49 cloneCommand->setOverrideValue(table.findColumnIndex(CSMWorld::Columns::ColumnId_Topic), mTopic->text());
50 }
51 }
52 else
53 {
54 if (!cloneCommand)
55 {
56 command.addValue (table.findColumnIndex(CSMWorld::Columns::ColumnId_Journal), mTopic->text());
57 }
58 else
59 cloneCommand->setOverrideValue(table.findColumnIndex(CSMWorld::Columns::ColumnId_Journal), mTopic->text());
60 }
61 }
62
InfoCreator(CSMWorld::Data & data,QUndoStack & undoStack,const CSMWorld::UniversalId & id,CSMWorld::IdCompletionManager & completionManager)63 CSVWorld::InfoCreator::InfoCreator (CSMWorld::Data& data, QUndoStack& undoStack,
64 const CSMWorld::UniversalId& id, CSMWorld::IdCompletionManager& completionManager)
65 : GenericCreator (data, undoStack, id)
66 {
67 // Determine if we're dealing with topics or journals.
68 CSMWorld::ColumnBase::Display displayType = CSMWorld::ColumnBase::Display_Topic;
69 QString labelText = "Topic";
70 if (getCollectionId().getType() == CSMWorld::UniversalId::Type_JournalInfos)
71 {
72 displayType = CSMWorld::ColumnBase::Display_Journal;
73 labelText = "Journal";
74 }
75
76 QLabel *label = new QLabel (labelText, this);
77 insertBeforeButtons (label, false);
78
79 // Add topic/journal ID input with auto-completion.
80 // Only existing topic/journal IDs are accepted so no ID validation is performed.
81 mTopic = new CSVWidget::DropLineEdit(displayType, this);
82 mTopic->setCompleter(completionManager.getCompleter(displayType).get());
83 insertBeforeButtons (mTopic, true);
84
85 setManualEditing (false);
86
87 connect (mTopic, SIGNAL (textChanged (const QString&)), this, SLOT (topicChanged()));
88 connect (mTopic, SIGNAL (returnPressed()), this, SLOT (inputReturnPressed()));
89 }
90
cloneMode(const std::string & originId,const CSMWorld::UniversalId::Type type)91 void CSVWorld::InfoCreator::cloneMode (const std::string& originId,
92 const CSMWorld::UniversalId::Type type)
93 {
94 CSMWorld::IdTable& infoTable =
95 dynamic_cast<CSMWorld::IdTable&> (*getData().getTableModel (getCollectionId()));
96
97 int topicColumn = infoTable.findColumnIndex (
98 getCollectionId().getType()==CSMWorld::UniversalId::Type_TopicInfos ?
99 CSMWorld::Columns::ColumnId_Topic : CSMWorld::Columns::ColumnId_Journal);
100
101 mTopic->setText (
102 infoTable.data (infoTable.getModelIndex (originId, topicColumn)).toString());
103
104 GenericCreator::cloneMode (originId, type);
105 }
106
reset()107 void CSVWorld::InfoCreator::reset()
108 {
109 mTopic->setText ("");
110 GenericCreator::reset();
111 }
112
getErrors() const113 std::string CSVWorld::InfoCreator::getErrors() const
114 {
115 // We ignore errors from GenericCreator here, because they can never happen in an InfoCreator.
116 std::string errors;
117
118 std::string topic = mTopic->text().toUtf8().constData();
119
120 if ((getCollectionId().getType()==CSMWorld::UniversalId::Type_TopicInfos ?
121 getData().getTopics() : getData().getJournals()).searchId (topic)==-1)
122 {
123 errors += "Invalid Topic ID";
124 }
125
126 return errors;
127 }
128
focus()129 void CSVWorld::InfoCreator::focus()
130 {
131 mTopic->setFocus();
132 }
133
topicChanged()134 void CSVWorld::InfoCreator::topicChanged()
135 {
136 update();
137 }
138
makeCreator(CSMDoc::Document & document,const CSMWorld::UniversalId & id) const139 CSVWorld::Creator *CSVWorld::InfoCreatorFactory::makeCreator(CSMDoc::Document& document,
140 const CSMWorld::UniversalId& id) const
141 {
142 return new InfoCreator(document.getData(),
143 document.getUndoStack(),
144 id,
145 document.getIdCompletionManager());
146 }
147