477 lines
14 KiB
C++
477 lines
14 KiB
C++
#if !defined(AFX_VIRICHEDIT_H__89F06A80_24BC_11D3_BAE2_00A0C9CC72C3__INCLUDED_)
|
|
#define AFX_VIRICHEDIT_H__89F06A80_24BC_11D3_BAE2_00A0C9CC72C3__INCLUDED_
|
|
|
|
#if _MSC_VER > 1000
|
|
#pragma once
|
|
#endif // _MSC_VER > 1000
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// VIRichEdit window
|
|
|
|
typedef enum {
|
|
VI_CTRL_RICHEDIT_TEXT = 0x00000000,
|
|
VI_CTRL_RICHEDIT_FRAMERECT = 0x00000020,
|
|
VI_CTRL_RICHEDIT_NOREDRAW = 0x00000040,
|
|
VI_CTRL_RICHEDIT_CREATE_CONTROLS_AFTER_CREATE = 0x00000080,
|
|
VI_CTRL_RICHEDIT_CTRLSPACECOMPLETION = 0x00000100,
|
|
}VI_CTRL_RICHEDIT_FLAGS;
|
|
|
|
#include "XHashTable.h"
|
|
#include "XClassArray.h"
|
|
#include "XDictionnary.h"
|
|
#include "XList.h"
|
|
#include "XBitArray.h"
|
|
|
|
#define WM_FIND_ALLDOC_CMD WM_USER+34
|
|
#define WM_REPLACE_ALLDOC_CMD WM_USER+35
|
|
|
|
|
|
typedef struct MarkUpdateData{
|
|
int m_l1;
|
|
int m_l2;
|
|
int m_l3;
|
|
int m_l4;
|
|
int m_newRangeCpMin;
|
|
int m_newRangeCpMax;
|
|
BOOL m_noChange;
|
|
MarkUpdateData() : m_l1(-1),m_l2(-1),m_l3(-1),m_l4(-1),m_newRangeCpMin(-1),m_newRangeCpMax(-1) {}
|
|
BOOL IsValid()
|
|
{
|
|
return ((m_l1!=-1) && (m_l2!=-1));
|
|
}
|
|
BOOL NeedToComputeL3L4()
|
|
{
|
|
return ((m_l3==-1) && (m_l4==-1));
|
|
}
|
|
}MarkUpdateData;
|
|
/******************************************
|
|
Class Unit :
|
|
For autocompletion some function, members only applies to
|
|
a specific class.
|
|
|
|
*******************************************/
|
|
class XClassUnit
|
|
{
|
|
public:
|
|
XClassUnit(char* Name = "") {
|
|
m_ClassName = Name;
|
|
}
|
|
XString m_ClassName;
|
|
XClassArray<XString> m_ParentClassNames;
|
|
XCharDictionnary m_AutoCompleteDictionnary;
|
|
};
|
|
|
|
// Hash Tables (keyword <-> color)
|
|
typedef XHashTable<DWORD,XString> XKeyWordColorHashTable;
|
|
typedef XHashTable<DWORD,XString>::Iterator XKeyWordColorHashTableIt;
|
|
|
|
// Hash Tables (keyword <-> class)
|
|
typedef XHashTable<XClassUnit*,XString> XClassHashTable;
|
|
typedef XHashTable<XClassUnit*,XString>::Iterator XClassHashTableIt;
|
|
|
|
// Hash Tables (keyword <-> string)
|
|
typedef XHashTable<XString,XString> XStringHashTable;
|
|
typedef XHashTable<XString,XString>::Iterator XStringHashTableIt;
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************
|
|
Undo Unit :
|
|
This describes an action taken by the user :
|
|
Text (TextReplaced) which was at the given position (TextPosition) was
|
|
replaced by the Text (NewText) and now occupies (NewRange) position
|
|
*******************************************/
|
|
class XUndoUnit {
|
|
public:
|
|
XString TextReplaced;
|
|
CHARRANGE TextRange;
|
|
XString NewText;
|
|
CHARRANGE NewRange;
|
|
BOOL UndoPreviousUnit;
|
|
BOOL RedoNextUnit;
|
|
};
|
|
|
|
|
|
class XUndoStorage {
|
|
public:
|
|
mutable XList<XUndoUnit*> m_UndoUnits; // List of undo units
|
|
mutable XList<XUndoUnit*> m_RedoUnits; // List of redo units (an undo unit goes to the redo when done anc vice versa)
|
|
mutable XClassArray<XUndoUnit> m_UndoUnitsPool; // A preallocated pool of undo units (~200)
|
|
XBitArray m_TakenUndoUnits; // a bit array of each undo unit that is used...
|
|
|
|
|
|
// Warning => this operator transfer data from one structure to another....
|
|
XUndoStorage& operator = (const XUndoStorage& a) {
|
|
m_UndoUnits.Swap(a.m_UndoUnits);
|
|
m_RedoUnits.Swap(a.m_RedoUnits);
|
|
m_UndoUnitsPool.Swap(a.m_UndoUnitsPool);
|
|
m_TakenUndoUnits = a.m_TakenUndoUnits;
|
|
return *this;
|
|
}
|
|
/*
|
|
XUndoStorage& operator = (const XUndoStorage& a) {
|
|
m_UndoUnits.Swap(a.m_UndoUnits);
|
|
m_RedoUnits.Swap(a.m_RedoUnits);
|
|
m_UndoUnitsPool.Swap(a.m_UndoUnitsPool);
|
|
m_TakenUndoUnits = a.m_TakenUndoUnits;
|
|
return *this;
|
|
}
|
|
*/
|
|
};
|
|
|
|
|
|
/*******************************************
|
|
Not used : a marker of scope
|
|
*********************************************/
|
|
class XScope{
|
|
public:
|
|
XScope() {}
|
|
XScope(char* StartMarker,char* EndMarker,DWORD Color):m_StartScopeMarker(StartMarker),m_EndScopeMarker(EndMarker),m_Color(Color) {
|
|
m_StartMarkerLength = StartMarker ? strlen(StartMarker) : 0;
|
|
m_EndMarkerLength = EndMarker ? strlen(EndMarker) : 0;
|
|
}
|
|
|
|
bool IsStartMarker(char* text) {
|
|
for (int i=0;i<m_StartMarkerLength;++i) if (text[i] != m_StartScopeMarker[i]) return FALSE;
|
|
return TRUE;
|
|
}
|
|
bool IsEndMarker(char* text) {
|
|
for (int i=0;i<m_EndMarkerLength;++i) if (text[i] != m_EndScopeMarker[i]) return FALSE;
|
|
return TRUE;
|
|
}
|
|
int ScopeEnum(int en) {
|
|
return (en << Index*3);
|
|
}
|
|
|
|
int Index;
|
|
char* m_StartScopeMarker;
|
|
int m_StartMarkerLength;
|
|
char* m_EndScopeMarker;
|
|
int m_EndMarkerLength;
|
|
DWORD m_Color;
|
|
XArray<CHARRANGE> m_Ranges;
|
|
};
|
|
|
|
struct DescAndRealName {
|
|
char* Description;
|
|
char* RealName;
|
|
~DescAndRealName() {
|
|
free(Description);
|
|
free(RealName);
|
|
}
|
|
};
|
|
|
|
class VIFindReplaceDlg;
|
|
|
|
class AFX_EXT_CLASS VIRichEdit : public CRichEditCtrl,public VIControl
|
|
{
|
|
// Construction
|
|
public:
|
|
VIRichEdit();
|
|
|
|
BOOL Create(DWORD in_dwStyle, const RECT& in_rcRect,CWnd* in_pParentWnd, UINT in_nID);
|
|
|
|
|
|
void SetRedraw( BOOL bRedraw = TRUE );
|
|
|
|
BOOL GetOverTypeMode();
|
|
|
|
BOOL DoRedo(int* ls=NULL,int* le=NULL);
|
|
BOOL DoUndo(int* ls=NULL,int* le=NULL);
|
|
BOOL DoCut();
|
|
BOOL DoPaste();
|
|
|
|
//---find & replace
|
|
//BOOL DoFindText();
|
|
//BOOL DoReplaceText();
|
|
BOOL DoGotoLine();
|
|
|
|
BOOL FindReplaceDlg(BOOL iReplace);
|
|
void OnFindReplaceCommand(int iCommand,BOOL iFocus=TRUE);
|
|
VIFindReplaceDlg* m_FindReplaceDlg;
|
|
void OnFindCommand();
|
|
void OnReplaceCommand();
|
|
void ReplaceAll();
|
|
|
|
XUndoUnit* ReplaceNext();
|
|
BOOL FindNext(CHARRANGE &range,BOOL down=TRUE,BOOL select=FALSE,BOOL* oEndOfFilePassed=0);
|
|
public:
|
|
XString m_findStr;
|
|
XString m_replaceStr;
|
|
int m_findTextMatchCase;
|
|
BOOL m_findBackward;
|
|
//----
|
|
|
|
public:
|
|
void GetRangeString(XString& string,int cpMin,int cpMax);
|
|
void GetCurSelString(XString& string);
|
|
|
|
//---- icon, breakpoint, any kind of mark, managment & margin management too
|
|
//SetMarkImageList: computes margin for richedit where icon will be drawn
|
|
//call UpdateSizeForMarks after that so that new margin takes effect
|
|
void SetMarkImageList(CImageList *list);
|
|
void AddMarkToLine(int indexInImageList,int line);
|
|
BOOL HasMarkInLine(int indexInImageList,int line);
|
|
void RemoveMarkFromLine(int indexInImageList,int line);
|
|
void RemoveAllMarksFromLine(int line);
|
|
void RemoveAllMarks();
|
|
void RemoveMarkFromAllLine(int indexInImageList);
|
|
void UpdateSizeForMarks();
|
|
void SetLineHeight();
|
|
void UpdateMarks(MarkUpdateData &data);
|
|
XHashTable<DWORD,int>::Iterator GetMarkList() {return m_markList.Begin();}
|
|
void GetMarkLines(int indexInImageList, XArray <int> &oLines) const;
|
|
void SetMargin(int m); //set margin size where no text will be drawn, marin is on the left
|
|
int GetMargin() const; //get margin size
|
|
|
|
//----- Must be called by the owner PreTranslateMessage function
|
|
// if it returns TRUE no more processing should be done...
|
|
BOOL TranslateKeyMessages(MSG* pMsg);
|
|
|
|
//---- Updates the complete edit colors...
|
|
void UpdateColors(BOOL iOnlyVisible = FALSE);
|
|
|
|
//--- Sets / Gets the Control Font ----------
|
|
virtual void SetControlFont(CFont *fnt);
|
|
virtual void SetBackColor(COLORREF clr);
|
|
|
|
//--- Fullscreen----------------------------------------------------
|
|
void ToggleFullscreen();
|
|
BOOL IsFullScreen();
|
|
|
|
//--- Tab Size ----------------------------------------------------
|
|
int GetTabSize() { return m_TabSize; }
|
|
void SetTabSize(int TabSize);
|
|
|
|
//--- Word Separators ----------------------------------------------------
|
|
BOOL IsSeparator(char a) { return m_WordSeparator[a]; }
|
|
void SetSeparator(char a,BOOL Separator=TRUE) { m_WordSeparator[a] = Separator; }
|
|
|
|
void SelectRow(int iRow);
|
|
|
|
//--- Auto complete -----------------------------------------------
|
|
BOOL AddKeyWord(char* Owner,char* KeyWord,char* Description = NULL);
|
|
void RemoveKeyWord(char* Owner,char* KeyWord);
|
|
// Add '.' ,'->'
|
|
void AddOwnerSeparator(char* SeparatorString);
|
|
// A type (as a class )
|
|
void AddOwnerType(char* Type, char* ParentType);
|
|
|
|
// for global variables that are not visible in the rich edit
|
|
// text : an association (object and its type )
|
|
void AddGlobalAssociation(char* Object,char* Type);
|
|
void RemoveGlobalAssociation(char* Object);
|
|
|
|
// search in the text and the global association table if
|
|
// we find the type of an object
|
|
char* GetTypeOf(char* Object);
|
|
|
|
void ResetAutoComplete();
|
|
|
|
BOOL GetAutoComplete() { return m_AutoComplete; }
|
|
void SetAutoComplete(BOOL Auto = TRUE) { m_AutoComplete = Auto; }
|
|
|
|
//--- Auto complete list Tool Tip -----------------------------------
|
|
void InsertAutoCompletion(int SuggestionIndex);
|
|
|
|
void ValidateAutoCompleteList();
|
|
BOOL IsAutoCompleteListVisible();
|
|
void HideAutoCompleteList();
|
|
void ShowAutoCompleteList();
|
|
|
|
COLORREF GetToolTipColor() { return m_ToolTipColor; }
|
|
void SetToolTipColor(COLORREF col);
|
|
void SetToolTipFont(CFont *fnt);
|
|
|
|
//--- Colored Keywords ------------------------------------------
|
|
void AddColorKeyWord(char* KeyWord,DWORD Color);
|
|
void AddColorScope(char* StartKeyWord,char* EndKeyWord,DWORD Color);
|
|
|
|
void RemoveColorKeyWord(char* KeyWord);
|
|
void RemoveAllColorKeyWords() {
|
|
m_SingleWordHash.Clear();
|
|
m_Scopes.Clear();
|
|
}
|
|
|
|
//--- Streaming.... ---------------------------------------------
|
|
BOOL Load(char* FileName);
|
|
BOOL Save(char* FileName);
|
|
|
|
|
|
//------ Undo ------------
|
|
void SaveUndoData(XUndoStorage& data);
|
|
void LoadUndoData(const XUndoStorage& data);
|
|
void ClearUndo();
|
|
int GetUndoLimit() { return m_UndoUnitsPool.Size(); }
|
|
void SetUndoLimit(int NbUndo);
|
|
|
|
|
|
BOOL ProposeAutoComplete();
|
|
|
|
|
|
// Attributes
|
|
public:
|
|
|
|
// Operations
|
|
public:
|
|
|
|
// Overrides
|
|
// ClassWizard generated virtual function overrides
|
|
//{{AFX_VIRTUAL(VIRichEdit)
|
|
protected:
|
|
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
|
|
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
|
virtual void PreSubclassWindow();
|
|
//}}AFX_VIRTUAL
|
|
|
|
// Implementation
|
|
public:
|
|
virtual ~VIRichEdit();
|
|
static int DefaultHeight;
|
|
BOOL m_ShowAutoCompleteListOnNextChar;
|
|
void DoOnPaint(int pos=-1);
|
|
protected:
|
|
void InsertTabulation(BOOL Remove);
|
|
void FormatLineRange(int StartLine,int EndLine,BOOL redraw = TRUE);
|
|
|
|
//---- undo
|
|
void ReplaceSelection(char* newtext,BOOL Backspace = FALSE,BOOL Suppr = FALSE);
|
|
void CurrentSelectionIsBeingReplaced(BOOL Backspace,BOOL Suppr,char* newtext,MarkUpdateData *data = NULL);
|
|
void ClearRedoUnits();
|
|
XUndoUnit* GetNewUndoUnit();
|
|
void CheckWordUnit();
|
|
//-- Autocomplete
|
|
void FindWordUnderCursor();
|
|
void ComputeAutoCompleteSuggestions();
|
|
void ScrollAutoCompleteList(int Dir);
|
|
|
|
//-- get the appropriate class description (Dictionnary)
|
|
XClassUnit* GetClass(char* Owner);
|
|
XClassUnit* GetClassAndConstruct(char* Owner);
|
|
int BackwardSearch(int Pos,char* Object,BOOL matchcase=TRUE,CHARRANGE *range=NULL);
|
|
|
|
|
|
int GetToolTipSel();
|
|
int GetToolTipItemCount();
|
|
void SetToolTipSel(int index);
|
|
|
|
void CompleteClassHierarchy(char* Type, const XString& WordUnderCursor);
|
|
bool ShowDescriptionHierarchy(char* Type, const XString& WordUnderCursor);
|
|
|
|
void GetTextBuffer();
|
|
|
|
BOOL IsSelectionComment();
|
|
|
|
//--- Find the '(' , ' [' or '{' corresponding to the one under the current curosr
|
|
void FindScope();
|
|
|
|
//----- Colors
|
|
XKeyWordColorHashTable m_SingleWordHash;
|
|
// Scopes like /* */ and " "
|
|
// number of scopes is limited to 8
|
|
XClassArray<XScope> m_Scopes;
|
|
|
|
//--- Settings
|
|
BYTE m_WordSeparator[256];
|
|
int m_TabSize;
|
|
BOOL m_AutoComplete;
|
|
BOOL m_AutoClosingBrackets;
|
|
BOOL m_IsInFormat;
|
|
XArray<char> m_TempLine;
|
|
XArray<char> m_TextBuffer;
|
|
|
|
//----- Mouse drag& drop
|
|
CHARRANGE m_DragSelection;
|
|
XString m_DragSelectionString;
|
|
CHARRANGE m_DropSelection;
|
|
BOOL m_DragNDropCopyMode;
|
|
|
|
|
|
//---- Auto complete
|
|
XClassArray<XString> m_AutoCompleteSuggestion;
|
|
XClassArray<XString> m_ClassSeparators;
|
|
XStringHashTable m_GlobalAssociations;
|
|
XClassHashTable m_DictionnariesPerClass; // A dictionnary for each registred class
|
|
// ("" is a generic class which stands for a global scope)
|
|
|
|
|
|
//---- Tool tip list
|
|
XString m_OwnerWord;
|
|
XString m_OwnerType;
|
|
XString m_WordUnderCursor;
|
|
BOOL m_CursorAtEndOfWord;
|
|
VIListBox m_List;
|
|
COLORREF m_ToolTipColor;
|
|
CBrush m_ToolTipBrush;
|
|
|
|
//---- undo
|
|
XList<XUndoUnit*> m_UndoUnits; // List of undo units
|
|
XList<XUndoUnit*> m_RedoUnits; // List of redo units (an undo unit goes to the redo when done anc vice versa)
|
|
XClassArray<XUndoUnit> m_UndoUnitsPool; // A preallocated pool of undo units (~200)
|
|
XBitArray m_TakenUndoUnits; // a bit array of each undo unit that is used...
|
|
|
|
//----- Color updating
|
|
// Each scope marker use this enum to mark the line
|
|
// (for each new scope the enum value is shifted by 3 so we are limited to 9 type of scopes
|
|
enum {
|
|
INSIDESCOPE = 1, // Line is inside a given scope
|
|
PARTIALLY_INSIDESCOPE = 2, // only part of the line is inside the scope (otherwise the whole line is...)
|
|
START_INSCOPE = 4, // The start of the line is inside the scope but not entirely
|
|
|
|
SCOPE_MASK = INSIDESCOPE|START_INSCOPE|PARTIALLY_INSIDESCOPE,
|
|
MASK = 0x7FFFFFFF,
|
|
COLOR_TO_UPDATE = 0x80000000, // this line has been modified in a way that needs its color to be updated
|
|
};
|
|
|
|
CHARRANGE m_LastModifiedRange;
|
|
// For each line a flags whether line is inside a given scope
|
|
XArray<int> m_ScopeLines;
|
|
XArray<int> m_PreviousScopeLines; // Same thing before the user modified the text
|
|
XArray<CHARRANGE> m_CommentedRanges;
|
|
|
|
void SetSynchronize(XBOOL iSynchro = TRUE) {
|
|
m_Synchronized = iSynchro;
|
|
}
|
|
XBOOL IsSynchronized() {
|
|
return m_Synchronized;
|
|
}
|
|
XBOOL m_Synchronized;
|
|
|
|
// Description
|
|
void ShowDescription();
|
|
XArray<DescAndRealName*> m_Descriptions;
|
|
VIStaticText m_DescriptionToolTip;
|
|
|
|
//--Fullscreen
|
|
FullScreenData m_FSData;
|
|
|
|
//{{AFX_MSG(VIRichEdit)
|
|
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
|
|
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
|
|
afx_msg void OnMsgfilter(NMHDR* pNMHDR, LRESULT* pResult);
|
|
afx_msg void OnDragDropDone(NMHDR* pNMHDR, LRESULT* pResult);
|
|
afx_msg void OnDropFiles(HDROP hDropInfo);
|
|
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
|
|
//}}AFX_MSG
|
|
|
|
//mark drawing & internal managment
|
|
int m_margin;
|
|
CImageList* m_pImageList;
|
|
XHashTable<DWORD,int> m_markList;
|
|
int m_lineHeight;
|
|
BOOL m_bMarkLastChangeIsSize; //hack for richedit resize
|
|
|
|
DECLARE_MESSAGE_MAP()
|
|
|
|
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
//{{AFX_INSERT_LOCATION}}
|
|
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
|
|
|
#endif // !defined(AFX_VIRICHEDIT_H__89F06A80_24BC_11D3_BAE2_00A0C9CC72C3__INCLUDED_)
|