ushort TEditor::prevWord( ushort p )
{
    while( p > 0 && isWordChar(bufChar(prevChar(p))) == 0 )
        p = prevChar(p);
    while( p > 0 && isWordChar(bufChar(prevChar(p))) != 0 )
        p = prevChar(p);
    return p;
}
示例#2
0
size_t TextEdit::moveWordFromCursor(Direction dir, bool word_end) const
{
  size_t new_pos = current_pos;
  const char *cur = point;
  if (cur == gapstart)
    cur = gapend;

  if (dir == DIR_FORWARD) {
    if (word_end) {
      // search for the first white character after nonwhite characters
      bool nonwhite = false;
      while (new_pos < text_length) {
        if (!g_unichar_isspace(g_utf8_get_char(cur)) && *cur != '\n')
          nonwhite = true;
        else if (nonwhite)
          break;
        cur = nextChar(cur);
        new_pos++;
      }
      return new_pos;
    }
    else {
      // search for the first nonwhite character after white characters
      bool white = false;
      while (new_pos < text_length) {
        if (g_unichar_isspace(g_utf8_get_char(cur)) || *cur == '\n')
          white = true;
        else if (white)
          break;
        cur = nextChar(cur);
        new_pos++;
      }
      return new_pos;
    }
  }
  else { // DIR_BACK
    if (new_pos == 0)
      return 0;

    // always move at least one character back
    cur = prevChar(cur);
    new_pos--;

    // search for the first white character before nonwhite characters
    bool nonwhite = false;
    while (new_pos != static_cast<size_t>(-1)) {
      if (!g_unichar_isspace(g_utf8_get_char(cur)) && *cur != '\n')
        nonwhite = true;
      else if (nonwhite)
        break;
      if (new_pos > 0)
        cur = prevChar(cur);
      new_pos--;
    }
    return ++new_pos;
  }
}
示例#3
0
int TwordWrap::pwidthsLeft(int x)
{
    if (x == 0) {
        return 0;
    }
    return pwidths[prevChar(x)];
}
示例#4
0
void ScriptEdit::TextEdit::keyPressEvent(QKeyEvent *e)
{
    updateCursor();

    switch(e->key())
    {
//    case Qt::Key_Space:
//        if(!(e->modifiers() & Qt::ControlModifier)) QTextEdit::keyPressEvent(e);
//        else Kernel::run(document()->toPlainText()); break;

    case Qt::Key_Tab: insert("    "); break;

    case Qt::Key_ParenLeft:
        if(!curChar().isLetterOrNumber()) { insert("()"); moveCursor(-1); }
        else QTextEdit::keyPressEvent(e); break;

    case Qt::Key_ParenRight:
        if(curChar() == ')') moveCursor(1);
        else QTextEdit::keyPressEvent(e); break;

    case Qt::Key_BraceLeft:
        insert("{}"); moveCursor(-1); break;

    case Qt::Key_BraceRight:
        if(curChar() == '}') moveCursor(1);
        else QTextEdit::keyPressEvent(e); break;

    case Qt::Key_Return:
    {
        QString text = document()->toPlainText(), space = "";
        int n = 0;

        for(int i = 0; i < pos(); i++) if(text.at(i) == '{') n++; else if(text.at(i) == '}') n--;
        space.fill(' ', 4*n);

        if(prevChar() == '{')
        {
            insert("\n" + space);
            if(curChar() == '}')
            {
                insert("\n" + space.left(space.length()-4));
                moveCursor(3-4*n);
            }
            break;
        }
        else if(curChar() == '}') { insert("\n" + space.left(space.length()-4)); break; }
        else { insert("\n" + space); break; }

        QTextEdit::keyPressEvent(e); break;
    }

    default: QTextEdit::keyPressEvent(e);
    }
}
示例#5
0
void TextEdit::deleteFromCursor(DeleteType type, Direction dir)
{
  if (!editable)
    return;

  assertUpdatedScreenLines();

  int count = 0;

  switch (type) {
    case DELETE_CHARS:
      count = moveLogicallyFromCursor(dir) - current_pos;
      break;
    case DELETE_WORD_ENDS:
      count = moveWordFromCursor(dir, true) - current_pos;
      break;
    default:
      g_assert_not_reached();
  }

  if (count) {
    const char *min = gapstart;
    const char *max = gapend;
    moveGapToCursor();

    while (count > 0) {
      gapend = nextChar(gapend);
      text_length--;
      count--;
    }

    while (count < 0) {
      gapstart = prevChar(gapstart);
      current_pos--;
      text_length--;
      count++;
    }
    point = gapstart;

    updateScreenLines(MIN(min, gapstart), MAX(max, gapend));
    updateScreenCursor();
    redraw();

    signal_text_change(*this);
  }
}
示例#6
0
QChar QComplexText::shapedCharacter( const QString &str, int pos, const QFontMetrics *fm )
{
    const QChar *ch = str.unicode() + pos;
    if ( ch->row() != 0x06 )
        return *ch;
    else {
        int shape = glyphVariantLogical( str, pos );
        //qDebug("mapping U+%x to shape %d glyph=0x%x", ch->unicode(), shape, arabicUnicodeMapping[ch->cell()][shape]);
        // lam aleph ligatures
        switch ( ch->cell() ) {
        case 0x44: { // lam
            const QChar *nch = nextChar( str, pos );
            if ( nch->row() == 0x06 ) {
                switch ( nch->cell() ) {
                case 0x22:
                case 0x23:
                case 0x25:
                case 0x27:
                    return QChar(arabicUnicodeLamAlefMapping[nch->cell() - 0x22][shape]);
                default:
                    break;
                }
            }
            break;
        }
        case 0x22: // alef with madda
        case 0x23: // alef with hamza above
        case 0x25: // alef with hamza below
        case 0x27: // alef
            if ( prevChar( str, pos )->unicode() == 0x0644 )
                // have a lam alef ligature
                return QChar(0);
        default:
            break;
        }
        return QChar( getShape( ch, ch->cell(), shape, fm ) );
    }
}
示例#7
0
static inline bool nextLogicalCharJoins( const QString &str, int pos)
{
    QChar::Joining join = prevChar( str, pos )->joining();
    return ( join == QChar::Dual || join == QChar::Center );
}
示例#8
0
static inline bool prevVisualCharJoins( const QString &str, int pos)
{
    return (     prevChar( str, pos )->joining() != QChar::OtherJoining );
}
示例#9
0
void TEditor::handleEvent( TEvent& event )
{
    TView::handleEvent( event );
    convertEvent( event );
    Boolean centerCursor = Boolean(!cursorVisible());
    uchar selectMode = 0;

    if( selecting == True || (getShiftState() & 0x03) != 0 )
        selectMode = smExtend;

    switch( event.what )
        {

        case evMouseDown:
            if( event.mouse.doubleClick == True )
                selectMode |= smDouble;

            do  {
                lock();
                if( event.what == evMouseAuto )
                    {
                    TPoint mouse = makeLocal( event.mouse.where );
                    TPoint d = delta;
                    if( mouse.x < 0 )
                        d.x--;
                    if( mouse.x >= size.x )
                        d.x++;
                    if( mouse.y < 0 )
                        d.y--;
                    if( mouse.y >= size.y )
                        d.y++;
                    scrollTo(d.x, d.y);
                    }
                setCurPtr(getMousePtr(event.mouse.where), selectMode);
                selectMode |= smExtend;
                unlock();
                } while( mouseEvent(event, evMouseMove + evMouseAuto) );
            break;

        case evKeyDown:
            if( event.keyDown.charScan.charCode == 9 ||
                ( event.keyDown.charScan.charCode >= 32 && event.keyDown.charScan.charCode < 255 ) )
                    {
                    lock();
                    if( overwrite == True && hasSelection() == False )
                        if( curPtr != lineEnd(curPtr) )
                            selEnd = nextChar(curPtr);
                    insertText( &event.keyDown.charScan.charCode, 1, False);
                    trackCursor(centerCursor);
                    unlock();
                    }
            else
                return;
            break;

        case evCommand:
            switch( event.message.command )
                {
                case cmFind:
                    find();
                    break;
                case cmReplace:
                    replace();
                    break;
                case cmSearchAgain:
                    doSearchReplace();
                    break;
                default:
                    lock();
                    switch( event.message.command )
                        {
                        case cmCut:
                            clipCut();
                            break;
                        case cmCopy:
                            clipCopy();
                            // hideSelect(); // JS 12.4.94
                            break;
                        case cmPaste:
                            clipPaste();
                            break;
                        case cmUndo:
                            undo();
                            break;
                        case cmClear:
                            deleteSelect();
                            break;
                        case cmCharLeft:
                            setCurPtr(prevChar(curPtr), selectMode);
                            break;
                        case cmCharRight:
                            setCurPtr(nextChar(curPtr), selectMode);
                            break;
                        case cmWordLeft:
                            setCurPtr(prevWord(curPtr), selectMode);
                            break;
                        case cmWordRight:
                            setCurPtr(nextWord(curPtr), selectMode);
                            break;
                        case cmLineStart:
                            setCurPtr(lineStart(curPtr), selectMode);
                            break;
                        case cmLineEnd:
                            setCurPtr(lineEnd(curPtr), selectMode);
                            break;
                        case cmLineUp:
                            setCurPtr(lineMove(curPtr, -1), selectMode);
                            break;
                        case cmLineDown:
                            setCurPtr(lineMove(curPtr, 1), selectMode);
                            break;
                        case cmPageUp:
                            setCurPtr(lineMove(curPtr, -(size.y-1)), selectMode);
                            break;
                        case cmPageDown:
                            setCurPtr(lineMove(curPtr, size.y-1), selectMode);
                            break;
                        case cmTextStart:
                            setCurPtr(0, selectMode);
                            break;
                        case cmTextEnd:
                            setCurPtr(bufLen, selectMode);
                            break;
                        case cmNewLine:
                            newLine();
                            break;
                        case cmBackSpace:
                            deleteRange(prevChar(curPtr), curPtr, True);
                            break;
                        case cmDelChar:
                            deleteRange(curPtr, nextChar(curPtr), True);
                            break;
                        case cmDelWord:
                            deleteRange(curPtr, nextWord(curPtr), False);
                            break;
                        case cmDelStart:
                            deleteRange(lineStart(curPtr), curPtr, False);
                            break;
                        case cmDelEnd:
                            deleteRange(curPtr, lineEnd(curPtr), False);
                            break;
                        case cmDelLine:
                            deleteRange(lineStart(curPtr), nextLine(curPtr), False);
                            break;
                        case cmInsMode:
                            toggleInsMode();
                            break;
                        case cmStartSelect:
                            startSelect();
                            break;
                        case cmHideSelect:
                            hideSelect();
                            break;
                        case cmIndentMode:
                            autoIndent = Boolean(!autoIndent);
                            break;
                        default:
                            unlock();
                            return;
                        }
                    trackCursor(centerCursor);
                    unlock();
                    break;
                }

        case evBroadcast:
            switch( event.message.command )
                {
                case cmScrollBarChanged:
                    checkScrollBar( event, hScrollBar, delta.x );
                    checkScrollBar( event, vScrollBar, delta.y );
                    break;
                default:
                    return;
                }
        }
    clearEvent(event);
}
示例#10
0
int TwordWrap::smart()
{
    int left = 0;
    int strlenp = (int)str.size();
    bool skippingSpace = false;
    int xx = 0;
    rightOfTheLines.clear();
    for (int x = 0; x < strlenp; x++) {
        if (skippingSpace || (pwidths[x] - left > splitdxMin && pwidths[x] - left <= splitdxMax)) { // ideal for line break.
            if (skippingSpace) {
                if (!iswspace(str.at(x))) {
                    skippingSpace = false;
                    left = x > 0 ? pwidths[x - 1] : 0;
                    xx = x;
                }
            } else {
                if (iswspace(str.at(x))) {
                    rightOfTheLines.push_back(x > 0 ? x - 1 : 0);
                    skippingSpace = true;
                }
            }
        }
        if (pwidths[x] - left > splitdxMax && !skippingSpace) { // Not ideal, but we have to break before current word.
            bool found = false;
            skippingSpace = false;
            for (; x > xx; x--) {
                if (pwidths[x] - left <= splitdxMax) {
                    if (iswspace(str.at(x))) {
                        rightOfTheLines.push_back(x > 0 ? x - 1 : 0);
                        left = pwidths[x];
                        xx = nextChar(x);
                        found = true;
                        break;
                    }
                }
            }
            // fail over : no space to cut. Japanese subtitles often come here.
            if (!found) {
                if (assCompatibleMode) {
                    for (; x < strlenp; x++) {
                        if (iswspace(str.at(x))) {
                            rightOfTheLines.push_back(x > 0 ? x - 1 : 0);
                            skippingSpace = true;
                            break;
                        }
                    }
                } else {
                    for (; x < strlenp; x++) {
                        if (pwidths[x] - left > splitdxMin) {
                            if (x > xx && pwidths[x] - left > splitdxMax) {
                                x = prevChar(x);
                            }
                            left = pwidths[x];
                            xx = nextChar(x);
                            rightOfTheLines.push_back(x);
                            break;
                        }
                    }
                }
            }
        }
    }
    rightOfTheLines.push_back(strlenp);
    return (int)rightOfTheLines.size();
}
示例#11
0
int TwordWrap::smartReverse()
{
    int strlenp = (int)str.size();
    int right = pwidths[strlenp - 1];
    bool skippingSpace = false;
    int xx = strlenp - 1;
    rightOfTheLines.clear();
    rightOfTheLines.push_front(xx);
    for (int x = strlenp - 1; x >= 0; x--) {
        if (skippingSpace || (right - pwidthsLeft(x) > splitdxMin && right - pwidthsLeft(x) <= splitdxMax)) { // ideal for line break.
            if (skippingSpace) {
                if (!iswspace(str.at(x))) {
                    skippingSpace = false;
                    right = pwidths[x];
                    xx = x;
                    rightOfTheLines.push_front(xx);
                }
            } else {
                if (iswspace(str.at(x))) {
                    skippingSpace = true;
                }
            }
        }
        if (right - pwidthsLeft(x) > splitdxMax && !skippingSpace) { // Not ideal, but we have to break after current word.
            bool found = false;
            skippingSpace = false;
            for (; x < xx; x++) {
                if (right - pwidths[x] <= splitdxMax) {
                    if (iswspace(str.at(x))) {
                        xx = x > 0 ? x - 1 : 0;
                        rightOfTheLines.push_front(xx);
                        right = pwidths[xx];
                        found = true;
                        break;
                    }
                }
            }
            // fail over : no space to cut. Japanese subtitles often come here.
            if (!found) {
                if (assCompatibleMode) {
                    for (; x >= 0; x--) {
                        if (iswspace(str.at(x))) {
                            skippingSpace = true;
                            break;
                        }
                    }
                } else {
                    for (; x >= 0; x--) {
                        if (right - pwidths[x] > splitdxMin) {
                            if (x < xx && right - pwidthsLeft(x) > splitdxMax) {
                                x = nextChar(x);
                            }
                            xx = prevChar(x);
                            rightOfTheLines.push_front(xx);
                            right = pwidths[xx];
                            break;
                        }
                    }
                }
            }
        }
    }
    return (int)rightOfTheLines.size();
}
ushort TEditor::prevLine( ushort p )
{
  return lineStart(prevChar(p));
}
示例#13
0
void TextEdit::moveCursor(CursorMovement step, Direction dir)
{
  assertUpdatedScreenLines();

  size_t old_pos = current_pos;
  switch (step) {
    case MOVE_LOGICAL_POSITIONS:
      current_pos = moveLogicallyFromCursor(dir);
      break;
    case MOVE_WORDS:
      current_pos = moveWordFromCursor(dir, false);
      break;
    case MOVE_DISPLAY_LINES:
      if (dir == DIR_FORWARD) {
        if (current_sc_line + 1 < screen_lines.size()) {
          int oldw = width(screen_lines[current_sc_line].start,
              current_sc_linepos);
          // first move to end of current line
          current_pos += screen_lines[current_sc_line].length
              - current_sc_linepos;
          // find a character close to the original position
          const char *ch = screen_lines[current_sc_line + 1].start;
          size_t i = 0;
          int w = 0;
          while (w < oldw
              && i < screen_lines[current_sc_line + 1].length - 1) {
            gunichar uc = g_utf8_get_char(ch);
            w += onScreenWidth(uc, w);
            ch = nextChar(ch);
            i++;
          }
          current_pos += i;
        }
      }
      else { // DIR_BACK
        if (current_sc_line > 0) {
          int oldw = width(screen_lines[current_sc_line].start,
              current_sc_linepos);
          // first move to start of current line
          current_pos -= current_sc_linepos;
          // move to the start of the previous line
          current_pos -= screen_lines[current_sc_line - 1].length;
          // find a character close to the original position
          const char *ch = screen_lines[current_sc_line - 1].start;
          size_t i = 0;
          int w = 0;
          while (w < oldw
              && i < screen_lines[current_sc_line - 1].length - 1) {
            gunichar uc = g_utf8_get_char(ch);
            w += onScreenWidth(uc, w);
            ch = nextChar(ch);
            i++;
          }
          current_pos += i;
        }
      }
      break;
    case MOVE_DISPLAY_LINE_ENDS:
      if (dir == DIR_FORWARD)
        current_pos += screen_lines[current_sc_line].length
          - current_sc_linepos - 1;
      else // DIR_BACK
        current_pos -= current_sc_linepos;
      break;
    default:
      g_assert_not_reached();
  }

  // update point
  while (old_pos > current_pos) {
    point = prevChar(point);
    old_pos--;
  }
  while (old_pos < current_pos) {
    point = nextChar(point);
    old_pos++;
  }

  updateScreenCursor();
  redraw();
}
示例#14
0
文件: Lex.c 项目: jonaskje/c1
int lex_nextToken(lex_Context* c)
{
	if (c->sourceCodeCursor == c->sourceCodeEnd) 
		return token(c, tokEOF);
	
	nextChar(c);
	if (c->c == '_' || isalpha(c->c)) {
		const char* idBegin = c->sourceCodeCursor - 1;
		while(c->sourceCodeCursor - idBegin < lex_MAX_ID_LENGTH) {
			nextChar(c);
			if (!(c->c == '_' || isalnum(c->c))) {
				prevChar(c);
				return tokenId(c, idBegin);
			}
		}
		return token(c, tokERROR_IDENTIFIER_TOO_LONG);
	}
	if (isdigit(c->c)) {
		const char* constBegin = c->sourceCodeCursor - 1;
		while(c->sourceCodeCursor - constBegin < lex_MAX_NUMCONST_LENGTH) {
			nextChar(c);
			if (!isdigit(c->c)) {
				prevChar(c);
				return tokenNumConst(c, constBegin);
			}
		}
		return token(c, tokERROR_NUMCONST_OVERFLOW);
	}
	for (;;)
	{
		switch(c->c) {
		case -1  : return token(c, tokEOF);
		case '\r': /* Fall through */
		case '\n':
			   for(;;) {
				   nextChar(c);
				   if (c->c != '\r' && c->c != '\n') {
					   prevChar(c);
					   break;
				   }
			   }
			   return token(c, tokNEWLINE);
		case '+' : return token(c, tokPLUS);
		case '-' : return token(c, tokMINUS);
		case '*' : return token(c, tokMULT);
		case '/' : return token(c, tokDIV);
		case '%' : return token(c, tokMOD);
		case '=' : return token(c, tokEQ);
		case '<' :
			   nextChar(c);
			   if (c->c == '>')
				   return token(c, tokNE);
			   else if (c->c == '=')
				   return token(c, tokLE);
			   else
				   prevChar(c);
			   return token(c, tokLT);
		case '>' :
			   nextChar(c);
			   if (c->c == '=')
				   return token(c, tokGE);
			   else
				   prevChar(c);
			   return token(c, tokGT);
		case ' ' : return token(c, tokWHITE);
		case '\t': return token(c, tokWHITE);
		case '(' : return token(c, tokLPAR);
		case ')' : return token(c, tokRPAR);
		case ':' : return token(c, tokCOLON);
		case ',' : return token(c, tokCOMMA);
		case '#' : /* comment */
			   for(;;) {
				   nextChar(c);
				   if (c->c == '\n' || c->c == -1) {
					   prevChar(c);
					   break;
				   }
			   }
			   break;
		default  : return token(c, tokERROR_ILLEGAL_CHARACTER);		   
		}	
	}
}