diff options
author | Aleksey Lim <alsroot@member.fsf.org> | 2009-02-26 15:52:53 (GMT) |
---|---|---|
committer | Aleksey Lim <alsroot@member.fsf.org> | 2009-03-02 06:32:18 (GMT) |
commit | 842a3724c9277b7ecad2d17408128ea22efb4132 (patch) | |
tree | 8cd942af824d275796e666110aefc5c43cbbe2d2 | |
parent | ba80473f40ad39e03bb2edfe87cf6d03c48d2478 (diff) |
Use array in memory to store map
-rw-r--r-- | GUI_Components/Compound_Widgets/bookview.py | 65 | ||||
-rw-r--r-- | GUI_Components/Compound_Widgets/toolbar.py | 17 | ||||
-rw-r--r-- | Processing/IO_Manager.py | 129 | ||||
-rw-r--r-- | activity.py | 2 | ||||
-rw-r--r-- | book.py | 31 | ||||
-rw-r--r-- | library.py | 23 |
6 files changed, 140 insertions, 127 deletions
diff --git a/GUI_Components/Compound_Widgets/bookview.py b/GUI_Components/Compound_Widgets/bookview.py index 3396dfd..79fccd9 100644 --- a/GUI_Components/Compound_Widgets/bookview.py +++ b/GUI_Components/Compound_Widgets/bookview.py @@ -18,10 +18,12 @@ import logging import gobject from gettext import gettext as _ +from sugar.graphics.toolbutton import ToolButton from sugar.activity.activity import get_bundle_path, get_activity_root from sugar.graphics.style import * from Processing.IO_Manager import IO_Manager +from GUI_Components.Compound_Widgets.toolbar import WidgetItem, ButtonItem logger = logging.getLogger('infoslicer') @@ -31,34 +33,53 @@ class BookView(gtk.VBox): self.book = book self._changing = None - # title + title = gtk.Toolbar() + + # title checkbox self._check = gtk.CheckButton() - self._check.show() self._check.props.can_focus = False + self._check.props.tooltip_text = _('Chech/uncheck all articles') self._check.connect('toggled', self._check_toggled_cb) check_box = gtk.HBox() - check_box.show() check_box.set_size_request(50, -1) check_box.pack_start(self._check, True, False) - - title = gtk.Label(name) - title.show() - title.modify_fg(gtk.STATE_NORMAL, COLOR_WHITE.get_gdk_color()) - title_box = gtk.HBox() - title_box.show() - title_box.pack_start(check_box, False) - title_box.pack_start(title, False) - title = gtk.EventBox() - title.show() - title.add(title_box) - title.modify_bg(gtk.STATE_NORMAL, COLOR_TOOLBAR_GREY.get_gdk_color()) + title.insert(WidgetItem(check_box), -1) + + # title caption + + caption_label = gtk.Label(name) + caption_label.modify_fg(gtk.STATE_NORMAL, COLOR_WHITE.get_gdk_color()) + caption_box = gtk.HBox() + caption_box.pack_start(check_box, False) + caption_box.pack_start(caption_label, False) + caption = gtk.EventBox() + caption.add(caption_box) + caption.modify_bg(gtk.STATE_NORMAL, COLOR_TOOLBAR_GREY.get_gdk_color()) + title.insert(WidgetItem(caption), -1) + + separator = gtk.SeparatorToolItem() + separator.props.draw = False + separator.set_expand(True) + title.insert(separator, -1) + + # move buttons + + downward = ButtonItem('go-down', + label='Move downward', + tooltip_text=_('Move article downward')) + downward.connect('clicked', self._downward_clicked_cb) + title.insert(downward, -1) + upward = ButtonItem('go-up', + label=_('Move upward'), + tooltip_text=_('Move article upward')) + upward.connect('clicked', self._upward_clicked_cb) + title.insert(upward, -1) # tree self.store = gtk.ListStore(bool, str) self.tree = gtk.TreeView(self.store) - self.tree.show() self.tree.props.headers_visible = False self.tree.connect('cursor-changed', self._cursor_changed_cb) @@ -75,19 +96,25 @@ class BookView(gtk.VBox): cell.props.editable = True self.tree.insert_column_with_attributes(1, '', cell, text=1) - for i in self.book.get_pages(): - self.store.append((False, i)) + for i in self.book.map: + self.store.append((False, i['title'])) # scrolled tree tree_scroll = gtk.ScrolledWindow() - tree_scroll.show() tree_scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) tree_scroll.add_with_viewport(self.tree) self.pack_start(title, False) self.pack_start(tree_scroll) self.tree.set_cursor(0, self.tree.get_column(1), False) + self.show_all() + + def _downward_clicked_cb(self, widget): + pass + + def _upward_clicked_cb(self, widget): + pass def _check_toggled_cb(self, widget): for i in self.store: diff --git a/GUI_Components/Compound_Widgets/toolbar.py b/GUI_Components/Compound_Widgets/toolbar.py index 7fc3bb9..f9f7a34 100644 --- a/GUI_Components/Compound_Widgets/toolbar.py +++ b/GUI_Components/Compound_Widgets/toolbar.py @@ -13,10 +13,23 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import gtk +import gobject + +from sugar.graphics.icon import Icon class WidgetItem(gtk.ToolItem): - def __init__(self, widget, expand=False): + def __init__(self, widget): gtk.ToolItem.__init__(self) - self.set_expand(expand) self.add(widget) widget.show() + +class ButtonItem(gtk.ToolButton): + def __init__(self, icon_name, size=gtk.ICON_SIZE_SMALL_TOOLBAR, **kwargs): + gobject.GObject.__init__(self, **kwargs) + + icon = Icon(icon_name=icon_name, icon_size=size) + # The alignment is a hack to work around gtk.ToolButton code + # that sets the icon_size when the icon_widget is a gtk.Image + alignment = gtk.Alignment(0.5, 0.5) + alignment.add(icon) + self.set_icon_widget(alignment) diff --git a/Processing/IO_Manager.py b/Processing/IO_Manager.py index 2cc3bd8..d00c2b7 100644 --- a/Processing/IO_Manager.py +++ b/Processing/IO_Manager.py @@ -45,6 +45,10 @@ class IO_Manager(gobject.GObject): def __init__(self, foo):
gobject.GObject.__init__(self)
+ def load_map(self):
+ # stub
+ pass
+
def clean_title(self, title):
"""
removes non-alphanumeric chars from titles and lowercases it
@@ -61,26 +65,15 @@ class IO_Manager(gobject.GObject): @param title: The title of the article to add to library.
@param path: The path of the article to add to library.
"""
- try:
- #change to relative path
- path = path.replace(os.path.join(self.workingDir, ""), "", 1)
- map = self.load_map()
- existing_entry = map.find("topicref", attrs={"navtitle" : title})
- if existing_entry != None:
- existing_entry.extract()
- map.map.append(Tag(map, "topicref", [("href", path), ("navtitle", title)]))
- self.save_map(map)
- except Exception, e:
- elogger.debug('__add_page_to_library: %s' % e)
- self.__add_page_to_library(title, path)
+ #change to relative path
+ path = path.replace(os.path.join(self.workingDir, ""), "", 1)
+ map = self.load_map()
+
+ for i in [i for i in map if i['title'] == title]:
+ self.remove_page(i['title'])
+
+ map.append({'title': title, 'href': path})
- def __create_map(self):
- return BeautifulStoneSoup(\
- '<?xml version="1.0" encoding="utf-8"?>\
- <!DOCTYPE map PUBLIC "-//IBM//DTD DITA IBM Map//EN" "ibm-map.dtd">\
- <map title="footheme">\
- </map>')
-
def download_wiki_article(self, title, theme, wiki=None, statuslabel = None):
"""
manages downloading and saving of wiki articles.
@@ -119,22 +112,6 @@ class IO_Manager(gobject.GObject): # file.write(contents)
# file.close()
- def get_pages(self):
- """
- Returns a list of all pages
- @return: List of dictionaries containing page 'path' and 'title'.
- """
- try:
- map = self.load_map()
- except Exception, e:
- elogger.debug('get_pages: %s' % e)
- return []
- output = []
- for page in map.map.findAll("topicref"):
- output.append(page['navtitle'])
- output.sort()
- return output
-
def get_unique_article_ID(self):
"""
Creates and maintains a file to record the last unique article ID issued.
@@ -210,24 +187,6 @@ class IO_Manager(gobject.GObject): else:
image.extract()
return document.prettify()
-
- def load_map(self):
- """
- Loads the specified theme map.
- @return: map contents as a Soup
- @raise theme_not_found_error: If theme map not found.
- """
- filepath = os.path.join(self.workingDir, "ditamap")
-
- if not os.access(filepath, os.F_OK):
- logger.debug('create new map')
- return self.__create_map();
-
- file = open(filepath, "r")
- map = BeautifulStoneSoup(file.read())
- file.close()
-
- return map
def load_raw_page(self, title):
"""
@@ -236,11 +195,12 @@ class IO_Manager(gobject.GObject): @param title: Title of page to open.
@return: Contents of page.
"""
+ logger.debug('load article %s' % title)
theme_map = self.load_map()
- logger.debug(title)
- page_location = theme_map.find("topicref", attrs={ "navtitle" : title })
- if page_location != None:
- page_location = page_location['href']
+
+ page_location = [i for i in theme_map if i['title'] == title]
+ if page_location:
+ page_location = page_location[0]['href']
else:
raise page_not_found_error("No match for " + title)
@@ -283,46 +243,32 @@ class IO_Manager(gobject.GObject): except IOError, e:
elogger.debug('__open_URL: %s' % e)
- def page_exists(self, title):
- """
- boolean check if an article exists
- """
- try:
- map = self.load_map()
- if map.find("topicref", attrs={"navtitle" : title}) != None:
- return True
- else:
- return False
- except Exception, e:
- elogger.debug('page_exists: %s' % e)
- return False
-
def remove_page(self, page):
"""
Removes specified page from the specified.
@param page: Page to remove
"""
theme_map = self.load_map()
- entry = theme_map.find("topicref", attrs={"navtitle" : page})
- try:
- os.remove(entry['href'])
- except Exception, e:
- elogger.debug('remove_page: %s' % e)
- entry.extract()
- self.save_map(theme_map)
+
+ for i, entry in enumerate(theme_map):
+ if entry['title'] != title:
+ continue
+ try:
+ os.remove(entry['href'])
+ except Exception, e:
+ elogger.debug('remove_page: %s' % e)
+ del theme_map[i]
def rename_page(self, old_title, new_title):
"""
renames specified page
"""
- try:
- map = self.load_map()
- page = map.find("topicref", attrs={"navtitle" : old_title})
- if page != None:
- page['navtitle'] = new_title
- self.save_map(map)
- except Exception, e:
- elogger.debug('rename_page: %s' % e)
+ map = self.load_map()
+
+ for entry in map:
+ if entry['title'] != old_title:
+ continue
+ entry['title'] = new_title
def save_article(self, article, overwrite = True):
"""
@@ -336,17 +282,6 @@ class IO_Manager(gobject.GObject): else:
raise theme_not_found_error("Title not specified")
- def save_map(self, map_data):
- """
- Saves the specified map.
- @param map_data: Contents of map
- """
- if not os.path.exists(self.workingDir):
- os.makedirs(self.workingDir, 0777)
- map = open(os.path.join(self.workingDir, "ditamap"), "w")
- map.write(map_data.prettify())
- map.close()
-
def save_page(self, title, contents, get_images=False, statuslabel=None):
"""
Saves the specified page contents as specified title.
diff --git a/activity.py b/activity.py index c5d7c5e..adcd79b 100644 --- a/activity.py +++ b/activity.py @@ -43,7 +43,7 @@ class InfoslicerActivity(SharedActivity): pass def write_file(self, filepath): - pass + book.teardown() def _init_cb(self, sender): book.init() @@ -16,6 +16,7 @@ import os import gtk import logging import gobject +import cjson from gobject import SIGNAL_RUN_FIRST, TYPE_PYOBJECT from gettext import gettext as _ @@ -39,13 +40,13 @@ class Book(IO_Manager): if self._article.article_title == name: return - new_name = [i for i in self.get_pages() if i == name] + new = [i for i in self.map if i['title'] == name] - if not new_name: + if not new: logger.debug('cannot find article %s' % name) return - self._article = self.load_article(new_name) + self._article = self.load_article(new[0]['title']) self.emit('article-changed', self._article) article = gobject.property(type=object, @@ -54,8 +55,12 @@ class Book(IO_Manager): def __init__(self, preinstalled, dirname): IO_Manager.__init__(self, 0) self.workingDir = os.path.join(get_activity_root(), dirname) + self.map = [] - if not os.path.exists(self.workingDir): + if os.path.exists(self.workingDir): + mapfile = file(os.path.join(self.workingDir, 'map'), 'r') + self.map = cjson.decode(mapfile.read()) + else: os.makedirs(self.workingDir, 0777) for i in preinstalled: @@ -71,9 +76,8 @@ class Book(IO_Manager): self.save_page(i[0], contents, get_images=True) logger.debug("install library: save successful") - pages = self.get_pages() - if pages: - self._article = self.load_article(pages[0]) + if self.map: + self._article = self.load_article(self.map[0]['title']) else: self._article = None @@ -83,6 +87,15 @@ class Book(IO_Manager): logger.debug('article %s was renamed to %s' % (old_name, new_name)) self._article.article_title = new_name + def save_map(self): + mapfile = file(os.path.join(self.workingDir, 'map'), 'w') + mapfile.write(cjson.encode(self.map)) + mapfile.close() + + # backward compatibility with IO_Manager + def load_map(self): + return self.map + class WikiBook(Book): def __init__(self): PREINSTALLED = [ @@ -102,3 +115,7 @@ def init(): global wiki, custom wiki = WikiBook() custom = CustomBook() + +def teardown(): + wiki.save_map() + custom.save_map() @@ -23,6 +23,7 @@ from sugar.graphics.toolcombobox import ToolComboBox from GUI_Components.Compound_Widgets.Library_View import Library_View from GUI_Components.Compound_Widgets.toolbar import WidgetItem from GUI_Components.Compound_Widgets.bookview import BookView +from GUI_Components.Compound_Widgets.Reading_View import Reading_View import book class View(gtk.EventBox): #Library_View): @@ -30,15 +31,35 @@ class View(gtk.EventBox): #Library_View): gtk.EventBox.__init__(self) books = gtk.VBox() + books.set_size_request(gtk.gdk.screen_width()/4, -1) books.pack_start(BookView(book.wiki, _('Wiki Articles'))) books.pack_start(BookView(book.custom, _('Custom Articles'))) + self.wiki_arcticle = Reading_View() + self.custom_arcticle = Reading_View() + self.custom_arcticle.set_size_request(gtk.gdk.screen_width()/4*3/2, -1) + + articles = gtk.HBox() + articles.pack_start(self.wiki_arcticle) + articles.pack_start(self.custom_arcticle, False) + desktop = gtk.HBox() - desktop.pack_start(books) + desktop.pack_start(books, False) + desktop.pack_start(articles) desktop.show_all() self.add(desktop) + book.wiki.connect('article-changed', self._wiki_changed_cb) + book.custom.connect('article-changed', self._custom_changed_cb) + + def _wiki_changed_cb(self, book, article): + self.wiki_arcticle.textbox.set_article(article) + + def _custom_changed_cb(self, book, article): + self.custom_arcticle.textbox.set_article(article) + + #Library_View.__init__(self) |