]> cloud.milkyroute.net Git - dolphin.git/blob - src/search/searchcriterionselector.cpp
don't forget to hide the value-widget again, if e. g. "Any" from "Date:" has been...
[dolphin.git] / src / search / searchcriterionselector.cpp
1 /***************************************************************************
2 * Copyright (C) 2009 by Adam Kidder <thekidder@gmail.com> *
3 * Copyright (C) 2009 by Peter Penz <peter.penz@gmx.at> *
4 * *
5 * This program 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. *
9 * *
10 * This program 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. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
19 ***************************************************************************/
20
21 #include "searchcriterionselector.h"
22
23 #include "searchcriterionvalue.h"
24
25 #include <QComboBox>
26 #include <QHBoxLayout>
27 #include <QList>
28 #include <QPushButton>
29
30 #include <kicon.h>
31 #include <klocale.h>
32
33 SearchCriterionSelector::SearchCriterionSelector(Type type, QWidget* parent) :
34 QWidget(parent),
35 m_layout(0),
36 m_descriptionsBox(0),
37 m_comparatorBox(0),
38 m_valueWidget(0),
39 m_removeButton(0),
40 m_descriptions()
41 {
42 m_descriptionsBox = new QComboBox(this);
43
44 m_comparatorBox = new QComboBox(this);
45 m_comparatorBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
46
47 createDescriptions();
48 const int index = static_cast<int>(type);
49 m_descriptionsBox->setCurrentIndex(index);
50
51 QWidget* filler = new QWidget(this);
52 filler->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
53
54 m_removeButton = new QPushButton(this);
55 m_removeButton->setIcon(KIcon("list-remove"));
56 m_removeButton->setToolTip(i18nc("@info", "Remove search option"));
57 m_removeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
58 connect(m_removeButton, SIGNAL(clicked()), this, SIGNAL(removeCriterion()));
59
60 m_layout = new QHBoxLayout(this);
61 m_layout->setMargin(0);
62 m_layout->addWidget(m_removeButton);
63 m_layout->addWidget(m_descriptionsBox);
64 m_layout->addWidget(m_comparatorBox);
65 m_layout->addWidget(filler);
66
67 setLayout(m_layout);
68
69 slotDescriptionChanged(index);
70 connect(m_descriptionsBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotDescriptionChanged(int)));
71 }
72
73 SearchCriterionSelector::~SearchCriterionSelector()
74 {
75 }
76
77 QString SearchCriterionSelector::toString() const
78 {
79 if (m_valueWidget == 0) {
80 return QString();
81 }
82
83 const int descIndex = m_descriptionsBox->currentIndex();
84 const SearchCriterionDescription& descr = m_descriptions[descIndex];
85
86 const int compIndex = m_comparatorBox->currentIndex();
87 const SearchCriterionDescription::Comparator& comp = descr.comparators()[compIndex];
88 if (comp.operation.isEmpty()) {
89 return QString();
90 }
91
92 QString criterion = comp.prefix + descr.identifier() + comp.operation;
93 if (!m_valueWidget->value().isEmpty()) {
94 const QString value = m_valueWidget->value();
95 if (value.contains(' ')) {
96 criterion += '"' + value + '"';
97 } else {
98 // Don't surround the value by " if no space is part of the value.
99 // This increases the readability of the search-URL.
100 criterion += value;
101 }
102 }
103 return criterion;
104 }
105
106 void SearchCriterionSelector::slotDescriptionChanged(int index)
107 {
108 if (m_valueWidget != 0) {
109 m_valueWidget->hide();
110 m_layout->removeWidget(m_valueWidget);
111 m_valueWidget = 0;
112 // the value widget is obtained by the Search Criterion
113 // Selector instance and may not get deleted
114 }
115
116 // add comparator items
117 disconnect(m_comparatorBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotComparatorChanged(int)));
118 m_comparatorBox->clear();
119
120 const SearchCriterionDescription& description = m_descriptions[index];
121 foreach (const SearchCriterionDescription::Comparator& comp, description.comparators()) {
122 m_comparatorBox->addItem(comp.name);
123 }
124
125 // add value widget
126 m_valueWidget = description.valueWidget();
127 m_layout->insertWidget(3, m_valueWidget);
128
129 m_comparatorBox->setCurrentIndex(0);
130 slotComparatorChanged(0);
131 connect(m_comparatorBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotComparatorChanged(int)));
132 }
133
134 void SearchCriterionSelector::slotComparatorChanged(int index)
135 {
136 Q_ASSERT(index >= 0);
137
138 // only show the value widget if an operation is defined by the comparator
139 const int descIndex = m_descriptionsBox->currentIndex();
140 const SearchCriterionDescription& descr = m_descriptions[descIndex];
141 const SearchCriterionDescription::Comparator& comp = descr.comparators()[index];
142
143 m_valueWidget->initializeValue(comp.autoValueType);
144 // only show the value widget, if an operation is defined
145 // and no automatic calculation is provided
146 m_valueWidget->setVisible(!comp.operation.isEmpty() && comp.autoValueType.isEmpty());
147
148 emit criterionChanged();
149 }
150
151 void SearchCriterionSelector::createDescriptions()
152 {
153 Q_ASSERT(m_descriptionsBox != 0);
154 Q_ASSERT(m_comparatorBox != 0);
155
156 // TODO: maybe this creation should be forwarded to a factory if
157 // the number of items increases in future
158 QList<SearchCriterionDescription::Comparator> defaultComps;
159 defaultComps.append(SearchCriterionDescription::Comparator(i18nc("@label", "Greater Than"), ">", "+"));
160 defaultComps.append(SearchCriterionDescription::Comparator(i18nc("@label", "Greater Than or Equal to"), ">=", "+"));
161 defaultComps.append(SearchCriterionDescription::Comparator(i18nc("@label", "Less Than"), "<", "+"));
162 defaultComps.append(SearchCriterionDescription::Comparator(i18nc("@label", "Less Than or Equal to"), "<=", "+"));
163
164 // add "Date" description
165 QList<SearchCriterionDescription::Comparator> dateComps;
166 dateComps.append(SearchCriterionDescription::Comparator(i18nc("@label", "Anytime")));
167 dateComps.append(SearchCriterionDescription::Comparator(i18nc("@label", "Today"), ":", "+", "today"));
168 dateComps.append(SearchCriterionDescription::Comparator(i18nc("@label", "This Week"), ">=", "+", "thisWeek"));
169 dateComps.append(SearchCriterionDescription::Comparator(i18nc("@label", "This Month"), ">=", "+", "thisMonth"));
170 dateComps.append(SearchCriterionDescription::Comparator(i18nc("@label", "This Year"), ">=", "+", "thisYear"));
171 foreach (const SearchCriterionDescription::Comparator& comp, defaultComps) {
172 dateComps.append(comp);
173 }
174
175 DateValue* dateValue = new DateValue(this);
176 dateValue->hide();
177 SearchCriterionDescription date(i18nc("@label", "Date:"),
178 "lastModified",
179 dateComps,
180 dateValue);
181 Q_ASSERT(static_cast<int>(SearchCriterionSelector::Date) == 0);
182 m_descriptions.append(date);
183
184 // add "Size" description
185 QList<SearchCriterionDescription::Comparator> sizeComps = defaultComps;
186 sizeComps.insert(0, SearchCriterionDescription::Comparator(i18nc("@label Any (file size)", "Any")));
187
188 SizeValue* sizeValue = new SizeValue(this);
189 sizeValue->hide();
190 SearchCriterionDescription size(i18nc("@label", "Size:"),
191 "contentSize",
192 sizeComps,
193 sizeValue);
194 Q_ASSERT(static_cast<int>(SearchCriterionSelector::Size) == 1);
195 m_descriptions.append(size);
196
197 // add "Tag" description
198 QList<SearchCriterionDescription::Comparator> tagComps;
199 tagComps.append(SearchCriterionDescription::Comparator(i18nc("@label All (tags)", "All")));
200 tagComps.append(SearchCriterionDescription::Comparator(i18nc("@label", "Equal to"), ":", "+"));
201 tagComps.append(SearchCriterionDescription::Comparator(i18nc("@label", "Not Equal to"), ":", "-"));
202
203 TagValue* tagValue = new TagValue(this);
204 tagValue->hide();
205 SearchCriterionDescription tag(i18nc("@label", "Tag:"),
206 "tag",
207 tagComps,
208 tagValue);
209 Q_ASSERT(static_cast<int>(SearchCriterionSelector::Tag) == 2);
210 m_descriptions.append(tag);
211
212 // add "Rating" description
213 QList<SearchCriterionDescription::Comparator> ratingComps = defaultComps;
214 ratingComps.insert(0, SearchCriterionDescription::Comparator(i18nc("@label Any (rating)", "Any")));
215
216 RatingValue* ratingValue = new RatingValue(this);
217 ratingValue->hide();
218 SearchCriterionDescription rating(i18nc("@label", "Rating:"),
219 "rating",
220 ratingComps,
221 ratingValue);
222 Q_ASSERT(static_cast<int>(SearchCriterionSelector::Rating) == 3);
223 m_descriptions.append(rating);
224
225 // add all descriptions to the combo box and connect the value widgets
226 int i = 0;
227 foreach (const SearchCriterionDescription& desc, m_descriptions) {
228 m_descriptionsBox->addItem(desc.name(), i);
229 connect(desc.valueWidget(), SIGNAL(valueChanged(QString)), this, SIGNAL(criterionChanged()));
230 ++i;
231 }
232 }
233
234 #include "searchcriterionselector.moc"