⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mimerichtextselect.c

📁 linux下的E_MAIL客户端源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *  $Id: MimeRichTextSelect.C,v 1.4 2000/12/25 15:05:52 evgeny Exp $ *   *  Copyright (c) 1994 HAL Computer Systems International, Ltd. *  *          HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. *                  1315 Dell Avenue *                  Campbell, CA  95008 * * Author: Greg Hilton * Contributors: Tom Lang, Frank Bieser, and others * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * http://www.gnu.org/copyleft/gpl.html * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */#include <config.h>#include "MimeRichTextC.h"#include "MimeRichTextP.h"#include "HalAppC.h"#include "rsrc.h"#include "System.h"#include "CharC.h"#include <Xm/AtomMgr.h>#include <Xm/CutPaste.h>#include <X11/Xatom.h>#include <X11/Xmu/Atoms.h>#include <X11/Xmu/StdSel.h>#include <X11/Xmu/CharSet.h>#include <X11/IntrinsicP.h>#include <X11/CoreP.h>#include <math.h>#include <values.h>	// For MAXINTextern int	debuglev;/*---------------------------------------------------------------------- * Callback to handle loss of primary selection ownership */voidMimeRichTextP::LoseSelection(Widget w, Atom*){   MimeRichTextC	*This;   XtVaGetValues(w, XmNuserData, &This, NULL);//// Clear current selection since we no longer own it.//   if ( This->priv->selectOn ) This->priv->DrawSelection();   This->priv->selectOn = False;}/*---------------------------------------------------------------------- * Callback to handle request for primary selection */BooleanMimeRichTextP::SendSelection(Widget w, Atom *selection, Atom *target,			     Atom *type, XtPointer *val, unsigned long *len,			     int *format){   MimeRichTextC	*This;   XtVaGetValues(w, XmNuserData, &This, NULL);//// Handle required atoms//   if ( *target == XA_TARGETS(halApp->display) ) {      *len = 4;      *val = XtMalloc((Cardinal)(sizeof(Atom) * (*len)));      Atom	*targetP = *(Atom**)val;      *targetP++ = XA_STRING;      *targetP++ = XA_TEXT(halApp->display);      *targetP++ = XA_COMPOUND_TEXT(halApp->display);      *targetP++ = mimeRichAtom;      *type = XA_ATOM;      *format = sizeof(Atom) * 8;      return True;   } // End if someone wants to know what types we can send   else if (    *target != XA_STRING	     && *target != XA_TEXT(halApp->display)	     && *target != XA_COMPOUND_TEXT(halApp->display)	     && *target != mimeRichAtom ) {      return XmuConvertStandardSelection(w, CurrentTime, selection, target,				         type, (caddr_t*)val, len, format);   }//// Now handle the targets we can supply//   if ( *target == XA_TEXT(halApp->display) ) *type = XA_STRING;   else					      *type = *target;   *format = sizeof(char) * 8;//// If there's a current selection, try that//   if ( This->priv->selectOn ) {//// Load up the output//      StringC	outbuf;      This->priv->GetSelectionData(outbuf, (*target == mimeRichAtom)					   ? TT_ENRICHED : TT_PLAIN);//// Get the length of the selection//      *len = outbuf.size();//// Allocate memory for selection data.  This memory will be freed by the//    Intrinsics since we didn't register an XtSelectionDoneProc//      *val = XtMalloc((Cardinal)*len);//// Copy current selection//      register char	*dst = (char*)(*val);      register char	*src = (char*)outbuf;      for (int i=0; i<*len; i++) *dst++ = *src++;   } // End if there's a current selection//// Try the clipboard if there's no selection//   else {      int	status;      u_long	clipLen;      Window	win = XtWindow(This->priv->textDA);      char	*format = (char *) ((*target == mimeRichAtom) ?                                    MIME_ENRICHED_ATOM_NAME : "STRING");      do {	 status = XmClipboardInquireLength(halApp->display, win, format,	 				   &clipLen);      } while ( status == ClipboardLocked );      if ( clipLen == 0 || status == ClipboardNoData )	 return False;//// Allocate memory for selection data.  This memory will be freed by the//    Intrinsics since we didn't register an XtSelectionDoneProc//      *val = XtMalloc((Cardinal)clipLen+1);      char	*out = (char*)*val;      long	privId;      do {	 status = XmClipboardRetrieve(halApp->display, win, format, out,				      clipLen, len, &privId);      } while ( status == ClipboardLocked );      out[*len] = 0;      *len = strlen(out);   } // End if there's no current selection   return True;} // End SendSelection/*---------------------------------------------------------------------- * Method to build a string from the current selection */voidMimeRichTextP::GetSelectionData(StringC& outbuf, TextTypeT type){   if ( !selectBegPos.textLine || !selectEndPos.textLine ||        selectBegPos == selectEndPos )      return;   TextPosC	*begPos = &selectBegPos;   TextPosC	*endPos = &selectEndPos;//// Swap points if they are reversed//   if ( *begPos > *endPos ) {      begPos = &selectEndPos;      endPos = &selectBegPos;   }   sendExcerpt = False;	// We don't send this with selections//// Add commands to bring us up to the initial state//   if ( type != TT_PLAIN ) {      TextPosC		prevPos;      if ( FindPosPrevCmd(*begPos, &prevPos) ) {	 TextStateC	*begState = prevPos.State();	 TextStateC	nullState;	 GetStateCommands(nullState, *begState, outbuf, type);      }   }//// Add command in the selected range//   GetRangeData(begPos, endPos, outbuf, type);//// Add commands to reset the state//   if ( type != TT_PLAIN ) {      TextStateC	*endState = endPos->State();      TextStateC	nullState;      GetStateCommands(*endState, nullState, outbuf, type);   }   sendExcerpt = True;   if ( debuglev > 1 )      cout <<"Selection buffer is: [" <<outbuf <<"]" <<endl;} // End GetSelectionData/*---------------------------------------------------------------------- * Method to build a string from the given range */voidMimeRichTextP::GetRangeData(TextPosC *pos1, TextPosC *pos2, StringC& outbuf,			    TextTypeT type, Boolean closeState, int lineSize){   TextPosC	*begPos = pos1;   TextPosC	*endPos = pos2;//// Swap points if they are reversed//   if ( *begPos > *endPos ) {      begPos = pos2;      endPos = pos1;   }//// See if there's just one line involved//   if ( begPos->textLine == endPos->textLine ) {      GetLineText(begPos, endPos, outbuf, type, lineSize);   }   else {//// Read to the end of the start line//      GetLineText(begPos, NULL, outbuf, type, lineSize);//// Add a newline//      if      ( type == TT_ENRICHED ) outbuf += '\n';      else if ( type == TT_RICH     ) outbuf += "<nl>";      outbuf += '\n';//// Read all lines in-between start and end line//      TextLineC	*begLine = begPos->textLine;      TextLineC	*endLine = endPos->textLine;      TextLineC	*tline   = begLine->next;      while ( tline && tline != endLine ) {	 int	oldLen = outbuf.size();	 GetLineText(tline, outbuf, type, lineSize);	 int	added = outbuf.size() - oldLen;//// Add a newline//	 if      ( type == TT_ENRICHED && added ) outbuf += '\n';	 else if ( type == TT_RICH              ) outbuf += "<nl>";	 outbuf += '\n';	 tline = tline->next;      }//// Read from the beginning of the end line//      GetLineText(NULL, endPos, outbuf, type, lineSize);   } // End if more than one line selected//// Get closing commands//   if ( closeState && type != TT_PLAIN ) {      TextStateC	nullState;      GetStateCommands(*endPos->State(), nullState, outbuf, type);   }} // End GetRangeData/*---------------------------------------------------------------------- * Method to append the first text to the second, doubling any '<'s in *    the process if the type is enriched. */voidMimeRichTextP::CopyText(StringC& src, StringC& dst, TextTypeT type,			TextStateC *state, int lineSize){//// lineSize of 0 means we're not wrapping//   if ( lineSize == 0 ) {//// Once folded, plain cannot be restored.// Enriched can always be restored so we can use 72 regardless//      if ( type == TT_PLAIN ) lineSize = MAXINT;      else		      lineSize = 72;   }//// See how much we're trying to add//   int		remaining = src.size();//// See how much room is left on the current line//   int		pos     = dst.RevPosOf('\n');   int		wrapLen = lineSize - (dst.size() - pos - 1);//// If this line is full, see if there's a space where a break can be inserted//   if ( wrapLen <= 2 ) {      pos     = dst.RevPosOf(' ');      wrapLen = lineSize - (dst.size() - pos - 1);      if ( wrapLen <= 2 ) {	// There is no space	 //dst += "\n";	 wrapLen = lineSize;      }      else {//// Insert break//	 char	*cs = dst;	 cs[pos] = '\n';//// Add excerpting to plain text//	 if ( type == TT_PLAIN ) {	    int	i;	    pos++;	    if ( sendExcerpt ) {	       for (i=0; i<state->Excerpt(); i++) {		  dst(pos,0) = excerptStr;		  pos       += excerptStr.size();		  wrapLen   -= excerptStr.size();	       }	    }	    for (i=0; i<state->LIndent(); i++) {	       dst(pos,0) = "   ";	       pos       += 3;	       wrapLen   -= 3;	    }	 }      }   }      u_int	sstart = 0;   CharC	line;//// Wrap lines at lineSize columns//   while ( remaining > 0 ) {      Boolean	split = False;      if ( remaining > wrapLen ) {//// Look backward from position lineSize and see if we can find a space//	 pos = sstart + wrapLen;	 while ( pos > sstart && !isspace(src[pos]) ) pos--;//// If we found a space, end the line before it.//	 if ( pos > sstart ) {	    line      = src(sstart, pos-sstart);	    sstart    = pos + 1;	    remaining = src.size() - sstart;	    split     = True;	 }//// If we didn't find a space to the left, look forward//	 else {	    pos = sstart + wrapLen + 1;	    while ( pos < src.size() && !isspace(src[pos]) ) pos++;//// If we found a space, insert a newline before the space//	    if ( pos < src.size() ) {	       line      = src(sstart, pos-sstart);	       sstart    = pos + 1;	       remaining = src.size() - sstart;	       split     = True;	    }	 }      } // End if there are more than lineSize characters remaining//// If we didn't or couldn't split, just use what's left//      if ( !split ) {	 line = src(sstart, remaining);	 remaining = 0;      }//// Look for "<" and replace with "<<"//      u_int	lstart = 0;      if ( type == TT_ENRICHED ) {	 pos = line.PosOf('<');	 while ( pos >= 0 ) {//// Copy from start pos to current pos and add two less-than's//	    dst += line(lstart, pos-lstart);	    dst += "<<";	    lstart = pos + 1;	    pos    = line.PosOf('<', lstart);	 } // End for each '<'      } // End if enriched//// Copy to end.//      int	len = line.Length() - lstart;      if ( len > 0 )	 dst += line(lstart, len);//// Add newline if text remains//      if ( remaining > 0 ) {	 dst += "\n";	 wrapLen = lineSize;	// Use this for all but the first line	 if ( type == TT_PLAIN ) {	    int	i;	    if ( sendExcerpt ) {	       for (i=0; i<state->Excerpt(); i++) {		  dst     += excerptStr;		  wrapLen -= excerptStr.size();	       }	    }	    for (i=0; i<state->LIndent(); i++) {	       dst     += "   ";	       wrapLen -= 3;	    }	 }      } // End more text to be added   } // End while more source remains} // End CopyText/*---------------------------------------------------------------------- * Method to extract the text between the given positions.  The positions *    are assumed to be on the same line.  If the start position is NULL, *    the beginning of the line is used.  If the end position is NULL, *    the end of the line is used.  The character at the end pos is not *    returned.  The type determines whether markup is included */voidMimeRichTextP::GetLineText(TextPosC *begPos, TextPosC *endPos, StringC& outbuf,			   TextTypeT type, int lineSize){   if ( !begPos && !endPos ) return;   TextLineC	*tl = begPos ? begPos->textLine : endPos->textLine;   int	begCmdPos = 0;   int	begStrPos = 0;   if ( begPos ) {      begCmdPos = begPos->cmdPos;      begStrPos = begPos->strPos;   }   int	endCmdPos;   int	endStrPos;   if ( endPos ) {      endCmdPos = endPos->cmdPos;      endStrPos = endPos->strPos;   }   else {      endCmdPos = tl->cmdList.size() - 1;      endStrPos = tl->Cmd(endCmdPos)->LastPos();   }   RichCmdC	*cmd      = tl->Cmd(begCmdPos);   TextStateC	*curState = &cmd->state;   int		i;//// Get opening commands//   if ( type != TT_PLAIN ) {      if ( begPos )	 GetStateCommands(*begPos, outbuf, type);      else {	 TextPosC	pos(tl, begCmdPos, begStrPos);	 GetStateCommands(pos, outbuf, type);      }   }   else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -