Merge pull request #1715 from andreituicu/45666

Accessibility for Search (goto) dialog.
This commit is contained in:
Werner Schweer 2015-02-02 10:43:28 +01:00
commit 9d0c16afee
7 changed files with 215 additions and 70 deletions

View file

@ -263,7 +263,7 @@ add_executable ( ${ExecutableName}
resourceManager.cpp downloadUtils.cpp
textcursor.cpp continuouspanel.cpp accessibletoolbutton.cpp scoreaccessibility.cpp
startcenter.cpp scoreBrowser.cpp scorePreview.cpp scoreInfo.cpp
logindialog.cpp loginmanager.cpp uploadscoredialog.cpp breaksdialog.cpp
logindialog.cpp loginmanager.cpp uploadscoredialog.cpp breaksdialog.cpp searchComboBox.cpp
${OMR_FILES}
${AUDIO}

View file

@ -98,6 +98,7 @@
#include "fluid/fluid.h"
#include "qmlplugin.h"
#include "accessibletoolbutton.h"
#include "searchComboBox.h"
#include "startcenter.h"
@ -4373,17 +4374,6 @@ void MuseScore::updateDrumTools()
_drumTools->updateDrumset();
}
//---------------------------------------------------------
// searchTextChanged
//---------------------------------------------------------
void MuseScore::searchTextChanged(const QString& s)
{
if (cv == 0)
return;
cv->search(s);
}
//---------------------------------------------------------
// endSearch
//---------------------------------------------------------
@ -4417,9 +4407,7 @@ void MuseScore::showSearchDialog()
searchDialogLayout->addWidget(new QLabel(tr("Go To: ")));
searchCombo = new QComboBox;
searchCombo->setEditable(true);
searchCombo->setInsertPolicy(QComboBox::InsertAtTop);
searchCombo = new SearchComboBox;
searchDialogLayout->addWidget(searchCombo);
searchDialogLayout->addStretch(10);
@ -4429,9 +4417,6 @@ void MuseScore::showSearchDialog()
// does not work: connect(searchCombo->lineEdit(), SIGNAL(returnPressed()), SLOT(endSearch()));
connect(searchCombo->lineEdit(), SIGNAL(editingFinished()), SLOT(endSearch()));
connect(searchCombo, SIGNAL(editTextChanged(const QString&)),
SLOT(searchTextChanged(const QString&)));
}
searchCombo->clearEditText();
@ -4504,7 +4489,7 @@ int main(int argc, char* av[])
QCoreApplication::setOrganizationDomain("musescore.org");
QCoreApplication::setApplicationName("MuseScoreDevelopment");
QAccessible::installFactory(AccessibleScoreView::ScoreViewFactory);
QAccessible::installFactory(AccessibleSearchBox::SearchBoxFactory);
Q_INIT_RESOURCE(zita);
#ifndef Q_OS_MAC

View file

