1 /***************************************************************************
2 * This file is part of KWorship. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
5 * KWorship is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
10 * KWorship is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with KWorship. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
21 * @file KwSongdbFilterNode.cpp
22 * @brief A node for filtering songs.
23 * @author James Hogan <james@albanarts.com>
26 #include "KwSongdbFilterNode.h"
27 #include "KwSongdbVersionNode.h"
35 * Constructors + destructor.
38 /// Primary constructor.
39 KwSongdbFilterNode::KwSongdbFilterNode(const KwSongdbFilterLevelList
* filters
, QString label
, KwSongdbNode
* parent
)
40 : KwSongdbNode(parent
)
42 , m_filterLevels(filters
)
48 assert(filters
->size() > 0);
49 m_knownValue
.next
= 0;
54 KwSongdbFilterNode::~KwSongdbFilterNode()
60 * Private constructors
63 /// Primary constructor.
64 KwSongdbFilterNode::KwSongdbFilterNode(KwSongdbFilterNode
* parent
, QString label
, QString knownIdExpression
, int knownId
)
65 : KwSongdbNode(parent
)
67 , m_filterLevels(parent
->m_filterLevels
)
68 , m_currentFilter(parent
->m_currentFilter
+ 1)
72 m_knownValue
.idExpression
= knownIdExpression
;
73 m_knownValue
.idValue
= knownId
;
74 m_knownValue
.next
= &parent
->m_knownValue
;
79 * Associated data access
82 KwSongdbSong
* KwSongdbFilterNode::associatedSong()
84 KnownValue
* val
= &m_knownValue
;
87 if (val
->idExpression
== "`Song`.`id`")
89 return KwSongdb::self()->songById(val
->idValue
);
96 KwSongdbVersion
* KwSongdbFilterNode::associatedSongVersion()
98 // If only the one child, ask it
99 if (getChildCount() == 1)
101 KwSongdbNode
* child
= dynamic_cast<KwSongdbNode
*>(getChild(0));
104 return child
->associatedSongVersion();
114 /// Get data associated with the node.
115 QVariant
KwSongdbFilterNode::getData(int role
, int column
)
117 if (role
== Qt::DisplayRole
)
124 else if (role
== Qt::DecorationRole
)
126 // Use icon of previous filter
127 if (column
== 0 && m_currentFilter
> 0)
129 return (*m_filterLevels
)[m_currentFilter
- 1].icon
;
135 /// Get the number of children.
136 int KwSongdbFilterNode::getChildCount() const
139 if (m_query
->isActive())
141 rows
= m_query
->size();
144 if (m_query
->first())
147 while (m_query
->next())
158 /// Get a child node by index.
159 KwSongdbNode
* KwSongdbFilterNode::_getChild(int index
)
161 bool seekResult
= m_query
->seek(index
);
164 /// @todo implement "end condition"
165 if (m_currentFilter
< m_filterLevels
->size() - 1)
167 return _newNode(m_query
->value(1).toString(),
168 (*m_filterLevels
)[m_currentFilter
].idExpression
, m_query
->value(0).toInt());
172 assert(m_currentFilter
== m_filterLevels
->size() - 1);
173 return _newFinalNode(m_query
->value(1).toString(), m_query
->value(0).toInt(),
174 (*m_filterLevels
)[m_currentFilter
].icon
);
183 /// Get flags for this item.
184 Qt::ItemFlags
KwSongdbFilterNode::getFlags(Qt::ItemFlags defaultFlags
) const
186 Qt::ItemFlags flags
= defaultFlags
;
187 // Only allow dragging if only one final song version within
188 /// @todo improve so it works at 3 levels
189 if (m_currentFilter
== m_filterLevels
->size()-1 && m_query
->size() == 1)
191 flags
|= Qt::ItemIsDragEnabled
;
196 /// Get mime data string for this set of songs.
197 QString
KwSongdbFilterNode::mimeData()
199 // If a single child node, ask that
200 assert(m_currentFilter
== m_filterLevels
->size()-1 && m_query
->size() == 1);
201 return _getChild(0)->mimeData();
204 /// Get a new node of this type.
205 KwSongdbFilterNode
* KwSongdbFilterNode::_newNode(QString label
, QString idExpression
, int idValue
)
207 return new KwSongdbFilterNode(this, label
, idExpression
, idValue
);
210 /// Get a new final node.
211 KwSongdbNode
* KwSongdbFilterNode::_newFinalNode(QString label
, int id
, const QIcon
& icon
)
213 KwSongdbVersionNode
* node
= new KwSongdbVersionNode(this, label
, id
);
223 void KwSongdbFilterNode::setupQuery()
227 // Collect joins and where conditions
229 QStringList whereClauses
;
230 for (int i
= 0; i
<= m_currentFilter
; ++i
)
232 const KwSongdbFilterLevel
& filterI
= m_filterLevels
->at(i
);
233 QStringList::const_iterator it
;
234 for (it
= filterI
.innerJoinClauses
.begin(); it
!= filterI
.innerJoinClauses
.end(); ++it
)
236 innerJoins
+= "INNER JOIN " + (*it
) + " ";
238 whereClauses
<< filterI
.whereClauses
;
240 KnownValue
* knownValue
= &m_knownValue
;
241 while (0 != knownValue
->next
)
243 whereClauses
<< (knownValue
->idExpression
+ " = ?");
244 knownValue
= knownValue
->next
;
247 // Generate the SQL query
248 const KwSongdbFilterLevel
& filterLevel
= m_filterLevels
->at(m_currentFilter
);
249 QString query
= "SELECT " + filterLevel
.idExpression
+ " AS id,"
250 + filterLevel
.labelExpression
+ " AS label "
251 "FROM " + m_filterLevels
->at(0).tableName
+ " ";
253 if (!whereClauses
.empty())
255 query
+= "WHERE " + whereClauses
.join(" AND ") + " ";
257 if (!filterLevel
.orderBy
.empty())
259 query
+= "ORDER BY " + filterLevel
.orderBy
.join(",");
264 m_query
= new QSqlQuery();
265 m_query
->prepare(query
);
266 knownValue
= &m_knownValue
;
267 while (0 != knownValue
->next
)
269 m_query
->addBindValue(knownValue
->idValue
);
270 knownValue
= knownValue
->next
;