Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWalter Bender <walter.bender@gmail.com>2011-06-10 13:06:21 (GMT)
committer Walter Bender <walter.bender@gmail.com>2011-06-10 13:06:21 (GMT)
commit5138f2678da9af91cff2c15911ebefc012a9b18b (patch)
tree4dbaccf9586b5994a733c2f588e1619dc097ac4d
parente2cbb4b0a12ceda80e7ea8d77fa5325a778ec2c2 (diff)
added file system IO
-rw-r--r--edit_app.py161
-rw-r--r--mdnames.py1
2 files changed, 153 insertions, 9 deletions
diff --git a/edit_app.py b/edit_app.py
index 2c4c7f0..07b7130 100644
--- a/edit_app.py
+++ b/edit_app.py
@@ -21,11 +21,15 @@ from groupthink import sugar_tools, gtk_tools
from gettext import gettext as _
+import os
import gtk
import pango
import time
import gtksourceview2 as gtksourceview
+import logging
+_logger = logging.getLogger('edit-activity')
+
from sugar.activity import activity
try: # Can use 'New' toolbar design?
@@ -40,10 +44,33 @@ if _HAVE_TOOLBOX:
from sugar.graphics import style
from sugar.activity.activity import EditToolbar
+from sugar.graphics.toolbutton import ToolButton
+from sugar.graphics.alert import Alert
+from sugar.graphics.icon import Icon
import mdnames
+def _button_factory(icon_name, tooltip, callback, toolbar, cb_arg=None,
+ accelerator=None):
+ '''Factory for making toolbar buttons'''
+ my_button = ToolButton(icon_name)
+ my_button.set_tooltip(tooltip)
+ my_button.props.sensitive = True
+ if accelerator is not None:
+ my_button.props.accelerator = accelerator
+ if cb_arg is not None:
+ my_button.connect('clicked', callback, cb_arg)
+ else:
+ my_button.connect('clicked', callback)
+ if hasattr(toolbar, 'insert'): # the main toolbar
+ toolbar.insert(my_button, -1)
+ else: # or a secondary toolbar
+ toolbar.props.page.insert(my_button, -1)
+ my_button.show()
+ return my_button
+
+
class EditActivity(sugar_tools.GroupActivity):
'''A text editor for Sugar
pylint says I need a docstring. Here you go.
@@ -68,6 +95,8 @@ class EditActivity(sugar_tools.GroupActivity):
sure there's early_setup, but that's not early enough
'''
+ self._object_id = handle.object_id
+
self.buffer = gtksourceview.Buffer()
self.refresh_buffer = False
@@ -78,6 +107,13 @@ class EditActivity(sugar_tools.GroupActivity):
sugar_tools.GroupActivity.__init__(self, handle)
+ self.gnome_folder = os.environ['HOME']
+ if mdnames.gnomefilename_md in self.metadata:
+ self.gnome_filename = self.metadata[mdnames.gnomefilename_md]
+ else:
+ self.gnome_filename = None
+
+
def fix_mimetype(self):
'''We must have a mimetype. Sometimes, we don't (when we get launched
newly.) This fixes that.'''
@@ -121,6 +157,17 @@ class EditActivity(sugar_tools.GroupActivity):
self.edit_toolbar.copy.connect('clicked', self.copybutton_cb)
self.edit_toolbar.paste.connect('clicked', self.pastebutton_cb)
+ # Only enable file open dialogs if this is a new, unshared instance
+ if self._object_id is None:
+ self._new_file_from_gnome = _button_factory(
+ 'user-document-open', _('New file from GNOME'),
+ self._new_file_from_gnome_cb, toolbar)
+
+ # But always enable save as to GNOME
+ self._save_file_to_gnome = _button_factory(
+ 'user-document-save', _('Save file to GNOME'),
+ self._save_as_file_to_gnome_cb, toolbar)
+
if _HAVE_TOOLBOX:
separator = gtk.SeparatorToolItem()
separator.props.draw = False
@@ -191,24 +238,117 @@ class EditActivity(sugar_tools.GroupActivity):
#Return the main widget. our parents take care of GTK stuff
return self.scrollwindow
- def save_to_journal(self, filename, cloudstring):
- '''Saves to the journal.
- We use metadata magic to keep the collab. stuff'''
- self.metadata[mdnames.cloudstring_md] = cloudstring
+ def _new_file_from_gnome_cb(self, button=None):
+ ''' Opens a chooser dialog to file system for loading '''
+ text = self._get_text()
+ if len(text) > 0:
+ discard_alert = Alert()
+ discard_alert.props.title = _('You have been typing. Discard?')
+ discard_alert.props.msg = self._get_text()[0:min(25, len(text))] +\
+ '...'
+ cancel_icon = Icon(icon_name='dialog-cancel')
+ discard_alert.add_button(gtk.RESPONSE_CANCEL, _('Cancel'),
+ cancel_icon)
+ cancel_icon.show()
+ discard_icon = Icon(icon_name='dialog-ok')
+ discard_alert.add_button(gtk.RESPONSE_APPLY, _('Discard'),
+ discard_icon)
+ discard_icon.show()
+ self.add_alert(discard_alert)
+ discard_alert.connect('response', self.__discard_cb)
+ discard_alert.show()
+ else:
+ self._open_dialog()
+
+ def __discard_cb(self, alert, response_id):
+ ''' Callback for positive response to discard alert '''
+ if response_id is gtk.RESPONSE_APPLY:
+ self._open_dialog()
+ self.remove_alert(alert)
+
+ def _open_dialog(self):
+ dialog = gtk.FileChooserDialog(
+ _('Load...'), None, gtk.FILE_CHOOSER_ACTION_OPEN,
+ (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN,
+ gtk.RESPONSE_OK))
+ dialog.set_default_response(gtk.RESPONSE_OK)
+ dialog.set_current_folder(self.gnome_folder)
+ response = dialog.run()
+ if response == gtk.RESPONSE_OK:
+ self.load_from_journal(dialog.get_filename())
+ self.gnome_folder = dialog.get_current_folder()
+ self.gnome_filename = dialog.get_filename()
+ self.metadata['title'] = self.gnome_filename
+ self.metadata[mdnames.gnomefilename_md] = self.gnome_filename
+ dialog.destroy()
+
+ def _save_as_file_to_gnome_cb(self, button=None):
+ ''' Opens a chooser dialog to file system for save as '''
+ dialog = gtk.FileChooserDialog(
+ _('Save as...'), None, gtk.FILE_CHOOSER_ACTION_OPEN,
+ (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE_AS,
+ gtk.RESPONSE_OK))
+ dialog.set_default_response(gtk.RESPONSE_OK)
+ dialog.set_current_folder(self.gnome_folder)
+ if self.gnome_filename is not None:
+ dialog.set_filename(self.gnome_filename)
+ response = dialog.run()
+ if response == gtk.RESPONSE_OK:
+ self.gnome_folder = dialog.get_current_folder()
+ self.gnome_filename = dialog.get_filename()
+ self.metadata['title'] = self.gnome_filename
+ self.metadata[mdnames.gnomefilename_md] = self.gnome_filename
+ if os.path.exists(dialog.get_filename()):
+ exists_alert = Alert()
+ exists_alert.props.title = _('File exists. Overwrite?')
+ exists_alert.props.msg = dialog.get_filename()
+ cancel_icon = Icon(icon_name='dialog-cancel')
+ exists_alert.add_button(gtk.RESPONSE_CANCEL, _('Cancel'),
+ cancel_icon)
+ cancel_icon.show()
+ save_icon = Icon(icon_name='dialog-ok')
+ exists_alert.add_button(gtk.RESPONSE_APPLY, _('Overwrite'),
+ save_icon)
+ save_icon.show()
+ self.add_alert(exists_alert)
+ exists_alert.connect('response', self.__overwrite_cb)
+ exists_alert.show()
+ else:
+ self._write_to_file(self.gnome_filename)
+ dialog.destroy()
- #Also write to file:
- fhandle = open(filename, "w")
+ def __overwrite_cb(self, alert, response_id):
+ ''' Callback for positive response to overwrite alert '''
+ if response_id is gtk.RESPONSE_APPLY:
+ self._write_to_file(self.gnome_filename)
+ self.remove_alert(alert)
+ def _get_text(self):
+ ''' Get text from edit buffer '''
bounds = self.buffer.get_bounds()
- text = self.buffer.get_text(bounds[0], bounds[1])
+ return self.buffer.get_text(bounds[0], bounds[1])
+
+ def _write_to_file(self, filename):
+ ''' Write text to file, either in the datastore or file system '''
+ fhandle = open(filename, "w")
+
+ text = self._get_text()
fhandle.write(text)
fhandle.close()
+ return text
- self.fix_mimetype()
+ def save_to_journal(self, filename, cloudstring):
+ '''Saves to the journal.
+ We use metadata magic to keep the collab. stuff'''
+
+ # TODO: Only save cloudstring_md if we have been sharing.
+ self.metadata[mdnames.cloudstring_md] = cloudstring
#We can do full-text search on all Edit documents, yay
- self.metadata[mdnames.contents_md] = text
+ self.metadata[mdnames.contents_md] = self._write_to_file(filename)
+
+ self.fix_mimetype()
#If we edit the file in another way, we need to reload the contents
#we fudge the timestamp forwards by 5 seconds
@@ -218,6 +358,7 @@ class EditActivity(sugar_tools.GroupActivity):
def load_from_journal(self, filename):
'''Load the file. Duh.'''
+ _logger.debug('loading %s' % (filename))
if mdnames.cloudstring_md in self.metadata:
if self.checkts():
#if we were edited in another program
@@ -240,6 +381,8 @@ class EditActivity(sugar_tools.GroupActivity):
def when_shared(self):
self._edit_toolbar.undo.set_sensitive(False)
self._edit_toolbar.redo.set_sensitive(False)
+ self._new_file_from_journal.set_sensitive(False)
+ self._new_file_from_gnome.set_sensitive(False)
def undobutton_cb(self, button):
if self.buffer.can_undo():
diff --git a/mdnames.py b/mdnames.py
index 654b628..8270ff2 100644
--- a/mdnames.py
+++ b/mdnames.py
@@ -5,3 +5,4 @@ cloudtimestamp_md = "org.laptop.Edit.cloudtimestamp"
cloudstring_md = "org.laptop.Edit.cloudstring"
contents_md = "org.laptop.Edit.contents:text"
mimetype_md = "mime_type"
+gnomefilename_md = "gnome_filename"