Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@member.fsf.org>2009-02-26 04:58:43 (GMT)
committer Aleksey Lim <alsroot@member.fsf.org>2009-03-02 06:32:18 (GMT)
commitba80473f40ad39e03bb2edfe87cf6d03c48d2478 (patch)
treecf4724acdab9caf78d969c5dc8f3b29a30a971d4
parenta14cb239a4c84cf7d69a679c9f68f94d76ee74d6 (diff)
Add bookview widget
-rw-r--r--GUI_Components/Compound_Widgets/bookview.py140
-rw-r--r--GUI_Components/Edit_Pane.py11
-rw-r--r--GUI_Components/Format_Pane.py5
-rw-r--r--GUI_Components/Image_Pane.py14
-rw-r--r--Processing/IO_Manager.py5
-rw-r--r--book.py34
-rw-r--r--edit.py8
-rw-r--r--library.py14
8 files changed, 208 insertions, 23 deletions
diff --git a/GUI_Components/Compound_Widgets/bookview.py b/GUI_Components/Compound_Widgets/bookview.py
new file mode 100644
index 0000000..3396dfd
--- /dev/null
+++ b/GUI_Components/Compound_Widgets/bookview.py
@@ -0,0 +1,140 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+import gtk
+import logging
+import gobject
+from gettext import gettext as _
+
+from sugar.activity.activity import get_bundle_path, get_activity_root
+from sugar.graphics.style import *
+
+from Processing.IO_Manager import IO_Manager
+
+logger = logging.getLogger('infoslicer')
+
+class BookView(gtk.VBox):
+ def __init__(self, book, name):
+ gtk.VBox.__init__(self)
+ self.book = book
+ self._changing = None
+
+ # title
+
+ self._check = gtk.CheckButton()
+ self._check.show()
+ self._check.props.can_focus = False
+ 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())
+
+ # 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)
+
+ cell = gtk.CellRendererToggle()
+ cell.connect('toggled', self._cell_toggled_cb)
+ cell.props.activatable = True
+
+ column = self.tree.insert_column_with_attributes(0, '', cell, active=0)
+ column.props.sizing = gtk.TREE_VIEW_COLUMN_FIXED
+ column.props.fixed_width = 50
+
+ cell = gtk.CellRendererText()
+ cell.connect('edited', self._cell_edited_cb)
+ 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))
+
+ # 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)
+
+ def _check_toggled_cb(self, widget):
+ for i in self.store:
+ i[0] = widget.props.active
+ self._check.props.inconsistent = False
+
+ def _cell_toggled_cb(self, cell, index):
+ value = not self.store[index][0]
+ self.store[index][0] = value
+
+ for i in self.store:
+ if i[0] != value:
+ self._check.props.inconsistent = True
+ return
+
+ self._check.props.inconsistent = False
+ self._check.props.active = value
+
+ def _cursor_changed_cb(self, widget):
+ if self._changing:
+ gobject.source_remove(self._changing)
+ index, column = self.tree.get_cursor()
+ self._changing = gobject.timeout_add(1000, self._cursor_changed, index)
+
+ def _cursor_changed(self, index):
+ self.book.props.article = self.store[index][1]
+ self._changing = False
+ return False
+
+ def _cell_edited_cb(self, cell, index, newtext):
+ # Disallowed chars are < > and &
+ if newtext == "" or newtext.isspace() or '&' in newtext \
+ or '<' in newtext or '>' in newtext:
+ return
+
+ index, column = self.tree.get_cursor()
+
+ if self._changing:
+ gobject.source_remove(self._changing)
+ _cursor_changed(index)
+
+ # If there is already an article with the new name in the theme,
+ # then we ignore the name change and highlight the existing article
+ overides = [i for i, row in enumerate(self.store) if row[1] == newtext]
+ if overides:
+ self.tree.set_cursor(overides[0], self.tree.get_column(1), False)
+ return
+
+ self.book.rename(newtext)
+ self.store[index][1] = newtext
diff --git a/GUI_Components/Edit_Pane.py b/GUI_Components/Edit_Pane.py
index ae13188..9a9fe47 100644
--- a/GUI_Components/Edit_Pane.py
+++ b/GUI_Components/Edit_Pane.py
@@ -91,19 +91,16 @@ class Edit_Pane(gtk.HBox):
#logger.debug(current_selection)
def set_source_article(self, article):
- if self.readarticle.textbox.get_article() == article:
- return
-
self.articletitle.set_markup(
"<span size='medium'><b> %s </b> %s</span>" % \
(_("Article:"), article.article_title))
- self.readarticle.textbox.set_article(article)
+ if self.readarticle.textbox.get_article() != article:
+ self.readarticle.textbox.set_article(article)
def set_working_article(self, article):
- if self.editarticle.textbox.get_article() == article:
- return
self.editarticle.articletitle.set_markup(
"<span size='medium'><b> %s </b> %s</span>" % \
(_("Article:"), article.article_title))
- self.editarticle.textbox.set_article(article)
+ if self.editarticle.textbox.get_article() != article:
+ self.editarticle.textbox.set_article(article)
diff --git a/GUI_Components/Format_Pane.py b/GUI_Components/Format_Pane.py
index 72c04b6..a3ff091 100644
--- a/GUI_Components/Format_Pane.py
+++ b/GUI_Components/Format_Pane.py
@@ -47,9 +47,8 @@ class Format_Pane(Editing_View):
self.source = article
def set_working_article(self, article):
- if self.textbox.get_article() == article:
- return
self.articletitle.set_markup(
"<span size='medium'><b> %s </b> %s</span>" % \
(_("Article:"), article.article_title))
- self.textbox.set_article(article)
+ if self.textbox.get_article() != article:
+ self.textbox.set_article(article)
diff --git a/GUI_Components/Image_Pane.py b/GUI_Components/Image_Pane.py
index f5a3023..7162522 100644
--- a/GUI_Components/Image_Pane.py
+++ b/GUI_Components/Image_Pane.py
@@ -51,6 +51,10 @@ class Image_Pane(gtk.HBox):
self.gallery._source_article = None
def set_source_article(self, source):
+ self.articletitle.set_markup(
+ "<span size='medium'><b> %s </b> %s</span>"% \
+ (_("Article:"), source.article_title))
+
if self.gallery._source_article == source:
return
@@ -58,10 +62,6 @@ class Image_Pane(gtk.HBox):
current = self.gallery._source_article
self.gallery._source_article = source
- self.articletitle.set_markup(
- "<span size='medium'><b> %s </b> %s</span>"% \
- (_("Article:"), source.article_title))
-
if source and source.article_title:
self.gallery.current_index = 0
if source.image_list != []:
@@ -80,13 +80,11 @@ class Image_Pane(gtk.HBox):
self.gallery.caption.set_text(_("Please select a Wikipedia article from the menu above"))
def set_working_article(self, article):
- if self.editarticle.textbox.get_article() == article:
- return
-
logger.debug("working received, title %s" % article.article_title)
self.editarticle.articletitle.set_markup(
"<span size='medium'><b> %s </b> %s</span>"% \
(_("Article:"), article.article_title))
- self.editarticle.textbox.set_article(article)
+ if self.editarticle.textbox.get_article() != article:
+ self.editarticle.textbox.set_article(article)
diff --git a/Processing/IO_Manager.py b/Processing/IO_Manager.py
index d349ab2..2cc3bd8 100644
--- a/Processing/IO_Manager.py
+++ b/Processing/IO_Manager.py
@@ -6,6 +6,7 @@ import re
import logging
import os
import urllib
+import gobject
from gettext import gettext as _
from BeautifulSoup import Tag
@@ -40,9 +41,9 @@ class theme_exists_error(Exception):
This class sits between the GUI and the back end (handling
mediawiki communication and raw pages/article modifications)
"""
-class IO_Manager:
+class IO_Manager(gobject.GObject):
def __init__(self, foo):
- pass
+ gobject.GObject.__init__(self)
def clean_title(self, title):
"""
diff --git a/book.py b/book.py
index f65b493..9b94716 100644
--- a/book.py
+++ b/book.py
@@ -15,6 +15,8 @@
import os
import gtk
import logging
+import gobject
+from gobject import SIGNAL_RUN_FIRST, TYPE_PYOBJECT
from gettext import gettext as _
from sugar.activity.activity import get_bundle_path, get_activity_root
@@ -27,6 +29,28 @@ wiki = None
custom = None
class Book(IO_Manager):
+ __gsignals__ = {
+ 'article-changed' : (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]) }
+
+ def get_article(self):
+ return self._article
+
+ def set_article(self, name):
+ if self._article.article_title == name:
+ return
+
+ new_name = [i for i in self.get_pages() if i == name]
+
+ if not new_name:
+ logger.debug('cannot find article %s' % name)
+ return
+
+ self._article = self.load_article(new_name)
+ self.emit('article-changed', self._article)
+
+ article = gobject.property(type=object,
+ getter=get_article, setter=set_article)
+
def __init__(self, preinstalled, dirname):
IO_Manager.__init__(self, 0)
self.workingDir = os.path.join(get_activity_root(), dirname)
@@ -49,9 +73,15 @@ class Book(IO_Manager):
pages = self.get_pages()
if pages:
- self.article = self.load_article(pages[0])
+ self._article = self.load_article(pages[0])
else:
- self.article = Article()
+ self._article = None
+
+ def rename(self, new_name):
+ old_name = self._article.article_title
+ self.rename_page(old_name, new_name)
+ logger.debug('article %s was renamed to %s' % (old_name, new_name))
+ self._article.article_title = new_name
class WikiBook(Book):
def __init__(self):
diff --git a/edit.py b/edit.py
index 7432347..8089bdb 100644
--- a/edit.py
+++ b/edit.py
@@ -22,7 +22,6 @@ from sugar.activity.activity import ActivityToolbox
from GUI_Components.Edit_Pane import Edit_Pane
from GUI_Components.Format_Pane import Format_Pane
from GUI_Components.Image_Pane import Image_Pane
-import document
import book
TABS = (Edit_Pane(),
@@ -39,6 +38,13 @@ class View(gtk.Notebook):
self.append_page(i)
i.show()
+ self.connect('map', self._map_cb)
+
+ def _map_cb(self, widget):
+ index = self.get_current_page()
+ TABS[index].set_source_article(book.wiki.article)
+ TABS[index].set_working_article(book.custom.article)
+
class Toolbar(gtk.Toolbar):
def __init__(self, edit):
gtk.Toolbar.__init__(self)
diff --git a/library.py b/library.py
index 6b0eafb..f649291 100644
--- a/library.py
+++ b/library.py
@@ -22,10 +22,24 @@ 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
+import book
class View(gtk.EventBox): #Library_View):
def __init__(self):
gtk.EventBox.__init__(self)
+
+ books = gtk.VBox()
+ books.pack_start(BookView(book.wiki, _('Wiki Articles')))
+ books.pack_start(BookView(book.custom, _('Custom Articles')))
+
+ desktop = gtk.HBox()
+ desktop.pack_start(books)
+ desktop.show_all()
+
+ self.add(desktop)
+
+
#Library_View.__init__(self)
"""