diff --git a/src/commandline.cpp b/src/commandline.cpp index 49ce4531..9eacf3e0 100644 --- a/src/commandline.cpp +++ b/src/commandline.cpp @@ -1,10 +1,13 @@ +#include #include "commandline.h" #include "consts.h" #include "preferences.h" -CommandLine::CommandLine() +CommandLine::CommandLine(QObject *parent) : QObject(parent), + m_terminated(false), + m_clearKeyTimer(new QTimer(this)) { - m_terminated = false; + m_clearKeyTimer->setSingleShot(true); } void CommandLine::processKey(Key value) @@ -38,12 +41,20 @@ void CommandLine::processKey(Key value) m_addresses.clear(); m_terminated = false; } + else if (m_clearKeyTimer->isActive()) + { + // Double tap, clear line + m_keyStack.clear(); + m_errorText.clear(); + } else { // Backspace m_keyStack.pop(); m_errorText.clear(); } + + m_clearKeyTimer->start(QApplication::doubleClickInterval()); } else { @@ -60,6 +71,29 @@ void CommandLine::processKey(Key value) processStack(); } +void getSelection(QSet *selection, int *numberEntry, int *startRange) +{ + if(*startRange != 0 && *numberEntry != 0) + { + // Thru + if (*numberEntry > *startRange) + for(int i = *startRange; i <= *numberEntry; i++) + selection->insert(i); + else + for(int i = *numberEntry; i <= *startRange; i++) + selection->insert(i); + } + else + { + // Single + if(*numberEntry!=0) + selection->insert(*numberEntry); + } + + *numberEntry = 0; + *startRange = 0; +} + void CommandLine::processStack() { enum { @@ -106,7 +140,7 @@ void CommandLine::processStack() { // Not a valid entry, would be >512 state = stError; - m_errorText = "Error - number out of range"; + m_errorText = E_RANGE; return; } @@ -118,17 +152,17 @@ void CommandLine::processStack() { // Not a valid entry, would be >max state = stError; - m_errorText = "Error - number out of range"; + m_errorText = E_RANGE; return; } } break; case THRU: - m_text.append(" THRU "); + m_text.append(QString(" %1 ").arg(K_THRU)); if(numberEntry==0 || state!=stChannel || startRange!=0) { - m_errorText = "Error - syntax error"; + m_errorText = E_SYNTAX; return; } startRange=numberEntry; @@ -136,18 +170,25 @@ void CommandLine::processStack() break; case AT: - m_text.append(" @ "); - if(startRange!=0 && numberEntry==0) + // [@] [@] = [@] [Full] + if ( + m_keyStack.count() > 1 && + m_keyStack.last() == m_keyStack[m_keyStack.count() - 2] + ) { - m_errorText = "Error - syntax error"; + m_keyStack.pop(); + processKey(FULL); return; } - if(startRange!=0 && numberEntry!=0) + + m_text.append(QString(" %1 ").arg(K_AT));; + if(startRange!=0 && numberEntry==0) { - for(int i=startRange; isetReadOnly(true); setStyleSheet("color: rgb(127, 255, 23);background: black;font: 75 12pt \"Courier\";"); clear(); + + // Cursor blinker + connect(m_cursorTimer, SIGNAL(timeout()), this, SLOT(flashCursor())); + m_cursorTimer->setInterval(300); + m_cursorTimer->setSingleShot(false); + m_cursorTimer->start(); +} + +void CommandLineWidget::flashCursor() +{ + if (this->hasFocus()) + { + auto cursor = (m_cursorState == true) ? "_" : ""; + this->setText(QString("%1%2") + .arg(m_commandLine.text()) + .arg(cursor)); + + m_cursorState = !m_cursorState; + } else { + this->setText(m_commandLine.text()); + } } void CommandLineWidget::displayText() diff --git a/src/commandline.h b/src/commandline.h index 1acf271b..b80b267f 100644 --- a/src/commandline.h +++ b/src/commandline.h @@ -6,10 +6,26 @@ #include #include #include +#include +#include -class CommandLine +// Strings +static const QString K_THRU(QObject::tr("THRU")); +static const QString K_AT(QObject::tr("AT")); +static const QString K_FULL(QObject::tr("FULL")); +static const QString K_CLEAR(QObject::tr("CLEAR")); +static const QString K_AND(QObject::tr("AND")); + +static const QString E_SYNTAX(QObject::tr("Error - syntax error")); +static const QString E_RANGE(QObject::tr("Error - number out of range")); +static const QString E_NO_SELECTION(QObject::tr("Error - no selection")); + +class CommandLine : public QObject { + Q_OBJECT public: + explicit CommandLine(QObject *parent = nullptr); + enum Key { K0, K1, @@ -30,7 +46,6 @@ class CommandLine ALL_OFF }; - CommandLine(); QString text(); QString errorText() { return m_errorText; } @@ -46,6 +61,7 @@ class CommandLine bool m_terminated; QStack m_previousKeyStack; QStack m_keyStack; + QTimer *m_clearKeyTimer; }; class CommandLineWidget : public QTextEdit @@ -75,9 +91,13 @@ public slots: void setLevels(QSet addreses, int level); protected: virtual void keyPressEvent(QKeyEvent *e); +private slots: + void flashCursor(); private: CommandLine m_commandLine; void displayText(); + QTimer *m_cursorTimer; + bool m_cursorState; }; class EditableLCDNumber : public QLCDNumber diff --git a/src/transmitwindow.cpp b/src/transmitwindow.cpp index b1b8ef25..87b07d78 100644 --- a/src/transmitwindow.cpp +++ b/src/transmitwindow.cpp @@ -77,6 +77,7 @@ transmitwindow::transmitwindow(int universe, QWidget *parent) : QToolButton *button = new QToolButton(this); button->setText(QString::number(i+1)); button->setMinimumSize(16, 16); + button->setFocusPolicy(Qt::FocusPolicy::NoFocus); layout->addWidget(button); m_presetButtons << button; connect(button, SIGNAL(pressed()), this, SLOT(presetButtonPressed())); @@ -85,6 +86,7 @@ transmitwindow::transmitwindow(int universe, QWidget *parent) : m_presetButtons << recordButton; recordButton->setCheckable(true); recordButton->setIcon(QIcon(":/icons/record.png")); + recordButton->setFocusPolicy(Qt::FocusPolicy::NoFocus); layout->addWidget(recordButton); ui->gbPresets->setLayout(layout); connect(recordButton, SIGNAL(toggled(bool)), this, SLOT(recordButtonPressed(bool))); @@ -271,7 +273,7 @@ void transmitwindow::setUniverseOptsEnabled(bool enabled) ui->gbProtocolVersion->setEnabled(enabled); ui->cbBlind->setEnabled(enabled ? ui->rbRatified->isChecked() : false); ui->tabWidget->setEnabled(!enabled); - + on_tabWidget_currentChanged(ui->tabWidget->currentIndex()); if(enabled) { @@ -528,6 +530,8 @@ void transmitwindow::on_tabWidget_currentChanged(int index) m_sender->setLevelRange(0, MAX_DMX_ADDRESS-1, 0); QMetaObject::invokeMethod( m_fxEngine,"pause"); + + ui->teCommandline->setFocus(); } if(index==tabEffects) diff --git a/ui/transmitwindow.ui b/ui/transmitwindow.ui index 6fc51366..1b8054c7 100644 --- a/ui/transmitwindow.ui +++ b/ui/transmitwindow.ui @@ -7,7 +7,7 @@ 0 0 903 - 525 + 583 @@ -113,6 +113,9 @@ border-radius: 4px; + + Qt::NoFocus + Qt::Horizontal @@ -123,18 +126,27 @@ border-radius: 4px; 0 + + Qt::NoFocus + Source + + Qt::NoFocus + Mode + + Qt::NoFocus + Multicast to @@ -145,19 +157,29 @@ border-radius: 4px; + + Qt::NoFocus + Unicast to - + + + Qt::NoFocus + + + + Qt::NoFocus + Blind-mode data @@ -165,6 +187,9 @@ border-radius: 4px; + + Qt::ClickFocus + 63 @@ -172,6 +197,9 @@ border-radius: 4px; + + Qt::ClickFocus + Per-Source @@ -186,6 +214,9 @@ border-radius: 4px; + + Qt::NoFocus + Priority Mode: @@ -193,6 +224,9 @@ border-radius: 4px; + + Qt::NoFocus + Priority: @@ -200,6 +234,9 @@ border-radius: 4px; + + Qt::NoFocus + Universe: @@ -238,6 +275,9 @@ border-radius: 4px; + + Qt::ClickFocus + Qt::AlignCenter @@ -245,12 +285,18 @@ border-radius: 4px; + + Qt::NoFocus + Protocol Version + + Qt::NoFocus + Ratified @@ -261,6 +307,9 @@ border-radius: 4px; + + Qt::NoFocus + Draft @@ -271,6 +320,9 @@ border-radius: 4px; + + Qt::NoFocus + Qt::Vertical @@ -284,6 +336,9 @@ border-radius: 4px; + + Qt::NoFocus + Source Name: @@ -297,6 +352,9 @@ border-radius: 4px; 0 + + Qt::ClickFocus + Qt::AlignCenter @@ -336,12 +394,18 @@ border-radius: 4px; + + Qt::NoFocus + Start + + Qt::NoFocus + Start at : @@ -349,6 +413,9 @@ border-radius: 4px; + + Qt::ClickFocus + Qt::AlignCenter @@ -359,6 +426,9 @@ border-radius: 4px; + + Qt::NoFocus + Presets @@ -376,6 +446,9 @@ border-radius: 4px; 0 + + Qt::NoFocus + @@ -389,12 +462,18 @@ border-radius: 4px; 0 + + Qt::NoFocus + + + Qt::StrongFocus + @@ -898,6 +977,9 @@ border-radius: 4px; true + + Qt::NoFocus + ALL OFF @@ -1109,10 +1191,13 @@ color: rgb(255, 85, 0); - 102 - 82 + 106 + 86 + + Qt::NoFocus + QSpinBox { min-height: 80px; @@ -1140,6 +1225,9 @@ color: rgb(255, 85, 0); + + Qt::NoFocus + font: 12pt "Arial"; @@ -1155,10 +1243,13 @@ color: rgb(255, 85, 0); - 102 - 82 + 106 + 86 + + Qt::NoFocus + QSpinBox { min-height: 80px; @@ -1190,12 +1281,18 @@ color: rgb(255, 85, 0); 0 + + Qt::NoFocus + Effect Type + + Qt::NoFocus + Manual @@ -1203,6 +1300,9 @@ color: rgb(255, 85, 0); + + Qt::NoFocus + Sinewave @@ -1210,6 +1310,9 @@ color: rgb(255, 85, 0); + + Qt::NoFocus + Ramp @@ -1217,6 +1320,9 @@ color: rgb(255, 85, 0); + + Qt::NoFocus + Chase @@ -1224,6 +1330,9 @@ color: rgb(255, 85, 0); + + Qt::NoFocus + Text @@ -1231,6 +1340,9 @@ color: rgb(255, 85, 0); + + Qt::NoFocus + Date/Time @@ -1238,6 +1350,9 @@ color: rgb(255, 85, 0); + + Qt::NoFocus + false @@ -1248,6 +1363,9 @@ color: rgb(255, 85, 0); + + Qt::NoFocus + Speed - 1Hz @@ -1258,6 +1376,9 @@ color: rgb(255, 85, 0); + + Qt::NoFocus + Qt::Vertical @@ -1273,6 +1394,9 @@ color: rgb(255, 85, 0); + + Qt::NoFocus + ... @@ -1284,6 +1408,9 @@ color: rgb(255, 85, 0); + + Qt::NoFocus + ... @@ -1306,6 +1433,9 @@ color: rgb(255, 85, 0); 0 + + Qt::NoFocus + 0 @@ -1315,6 +1445,9 @@ color: rgb(255, 85, 0); + + Qt::NoFocus + Qt::Vertical @@ -1324,6 +1457,9 @@ color: rgb(255, 85, 0); + + Qt::NoFocus + 0