@ -468,7 +468,6 @@ class MuseScore : public QMainWindow, public MuseScoreCore {
virtual void cmd(QAction* a);
void dirtyChanged(Score*);
void setPos(int tick);
void searchTextChanged(const QString& s);
void pluginTriggered(int);
void handleMessage(const QString& message);
void setCurrentScoreView(ScoreView*);

View file

@ -5313,75 +5313,42 @@ void ScoreView::selectMeasure(int n)
}
}
//---------------------------------------------------------
// search
//---------------------------------------------------------
void ScoreView::search(const QString& s)
{
bool ok;
int n = s.toInt(&ok);
if (ok && n >= 0)
searchMeasure(n);
else {
if (s.size() >= 2 && s[0].toLower() == 'p' && s[1].isNumber()) {
n = s.mid(1).toInt(&ok);
if (ok && n >= 0)
searchPage(n);
}
else {
//search rehearsal marks
QString ss = s.toLower();
bool found = false;
for (Segment* seg = score()->firstSegment(); seg; seg = seg->next1(Segment::Type::ChordRest)) {
for (Element* e : seg->annotations()){
if (e->type() == Element::Type::REHEARSAL_MARK) {
RehearsalMark* rm = static_cast<RehearsalMark*>(e);
QString rms = rm->text().toLower();
if (rms.startsWith(ss)) {
gotoMeasure(seg->measure());
found = true;
break;
}
}
}
if (found)
break;
}
}
}
}
//---------------------------------------------------------
// searchPage
//---------------------------------------------------------
void ScoreView::searchPage(int n)
bool ScoreView::searchPage(int n)
{
bool result = true;
n -= score()->pageNumberOffset();
if (n <= 0)
if (n <= 0) {
n = 1;
result = false;
}
n--;
if (n >= _score->npages())
if (n >= _score->npages()) {
result = false;
n = _score->npages() - 1;
}
const Page* page = _score->pages()[n];
foreach (System* s, *page->systems()) {
if (s->firstMeasure()) {
gotoMeasure(s->firstMeasure());
return;
break;
}
}
return result;
}
//---------------------------------------------------------
// searchMeasure
//---------------------------------------------------------
void ScoreView::searchMeasure(int n)
bool ScoreView::searchMeasure(int n)
{
if (n <= 0)
return;
return false;
bool result = true;
--n;
int i = 0;
Measure* measure;
@ -5392,9 +5359,39 @@ void ScoreView::searchMeasure(int n)
break;
i += nn;
}
if (!measure)
if (!measure) {
measure = score()->lastMeasureMM();
result = false;
}
gotoMeasure(measure);
return result;
}
//---------------------------------------------------------
// searchRehearsalMark
//---------------------------------------------------------
bool ScoreView::searchRehearsalMark(const QString& s)
{
//search rehearsal marks
QString ss = s.toLower();
bool found = false;
for (Segment* seg = score()->firstSegment(); seg; seg = seg->next1(Segment::Type::ChordRest)) {
for (Element* e : seg->annotations()){
if (e->type() == Element::Type::REHEARSAL_MARK) {
RehearsalMark* rm = static_cast<RehearsalMark*>(e);
QString rms = rm->text().toLower();
if (rms.startsWith(ss)) {
gotoMeasure(seg->measure());
found = true;
break;
}
}
}
if (found)
break;
}
return found;
}
//---------------------------------------------------------

View file

