~marco-crosio/pyroom/austosave

« back to all changes in this revision

Viewing changes to basic_edit.py

  • Committer: markino
  • Date: 2008-02-18 21:32:08 UTC
  • Revision ID: markino@casseruola-20080218213208-u59318mvs4tz6ycv
Modularized and Integrated with main trunk (rev27)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import gtk
 
2
import gtksourceview
 
3
 
 
4
from status_label import FadeLabel
 
5
from gui import GUI
 
6
 
 
7
import restore_session #Allows a session to be restored with "-s"
 
8
import check_unsaved #Checks that a buffer is unmodified before closing
 
9
import autosave
 
10
import styles
 
11
 
 
12
FILE_UNNAMED = _('* Unnamed *')
 
13
 
 
14
USAGE = _('Usage: pyroom [-v] [-l] [-C] [--style={style name}] [--autosave_time={minutes}/{0 = Autosave Disabled}] file1 file2')
 
15
 
 
16
STYLES = ', '.join(style for style in styles.styles)
 
17
 
 
18
KEY_BINDINGS = '\n'.join([
 
19
_('Control-H: Show help in a new buffer'),
 
20
_('Control-I: Show buffer information'),
 
21
_('Control-L: Toggle line number'),
 
22
_('Control-N: Create a new buffer'),
 
23
_('Control-O: Open a file in a new buffer'),
 
24
_('Control-Q: Quit'),
 
25
_('Control-S: Save current buffer'),
 
26
_('Control-Shift-S: Save current buffer as'),
 
27
_('Control-W: Close buffer and exit if it was the last buffer'),
 
28
_('Control-Y: Redo last typing'),
 
29
_('Control-Z: Undo last typing'),
 
30
_('Control-Page Up: Switch to previous buffer'),
 
31
_('Control-Page Down: Switch to next buffer'),
 
32
_('Control-Plus: Increases font size'),
 
33
_('Control-Minus: Decreases font size'),]
 
34
)
 
35
 
 
36
HELP = \
 
37
    _("""PyRoom - an adaptation of write room
 
38
Copyright (c) 2007 Nicolas Rougier, NoWhereMan
 
39
Copyright (c) 2008 Bruno Bord
 
40
 
 
41
This program is free software: you can redistribute it and/or modify it under
 
42
the terms of the GNU General Public License as published by the Free Software
 
43
Foundation, either version 3 of the License, or (at your option) any later
 
44
version.
 
45
 
 
46
Usage:
 
47
------
 
48
 
 
49
%s
 
50
style can be either: %s
 
51
 
 
52
 
 
53
Commands:
 
54
---------
 
55
%s
 
56
 
 
57
Warnings:
 
58
---------
 
59
No autosave.
 
60
No question whether to close a modified buffer or not
 
61
""" % (USAGE, STYLES, KEY_BINDINGS))
 
62
 
 
63
class BasicEdit():
 
64
    def __init__(self,style,verbose, ret):
 
65
    
 
66
        self.ret = ret
 
67
        self.style = style
 
68
        self.gui = GUI(style)
 
69
        self.status = self.gui.status
 
70
        self.window = self.gui.window
 
71
        self.textbox = self.gui.textbox
 
72
 
 
73
 
 
74
        self.new_buffer()
 
75
        restore_session.open_session(self, ret)
 
76
        self.textbox.connect('key-press-event', self.key_press_event)
 
77
        self.status.set_text(
 
78
            _('Welcome to PyRoom 1.0, type Control-H for help'))
 
79
        self.window.show_all()
 
80
        self.window.fullscreen()
 
81
        autosave.autosave_init(self) #autosave timer object
 
82
 
 
83
    def key_press_event(self, widget, event):
 
84
        """ key press event dispatcher """
 
85
 
 
86
        bindings = {
 
87
            gtk.keysyms.Page_Up: self.prev_buffer,
 
88
            gtk.keysyms.Page_Down: self.next_buffer,
 
89
            gtk.keysyms.h: self.show_help,
 
90
            gtk.keysyms.H: self.show_help,
 
91
            gtk.keysyms.i: self.show_info,
 
92
            gtk.keysyms.I: self.show_info,
 
93
            gtk.keysyms.l: self.toggle_lines,
 
94
            gtk.keysyms.L: self.toggle_lines,
 
95
            gtk.keysyms.n: self.new_buffer,
 
96
            gtk.keysyms.N: self.new_buffer,
 
97
            gtk.keysyms.o: self.open_file,
 
98
            gtk.keysyms.O: self.open_file,
 
99
            gtk.keysyms.q: self.quit,
 
100
            gtk.keysyms.Q: self.quit,
 
101
            gtk.keysyms.s: self.save_file,
 
102
            gtk.keysyms.S: self.save_file,
 
103
            gtk.keysyms.w: self.close_buffer,
 
104
            gtk.keysyms.W: self.close_buffer,
 
105
            gtk.keysyms.y: self.redo,
 
106
            gtk.keysyms.Y: self.redo,
 
107
            gtk.keysyms.z: self.undo,
 
108
            gtk.keysyms.Z: self.undo,
 
109
            gtk.keysyms.plus: self.gui.plus,
 
110
            gtk.keysyms.equal: self.gui.plus,
 
111
            gtk.keysyms.minus: self.gui.minus,
 
112
            }
 
