Chris@416
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@416
|
2
|
Chris@416
|
3 /*
|
Chris@416
|
4 Sonic Visualiser
|
Chris@416
|
5 An audio file viewer and annotation editor.
|
Chris@416
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@416
|
7 This file copyright 2008 QMUL.
|
Chris@416
|
8
|
Chris@416
|
9 This program is free software; you can redistribute it and/or
|
Chris@416
|
10 modify it under the terms of the GNU General Public License as
|
Chris@416
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@416
|
12 License, or (at your option) any later version. See the file
|
Chris@416
|
13 COPYING included with this distribution for more information.
|
Chris@416
|
14 */
|
Chris@416
|
15
|
Chris@416
|
16 #include "TransformFinder.h"
|
Chris@416
|
17
|
Chris@424
|
18 #include "base/XmlExportable.h"
|
Chris@416
|
19 #include "transform/TransformFactory.h"
|
Chris@424
|
20 #include "SelectableLabel.h"
|
Chris@416
|
21
|
Chris@421
|
22 #include <QVBoxLayout>
|
Chris@416
|
23 #include <QGridLayout>
|
Chris@416
|
24 #include <QLineEdit>
|
Chris@416
|
25 #include <QLabel>
|
Chris@416
|
26 #include <QDialogButtonBox>
|
Chris@416
|
27 #include <QScrollArea>
|
Chris@421
|
28 #include <QApplication>
|
Chris@423
|
29 #include <QDesktopWidget>
|
Chris@424
|
30 #include <QTimer>
|
Chris@421
|
31
|
Chris@416
|
32 TransformFinder::TransformFinder(QWidget *parent) :
|
Chris@417
|
33 QDialog(parent),
|
Chris@417
|
34 m_resultsFrame(0),
|
Chris@417
|
35 m_resultsLayout(0)
|
Chris@416
|
36 {
|
Chris@416
|
37 setWindowTitle(tr("Find a Transform"));
|
Chris@416
|
38
|
Chris@416
|
39 QGridLayout *mainGrid = new QGridLayout;
|
Chris@421
|
40 mainGrid->setVerticalSpacing(0);
|
Chris@416
|
41 setLayout(mainGrid);
|
Chris@416
|
42
|
Chris@416
|
43 mainGrid->addWidget(new QLabel(tr("Find:")), 0, 0);
|
Chris@416
|
44
|
Chris@416
|
45 QLineEdit *searchField = new QLineEdit;
|
Chris@416
|
46 mainGrid->addWidget(searchField, 0, 1);
|
Chris@416
|
47 connect(searchField, SIGNAL(textChanged(const QString &)),
|
Chris@416
|
48 this, SLOT(searchTextChanged(const QString &)));
|
Chris@416
|
49
|
Chris@416
|
50 m_resultsScroll = new QScrollArea;
|
Chris@420
|
51 // m_resultsScroll->setWidgetResizable(true);
|
Chris@416
|
52 mainGrid->addWidget(m_resultsScroll, 1, 0, 1, 2);
|
Chris@416
|
53 mainGrid->setRowStretch(1, 10);
|
Chris@416
|
54
|
Chris@416
|
55 QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok |
|
Chris@416
|
56 QDialogButtonBox::Cancel);
|
Chris@416
|
57 mainGrid->addWidget(bb, 2, 0, 1, 2);
|
Chris@416
|
58 connect(bb, SIGNAL(accepted()), this, SLOT(accept()));
|
Chris@416
|
59 connect(bb, SIGNAL(rejected()), this, SLOT(reject()));
|
Chris@421
|
60 if (!m_resultsLayout) {
|
Chris@421
|
61 std::cerr << "creating frame & layout" << std::endl;
|
Chris@421
|
62 m_resultsFrame = new QWidget;
|
Chris@421
|
63 QPalette palette = m_resultsFrame->palette();
|
Chris@421
|
64 palette.setColor(QPalette::Window, palette.color(QPalette::Base));
|
Chris@421
|
65 m_resultsFrame->setPalette(palette);
|
Chris@421
|
66 m_resultsScroll->setPalette(palette);
|
Chris@421
|
67 m_resultsLayout = new QVBoxLayout;
|
Chris@423
|
68 m_resultsLayout->setSpacing(0);
|
Chris@423
|
69 m_resultsLayout->setContentsMargins(0, 0, 0, 0);
|
Chris@421
|
70 m_resultsFrame->setLayout(m_resultsLayout);
|
Chris@421
|
71 m_resultsScroll->setWidget(m_resultsFrame);
|
Chris@421
|
72 m_resultsFrame->show();
|
Chris@421
|
73 }
|
Chris@416
|
74
|
Chris@423
|
75 QDesktopWidget *desktop = QApplication::desktop();
|
Chris@423
|
76 QRect available = desktop->availableGeometry();
|
Chris@423
|
77
|
Chris@423
|
78 int width = available.width() / 2;
|
Chris@423
|
79 int height = available.height() / 2;
|
Chris@423
|
80 if (height < 450) {
|
Chris@423
|
81 if (available.height() > 500) height = 450;
|
Chris@423
|
82 }
|
Chris@423
|
83 if (width < 600) {
|
Chris@423
|
84 if (available.width() > 650) width = 600;
|
Chris@423
|
85 }
|
Chris@423
|
86
|
Chris@423
|
87 resize(width, height);
|
Chris@423
|
88 raise();
|
Chris@424
|
89
|
Chris@424
|
90 m_upToDateCount = 0;
|
Chris@424
|
91 m_timer = new QTimer(this);
|
Chris@424
|
92 connect(m_timer, SIGNAL(timeout()), this, SLOT(timeout()));
|
Chris@425
|
93 m_timer->start(30);
|
Chris@416
|
94 }
|
Chris@416
|
95
|
Chris@416
|
96 TransformFinder::~TransformFinder()
|
Chris@416
|
97 {
|
Chris@416
|
98 }
|
Chris@416
|
99
|
Chris@416
|
100 void
|
Chris@416
|
101 TransformFinder::searchTextChanged(const QString &text)
|
Chris@416
|
102 {
|
Chris@416
|
103 std::cerr << "text is " << text.toStdString() << std::endl;
|
Chris@424
|
104 m_newSearchText = text;
|
Chris@424
|
105 }
|
Chris@416
|
106
|
Chris@424
|
107 void
|
Chris@424
|
108 TransformFinder::timeout()
|
Chris@424
|
109 {
|
Chris@424
|
110 int maxResults = 40;
|
Chris@416
|
111
|
Chris@424
|
112 if (m_newSearchText != "") {
|
Chris@416
|
113
|
Chris@424
|
114 QString text = m_newSearchText;
|
Chris@424
|
115 m_newSearchText = "";
|
Chris@424
|
116
|
Chris@424
|
117 QStringList keywords = text.split(' ', QString::SkipEmptyParts);
|
Chris@424
|
118 TransformFactory::SearchResults results =
|
Chris@424
|
119 TransformFactory::getInstance()->search(keywords);
|
Chris@424
|
120
|
Chris@424
|
121 std::cerr << results.size() << " result(s)..." << std::endl;
|
Chris@424
|
122
|
Chris@424
|
123 std::set<TransformFactory::Match> sorted;
|
Chris@424
|
124 sorted.clear();
|
Chris@424
|
125 for (TransformFactory::SearchResults::const_iterator j = results.begin();
|
Chris@424
|
126 j != results.end(); ++j) {
|
Chris@424
|
127 sorted.insert(j->second);
|
Chris@424
|
128 }
|
Chris@424
|
129
|
Chris@424
|
130 m_sortedResults.clear();
|
Chris@424
|
131 for (std::set<TransformFactory::Match>::const_iterator j = sorted.end();
|
Chris@424
|
132 j != sorted.begin(); ) {
|
Chris@424
|
133 --j;
|
Chris@424
|
134 m_sortedResults.push_back(*j);
|
Chris@424
|
135 if (m_sortedResults.size() == maxResults) break;
|
Chris@424
|
136 }
|
Chris@424
|
137
|
Chris@424
|
138 if (m_sortedResults.empty()) m_selectedTransform = "";
|
Chris@424
|
139 else m_selectedTransform = m_sortedResults.begin()->transform;
|
Chris@424
|
140
|
Chris@424
|
141 m_upToDateCount = 0;
|
Chris@424
|
142
|
Chris@424
|
143 for (int j = m_labels.size(); j > m_sortedResults.size(); ) {
|
Chris@424
|
144 m_labels[--j]->hide();
|
Chris@424
|
145 }
|
Chris@424
|
146
|
Chris@424
|
147 return;
|
Chris@416
|
148 }
|
Chris@416
|
149
|
Chris@425
|
150 if (m_upToDateCount >= m_sortedResults.size()) return;
|
Chris@425
|
151
|
Chris@425
|
152 while (m_upToDateCount < m_sortedResults.size()) {
|
Chris@417
|
153
|
Chris@424
|
154 int i = m_upToDateCount;
|
Chris@416
|
155
|
Chris@424
|
156 std::cerr << "sorted size = " << m_sortedResults.size() << std::endl;
|
Chris@417
|
157
|
Chris@416
|
158 TransformDescription desc =
|
Chris@424
|
159 TransformFactory::getInstance()->getTransformDescription
|
Chris@424
|
160 (m_sortedResults[i].transform);
|
Chris@419
|
161
|
Chris@419
|
162 QString labelText;
|
Chris@425
|
163 labelText += tr("%1<br><small>")
|
Chris@424
|
164 .arg(XmlExportable::encodeEntities(desc.name));
|
Chris@424
|
165
|
Chris@416
|
166 labelText += "...";
|
Chris@416
|
167 for (TransformFactory::Match::FragmentMap::const_iterator k =
|
Chris@424
|
168 m_sortedResults[i].fragments.begin();
|
Chris@424
|
169 k != m_sortedResults[i].fragments.end(); ++k) {
|
Chris@416
|
170 labelText += k->second;
|
Chris@416
|
171 labelText += "... ";
|
Chris@416
|
172 }
|
Chris@416
|
173 labelText += tr("</small>");
|
Chris@417
|
174
|
Chris@419
|
175 QString selectedText;
|
Chris@424
|
176 selectedText += tr("<b>%1</b><br>")
|
Chris@424
|
177 .arg(XmlExportable::encodeEntities(desc.name));
|
Chris@424
|
178 selectedText += tr("<small>%1</small>")
|
Chris@424
|
179 .arg(XmlExportable::encodeEntities(desc.longDescription));
|
Chris@419
|
180
|
Chris@420
|
181 selectedText += tr("<ul><small>");
|
Chris@424
|
182 selectedText += tr("<li>Plugin type: %1</li>")
|
Chris@424
|
183 .arg(XmlExportable::encodeEntities(desc.type));
|
Chris@424
|
184 selectedText += tr("<li>Category: %1</li>")
|
Chris@424
|
185 .arg(XmlExportable::encodeEntities(desc.category));
|
Chris@424
|
186 selectedText += tr("<li>System identifier: %1</li>")
|
Chris@424
|
187 .arg(XmlExportable::encodeEntities(desc.identifier));
|
Chris@420
|
188 selectedText += tr("</small></ul>");
|
Chris@419
|
189
|
Chris@417
|
190 if (i >= m_labels.size()) {
|
Chris@419
|
191 SelectableLabel *label = new SelectableLabel(m_resultsFrame);
|
Chris@421
|
192 m_resultsLayout->addWidget(label);
|
Chris@420
|
193 connect(label, SIGNAL(selectionChanged()), this,
|
Chris@420
|
194 SLOT(selectedLabelChanged()));
|
Chris@424
|
195 connect(label, SIGNAL(doubleClicked()), this,
|
Chris@424
|
196 SLOT(accept()));
|
Chris@421
|
197 QPalette palette = label->palette();
|
Chris@421
|
198 label->setPalette(palette);
|
Chris@417
|
199 m_labels.push_back(label);
|
Chris@417
|
200 }
|
Chris@421
|
201
|
Chris@420
|
202 m_labels[i]->setObjectName(desc.identifier);
|
Chris@423
|
203 m_labels[i]->setFixedWidth(this->width() - 40);
|
Chris@419
|
204 m_labels[i]->setUnselectedText(labelText);
|
Chris@425
|
205
|
Chris@425
|
206 // std::cerr << "selected text: " << selectedText.toStdString() << std::endl;
|
Chris@419
|
207 m_labels[i]->setSelectedText(selectedText);
|
Chris@423
|
208
|
Chris@424
|
209 m_labels[i]->setSelected(m_selectedTransform == desc.identifier);
|
Chris@425
|
210
|
Chris@425
|
211 if (!m_labels[i]->isVisible()) m_labels[i]->show();
|
Chris@417
|
212
|
Chris@424
|
213 ++m_upToDateCount;
|
Chris@424
|
214
|
Chris@425
|
215 if (i == 0) break;
|
Chris@416
|
216 }
|
Chris@425
|
217
|
Chris@425
|
218 m_resultsFrame->resize(m_resultsFrame->sizeHint());
|
Chris@416
|
219 }
|
Chris@416
|
220
|
Chris@420
|
221 void
|
Chris@420
|
222 TransformFinder::selectedLabelChanged()
|
Chris@420
|
223 {
|
Chris@420
|
224 QObject *s = sender();
|
Chris@420
|
225 m_selectedTransform = "";
|
Chris@420
|
226 for (int i = 0; i < m_labels.size(); ++i) {
|
Chris@420
|
227 if (!m_labels[i]->isVisible()) continue;
|
Chris@420
|
228 if (m_labels[i] == s) {
|
Chris@420
|
229 if (m_labels[i]->isSelected()) {
|
Chris@420
|
230 m_selectedTransform = m_labels[i]->objectName();
|
Chris@420
|
231 }
|
Chris@420
|
232 } else {
|
Chris@420
|
233 if (m_labels[i]->isSelected()) {
|
Chris@420
|
234 m_labels[i]->setSelected(false);
|
Chris@420
|
235 }
|
Chris@420
|
236 }
|
Chris@420
|
237 }
|
Chris@420
|
238 std::cerr << "selectedLabelChanged: selected transform is now \""
|
Chris@420
|
239 << m_selectedTransform.toStdString() << "\"" << std::endl;
|
Chris@420
|
240 }
|
Chris@420
|
241
|
Chris@416
|
242 TransformId
|
Chris@416
|
243 TransformFinder::getTransform() const
|
Chris@416
|
244 {
|
Chris@424
|
245 return m_selectedTransform;
|
Chris@416
|
246 }
|
Chris@416
|
247
|