mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-14 16:39:57 +00:00
.. introduce concept of configChanged(what) to pass details of what config has been changed .. fixed zones changes to re-read after write to correct the save twice to get changes to zones bug. .. next parts need to spot changes (part 2) and then action appropriately (part 3)
337 lines
11 KiB
C++
337 lines
11 KiB
C++
/*
|
|
* Copyright (c) 2012 Mark Liversedge (liversedge@gmail.com)
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
* Software Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
|
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "SearchBox.h"
|
|
#include "Context.h"
|
|
#include "Tab.h"
|
|
#include "Athlete.h"
|
|
#include "NamedSearch.h"
|
|
#include "RideNavigator.h"
|
|
#include "GcSideBarItem.h"
|
|
#include "AnalysisSidebar.h"
|
|
#include <QToolButton>
|
|
#include <QInputDialog>
|
|
|
|
#include <QStyle>
|
|
#include <QMenu>
|
|
#include <QDebug>
|
|
|
|
SearchBox::SearchBox(Context *context, QWidget *parent, bool nochooser)
|
|
: QLineEdit(parent), context(context), filtered(false), nochooser(nochooser)
|
|
{
|
|
setFixedHeight(21);
|
|
//clear button
|
|
clearButton = new QToolButton(this);
|
|
clearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }");
|
|
QIcon pixmap(":images/toolbar/popbutton.png");
|
|
clearButton->setIcon(QIcon(pixmap));
|
|
clearButton->setIconSize(QSize(12,12));
|
|
clearButton->setCursor(Qt::ArrowCursor);
|
|
clearButton->hide();
|
|
//connect(clearButton, SIGNAL(clicked()), this, SLOT(clear()));
|
|
connect(clearButton, SIGNAL(clicked()), this, SLOT(clearClicked()));
|
|
connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateCloseButton(const QString&)));
|
|
|
|
// make sure its underneath the toggle button
|
|
toolButton = new QToolButton(this);
|
|
toolButton->setFixedSize(QSize(16,16));
|
|
toolButton->setStyleSheet("QToolButton { border: none; padding: 0px; }");
|
|
toolButton->setCursor(Qt::ArrowCursor);
|
|
toolButton->setPopupMode(QToolButton::InstantPopup);
|
|
|
|
dropMenu = new QMenu(this);
|
|
toolButton->setMenu(dropMenu);
|
|
connect(dropMenu, SIGNAL(aboutToShow()), this, SLOT(setMenu()));
|
|
connect(dropMenu, SIGNAL(triggered(QAction*)), this, SLOT(runMenu(QAction*)));
|
|
|
|
// search button
|
|
searchButton = new QToolButton(this);
|
|
QIcon search = iconFromPNG(":images/toolbar/search3.png", false);
|
|
searchButton->setStyleSheet("QToolButton { border: none; padding: 0px; }");
|
|
searchButton->setIcon(search);
|
|
searchButton->setIconSize(QSize(11,11));
|
|
searchButton->setCursor(Qt::ArrowCursor);
|
|
connect(searchButton, SIGNAL(clicked()), this, SLOT(toggleMode()));
|
|
|
|
#ifdef Q_OS_MAC
|
|
setAttribute(Qt::WA_MacShowFocusRect, 0);
|
|
#endif
|
|
setObjectName("SearchBox");
|
|
setPlaceholderText(tr("Search..."));
|
|
mode = Search;
|
|
setDragEnabled(true);
|
|
checkMenu();
|
|
connect(this, SIGNAL(returnPressed()), this, SLOT(searchSubmit()));
|
|
connect(context, SIGNAL(configChanged(qint32)), this, SLOT(configChanged(qint32)));
|
|
|
|
// set colors and curviness
|
|
configChanged(CONFIG_APPEARANCE);
|
|
}
|
|
|
|
void
|
|
SearchBox::configChanged(qint32)
|
|
{
|
|
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
|
QColor color = QPalette().color(QPalette::Highlight);
|
|
|
|
// flat mode has square corners
|
|
if (GCColor::isFlat()) {
|
|
|
|
setStyleSheet(QString( //"QLineEdit { padding-right: %1px; } "
|
|
"QLineEdit#SearchBox {"
|
|
" border-radius: 3px; "
|
|
" border: 1px solid rgba(127,127,127,127);"
|
|
" padding: 0px %1px;"
|
|
"}"
|
|
"QLineEdit#SearchBox:focus {"
|
|
" border-radius: 3px; "
|
|
#ifdef WIN32
|
|
" border: 1px solid rgba(%2,%3,%4,255);"
|
|
#else
|
|
" border: 2px solid rgba(%2,%3,%4,255);"
|
|
#endif
|
|
" padding: 0px %5px;"
|
|
"}"
|
|
).arg(clearButton->sizeHint().width() + frameWidth + 12)
|
|
.arg(color.red()).arg(color.green()).arg(color.blue())
|
|
.arg(clearButton->sizeHint().width() + frameWidth + 12));
|
|
|
|
} else {
|
|
setStyleSheet(QString( //"QLineEdit { padding-right: %1px; } "
|
|
"QLineEdit#SearchBox {"
|
|
" border-radius: 10px; "
|
|
" border: 1px solid rgba(127,127,127,127);"
|
|
" padding: 0px %1px;"
|
|
"}"
|
|
"QLineEdit#SearchBox:focus {"
|
|
" border-radius: 10px; "
|
|
#ifdef WIN32
|
|
" border: 1px solid rgba(%2,%3,%4,255);"
|
|
#else
|
|
" border: 2px solid rgba(%2,%3,%4,255);"
|
|
#endif
|
|
" padding: 0px %5px;"
|
|
"}"
|
|
).arg(clearButton->sizeHint().width() + frameWidth + 12)
|
|
.arg(color.red()).arg(color.green()).arg(color.blue())
|
|
.arg(clearButton->sizeHint().width() + frameWidth + 12));
|
|
|
|
}
|
|
}
|
|
|
|
void SearchBox::resizeEvent(QResizeEvent *)
|
|
{
|
|
QSize sz = clearButton->sizeHint();
|
|
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
|
clearButton->move(rect().right() - frameWidth - sz.width() - 1, 3);
|
|
searchButton->move(5, 3);
|
|
#ifndef Q_OS_MAC
|
|
toolButton->move(15, 0);
|
|
#else
|
|
toolButton->move(13, 0);
|
|
#endif
|
|
|
|
//container->move(rect().left(), rect().bottom() + 3); // named dialog...
|
|
checkMenu();
|
|
}
|
|
|
|
void SearchBox::toggleMode()
|
|
{
|
|
clear(); // clear whatever is there first
|
|
if (mode == Search) setMode(Filter);
|
|
else setMode(Search);
|
|
}
|
|
|
|
void SearchBox::setMode(SearchBoxMode mode)
|
|
{
|
|
switch (mode) {
|
|
|
|
case Filter:
|
|
{
|
|
QIcon filter = iconFromPNG(":images/toolbar/filter3.png", false);
|
|
searchButton->setIcon(filter);
|
|
searchButton->setIconSize(QSize(11,11));
|
|
setPlaceholderText(tr("Filter..."));
|
|
}
|
|
break;
|
|
|
|
case Search:
|
|
default:
|
|
{
|
|
QIcon search = iconFromPNG(":images/toolbar/search3.png", false);
|
|
searchButton->setIcon(search);
|
|
searchButton->setIconSize(QSize(11,11));
|
|
setPlaceholderText(tr("Search..."));
|
|
}
|
|
break;
|
|
}
|
|
this->mode = mode;
|
|
}
|
|
|
|
void SearchBox::updateCloseButton(const QString& text)
|
|
{
|
|
if (clearButton->isVisible() && text.isEmpty()) mode == Search ? clearQuery() : clearFilter();
|
|
clearButton->setVisible(!text.isEmpty());
|
|
|
|
//REMOVED SINCE TOO HEAVY NOW AFFECTS CHARTS TOO
|
|
//if (mode == Search) searchSubmit(); // only do search as you type in search mode
|
|
|
|
setGood(); // if user changing then don't stay red - wait till resubmitted
|
|
checkMenu();
|
|
}
|
|
|
|
void SearchBox::searchSubmit()
|
|
{
|
|
// return hit / key pressed
|
|
if (text() != "") {
|
|
filtered = true;
|
|
mode == Search ? submitQuery(text()) : submitFilter(text());
|
|
}
|
|
}
|
|
|
|
void SearchBox::clearClicked()
|
|
{
|
|
setText("");
|
|
filtered = false;
|
|
//mode == Search ? clearQuery() : clearFilter();
|
|
setGood();
|
|
}
|
|
|
|
void SearchBox::checkMenu()
|
|
{
|
|
if (context->athlete->namedSearches->getList().count() || text() != "") toolButton->show();
|
|
else toolButton->hide();
|
|
}
|
|
|
|
void SearchBox::setMenu()
|
|
{
|
|
dropMenu->clear();
|
|
if (text() != "") dropMenu->addAction(tr("Add to Named Filters"));
|
|
if (context->athlete->namedSearches->getList().count()) {
|
|
if (text() != "") dropMenu->addSeparator();
|
|
foreach(NamedSearch x, context->athlete->namedSearches->getList()) {
|
|
dropMenu->addAction(x.name);
|
|
}
|
|
dropMenu->addSeparator();
|
|
dropMenu->addAction(tr("Manage Filters"));
|
|
}
|
|
if (!nochooser) dropMenu->addAction(tr("Column Chooser"));
|
|
}
|
|
|
|
void SearchBox::runMenu(QAction *x)
|
|
{
|
|
// just qdebug for now
|
|
if (x->text() == tr("Add to Named Filters")) addNamed();
|
|
else if (x->text() == tr("Manage Filters")) {
|
|
|
|
EditNamedSearches *editor = new EditNamedSearches(this, context);
|
|
editor->move(QCursor::pos()-QPoint(230,-5));
|
|
editor->show();
|
|
|
|
} else if (x->text() == tr("Column Chooser")) {
|
|
|
|
ColumnChooser *selector = new ColumnChooser(context->tab->rideNavigator()->logicalHeadings);
|
|
selector->show();
|
|
|
|
} else {
|
|
NamedSearch get = context->athlete->namedSearches->get(x->text());
|
|
if (get.name == x->text()) {
|
|
setMode(static_cast<SearchBox::SearchBoxMode>(get.type));
|
|
setText(get.text);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SearchBox::setBad(QStringList errors)
|
|
{
|
|
QPalette pal;
|
|
pal.setColor(QPalette::Text, Qt::red);
|
|
setPalette(pal);
|
|
|
|
setToolTip(errors.join(tr(" and ")));
|
|
}
|
|
|
|
void SearchBox::setGood()
|
|
{
|
|
QPalette pal;
|
|
pal.setColor(QPalette::Text, Qt::black);
|
|
setPalette(pal);
|
|
|
|
setToolTip("");
|
|
}
|
|
|
|
|
|
|
|
// Drag and drop columns from the chooser...
|
|
void
|
|
SearchBox::dragEnterEvent(QDragEnterEvent *event)
|
|
{
|
|
if (event->mimeData()->data("application/x-columnchooser") != "")
|
|
event->acceptProposedAction(); // whatever you wanna drop we will try and process!
|
|
else
|
|
event->ignore();
|
|
}
|
|
|
|
void
|
|
SearchBox::dropEvent(QDropEvent *event)
|
|
{
|
|
QByteArray rawData = event->mimeData()->data("application/x-columnchooser");
|
|
QDataStream stream(&rawData, QIODevice::ReadOnly);
|
|
stream.setVersion(QDataStream::Qt_4_6);
|
|
QString name;
|
|
stream >> name;
|
|
|
|
// fugly, but it works for BikeScore with the (TM) in it... so...
|
|
// independent of Latin1 or UTF-8 coming from "Column Chooser" the "TM" special sign is not recognized by the parser,
|
|
// so strip the "TM" off for this case (only)
|
|
if (name.startsWith("BikeScore")) name = QString("BikeScore");
|
|
|
|
// Always use the "internalNames" in Filter expressions
|
|
SpecialFields sp;
|
|
name = sp.internalName(name);
|
|
|
|
// we do very little to the name, just space to _ and lower case it for now...
|
|
name.replace(' ', '_');
|
|
insert(name);
|
|
}
|
|
|
|
void
|
|
SearchBox::setText(QString s)
|
|
{
|
|
QLineEdit::setText(s);
|
|
if (s != "") searchSubmit();
|
|
}
|
|
|
|
void
|
|
SearchBox::addNamed()
|
|
{
|
|
bool ok;
|
|
QString text = QInputDialog::getText(this, tr("Add new search"),
|
|
tr("Name:"), QLineEdit::Normal, QString(""), &ok);
|
|
|
|
if (ok && !text.isEmpty()) {
|
|
NamedSearch x;
|
|
x.name = text;
|
|
x.text = this->text();
|
|
x.type = mode;
|
|
x.count = 0;
|
|
context->athlete->namedSearches->getList().append(x);
|
|
context->athlete->namedSearches->write();
|
|
}
|
|
}
|