1 /* Scintilla source code edit control */
2 /* ScintillaGTKAccessible.h - GTK+ accessibility for ScintillaGTK */
3 /* Copyright 2016 by Colomban Wendling <colomban@geany.org>
4 * The License.txt file describes the conditions under which this software may be distributed. */
6 #ifndef SCINTILLAGTKACCESSIBLE_H
7 #define SCINTILLAGTKACCESSIBLE_H
13 #ifndef ATK_CHECK_VERSION
14 # define ATK_CHECK_VERSION(x, y, z) 0
17 class ScintillaGTKAccessible
{
19 // weak references to related objects
20 GtkAccessible
*accessible
;
23 // cache holding character offset for each line start, see CharacterOffsetFromByteOffset()
24 std::vector
<Sci::Position
> character_offsets
;
26 // cached length of the deletion, in characters (see Notify())
27 int deletionLengthChar
;
28 // local state for comparing
29 Sci::Position old_pos
;
30 std::vector
<SelectionRange
> old_sels
;
34 void Notify(GtkWidget
*widget
, gint code
, SCNotification
*nt
);
35 static void SciNotify(GtkWidget
*widget
, gint code
, SCNotification
*nt
, gpointer data
) {
37 reinterpret_cast<ScintillaGTKAccessible
*>(data
)->Notify(widget
, code
, nt
);
41 Sci::Position
ByteOffsetFromCharacterOffset(Sci::Position startByte
, int characterOffset
) {
42 Sci::Position pos
= sci
->pdoc
->GetRelativePosition(startByte
, characterOffset
);
43 if (pos
== INVALID_POSITION
) {
44 // clamp invalid positions inside the document
45 if (characterOffset
> 0) {
46 return sci
->pdoc
->Length();
54 Sci::Position
ByteOffsetFromCharacterOffset(Sci::Position characterOffset
) {
55 return ByteOffsetFromCharacterOffset(0, characterOffset
);
58 Sci::Position
CharacterOffsetFromByteOffset(Sci::Position byteOffset
) {
59 const Sci::Line line
= sci
->pdoc
->LineFromPosition(byteOffset
);
60 if (character_offsets
.size() <= static_cast<size_t>(line
)) {
61 if (character_offsets
.empty())
62 character_offsets
.push_back(0);
63 for (Sci::Position i
= character_offsets
.size(); i
<= line
; i
++) {
64 const Sci::Position start
= sci
->pdoc
->LineStart(i
- 1);
65 const Sci::Position end
= sci
->pdoc
->LineStart(i
);
66 character_offsets
.push_back(character_offsets
[i
- 1] + sci
->pdoc
->CountCharacters(start
, end
));
69 const Sci::Position lineStart
= sci
->pdoc
->LineStart(line
);
70 return character_offsets
[line
] + sci
->pdoc
->CountCharacters(lineStart
, byteOffset
);
73 void CharacterRangeFromByteRange(Sci::Position startByte
, Sci::Position endByte
, int *startChar
, int *endChar
) {
74 *startChar
= CharacterOffsetFromByteOffset(startByte
);
75 *endChar
= *startChar
+ sci
->pdoc
->CountCharacters(startByte
, endByte
);
78 void ByteRangeFromCharacterRange(int startChar
, int endChar
, Sci::Position
& startByte
, Sci::Position
& endByte
) {
79 startByte
= ByteOffsetFromCharacterOffset(startChar
);
80 endByte
= ByteOffsetFromCharacterOffset(startByte
, endChar
- startChar
);
83 Sci::Position
PositionBefore(Sci::Position pos
) {
84 return sci
->pdoc
->MovePositionOutsideChar(pos
- 1, -1, true);
87 Sci::Position
PositionAfter(Sci::Position pos
) {
88 return sci
->pdoc
->MovePositionOutsideChar(pos
+ 1, 1, true);
91 int StyleAt(Sci::Position position
, bool ensureStyle
= false) {
93 sci
->pdoc
->EnsureStyledTo(position
);
94 return sci
->pdoc
->StyleAt(position
);
98 gchar
*GetTextRangeUTF8(Sci::Position startByte
, Sci::Position endByte
);
99 gchar
*GetText(int startChar
, int endChar
);
100 gchar
*GetTextAfterOffset(int charOffset
, AtkTextBoundary boundaryType
, int *startChar
, int *endChar
);
101 gchar
*GetTextBeforeOffset(int charOffset
, AtkTextBoundary boundaryType
, int *startChar
, int *endChar
);
102 gchar
*GetTextAtOffset(int charOffset
, AtkTextBoundary boundaryType
, int *startChar
, int *endChar
);
103 #if ATK_CHECK_VERSION(2, 10, 0)
104 gchar
*GetStringAtOffset(int charOffset
, AtkTextGranularity granularity
, int *startChar
, int *endChar
);
106 gunichar
GetCharacterAtOffset(int charOffset
);
107 gint
GetCharacterCount();
108 gint
GetCaretOffset();
109 gboolean
SetCaretOffset(int charOffset
);
110 gint
GetOffsetAtPoint(gint x
, gint y
, AtkCoordType coords
);
111 void GetCharacterExtents(int charOffset
, gint
*x
, gint
*y
, gint
*width
, gint
*height
, AtkCoordType coords
);
112 AtkAttributeSet
*GetAttributesForStyle(unsigned int styleNum
);
113 AtkAttributeSet
*GetRunAttributes(int charOffset
, int *startChar
, int *endChar
);
114 AtkAttributeSet
*GetDefaultAttributes();
115 gint
GetNSelections();
116 gchar
*GetSelection(gint selection_num
, int *startChar
, int *endChar
);
117 gboolean
AddSelection(int startChar
, int endChar
);
118 gboolean
RemoveSelection(int selection_num
);
119 gboolean
SetSelection(gint selection_num
, int startChar
, int endChar
);
120 // for AtkEditableText
121 bool InsertStringUTF8(Sci::Position bytePos
, const gchar
*utf8
, Sci::Position lengthBytes
);
122 void SetTextContents(const gchar
*contents
);
123 void InsertText(const gchar
*text
, int lengthBytes
, int *charPosition
);
124 void CopyText(int startChar
, int endChar
);
125 void CutText(int startChar
, int endChar
);
126 void DeleteText(int startChar
, int endChar
);
127 void PasteText(int charPosition
);
130 ScintillaGTKAccessible(GtkAccessible
*accessible_
, GtkWidget
*widget_
);
131 ~ScintillaGTKAccessible();
133 static ScintillaGTKAccessible
*FromAccessible(GtkAccessible
*accessible
);
134 static ScintillaGTKAccessible
*FromAccessible(AtkObject
*accessible
) {
135 return FromAccessible(GTK_ACCESSIBLE(accessible
));
137 // So ScintillaGTK can notify us
138 void ChangeDocument(Document
*oldDoc
, Document
*newDoc
);
139 void NotifyReadOnly();
140 void SetAccessibility();
142 // Helper GtkWidget methods
143 static AtkObject
*WidgetGetAccessibleImpl(GtkWidget
*widget
, AtkObject
**cache
, gpointer widget_parent_class
);
149 static void init(::AtkTextIface
*iface
);
154 static gchar
*GetText(AtkText
*text
, int start_offset
, int end_offset
);
155 static gchar
*GetTextAfterOffset(AtkText
*text
, int offset
, AtkTextBoundary boundary_type
, int *start_offset
, int *end_offset
);
156 static gchar
*GetTextBeforeOffset(AtkText
*text
, int offset
, AtkTextBoundary boundary_type
, int *start_offset
, int *end_offset
);
157 static gchar
*GetTextAtOffset(AtkText
*text
, gint offset
, AtkTextBoundary boundary_type
, gint
*start_offset
, gint
*end_offset
);
158 #if ATK_CHECK_VERSION(2, 10, 0)
159 static gchar
*GetStringAtOffset(AtkText
*text
, gint offset
, AtkTextGranularity granularity
, gint
*start_offset
, gint
*end_offset
);
161 static gunichar
GetCharacterAtOffset(AtkText
*text
, gint offset
);
162 static gint
GetCharacterCount(AtkText
*text
);
163 static gint
GetCaretOffset(AtkText
*text
);
164 static gboolean
SetCaretOffset(AtkText
*text
, gint offset
);
165 static gint
GetOffsetAtPoint(AtkText
*text
, gint x
, gint y
, AtkCoordType coords
);
166 static void GetCharacterExtents(AtkText
*text
, gint offset
, gint
*x
, gint
*y
, gint
*width
, gint
*height
, AtkCoordType coords
);
167 static AtkAttributeSet
*GetRunAttributes(AtkText
*text
, gint offset
, gint
*start_offset
, gint
*end_offset
);
168 static AtkAttributeSet
*GetDefaultAttributes(AtkText
*text
);
169 static gint
GetNSelections(AtkText
*text
);
170 static gchar
*GetSelection(AtkText
*text
, gint selection_num
, gint
*start_pos
, gint
*end_pos
);
171 static gboolean
AddSelection(AtkText
*text
, gint start
, gint end
);
172 static gboolean
RemoveSelection(AtkText
*text
, gint selection_num
);
173 static gboolean
SetSelection(AtkText
*text
, gint selection_num
, gint start
, gint end
);
175 class AtkEditableTextIface
{
177 static void init(::AtkEditableTextIface
*iface
);
180 AtkEditableTextIface();
182 static void SetTextContents(AtkEditableText
*text
, const gchar
*contents
);
183 static void InsertText(AtkEditableText
*text
, const gchar
*contents
, gint length
, gint
*position
);
184 static void CopyText(AtkEditableText
*text
, gint start
, gint end
);
185 static void CutText(AtkEditableText
*text
, gint start
, gint end
);
186 static void DeleteText(AtkEditableText
*text
, gint start
, gint end
);
187 static void PasteText(AtkEditableText
*text
, gint position
);
196 #endif /* SCINTILLAGTKACCESSIBLE_H */