Chris@281: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
Chris@281: 
Chris@281: /*
Chris@281:     Sonic Visualiser
Chris@281:     An audio file viewer and annotation editor.
Chris@281:     Centre for Digital Music, Queen Mary, University of London.
Chris@281:     This file copyright 2007 QMUL.
Chris@281:     
Chris@281:     This program is free software; you can redistribute it and/or
Chris@281:     modify it under the terms of the GNU General Public License as
Chris@281:     published by the Free Software Foundation; either version 2 of the
Chris@281:     License, or (at your option) any later version.  See the file
Chris@281:     COPYING included with this distribution for more information.
Chris@281: */
Chris@281: 
Chris@281: #include "KeyReference.h"
Chris@281: 
Chris@281: #include <QAction>
Chris@281: #include <QTextEdit>
Chris@282: #include <QDialog>
Chris@282: #include <QVBoxLayout>
Chris@282: #include <QDialogButtonBox>
Chris@282: #include <QApplication>
Chris@282: #include <QDesktopWidget>
Chris@281: 
Chris@281: KeyReference::KeyReference() :
Chris@282:     m_dialog(0)
Chris@281: {
Chris@281: }
Chris@281: 
Chris@281: KeyReference::~KeyReference()
Chris@281: {
Chris@282:     delete m_dialog;
Chris@281: }
Chris@281: 
Chris@281: void
Chris@281: KeyReference::setCategory(QString category)
Chris@281: {
Chris@281:     if (m_map.find(category) == m_map.end()) {
Chris@281:         m_categoryOrder.push_back(category);
Chris@282:         m_map[category] = KeyList();
Chris@281:     }
Chris@281:     m_currentCategory = category;
Chris@281: }
Chris@281: 
Chris@281: void
Chris@281: KeyReference::registerShortcut(QAction *action, QString overrideName)
Chris@281: {
Chris@281:     QString name = action->text();
Chris@281:     if (overrideName != "") name = overrideName;
Chris@281: 
Chris@616:     QString shortcut = action->shortcut().toString();
Chris@281:     QString tip = action->statusTip();
Chris@281: 
Chris@281:     registerShortcut(name, shortcut, tip);
Chris@281: }
Chris@281: 
Chris@281: void
Chris@281: KeyReference::registerShortcut(QString name, QString shortcut, QString tip)
Chris@281: {
Chris@282:     name.replace(tr("&"), "");
Chris@282:             
Chris@281:     KeyList &list = m_map[m_currentCategory];
Chris@281: 
Chris@281:     for (KeyList::iterator i = list.begin(); i != list.end(); ++i) {
Chris@281:         if (i->actionName == name) {
Chris@281:             i->shortcut = shortcut;
Chris@281:             i->tip = tip;
Chris@281:             i->alternatives.clear();
Chris@281:             return;
Chris@281:         }
Chris@281:     }
Chris@281: 
Chris@281:     KeyDetails details;
Chris@281:     details.actionName = name;
Chris@281:     details.shortcut = shortcut;
Chris@281:     details.tip = tip;
Chris@281: 
Chris@281:     list.push_back(details);
Chris@281: }
Chris@281: 
Chris@281: void
Chris@281: KeyReference::registerAlternativeShortcut(QAction *action, QString alternative)
Chris@281: {
Chris@281:     QString name = action->text();
Chris@281:     registerAlternativeShortcut(name, alternative);
Chris@281: }
Chris@281: 
Chris@281: void
Chris@281: KeyReference::registerAlternativeShortcut(QString name, QString alternative)
Chris@281: {
Chris@282:     name.replace(tr("&"), "");
Chris@282: 
Chris@281:     KeyList &list = m_map[m_currentCategory];
Chris@281: 
Chris@281:     for (KeyList::iterator i = list.begin(); i != list.end(); ++i) {
Chris@281:         if (i->actionName == name) {
Chris@281:             i->alternatives.push_back(alternative);
Chris@281:             return;
Chris@281:         }
Chris@281:     }
Chris@281: }
Chris@281: 
Chris@281: void
Chris@281: KeyReference::show()
Chris@281: {
Chris@282:     if (m_dialog) {
Chris@282:         m_dialog->show();
Chris@282:         m_dialog->raise();
Chris@281:         return;
Chris@281:     }
Chris@281: 
Chris@281:     QString text;
Chris@291:     
Chris@291:     QColor bgcolor = QApplication::palette().window().color();
Chris@291:     bool darkbg = (bgcolor.red() + bgcolor.green() + bgcolor.blue() < 384);
Chris@281: 
Chris@291:     text += QString("<center><table bgcolor=\"%1\">")
Chris@291:         .arg(darkbg ? "#121212" : "#e8e8e8");
Chris@281:         
Chris@281:     for (CategoryList::iterator i = m_categoryOrder.begin();
Chris@281:          i != m_categoryOrder.end(); ++i) {
Chris@281: 
Chris@281:         QString category = *i;
Chris@281:         KeyList &list = m_map[category];
Chris@281: 
Chris@291:         text += QString("<tr><td bgcolor=\"%1\" colspan=3 align=\"center\"><br><b>%2</b><br></td></tr>\n").arg(darkbg ? "#303030" : "#d0d0d0").arg(category);
Chris@281: 
Chris@281:         for (KeyList::iterator j = list.begin(); j != list.end(); ++j) {
Chris@281: 
Chris@281:             QString actionName = j->actionName;
Chris@282: 
Chris@282:             QString shortcut = j->shortcut;
Chris@282:             shortcut.replace(" ", "&nbsp;");
Chris@281: 
Chris@281:             QString tip = j->tip;
Chris@281:             if (tip != "") tip = QString("<i>%1</i>").arg(tip);
Chris@281: 
Chris@281:             QString altdesc;
Chris@281:             if (!j->alternatives.empty()) {
Chris@281:                 for (std::vector<QString>::iterator k = j->alternatives.begin();
Chris@281:                      k != j->alternatives.end(); ++k) {
Chris@282:                     QString alt = *k;
Chris@282:                     alt.replace(" ", "&nbsp;");
Chris@282:                     altdesc += tr("<i>or</i>&nbsp;<b>%1</b>").arg(alt);
Chris@281:                 }
Chris@281:                 altdesc = tr("</b>&nbsp;(%1)<b>").arg(altdesc);
Chris@281:             }
Chris@281: 
Chris@281:             text += QString("<tr><td>&nbsp;<b>%1%2</b></td><td>&nbsp;%3</td><td>%4</td></tr>\n")
Chris@282:                 .arg(shortcut).arg(altdesc).arg(actionName).arg(tip);
Chris@281:         }
Chris@281:     }
Chris@281: 
Chris@281:     text += "</table></center>\n";
Chris@281: 
Chris@281:     m_text = new QTextEdit;
Chris@281:     m_text->setHtml(text);
Chris@281:     m_text->setReadOnly(true);
Chris@282: 
Chris@282:     m_dialog = new QDialog;
Chris@282:     m_dialog->setWindowTitle(tr("Sonic Visualiser: Key and Mouse Reference"));
Chris@282: 
Chris@282:     QVBoxLayout *layout = new QVBoxLayout;
Chris@282:     m_dialog->setLayout(layout);
Chris@282:     layout->addWidget(m_text);
Chris@282: 
Chris@282:     QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Close);
Chris@282:     connect(bb, SIGNAL(clicked(QAbstractButton *)), this, SLOT(dialogButtonClicked(QAbstractButton *)));
Chris@282:     layout->addWidget(bb);
Chris@282: 
Chris@282:     m_dialog->show();
Chris@282:     
Chris@282:     QDesktopWidget *desktop = QApplication::desktop();
Chris@282:     QRect available = desktop->availableGeometry();
Chris@282: 
Chris@282:     int width = available.width() * 3 / 5;
Chris@282:     int height = available.height() * 2 / 3;
Chris@282:     if (height < 450) {
Chris@282:         if (available.height() > 500) height = 450;
Chris@282:     }
Chris@282:     if (width < 600) {
Chris@282:         if (available.width() > 650) width = 600;
Chris@282:     }
Chris@282: 
Chris@282:     m_dialog->resize(width, height);
Chris@282:     m_dialog->raise();
Chris@281: }
Chris@281: 
Chris@282: void
Chris@282: KeyReference::dialogButtonClicked(QAbstractButton *)
Chris@282: {
Chris@282:     // only button is Close
Chris@282:     m_dialog->hide();
Chris@282: }
Chris@282: 
Chris@609: void
Chris@609: KeyReference::hide()
Chris@609: {
Chris@609:     if (m_dialog) {
Chris@609:         m_dialog->hide();
Chris@609:     }
Chris@609: }