File: ScintillaGTKAccessible.h

package info (click to toggle)
codequery 1.0.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 17,860 kB
  • sloc: cpp: 151,420; xml: 16,576; python: 5,602; ansic: 5,487; makefile: 559; perl: 496; ruby: 209; sql: 194; sh: 106; php: 53; vhdl: 51; erlang: 47; objc: 22; lisp: 18; cobol: 18; modula3: 17; asm: 14; fortran: 12; ml: 11; tcl: 6
file content (194 lines) | stat: -rw-r--r-- 8,537 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/* Scintilla source code edit control */
/* ScintillaGTKAccessible.h - GTK+ accessibility for ScintillaGTK */
/* Copyright 2016 by Colomban Wendling <colomban@geany.org>
 * The License.txt file describes the conditions under which this software may be distributed. */

#ifndef SCINTILLAGTKACCESSIBLE_H
#define SCINTILLAGTKACCESSIBLE_H

namespace Scintilla::Internal {

#ifndef ATK_CHECK_VERSION
# define ATK_CHECK_VERSION(x, y, z) 0
#endif

class ScintillaGTKAccessible {
private:
	// weak references to related objects
	GtkAccessible *accessible;
	ScintillaGTK *sci;

	// local state for comparing
	Sci::Position old_pos;
	std::vector<SelectionRange> old_sels;

	bool Enabled() const;
	void UpdateCursor();
	void Notify(GtkWidget *widget, gint code, Scintilla::NotificationData *nt);
	static void SciNotify(GtkWidget *widget, gint code, Scintilla::NotificationData *nt, gpointer data) {
		try {
			static_cast<ScintillaGTKAccessible*>(data)->Notify(widget, code, nt);
		} catch (...) {}
	}

	Sci::Position ByteOffsetFromCharacterOffset(Sci::Position startByte, int characterOffset) {
		if (!FlagSet(sci->pdoc->LineCharacterIndex(), Scintilla::LineCharacterIndexType::Utf32)) {
			return startByte + characterOffset;
		}
		if (characterOffset > 0) {
			// Try and reduce the range by reverse-looking into the character offset cache
			Sci::Line lineStart = sci->pdoc->LineFromPosition(startByte);
			Sci::Position posStart = sci->pdoc->IndexLineStart(lineStart, Scintilla::LineCharacterIndexType::Utf32);
			Sci::Line line = sci->pdoc->LineFromPositionIndex(posStart + characterOffset, Scintilla::LineCharacterIndexType::Utf32);
			if (line != lineStart) {
				startByte += sci->pdoc->LineStart(line) - sci->pdoc->LineStart(lineStart);
				characterOffset -= sci->pdoc->IndexLineStart(line, Scintilla::LineCharacterIndexType::Utf32) - posStart;
			}
		}
		Sci::Position pos = sci->pdoc->GetRelativePosition(startByte, characterOffset);
		if (pos == INVALID_POSITION) {
			// clamp invalid positions inside the document
			if (characterOffset > 0) {
				return sci->pdoc->Length();
			} else {
				return 0;
			}
		}
		return pos;
	}

	Sci::Position ByteOffsetFromCharacterOffset(Sci::Position characterOffset) {
		return ByteOffsetFromCharacterOffset(0, characterOffset);
	}

	Sci::Position CharacterOffsetFromByteOffset(Sci::Position byteOffset) {
		if (!FlagSet(sci->pdoc->LineCharacterIndex(), Scintilla::LineCharacterIndexType::Utf32)) {
			return byteOffset;
		}
		const Sci::Line line = sci->pdoc->LineFromPosition(byteOffset);
		const Sci::Position lineStart = sci->pdoc->LineStart(line);
		return sci->pdoc->IndexLineStart(line, Scintilla::LineCharacterIndexType::Utf32) + sci->pdoc->CountCharacters(lineStart, byteOffset);
	}

	void CharacterRangeFromByteRange(Sci::Position startByte, Sci::Position endByte, int *startChar, int *endChar) {
		*startChar = CharacterOffsetFromByteOffset(startByte);
		*endChar = *startChar + sci->pdoc->CountCharacters(startByte, endByte);
	}

	void ByteRangeFromCharacterRange(int startChar, int endChar, Sci::Position& startByte, Sci::Position& endByte) {
		startByte = ByteOffsetFromCharacterOffset(startChar);
		endByte = ByteOffsetFromCharacterOffset(startByte, endChar - startChar);
	}

	Sci::Position PositionBefore(Sci::Position pos) {
		return sci->pdoc->MovePositionOutsideChar(pos - 1, -1, true);
	}

	Sci::Position PositionAfter(Sci::Position pos) {
		return sci->pdoc->MovePositionOutsideChar(pos + 1, 1, true);
	}

	int StyleAt(Sci::Position position, bool ensureStyle = false) {
		if (ensureStyle)
			sci->pdoc->EnsureStyledTo(position);
		return sci->pdoc->StyleAt(position);
	}

