Merge pull request #1715 from andreituicu/45666
Accessibility for Search (goto) dialog.
This commit is contained in:
commit
9d0c16afee
7 changed files with 215 additions and 70 deletions
|
@ -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}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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
117
mscore/searchComboBox.cpp
Normal 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
47
mscore/searchComboBox.h
Normal 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
|
Loading…
Reference in a new issue