deargui-vpl/ref/virtools/Includes/VIRichEdit.h

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_)