@ -385,9 +385,9 @@ class ScoreView : public QWidget, public MuseScoreView {
QRectF toLogical(const QRectF& r) const { return imatrix.mapRect(r); }
QRect toPhysical(const QRectF& r) const { return _matrix.mapRect(r).toRect(); }
void search(const QString& s);
void searchMeasure(int i);
void searchPage(int i);
bool searchMeasure(int i);
bool searchPage(int i);
bool searchRehearsalMark(const QString& s);
void gotoMeasure(Measure*);
void selectMeasure(int m);
void postCmd(const char* cmd) { sm->postEvent(new CommandEvent(cmd)); }

117
mscore/searchComboBox.cpp Normal file
View file

@ -0,0 +1,117 @@
#include "searchComboBox.h"
#include "musescore.h"
#include "scoreview.h"
#include "libmscore/score.h"
#include "scoreaccessibility.h"
namespace Ms {
SearchComboBox::SearchComboBox(QWidget* p) : QComboBox(p)
{
setAccessibleName(tr("Search Box"));
setAccessibleDescription(tr("Type to search. Press Enter to return to score."));
setEditable(true);
setInsertPolicy(QComboBox::InsertAtTop);
_found = false;
_searchType = SearchType::NO_SEARCH;
connect(this, SIGNAL(editTextChanged(QString)), this, SLOT(searchTextChanged(QString)));
}
void SearchComboBox::searchInit()
{
_searchType = SearchType::NO_SEARCH;
_found = false;
}
void SearchComboBox::setSearchType(SearchType s)
{
_searchType = s;
}
void SearchComboBox::searchTextChanged(const QString& s)
{
searchInit();
if (s.isEmpty())
return;
ScoreView* cv = mscore->currentScoreView();
if (cv == 0)
return;
bool ok;
int n = s.toInt(&ok);
if (ok && n >= 0) {
setSearchType(SearchType::SEARCH_MEASURE);
_found = cv->searchMeasure(n);
}
else {
if (s.size() >= 2 && s[0].toLower() == 'p' && s[1].isNumber()) {
n = s.mid(1).toInt(&ok);
if (ok && n >= 0) {
setSearchType(SearchType::SEARCH_PAGE);
_found = cv->searchPage(n);
}
}
if (searchType() != SearchType::SEARCH_PAGE) {
setSearchType(SearchType::SEARCH_REHEARSAL_MARK);
_found = cv->searchRehearsalMark(s);
}
}
//updating status bar
ScoreAccessibility::instance()->updateAccessibilityInfo();
emit currentSearchFinished();
}
AccessibleSearchBox::AccessibleSearchBox(SearchComboBox *comboBox) : QAccessibleWidget(comboBox)
{
searchBox = comboBox;
}
QAccessibleInterface* AccessibleSearchBox::SearchBoxFactory(const QString &classname, QObject *object)
{
QAccessibleInterface *iface = 0;
if (classname == QLatin1String("Ms::SearchComboBox") && object && object->isWidgetType()){
qDebug("Creating interface for SearchComboBox object");
SearchComboBox* s = static_cast<SearchComboBox*>(object);
AccessibleSearchBox* a = new AccessibleSearchBox(s);
QObject::connect(s, SIGNAL(currentSearchFinished()), a, SLOT(searchFinished()));
iface = static_cast<QAccessibleInterface*>(a);
}
return iface;
}
QString AccessibleSearchBox::text(QAccessible::Text t) const
{
QString type;
QString value = searchBox->currentText();
if (t == QAccessible::Value) {
switch (searchBox->searchType()) {
case SearchComboBox::SearchType::NO_SEARCH:
return QString();
case SearchComboBox::SearchType::SEARCH_MEASURE:
type = tr("Measure");
break;
case SearchComboBox::SearchType::SEARCH_PAGE:
type = tr("Page");
value = value.mid(1);
break;
case SearchComboBox::SearchType::SEARCH_REHEARSAL_MARK:
type = tr("Rehearsal Mark");
break;
}
QString found = searchBox->found() ? "" : tr("Not found ");
return QString("%1 %2 %3%4").arg(type).arg(value).arg(found).arg(mscore->currentScoreView()->score()->accessibleInfo());
}
return QAccessibleWidget::text(t);
}
void AccessibleSearchBox::searchFinished()
{
QAccessibleValueChangeEvent ev(searchBox, text(QAccessible::Value));
QAccessible::updateAccessibility(&ev);
}
}

47
mscore/searchComboBox.h Normal file
View file

@ -0,0 +1,47 @@
#ifndef __SEARCHCOMBOBOX__
#define __SEARCHCOMBOBOX__
#include <QAccessibleWidget>
namespace Ms {
class SearchComboBox : public QComboBox {
Q_OBJECT
public:
enum SearchType {
SEARCH_MEASURE,
SEARCH_PAGE,
SEARCH_REHEARSAL_MARK,
NO_SEARCH
};
private:
SearchType _searchType;
bool _found;
void searchInit();
void setSearchType(SearchType s);
private slots:
void searchTextChanged(const QString& s);
public:
SearchType searchType() { return _searchType; }
bool found() { return _found; }
SearchComboBox(QWidget* p = 0);
signals:
void currentSearchFinished();
};
class AccessibleSearchBox : public QObject, QAccessibleWidget {
Q_OBJECT
SearchComboBox* searchBox;
//JAWS compatibility - no idea why yet. Adjustments needs to be made to the JawsScript.
//QAccessible::Role role() const Q_DECL_OVERRIDE { return QAccessible::ComboBox; }
QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
public:
AccessibleSearchBox(SearchComboBox* comboBox);
static QAccessibleInterface* SearchBoxFactory(const QString &classname, QObject *object);
public slots:
void searchFinished();
};
}
#endif