1 #include "library/crate/cratefeaturehelper.h"
2 
3 #include <QInputDialog>
4 #include <QLineEdit>
5 
6 #include "library/trackcollection.h"
7 #include "moc_cratefeaturehelper.cpp"
8 
CrateFeatureHelper(TrackCollection * pTrackCollection,UserSettingsPointer pConfig)9 CrateFeatureHelper::CrateFeatureHelper(
10         TrackCollection* pTrackCollection,
11         UserSettingsPointer pConfig)
12         : m_pTrackCollection(pTrackCollection),
13           m_pConfig(pConfig) {
14 }
15 
proposeNameForNewCrate(const QString & initialName) const16 QString CrateFeatureHelper::proposeNameForNewCrate(
17         const QString& initialName) const {
18     DEBUG_ASSERT(!initialName.isEmpty());
19     QString proposedName;
20     int suffixCounter = 0;
21     do {
22         if (suffixCounter++ > 0) {
23             // Append suffix " 2", " 3", ...
24             proposedName = QString("%1 %2").arg(
25                     initialName, QString::number(suffixCounter));
26         } else {
27             proposedName = initialName;
28         }
29     } while (m_pTrackCollection->crates().readCrateByName(proposedName));
30     // Found an unused crate name
31     return proposedName;
32 }
33 
createEmptyCrate()34 CrateId CrateFeatureHelper::createEmptyCrate() {
35     const QString proposedCrateName =
36             proposeNameForNewCrate(tr("New Crate"));
37     Crate newCrate;
38     for (;;) {
39         bool ok = false;
40         auto newName =
41                 QInputDialog::getText(
42                         nullptr,
43                         tr("Create New Crate"),
44                         tr("Enter name for new crate:"),
45                         QLineEdit::Normal,
46                         proposedCrateName,
47                         &ok).trimmed();
48         if (!ok) {
49             return CrateId();
50         }
51         if (newName.isEmpty()) {
52             QMessageBox::warning(
53                     nullptr,
54                     tr("Creating Crate Failed"),
55                     tr("A crate cannot have a blank name."));
56             continue;
57         }
58         if (m_pTrackCollection->crates().readCrateByName(newName)) {
59             QMessageBox::warning(
60                     nullptr,
61                     tr("Creating Crate Failed"),
62                     tr("A crate by that name already exists."));
63             continue;
64         }
65         newCrate.setName(std::move(newName));
66         DEBUG_ASSERT(newCrate.hasName());
67         break;
68     }
69 
70     CrateId newCrateId;
71     if (m_pTrackCollection->insertCrate(newCrate, &newCrateId)) {
72         DEBUG_ASSERT(newCrateId.isValid());
73         newCrate.setId(newCrateId);
74         qDebug() << "Created new crate" << newCrate;
75     } else {
76         DEBUG_ASSERT(!newCrateId.isValid());
77         qWarning() << "Failed to create new crate"
78                 << "->"  << newCrate.getName();
79         QMessageBox::warning(
80                 nullptr,
81                 tr("Creating Crate Failed"),
82                 tr("An unknown error occurred while creating crate: ") + newCrate.getName());
83     }
84     return newCrateId;
85 }
86 
duplicateCrate(const Crate & oldCrate)87 CrateId CrateFeatureHelper::duplicateCrate(const Crate& oldCrate) {
88     const QString proposedCrateName =
89             proposeNameForNewCrate(
90                     QString("%1 %2").arg(
91                             oldCrate.getName(), tr("copy" , "[noun]")));
92     Crate newCrate;
93     for (;;) {
94         bool ok = false;
95         auto newName =
96                 QInputDialog::getText(
97                         nullptr,
98                          tr("Duplicate Crate"),
99                          tr("Enter name for new crate:"),
100                          QLineEdit::Normal,
101                          proposedCrateName,
102                          &ok).trimmed();
103         if (!ok) {
104             return CrateId();
105         }
106         if (newName.isEmpty()) {
107             QMessageBox::warning(
108                     nullptr,
109                     tr("Duplicating Crate Failed"),
110                     tr("A crate cannot have a blank name."));
111             continue;
112         }
113         if (m_pTrackCollection->crates().readCrateByName(newName)) {
114             QMessageBox::warning(
115                     nullptr,
116                     tr("Duplicating Crate Failed"),
117                     tr("A crate by that name already exists."));
118             continue;
119         }
120         newCrate.setName(std::move(newName));
121         DEBUG_ASSERT(newCrate.hasName());
122         break;
123     }
124 
125     CrateId newCrateId;
126     if (m_pTrackCollection->insertCrate(newCrate, &newCrateId)) {
127         DEBUG_ASSERT(newCrateId.isValid());
128         newCrate.setId(newCrateId);
129         qDebug() << "Created new crate" << newCrate;
130         QList<TrackId> trackIds;
131         trackIds.reserve(
132                 m_pTrackCollection->crates().countCrateTracks(oldCrate.getId()));
133         {
134             CrateTrackSelectResult crateTracks(
135                     m_pTrackCollection->crates().selectCrateTracksSorted(oldCrate.getId()));
136             while (crateTracks.next()) {
137                 trackIds.append(crateTracks.trackId());
138             }
139         }
140         if (m_pTrackCollection->addCrateTracks(newCrateId, trackIds)) {
141             qDebug() << "Duplicated crate"
142                 << oldCrate << "->" << newCrate;
143         } else {
144             qWarning() << "Failed to copy tracks from"
145                     << oldCrate << "into" << newCrate;
146         }
147     } else {
148         qWarning() << "Failed to duplicate crate"
149                 << oldCrate << "->" << newCrate.getName();
150         QMessageBox::warning(
151                 nullptr,
152                 tr("Duplicating Crate Failed"),
153                 tr("An unknown error occurred while creating crate: ") + newCrate.getName());
154     }
155     return newCrateId;
156 }
157