Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenlist.c
Go to the documentation of this file.
00001 /* 00002 * RichEdit - Basic operations on double linked lists. 00003 * 00004 * Copyright 2004 by Krzysztof Foltman 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 00022 #include "editor.h" 00023 00024 WINE_DEFAULT_DEBUG_CHANNEL(richedit_lists); 00025 00026 void ME_InsertBefore(ME_DisplayItem *diWhere, ME_DisplayItem *diWhat) 00027 { 00028 diWhat->next = diWhere; 00029 diWhat->prev = diWhere->prev; 00030 00031 diWhere->prev->next = diWhat; 00032 diWhat->next->prev = diWhat; 00033 } 00034 00035 void ME_Remove(ME_DisplayItem *diWhere) 00036 { 00037 ME_DisplayItem *diNext = diWhere->next; 00038 ME_DisplayItem *diPrev = diWhere->prev; 00039 assert(diNext); 00040 assert(diPrev); 00041 diPrev->next = diNext; 00042 diNext->prev = diPrev; 00043 } 00044 00045 static BOOL ME_DITypesEqual(ME_DIType type, ME_DIType nTypeOrClass) 00046 { 00047 switch (nTypeOrClass) 00048 { 00049 case diRunOrParagraph: 00050 return type == diRun || type == diParagraph; 00051 case diRunOrStartRow: 00052 return type == diRun || type == diStartRow; 00053 case diParagraphOrEnd: 00054 return type == diTextEnd || type == diParagraph; 00055 case diStartRowOrParagraph: 00056 return type == diStartRow || type == diParagraph; 00057 case diStartRowOrParagraphOrEnd: 00058 return type == diStartRow || type == diParagraph || type == diTextEnd; 00059 case diRunOrParagraphOrEnd: 00060 return type == diRun || type == diParagraph || type == diTextEnd; 00061 default: 00062 return type == nTypeOrClass; 00063 } 00064 } 00065 00066 /* Modifies run pointer to point to the next run, and modify the 00067 * paragraph pointer if moving into the next paragraph. 00068 * 00069 * Returns TRUE if next run is found, otherwise returns FALSE. */ 00070 BOOL ME_NextRun(ME_DisplayItem **para, ME_DisplayItem **run) 00071 { 00072 ME_DisplayItem *p = (*run)->next; 00073 while (p->type != diTextEnd) 00074 { 00075 if (p->type == diParagraph) { 00076 *para = p; 00077 } else if (p->type == diRun) { 00078 *run = p; 00079 return TRUE; 00080 } 00081 p = p->next; 00082 } 00083 return FALSE; 00084 } 00085 00086 /* Modifies run pointer to point to the previous run, and modify the 00087 * paragraph pointer if moving into the previous paragraph. 00088 * 00089 * Returns TRUE if previous run is found, otherwise returns FALSE. */ 00090 BOOL ME_PrevRun(ME_DisplayItem **para, ME_DisplayItem **run) 00091 { 00092 ME_DisplayItem *p = (*run)->prev; 00093 while (p->type != diTextStart) 00094 { 00095 if (p->type == diParagraph) { 00096 if (p->member.para.prev_para->type == diParagraph) 00097 *para = p->member.para.prev_para; 00098 } else if (p->type == diRun) { 00099 *run = p; 00100 return TRUE; 00101 } 00102 p = p->prev; 00103 } 00104 return FALSE; 00105 } 00106 00107 ME_DisplayItem *ME_FindItemBack(ME_DisplayItem *di, ME_DIType nTypeOrClass) 00108 { 00109 if (!di) 00110 return NULL; 00111 di = di->prev; 00112 while(di!=NULL) { 00113 if (ME_DITypesEqual(di->type, nTypeOrClass)) 00114 return di; 00115 di = di->prev; 00116 } 00117 return NULL; 00118 } 00119 00120 ME_DisplayItem *ME_FindItemBackOrHere(ME_DisplayItem *di, ME_DIType nTypeOrClass) 00121 { 00122 while(di!=NULL) { 00123 if (ME_DITypesEqual(di->type, nTypeOrClass)) 00124 return di; 00125 di = di->prev; 00126 } 00127 return NULL; 00128 } 00129 00130 ME_DisplayItem *ME_FindItemFwd(ME_DisplayItem *di, ME_DIType nTypeOrClass) 00131 { 00132 if (!di) return NULL; 00133 di = di->next; 00134 while(di!=NULL) { 00135 if (ME_DITypesEqual(di->type, nTypeOrClass)) 00136 return di; 00137 di = di->next; 00138 } 00139 return NULL; 00140 } 00141 00142 void ME_DestroyDisplayItem(ME_DisplayItem *item) { 00143 /* TRACE("type=%s\n", ME_GetDITypeName(item->type)); */ 00144 if (item->type==diParagraph || item->type == diUndoSetParagraphFormat) { 00145 FREE_OBJ(item->member.para.pFmt); 00146 } 00147 if (item->type==diRun || item->type == diUndoInsertRun) { 00148 if (item->member.run.ole_obj) ME_DeleteReObject(item->member.run.ole_obj); 00149 ME_ReleaseStyle(item->member.run.style); 00150 ME_DestroyString(item->member.run.strText); 00151 } 00152 if (item->type==diUndoSetCharFormat) { 00153 ME_ReleaseStyle(item->member.ustyle); 00154 } 00155 if (item->type==diUndoSplitParagraph) { 00156 FREE_OBJ(item->member.para.pFmt); 00157 FREE_OBJ(item->member.para.pCell); 00158 } 00159 FREE_OBJ(item); 00160 } 00161 00162 ME_DisplayItem *ME_MakeDI(ME_DIType type) { 00163 ME_DisplayItem *item = ALLOC_OBJ(ME_DisplayItem); 00164 ZeroMemory(item, sizeof(ME_DisplayItem)); 00165 item->type = type; 00166 item->prev = item->next = NULL; 00167 if (type == diParagraph || type == diUndoSplitParagraph) { 00168 item->member.para.pFmt = ALLOC_OBJ(PARAFORMAT2); 00169 ME_SetDefaultParaFormat(item->member.para.pFmt); 00170 item->member.para.nFlags = MEPF_REWRAP; 00171 } 00172 00173 return item; 00174 } 00175 00176 const char *ME_GetDITypeName(ME_DIType type) 00177 { 00178 switch(type) 00179 { 00180 case diParagraph: return "diParagraph"; 00181 case diRun: return "diRun"; 00182 case diCell: return "diCell"; 00183 case diTextStart: return "diTextStart"; 00184 case diTextEnd: return "diTextEnd"; 00185 case diStartRow: return "diStartRow"; 00186 case diUndoEndTransaction: return "diUndoEndTransaction"; 00187 case diUndoPotentialEndTransaction: return "diUndoPotentialEndTransaction"; 00188 case diUndoSetParagraphFormat: return "diUndoSetParagraphFormat"; 00189 case diUndoSetCharFormat: return "diUndoSetCharFormat"; 00190 case diUndoInsertRun: return "diUndoInsertRun"; 00191 case diUndoDeleteRun: return "diUndoDeleteRun"; 00192 case diUndoJoinParagraphs: return "diJoinParagraphs"; 00193 case diUndoSplitParagraph: return "diSplitParagraph"; 00194 default: return "?"; 00195 } 00196 } 00197 00198 void ME_DumpDocument(ME_TextBuffer *buffer) 00199 { 00200 /* FIXME this is useless, */ 00201 ME_DisplayItem *pItem = buffer->pFirst; 00202 TRACE("DOCUMENT DUMP START\n"); 00203 while(pItem) { 00204 switch(pItem->type) 00205 { 00206 case diTextStart: 00207 TRACE("Start\n"); 00208 break; 00209 case diCell: 00210 TRACE("Cell(level=%d%s)\n", pItem->member.cell.nNestingLevel, 00211 !pItem->member.cell.next_cell ? ", END" : 00212 (!pItem->member.cell.prev_cell ? ", START" :"")); 00213 break; 00214 case diParagraph: 00215 TRACE("Paragraph(ofs=%d)\n", pItem->member.para.nCharOfs); 00216 if (pItem->member.para.nFlags & MEPF_ROWSTART) 00217 TRACE(" - (Table Row Start)\n"); 00218 if (pItem->member.para.nFlags & MEPF_ROWEND) 00219 TRACE(" - (Table Row End)\n"); 00220 break; 00221 case diStartRow: 00222 TRACE(" - StartRow\n"); 00223 break; 00224 case diRun: 00225 TRACE(" - Run(\"%s\", %d, flags=%x)\n", debugstr_w(pItem->member.run.strText->szData), 00226 pItem->member.run.nCharOfs, pItem->member.run.nFlags); 00227 break; 00228 case diTextEnd: 00229 TRACE("End(ofs=%d)\n", pItem->member.para.nCharOfs); 00230 break; 00231 default: 00232 break; 00233 } 00234 pItem = pItem->next; 00235 } 00236 TRACE("DOCUMENT DUMP END\n"); 00237 } Generated on Sun May 27 2012 04:18:48 for ReactOS by
1.7.6.1
|