📄 mimerichtextselect.c
字号:
if ( sendExcerpt ) for (i=0; i<curState->Excerpt(); i++) outbuf += excerptStr; for (i=0; i<curState->LIndent(); i++) outbuf += " "; }//// Get text// StringC tmpbuf; if ( begCmdPos == endCmdPos ) { if ( endStrPos > begStrPos ) { if ( cmd->IsText() ) tmpbuf = (*cmd->text)(begStrPos, endStrPos-begStrPos); else { tmpbuf.Clear(); cmd->graphic->GetText(tmpbuf); } CopyText(tmpbuf, outbuf, type, curState, lineSize); } } else {//// Grab the part from the start command// int len = cmd->LastPos() - begStrPos; if ( len > 0 ) { if ( cmd->IsText() ) tmpbuf = (*cmd->text)(begStrPos, len); else { tmpbuf.Clear(); cmd->graphic->GetText(tmpbuf); } CopyText(tmpbuf, outbuf, type, curState, lineSize); }//// Grab the text in between// curState = &cmd->state; for (i=begCmdPos+1; i<endCmdPos; i++) { cmd = tl->Cmd(i); if ( type != TT_PLAIN ) GetStateCommands(*curState, cmd->state, outbuf, type); curState = &cmd->state; if ( cmd->IsText() ) tmpbuf = *cmd->text; else { tmpbuf.Clear(); cmd->graphic->GetText(tmpbuf); } CopyText(tmpbuf, outbuf, type, curState, lineSize); }//// Grab the part from the end command// cmd = tl->Cmd(endCmdPos); if ( type != TT_PLAIN ) GetStateCommands(*curState, cmd->state, outbuf, type); curState = &cmd->state; if ( endStrPos > 0 ) { if ( cmd->IsText() ) tmpbuf = (*cmd->text)(0, endStrPos); else { tmpbuf.Clear(); cmd->graphic->GetText(tmpbuf); } CopyText(tmpbuf, outbuf, type, curState, lineSize); } } // End if there is more than one data segment} // End GetLineText/*---------------------------------------------------------------------- * Method to extract the text for the given line. */voidMimeRichTextP::GetLineText(TextLineC *line, StringC& outbuf, TextTypeT type, int lineSize){//// Add text segments// RichCmdC *cmd; TextStateC *curState; int i; if ( type != TT_PLAIN ) { TextPosC thisPos(line, 0, 0); GetStateCommands(thisPos, outbuf, type); } else { cmd = line->Cmd(0); curState = &cmd->state; if ( sendExcerpt ) for (i=0; i<curState->Excerpt(); i++) outbuf += excerptStr; for (i=0; i<curState->LIndent(); i++) outbuf += " "; } StringC tmpbuf; TextStateC *prevState = NULL; unsigned count = line->cmdList.size(); for (i=0; i<count; i++) { cmd = line->Cmd(i);//// See if we need any commands// curState = &cmd->state; if ( prevState && type != TT_PLAIN ) GetStateCommands(*prevState, *curState, outbuf, type); if ( cmd->IsText() ) tmpbuf = *cmd->text; else { tmpbuf.Clear(); cmd->graphic->GetText(tmpbuf); } CopyText(tmpbuf, outbuf, type, curState, lineSize); prevState = curState; } // End for each command} // End GetLineText/*---------------------------------------------------------------------- * Method to produce the commands required to change to the state at the * specified position. */voidMimeRichTextP::GetStateCommands(TextPosC& pos, StringC& outbuf, TextTypeT type){//// See if the state has changed since the last state// TextPosC prevPos; TextStateC *curState = pos.State(); if ( FindPosPrevCmd(pos, &prevPos) ) { TextStateC *prevState = prevPos.State(); GetStateCommands(*prevState, *curState, outbuf, type); } else { TextStateC nullState; GetStateCommands(nullState, *curState, outbuf, type); }} // End GetStateCommands#if 0/*---------------------------------------------------------------------- * Function to compare the colors in two states */static BooleanColorsEqual(TextStateC& state1, TextStateC& state2){ PixelListC& list1 = state1.ColorStack(); PixelListC& list2 = state2.ColorStack(); u_int len1 = list1.size(); u_int len2 = list2.size(); if ( len1 != len2 ) return False; for (int i=0; i<len1; i++) if ( *list1[i] != *list2[i] ) return False; return True;}#endif/*---------------------------------------------------------------------- * Method to produce the commands required to change between the 2 states */voidMimeRichTextP::GetStateCommands(TextStateC& state1, TextStateC& state2, StringC& outbuf, TextTypeT type){ if ( state1 == state2 ) return;//// We will turn off any fonts in 1 but not in 2// We will turn on any fonts in 2 but not in 1// StringC fonts1, fonts2; StringC jus1, jus2;// PixelListC col1, col2; StringC *link1 = state1.PLink(); StringC *link2 = state2.PLink(); if ( link1 && link2 && *link1 == *link2 ) { link1 = link2 = NULL; } if ( state1.FontStack() != state2.FontStack() ) { fonts1 = state1.FontStack(); fonts2 = state2.FontStack(); int len1 = fonts1.size(); int len2 = fonts2.size(); int len = MIN(len1, len2); int fpos = 0;//// Remove common elements// while (fpos<len && fonts1[fpos] == fonts2[fpos]) fpos++; if ( fpos > 0 ) { fonts1(0,fpos) = ""; fonts2(0,fpos) = ""; } }//// We will turn off any justification in 1 but not in 2// We will turn on any justification in 2 but not in 1// if ( state1.JustStack() != state2.JustStack() ) { jus1 = state1.JustStack(); jus2 = state2.JustStack(); int len1 = jus1.size(); int len2 = jus2.size(); int len = MIN(len1, len2); int jpos = 0;//// Skip over common elements// while (jpos<len && jus1[jpos] == jus2[jpos]) jpos++; if ( jpos > 0 ) { jus1(0,jpos) = ""; jus2(0,jpos) = ""; } }//// Turn off any fonts, starting at the end and working forward// if ( fonts1.size() > 0 ) { int size = fonts1.size(); for (int i=size-1; i>=0; i--) { switch (fonts1[i]) { case (FC_BOLD): outbuf += "</Bold>"; break; case (FC_ITALIC): outbuf += "</Italic>"; break; case (FC_FIXED): outbuf += "</Fixed>"; break; case (FC_SMALLER): outbuf += "</Smaller>"; break; case (FC_BIGGER): outbuf += "</Bigger>"; break; } } }//// Turn off current color if it changes any colors// Pixel *col1 = NULL; Pixel *col2 = NULL; Pixel p1, p2; if ( state1.ColorCmdCount() > 0 ) { p1 = state1.CurColor(); col1 = &p1; } if ( state2.ColorCmdCount() > 0 ) { p2 = state2.CurColor(); col2 = &p2; } Boolean colorChange = ((col1 && col2 && (*col1 != *col2)) || (col1 && !col2) || (col2 && !col1)); if ( colorChange && col1 ) outbuf += "</X-Color>";//// Turn off any links// if ( link1 ) outbuf += "</X-Link>";//// Turn off any underlining// if ( state2.Underline() < state1.Underline() ) { int diff = state1.Underline() - state2.Underline(); for (int i=0; i<diff; i++) outbuf += "</Underline>"; }//// Turn off any justification// if ( jus1.size() > 0 ) { int size = jus1.size(); for (int i=size-1; i>=0; i--) { switch (jus1[i]) { case (JC_LEFT): outbuf += "</FlushLeft>"; break; case (JC_RIGHT): outbuf += "</FlushRight>"; break; case (JC_BOTH): outbuf += "</FlushBoth>"; break; case (JC_CENTER): outbuf += "</Center>"; break; case (JC_NOFILL): outbuf += "</NoFill>"; break; } } }//// Turn off any indenting// if ( state2.RIndent() < state1.RIndent() ) { int diff = state1.RIndent() - state2.RIndent(); for (int i=0; i<diff; i++) outbuf += "</IndentRight>"; } if ( state2.LIndent() < state1.LIndent() ) { int diff = state1.LIndent() - state2.LIndent(); for (int i=0; i<diff; i++) outbuf += "</Indent>"; } if ( sendExcerpt && (state2.Excerpt() < state1.Excerpt()) ) { int diff = state1.Excerpt() - state2.Excerpt(); for (int i=0; i<diff; i++) outbuf += "</Excerpt>"; }//// Look for things turning on// if ( sendExcerpt && (state2.Excerpt() > state1.Excerpt()) ) { int diff = state2.Excerpt() - state1.Excerpt(); for (int i=0; i<diff; i++) outbuf += "<Excerpt>"; } if ( state2.LIndent() > state1.LIndent() ) { int diff = state2.LIndent() - state1.LIndent(); for (int i=0; i<diff; i++) outbuf += "<Indent>"; } if ( state2.RIndent() > state1.RIndent() ) { int diff = state2.RIndent() - state1.RIndent(); for (int i=0; i<diff; i++) outbuf += "<IndentRight>"; }//// Turn on any justification// if ( jus2.size() > 0 ) { int size = jus2.size(); for (int i=0; i<size; i++) { switch (jus2[i]) { case (JC_LEFT): outbuf += "<FlushLeft>"; break; case (JC_RIGHT): outbuf += "<FlushRight>"; break; case (JC_BOTH): outbuf += "<FlushBoth>"; break; case (JC_CENTER): outbuf += "<Center>"; break; case (JC_NOFILL): outbuf += "<NoFill>"; break; } } }//// Turn on any underlining// if ( state2.Underline() > state1.Underline() ) { int diff = state2.Underline() - state1.Underline(); for (int i=0; i<diff; i++) outbuf += "<Underline>"; }//// Turn on any links// if ( link2 ) { outbuf += "<X-Link><Param>"; outbuf += *link2; outbuf += "</Param>"; }//// Turn on any colors// if ( colorChange && col2 ) { outbuf += "<X-Color><Param>"; outbuf += ColorName(textDA, *col2); outbuf += "</Param>"; }//// Turn on any fonts// if ( fonts2.size() > 0 ) { int size = fonts2.size(); for (int i=0; i<size; i++) { switch (fonts2[i]) { case (FC_BOLD): outbuf += "<Bold>"; break; case (FC_ITALIC): outbuf += "<Italic>"; break; case (FC_FIXED): outbuf += "<Fixed>"; break; case (FC_SMALLER): outbuf += "<Smaller>"; break; case (FC_BIGGER): outbuf += "<Bigger>"; break; } } }} // End GetStateCommands/*---------------------------------------------------------------------- * Action proc to copy of selection to clipboard. This is a noop since * the text is copied when the selection takes place. */voidMimeRichTextP::ActCopySelection(Widget, XKeyEvent*, String*, Cardinal*){} // End ActCopySelection/*---------------------------------------------------------------------- * Action proc to handle release of paste selection button */voidMimeRichTextP::ActPaste(Widget w, XEvent *ev, String*, Cardinal*){ if ( debuglev > 1 ) cout <<"Paste" <<endl; MimeRichTextC *This; XtVaGetValues(w, XmNuserData, &This, NULL); if ( !This->priv->editable ) { XBell(halApp->display, 0); return; }//// See what type of data is available. ReceiveTargets will complete// the paste.// This->priv->mousePaste = (ev->type == ButtonPress || ev->type == ButtonRelease); XButtonEvent *bev = new XButtonEvent; *bev = *(XButtonEvent*)ev; // ev goes away; we need a copy XtGetSelectionValue(w, XA_PRIMARY, XA_TARGETS(halApp->display), (XtSelectionCallbackProc)ReceiveTargets, bev, bev->time);} // End ActPaste/*---------------------------------------------------------------------- * Callback to handle return of target types */voidMimeRichTextP::ReceiveTargets(Widget w, XtPointer clientData, Atom*, Atom *type, XtPointer val, unsigned long *len, int*){ MimeRichTextC *This; XtVaGetValues(w, XmNuserData, &This, NULL); XButtonEvent *ev = (XButtonEvent*)clientData;//// Check for valid data// if ( val == NULL || *len == 0 || *type == XT_CONVERT_FAIL || *type != XA_ATOM ) { delete ev; return; }//// We have been sent a list of atoms that can be sent by the selection owner.// See if enriched is supported.// Atom* targetP = (Atom*)val; unsigned atomCount = (unsigned)*len; Boolean enrichedOk = False; if ( This->priv->textType == TT_ENRICHED ) { while ( atomCount > 0 ) { if ( *targetP == mimeRichAtom ) enrichedOk = True; atomCount--; targetP++; } }//// Use the clipboard if we own the selection but it is not active.// Window swin = XGetSelectionOwner(halApp->display, XA_PRIMARY); if ( swin == XtWindow(This->priv->textDA) && !This->priv->selectOn ) { int status; u_long clipLen; char *format = (char *) ((enrichedOk) ? MIME_ENRICHED_ATOM_NAME : "STRING"); do { status = XmClipboardInquireLength(halApp->display, swin, format, &clipLen); } while ( status == ClipboardLocked ); if ( clipLen > 0 && status != ClipboardNoData ) {//// Allocate memory for selection data. This memory will be freed by the// Intrinsics since we didn't register an XtSelectionDoneProc// char *out = XtMalloc((Cardinal)clipLen+1); long privId; u_long len; do { status = XmClipboardRetrieve(halApp->display, swin, format, out, clipLen, &len, &privId); } while ( status == ClipboardLocked ); out[len] = 0; len = strlen(out); CharC buffer(out, (u_int)len); This->priv->PasteText(w, ev, enrichedOk ? TT_ENRICHED : TT_PLAIN, buffer); delete ev; return; } // End if clipboard has data } // End if getting data from clipboard//// If we get here, request the selection// XtGetSelectionValue(w, XA_PRIMARY, enrichedOk ? mimeRichAtom : XA_STRING, (XtSelectionCallbackProc)ReceiveSelection, ev, ev->time);} // End ReceiveTargets/*---------------------------------------------------------------------- * Callback to handle paste of primary selection */voidMimeRichTextP::ReceiveSelection(Widget w, XtPointer clientData, Atom*, Atom *type, XtPointer val, unsigned long *len, int*){ //cout <<"ReceiveSelection " << *selection << " of type " << *type NL; MimeRichTextC *This; XtVaGetValues(w, XmNuserData, &This, NULL); XButtonEvent *ev = (XButtonEvent*)clientData;//// Check for valid data// if ( val == NULL || *len == 0 || *type == XT_CONVERT_FAIL || (*type != XA_STRING && *type != mimeRichAtom) ) { delete ev;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -