mimerichtextinit.c
来自「linux下的E_MAIL客户端源码」· C语言 代码 · 共 2,162 行 · 第 1/5 页
C
2,162 行
TextTypeT saveType = priv->textType; priv->textType = TT_RICH;//// Create text command if necessary// if ( !priv->inputCmd->IsText() ) { RichCmdC *rcmd = new RichCmdC(RC_TEXT); rcmd->state = priv->inputCmd->state; priv->inputLine->AddCommand(rcmd, /*after*/priv->inputCmd); priv->inputCmd = rcmd; } char comment = 0; static StringC *cmd = NULL; if ( !cmd ) cmd = new StringC;//// Loop through input// u_int i = 0; if ( priv->checkFroms && priv->BeginningOfInputLine() && cs.StartsWith(">From ") ) i++; while ( i < cs.Length() ) { char c = cs[i];//// Look at current character// if ( c == '<' ) { c = cs[++i];//// Get command// Boolean negate = False; if ( c == '/' ) { negate = True; c = cs[++i]; } cmd->Clear(); int pos = cs.PosOf('>', i); if ( pos >= 0 ) { *cmd = cs(i, (u_int)pos-i); i = pos + 1; c = cs[i]; }//// If we're in a comment, the only thing we'll recognize is more comment// commands.// if ( comment ) { if ( strcasecmp(*cmd, "comment") == 0 ) { comment += (negate ? -1: 1);#ifdef __CHAR_UNSIGNED__ if ( comment > 127 ) comment = 0;#else if ( comment < 0 ) comment = 0;#endif } } else {//// Process command// if ( strcasecmp(*cmd, "nl") == 0 ) priv->NewInputLine(); else if ( strcasecmp(*cmd, "np") == 0 || strcasecmp(*cmd, "paragraph") == 0 ) { priv->NewInputLine(); priv->NewInputLine(); } else if ( strcasecmp(*cmd, "lt") == 0 ) priv->inputTextBuf += '<'; else if ( strcasecmp(*cmd, "comment") == 0 ) { comment += (negate ? -1: 1);#ifdef __CHAR_UNSIGNED__ if ( comment > 127 ) comment = 0;#else if ( comment < 0 ) comment = 0;#endif } else if ( !AddCommand(*cmd, negate) ) { // Unknown command if ( priv->inputTextBuf.size() > 0 && !isspace(priv->inputTextBuf.LastChar()) ) priv->inputTextBuf += ' '; } } // End if not in comment } // End if left angle else if ( c == '\n' ) { c = cs[++i]; if ( c && c != '\n' && !comment ) // Single newline becomes space priv->inputTextBuf += ' ';//// Skip > if necessary// if ( priv->checkFroms && cs.StartsWith(">From ", i) ) c = cs[++i]; } // End if found a newline else { // Printable character if ( !comment ) priv->inputTextBuf += c; i++; } } // End for each input character//// Transfer final text// priv->FlushTextBuf(); priv->textType = saveType;//// Redraw if necessary// priv->changed = True; if ( !priv->defer ) { Refresh(); CallCallbacks(priv->changeCalls, this); } if ( cs.Length() > 10000 ) halApp->BusyCursor(False);} // End AddStringRichtext/*---------------------------------------------------------------------- * Set text string in plaintext mode */voidMimeRichTextC::AddStringPlain(CharC cs){ if ( cs.Length() > 10000 ) halApp->BusyCursor(True); TextTypeT saveType = priv->textType; priv->textType = TT_PLAIN;//// Create text command if necessary// if ( !priv->inputCmd->IsText() ) { RichCmdC *rcmd = new RichCmdC(RC_TEXT); rcmd->state = priv->inputCmd->state; priv->inputLine->AddCommand(rcmd, /*after*/priv->inputCmd); priv->inputCmd = rcmd; } u_int offset = 0; if ( priv->checkFroms && priv->BeginningOfInputLine() && cs.StartsWith(">From ", offset) ) offset++;//// Loop through input. For each newline, create a text line// int nlPos = cs.PosOf('\n'); while ( nlPos >= 0 ) { priv->inputTextBuf = cs(offset, nlPos-offset); priv->NewInputLine(); offset = nlPos + 1; if ( priv->checkFroms && cs.StartsWith(">From ", offset) ) offset++; nlPos = cs.PosOf('\n', offset); }//// Transfer final text// u_int len = cs.Length() - offset; if ( len > 0 ) { priv->inputTextBuf = cs(offset, len); priv->FlushTextBuf(); } priv->textType = saveType;//// Redraw if necessary// priv->changed = True; if ( !priv->defer ) { Refresh(); CallCallbacks(priv->changeCalls, this); } if ( cs.Length() > 10000 ) halApp->BusyCursor(False);} // End AddStringPlain/*---------------------------------------------------------------------- * Set text string in HTML mode */voidMimeRichTextC::AddStringHTML(CharC cs){ AddStringPlain(cs);}/*---------------------------------------------------------------------- * Copy text buffer to current input line's command buffer */voidMimeRichTextP::FlushTextBuf(){ static Boolean flushing = False; if ( flushing || !inputCmd || inputTextBuf.size() == 0 ) return; flushing = True;//// remove extra whitespace if we're filling// Boolean fillOk = False;// (textType != TT_PLAIN && inputCmd->state.CurJustCmd() != JC_NOFILL); if ( fillOk ) { Boolean prevWhite = inputLastWhite;//// make a pass and see if there are any spaces to be removed// char *ip = inputTextBuf; char *ep = ip + inputTextBuf.size(); Boolean needsFill = False; while ( !needsFill && ip < ep ) {// Boolean thisWhite = isspace(*ip); Boolean thisWhite = (*ip == ' '); needsFill = (prevWhite && thisWhite);// prevWhite = thisWhite; prevWhite = isspace(*ip); ip++; } if ( needsFill ) { prevWhite = inputLastWhite; char *newBuf = new char[inputTextBuf.size()+1]; char *op = newBuf; ip = inputTextBuf; while ( ip < ep ) {// Boolean thisWhite = isspace(*ip); Boolean thisWhite = (*ip == ' '); if ( !thisWhite || !prevWhite ) *op++ = *ip;// prevWhite = thisWhite; prevWhite = isspace(*ip); ip++; } *op = 0; inputTextBuf = newBuf; delete newBuf; } // End if this string needs filling } // End if filling is ok//// Look for URL's in non-editable text only. It's too hard to keep looking// for them if the user can make changes.// CharC range = inputTextBuf; if ( !editable && range.Contains(':') && ( range.Contains("http://") || range.Contains("https://") || range.Contains("ftp://") || range.Contains("gopher://") || range.Contains("telnet://") || range.Contains("mailto:") || range.Contains("afs://") || range.Contains("file:/") || range.Contains("news:") || range.Contains("nntp:") || range.Contains("mid:") || range.Contains("cid:") || range.Contains("wais://") || range.Contains("prospero://") ) ) { FlushTextURL(range); }//// copy current text buffer// else { if ( debuglev > 1 ) cout <<"Adding text ^" <<inputTextBuf <<"^" <<endl; *inputCmd->text += inputTextBuf; } inputLastWhite = isspace(inputTextBuf.LastChar()); inputTextBuf.Clear(); flushing = False;} // End FlushTextBuf/*---------------------------------------------------------------------- * See if text is a valid URL prefix */static BooleanIsURL(CharC text){ return ( text.Equals("http://") || text.Equals("https://") || text.Equals("ftp://") || text.Equals("gopher://") || text.Equals("telnet://") || text.Equals("mailto:") || text.Equals("afs://") || text.Equals("file:/") || text.Equals("news:") || text.Equals("nntp:") || text.Equals("mid:") || text.Equals("cid:") || text.Equals("wais://") || text.Equals("prospero://") );}/*---------------------------------------------------------------------- * Copy text buffer to current input line's command buffer while marking * any URL's */voidMimeRichTextP::FlushTextURL(CharC buffer){ static RegexC *urlPat = NULL;//// URL patterns.// Pattern matches any://, any:/ or any:// if ( !urlPat ) { //urlPat = new RegexC("[a-z]+://[a-zA-Z0-9\$_@\.&\+!\*\"'(),%/-]+"); urlPat = new RegexC("\\([a-z]+:/*\\)[^ \t\n()<>\"]+[a-zA-Z0-9]"); }//// Check for pattern. Make sure "any" is valid// int pos = urlPat->search(buffer); while ( pos >= 0 && !IsURL(buffer((*urlPat)[1])) ) { pos += (*urlPat)[1].length(); pos = urlPat->search(buffer, pos); }//// See if we found a valid URL// if ( pos < 0 ) { if ( debuglev > 1 ) cout <<"Adding false URL ^" <<buffer <<"^" <<endl; *inputCmd->text += buffer; return; } int offset = 0; while ( pos >= 0 ) {//// Add text up to this point// int len = pos - offset; if ( len > 0 ) { if ( debuglev > 1 ) cout <<"Adding text ^" <<buffer(offset, len) <<"^" <<endl; *inputCmd->text += buffer(offset, len); }//// Create a new command for the URL// RichCmdC *rcmd = new RichCmdC(RC_TEXT); rcmd->state = inputCmd->state; rcmd->state.PushFont(FC_URL); inputLine->AddCommand(rcmd, /*after*/inputCmd); inputCmd = rcmd;//// Add the URL text// RangeC urlRange = (*urlPat)[0]; if ( debuglev > 1 ) cout <<"Adding URL text ^" <<buffer(urlRange) <<"^" <<endl; *inputCmd->text += buffer(urlRange);//// Create a new command for the plain text again// rcmd = new RichCmdC(RC_TEXT); rcmd->state = inputCmd->state; rcmd->state.PopFont(); // Remove URL markup inputLine->AddCommand(rcmd, /*after*/inputCmd); inputCmd = rcmd;//// Look for next pattern// offset = pos + urlRange.length(); pos = urlPat->search(buffer, offset); while ( pos >= 0 && !IsURL(buffer((*urlPat)[1])) ) { pos += (*urlPat)[1].length(); pos = urlPat->search(buffer, pos); } } // End for each pattern//// Add any remaining text// int len = buffer.Length() - offset; if ( len > 0 ) { if ( debuglev > 1 ) cout <<"Adding text ^" <<buffer(offset, len) <<"^" <<endl; *inputCmd->text += buffer(offset, len); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?