Beispiel #1
0
/** TagButton instances are converted with whitespaces in the LineEdit in order to move them. */
void TagLineEdit::insertSpaces()
{
	TagButton *t = qobject_cast<TagButton*>(sender());
	int cx = cursorRect().x();
	t->setPosition(cursorPosition());
	int numberOfSpace = 2;

	this->setText(this->text().insert(cursorPosition(), "  "));

	cursorForward(false, 2);
	while (t->frameGeometry().contains(cursorRect().center())) {
		this->setText(this->text().insert(cursorPosition(), " "));
		cursorForward(false);
		numberOfSpace++;
	}
	t->setMinimumWidth(numberOfSpace * fontMetrics().width(" ") - 5);
	t->setSpaceCount(numberOfSpace);
	t->disconnect();

	for (TagButton *tag : _tags) {
		//qDebug() << Q_FUNC_INFO << "trying to move tag";
		if (t != tag && tag->frameGeometry().x() > cx) {
			//qDebug() << Q_FUNC_INFO << "moving tag" << tag->text();
			tag->move(tag->x() + fontMetrics().width(" ") * numberOfSpace, 0);
		}
	}
}
Beispiel #2
0
/** Redefined to be able to move TagButton when typing. */
void TagLineEdit::keyPressEvent(QKeyEvent *event)
{
	if (event->key() == Qt::Key_Left || event->key() == Qt::Key_Right) {
		/// TODO cursorWordForward / cursorWordBackard to stop on TagButton
		if (QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier)) {
			qDebug() << "cursorWordForward / backward";
		}
		LineEdit::keyPressEvent(event);
		for (TagButton *t : _tags) {
			if (t->frameGeometry().contains(cursorRect().center())) {
				if (event->key() == Qt::Key_Left) {
					cursorBackward(false, t->spaceCount() - 1);
				} else {
					cursorForward(false, t->spaceCount() - 1);
				}
				break;
			}
		}
	} else {
		QString k = event->text();
		int w = fontMetrics().width(k);
		if (event->key() == Qt::Key_Delete) {
			qDebug() << Q_FUNC_INFO << "Key_Delete";
			w = -w;
		}
		for (TagButton *t : _tags) {
			if (t->frameGeometry().x() > cursorRect().center().x()) {
				t->move(t->x() + w, 0);
			}
		}
		LineEdit::keyPressEvent(event);
	}
}
Beispiel #3
0
void CharLineEdit::keyPressEvent(QKeyEvent* event)
{
	bool handled = false;

	if (selectionStart() == -1)
	{
		switch (event->key())
		{
		case Qt::Key_Backspace:
			if (isAtEndOfSeparator())
			{
				// Delete separator characters in a single keypress.
				// Don't use setText This method maintains the undo history
				backspace();
				backspace();
				backspace();
				handled = true;
			}
			break;

		case Qt::Key_Delete:
			if (isAtStartOfSeparator())
			{
				del();
				del();
				del();
				handled = true;
			}
			break;

		case Qt::Key_Left:
			if (isAtEndOfSeparator())
			{
				cursorBackward(false, 3);
				handled = true;
			}
			break;

		case Qt::Key_Right:
			if (isAtStartOfSeparator())
			{
				cursorForward(false, 3);
				handled = true;
			}
			break;
		}
	}

	if (handled)
	{
		event->ignore();
	}
	else
	{
		QLineEdit::keyPressEvent(event);
	}

	emit keyPressed(event);
}
Beispiel #4
0
/** Redefined to be able to move tag buttons.
 * Backspace method is not virtual in QLineEdit, therefore keyPressEvent must be intercepted and eaten. */
void TagLineEdit::backspace()
{
	bool oneTagNeedToBeRemoved = false;
	TagButton *tag = nullptr;
	QPoint cursorCenter;

	cursorBackward(false);
	int dx = fontMetrics().width(text().at(cursorPosition()));
	for (TagButton *button : _tags) {
		cursorCenter = cursorRect().center();
		// One tag button need to be removed
		if (button->frameGeometry().contains(cursorCenter)) {
			oneTagNeedToBeRemoved = true;
			tag = button;
		}

		// Tags need to be moved to the left
		if (button->x() > cursorCenter.x()) {
			button->move(button->x() - dx, 0);
			button->setPosition(cursorPosition());
		}
	}

	cursorForward(false);
	if (oneTagNeedToBeRemoved) {
		for (int i = 0; i < tag->spaceCount(); i++) {
			LineEdit::backspace();
		}

		dx = fontMetrics().width(" ") * tag->spaceCount();
		for (TagButton *button : _tags) {
			if (button != tag && button->x() > cursorCenter.x()) {
				button->move(button->x() - dx, 0);
				button->setPosition(cursorPosition());
			}
		}
		_tags.removeOne(tag);
		delete tag;
		/// FIXME
		//emit taglistHasChanged(this->toStringList());
	} else {
		LineEdit::backspace();
	}
}
Beispiel #5
0
/** Redefined to automatically move cursor outside TagButton. */
void TagLineEdit::mousePressEvent(QMouseEvent *event)
{
	LineEdit::mousePressEvent(event);
	for (TagButton *t : _tags) {
		QRect r = t->frameGeometry();
		if (r.contains(event->pos())) {
			if (r.x() + r.width() / 2 >= event->pos().x()) {
				while (r.contains(cursorRect().center()) && cursorPosition() > 0) {
					cursorBackward(false);
					//qDebug() << "cursorBackward" << "pos" << t->position() << "spaces" << t->spaceCount();
				}
			} else {
				while (r.contains(cursorRect().center()) && cursorPosition() < text().length()) {
					cursorForward(false);
					//qDebug() << "cursorForward" << "pos" << t->position() << "spaces" << t->spaceCount();
				}
			}
			break;
		}
	}
}
Beispiel #6
0
void
H19::processCharacter(char ch)
{
    // mask off the high bit just in case, the real H19 would not have it set.
    ch &= 0x7f;

    if (mode_m == Normal)
    {
        switch (ch)
        {
            case ascii::NUL:
            case ascii::SOH:
            case ascii::STX:
            case ascii::ETX:
            case ascii::EOT:
            case ascii::ENQ:
            case ascii::ACK:
            case ascii::VT:
            case ascii::FF:
            case ascii::SO:
            case ascii::SI:
            case ascii::DLE:
            case ascii::DC1:
            case ascii::DC2:
            case ascii::DC3:
            case ascii::DC4:
            case ascii::NAK:
            case ascii::SYN:
            case ascii::ETB:
            case ascii::EM:
            case ascii::SUB:
            case ascii::FS:
            case ascii::GS:
            case ascii::RS:
            case ascii::US:
            case ascii::DEL:
                // From manual, these characters are not processed by the terminal
                break;

            case ascii::BEL: // Rings the bell.
                /// \todo - implement ringing bell.
                consoleLog("<BEL>");
                break;

            case ascii::BS: // Backspace
                consoleLog("<BS>");
                processBS();
                break;

            case ascii::HT: // Horizontal Tab
                consoleLog("<TAB>");
                processTAB();
                break;

            case ascii::LF: // Line Feed
                processLF();

                if (autoCR_m)
                {
                    processCR();
                }

                consoleLog("\n");
                break;

            case ascii::CR: // Carriage Return
                processCR();

                if (autoLF_m)
                {
                    processLF();
                }

                break;

            case ascii::CAN: // Cancel.
                break;

            case ascii::ESC: // Escape
                mode_m = Escape;
                consoleLog("<ESC>");
                break;

            default:
                // if Printable character display it.
#if CONSOLE_LOG
                fprintf(console_out, "%c", ch);
#endif
                displayCharacter(ch);
                break;
        }
    }
    else if (mode_m == Escape)
    {
        // Assume we go back to Normal, so only the few that don't need to set the mode.
        mode_m = Normal;

        switch (ch)
        {
            case ascii::CAN: // CAN - Cancel
                // return to Normal mode, already set.
                break;

            case ascii::ESC: // Escape
                // From the ROM listing, stay in this mode.
                mode_m = Escape;
                break;

            // Cursor Functions

            case 'H': // Cursor Home
                posX_m    = posY_m = 0;
                updated_m = true;
                break;

            case 'C': // Cursor Forward
                cursorForward();
                break;

            case 'D':        // Cursor Backward
                processBS(); // same processing as cursor backward
                break;

            case 'B': // Cursor Down
                cursorDown();
                break;

            case 'A': // Cursor Up
                cursorUp();
                break;

            case 'I': // Reverse Index
                reverseIndex();
                break;

            case 'n': // Cursor Position Report
                cursorPositionReport();
                break;

            case 'j': // Save cursor position
                saveCursorPosition();
                break;

            case 'k': // Restore cursor position
                restoreCursorPosition();
                break;

            case 'Y': // Direct Cursor Addressing
                mode_m = DCA_1;
                break;

            // Erase and Editing

            case 'E': // Clear Display
                clearDisplay();
                break;

            case 'b': // Erase Beginning of Display
                eraseBOD();
                break;

            case 'J': // Erase to End of Page
                eraseEOP();
                break;

            case 'l': // Erase entire Line
                eraseEL();
                break;

            case 'o': // Erase Beginning Of Line
                eraseBOL();
                break;

            case 'K': // Erase To End Of Line
                eraseEOL();
                break;

            case 'L': // Insert Line
                insertLine();
                break;

            case 'M': // Delete Line
                deleteLine();
                break;

            case 'N': // Delete Character
                deleteChar();
                break;

            case '@': // Enter Insert Character Mode
                insertMode_m = true;
                break;

            case 'O': // Exit Insert Character Mode
                insertMode_m = false;
                break;

            // Configuration

            case 'z': // Reset To Power-Up Configuration
                reset();
                break;

            case 'r': // Modify the Baud Rate
                /// \todo - determine if we should support this.
                debugss(ssH19, ERROR, "Error Unimplemented Modify Baud\n");
                break;

            case 'x': // Set Mode
                mode_m = SetMode;
                break;

            case 'y': // Reset Mode
                mode_m = ResetMode;
                break;

            case '<': // Enter ANSI Mode
                /// \todo - implement ANSI mode.
                // ROM - just sets the mode
                debugss(ssH19, ERROR, "Error Entering ANSI mode - unsupported\n");
                break;

            // Modes of operation

            case '[': // Enter Hold Screen Mode
                holdScreen_m = true;
                break;

            case '\\': // Exit Hold Screen Mode
                holdScreen_m = false;
                break;

            case 'p': // Enter Reverse Video Mode
                reverseVideo_m = true;
                break;

            case 'q': // Exit Reverse Video Mode
                reverseVideo_m = false;
                break;

            case 'F': // Enter Graphics Mode
                graphicMode_m = true;
                break;

            case 'G': // Exit Graphics Mode
                graphicMode_m = false;
                break;

            case 't': // Enter Keypad Shifted Mode
                keypadShifted_m = true;
                break;

            case 'u': // Exit Keypad Shifted Mode
                // ROM - just sets the mode
                keypadShifted_m = false;
                break;

            case '=': // Enter Alternate Keypad Mode
                // ROM - just sets the mode
                keypadShifted_m = true;
                break;

            case '>': // Exit Alternate Keypad Mode
                // ROM - just sets the mode
                keypadShifted_m = false;
                break;

            // Additional Functions

            case '}': // Keyboard Disable
                /// \todo - determine whether to do this.
                keyboardEnabled_m = false;
                break;

            case '{': // Keyboard Enable
                keyboardEnabled_m = true;
                break;

            case 'v': // Wrap Around at End Of Line
                wrapEOL_m = true;
                break;

            case 'w': // Discard At End Of Line
                wrapEOL_m = false;
                break;

            case 'Z': // Identify as VT52 (Data: ESC / K)
                debugss(ssH19, ERROR, "Identify request\n");
                sendData(ascii::ESC);
                sendData('/');
                sendData('K');
                break;

            case ']': // Transmit 25th Line
                transmitLine25();
                break;

            case '#': // Transmit Page
                transmitPage();
                break;

            default:
                debugss(ssH19, WARNING, "Unhandled ESC: %d\n", ch);
                /// \todo - verify this is how the H19 ROM does it.
                break;
        }
    }
    else if (mode_m == SetMode)
    {
        mode_m = Normal;

        switch (ch)
        {
            case '1': // Enable 25th line
                // From the ROM, it erases line 25 on the enable, but here we erase on the disable.
                line25_m = true;
                break;

            case '2': // No key click
                keyClick_m = true;
                break;

            case '3': // Hold screen mode
                holdScreen_m = true;
                break;

            case '4': // Block Cursor
                cursorBlock_m = true;
                updated_m     = true;
                break;

            case '5': // Cursor Off
                cursorOff_m = true;
                updated_m   = true;
                break;

            case '6': // Keypad Shifted
                keypadShifted_m = true;
                break;

            case '7': // Alternate Keypad mode
                altKeypadMode_m = true;
                break;

            case '8': // Auto LF
                autoLF_m = true;
                break;

            case '9': // Auto CR
                autoCR_m = true;
                break;

            default:
                /// \todo Need to process ch as if none of this happened...
                debugss(ssH19, WARNING, "Invalid set Mode: %c\n", ch);
                break;
        }
    }
    else if (mode_m == ResetMode)
    {
        mode_m = Normal;

        switch (ch)
        {
            case '1': // Disable 25th line
                eraseLine(rowsMain_c);
                line25_m  = false;
                updated_m = true;
                break;

            case '2': // key click
                keyClick_m = false;
                break;

            case '3': // Hold screen mode
                holdScreen_m = false;
                break;

            case '4': // Block Cursor
                cursorBlock_m = false;
                updated_m     = true;
                break;

            case '5': // Cursor On
                cursorOff_m = false;
                updated_m   = true;
                break;

            case '6': // Keypad Unshifted
                keypadShifted_m = false;
                break;

            case '7': // Exit Alternate Keypad mode
                altKeypadMode_m = false;
                break;

            case '8': // No Auto LF
                autoLF_m = false;
                break;

            case '9': // No Auto CR
                autoCR_m = false;
                break;

            default:
                /// \todo Need to process ch as if none of this happened...
                debugss(ssH19, WARNING, "Invalid reset Mode: %c\n", ch);
                break;
        }
    }
    else if (mode_m == DCA_1)
    {
        // From actual H19, once the line is specified, the cursor
        // immediately moves to that line, so no need to save the
        // position and wait for the entire command.
        /// \todo verify that this is the same on newer H19s.
        if (ch == ascii::CAN)
        {
            // cancel
            mode_m = Normal;
        }
        else
        {
            // \todo handle error conditions

            int pos = ch - 31;

            // verify valid Position
            if (((pos > 0) && (pos < (signed) rows_c)) || ((pos == (signed) rows_c) && (line25_m)))
            {
                posY_m = pos - 1;
            }
            else
            {
                /// \todo check to see how a real h19 handles this.
                debugss(ssH19, INFO, "DCA invalid Y: %d\n", pos);
            }

            mode_m = DCA_2;
        }
    }
    else if (mode_m == DCA_2)
    {
        if (ch == ascii::CAN)
        {
            // cancel
            mode_m = Normal;
        }
        else
        {
            int pos = ch - 31;

            if ((pos > 0) && (pos < 81))
            {
                posX_m = pos - 1;
            }
            else
            {
                posX_m = (cols_c - 1);
            }

            updated_m = true;
            mode_m    = Normal;
        }
    }
}
Beispiel #7
0
Screen::InputActions Screen::getInput2( void ) {

  gotoxy( cur_x, cur_y2 );

  uint16_t key = bioskey(0);

  if ( eatNextChar == true ) {
    eatNextChar = false;
    return AteOneKeypress;
  }

  bool removeColorPopup = false;

  if ( (key & 0xff) == 0 ) {

    // If any function key is pressed get rid of the color chart popup table
    removeColorPopup = true;

    // Function key
    uint8_t fkey = key >> 8;

    switch ( fkey ) {

      case 19: return ShowRawToggle;          // Alt-R
      case 20: return TimestampToggle;        // Alt-T
      case 31: return Stats;                  // Alt-S
      case 35: return Help;                   // Alt-H
      case 38: return LoggingToggle;          // Alt-L
      case 45: return EndProgram;             // Alt-X
      case 46: return CloseWindow;            // Alt-C
      case 48: return BeepToggle;             // Alt-B
      case 73: return BackScroll;             // PgUp
      case 81: return ForwardScroll;          // PgDn

      case 71: {  // Home
        cur_x = 0;
        cur_y = 0; cur_y2 = separatorRow+1;
        break;
      }

      case 72: {  // Up
        if ( cur_y ) { cur_y--; cur_y2--; } else { ERRBEEP( ); }
        break;
      }

      case 75: {  // Left
        if ( !isCursorHome( ) ) { cursorBack( ); } else { ERRBEEP( ); }
        break;
      }

      case 77: {  // Right
        if ( cur_x + (cur_y * screenCols) < input_len ) { cursorForward( ); } else { ERRBEEP( ); }
        break;
      }

      case 79: {  // End
        cur_x = input_len % screenCols;
        cur_y = input_len / screenCols;
        cur_y2 = cur_y + separatorRow + 1;
        break;
      }

      case 80: {  // Down
        if ( cur_x + ((cur_y+1)*screenCols) <= input_len ) { cur_y++; cur_y2++; } else { ERRBEEP( ); }
        break;
      }

      case 82: {  // Insert

        insertMode = !insertMode;
        if ( insertMode ) {
          sound(500); delay(50); sound(750); delay(50); nosound( );
        }
        else {
          // Not really complaining - just indicating back to overstrike
          sound(750); delay(50); sound(500); delay(50); nosound( );
        }

        break;
      }

      case 83: {  // Delete

        // Has to be on an existing char

        uint16_t startIndex = cur_x + cur_y*screenCols;

        if ( startIndex < input_len ) {

          memmove( userInputBuffer+startIndex, userInputBuffer+startIndex+1, (input_len-startIndex) );
          input_len--;
          userInputBuffer[input_len] = 0;

          repaintInputArea( startIndex, userInputBuffer+startIndex, (input_len-startIndex) );
        }
        else {
          ERRBEEP( );
        }

        break;
      }

      case 129: {  // Alt-0 (Server Session)
        *switchToSession = 0;
        return SwitchSession;
      }

      default: {

        if ( fkey >= 120 && fkey <= 128 ) {
          *switchToSession = fkey - 119;
          return SwitchSession;
        }

      }

    }



  }