📄 mimerichtextselect.c
字号:
return; } CharC buffer((char*)val, (unsigned)*len); This->priv->PasteText(w, ev, (*type == mimeRichAtom) ? TT_ENRICHED : TT_PLAIN, buffer); delete ev;} // End ReceiveSelection/*---------------------------------------------------------------------- * Method to paste text at specified position */voidMimeRichTextP::PasteText(Widget w, XButtonEvent *ev, TextTypeT type, CharC data){ halApp->BusyCursor(True); if ( selectOn ) DrawSelection(); // turn it off if ( mousePaste ) pub->MoveCursor(w, ev->x, ev->y);//// If there is a selection and the click is inside it, reset the selection// range// if ( selectOn ) { TextPosC *begPos = &selectBegPos; TextPosC *endPos = &selectEndPos; if ( *begPos > *endPos ) { begPos = &selectEndPos; endPos = &selectBegPos; } if ( cursorPos >= *begPos && cursorPos <= *endPos ) { selectBegPos = cursorPos; selectEndPos = cursorPos; selectOn = False; } }//// Add the data// TextTypeT saveType = textType; textType = type; pub->InsertString(data);//// Move cursor to end of string// if ( mousePaste ) { HideCursor(); u_int count = inputLine->cmdList.size(); for (int i=0; i<count; i++) { RichCmdC *cmd = inputLine->Cmd(i); if ( cmd == inputCmd ) { cursorPos.Set(inputLine, i, cmd->LastPos()); i = count; } }//// Keep the cursor visible// ScrollToCursor(); ScreenPosC spos = cursorPos; desiredCursorX = spos.x; ShowCursor(); } // End if this was a mouse paste textType = saveType;//// Redraw the selection// if ( selectOn ) DrawSelection(); // turn it on halApp->BusyCursor(False);} // End PasteText/*----------------------------------------------------------------------- * Reset the click count after this timeout */voidMimeRichTextP::ClickReset(MimeRichTextP *This, XtIntervalId*){ //if ( debuglev > 1 ) cout <<"Click timed out" <<endl; This->clickCount = 0; This->clickTimer = (XtIntervalId)NULL;//// A multi-click effectively ends the selection// if ( This->okToEndSelection ) ActSelectEnd(This->clickWidget, &This->clickEvent, NULL, NULL);}/*--------------------------------------------------------------- * Draws the selection region using XOR mode. May turn it on, may turn it off. * Depends on whether it was on or off previously. */voidMimeRichTextP::DrawSelection(){ DrawSelectionRange(&selectBegPos, &selectEndPos);}voidMimeRichTextP::DrawSelectionRange(TextPosC *begPos, TextPosC *endPos){ if ( !begPos->textLine || !endPos->textLine || *begPos == *endPos ) return;//// Swap points if they are reversed// if ( *begPos > *endPos ) { TextPosC *tmpPos = begPos; begPos = endPos; endPos = tmpPos; } ScreenPosC begScr = *begPos; ScreenPosC endScr = *endPos; int begX = begScr.x + 1; int endX = endScr.x; SoftLineC *begLine = begScr.softLine; SoftLineC *endLine = endScr.softLine; if ( !begLine || !endLine ) return; HideCursor(); Drawable drawto = textPm ? textPm : textWin; RectC visArea(hsbVal, vsbVal, drawWd, drawHt); if ( begLine == endLine ) { int wd = endX - begX + 1; if ( wd > 0 ) { int y = begLine->bounds.ymin - lineSpacing; int ht = begLine->bounds.ht + lineSpacing; if (y < 0) { ht += y; y = 0; } RectC lineArea(begX, y, wd, ht); if ( visArea.OverlapsY(lineArea) ) { XSetFunction(halApp->display, textGC, GXxor); XSetForeground(halApp->display, textGC, cursorColor); if ( debuglev > 1 ) cout <<"Drawing selection: " <<begX <<" " <<y <<" " <<wd <<" " <<ht <<endl; XFillRectangle(halApp->display, drawto, textGC, begX-hsbVal, y-vsbVal, wd, ht); XSetFunction(halApp->display, textGC, GXcopy); XSetForeground(halApp->display, textGC, fgColor); } } } // End if just one line else { XSetFunction(halApp->display, textGC, GXxor); XSetForeground(halApp->display, textGC, cursorColor);// int rightX = drawWd - 1;//// Select to the end of the start line//// int wd = rightX - begX + 1; int wd = drawWd - (begX - hsbVal); int y; int ht; if ( wd > 0 && visArea.OverlapsY(begLine->bounds) ) { y = begLine->bounds.ymin - lineSpacing; ht = begLine->bounds.ht + lineSpacing; if (y < 0) { ht += y; y = 0; } if ( debuglev > 1 ) cout <<"Drawing selection: " <<begX <<" " <<y <<" " <<wd <<" " <<ht <<endl; XFillRectangle(halApp->display, drawto, textGC, begX-hsbVal, y-vsbVal, wd, ht); }//// Select all lines between start and end line// SoftLineC *sline = begScr.softLine->next; while ( sline && sline != endScr.softLine ) { int x = sline->bounds.xmin;// wd = rightX - x + 1; wd = drawWd - (x - hsbVal); if ( wd > 0 && visArea.OverlapsY(sline->bounds) ) { y = sline->bounds.ymin - lineSpacing; ht = sline->bounds.ht + lineSpacing; if (y < 0) { ht += y; y = 0; } if ( debuglev > 1 ) cout <<"Drawing selection: " <<x <<" " <<y <<" " <<wd <<" " <<ht <<endl; XFillRectangle(halApp->display, drawto, textGC, x-hsbVal, y-vsbVal, wd, ht); } sline = sline->next; } // End for each intermediate line//// Select from the beginning of the end line// wd = endX - endLine->bounds.xmin + 1; if ( wd > 0 && visArea.OverlapsY(endLine->bounds) ) { y = endLine->bounds.ymin - lineSpacing; ht = endLine->bounds.ht + lineSpacing; if (y < 0) { ht += y; y = 0; } if ( debuglev > 1 ) cout <<"Drawing selection: " <<endLine->bounds.xmin <<" " <<y <<" " <<wd <<" " <<ht <<endl; XFillRectangle(halApp->display, drawto, textGC, endLine->bounds.xmin-hsbVal, y-vsbVal, wd, ht); } XSetFunction(halApp->display, textGC, GXcopy); XSetForeground(halApp->display, textGC, fgColor); } // End if more than one line selected if ( drawto != textWin ) XCopyArea(halApp->display, drawto, textWin, textGC, 0, 0, drawWd, drawHt, 0, 0); ShowCursor();} // End DrawSelectionRange/*--------------------------------------------------------------- * Method to find the line containing the specified y position */SoftLineC*MimeRichTextP::PickLine(int y){//// Loop through the line list and look for one containing the position.// SoftLineC *pickLine = NULL; TextLineC *tline = topTextLine; while ( tline ) {//// Loop until we hit the correct text line// if ( tline->bounds.ymax >= y ) { SoftLineC *sline = tline->softLine; while ( sline && sline->textLine == tline && !pickLine ) {//// Loop until we hit the correct soft line// if ( sline->bounds.ymax >= y ) {//// Back up if we've gone past.// if ( sline->bounds.ymin > y && sline->prev ) sline = sline->prev;//// This should be the one// pickLine = sline; } sline = sline->next; } // End for each soft line if ( !pickLine && tline->softLine ) { sline = tline->softLine; if ( y <= sline->bounds.ymin ) pickLine = sline; else pickLine = NULL; } } // End if we hit the correct text line tline = tline->next; } // End for each text line if ( !pickLine && topSoftLine ) { SoftLineC *sline = topSoftLine; if ( y <= sline->bounds.ymin ) pickLine = sline; else pickLine = NULL; } return pickLine;} // End PickLine/*--------------------------------------------------------------- * Method to move the cursor as close as possible to the specified x,y */voidMimeRichTextC::MoveCursor(Widget w, int x, int y){ priv->HideCursor();//// Take scrolling into account// x += priv->hsbVal; y += priv->vsbVal;//// Find the line under the cursor// SoftLineC *pline = priv->PickLine(y); if ( !pline ) { pline = priv->botSoftLine; if ( pline ) x = pline->bounds.xmax; } ScreenPosC spos(pline, x); priv->cursorPos = spos;//// Update the cursor// priv->ScrollToCursor(); priv->desiredCursorX = spos.x; priv->ShowCursor();} // End MoveCursor(int,int)/*----------------------------------------------------------------------- * distance between 2 screen positions */intMimeRichTextP::Distance(ScreenPosC& sp1, ScreenPosC& sp2){ if ( !sp1.softLine || !sp2.softLine ) return 0; if ( sp1.softLine == sp2.softLine ) return abs(sp1.x - sp2.x); ScreenPosC *pos1, *pos2; if ( sp1.softLine->bounds.ymin < sp2.softLine->bounds.ymin ) { pos1 = &sp1; pos2 = &sp2; } else { pos1 = &sp2; pos2 = &sp1; }//// Find the distance to the end of line1// int sum = drawWd - pos1->x;//// Add the distance from the beginning of line2// sum += pos2->x;//// Count the lines in between// SoftLineC *sline = pos1->softLine->next; while ( sline && sline != pos2->softLine ) { sum += drawWd; sline = sline->next; } return sum;} // End Distance/*--------------------------------------------------------------- * Method to return the position in the data block nearest to the specified x */intRichDrawDataC::Snap(int snapX){ if ( snapX < x ) snapX = x; else if ( snapX >= x + width ) snapX = x + width - 1; else { // Somewhere in the middle//// Add characters until we reach the x position// int dir, asc, dsc; XCharStruct size; int len = 1; char *cs = string; int curX = x; int origX = snapX; int dist = abs(origX - curX); int minDist = dist; snapX = curX; while ( dist <= minDist && len < string.size() ) { XTextExtents(font->xfont, cs, len, &dir, &asc, &dsc, &size); curX = x + size.width - 1; dist = abs(origX - curX); if ( dist < minDist ) { minDist = dist; snapX = curX; } len++; } } // End if position in the middle return snapX;} // End RichDrawDataC::Snap/*--------------------------------------------------------------- * Method to return the position in the data block nearest to the specified x */intRichDrawDataC::CharPos(int charX){ int charPos; if ( charX <= x ) charPos = 0; else if ( charX >= x + width ) charPos = string.size(); else { // Somewhere in the middle RichCmdC *cmd = softLine->textLine->Cmd(cmdPos); if ( cmd->IsText() ) {//// Add characters until we reach the x position. The position should already// be snapped.// int dir, asc, dsc; XCharStruct size; int len = 1; char *cs = string; int curX = x; XTextExtents(font->xfont, cs, len, &dir, &asc, &dsc, &size); curX = x + size.width - 1; while ( curX < charX && len < string.size() ) { len++; XTextExtents(font->xfont, cs, len, &dir, &asc, &dsc, &size); curX = x + size.width - 1; } charPos = len; } // End if we're in a text command else { int minDist = charX - x; int maxDist = x + width - charX; if ( minDist < maxDist ) charPos = 0; else charPos = 1; } } // End if position in the middle return charPos;} // End CharPos/*----------------------------------------------------------------------- * Find the leftmost character that belongs to the current character class. */BooleanMimeRichTextP::FindPosBegClass(TextPosC& curPos, TextPosC *newPos){ TextLineC *tl = curPos.textLine; RichCmdC *cmd = tl->Cmd(curPos.cmdPos); *newPos = curPos;//// If we're on a graphic command, just use that one// if ( cmd->IsGraphic() ) { newPos->Set(tl, curPos.cmdPos, 0); return True; }//// We must be on a text command// StringC *str = tl->Text(curPos.cmdPos); unsigned strSize = str->size(); if ( strSize == 0 ) return True; int charPos = curPos.strPos; if ( charPos == strSize ) charPos--;//// Find the character class of the current character// char curChar = (*str)[charPos]; int curClass = charClasses[curChar];//// Look to the left// int strPos = charPos - 1; while ( strPos >= 0 && charClasses[(*str)[strPos]] == curClass ) strPos--;//// If we're still good, look in other text strings// int cmdPos = curPos.cmdPos; Boolean done = False; while ( !done && strPos < 0 && cmdPos > 0 ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -