annotate widgets/TransformFinder.cpp @ 424:374b72f5b4bb

* More SelectableLabel and TransformFinder tweaking
author Chris Cannam
date Mon, 29 Sep 2008 15:06:43 +0000
parents 5a55d0683ee5
children 4a5fe5471282
rev   line source
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@424 93 m_timer->start(0);
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@424 150 if (m_upToDateCount < m_sortedResults.size()) {
Chris@417 151
Chris@424 152 int i = m_upToDateCount;
Chris@416 153
Chris@424 154 std::cerr << "sorted size = " << m_sortedResults.size() << std::endl;
Chris@417 155
Chris@416 156 TransformDescription desc =
Chris@424 157 TransformFactory::getInstance()->getTransformDescription
Chris@424 158 (m_sortedResults[i].transform);
Chris@419 159
Chris@419 160 QString labelText;
Chris@424 161 labelText += tr("%1: %2<br><small>")
Chris@424 162 .arg(m_sortedResults[i].score)
Chris@424 163 .arg(XmlExportable::encodeEntities(desc.name));
Chris@424 164
Chris@416 165 labelText += "...";
Chris@416 166 for (TransformFactory::Match::FragmentMap::const_iterator k =
Chris@424 167 m_sortedResults[i].fragments.begin();
Chris@424 168 k != m_sortedResults[i].fragments.end(); ++k) {
Chris@416 169 labelText += k->second;
Chris@416 170 labelText += "... ";
Chris@416 171 }
Chris@416 172 labelText += tr("</small>");
Chris@417 173
Chris@419 174 QString selectedText;
Chris@424 175 selectedText += tr("<b>%1</b><br>")
Chris@424 176 .arg(XmlExportable::encodeEntities(desc.name));
Chris@424 177 selectedText += tr("<small>%1</small>")
Chris@424 178 .arg(XmlExportable::encodeEntities(desc.longDescription));
Chris@419 179
Chris@420 180 selectedText += tr("<ul><small>");
Chris@424 181 selectedText += tr("<li>Plugin type: %1</li>")
Chris@424 182 .arg(XmlExportable::encodeEntities(desc.type));
Chris@424 183 selectedText += tr("<li>Category: %1</li>")
Chris@424 184 .arg(XmlExportable::encodeEntities(desc.category));
Chris@424 185 selectedText += tr("<li>System identifier: %1</li>")
Chris@424 186 .arg(XmlExportable::encodeEntities(desc.identifier));
Chris@420 187 selectedText += tr("</small></ul>");
Chris@419 188
Chris@417 189 if (i >= m_labels.size()) {
Chris@419 190 SelectableLabel *label = new SelectableLabel(m_resultsFrame);
Chris@421 191 m_resultsLayout->addWidget(label);
Chris@420 192 connect(label, SIGNAL(selectionChanged()), this,
Chris@420 193 SLOT(selectedLabelChanged()));
Chris@424 194 connect(label, SIGNAL(doubleClicked()), this,
Chris@424 195 SLOT(accept()));
Chris@421 196 QPalette palette = label->palette();
Chris@421 197 label->setPalette(palette);
Chris@417 198 m_labels.push_back(label);
Chris@417 199 }
Chris@421 200
Chris@420 201 m_labels[i]->setObjectName(desc.identifier);
Chris@423 202 m_labels[i]->setFixedWidth(this->width() - 40);
Chris@419 203 m_labels[i]->setUnselectedText(labelText);
Chris@419 204 m_labels[i]->setSelectedText(selectedText);
Chris@423 205
Chris@424 206 m_labels[i]->setSelected(m_selectedTransform == desc.identifier);
Chris@417 207 m_labels[i]->show();
Chris@417 208
Chris@424 209 ++m_upToDateCount;
Chris@424 210
Chris@424 211 // if (m_upToDateCount == m_sortedResults.size()) {
Chris@424 212 m_resultsFrame->resize(m_resultsFrame->sizeHint());
Chris@424 213 // }
Chris@416 214 }
Chris@416 215 }
Chris@416 216
Chris@420 217 void
Chris@420 218 TransformFinder::selectedLabelChanged()
Chris@420 219 {
Chris@420 220 QObject *s = sender();
Chris@420 221 m_selectedTransform = "";
Chris@420 222 for (int i = 0; i < m_labels.size(); ++i) {
Chris@420 223 if (!m_labels[i]->isVisible()) continue;
Chris@420 224 if (m_labels[i] == s) {
Chris@420 225 if (m_labels[i]->isSelected()) {
Chris@420 226 m_selectedTransform = m_labels[i]->objectName();
Chris@420 227 }
Chris@420 228 } else {
Chris@420 229 if (m_labels[i]->isSelected()) {
Chris@420 230 m_labels[i]->setSelected(false);
Chris@420 231 }
Chris@420 232 }
Chris@420 233 }
Chris@420 234 std::cerr << "selectedLabelChanged: selected transform is now \""
Chris@420 235 << m_selectedTransform.toStdString() << "\"" << std::endl;
Chris@420 236 }
Chris@420 237
Chris@416 238 TransformId
Chris@416 239 TransformFinder::getTransform() const
Chris@416 240 {
Chris@424 241 return m_selectedTransform;
Chris@416 242 }
Chris@416 243