113
        if event.state & gtk.gdk.CONTROL_MASK:
 
114
 
 
115
            # Special case for Control-Shift-s
 
116
 
 
117
            if event.state & gtk.gdk.SHIFT_MASK:
 
118
                print event.keyval
 
119
            if event.state & gtk.gdk.SHIFT_MASK and event.keyval\
 
120
                 == gtk.keysyms.S:
 
121
                self.edit.save_file_as()
 
122
                return True
 
123
            if bindings.has_key(event.keyval):
 
124
                bindings[event.keyval]()
 
125
                return True
 
126
        return False
 
127
 
 
128
 
 
129
    current = 0
 
130
    buffers = []
 
131
    def show_info(self):
 
132
        """ Display buffer information on status label for 5 seconds """
 
133
 
 
134
        buffer = self.buffers[self.current]
 
135
        if buffer.can_undo() or buffer.can_redo():
 
136
            status = _(' (modified)')
 
137
        else:
 
138
            status = ''
 
139
        self.status.set_text(_('Buffer %(buffer_id)d: %(buffer_name)s%(status)s, %(char_count)d byte(s), %(word_count)d word(s), %(lines)d line(s)') % {
 
140
            'buffer_id': self.current + 1,
 
141
            'buffer_name': buffer.filename,
 
142
            'status': status,
 
143
            'char_count': buffer.get_char_count(),
 
144
            'word_count': self.word_count(buffer),
 
145
            'lines': buffer.get_line_count(),
 
146
            }, 5000)
 
147
    def undo(self):
 
148
        """ Undo last typing """
 
149
 
 
150
        buffer = self.textbox.get_buffer()
 
151
        if buffer.can_undo():
 
152
            buffer.undo()
 
153
        else:
 
154
            self.status.set_text(_('No more undo!'))
 
155
 
 
156
    def redo(self):
 
157
        """ Redo last typing """
 
158
 
 
159
        buffer = self.textbox.get_buffer()
 
160
        if buffer.can_redo():
 
161
            buffer.redo()
 
162
        else:
 
163
            self.status.set_text(_('No more redo!'))
 
164
 
 
165
    def toggle_lines(self):
 
166
        """ Toggle lines number """
 
167
 
 
168
        b = not self.textbox.get_show_line_numbers()
 
169
        self.textbox.set_show_line_numbers(b)
 
170
 
 
171
    def open_file(self):
 
172
        """ Open file """
 
173
 
 
174
        chooser = gtk.FileChooserDialog('PyRoom', self.window,
 
175
                gtk.FILE_CHOOSER_ACTION_OPEN,
 
176
                buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
 
177
                gtk.STOCK_OPEN, gtk.RESPONSE_OK))
 
178
        chooser.set_default_response(gtk.RESPONSE_OK)
 
179
 
 
180
        res = chooser.run()
 
181
        if res == gtk.RESPONSE_OK:
 
182
            buffer = self.new_buffer()
 
183
            buffer.filename = chooser.get_filename()
 
184
            try:
 
185
                f = open(buffer.filename, 'r')
 
186
                buffer = self.buffers[self.current]
 
187
                buffer.begin_not_undoable_action()
 
188
                utf8 = unicode(f.read(), 'utf-8')
 
189
                buffer.set_text(utf8)
 
190
                buffer.end_not_undoable_action()
 
191
                f.close()
 
192
                self.status.set_text(_('File %s open')
 
193
                         % buffer.filename)
 
194
            except IOError, (errno, strerror):
 
195
                errortext = _('Unable to open %(filename)s.' % {'filename': buffer.filename})
 
196
                if errno == 2:
 
197
                    errortext += _(' The file does not exist.')
 
198
                elif errno == 13:
 
199
                    errortext += _(' You do not have permission to open the file.')
 
200
                buffer.set_text(_(errortext))
 
201
                if verbose:
 
202
                    print ('Unable to open %(filename)s. %(traceback)s'
 
203
                        % {'filename': buffer.filename, 'traceback': traceback.format_exc()})
 
204
                self.status.set_text(_('Failed to open %s')
 
205
                    % buffer.filename)
 
206
                buffer.filename = FILE_UNNAMED
 
207
            except:
 
208
                buffer.set_text(_('Unable to open %s\n'
 
209
                                 % buffer.filename))
 
210
                if verbose:
 
211
                    print ('Unable to open %(filename)s. %(traceback)s'
 
212
                        % {'filename': buffer.filename,
 
213
                        'traceback': traceback.format_exc()})
 
214
                buffer.filename = FILE_UNNAMED
 
215
        else:
 
216
            self.status.set_text(_('Closed, no files selected'))
 
217
        chooser.destroy()
 
