~writer-devs/writer/trunk

« back to all changes in this revision

Viewing changes to src/Utils/TextEditor.vala

  • Committer: Tuur Dutoit
  • Date: 2014-12-19 21:26:52 UTC
  • mfrom: (74.1.1 instant_style_apply)
  • Revision ID: me@tuurdutoit.be-20141219212652-57jdqncb38kwa1qb
MergeĀ ~ryanriffle/writer/instant_style_apply

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
 
31
31
namespace Writer {
32
32
    public class TextEditor : TextBuffer {
33
 
    
 
33
 
34
34
        public TextView text_view;
35
 
        
 
35
        public bool style_bold;
 
36
        public bool style_italic;
 
37
        public bool style_underline;
 
38
        public bool style_strikethrough;
 
39
 
36
40
        public signal void cursor_moved ();
37
41
        public signal void text_inserted ();
38
 
    
 
42
 
39
43
        public TextEditor () {
40
44
            setup_tagtable (this);
41
45
            text_view = new TextView.with_buffer (this);
42
 
            
43
 
            this.notify["cursor-position"].connect (cursor_moved_callback);
 
46
 
 
47
            style_bold = false;
 
48
            style_italic = false;
 
49
            style_underline = false;
 
50
            style_strikethrough = false;
 
51
 
 
52
            text_view.move_cursor.connect (cursor_moved_callback);
 
53
            text_view.button_release_event.connect (editor_clicked_callback);
44
54
            this.insert_text.connect_after (text_inserted_callback);
45
 
            
 
55
 
46
56
            text_view.key_press_event.connect (key_press_callback);
47
57
            text_view.pixels_below_lines = 20;
48
58
        }
49
 
        
 
59
 
50
60
        // Get a TextTagTable with all the default tags
51
61
        private void setup_tagtable (TextBuffer buffer) {
52
 
            
 
62
 
53
63
            buffer.create_tag ("bold", "weight", 700);
54
64
            buffer.create_tag ("italic", "style", Pango.Style.ITALIC);
55
65
            buffer.create_tag ("underline", "underline", Pango.Underline.SINGLE);
56
66
            buffer.create_tag ("strikethrough", "strikethrough", true);
57
 
            
 
67
 
58
68
            buffer.create_tag ("align-left", "justification", Gtk.Justification.LEFT);
59
69
            buffer.create_tag ("align-center", "justification", Gtk.Justification.CENTER);
60
70
            buffer.create_tag ("align-right", "justification", Gtk.Justification.RIGHT);
61
71
            buffer.create_tag ("align-fill", "justification", Gtk.Justification.FILL);
62
 
            
 
72
 
63
73
        }
64
 
        
65
 
        
 
74
 
 
75
 
66
76
        /*
67
77
         * Styles (apply, remove, check)
68
78
         */
69
 
         
 
79
 
70
80
        public void apply_style (string name) {
71
81
            if (has_selection)
72
82
                get_selection_range ().apply_style (name);
 
83
 
 
84
            if (name == "bold")
 
85
                style_bold = true;
 
86
            else if (name == "italic")
 
87
                style_italic = true;
 
88
            else if (name == "underline")
 
89
                style_underline = true;
 
90
            else if (name == "strikethrough")
 
91
                style_strikethrough = true;
73
92
        }
74
 
        
 
93
 
75
94
        public void remove_style (string name) {
76
95
            if (has_selection)
77
96
                get_selection_range ().remove_style (name);
 
97
 
 
98
            if (name == "bold")
 
99
                style_bold = false;
 
100
            else if (name == "italic")
 
101
                style_italic = false;
 
102
            else if (name == "underline")
 
103
                style_underline = false;
 
104
            else if (name == "strikethrough")
 
105
                style_strikethrough = false;
78
106
        }
79
 
        
 
107
 
80
108
        public void toggle_style (string name) {
81
109
            if (has_selection)
82
110
                get_selection_range ().toggle_style (name);
 
111
 
 
112
            if (name == "bold")
 
113
                style_bold = !style_bold;
 
114
            else if (name == "italic")
 
115
                style_italic = !style_italic;
 
116
            else if (name == "underline")
 
117
                style_underline = !style_underline;
 
118
            else if (name == "strikethrough")
 
119
                style_strikethrough = !style_strikethrough;
83
120
        }
84
 
        
 
121
 
85
122
        public bool has_style (string name) {
86
123
            if (has_selection)
87
124
                return get_selection_range ().has_style (name);
88
125
            else
89
126
                return iter_has_style (get_cursor (), name);
90
127
        }
91
 
        
92
 
        
 
128
 
 
129
 
93
130
        public Gtk.Justification get_justification () {
94
131
            if (has_selection)
95
132
                return get_selection_range ().get_justification ();
96
133
            else
97
134
                return get_justification_at_iter (get_cursor ());
98
135
        }
99
 
        
 
136
 
100
137
        public Gtk.Justification get_justification_at_iter (TextIter iter) {
101
138
            if (iter_has_style (iter, "align-center"))
102
139
                return Gtk.Justification.CENTER;
107
144
            else
108
145
                return Gtk.Justification.LEFT;
109
146
        }
110
 
        
 
147
 
111
148
        public int get_justification_as_int () {
112
149
            if (has_selection)
113
150
                return get_selection_range ().get_justification_as_int ();
114
151
            else
115
152
                return get_justification_as_int_at_iter (get_cursor ());
116
153
        }
117
 
        
 
154
 
118
155
        public int get_justification_as_int_at_iter (TextIter iter) {
119
156
            if (iter_has_style (iter, "align-center"))
120
157
                return 1;
125
162
            else
126
163
                return 0;
127
164
        }
128
 
        
 
165
 
129
166
        public void set_justification (string align) {
130
167
            get_paragraph (get_cursor ()).set_justification (align);
131
168
        }
132
 
        
133
 
        
 
169
 
 
170
 
134
171
        public void set_font (FontDescription font) {
135
172
            get_selection_range ().set_font (font);
136
173
        }
137
 
        
 
174
 
138
175
        public void set_font_from_string (string font) {
139
176
            get_selection_range ().set_font_from_string (font);
140
177
        }
141
 
        
142
 
        
 
178
 
 
179
 
143
180
        public void set_font_color (Gdk.Color color) {
144
181
            get_selection_range ().set_font_color (color);
145
182
        }
146
 
        
 
183
 
147
184
        public void set_font_color_from_string (string color) {
148
185
            get_selection_range ().set_font_color_from_string (color);
149
186
        }
150
 
        
151
 
        
152
 
        
 
187
 
 
188
 
 
189
 
153
190
        /*
154
191
         * Inserts
155
192
         */
156
 
        
 
193
 
157
194
        public void insert_comment () {
158
195
            print ("Insert Comment\n");
159
196
        }
160
 
        
 
197
 
161
198
        public void insert_image () {
162
199
            print ("Insert Image\n");
163
200
        }
164
 
        
 
201
 
165
202
        public void insert_link () {
166
203
            print ("Insert Link\n");
167
204
        }
168
 
        
 
205
 
169
206
        public void insert_table (int cols, int rows) {
170
207
            print ("Insert Table of %d columns by %d rows\n", cols, rows);
171
208
        }
172
 
        
173
 
        
 
209
 
 
210
 
174
211
        public void insert_line () {
175
212
            TextIter insert_cursor = get_cursor ();
176
213
            insert_line_at_iter (insert_cursor);
177
214
        }
178
 
        
 
215
 
179
216
        public void insert_paragraph () {
180
217
            TextIter cursor = get_cursor ();
181
218
            insert_paragraph_at_iter (cursor);
182
219
        }
183
 
        
 
220
 
184
221
        public void insert_line_at_iter (TextIter iter) {
185
222
            //TODO
186
223
            // Cursor does not move to next line
187
224
            // Only happens when inserting at the end of the buffer
188
225
            // Bug reported in GTK+
189
 
            
 
226
 
190
227
            insert (ref iter, "\u2028", -1);
191
228
        }
192
 
        
 
229
 
193
230
        public void insert_paragraph_at_iter (TextIter iter) {
194
231
            insert (ref iter, "\n", -1);
195
232
        }
196
 
        
197
 
        
198
 
        
199
 
        
 
233
 
 
234
 
 
235
 
 
236
 
200
237
        /*
201
238
         * paragraphs
202
239
         */
203
 
        
 
240
 
204
241
        // Moves iter to the start of the paragraph it is located in
205
242
        public TextIter get_paragraph_start (TextIter iter) {
206
243
            iter.backward_find_char ((char) => {
211
248
            }, null);
212
249
            return iter;
213
250
        }
214
 
        
 
251
 
215
252
        // Moves iter to the end of the paragraph it is located in
216
253
        public TextIter get_paragraph_end (TextIter iter) {
217
254
            iter.forward_find_char ((char) => {
222
259
            }, null);
223
260
            return iter;
224
261
        }
225
 
        
 
262
 
226
263
        public TextRange get_paragraph (TextIter iter) {
227
264
            TextIter start = get_paragraph_start (iter);
228
265
            TextIter end = get_paragraph_end (iter);
229
 
            
 
266
 
230
267
            return new TextRange (this, start, end);
231
268
        }
232
 
        
233
 
        
234
 
        
235
 
        
 
269
 
 
270
 
 
271
 
 
272
 
236
273
        /*
237
274
         * Search
238
275
         */
239
 
        
 
276
 
240
277
        public void search (string text) {
241
278
            if (text.length > 0)
242
279
                search_string (text);
243
280
            else
244
281
                clear_search ();
245
282
        }
246
 
        
 
283
 
247
284
        public void search_string (string text) {
248
285
            print ("Searching for: %s\n", text);
249
286
        }
250
 
        
 
287
 
251
288
        public void clear_search () {
252
289
            print ("Clearing search");
253
290
        }
254
 
        
255
 
        
256
 
        
 
291
 
 
292
 
 
293
 
257
294
        /*
258
295
         * Utilities
259
296
         */
260
 
        
 
297
 
261
298
        public TextIter get_cursor () {
262
299
            TextIter iter;
263
300
            get_iter_at_mark (out iter, get_insert ());
264
301
            return iter;
265
302
        }
266
 
        
 
303
 
267
304
        public TextRange get_cursor_as_range () {
268
305
            var cursor = get_cursor ();
269
306
            return new TextRange (this, cursor, cursor);
270
307
        }
271
 
        
 
308
 
272
309
        public TextRange get_selection_range () {
273
310
            TextIter start; TextIter end;
274
311
            get_selection_bounds (out start, out end);
275
312
            return new TextRange (this, start, end);
276
313
        }
277
 
        
 
314
 
278
315
        public bool iter_has_tag (TextIter iter, TextTag tag) {
279
316
            return iter.has_tag (tag) || iter.begins_tag (tag) || iter.ends_tag (tag);
280
317
        }
281
 
        
 
318
 
282
319
        public bool iter_has_style (TextIter iter, string name) {
283
320
            var tag = tag_table.lookup (name);
284
321
            return iter_has_tag (iter, tag);
285
322
        }
286
 
        
 
323
 
287
324
        public TextIter copy_iter (TextIter iter) {
288
325
            TextIter copy;
289
326
            get_iter_at_offset (out copy, iter.get_offset ());
290
327
            return copy;
291
328
        }
292
 
        
293
 
        
294
 
        
295
 
        
296
 
        
 
329
 
 
330
 
 
331
 
 
332
        private void update_styles () {
 
333
            var iter = get_cursor();
 
334
 
 
335
            style_bold = iter_has_style (iter, "bold");
 
336
            style_italic = iter_has_style (iter, "italic");
 
337
            style_underline = iter_has_style (iter, "underline");
 
338
            style_strikethrough = iter_has_style (iter, "strikethrough");
 
339
        }
 
340
 
297
341
        /*
298
342
         * Signal callbacks
299
343
         */
300
 
        
 
344
 
301
345
        private void cursor_moved_callback () {
302
346
            // Emit 'cursor_moved' signal
 
347
            update_styles ();
303
348
            cursor_moved ();
304
349
        }
305
 
        
 
350
 
306
351
        private void text_inserted_callback (TextIter cursor, string new_text, int length) {
307
352
            TextIter previous;
308
353
            get_iter_at_offset (out previous, cursor.get_offset () - length);
309
 
            
310
 
            if (iter_has_style (previous, "bold"))
 
354
 
 
355
            if (style_bold)
311
356
                apply_tag_by_name ("bold", previous, cursor);
312
 
            if (iter_has_style (previous, "italic"))
 
357
            if (style_italic)
313
358
                apply_tag_by_name ("italic", previous, cursor);
314
 
            if (iter_has_style (previous, "underline"))
 
359
            if (style_underline)
315
360
                apply_tag_by_name ("underline", previous, cursor);
316
 
            if (iter_has_style (previous, "strikethrough"))
 
361
            if (style_strikethrough)
317
362
                apply_tag_by_name ("strikethrough", previous, cursor);
318
 
            
319
 
            
 
363
 
 
364
 
320
365
            // Emit signals
321
366
            text_inserted ();
322
367
            cursor_moved ();
323
368
        }
324
 
        
 
369
 
325
370
        private bool key_press_callback (EventKey event) {
326
371
            if (Gdk.keyval_name (event.keyval) == "Return") {
327
372
                ModifierType modifiers = Gtk.accelerator_get_default_mod_mask ();
328
 
                
 
373
 
329
374
                if ((event.state & modifiers) == Gdk.ModifierType.SHIFT_MASK)
330
375
                    insert_line ();
331
376
                else
332
377
                    insert_paragraph ();
333
 
                
 
378
 
334
379
                return true;
335
380
            }
336
 
            else {                
 
381
            else {
337
382
                return false;
338
383
            }
339
384
        }
340
 
    
 
385
 
 
386
        private bool editor_clicked_callback (EventButton event) {
 
387
            update_styles ();
 
388
            cursor_moved ();
 
389
 
 
390
            return false;
 
391
        }
 
392
 
341
393
    }
342
 
}
 
 
b'\\ No newline at end of file'
 
394
}