	// For AtkText
	gchar *GetTextRangeUTF8(Sci::Position startByte, Sci::Position endByte);
	gchar *GetText(int startChar, int endChar);
	gchar *GetTextAfterOffset(int charOffset, AtkTextBoundary boundaryType, int *startChar, int *endChar);
	gchar *GetTextBeforeOffset(int charOffset, AtkTextBoundary boundaryType, int *startChar, int *endChar);
	gchar *GetTextAtOffset(int charOffset, AtkTextBoundary boundaryType, int *startChar, int *endChar);
#if ATK_CHECK_VERSION(2, 10, 0)
	gchar *GetStringAtOffset(int charOffset, AtkTextGranularity granularity, int *startChar, int *endChar);
#endif
	gunichar GetCharacterAtOffset(int charOffset);
	gint GetCharacterCount();
	gint GetCaretOffset();
	gboolean SetCaretOffset(int charOffset);
	gint GetOffsetAtPoint(gint x, gint y, AtkCoordType coords);
	void GetCharacterExtents(int charOffset, gint *x, gint *y, gint *width, gint *height, AtkCoordType coords);
	AtkAttributeSet *GetAttributesForStyle(unsigned int styleNum);
	AtkAttributeSet *GetRunAttributes(int charOffset, int *startChar, int *endChar);
	AtkAttributeSet *GetDefaultAttributes();
	gint GetNSelections();
	gchar *GetSelection(gint selection_num, int *startChar, int *endChar);
	gboolean AddSelection(int startChar, int endChar);
	gboolean RemoveSelection(int selection_num);
	gboolean SetSelection(gint selection_num, int startChar, int endChar);
	// for AtkEditableText
	bool InsertStringUTF8(Sci::Position bytePos, const gchar *utf8, Sci::Position lengthBytes);
	void SetTextContents(const gchar *contents);
	void InsertText(const gchar *text, int lengthBytes, int *charPosition);
	void CopyText(int startChar, int endChar);
	void CutText(int startChar, int endChar);
	void DeleteText(int startChar, int endChar);
	void PasteText(int charPosition);

public:
	ScintillaGTKAccessible(GtkAccessible *accessible_, GtkWidget *widget_);
	~ScintillaGTKAccessible();

	static ScintillaGTKAccessible *FromAccessible(GtkAccessible *accessible);
	static ScintillaGTKAccessible *FromAccessible(AtkObject *accessible) {
		return FromAccessible(GTK_ACCESSIBLE(accessible));
	}
	// So ScintillaGTK can notify us
	void ChangeDocument(Document *oldDoc, Document *newDoc);
	void NotifyReadOnly();
	void SetAccessibility(bool enabled);

	// Helper GtkWidget methods
	static AtkObject *WidgetGetAccessibleImpl(GtkWidget *widget, AtkObject **cache, gpointer widget_parent_class);

	// ATK methods

	class AtkTextIface {
	public:
		static void init(::AtkTextIface *iface);

	private:
		AtkTextIface();

		static gchar *GetText(AtkText *text, int start_offset, int end_offset);
		static gchar *GetTextAfterOffset(AtkText *text, int offset, AtkTextBoundary boundary_type, int *start_offset, int *end_offset);
		static gchar *GetTextBeforeOffset(AtkText *text, int offset, AtkTextBoundary boundary_type, int *start_offset, int *end_offset);
		static gchar *GetTextAtOffset(AtkText *text, gint offset, AtkTextBoundary boundary_type, gint *start_offset, gint *end_offset);
#if ATK_CHECK_VERSION(2, 10, 0)
		static gchar *GetStringAtOffset(AtkText *text, gint offset, AtkTextGranularity granularity, gint *start_offset, gint *end_offset);
#endif
		static gunichar GetCharacterAtOffset(AtkText *text, gint offset);
		static gint GetCharacterCount(AtkText *text);
		static gint GetCaretOffset(AtkText *text);
		static gboolean SetCaretOffset(AtkText *text, gint offset);
		static gint GetOffsetAtPoint(AtkText *text, gint x, gint y, AtkCoordType coords);
		static void GetCharacterExtents(AtkText *text, gint offset, gint *x, gint *y, gint *width, gint *height, AtkCoordType coords);
		static AtkAttributeSet *GetRunAttributes(AtkText *text, gint offset, gint *start_offset, gint *end_offset);
		static AtkAttributeSet *GetDefaultAttributes(AtkText *text);
		static gint GetNSelections(AtkText *text);
		static gchar *GetSelection(AtkText *text, gint selection_num, gint *start_pos, gint *end_pos);
		static gboolean AddSelection(AtkText *text, gint start, gint end);
		static gboolean RemoveSelection(AtkText *text, gint selection_num);
		static gboolean SetSelection(AtkText *text, gint selection_num, gint start, gint end);
	};
	class AtkEditableTextIface {
	public:
		static void init(::AtkEditableTextIface *iface);

	private:
		AtkEditableTextIface();

		static void SetTextContents(AtkEditableText *text, const gchar *contents);
		static void InsertText(AtkEditableText *text, const gchar *contents, gint length, gint *position);
		static void CopyText(AtkEditableText *text, gint start, gint end);
		static void CutText(AtkEditableText *text, gint start, gint end);
		static void DeleteText(AtkEditableText *text, gint start, gint end);
		static void PasteText(AtkEditableText *text, gint position);
	};
};

}


#endif