Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/atoidejouerbeta/ui/notebook.py
diff options
context:
space:
mode:
Diffstat (limited to 'atoidejouerbeta/ui/notebook.py')
-rw-r--r--atoidejouerbeta/ui/notebook.py574
1 files changed, 574 insertions, 0 deletions
diff --git a/atoidejouerbeta/ui/notebook.py b/atoidejouerbeta/ui/notebook.py
new file mode 100644
index 0000000..3ab3e60
--- /dev/null
+++ b/atoidejouerbeta/ui/notebook.py
@@ -0,0 +1,574 @@
+
+# python import
+import logging, os, shutil
+# ..
+from functools import partial
+from gettext import gettext as _
+
+# gtk import
+import gobject, gtk, glib
+
+# sugar import
+from sugar.activity import activity
+
+# atoidejouerbeta import
+from atoidejouerbeta.tools import image, storage, ui
+
+# get application logger
+logger = logging.getLogger('atoidejouerbeta')
+
+
+COLOR_GREY_DARK = ui.get_color(0.5, 0.5, 0.5)
+COLOR_GREY_LIGHT = ui.get_color(0.7, 0.7, 0.7)
+COLOR_GREY_WHITE = ui.get_color(0.85, 0.85, 0.85)
+COLOR_WHITE = ui.get_color(1.0, 1.0, 1.0)
+
+
+def _cb_swicth_page(widget, page, page_num, notebook):
+ if page_num == 1:
+ notebook.remove_button.show()
+ else:
+ notebook.remove_button.hide()
+ notebook.remove_label.hide()
+ # get current child
+ _child = widget.get_nth_page(page_num)
+ # get current label
+ _label = widget.get_tab_label(_child)
+ # force white
+ glib.idle_add(partial(_label.modify_fg, gtk.STATE_NORMAL, COLOR_WHITE))
+
+
+def _cb_cursor_changed(treeview, notebook, type_):
+ # get the current cursor and path
+ _path, _column = treeview.get_cursor()
+ # DEBUG
+ if _column is None:
+ return
+ else:
+ pass
+ # get model
+ _model = treeview.get_model()
+ # get resource info
+ _info = _model
+ # get iter
+ _iter = _model.get_iter(_path)
+ # update current
+ if type_ in ['graphics', 'sounds']:
+ # get value
+ _filename = _model.get_value(_iter, 1)
+ # udpate preview
+ notebook.screen.item_preview.set_item(filename=_filename)
+ # update current
+ notebook.current_item = _filename
+ # update current
+ elif type_ == 'journal':
+ # get value
+ _pixbuf = _model.get_value(_iter, 0)
+ _filename = _model.get_value(_iter, 1)
+ _metadata = _model.get_value(_iter, 3)
+ # copy journal item to library to work on it
+ if notebook._type == 'graphics':
+ storage.png_from_pixbuf(_filename, _metadata['timestamp'])
+ # ..
+ notebook._get_store_graphic()
+ # for sound
+ else:
+ # get source path
+ _src_path = storage.get_path_from_journal(_metadata['timestamp'],
+ 'audio/ogg')
+ # get dst path
+ _dst_path = storage.get_sound_path(_filename)
+ # copy
+ shutil.copy(_src_path, _dst_path)
+ # ..
+ notebook._get_store_sound()
+ # udpate preview
+ notebook.screen.item_preview.set_item(filename=_filename)
+ # update current
+ notebook.current_item = _filename
+ elif type_ == 'sequence':
+ # clear sequence preview
+ notebook.screen.sequence_preview.clear()
+ # get value
+ _sequence_path = _model.get_value(_iter, 2)
+ # update sequence ..
+ _fnames = storage.get_sequence_items(_sequence_path)
+ for _f in _fnames:
+ notebook.screen.sequence_preview.add_item(_f.strip())
+ # get sequence name
+ _sequence_name = _model.get_value(_iter, 1)
+ # get toolbar sequence entry
+ _entry = notebook.screen.toolbar._sequence_entry
+ # update toolbar entry
+ _entry.set_text(_sequence_name)
+ # update current
+ notebook.current_sequence = _sequence_name
+ # ..
+ notebook.update_store_sequence()
+ else:
+ pass
+ # .. add action - add column as no title
+ if _column.get_title() is None:
+ # get graphic name
+ _item_name = notebook.current_item
+ _sequence_name = notebook.current_sequence
+ if _sequence_name is None\
+ or _sequence_name.strip() == ''\
+ or _item_name is None:
+ pass
+ else:
+ # udpate sequence preview
+ notebook.screen.sequence_preview.add_item(_item_name)
+ # update sequence file
+ storage.sequence_save(notebook.screen.toolbar)
+ else:
+ pass
+
+
+def __remove_filename_from_sequence(type_, sequence, filename):
+ # little check
+ if filename.strip() == '':
+ # do nothing
+ return True
+ else:
+ # get sequence path
+ _seq_path = storage.get_sequence_path(type_, sequence)
+ # get current names
+ _fnames = storage.get_sequence_items(_seq_path)
+ # has remaining files
+ if filename in _fnames:
+ _fnames.remove(filename)
+ else:
+ return True
+ # ..
+ if len(_fnames) == 0:
+ os.remove(_seq_path)
+ return False
+ else:
+ # open file
+ _file = open(_seq_path, 'wb')
+ # update
+ for _f in _fnames:
+ _file.write('%s\n' % _f)
+ # close
+ _file.close()
+ # ..
+ return True
+
+
+def _on_button_click(button, notebook):
+ # get file path
+ if notebook._type == 'graphics':
+ _path = storage.get_image_path(notebook.current_item)
+ elif notebook._type == 'sounds':
+ _path = storage.get_sound_path(notebook.current_item)
+ # do nothing
+ else:
+ return
+ # remove file
+ os.remove(_path)
+ # shortcuts
+ _screen = notebook.screen
+ _toolbar = _screen.toolbar
+ _activity = _toolbar.activity
+ # ..
+ _keys = _activity.graphic_keys\
+ if _toolbar.name == 'graphics_add'\
+ else _activity.sound_keys
+ # ..
+ _type = 'graphics' if _toolbar.name == 'graphics_add' else 'sounds'
+ # prepare seq path
+ _seq_dir = os.path.join(activity.get_activity_root(), 'data',
+ 'sequences', _type)
+ # get sequence names
+ for _seq_name in os.listdir(_seq_dir):
+ # get sequence name from corresponding file name
+ _seq_name = _seq_name.replace('.seq', '')
+ # remove from file system
+ if __remove_filename_from_sequence(_type, _seq_name,
+ notebook.current_item) is True:
+ # remove from keys
+ _keys.remove_filename_from_all(_seq_name, notebook.current_item)
+ # remove the entire sequence
+ else:
+ # from keys
+ _keys.remove_sequence(_seq_name)
+ # ..
+ notebook._get_store_sequence()
+ # remove item in treview
+ notebook.remove_current_row()
+ # remove current sequence
+ _screen.sequence_preview.remove_item(notebook.current_item)
+ # avoid current
+ notebook.current_item = None
+
+
+class ResourceNotebook(gtk.Frame):
+
+ def __init__(self, screen, type_):
+ # init parent
+ gtk.Frame.__init__(self)
+ self.set_shadow_type(gtk.SHADOW_NONE)
+ # do show
+ self.show()
+ # keep the screen
+ self.screen = screen
+ # keep the type
+ self._type = type_
+ # keep the current item
+ self.current_item = None
+ self.current_sequence = None
+ # ..
+ self.library_treeview = None
+ self.sequence_treeview = None
+ # keep stores
+ self._store_sequence = None
+ self._store_graphic = None
+ self._store_sound = None
+ self._store_journal = None
+ # init main box
+ _main_box = gtk.VBox(homogeneous=False, spacing=0)
+ _main_box.show()
+ # ..
+ self.add(_main_box)
+ # init remove button and label
+ self.remove_button, self.remove_label = self._get_remove_button()
+ # ..
+ _main_box.pack_start(self._get_notebook(), expand=True, fill=True)
+ # ..
+ _main_box.pack_start(self.remove_button, expand=False, fill=True)
+ _main_box.pack_start(self.remove_label, expand=False, fill=True)
+
+ def _get_remove_button(self):
+ # init button
+ _button = ui.get_button(label=_('Remove Item from Disk'),
+ stock_id='delete', width=48, padding=(5, 0))
+ _button.set_border_width(2)
+ _button.hide()
+ # set cb
+ _button.connect('clicked', _on_button_click, self)
+ # init
+ _label = gtk.Label()
+ # set markup
+ _label.set_use_markup(True)
+ # align
+ _label.set_padding(5, 5)
+ _label.set_alignment(0, 0.5)
+ # return it
+ return _button, _label
+
+ def focus_current_seq(self, name=None):
+ # get seq names
+ _seq_names = [_n for _n, _p in storage.list_sequence_names(self._type)]
+ _seq_names.sort()
+ # ..
+ self.current_sequence = name\
+ if len(_seq_names) == 0 or name is not None\
+ else _seq_names[0]
+ if len(_seq_names) == 0:
+ return
+ else:
+ # ..
+ _index = 0 if self.current_sequence is None\
+ or self.current_sequence not in _seq_names\
+ else _seq_names.index(self.current_sequence)
+ # get the current cursor and path
+ self.sequence_treeview.set_cursor(_index)
+
+
+ def remove_current_row(self):
+ # get the current cursor and path
+ _path, _column = self.library_treeview.get_cursor()
+ # get model
+ _model = self.library_treeview.get_model()
+ # get resource info
+ _info = _model
+ # get iter
+ _iter = _model.get_iter(_path)
+ # and remove
+ _model.remove(_iter)
+
+ def update_store_sequence(self):
+ # ..
+ if self.current_sequence is None:
+ return
+ else:
+ # ..
+ _filename = storage.get_sequence_first_graphic_name(
+ self._type, self.current_sequence)
+ if _filename is None:
+ return
+ # set current
+ else:
+ self.screen.sequence_preview.set_current(_filename)
+
+ def _get_store_sequence(self):
+ # init store
+ if self._store_sequence is None:
+ self._store_sequence = gtk.ListStore(
+ gtk.gdk.Pixbuf,
+ gobject.TYPE_STRING,
+ gobject.TYPE_PYOBJECT
+ )
+ else:
+ self._store_sequence.clear()
+ # liste seq names
+ _seq_names = storage.list_sequence_names(self._type)
+ # ..
+ for _name, _path in _seq_names:
+ # ...
+ _pixbuf = image.get_sequence_first_graphic(self._type, _name)
+ # do update
+ self._store_sequence.append([_pixbuf, _name, _path])
+ # return the store
+ return self._store_sequence
+
+ def _get_store_graphic(self):
+ # init/reset store
+ if self._store_graphic is None:
+ self._store_graphic = gtk.ListStore(
+ gtk.gdk.Pixbuf,
+ gobject.TYPE_STRING,
+ gtk.gdk.Pixbuf,
+ gobject.TYPE_PYOBJECT
+ )
+ else:
+ self._store_graphic.clear()
+ # ..
+ _add_path = storage.get_icon_path('more_small')
+ # ..
+ _graphic_dir = os.path.join(activity.get_activity_root(), 'data',
+ 'graphics')
+ # ..
+ for _filename in os.listdir(_graphic_dir):
+ # ..
+ _path = os.path.join(_graphic_dir, _filename)
+ # little check
+ if os.path.isfile(_path):
+ # check name
+ try:
+ _filename, _ext = os.path.splitext(_filename)
+ # check ext
+ if _ext in ['.png']:
+ pass
+ else:
+ continue
+ except Exception, e:
+ # TODO log something
+ continue
+ # ..
+ _pixbuf = image.get_pixbuf(_path, 64, 48)
+ _pix_a = image.get_pixbuf(_add_path, 24, 24)
+ # do update
+ self._store_graphic.append([_pixbuf, _filename, _pix_a, _path])
+ else:
+ continue
+ # return the store
+ return self._store_graphic
+
+ def _get_store_sound(self):
+ # init/reset store
+ if self._store_sound is None:
+ self._store_sound = gtk.ListStore(
+ gtk.gdk.Pixbuf,
+ gobject.TYPE_STRING,
+ gtk.gdk.Pixbuf,
+ gobject.TYPE_PYOBJECT
+ )
+ else:
+ self._store_sound.clear()
+ # prepare icon path
+ _pix_path = storage.get_image_path('sound', dir_='data')
+ _add_path = storage.get_icon_path('more_small')
+ # ..
+ _sound_dir = os.path.join(activity.get_activity_root(), 'data',
+ 'sounds')
+ # ..
+ for _filename in os.listdir(_sound_dir):
+ # ..
+ _path = os.path.join(_sound_dir, _filename)
+ # little check
+ if os.path.isfile(_path):
+ # check name
+ try:
+ _filename, _ext = os.path.splitext(_filename)
+ # check ext
+ if _ext in ['.ogg']:
+ pass
+ else:
+ continue
+ except Exception, e:
+ # TODO log something
+ continue
+ # ..
+ _pixbuf = image.get_pixbuf(_pix_path, 64, 48)
+ _pix_a = image.get_pixbuf(_add_path, 24, 24)
+ # do update
+ self._store_sound.append([_pixbuf, _filename, _pix_a, _path])
+ else:
+ continue
+ # return the store
+ return self._store_sound
+
+ def __update_store(self, default_pix_path, **query):
+ # update store
+ for _i in storage.list_info_from_journal(**query):
+ if _i['preview'] is None:
+ # ..
+ _pixbuf = image.get_pixbuf(default_pix_path, 64, 48)
+ else:
+ # prepare preview
+ _pixbuf = storage.get_pixbuf_from_data(_i['preview'],
+ size=(64, 48))
+ # ..
+ _add_path = storage.get_icon_path('more_small')
+ _pix_a = image.get_pixbuf(_add_path, 24, 24)
+ # store info
+ _store_info = {
+ 'activity_id':_i['activity_id'],
+ 'timestamp': _i['timestamp']
+ }
+ # do update
+ _row = [_pixbuf, _i['title'], _pix_a, _store_info]
+ self._store_journal.append(_row)
+
+ def _get_store_journal(self):
+ # init/reset store
+ if self._store_journal is None:
+ self._store_journal = gtk.ListStore(
+ gtk.gdk.Pixbuf,
+ gobject.TYPE_STRING,
+ gtk.gdk.Pixbuf,
+ gobject.TYPE_PYOBJECT
+ )
+ else:
+ self._store_journal.clear()
+ # app to get the journal entries
+ _a_name = 'paint' if self._type=='graphics' else 'record'
+ # prepare icon path
+ _default_pix_path = storage.get_image_path(_a_name, dir_='data')
+ # manage image from app for paint only
+ if self._type=='graphics':
+ self.__update_store(_default_pix_path, activity_name=_a_name)
+ else:
+ pass
+ # ..
+ _mime_type = 'image/png' if self._type=='graphics' else 'audio/ogg'
+ # import based on myme type
+ self.__update_store(_default_pix_path, mime_type=_mime_type)
+ # return the store
+ return self._store_journal
+
+ def _get_treeview(self, type_=None):
+ # ..
+ _scrolled_win = gtk.ScrolledWindow()
+ _scrolled_win.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+ _scrolled_win.show()
+ # prepare colums
+ _col_preview = gtk.TreeViewColumn(_('Preview'))
+ _col_description = gtk.TreeViewColumn(_('Name'))
+ _col_add = gtk.TreeViewColumn()
+ # set renderers
+ _cell_pix = gtk.CellRendererPixbuf()
+ _cell_pix.set_property('height', 50)
+ _col_preview.pack_start(_cell_pix, expand=False)
+ _col_preview.add_attribute(_cell_pix, 'pixbuf', 0)
+ # ..
+ _cell_text = gtk.CellRendererText()
+ _cell_text.set_property('height', 50)
+ _col_description.pack_start(_cell_text, expand=False)
+ _col_description.add_attribute(_cell_text, 'text', 1)
+ _col_description.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+ # ..
+ if type_ == 'sequence':
+ _col_description.set_fixed_width(220)
+ else:
+ _col_description.set_fixed_width(250)
+ # ..
+ _cell_add = gtk.CellRendererPixbuf()
+ _cell_add.set_property('height', 50)
+ _col_add.pack_start(_cell_add, expand=False)
+ _col_add.add_attribute(_cell_add, 'pixbuf', 2)
+ _col_add.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+ _col_add.set_fixed_width(30)
+ # update store
+ if type_ == 'sequence':
+ _store = self._get_store_sequence()
+ elif type_ == 'graphics':
+ _store = self._get_store_graphic()
+ elif type_ == 'sounds':
+ _store = self._get_store_sound()
+ elif type_ == 'journal':
+ _store = self._get_store_journal()
+ else:
+ return None
+ # ensure sorting
+ _store.set_sort_column_id(1, gtk.SORT_ASCENDING)
+ # init treeview
+ _treeview = gtk.TreeView(_store)
+ _treeview.set_reorderable(False)
+ # cb
+ _treeview.connect('cursor-changed', _cb_cursor_changed, self, type_)
+ # show it
+ _treeview.show()
+ # add columns
+ _treeview.append_column(_col_preview)
+ _treeview.append_column(_col_description)
+ # ..
+ if type_ == 'sequence':
+ pass
+ else:
+ _treeview.append_column(_col_add)
+ # ..
+ _scrolled_win.add(_treeview)
+ # return it
+ return _scrolled_win
+
+ def _get_notebook(self):
+ # get list 1
+ _list1 = self._get_treeview(type_='sequence')
+ # keep sequence treeview
+ self.sequence_treeview = _list1.get_children()[0]
+ # create a label for the button
+ _label1 = gtk.Label(_('Sequences'))
+ # ...
+ _label1.modify_fg(gtk.STATE_ACTIVE, COLOR_WHITE)
+ # ...
+ _label1.show()
+ # get list 2
+ _list2 = self._get_treeview(type_=self._type)
+ # keep library treeview
+ self.library_treeview = _list2.get_children()[0]
+ # create a label for the button
+ _label2 = gtk.Label(_('Library'))
+ # ...
+ _label2.modify_fg(gtk.STATE_ACTIVE, COLOR_WHITE)
+ # ...
+ _label2.show()
+ # get list 2
+ _list3 = self._get_treeview(type_='journal')
+ # create a label for the button
+ _label3 = gtk.Label(_('Journal'))
+ # ...
+ _label3.modify_fg(gtk.STATE_ACTIVE, COLOR_WHITE)
+ # ...
+ _label3.show()
+ # init notebook
+ _notebook = gtk.Notebook()
+ _notebook.set_show_border(True)
+ _notebook.set_border_width(2)
+ _notebook.set_tab_pos(gtk.POS_TOP)
+ _notebook.set_size_request(360, -1)
+ # ..
+ _notebook.modify_bg(gtk.STATE_NORMAL, COLOR_GREY_DARK)
+ _notebook.modify_bg(gtk.STATE_ACTIVE, COLOR_GREY_LIGHT)
+ # ..
+ _notebook.connect('switch-page', _cb_swicth_page, self)
+ # ..
+ _notebook.show()
+ # add tabs
+ _notebook.append_page(_list1, _label1)
+ _notebook.append_page(_list2, _label2)
+ _notebook.append_page(_list3, _label3)
+ # return it
+ return _notebook