218
 
 
219
    def save_file(self):
 
220
        """ Save file """
 
221
 
 
222
        buffer = self.buffers[self.current]
 
223
        if buffer.filename != FILE_UNNAMED:
 
224
            f = open(buffer.filename, 'w')
 
225
            txt = buffer.get_text(buffer.get_start_iter(),
 
226
                                  buffer.get_end_iter())
 
227
            f.write(txt)
 
228
            f.close()
 
229
            buffer.begin_not_undoable_action()
 
230
            buffer.end_not_undoable_action()
 
231
            self.status.set_text(_('File %s saved') % buffer.filename)
 
232
        else:
 
233
            self.save_file_as()
 
234
 
 
235
    def save_file_as(self):
 
236
        """ Save file as """
 
237
 
 
238
        buffer = self.buffers[self.current]
 
239
        chooser = gtk.FileChooserDialog('PyRoom', self.window,
 
240
                gtk.FILE_CHOOSER_ACTION_SAVE,
 
241
                buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
 
242
                gtk.STOCK_SAVE, gtk.RESPONSE_OK))
 
243
        chooser.set_default_response(gtk.RESPONSE_OK)
 
244
        if buffer.filename != FILE_UNNAMED:
 
245
            chooser.set_filename(buffer.filename)
 
246
        res = chooser.run()
 
247
        if res == gtk.RESPONSE_OK:
 
248
            buffer.filename = chooser.get_filename()
 
249
            self.save_file()
 
250
        else:
 
251
            self.status.set_text(_('Closed, no files selected'))
 
252
        chooser.destroy()
 
253
 
 
254
    # BB
 
255
 
 
256
 
 
257
 
 
258
    def word_count(self, buffer):
 
259
        """ Word count in a text buffer """
 
260
 
 
261
        iter1 = buffer.get_start_iter()
 
262
        iter2 = iter1.copy()
 
263
        iter2.forward_word_end()
 
264
        count = 0
 
265
        while iter2.get_offset() != iter1.get_offset():
 
266
            count += 1
 
267
            iter1 = iter2.copy()
 
268
            iter2.forward_word_end()
 
269
        return count
 
270
 
 
271
    def show_help(self):
 
272
        """ Create a new buffer and inserts help """
 
273
        buffer = self.new_buffer()
 
274
        buffer.begin_not_undoable_action()
 
275
        buffer.set_text(HELP)
 
276
        buffer.end_not_undoable_action()
 
277
 
 
278
    def new_buffer(self):
 
279
        """ Create a new buffer """
 
280
 
 
281
        buffer = gtksourceview.SourceBuffer()
 
282
        buffer.set_check_brackets(False)
 
283
        buffer.set_highlight(False)
 
284
        buffer.filename = FILE_UNNAMED
 
285
        buffer.tmp_filename = None  #CM autosave feature tempfilename
 
286
        self.buffers.insert(self.current + 1, buffer)
 
287
        buffer.place_cursor(buffer.get_start_iter())
 
288
        self.next_buffer()
 
289
        return buffer
 
290
 
 
291
    def close_buffer(self):
 
292
        """ Close current buffer """
 
293
        check_unsaved.check_unsaved_buffer(self)
 
294
        if len(self.buffers) > 1:
 
295
 
 
296
            self.buffers.pop(self.current)
 
297
            self.current = min(len(self.buffers) - 1, self.current)
 
298
            self.set_buffer(self.current)
 
299
        else:
 
300
            quit()
 
301
 
 
302
    def set_buffer(self, index):
 
303
        """ Set current buffer """
 
304
 
 
305
        if index >= 0 and index < len(self.buffers):
 
306
            self.current = index
 
307
            buffer = self.buffers[index]
 
308
            self.textbox.set_buffer(buffer)
 
309
            if hasattr(self, 'status'):
 
310
                self.status.set_text(
 
311
                    _('Switching to buffer %(buffer_id)d (%(buffer_name)s)'
 
312
                    % {'buffer_id': self.current + 1, 'buffer_name'
 
313
                    : buffer.filename}))
 
314
 
 
315
    def next_buffer(self):
 
316
        """ Switch to next buffer """
 
317
 
 
318
        if self.current < len(self.buffers) - 1:
 
319
            self.current += 1
 
320
        else:
 
321
            self.current = 0
 
322
        self.set_buffer(self.current)
 
323
 
 
324
    def prev_buffer(self):
 
325
        """ Switch to prev buffer """
 
326
 
 
327
        if self.current > 0:
 
328
            self.current -= 1
 
329
        else:
 
330
            self.current = len(self.buffers) - 1
 
331
        self.set_buffer(self.current)
 
332
 
 
333
    def quit(self):
 
334
        #Add any functions that you want to take place here before pyRoom quits
 
335
        check_unsaved.save_unsaved_on_exit(self)
 
336
        restore_session.save_session(self)
 
337
        autosave.autosave_quit(self)
 
338
        self.gui.quit()
 
339
 
 
340
# EOF