📄 tescreen.cpp
字号:
void TEScreen::BackSpace(){ cuX = QMAX(0,cuX-1); if (BS_CLEARS) image[loc(cuX,cuY)].c = ' ';}/**/void TEScreen::Tabulate(){ // note that TAB is a format effector (does not write ' '); cursorRight(1); while(cuX < columns-1 && !tabstops[cuX]) cursorRight(1);}void TEScreen::clearTabStops(){ for (int i = 0; i < columns; i++) tabstops[i-1] = FALSE;}void TEScreen::changeTabStop(bool set){ if (cuX >= columns) return; tabstops[cuX] = set;}void TEScreen::initTabStops(){ if (tabstops) free(tabstops); tabstops = (bool*)malloc(columns*sizeof(bool)); // Arrg! The 1st tabstop has to be one longer than the other. // i.e. the kids start counting from 0 instead of 1. // Other programs might behave correctly. Be aware. for (int i = 0; i < columns; i++) tabstops[i] = (i%8 == 0 && i != 0);}/* This behaves either as IND (Screen::Index) or as NEL (Screen::NextLine) depending on the NewLine Mode (LNM). This mode also affects the key sequence returned for newline ([CR]LF).*/void TEScreen::NewLine(){ if (getMode(MODE_NewLine)) Return(); index();}/*? put `c' literally onto the screen at the current cursor position. VT100 uses the convention to produce an automatic newline (am) with the *first* character that would fall onto the next line (xenl).*/void TEScreen::checkSelection(int from, int to){ if (sel_begin == -1) return; int scr_TL = loc(0, hist.getLines()); //Clear entire selection if it overlaps region [from, to] if ( (sel_BR > (from+scr_TL) )&&(sel_TL < (to+scr_TL)) ) { clearSelection(); }}void TEScreen::ShowCharacter(unsigned short c){ // Note that VT100 does wrapping BEFORE putting the character. // This has impact on the assumption of valid cursor positions. // We indicate the fact that a newline has to be triggered by // putting the cursor one right to the last column of the screen. if (cuX >= columns) { if (getMode(MODE_Wrap)) NextLine(); else cuX = columns-1; } if (getMode(MODE_Insert)) insertChars(1); int i = loc(cuX,cuY); checkSelection(i, i); // check if selection is still valid. image[i].c = c; image[i].f = ef_fg; image[i].b = ef_bg; image[i].r = ef_re; cuX += 1;}// Region commands -------------------------------------------------------------/* scroll up `n' lines within current region. The `n' new lines are cleared. \sa setRegion \sa scrollDown*/void TEScreen::scrollUp(int from, int n){ if (n <= 0 || from + n > bmargin) return; //FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds. moveImage(loc(0,from),loc(0,from+n),loc(columns-1,bmargin)); clearImage(loc(0,bmargin-n+1),loc(columns-1,bmargin),' ');}/* scroll down `n' lines within current region. The `n' new lines are cleared. \sa setRegion \sa scrollUp*/void TEScreen::scrollDown(int from, int n){//FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds. if (n <= 0) return; if (from > bmargin) return; if (from + n > bmargin) n = bmargin - from; moveImage(loc(0,from+n),loc(0,from),loc(columns-1,bmargin-n)); clearImage(loc(0,from),loc(columns-1,from+n-1),' ');}/* position the cursor to a specific \a y line and \a x column. */void TEScreen::setCursorYX(int y, int x){ setCursorY(y); setCursorX(x);}/* Set the cursor to \a x -th line. */void TEScreen::setCursorX(int x){ if (x == 0) x = 1; // Default x -= 1; // Adjust cuX = QMAX(0,QMIN(columns-1, x));}/* Set the cursor to \a y -th line. */void TEScreen::setCursorY(int y){ if (y == 0) y = 1; // Default y -= 1; // Adjust cuY = QMAX(0,QMIN(lines -1, y + (getMode(MODE_Origin) ? tmargin : 0) ));}/* set cursor to the `left upper' corner of the screen (1,1).*/void TEScreen::home(){ cuX = 0; cuY = 0;}/* set cursor to the begin of the current line.*/void TEScreen::Return(){ cuX = 0;}/* returns the current cursor columns.*/int TEScreen::getCursorX(){ return cuX;}/* returns the current cursor line.*/int TEScreen::getCursorY(){ return cuY;}// Erasing ---------------------------------------------------------------------/*? \section Erasing This group of operations erase parts of the screen contents by filling it with spaces colored due to the current rendition settings. Althought the cursor position is involved in most of these operations, it is never modified by them.*//* fill screen between (including) `loca' and `loce' with spaces. This is an internal helper functions. The parameter types are internal addresses of within the screen image and make use of the way how the screen matrix is mapped to the image vector.*/void TEScreen::clearImage(int loca, int loce, char c){ int i; int scr_TL=loc(0,hist.getLines()); //FIXME: check positions //Clear entire selection if it overlaps region to be moved... if ( (sel_BR > (loca+scr_TL) )&&(sel_TL < (loce+scr_TL)) ) { clearSelection(); } for (i = loca; i <= loce; i++) { image[i].c = c; image[i].f = ef_fg; //DEFAULT_FORE_COLOR; //FIXME: xterm and linux/ansi image[i].b = ef_bg; //DEFAULT_BACK_COLOR; // many have different image[i].r = ef_re; //DEFAULT_RENDITION; // ideas here. }}/* move image between (including) `loca' and `loce' to 'dst'. This is an internal helper functions. The parameter types are internal addresses of within the screen image and make use of the way how the screen matrix is mapped to the image vector.*/void TEScreen::moveImage(int dst, int loca, int loce){//FIXME: check positions if (loce < loca) { // kdDebug() << "WARNING!!! call to TEScreen:moveImage with loce < loca!" << endl; return; } memmove(&image[dst],&image[loca],(loce-loca+1)*sizeof(ca));}/* clear from (including) current cursor position to end of screen.*/void TEScreen::clearToEndOfScreen(){ clearImage(loc(cuX,cuY),loc(columns-1,lines-1),' ');}/* clear from begin of screen to (including) current cursor position.*/void TEScreen::clearToBeginOfScreen(){ clearImage(loc(0,0),loc(cuX,cuY),' ');}/* clear the entire screen.*/void TEScreen::clearEntireScreen(){ clearImage(loc(0,0),loc(columns-1,lines-1),' ');}/* fill screen with 'E' This is to aid screen alignment*/void TEScreen::helpAlign(){ clearImage(loc(0,0),loc(columns-1,lines-1),'E');}/* clear from (including) current cursor position to end of current cursor line.*/void TEScreen::clearToEndOfLine(){ clearImage(loc(cuX,cuY),loc(columns-1,cuY),' ');}/* clear from begin of current cursor line to (including) current cursor position.*/void TEScreen::clearToBeginOfLine(){ clearImage(loc(0,cuY),loc(cuX,cuY),' ');}/* clears entire current cursor line*/void TEScreen::clearEntireLine(){ clearImage(loc(0,cuY),loc(columns-1,cuY),' ');}// Rendition ------------------------------------------------------------------/* set rendition mode*/void TEScreen::setRendition(int re){ cu_re |= re; effectiveRendition();}/* reset rendition mode*/void TEScreen::resetRendition(int re){ cu_re &= ~re; effectiveRendition();}/**/void TEScreen::setDefaultRendition(){ setForeColorToDefault(); setBackColorToDefault(); cu_re = DEFAULT_RENDITION; effectiveRendition();}/**/void TEScreen::setForeColor(int fgcolor){ cu_fg = (fgcolor&7)+((fgcolor&8) ? 4+8 : 2); effectiveRendition();}/**/void TEScreen::setBackColor(int bgcolor){ cu_bg = (bgcolor&7)+((bgcolor&8) ? 4+8 : 2); effectiveRendition();}/**/void TEScreen::setBackColorToDefault(){ cu_bg = DEFAULT_BACK_COLOR; effectiveRendition();}/**/void TEScreen::setForeColorToDefault(){ cu_fg = DEFAULT_FORE_COLOR; effectiveRendition();}/* ------------------------------------------------------------------------- *//* *//* Marking & Selection *//* *//* ------------------------------------------------------------------------- */void TEScreen::clearSelection(){ sel_BR = -1; sel_TL = -1; sel_begin = -1;}void TEScreen::setSelBeginXY(const int x, const int y){ sel_begin = loc(x,y+histCursor) ; sel_BR = sel_begin; sel_TL = sel_begin;}void TEScreen::setSelExtentXY(const int x, const int y){ if (sel_begin == -1) return; int l = loc(x,y + histCursor); if (l < sel_begin) { sel_TL = l; sel_BR = sel_begin; } else { /* FIXME, HACK to correct for x too far to the right... */ if (( x == columns )|| (x == 0)) l--; sel_TL = sel_begin; sel_BR = l; }}QString TEScreen::getSelText(const BOOL preserve_line_breaks){ if (sel_begin == -1) return QString::null; // Selection got clear while selecting. int *m; // buffer to fill. int s, d; // source index, dest. index. int hist_BR = loc(0, hist.getLines()); int hY = sel_TL / columns; int hX = sel_TL % columns; int eol; // end of line s = sel_TL; // tracks copy in source. // allocate buffer for maximum // possible size... d = (sel_BR - sel_TL) / columns + 1; m = new int[d * (columns + 1) + 2]; d = 0; while (s <= sel_BR) { if (s < hist_BR) { // get lines from hist.history // buffer. eol = hist.getLineLen(hY); if ((hY == (sel_BR / columns)) && (eol >= (sel_BR % columns))) { eol = sel_BR % columns + 1; } while (hX < eol) { m[d++] = hist.getCell(hY, hX++).c; s++; } if (s <= sel_BR) { // The line break handling // It's different from the screen // image case! if (eol % columns == 0) { // That's either a completely filled // line or an empty line if (eol == 0) { m[d++] = '\n'; } else { // We have a full line. // FIXME: How can we handle newlines // at this position?! } } else if ((eol + 1) % columns == 0) { // FIXME: We don't know if this was a // space at the last position or a // short line!! m[d++] = ' '; } else { // We have a short line here. Put a // newline or a space into the // buffer. m[d++] = preserve_line_breaks ? '\n' : ' '; } } hY++; hX = 0; s = hY * columns; } else { // or from screen image. eol = (s / columns + 1) * columns - 1; if (eol < sel_BR) { while ((eol > s) && isspace(image[eol - hist_BR].c)) { eol--; } } else { eol = sel_BR; } while (s <= eol) { m[d++] = image[s++ - hist_BR].c; } if (eol < sel_BR) { // eol processing see below ... if ((eol + 1) % columns == 0) { if (image[eol - hist_BR].c == ' ') { m[d++] = ' '; } } else { m[d++] = ((preserve_line_breaks || ((eol % columns) == 0)) ? '\n' : ' '); } } s = (eol / columns + 1) * columns; } } QChar* qc = new QChar[d]; for (int i = 0; i < d; i++) { qc[i] = m[i]; } QString res(qc, d); delete m; delete qc; return res;}/* above ... end of line processing for selection -- psilvacases:1) (eol+1)%columns == 0 --> the whole line is filled. If the last char is a space, insert (preserve) space. otherwise leave the text alone, so that words that are broken by linewrap are preserved.FIXME: * this suppresses \n for command output that is sized to the exact column width of the screen.2) eol%columns == 0 --> blank line. insert a \n unconditionally. Do it either you would because you are in preserve_line_break mode, or because it's an ASCII paragraph delimiter, so even when not preserving line_breaks, you want to preserve paragraph breaks.3) else --> partially filled line insert a \n in preserve line break mode, else a space The space prevents concatenation of the last word of one line with the first of the next.*/void TEScreen::addHistLine(){ assert(hasScroll() || histCursor == 0); // add to hist buffer // we have to take care about scrolling, too... if (hasScroll()) { ca dft; int end = columns-1; while (end >= 0 && image[end] == dft) end -= 1; hist.addLine(image,end+1); // adjust history cursor histCursor += (hist.getLines()-1 == histCursor); } if (!hasScroll()) histCursor = 0; //FIXME: a poor workaround}void TEScreen::setHistCursor(int cursor){ histCursor = cursor; //FIXME:rangecheck}int TEScreen::getHistCursor(){ return histCursor;}int TEScreen::getHistLines(){ return hist.getLines();}void TEScreen::setScroll(bool on){ histCursor = 0; clearSelection(); hist.setScroll(on);}bool TEScreen::hasScroll(){ return hist.hasScroll();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -