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-27 15:56:52 (GMT)
committer Aleksey Lim <alsroot@member.fsf.org>2009-03-02 06:32:18 (GMT)
commit5651224fe4b7ae316f1df682ff7eef3b773dd8a5 (patch)
tree2844d69937df13f8bbca1f7620b4536b757184a6
parent842a3724c9277b7ecad2d17408128ea22efb4132 (diff)
Recode library tab to adopt new scheme w/o themes
-rw-r--r--GUI_Components/Compound_Widgets/Gallery_View.py20
-rw-r--r--GUI_Components/Compound_Widgets/Library_View.py1148
-rw-r--r--GUI_Components/Compound_Widgets/bookview.py182
-rw-r--r--GUI_Components/Compound_Widgets/toolbar.py5
-rw-r--r--Processing/Article/Sentence.py13
-rw-r--r--Processing/IO_Manager.py350
-rw-r--r--Processing/MediaWiki_Helper.py5
-rw-r--r--activity.py36
-rw-r--r--activity/activity.info2
-rw-r--r--book.py158
-rw-r--r--edit.py13
-rw-r--r--examples/giraffe-blank.dita (renamed from Processing/demolibrary/giraffe-blank.dita)0
-rw-r--r--examples/giraffe-wikipedia.dita (renamed from Processing/demolibrary/giraffe-wikipedia.dita)0
-rw-r--r--examples/images/120px-Siberian-Tiger.jpg (renamed from Processing/demolibrary/images/120px-Siberian-Tiger.jpg)bin2716 -> 2716 bytes
-rw-r--r--examples/images/120px-Siberischer_tiger_de_edit02.jpg (renamed from Processing/demolibrary/images/120px-Siberischer_tiger_de_edit02.jpg)bin5396 -> 5396 bytes
-rw-r--r--examples/images/120px-Tiger_cooling_off_at_Bandhavghar.jpg (renamed from Processing/demolibrary/images/120px-Tiger_cooling_off_at_Bandhavghar.jpg)bin2935 -> 2935 bytes
-rw-r--r--examples/images/120px-Vibrissae_of_a_Tiger_at_Chester_Zoo.jpg (renamed from Processing/demolibrary/images/120px-Vibrissae_of_a_Tiger_at_Chester_Zoo.jpg)bin6282 -> 6282 bytes
-rw-r--r--examples/images/140px-GD-EG-KomOmbo016.JPG (renamed from Processing/demolibrary/images/140px-GD-EG-KomOmbo016.JPG)bin12468 -> 12468 bytes
-rw-r--r--examples/images/140px-Jerusalem-coat-of-arms.svg.png (renamed from Processing/demolibrary/images/140px-Jerusalem-coat-of-arms.svg.png)bin32364 -> 32364 bytes
-rw-r--r--examples/images/140px-Lion_pair2.jpg (renamed from Processing/demolibrary/images/140px-Lion_pair2.jpg)bin8418 -> 8418 bytes
-rw-r--r--examples/images/140px-P_l_Bleyenberghi.jpg (renamed from Processing/demolibrary/images/140px-P_l_Bleyenberghi.jpg)bin9114 -> 9114 bytes
-rw-r--r--examples/images/150px-Climacoceras_gentryi_e.jpg (renamed from Processing/demolibrary/images/150px-Climacoceras_gentryi_e.jpg)bin14754 -> 14754 bytes
-rw-r--r--examples/images/150px-Giraffa_camelopardalis_angolensis_%28mating%29.jpg (renamed from Processing/demolibrary/images/150px-Giraffa_camelopardalis_angolensis_%28mating%29.jpg)bin9270 -> 9270 bytes
-rw-r--r--examples/images/150px-Giraffes_IMG_9614.JPG (renamed from Processing/demolibrary/images/150px-Giraffes_IMG_9614.JPG)bin11013 -> 11013 bytes
-rw-r--r--examples/images/150px-Kuniyoshi_Utagawa%2C_Tiger.jpg (renamed from Processing/demolibrary/images/150px-Kuniyoshi_Utagawa%2C_Tiger.jpg)bin35032 -> 35032 bytes
-rw-r--r--examples/images/150px-Mare_and_foal_%28Kvetina-Marie%29.jpg (renamed from Processing/demolibrary/images/150px-Mare_and_foal_%28Kvetina-Marie%29.jpg)bin6194 -> 6194 bytes
-rw-r--r--examples/images/150px-Tigergebiss.jpg (renamed from Processing/demolibrary/images/150px-Tigergebiss.jpg)bin13777 -> 13777 bytes
-rw-r--r--examples/images/150px-Zebra_eating.JPG (renamed from Processing/demolibrary/images/150px-Zebra_eating.JPG)bin5973 -> 5973 bytes
-rw-r--r--examples/images/150px-Zoo_UL%2C_Hartmann%27s_mountain_zebra.jpg (renamed from Processing/demolibrary/images/150px-Zoo_UL%2C_Hartmann%27s_mountain_zebra.jpg)bin12316 -> 12316 bytes
-rw-r--r--examples/images/180px-1990tiger.PNG (renamed from Processing/demolibrary/images/180px-1990tiger.PNG)bin15920 -> 15920 bytes
-rw-r--r--examples/images/180px-Asiatic.lioness.arp.jpg (renamed from Processing/demolibrary/images/180px-Asiatic.lioness.arp.jpg)bin8580 -> 8580 bytes
-rw-r--r--examples/images/180px-Bertramliger.jpg (renamed from Processing/demolibrary/images/180px-Bertramliger.jpg)bin10326 -> 10326 bytes
-rw-r--r--examples/images/180px-Circus_Lion_Tamer.jpg (renamed from Processing/demolibrary/images/180px-Circus_Lion_Tamer.jpg)bin9679 -> 9679 bytes
-rw-r--r--examples/images/180px-Durer_lions_%28sketch%29.jpg (renamed from Processing/demolibrary/images/180px-Durer_lions_%28sketch%29.jpg)bin7853 -> 7853 bytes
-rw-r--r--examples/images/180px-Female_Lion.JPG (renamed from Processing/demolibrary/images/180px-Female_Lion.JPG)bin9087 -> 9087 bytes
-rw-r--r--examples/images/180px-Giraffe08_-_melbourne_zoo_edit.jpg (renamed from Processing/demolibrary/images/180px-Giraffe08_-_melbourne_zoo_edit.jpg)bin7115 -> 7115 bytes
-rw-r--r--examples/images/180px-GiraffeSkelLyd2.png (renamed from Processing/demolibrary/images/180px-GiraffeSkelLyd2.png)bin41856 -> 41856 bytes
-rw-r--r--examples/images/180px-Giraffe_%28head%29.jpg (renamed from Processing/demolibrary/images/180px-Giraffe_%28head%29.jpg)bin6702 -> 6702 bytes
-rw-r--r--examples/images/180px-Giraffe_Ithala_KZN_South_Africa_Luca_Galuzzi_2004.JPG (renamed from Processing/demolibrary/images/180px-Giraffe_Ithala_KZN_South_Africa_Luca_Galuzzi_2004.JPG)bin8145 -> 8145 bytes
-rw-r--r--examples/images/180px-HansomeLion_002.jpg (renamed from Processing/demolibrary/images/180px-HansomeLion_002.jpg)bin7778 -> 7778 bytes
-rw-r--r--examples/images/180px-Lightmatter_lioness.jpg (renamed from Processing/demolibrary/images/180px-Lightmatter_lioness.jpg)bin9683 -> 9683 bytes
-rw-r--r--examples/images/180px-Lion_-_melbourne_zoo.jpg (renamed from Processing/demolibrary/images/180px-Lion_-_melbourne_zoo.jpg)bin11576 -> 11576 bytes
-rw-r--r--examples/images/180px-Lion_at_zoo.jpg (renamed from Processing/demolibrary/images/180px-Lion_at_zoo.jpg)bin13475 -> 13475 bytes
-rw-r--r--examples/images/180px-Lion_cub_with_mother.jpg (renamed from Processing/demolibrary/images/180px-Lion_cub_with_mother.jpg)bin9084 -> 9084 bytes
-rw-r--r--examples/images/180px-Lion_cubs_Serengeti.jpg (renamed from Processing/demolibrary/images/180px-Lion_cubs_Serengeti.jpg)bin8619 -> 8619 bytes
-rw-r--r--examples/images/180px-Male_Lion_and_Cub_Chitwa_South_Africa_Luca_Galuzzi_2004.JPG (renamed from Processing/demolibrary/images/180px-Male_Lion_and_Cub_Chitwa_South_Africa_Luca_Galuzzi_2004.JPG)bin9713 -> 9713 bytes
-rw-r--r--examples/images/180px-Maneating_lion.jpg (renamed from Processing/demolibrary/images/180px-Maneating_lion.jpg)bin9166 -> 9166 bytes
-rw-r--r--examples/images/180px-Maneless_lion_from_Tsavo_East_National_Park.png (renamed from Processing/demolibrary/images/180px-Maneless_lion_from_Tsavo_East_National_Park.png)bin45510 -> 45510 bytes
-rw-r--r--examples/images/180px-Map_Guj_Nat_Parks_Sanctuary.png (renamed from Processing/demolibrary/images/180px-Map_Guj_Nat_Parks_Sanctuary.png)bin24668 -> 24668 bytes
-rw-r--r--examples/images/180px-Matha.png (renamed from Processing/demolibrary/images/180px-Matha.png)bin107190 -> 107190 bytes
-rw-r--r--examples/images/180px-Panthera_leo_Kruger_Skull.jpg (renamed from Processing/demolibrary/images/180px-Panthera_leo_Kruger_Skull.jpg)bin10395 -> 10395 bytes
-rw-r--r--examples/images/180px-Panthera_tigris_amoyensis.jpg (renamed from Processing/demolibrary/images/180px-Panthera_tigris_amoyensis.jpg)bin7828 -> 7828 bytes
-rw-r--r--examples/images/180px-Panthera_tigris_balica.jpg (renamed from Processing/demolibrary/images/180px-Panthera_tigris_balica.jpg)bin10633 -> 10633 bytes
-rw-r--r--examples/images/180px-Panthera_tigris_sondaica_01.jpg (renamed from Processing/demolibrary/images/180px-Panthera_tigris_sondaica_01.jpg)bin10100 -> 10100 bytes
-rw-r--r--examples/images/180px-Panthera_tigris_sumatran_subspecies.jpg (renamed from Processing/demolibrary/images/180px-Panthera_tigris_sumatran_subspecies.jpg)bin11173 -> 11173 bytes
-rw-r--r--examples/images/180px-Panthera_tigris_virgata.jpg (renamed from Processing/demolibrary/images/180px-Panthera_tigris_virgata.jpg)bin22318 -> 22318 bytes
-rw-r--r--examples/images/180px-PregnantLioness.jpg (renamed from Processing/demolibrary/images/180px-PregnantLioness.jpg)bin8046 -> 8046 bytes
-rw-r--r--examples/images/180px-Royal_Arms_of_Scotland.svg.png (renamed from Processing/demolibrary/images/180px-Royal_Arms_of_Scotland.svg.png)bin31474 -> 31474 bytes
-rw-r--r--examples/images/180px-ShenDuGiraffePainting.jpg (renamed from Processing/demolibrary/images/180px-ShenDuGiraffePainting.jpg)bin12927 -> 12927 bytes
-rw-r--r--examples/images/180px-Status_iucn2.3_CD.svg.png (renamed from Processing/demolibrary/images/180px-Status_iucn2.3_CD.svg.png)bin8685 -> 8685 bytes
-rw-r--r--examples/images/180px-Status_iucn2.3_EN.svg.png (renamed from Processing/demolibrary/images/180px-Status_iucn2.3_EN.svg.png)bin8751 -> 8751 bytes
-rw-r--r--examples/images/180px-Status_iucn3.1_VU.svg.png (renamed from Processing/demolibrary/images/180px-Status_iucn3.1_VU.svg.png)bin8562 -> 8562 bytes
-rw-r--r--examples/images/180px-Tiger_032.jpg (renamed from Processing/demolibrary/images/180px-Tiger_032.jpg)bin15723 -> 15723 bytes
-rw-r--r--examples/images/180px-Tiger_Bandavgarh_adjusted_levels.jpg (renamed from Processing/demolibrary/images/180px-Tiger_Bandavgarh_adjusted_levels.jpg)bin14816 -> 14816 bytes
-rw-r--r--examples/images/180px-Tiger_in_the_snow_at_the_Detroit_Zoo_March_2008_pic_2.jpg (renamed from Processing/demolibrary/images/180px-Tiger_in_the_snow_at_the_Detroit_Zoo_March_2008_pic_2.jpg)bin8754 -> 8754 bytes
-rw-r--r--examples/images/180px-Tiger_in_the_water.jpg (renamed from Processing/demolibrary/images/180px-Tiger_in_the_water.jpg)bin13439 -> 13439 bytes
-rw-r--r--examples/images/180px-Tigress-Jowlagiri.jpg (renamed from Processing/demolibrary/images/180px-Tigress-Jowlagiri.jpg)bin6858 -> 6858 bytes
-rw-r--r--examples/images/180px-White_Lion.jpg (renamed from Processing/demolibrary/images/180px-White_Lion.jpg)bin6500 -> 6500 bytes
-rw-r--r--examples/images/180px-Zebra_Dallas_Zoo_1974.jpg (renamed from Processing/demolibrary/images/180px-Zebra_Dallas_Zoo_1974.jpg)bin37733 -> 37733 bytes
-rw-r--r--examples/images/200px-Lions_and_a_Zebra_a.jpg (renamed from Processing/demolibrary/images/200px-Lions_and_a_Zebra_a.jpg)bin9031 -> 9031 bytes
-rw-r--r--examples/images/200px-Zebra-tame-jumping.jpg (renamed from Processing/demolibrary/images/200px-Zebra-tame-jumping.jpg)bin5315 -> 5315 bytes
-rw-r--r--examples/images/200px-Zebra2.jpg (renamed from Processing/demolibrary/images/200px-Zebra2.jpg)bin13631 -> 13631 bytes
-rw-r--r--examples/images/200px-Zebra_Botswana_edit02.jpg (renamed from Processing/demolibrary/images/200px-Zebra_Botswana_edit02.jpg)bin14002 -> 14002 bytes
-rw-r--r--examples/images/200px-Zebra_rownikowa_Equus_burchelli_boehmi_RB3.jpg (renamed from Processing/demolibrary/images/200px-Zebra_rownikowa_Equus_burchelli_boehmi_RB3.jpg)bin7418 -> 7418 bytes
-rw-r--r--examples/images/220px-Tiger_distribution3.PNG (renamed from Processing/demolibrary/images/220px-Tiger_distribution3.PNG)bin28994 -> 28994 bytes
-rw-r--r--examples/images/225px-Una-lion.jpg (renamed from Processing/demolibrary/images/225px-Una-lion.jpg)bin15544 -> 15544 bytes
-rw-r--r--examples/images/230px-037tiger.jpg (renamed from Processing/demolibrary/images/230px-037tiger.jpg)bin11886 -> 11886 bytes
-rw-r--r--examples/images/230px-Giraffa_camelopardalis_subspecies_map.jpg (renamed from Processing/demolibrary/images/230px-Giraffa_camelopardalis_subspecies_map.jpg)bin14357 -> 14357 bytes
-rw-r--r--examples/images/230px-Giraffe_standing.jpg (renamed from Processing/demolibrary/images/230px-Giraffe_standing.jpg)bin18388 -> 18388 bytes
-rw-r--r--examples/images/230px-Golden_tiger_1_-_Buffalo_Zoo.jpg (renamed from Processing/demolibrary/images/230px-Golden_tiger_1_-_Buffalo_Zoo.jpg)bin16353 -> 16353 bytes
-rw-r--r--examples/images/230px-Singapore_Zoo_Tigers.jpg (renamed from Processing/demolibrary/images/230px-Singapore_Zoo_Tigers.jpg)bin11127 -> 11127 bytes
-rw-r--r--examples/images/230px-TigerSkelLyd1.png (renamed from Processing/demolibrary/images/230px-TigerSkelLyd1.png)bin23666 -> 23666 bytes
-rw-r--r--examples/images/240px-7_lions.jpg (renamed from Processing/demolibrary/images/240px-7_lions.jpg)bin13117 -> 13117 bytes
-rw-r--r--examples/images/240px-ElephantbackTigerHunt.jpg (renamed from Processing/demolibrary/images/240px-ElephantbackTigerHunt.jpg)bin10060 -> 10060 bytes
-rw-r--r--examples/images/240px-Flag_of_Sri_Lanka.svg.png (renamed from Processing/demolibrary/images/240px-Flag_of_Sri_Lanka.svg.png)bin8551 -> 8551 bytes
-rw-r--r--examples/images/240px-Stud_327_with_Blesbuck.jpg (renamed from Processing/demolibrary/images/240px-Stud_327_with_Blesbuck.jpg)bin18582 -> 18582 bytes
-rw-r--r--examples/images/240px-TigerSkinning.jpg (renamed from Processing/demolibrary/images/240px-TigerSkinning.jpg)bin8650 -> 8650 bytes
-rw-r--r--examples/images/250px-Beautiful_Zebra_in_South_Africa.JPG (renamed from Processing/demolibrary/images/250px-Beautiful_Zebra_in_South_Africa.JPG)bin24117 -> 24117 bytes
-rw-r--r--examples/images/250px-Equus_grevyi_in_Kenya_%28male%29.jpg (renamed from Processing/demolibrary/images/250px-Equus_grevyi_in_Kenya_%28male%29.jpg)bin16097 -> 16097 bytes
-rw-r--r--examples/images/250px-LAzooZebra.jpg (renamed from Processing/demolibrary/images/250px-LAzooZebra.jpg)bin15115 -> 15115 bytes
-rw-r--r--examples/images/250px-Lion_distribution.svg.png (renamed from Processing/demolibrary/images/250px-Lion_distribution.svg.png)bin32996 -> 32996 bytes
-rw-r--r--examples/images/250px-Lion_in_Ngorongoro_Crater%2C_Tanzania.jpg (renamed from Processing/demolibrary/images/250px-Lion_in_Ngorongoro_Crater%2C_Tanzania.jpg)bin15097 -> 15097 bytes
-rw-r--r--examples/images/250px-Lion_in_masai_mara.jpg (renamed from Processing/demolibrary/images/250px-Lion_in_masai_mara.jpg)bin18589 -> 18589 bytes
-rw-r--r--examples/images/250px-Lionesses%2C_Masai_Mara%2C_Kenya.jpg (renamed from Processing/demolibrary/images/250px-Lionesses%2C_Masai_Mara%2C_Kenya.jpg)bin17802 -> 17802 bytes
-rw-r--r--examples/images/250px-Map_Guj_Nat_Parks_Sanctuary.png (renamed from Processing/demolibrary/images/250px-Map_Guj_Nat_Parks_Sanctuary.png)bin40220 -> 40220 bytes
-rw-r--r--examples/images/250px-Mycenae_lion_gate_detail_dsc06384.jpg (renamed from Processing/demolibrary/images/250px-Mycenae_lion_gate_detail_dsc06384.jpg)bin16771 -> 16771 bytes
-rw-r--r--examples/images/250px-Pride_of_lions.JPG (renamed from Processing/demolibrary/images/250px-Pride_of_lions.JPG)bin9912 -> 9912 bytes
-rw-r--r--examples/images/250px-Serengeti_Lion_Running_saturated.jpg (renamed from Processing/demolibrary/images/250px-Serengeti_Lion_Running_saturated.jpg)bin7776 -> 7776 bytes
-rw-r--r--examples/images/250px-Siberian_Tiger_sf.jpg (renamed from Processing/demolibrary/images/250px-Siberian_Tiger_sf.jpg)bin14336 -> 14336 bytes
-rw-r--r--examples/images/250px-Tanzanian_Animals.jpg (renamed from Processing/demolibrary/images/250px-Tanzanian_Animals.jpg)bin9242 -> 9242 bytes
-rw-r--r--examples/images/250px-Tiger_map.jpg (renamed from Processing/demolibrary/images/250px-Tiger_map.jpg)bin17287 -> 17287 bytes
-rw-r--r--examples/images/250px-Tigerramki.jpg (renamed from Processing/demolibrary/images/250px-Tigerramki.jpg)bin15035 -> 15035 bytes
-rw-r--r--examples/images/250px-Tipu_Sultan%27s_Tiger.JPG (renamed from Processing/demolibrary/images/250px-Tipu_Sultan%27s_Tiger.JPG)bin7988 -> 7988 bytes
-rw-r--r--examples/images/250px-WalterRothschildWithZebras.jpg (renamed from Processing/demolibrary/images/250px-WalterRothschildWithZebras.jpg)bin11164 -> 11164 bytes
-rw-r--r--examples/images/250px-Wiki_lion.jpg (renamed from Processing/demolibrary/images/250px-Wiki_lion.jpg)bin5256 -> 5256 bytes
-rw-r--r--examples/images/250px-Wildlifephotography.jpg (renamed from Processing/demolibrary/images/250px-Wildlifephotography.jpg)bin13062 -> 13062 bytes
-rw-r--r--examples/images/300px-Lascaux-diverticule-f%C3%A9lins.jpg (renamed from Processing/demolibrary/images/300px-Lascaux-diverticule-f%C3%A9lins.jpg)bin13290 -> 13290 bytes
-rw-r--r--examples/images/300px-Namibie_Etosha_Girafe_01.jpg (renamed from Processing/demolibrary/images/300px-Namibie_Etosha_Girafe_01.jpg)bin42722 -> 42722 bytes
-rw-r--r--examples/images/80px-India_tiger.jpg (renamed from Processing/demolibrary/images/80px-India_tiger.jpg)bin5084 -> 5084 bytes
-rw-r--r--examples/images/83px-Indischer_Maler_um_1650_%28II%29_001.jpg (renamed from Processing/demolibrary/images/83px-Indischer_Maler_um_1650_%28II%29_001.jpg)bin6760 -> 6760 bytes
-rw-r--r--examples/images/84px-Brehms_Het_Leven_der_Dieren_Zoogdieren_Orde_4_Tijger_%28Felis_tigris%29.jpg (renamed from Processing/demolibrary/images/84px-Brehms_Het_Leven_der_Dieren_Zoogdieren_Orde_4_Tijger_%28Felis_tigris%29.jpg)bin3582 -> 3582 bytes
-rw-r--r--examples/images/97px-Sumatratiger-004.jpg (renamed from Processing/demolibrary/images/97px-Sumatratiger-004.jpg)bin28721 -> 28721 bytes
-rw-r--r--examples/lion-wikipedia.dita (renamed from Processing/demolibrary/lion-wikipedia.dita)0
-rw-r--r--examples/tiger-wikipedia.dita (renamed from Processing/demolibrary/tiger-wikipedia.dita)0
-rw-r--r--examples/zebra-wikipedia.dita (renamed from Processing/demolibrary/zebra-wikipedia.dita)0
-rw-r--r--icons/white-search.svg72
-rw-r--r--library.py264
-rw-r--r--net.py138
118 files changed, 695 insertions, 1711 deletions
diff --git a/GUI_Components/Compound_Widgets/Gallery_View.py b/GUI_Components/Compound_Widgets/Gallery_View.py
index cefe772..5b75dcb 100644
--- a/GUI_Components/Compound_Widgets/Gallery_View.py
+++ b/GUI_Components/Compound_Widgets/Gallery_View.py
@@ -2,6 +2,7 @@
import pygtk
pygtk.require('2.0')
import gtk
+import os
import cPickle
import logging
@@ -138,7 +139,7 @@ class Gallery_View( gtk.HBox ):
def set_image_list(self, image_list):
logger.debug("validagting image list")
- self.image_list = book.wiki.validate_image_list(image_list)
+ self.image_list = _validate_image_list(book.wiki.root, image_list)
logger.debug(self.image_list)
def drag_begin_event(self, widget, context, data):
@@ -155,4 +156,19 @@ class Gallery_View( gtk.HBox ):
string = cPickle.dumps(sectionsdata)
selection_data.set(atom, 8, string)
-
+def _validate_image_list(root, image_list):
+ """
+ provides a mechanism for validating image lists and expanding relative paths
+ @param image_list: list of images to validate
+ @return: list of images with corrected paths, and broken images removed
+ """
+ for i in xrange(len(image_list)):
+ if not os.access(image_list[i][0], os.F_OK):
+ if os.access(os.path.join(root, image_list[i][0]), os.F_OK):
+ image_list[i] = (os.path.join(root, image_list[i][0]), image_list[i][1])
+ else:
+ image = None
+ #removing during for loop was unreliable
+ while None in image_list:
+ image_list.remove(None)
+ return image_list
diff --git a/GUI_Components/Compound_Widgets/Library_View.py b/GUI_Components/Compound_Widgets/Library_View.py
deleted file mode 100644
index b990231..0000000
--- a/GUI_Components/Compound_Widgets/Library_View.py
+++ /dev/null
@@ -1,1148 +0,0 @@
-# Copyright (C) IBM Corporation 2008
-import pygtk
-pygtk.require('2.0')
-import gtk
-import pango
-import cPickle
-import time
-from threading import Timer
-from Processing.IO_Manager import *
-from Processing.Article.Article import Article
-from Processing.Article.Article_Data import *
-from GUI_Components.Compound_Widgets.Base_Widgets.Readonly_Textbox import Readonly_Textbox
-import logging
-
-logger = logging.getLogger('infoslicer')
-elogger = logging.getLogger('infoslicer::except')
-
-theme_xpm = [
-"16 16 4 1",
-" c None s None",
-". c black",
-"g c #62F24D",
-"G c black",
-" .......... ",
-" .gggggggg. ",
-" ..........g. ",
-" .gggggggg.g. ",
-" ..........g.g. ",
-" .gggggggg.g.g. ",
-" .gGGGgggg.g.g. ",
-" .gggggggg.g.g. ",
-" .gGGGGGGg.g.g. ",
-" .gggggggg.g.g. ",
-" .gGGGGGGg.g.g. ",
-" .gggggggg.g... ",
-" .gGGGGGGg.g. ",
-" .gggggggg... ",
-" .gGGGGGGg. ",
-" .......... "]
-
-newtheme_xpm = [
-"16 16 4 1",
-" c None s None",
-". c black",
-"g c white",
-"G c black",
-" .......... ",
-" .gggggggg. ",
-" ..........g. ",
-" .gggggggg.g. ",
-" ..........g.g. ",
-" .gggggggg.g.g. ",
-" .gggggggg.g.g. ",
-" .gggggggg.g.g. ",
-" .gggggggg.g.g. ",
-" .gggggggg.g.g. ",
-" .gggggggg.g.g. ",
-" .gggggggg.g... ",
-" .gggggggg.g. ",
-" .gggggggg... ",
-" .gggggggg. ",
-" .......... "]
-
-wikitheme_xpm = [
-"16 16 4 1",
-" c None s None",
-". c black",
-"g c #FC8B65",
-"G c black",
-" .......... ",
-" .gggggggg. ",
-" ..........g. ",
-" .gggggggg.g. ",
-" ..........g.g. ",
-" .gggggggg.g.g. ",
-" .gGGGgggg.g.g. ",
-" .gggggggg.g.g. ",
-" .gGGGGGGg.g.g. ",
-" .gggggggg.g.g. ",
-" .gGGGGGGg.g.g. ",
-" .gggggggg.g... ",
-" .gGGGGGGg.g. ",
-" .gggggggg... ",
-" .gGGGGGGg. ",
-" .......... "]
-
-mytheme_xpm = [
-"16 16 4 1",
-" c None s None",
-". c black",
-"g c #E6E6E6",
-"G c #080808",
-" .......... ",
-" .gggggggg. ",
-" ..........g. ",
-" .gggggggg.g. ",
-" ..........g.g. ",
-" .gggggggg.g.g. ",
-" .gGGGgggg.g.g. ",
-" .gggggggg.g.g. ",
-" .gGGGGGGg.g.g. ",
-" .gggggggg.g.g. ",
-" .gGGGGGGg.g.g. ",
-" .gggggggg.g... ",
-" .gGGGGGGg.g. ",
-" .gggggggg... ",
-" .gGGGGGGg. ",
-" .......... "]
-
-article_xpm = [
-"16 16 4 1",
-" c None s None",
-". c black",
-"g c #62F24D",
-"G c black",
-" ............ ",
-" .gggggggggg. ",
-" .GGGGgggggg. ",
-" .gggggggggg. ",
-" .gGGGGGGGGg. ",
-" .gggggggggg. ",
-" .gGGGGGGGGg. ",
-" .gggggggggg. ",
-" .gGGGGGGGGg. ",
-" .gggggggggg. ",
-" .gGGGGGGGGg. ",
-" .gggggggggg. ",
-" .gGGGGGGGGg. ",
-" .gggggggggg. ",
-" .gGGGGGGGGg. ",
-" ............ ",
-]
-
-newarticle_xpm = [
-"16 16 4 1",
-" c None s None",
-". c black",
-"g c white",
-"G c black",
-" ............ ",
-" .gggggggggg. ",
-" .gggggggggg. ",
-" .gggggggggg. ",
-" .gggggggggg. ",
-" .gggggggggg. ",
-" .gggggggggg. ",
-" .gggggggggg. ",
-" .gggggggggg. ",
-" .gggggggggg. ",
-" .gggggggggg. ",
-" .gggggggggg. ",
-" .gggggggggg. ",
-" .gggggggggg. ",
-" .gggggggggg. ",
-" ............ ",
-]
-
-wikiarticle_xpm = [
-"16 16 4 1",
-" c None s None",
-". c black",
-"g c #FC8B65",
-"G c black",
-" ............ ",
-" .gggggggggg. ",
-" .GGGGgggggg. ",
-" .gggggggggg. ",
-" .gGGGGGGGGg. ",
-" .gggggggggg. ",
-" .gGGGGGGGGg. ",
-" .gggggggggg. ",
-" .gGGGGGGGGg. ",
-" .gggggggggg. ",
-" .gGGGGGGGGg. ",
-" .gggggggggg. ",
-" .gGGGGGGGGg. ",
-" .gggggggggg. ",
-" .gGGGGGGGGg. ",
-" ............ ",
-]
-
-
-class Library_View( gtk.HBox ):
- """
- Created by: Jonathan Mace
-
- Library View sets up the view to the library.
- It consists of 3 main widgets:
- 1) Treeview widget
- This is populated with the themes and articles in the library.
- They can be renamed, new articles and themes can be added, and
- they can be moved about with drag and drop.
- 2) Source-view widget
- This widget displays the current source article. It is a drag
- destination for drags originating from the treeview. Upon receiving
- a drag, it will load the appropriate article
- 3) Edit-view widget
- This widget displays the current edit article. It acts the same
- way as the source-view widget.
-
- A few minor things also exist, such as the creation of new blank articles
- and new blank themes if the user goes to editing mode without having anything
- selected.
-
- There is also a method for downloading new articles into the currently selected
- theme, which is activated by a button in the toolbar which is set up in the
- Library_Pane class.
-
- """
-
- # Create the icons
- themeicon = gtk.gdk.pixbuf_new_from_xpm_data(theme_xpm)
- articleicon = gtk.gdk.pixbuf_new_from_xpm_data(article_xpm)
- newarticleicon = gtk.gdk.pixbuf_new_from_xpm_data(newarticle_xpm)
- newthemeicon = gtk.gdk.pixbuf_new_from_xpm_data(newtheme_xpm)
- wikithemeicon = gtk.gdk.pixbuf_new_from_xpm_data(wikitheme_xpm)
- wikiarticleicon = gtk.gdk.pixbuf_new_from_xpm_data(wikiarticle_xpm)
- mythemeicon = gtk.gdk.pixbuf_new_from_xpm_data(mytheme_xpm)
-
- def __init__(self):
- self.ignore = True
-
- gtk.HBox.__init__(self)
-
- # First things first - make it look nice depending on the platform
- running_on = platform.system()
- self.colwidth = 250
- if running_on == "Linux" and "olpc" in platform.platform().lower():
- self.colwidth = 350
-
-
- #self.set_homogeneous(True)
- self.set_spacing(2)
- self.set_border_width(1)
-
- # Create the tree view, pack and show it
- self.treestore, self.treeview = self.__create_tree()
- self.treestorecontainer = gtk.ScrolledWindow()
- self.treestorecontainer.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- self.treestorecontainer.add(self.treeview)
- self.pack_start(self.treestorecontainer, False, False, 1)
- self.treestorecontainer.set_size_request(self.colwidth, -1)
- self.treestorecontainer.show_all()
-
- # Create a box for the textviews at the top and the status bar at the bottom
- maindisplay = gtk.VBox()
- maindisplay.set_spacing(2)
- self.pack_start(maindisplay)
- maindisplay.show()
-
- # Create a box for the two text views
- textviewbox = gtk.HBox()
- textviewbox.set_spacing(3)
- textviewbox.set_homogeneous(True)
- maindisplay.pack_start(textviewbox)
- textviewbox.show()
-
- # Create the status bar at the bottom of the page
-
- # Not bothering to show the statusbar
- statuseb = gtk.EventBox()
- statuseb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#EEEEEE"))
- maindisplay.pack_start(statuseb, False, True, 0)
- statuseb.set_size_request(-1, 50)
- statuseb.show()
-
- self.statusbar = gtk.Label()
- statuseb.add(self.statusbar)
- self.statusbar.show()
-
- # Create the sourcepane label and textbox
- self.sourcepanebox = gtk.VBox()
- self.sourcepanebox.set_spacing(2)
- textviewbox.pack_start(self.sourcepanebox)
- self.sourcepanebox.show()
-
- labeleb = gtk.EventBox()
- labeleb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#EEEEEE"))
- self.sourcepanebox.pack_start(labeleb, False, False, 0)
- labeleb.show()
-
- self.sourcepanelabel = gtk.Label()
- self.sourcepanelabel.set_justify(gtk.JUSTIFY_CENTER)
- self.sourcepanelabel.set_markup("<b>Wikipedia Article:</b>\n ")
- labeleb.add(self.sourcepanelabel)
- self.sourcepanelabel.show()
-
-
- sourcetextbox = gtk.ScrolledWindow()
- sourcetextbox.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- self.sourcepanebox.pack_start(sourcetextbox)
- sourcetextbox.show()
-
- self.sourcetext = Readonly_Textbox(False)
- self.sourcetext.set_editable(False)
- self.sourcetext.set_cursor_visible(False)
- self.sourcetext.connect("button-press-event", self.suppress, None)
- sourcetextbox.add(self.sourcetext)
- self.sourcetext.modify_font(pango.FontDescription('arial 9'))
- self.sourcetext.show()
- self.sourcetext.drag_dest_set(gtk.DEST_DEFAULT_ALL, [("sourcearticle", gtk.TARGET_SAME_APP, 0)], gtk.gdk.ACTION_COPY)
-
-
- # Create the editpane label and textbox
- self.editpanebox = gtk.VBox()
- self.editpanebox.set_spacing(2)
- textviewbox.pack_start(self.editpanebox)
- self.editpanebox.show()
-
- labeleb = gtk.EventBox()
- labeleb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#EEEEEE"))
- self.editpanebox.pack_start(labeleb, False, False, 0)
- labeleb.show()
-
- self.editpanelabel = gtk.Label()
- self.editpanelabel.set_justify(gtk.JUSTIFY_CENTER)
- self.editpanelabel.set_markup("<b>My Article:</b>\n ")
- labeleb.add(self.editpanelabel)
- self.editpanelabel.show()
-
- edittextbox = gtk.ScrolledWindow()
- edittextbox.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- self.editpanebox.pack_start(edittextbox)
- edittextbox.show()
-
- self.edittext = Readonly_Textbox(False)
- self.edittext.set_editable(False)
- self.edittext.set_cursor_visible(False)
- self.edittext.connect("button-press-event", self.suppress, None)
- edittextbox.add(self.edittext)
- self.edittext.modify_font(pango.FontDescription('arial 9'))
- self.edittext.show()
- self.edittext.drag_dest_set(gtk.DEST_DEFAULT_ALL, [("editarticle", gtk.TARGET_SAME_APP, 0)], gtk.gdk.ACTION_COPY)
-
-
-
- def suppress(self, widget, event, data):
- widget.stop_emission("button-press-event")
-
- def __create_tree(self):
- """
- Written by: Jonathan Mace
- Last Modified: 22/08/2008
- This method sets up the tree structure used to browse topics and articles.
- It populates the treemodel, connects all the events together and then returns the treeview widget.
- """
-
- # Create and populate the treestore.
- # The first element is the text (so, topic title or article title).
- # The second element is the associated icon.
- # The third element is the type (so, theme or article)
- treestore = gtk.TreeStore(str, gtk.gdk.Pixbuf, str, str, bool)
- themes = IO_Manager().get_themes()
- if not "Wikipedia Articles" in themes:
- IO_Manager().add_theme_to_library("Wikipedia Articles")
- themes.append("Wikipedia Articles")
- if not "My Articles" in themes:
- IO_Manager().add_theme_to_library("My Articles")
- themes.append("My Articles")
-
- for theme in themes:
- if theme == "Wikipedia Articles":
- themeiter = treestore.append(None, ["<b>%s</b>" % (theme, ), self.wikithemeicon, "wikitheme", "aaaaaaaaaaaaaaaaaaa", False])
- articles = IO_Manager().get_pages_in_theme(theme)
- for article in articles:
- treestore.append(themeiter, [article, self.wikiarticleicon, "wikiarticle", article, False])
- elif theme == "My Articles":
- themeiter = treestore.append(None, ["<b>%s</b>" % (theme, ), self.mythemeicon, "mytheme", "aaaaaaaaaaaaaaaaaab", False])
- articles = IO_Manager().get_pages_in_theme(theme)
- for article in articles:
- treestore.append(themeiter, [article, self.articleicon, "article", article, True])
- treestore.append(themeiter, ["<i>Create new article</i>", self.newarticleicon, "newarticle", "aaaaaaaaaaaaaaaaaaaa", True])
- else:
- themeiter = treestore.append(None, ["<b>%s</b>" % (theme, ), self.themeicon, "theme", theme, True])
- articles = IO_Manager().get_pages_in_theme(theme)
- for article in articles:
- treestore.append(themeiter, [article, self.articleicon, "article", article, True])
- treestore.append(themeiter, ["<i>Create new article</i>", self.newarticleicon, "newarticle", "aaaaaaaaaaaaaaaaaaaa", True])
- treestore.append(None, ["<i>Create new theme</i>", self.newthemeicon, "newtheme", "zzzzzzzzzzzzzzzzz", True])
- treestore.set_sort_column_id(3, gtk.SORT_ASCENDING)
-
- # Create the treeview, set properties.
- treeview = gtk.TreeView(treestore)
- treeview.set_enable_search(False)
- treeview.set_headers_visible(False)
- treeview.set_reorderable(False)
- treeview.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, [('text/plain', 0, 0), ("sourcearticle", gtk.TARGET_SAME_APP, 0), ("editarticle", gtk.TARGET_SAME_APP, 0)], gtk.gdk.ACTION_MOVE | gtk.gdk.ACTION_COPY)
- treeview.enable_model_drag_dest([('text/plain', 0, 0)], gtk.gdk.ACTION_MOVE)
- treeview.connect("drag-begin", self.drag_begin_event, None)
- treeview.connect("drag-drop", self.drag_drop_event, None)
- treeview.connect("drag-data-get", self.drag_data_get_event, None)
- treeview.connect("key-press-event", self.key_pressed, None)
-
- # Create the column to show the data, add to the treeview
- column = gtk.TreeViewColumn()
- treeview.append_column(column)
-
- # Create the cell renderers. Set properties and add to the column
- iconcell = gtk.CellRendererPixbuf()
-
- cell = gtk.CellRendererText()
- cell.connect("edited", self.name_changed, None)
-
-
- column.pack_start(iconcell, False)
- column.set_attributes(iconcell, pixbuf=1)
- column.set_sort_column_id(0)
-
- column.pack_start(cell, True)
- cell.set_property("editable", True)
- column.set_attributes(cell, markup=0)
-
- path = (0, )
- iter = treestore.get_iter(path)
- path = treestore.get_path(iter)
- treeview.expand_to_path(path)
-
- return treestore, treeview
-
-
- def populate(self):
- # Remove and destroy the current contents of the panel
- self.remove(self.treestorecontainer)
- self.treestorecontainer.destroy()
-
- # Create the new tree view, pack and show it
- self.treestore, self.treeview = self.__create_tree()
- self.treestorecontainer = gtk.ScrolledWindow()
- self.treestorecontainer.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- self.treestorecontainer.set_size_request(self.colwidth, -1)
- self.treestorecontainer.add(self.treeview)
- self.pack_start(self.treestorecontainer, False, False, 0)
- self.reorder_child(self.treestorecontainer, 0)
- self.treestorecontainer.show_all()
-
- def add_theme_to_tree(self, theme):
- """ Adds a row to the tree with name 'theme'
- Note, that this does not save anything in the IO Manager
- """
- model = self.treestore
- model.append(None, ["<b>" + theme + "</b>", self.themeicon, "theme", theme, True])
-
- def add_article_to_tree(self, theme, title):
- """ Adds a row to the tree under theme 'theme' with title 'title'
- Note, that this does not save anything in the IO Manager
- A typical usage of this would be:
-
- IO_Manager().save_article(article)
- Library_View.add_article_to_tree(article.article_theme, article.article_title)
- Library_View.highlight_article(article.article_theme, article.article_title)
- """
- theme = "<b>%s</b>"%(theme,)
- model = self.treestore
- iter = model.get_iter_first()
- while iter != None:
- if model.get(iter, 0)[0] == theme:
- if theme == "Wikipedia Articles":
- model.append(iter, [title, self.wikiarticleicon, "wikiarticle", title, True])
- else:
- model.append(iter, [title, self.articleicon, "article", title, True])
- return
- else:
- iter = model.iter_next(iter)
-
- def article_exists_in_tree(self, theme, title):
- """ Returns true if the article specified exists in the tree structure.
- This is different to whether it exists as said by IO manager.
- Typical usage would be:
-
- IO_Manager().save_article(article)
- if not Library_View.article_exists_in_tree(article.article_theme, article.article_title):
- Library_View.add_article_to_tree(article.article_theme, article.article_title)
- Library_View.highlight_article(article.article_theme, article.article_title)
-
-
-
- """
-
- theme = "<b>%s</b>"%(theme,)
- iter = self.treestore.get_iter_first()
- while iter != None:
- if self.treestore.get(iter, 0)[0] == theme:
- break
- else:
- iter = self.treestore.iter_next(iter)
- if iter == None:
- return False
- iter = self.treestore.iter_children(iter)
- while iter != None:
- if self.treestore.get(iter, 0)[0] == title:
- return True
- else:
- iter = self.treestore.iter_next(iter)
- return False
-
-
- def highlight_theme(self, title):
- # Highlights the theme specified by title
- title = "<b>%s</b>"%(title,)
- iter = self.treestore.get_iter_first()
- while iter != None:
- if self.treestore.get(iter, 0)[0] == title:
- destpath = self.treestore.get_path(iter)
- self.treeview.set_cursor(destpath, None, True)
- return
- else:
- iter = self.treestore.iter_next(iter)
-
- def highlight_article(self, theme, title):
- # Expands the theme specified by theme and highlights
- # the article within this theme, specified by title.
- theme = "<b>%s</b>"%(theme,)
- iter = self.treestore.get_iter_first()
- while iter != None:
- if self.treestore.get(iter, 0)[0] == theme:
- break
- else:
- iter = self.treestore.iter_next(iter)
- if iter == None:
- return
- iter = self.treestore.iter_children(iter)
- while iter != None:
- if self.treestore.get(iter, 0)[0] == title:
- destpath = self.treestore.get_path(iter)
- self.treeview.expand_to_path(destpath)
- self.treeview.set_cursor(destpath, None, True)
- return
- else:
- iter = self.treestore.iter_next(iter)
-
- def get_current_selection_type(self):
- # Returns one of 'article', 'newarticle', 'theme', 'newtheme' or None
- # depending on which element of the tree is selected.
- model, sourceiter = self.treeview.get_selection().get_selected()
- if sourceiter == None:
- return None
- else:
- type = model.get(sourceiter, 2)
- return type
-
- def get_current_theme(self):
- # Returns the current theme if one is selected,
- # otherwise returns none.
- model, sourceiter = self.treeview.get_selection().get_selected()
- if sourceiter == None:
- return None
- title, type = model.get(sourceiter, 0, 2)
- if type == "theme" or type == "wikitheme" or type == "mytheme":
- return title[3:len(title)-4]
- elif type == "article" or type == "newarticle" or type == "wikiarticle":
- theme = model.get(model.get_iter(model.get_path(sourceiter)[0]), 0)[0]
- theme = theme[3:len(theme)-4]
- return theme
- else:
- return None
-
- def get_current_article(self):
- # Returns the current article if one is selected,
- # otherwise returns none.
- model, sourceiter = self.treeview.get_selection().get_selected()
- if sourceiter == None:
- return None
- title, type = model.get(sourceiter, 0, 2)
- if type == "article" or type == "wikiarticle":
- return title
- else:
- return None
-
- def set_status(self, status):
- pass
-
-
- def key_pressed(self, widget, event, data):
- # We want the delete key to do something.
- key = event.keyval
- if key == 65535 or key == 65288 or key == 65307:
- model, sourceiter = self.treeview.get_selection().get_selected()
- if sourceiter == None:
- return
- data = model.get(sourceiter, 0, 1, 2)
- title = data[0]
- type = data[2]
-
- if type == "newarticle" or type == "newtheme" or type == "mytheme" or type == "wikitheme":
- # If the current selection is a "Create new article" or "Create new theme" field then we ignore the keypress
- return
-
- if type == "article" or type == "wikiarticle":
- title = data[0]
- theme = model.get(model.get_iter(model.get_path(sourceiter)[0]), 0)[0]
- theme = theme[3:len(theme)-4]
-
- # Delete the article from the theme
- IO_Manager().remove_page(title, theme)
-
- # If the source/working articles are this one then we remove them
- source = self.sourcetext.get_article()
- working = self.edittext.get_article()
- if source != None and source.article_title == title and source.article_theme == theme:
- self.sourcepanelabel.set_markup("<b>Wikipedia Article:</b>\n ")
- self.sourcetext.set_article(Article())
- if working != None and working.article_title == title and working.article_theme == theme:
- self.editpanelabel.set_markup("<b>My Article:</b>\n ")
- self.edittext.set_article(Article())
-
- # Remove the article from the tree view
- self.treestore.remove(sourceiter)
-
- # Highlight the theme
- destpath = self.treestore.get_path(sourceiter)
- if destpath == None:
- self.highlight_theme(theme)
- else:
- self.treeview.set_cursor(destpath, None, True)
-
- elif type == "theme":
- theme = data[0]
- theme = theme[3:len(theme)-4]
-
- # Delete the theme from the filesystem
- IO_Manager().remove_theme(theme)
-
- # Remove the theme from the tree view
- destpath = self.treestore.get_path(sourceiter)
- self.treestore.remove(sourceiter)
-
- # If the source/working articles are in this theme then we remove them
- source = self.sourcetext.get_article()
- working = self.edittext.get_article()
- if working != None and working.article_theme == theme:
- self.editpanelabel.set_markup("<b>My Article:</b>\n ")
- self.edittext.set_article(Article())
-
- # Highlight the next theme
- if destpath != None:
- self.treeview.set_cursor(destpath, None, True)
-
- self.set_status("Theme %s deleted" % (theme, ))
-
-
- def name_changed(self, renderer, path, newtext, data):
- # Disallowed chars are < > and &
- if newtext == "" or newtext.isspace() or '&' in newtext or '<' in newtext or '>' in newtext:
- return
-
- newtext = newtext
- model, sourceiter = self.treeview.get_selection().get_selected()
- data = model.get(sourceiter, 0, 1, 2)
- title = data[0]
- type = data[2]
- if type == "article":
- """ Rename the selected article """
-
- # Find the source theme and strip formatting tags
- sourcetheme = model.get(model.get_iter(model.get_path(sourceiter)[0]), 0)[0]
- sourcetheme = sourcetheme[3:len(sourcetheme)-4]
-
- # Reset the name in the source/working articles if appropriate
- source = self.sourcetext.get_article()
- edit = self.edittext.get_article()
- if source and source.article_title == title and source.article_theme == sourcetheme:
- logger.debug("setting source title")
- source.article_title = newtext
- self.sourcepanelabel.set_markup("<b>Copy from: </b> %s\n "%(newtext, ))
- if edit and edit.article_title == title and edit.article_theme == sourcetheme:
- logger.debug("setting edit title")
- edit.article_title = newtext
- self.editpanelabel.set_markup("<span size='medium'><b>Theme: </b> %s \n<b>Article to edit: </b> %s</span>"%(sourcetheme, newtext))
-
- # If there is already an article with the new name in the theme, then we ignore the name change and highlight the existing article
- if IO_Manager().page_exists(newtext, sourcetheme):
- self.highlight_article(sourcetheme, newtext)
- return
-
- # Rename the page with IO Manager
- IO_Manager().rename_page(sourcetheme, title, newtext)
-
- # Set text on row to new text
- iter = model.get_iter(path)
- model.set(iter, 0, newtext)
- model.sort_column_changed()
- self.set_status("Article %s renamed to %s in theme %s" % (title, newtext, sourcetheme))
- elif type == "theme":
- """ Rename the selected theme """
-
- # Strip formatting tags
- title = title[3:len(title)-4]
-
- # Reset the theme in the source/working articles if appropriate
- source = self.sourcetext.get_article()
- edit = self.edittext.get_article()
- if source and source.article_theme == title:
- logger.debug("setting source theme")
- source.article_theme = newtext
- if edit and edit.article_theme == title:
- logger.debug("setting edit theme")
- edit.article_theme = newtext
- self.editpanelabel.set_markup("<span size='medium'><b>Theme: </b> %s \n<b>Article to edit: </b> %s</span>"%(edit.article_theme, edit.article_title))
-
- # If there is already a theme with the new name, then we ignore the name change and highlight the existing theme
- if IO_Manager().theme_exists(newtext):
- self.highlight_theme(newtext)
- return
-
- # Rename theme in IO Manager
- IO_Manager().rename_theme(title, newtext)
-
- # Set text on row to the new text (otherwise it would revert back)
- iter = model.get_iter(path)
- model.set(iter, 0, "<b>%s</b>"%(newtext,))
- model.sort_column_changed()
- self.set_status("Theme %s renamed to %s" % (title, newtext))
- elif type == "newarticle":
-
- """ Creating a new article """
-
- if newtext.find("Create new article") != -1:
- # If the contents of the text box haven't changed, then
- # we don't want to do anything.
- return
-
- # Find the source theme and strip formatting tags
- sourceiter = model.get_iter(model.get_path(sourceiter)[0])
- sourcetheme = model.get(sourceiter, 0)[0]
- sourcetheme = sourcetheme[3:len(sourcetheme)-4]
-
- # If there is already a page with the title, we ignore the new article request and highlight the existing article
- if IO_Manager().page_exists(newtext, sourcetheme):
- self.highlight_article(sourcetheme, newtext)
- return
-
- # Create blank article
- data = Article_Data(self, article_title = newtext, article_theme = sourcetheme)
- article = Article(data)
-
- # Save article with IO manager
- IO_Manager().save_article(article)
-
- # Add new row for article
- destiter = model.append(sourceiter, [newtext, self.articleicon, "article", newtext, True])
-
- # Highlight new row
- destpath = model.get_path(destiter)
- self.treeview.set_cursor(destpath, None, True)
- self.set_status("New article '%s' created in theme %s" % (newtext, sourcetheme))
-
- elif type == "newtheme":
- """ Creating a new theme """
-
- if newtext.find("Create new theme") != -1:
- # If the contents of the text box haven't changed, then we don't want to do anything
- return
-
- try:
- # Create new topic in IO manager
- IO_Manager().add_theme_to_library(newtext)
-
- # Add new row for theme
- themeiter = model.append(None, ["<b>%s</b>" % (newtext, ), self.themeicon, "theme", newtext, True])
- model.append(themeiter, ["<i>Create new article</i>", self.newarticleicon, "newarticle", "aaaaaaaaaaaaaaaaaaaa", True])
-
- except theme_exists_error, e:
- elogger.debug('name_changed: %s' % e)
- # If the theme already exists, then we proceed to just highlight it.
- self.highlight_theme(newtext)
- return
-
- # Highlight new theme
- destpath = model.get_path(themeiter)
- self.treeview.expand_to_path(destpath)
- self.treeview.set_cursor(destpath, None, True)
- self.set_status("New theme '%s' created" % (newtext, ))
-
- def drag_begin_event(self, widget, context, data):
- # This just aborts the drag if the user attempts to drag a theme.
- model, sourceiter = widget.get_selection().get_selected()
- type = model.get(sourceiter, 2)[0]
- if type != "article" and type != "newarticle" and type != "wikiarticle":
- context.drag_abort(int(time.time()))
-
- def drag_drop_event(self, widget, context, x, y, time, data):
- """
- This method moves the source article to the topic that the user
- has dragged it to.
- """
- # First, retrieve the initial selection
- model, sourceiter = widget.get_selection().get_selected()
- data = model.get(sourceiter, 0, 1, 2, 3, 4)
- title = data[0]
- type = data[2]
-
- # The source theme is the label of the first node along the path to the current selection
- sourcetheme = model.get(model.get_iter(model.get_path(sourceiter)[0]), 0)[0]
- # Strip bold tags
- sourcetheme = sourcetheme[3:len(sourcetheme)-4]
-
- # Check the type, if the user didn't drag an article, we ignore
- if type == "article":
- # Work out the destination
- destrow = widget.get_dest_row_at_pos(x, y)
- destiter = model.get_iter((destrow[0][0], ))
- destpath = (destrow[0][0], 0)
- # Strip bold tags
- desttheme = model.get(destiter, 0)[0]
- desttheme = desttheme[3:len(desttheme)-4]
-
- # If the theme already has an article with the name, we do nothing, and highlight the article
- # in the destination theme
- if IO_Manager().page_exists(title, desttheme):
- self.highlight_article(desttheme, title)
- return
-
-
-
- # If the destination is the "Create new theme" bit, then
- # we create a new theme and put the article in the new theme
- if desttheme == "Wikipedia Articles":
- return
- elif desttheme == "Create new theme":
- themes = IO_Manager().get_themes()
- desttheme = "New Theme 1"
- i = 1
- while desttheme in themes:
- i = i + 1
- desttheme = "New Theme %d" % (i,)
- IO_Manager().add_theme_to_library(desttheme)
-
- # Add new row for theme
- destiter = model.append(None, ["<b>%s</b>" % (desttheme, ), self.themeicon, "theme", desttheme, True])
- model.append(destiter, ["<i>Create new article</i>", self.newarticleicon, "newarticle", "aaaaaaaaaaaaaaaaaaaa", True])
-
- # Re-jig the rows on the visual side of things
- destiter = self.treestore.insert(destiter, 0, data)
- self.treestore.remove(sourceiter)
- self.treeview.set_model(self.treestore)
-
-
- # Re-jig the files in the filesystem
- IO_Manager().move_page(sourcetheme, desttheme, title)
-
- # Reset the topic in the source/working articles if appropriate
- source = self.sourcetext.get_article()
- edit = self.edittext.get_article()
- if edit != None and edit.article_title == title and edit.article_theme == sourcetheme:
- logger.debug("setting edit title")
- edit.article_theme = desttheme
- self.editpanelabel.set_markup("<span size='medium'><b>Theme: </b> %s \n<b>Article to edit: </b> %s</span>"%(desttheme, title))
-
- # Highlight the result of the drag
- destpath = model.get_path(destiter)
- self.treeview.expand_to_path(destpath)
- self.treeview.set_cursor(destpath, None, True)
- self.set_status("Article %s moved from %s to %s" % (title, sourcetheme, desttheme))
- elif type == "wikiarticle":
- # Work out the destination
- destrow = widget.get_dest_row_at_pos(x, y)
- destiter = model.get_iter((destrow[0][0], ))
- destpath = (destrow[0][0], 0)
- # Strip bold tags
- desttheme = model.get(destiter, 0)[0]
- desttheme = desttheme[3:len(desttheme)-4]
- # Strip the "from en.wikipedia.org" or equivalent name
- i = title.find(" (from ")
- newtitle = title[0:i]
-
- i = 0
- temptitle = newtitle
- while IO_Manager().page_exists(temptitle, desttheme):
- temptitle = "%s %d" % (newtitle, i)
-
- newtitle = temptitle
-
- # If the theme already has an article with the name, we do nothing, and highlight the article
- # in the destination theme
- if IO_Manager().page_exists(newtitle, desttheme):
- self.highlight_article(desttheme, newtitle)
- return
-
-
-
- # If the destination is the "Create new theme" bit, then
- # we create a new theme and put the article in the new theme
- if desttheme == "Wikipedia Articles":
- return
- elif desttheme == "Create new theme":
- themes = IO_Manager().get_themes()
- desttheme = "New Theme 1"
- i = 1
- while desttheme in themes:
- i = i + 1
- desttheme = "New Theme %d" % (i,)
- IO_Manager().add_theme_to_library(desttheme)
-
- # Add new row for theme
- destiter = model.append(None, ["<b>%s</b>" % (desttheme, ), self.themeicon, "theme", desttheme, True])
- model.append(destiter, ["<i>Create new article</i>", self.newarticleicon, "newarticle", "aaaaaaaaaaaaaaaaaaaa", True])
-
- # Re-jig the rows on the visual side of things
- newdata = [newtitle, self.articleicon, "article", newtitle, True]
- destiter = self.treestore.insert(destiter, 0, newdata)
- self.treeview.set_model(self.treestore)
-
- # Re-jig the files in the filesystem
- IO_Manager().copy_page(title, sourcetheme, desttheme)
- IO_Manager().rename_page(desttheme, title, newtitle)
-
- # Reset the topic in the source/working articles if appropriate
- source = self.sourcetext.get_article()
- edit = self.edittext.get_article()
-
- # Highlight the result of the drag
- destpath = model.get_path(destiter)
- self.treeview.expand_to_path(destpath)
- self.treeview.set_cursor(destpath, None, True)
-
- def drag_data_get_event(self, widget, context, selection_data, info, timestamp, data):
- model, sourceiter = self.treeview.get_selection().get_selected()
- type = model.get(sourceiter, 2)[0]
- target = selection_data.target
- if target == "sourcearticle":
- if type == "wikiarticle":
- atom = gtk.gdk.atom_intern("article")
- title = self.get_current_article()
- theme = self.get_current_theme()
- string = cPickle.dumps([title, theme])
- selection_data.set(atom, 8, string)
- self.sourcepanelabel.set_markup("<span size='medium'><b>Wikipedia Article: </b> \n%s</span> "%(title, ))
- elif target == "editarticle":
- if type == "newarticle":
- # If the type is "newarticle" then we create a new article
- # and highlight it.
-
- # Create and save the new article
- theme = self.get_current_theme()
- i = 0
- title = "New Article"
- while IO_Manager().page_exists(title, theme):
- i = i + 1
- title = "New Article %d" % (i, )
- data = Article_Data(article_title = title, article_theme = theme)
- article = Article(data)
- IO_Manager().save_article(article)
-
- # Add the row to the tree model
- sourceiter = model.get_iter(model.get_path(sourceiter)[0])
- destiter = model.append(sourceiter, [title, self.articleicon, "article", title, True])
-
- # Highlight new row
- destpath = model.get_path(destiter)
- self.treeview.set_cursor(destpath, None, True)
-
- # Set the selection data to the new article
- atom = gtk.gdk.atom_intern("article")
- string = cPickle.dumps([title, theme])
- selection_data.set(atom, 8, string)
- self.editpanelabel.set_markup("<span size='medium'><b>Theme: </b> %s \n<b>Article to edit: </b> %s</span>"%(theme, title))
- elif type == "article":
- # If type is article, set the selection data to the theme and articlename
- atom = gtk.gdk.atom_intern("article")
- title = self.get_current_article()
- theme = self.get_current_theme()
- string = cPickle.dumps([title, theme])
- selection_data.set(atom, 8, string)
- self.editpanelabel.set_markup("<span size='medium'><b>Theme: </b> %s \n<b>Article to edit: </b> %s</span>"%(theme, title))
- elif type == "wikiarticle":
- title = self.get_current_article()
- theme = self.get_current_theme()
- i = title.find(" (from ")
- newtitle = title[0:i]
-
- i = 0
- temptitle = newtitle
- while IO_Manager().page_exists(temptitle, "My Articles"):
- i = i + 1
- temptitle = "%s %d" % (newtitle, i)
-
- newtitle = temptitle
- article = Article()
- article.article_title = newtitle
- article.article_theme = "My Articles"
- IO_Manager().save_article(article)
-
-
- sourceiter = model.get_iter((1,))
- destiter = model.append(sourceiter, [newtitle, self.articleicon, "article", newtitle, True])
-
- destpath = self.treestore.get_path(destiter)
- self.treeview.expand_to_path(destpath)
- self.treeview.set_cursor(destpath, None, True)
-
- self.sourcetext.set_article(IO_Manager().load_article(title, "Wikipedia Articles"))
- self.sourcepanelabel.set_markup("<span size='medium'><b>Wikipedia Article: </b> \n%s</span> "%(title, ))
-
-
- atom = gtk.gdk.atom_intern("article")
- string = cPickle.dumps([newtitle, "My Articles"])
- selection_data.set(atom, 8, string)
- self.editpanelabel.set_markup("<span size='medium'><b>Theme: </b> %s \n<b>Article to edit: </b> %s</span>"%("My Articles", newtitle))
-
- else:
- # No data so nothing happens
- pass
-
-
- def commence_retrieval(self, widget, entry, statuslabel, wikimenu, wikidictionary):
- title = entry.get_text()
- wiki = wikidictionary[wikimenu.get_active_text()]
- theme = "Wikipedia Articles"
- if title == "" or title == None:
- return
- if IO_Manager().page_exists("%s (from %s)"%(title, wiki), theme):
- statuslabel.set_label("%s already exists" % (title, ))
- t = Timer(10, self.clear_label, [statuslabel])
- t.start()
- else:
- t = Timer(0, self.download_and_add, [title, theme, wiki, statuslabel])
- t.start()
- #self.download(title, theme)
-
-
- def download_and_add(self, title, theme, wiki, statuslabel):
- #exceptions handled by IO_Manager
- try:
- statuslabel.set_label("Downloading %s..."%(title,))
- IO_Manager().download_wiki_article(title=title, theme=theme, wiki = wiki, statuslabel=statuslabel)
- except PageNotFoundError, e:
- elogger.debug('download_and_add: %s' % e)
- statuslabel.set_label("%s could not be found."%(title, ))
- return
- except Exception, e:
- elogger.debug('download_and_add: %s' % e)
- statuslabel.set_label("Error downloading %s. Check your connection."%(title, ))
- return
-
- model = self.treeview.get_model()
-
- wikipath = (0, )
- wikiiter = model.get_iter(wikipath)
- destiter = model.append(wikiiter, ["%s (from %s)"%(title, wiki), self.wikiarticleicon, "wikiarticle", "%s (from %s)"%(title, wiki), False])
-
- destpath = model.get_path(destiter)
- self.treeview.expand_to_path(destpath)
-
- statuslabel.set_markup("%s successfully downloaded." % (title, ))
- t = Timer(10, self.clear_label, [statuslabel])
- t.start()
-
- def clear_label(self, label):
- label.set_markup("")
-
-
- def set_source(self, article):
- # Set the article in the source pane to 'article'
- title = article.article_title
- buf = article.getBuffer()
- text = buf.get_slice(buf.get_start_iter(), buf.get_end_iter())
- if article.article_title != None and text != "" and article.article_theme == "Wikipedia Articles":
- self.sourcetext.set_article(article)
- self.sourcepanelabel.set_markup("<b>Wikipedia Article: </b> \n%s "%(title, ))
- else:
- self.sourcetext.set_article(Article())
- self.sourcetext.set_editable(False)
- self.sourcetext.set_cursor_visible(False)
-
- def get_source(self):
- """
- This returns the currently selected source article.
- If the selected source article is from a different theme to the currently
- selected edit article, then the article theme is changed. This only
- a temporary change and since it is a source article it is read only
- so it will never be saved.
- New themes / articles are created and loaded in the event that
- nothing is currently selected.
- """
- currentarticle = self.sourcetext.get_article()
- if not currentarticle or not currentarticle.article_title or currentarticle.article_title == "":
- article = Article()
- else:
- article = currentarticle
- article.article_theme == "Wikipedia Articles"
- return article
-
-
- def set_working(self, article):
- # Set the working article to 'article'
- theme = article.article_theme
- title = article.article_title
- buf = article.getBuffer()
- text = buf.get_slice(buf.get_start_iter(), buf.get_end_iter())
- if text:
- logger.debug("article has text")
- if not theme:
- theme = "My Articles"
- if not title:
- i = 0
- title = "New Article"
- while IO_Manager().page_exists(title, theme):
- i = i + 1
- title = "New Article %s" % (i, )
- else:
- if title and theme and "New Article" in title and not IO_Manager().page_exists(title, theme):
- title == None
- if theme and title and theme != "Wikipedia Articles":
- if not self.article_exists_in_tree(theme, title):
- self.add_article_to_tree(theme, title)
- IO_Manager().save_article(article)
- self.highlight_article(theme, title)
- self.edittext.set_article(article)
- self.editpanelabel.set_markup("<span size='medium'><b>Theme: </b> %s \n<b>Article to edit: </b> %s</span>"%(theme, title))
-
- self.sourcetext.set_editable(False)
- self.sourcetext.set_cursor_visible(False)
-
- def get_working(self):
- # Return the current working article, or create a new article in the current theme
- # if there is no current working article.
- currentarticle = self.edittext.get_article()
- if currentarticle != None:
- article = currentarticle
- else:
- article = Article()
- title = article.article_title
- theme = article.article_theme
-
- if not theme or theme == "":
- theme = "My Articles"
- article.article_theme = theme
-
- if not title or title == "":
- sourcearticle = self.sourcetext.get_article()
- if sourcearticle and sourcearticle.article_title:
- sourcetitle = sourcearticle.article_title
- else:
- sourcetitle = ""
- j = sourcetitle.find(" (from ")
- if j != -1:
- title = sourcetitle[0:j]
- else:
- title = "New Article"
- articles = IO_Manager().get_pages_in_theme(theme)
- i = 0
- while title in articles:
- i = i + 1
- title = "New Article %d" % (i, )
- logger.debug(title)
- article.article_title = title
-
- return article
diff --git a/GUI_Components/Compound_Widgets/bookview.py b/GUI_Components/Compound_Widgets/bookview.py
index 79fccd9..71f296d 100644
--- a/GUI_Components/Compound_Widgets/bookview.py
+++ b/GUI_Components/Compound_Widgets/bookview.py
@@ -22,13 +22,22 @@ 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')
+PUBLISH = 0
+TITLE = 1
+
class BookView(gtk.VBox):
- def __init__(self, book, name):
+ def sync(self):
+ if not self._changing:
+ return
+ gobject.source_remove(self._changing)
+ index, column = self.tree.get_cursor()
+ self._cursor_changed(index)
+
+ def __init__(self, book, name, tooltip, custom):
gtk.VBox.__init__(self)
self.book = book
self._changing = None
@@ -37,21 +46,25 @@ class BookView(gtk.VBox):
# title checkbox
- self._check = gtk.CheckButton()
- 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.set_size_request(50, -1)
- check_box.pack_start(self._check, True, False)
- title.insert(WidgetItem(check_box), -1)
+ if custom:
+ self._check = gtk.CheckButton()
+ self._check.props.can_focus = False
+ self._check.props.tooltip_text = \
+ _('Articles are ready to be published')
+ self._check.connect('toggled', self._check_toggled_cb)
+ check_box = gtk.HBox()
+ check_box.set_size_request(50, -1)
+ check_box.pack_start(self._check, True, False)
+ title.insert(WidgetItem(check_box), -1)
+ else:
+ title.insert(WidgetItem(gtk.Label(' ')), -1)
# title caption
caption_label = gtk.Label(name)
+ caption_label.props.tooltip_text = tooltip
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)
@@ -63,17 +76,37 @@ class BookView(gtk.VBox):
separator.set_expand(True)
title.insert(separator, -1)
+ # create article button
+
+ if custom:
+ create = ButtonItem('add',
+ label=_('Create'),
+ tooltip_text=_('Create new article'))
+ create.connect('clicked', self._create_cb)
+ title.insert(create, -1)
+ else:
+ logger.debug('BookView(%s): listen for new articles' % name)
+ self.book.connect('article-added', self._article_added_cb)
+
+ # delete article button
+
+ delete = ButtonItem('edit-delete',
+ label=_('Delete'),
+ tooltip_text=_('Delete current article'))
+ delete.connect('clicked', self._delete_cb)
+ title.insert(delete, -1)
+
# move buttons
- downward = ButtonItem('go-down',
- label='Move downward',
+ downward = ButtonItem('down',
+ label=_('Move downward'),
tooltip_text=_('Move article downward'))
- downward.connect('clicked', self._downward_clicked_cb)
+ downward.connect('clicked', self._swap_cb, +1)
title.insert(downward, -1)
- upward = ButtonItem('go-up',
+ upward = ButtonItem('up',
label=_('Move upward'),
tooltip_text=_('Move article upward'))
- upward.connect('clicked', self._upward_clicked_cb)
+ upward.connect('clicked', self._swap_cb, -1)
title.insert(upward, -1)
# tree
@@ -90,6 +123,7 @@ class BookView(gtk.VBox):
column = self.tree.insert_column_with_attributes(0, '', cell, active=0)
column.props.sizing = gtk.TREE_VIEW_COLUMN_FIXED
column.props.fixed_width = 50
+ column.props.visible = custom
cell = gtk.CellRendererText()
cell.connect('edited', self._cell_edited_cb)
@@ -97,71 +131,133 @@ class BookView(gtk.VBox):
self.tree.insert_column_with_attributes(1, '', cell, text=1)
for i in self.book.map:
- self.store.append((False, i['title']))
+ self.store.append((i['ready'], i['title']))
# scrolled tree
tree_scroll = gtk.ScrolledWindow()
tree_scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- tree_scroll.add_with_viewport(self.tree)
+ tree_scroll.add(self.tree)
self.pack_start(title, False)
self.pack_start(tree_scroll)
- self.tree.set_cursor(0, self.tree.get_column(1), False)
+
+ if len(self.store):
+ self.tree.set_cursor(0, self.tree.get_column(1), False)
+ if custom:
+ self._update_check(self.store[0][PUBLISH])
+
self.show_all()
- def _downward_clicked_cb(self, widget):
- pass
+ def _article_added_cb(self, book, article):
+ logger.debug('_article_added_cb: new article %s' % article)
+
+ self.book.props.article = article
+ self.store.append((False, article))
+ self.tree.set_cursor(len(self.store)-1, self.tree.get_column(1), False)
+
+ def _create_cb(self, widget):
+ def find_name(list, prefix, uniq):
+ name = uniq == 0 and prefix or ('%s %d' % (prefix, uniq))
+ if not [i for i in list if i[TITLE] == name]:
+ return name
+ return find_name(list, prefix, uniq+1)
+
+ if self._changing:
+ gobject.source_remove(self._changing)
+ self._changing = None
+
+ name = find_name(self.store, _('New article'), 0)
+ self.book.props.article = name
+ self.store.append((False, name))
+ self.tree.set_cursor(len(self.store)-1, self.tree.get_column(1), True)
+
+ def _delete_cb(self, widget):
+ index, column = self.tree.get_cursor()
+ if not index:
+ return
+ index = index[0]
+
+ if self._changing:
+ gobject.source_remove(self._changing)
+ self._changing = None
+
+ self.book.remove(self.store[index][TITLE])
+ self.store.remove(self.tree.props.model.get_iter(index))
- def _upward_clicked_cb(self, widget):
- pass
+ if len(self.store):
+ if index >= len(self.store):
+ index -= 1
+ self.tree.set_cursor(index, self.tree.get_column(1), False)
+
+ def _swap_cb(self, widget, delta):
+ old_index, column = self.tree.get_cursor()
+ if not old_index:
+ return
+
+ old_index = old_index[0]
+ new_index = old_index + delta
+
+ if new_index < 0:
+ new_index = len(self.store)-1
+ elif new_index >= len(self.store):
+ new_index = 0
+
+ self.book.map[old_index], self.book.map[new_index] = \
+ self.book.map[new_index], self.book.map[old_index]
+ self.store.swap(self.tree.props.model.get_iter(old_index),
+ self.tree.props.model.get_iter(new_index))
def _check_toggled_cb(self, widget):
- for i in self.store:
- i[0] = widget.props.active
+ for i, entry in enumerate(self.store):
+ entry[PUBLISH] = widget.props.active
+ self.book.map[i]['ready'] = 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
-
+ def _update_check(self, value):
for i in self.store:
- if i[0] != value:
+ if i[PUBLISH] != value:
self._check.props.inconsistent = True
return
-
self._check.props.inconsistent = False
self._check.props.active = value
+ def _cell_toggled_cb(self, cell, index):
+ value = not self.store[index][PUBLISH]
+ self.store[index][PUBLISH] = value
+ self.book.map[int(index)]['ready'] = value
+ self._update_check(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)
+
+ if index != None:
+ self._changing = gobject.timeout_add(500, self._cursor_changed,
+ index)
def _cursor_changed(self, index):
- self.book.props.article = self.store[index][1]
- self._changing = False
+ self.book.props.article = self.store[index][TITLE]
+ self._changing = None
return False
def _cell_edited_cb(self, cell, index, newtext):
+ logger.debug('_cell_edited_cb(%s, %s)' % (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]
+ overides = [i for i, row in enumerate(self.store)
+ if row[TITLE] == 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
+ self.book.props.article.article_title = newtext
+ self.store[index][TITLE] = newtext
diff --git a/GUI_Components/Compound_Widgets/toolbar.py b/GUI_Components/Compound_Widgets/toolbar.py
index f9f7a34..aae66ca 100644
--- a/GUI_Components/Compound_Widgets/toolbar.py
+++ b/GUI_Components/Compound_Widgets/toolbar.py
@@ -16,6 +16,7 @@ import gtk
import gobject
from sugar.graphics.icon import Icon
+import sugar.graphics.style as style
class WidgetItem(gtk.ToolItem):
def __init__(self, widget):
@@ -33,3 +34,7 @@ class ButtonItem(gtk.ToolButton):
alignment = gtk.Alignment(0.5, 0.5)
alignment.add(icon)
self.set_icon_widget(alignment)
+
+ if size == gtk.ICON_SIZE_SMALL_TOOLBAR:
+ button_size = style.SMALL_ICON_SIZE + 4
+ self.set_size_request(button_size, button_size)
diff --git a/Processing/Article/Sentence.py b/Processing/Article/Sentence.py
index 3b11d5a..42feb2a 100644
--- a/Processing/Article/Sentence.py
+++ b/Processing/Article/Sentence.py
@@ -2,7 +2,9 @@
import pygtk
pygtk.require('2.0')
+import os
import gtk
+import logging
from Article_Data import *
@@ -26,7 +28,7 @@ from an action not controlled by the Article object it is contained in.
"""
-
+logger = logging.getLogger('infoslicer')
class RawSentence:
@@ -155,8 +157,11 @@ class Picture( RawSentence ):
rightmark = buf.create_mark(None, insertioniter, True)
leftmark = buf.create_mark(None, insertioniter, False)
- pixbuf = gtk.gdk.pixbuf_new_from_file(picture_data.text)
- buf.insert_pixbuf(insertioniter, pixbuf)
+ if os.path.isfile(picture_data.text):
+ pixbuf = gtk.gdk.pixbuf_new_from_file(picture_data.text)
+ buf.insert_pixbuf(insertioniter, pixbuf)
+ else:
+ logger.warning('cannot open image %s' % picture_data.text)
left = buf.get_iter_at_mark(rightmark)
right = buf.get_iter_at_mark(leftmark)
@@ -197,4 +202,4 @@ class dummySentence( Sentence ):
self.leftmark = self.buf.create_mark(None, insertioniter, leftgravity)
self.rightmark = self.buf.create_mark(None, insertioniter, leftgravity)
self.type = "dummysentence"
- \ No newline at end of file
+
diff --git a/Processing/IO_Manager.py b/Processing/IO_Manager.py
deleted file mode 100644
index d00c2b7..0000000
--- a/Processing/IO_Manager.py
+++ /dev/null
@@ -1,350 +0,0 @@
-# Copyright (C) IBM Corporation 2008
-
-import gtk
-import shutil
-import re
-import logging
-import os
-import urllib
-import gobject
-from gettext import gettext as _
-
-from BeautifulSoup import Tag
-from NewtifulSoup import NewtifulStoneSoup as BeautifulStoneSoup
-from Article_Builder import Article_Builder
-from Processing.Article.Article import Article
-from MediaWiki_Helper import MediaWiki_Helper, PageNotFoundError
-from MediaWiki_Parser import MediaWiki_Parser
-
-logger = logging.getLogger('infoslicer')
-elogger = logging.getLogger('infoslicer::except')
-
-class theme_not_found_error(Exception):
- def __init__(self, value):
- self.parameter = value
- def __str__(self):
- return repr(self.parameter)
-
-class page_not_found_error(Exception):
- def __init__(self, value):
- self.parameter = value
- def __str__(self):
- return repr(self.parameter)
-
-class theme_exists_error(Exception):
- def __init__(self, value):
- self.parameter = value
- def __str__(self):
- return repr(self.parameter)
-
-"""
-This class sits between the GUI and the back end (handling
-mediawiki communication and raw pages/article modifications)
-"""
-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
- """
- logger.debug("Cleaning: " + title)
- output = re.sub(re.compile('\W'), "_", title).lower()
- logger.debug("Output: " + output)
- return output
-
- def __add_page_to_library(self, title, path):
- """
- Adds a page to the library.
-
- @param title: The title of the article to add to library.
- @param path: The path of the article to add to library.
- """
- #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 download_wiki_article(self, title, theme, wiki=None, statuslabel = None):
- """
- manages downloading and saving of wiki articles.
- @param title: Title of article to get
- @param theme: Theme to save to
- @param wiki: (optional) wiki to search - see MediaWiki helper for default behaviour
- @param statuslabel: gtk status label to write to
-
- """
- if statuslabel != None:
- statuslabel.set_label("%s download in progress..." % (title))
- if wiki == None:
- #article, url = MediaWiki_Helper().getArticleAsHTMLByTitle(title)
- wiki = "en.wikipedia.org"
-
- article, url = MediaWiki_Helper().getArticleAsHTMLByTitle(title, wiki)
- if statuslabel != None:
- statuslabel.set_label("Processing %s..." % (title))
-
- parser = MediaWiki_Parser(article, title, url)
- contents = parser.parse()
- #TODO: change line below when taking from other sources:
- self.save_page(title + " (from %s)" % wiki, contents, theme, False, True, statuslabel)
- if statuslabel != None:
- statuslabel.set_label("Done.")
-# unique=2
-# new_title = title.lower()
-# contents = self.image_handler(parser.parse(), title)
-# if not os.path.exists(os.path.join(self.workingDir, title.lower())):
-# os.makedirs(os.path.join(self.workingDir, title.lower()), 0777)
-# while os.access(os.path.join(self.workingDir, title.lower(), "%s.dita" % new_title), os.F_OK):
-# new_title = title.lower() + str(unique)
-# unique += 1
-# contents = contents.replace('<prolog>', '<prolog>\n<resourceid id="%d" />' % self.get_unique_article_ID(), 1)
-# file = open(os.path.join(self.workingDir, title.lower(), "%s.dita" % new_title), "w")
-# file.write(contents)
-# file.close()
-
- def get_unique_article_ID(self):
- """
- Creates and maintains a file to record the last unique article ID issued.
- when a new ID is requested, returns last id + 1 and upates file.
- @returns: Unique numeric ID
- """
- if not os.access(os.path.join(self.workingDir, "idfile"), os.F_OK):
- # if no ID file, take a guess at where to start numbering.
- id = 1
- # Worst case scenario is that every file is an article, so count all files
- for item in os.walk(self.workingDir):
- id += len(item[2])
- # Multiply by 1000 to prevent any problems caused by deleting files
- id = id * 1000
- logger.debug("ID FILE NOT FOUND, setting ID to " + str(id))
- id_file = open(os.path.join(self.workingDir, "idfile"), "w")
- id_file.write(str(id))
- id_file.close()
- return id
- else:
- id_file = open(os.path.join(self.workingDir, "idfile"), "r")
- id = long(id_file.read())
- id_file.close()
- id += 1
- id_file = open(os.path.join(self.workingDir, "idfile"), "w")
- id_file.write(str(id))
- id_file.close()
- return id
-
- def image_handler(self, document, title, statuslabel=None):
- """
- Takes a DITA article and downloads images referenced in it (finding all <image> tags).
- Attemps to fix incomplete paths using source url.
- @param document: DITA to work on
- @param title: Title of article
- @return: The document with image tags adjusted to point to local paths
- """
- document = BeautifulStoneSoup(document)
- dir_path = os.path.join(self.workingDir, self.clean_title(title), "images")
- logger.debug(dir_path)
- if not os.path.exists(dir_path):
- os.makedirs(dir_path, 0777)
- if statuslabel != None:
- i = title.find(" (from ")
- temptitle = title[0:i]
- statuslabel.set_label("Downloading %s images..." % (temptitle, ))
- for image in document.findAll("image"):
- fail = False
- path = image['href']
- if "#DEMOLIBRARY#" in path:
- path = path.replace("#DEMOLIBRARY#", os.path.join(os.path.split(__file__)[0], "demolibrary"))
- image_title = os.path.split(path)[1]
- shutil.copyfile(path, os.path.join(dir_path, image_title))
- else:
- image_title = path.rsplit("/", 1)[-1]
- # attempt to fix incomplete paths
- if (not path.startswith("http://")) and document.source != None and document.source.has_key("href"):
- if path.startswith("/"):
- path = document.source['href'].rsplit("/", 1)[0] + path
- else:
- path = document.source['href'].rsplit("/", 1)[0] + "/" + path
- logger.debug("Retrieving image: " + path)
- file = open(os.path.join(dir_path, image_title), 'wb')
- image_contents = self.__open_URL(path)
- if image_contents == None:
- fail = True
- else:
- file.write(image_contents)
- file.close()
- #change to relative paths:
- if not fail:
- image['href'] = os.path.join(dir_path.replace(os.path.join(self.workingDir, ""), "", 1), image_title)
- else:
- image.extract()
- return document.prettify()
-
- def load_raw_page(self, title):
- """
- Returns contents of specified page.
-
- @param title: Title of page to open.
- @return: Contents of page.
- """
- logger.debug('load article %s' % title)
- theme_map = self.load_map()
-
- 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)
-
- #if not os.access(page_location, os.F_OK):
- if os.access(os.path.join(self.workingDir, page_location), os.F_OK):
- page_location = os.path.join(self.workingDir, page_location)
- else:
- raise page_not_found_error("Page not found at " + page_location)
- page = open(page_location, "r")
- output = page.read()
- page.close()
- return output
-
- def load_page(self, title):
- return Article_Builder(self.workingDir).get_article_from_dita(
- self.load_raw_page(title))
-
- def load_article(self, title):
- """
- loads the specified article
- """
- article_data = self.load_page(title)
- article = Article(article_data)
- article.article_title = title
- return article
-
- def __open_URL(self, url):
- """
- retrieves content from specified url
- """
- urllib._urlopener = self.New_URL_Opener()
- try:
- logger.debug("opening " + url)
- logger.debug("proxies: " + str(proxies))
- doc = urllib.urlopen(url, proxies=proxies)
- output = doc.read()
- doc.close()
- logger.debug("url opened succesfully")
- return output
- except IOError, e:
- elogger.debug('__open_URL: %s' % e)
-
- def remove_page(self, page):
- """
- Removes specified page from the specified.
- @param page: Page to remove
- """
- theme_map = self.load_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
- """
- 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):
- """
- wrapper method for save_page to allow saving article objects
- """
- title = article.article_title
- if title != None:
- contents = Article_Builder(self.workingDir).get_dita_from_article(
- article)
- self.save_page(title, contents, overwrite)
- else:
- raise theme_not_found_error("Title not specified")
-
- def save_page(self, title, contents, get_images=False, statuslabel=None):
- """
- Saves the specified page contents as specified title.
- @param title: Title to save as.
- @param contents: Contents to save.
- """
- new_title = self.clean_title(title)
- if get_images:
- contents = self.image_handler(contents, title, statuslabel)
-
- directory = os.path.join(self.workingDir, self.clean_title(title))
-
- if not os.path.exists(directory):
- os.makedirs(directory, 0777)
-
- contents = contents.replace(
- '<prolog>', '<prolog>\n<resourceid id="%d" />'
- % self.get_unique_article_ID(), 1)
-
- file = open(os.path.join(directory, "%s.dita" % new_title), "w")
- file.write(contents)
- file.close()
- self.__add_page_to_library(title, os.path.join(directory, "%s.dita" % new_title))
-
- logger.debug("Page saved to - " + os.path.join(directory, "%s.dita" %
- new_title))
-
- return os.path.join(directory, "%s.dita" % new_title)
-
- def validate_image_list(self, image_list):
- """
- provides a mechanism for validating image lists and expanding relative paths
- @param image_list: list of images to validate
- @return: list of images with corrected paths, and broken images removed
- """
- for i in xrange(len(image_list)):
- if not os.access(image_list[i][0], os.F_OK):
- if os.access(os.path.join(self.workingDir, image_list[i][0]), os.F_OK):
- image_list[i] = (os.path.join(self.workingDir, image_list[i][0]), image_list[i][1])
- else:
- image = None
- #removing during for loop was unreliable
- while None in image_list:
- image_list.remove(None)
- return image_list
-
- class New_URL_Opener(urllib.FancyURLopener):
- version = "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1b2)" \
- "Gecko/20081218 Gentoo Iceweasel/3.1b2"
-
-# http proxy
-
-proxies = {}
-
-proxy_file = os.path.join(os.path.split(os.path.split(__file__)[0])[0], 'proxy.cfg')
-
-if os.access(proxy_file, os.F_OK):
- proxy_file_handle = open(proxy_file, "r")
- for line in proxy_file_handle.readlines():
- parts = line.split(':', 1)
- #logger.debug("setting " + parts[0] + " proxy to " + parts[1])
- proxies[parts[0].strip()] = parts[1].strip()
- proxy_file_handle.close()
-
-if proxies == {}:
- proxies = None
diff --git a/Processing/MediaWiki_Helper.py b/Processing/MediaWiki_Helper.py
index acfc74d..a20c838 100644
--- a/Processing/MediaWiki_Helper.py
+++ b/Processing/MediaWiki_Helper.py
@@ -1,10 +1,11 @@
# Copyright (C) IBM Corporation 2008
import urllib
-import IO_Manager
from xml.dom import minidom
import logging
+import net
+
logger = logging.getLogger('infoslicer')
"""
@@ -38,7 +39,7 @@ content based on a number of parameters such as URL, Title, Revision.
class MediaWiki_Helper:
def __init__(self):
- self.proxies = IO_Manager.proxies
+ self.proxies = net.proxies
def resolveTitle(self, title, wiki=defaultWiki):
"""Check if a wiki article exists using the mediawiki api. Follow redirects.
diff --git a/activity.py b/activity.py
index adcd79b..3923e4b 100644
--- a/activity.py
+++ b/activity.py
@@ -48,32 +48,40 @@ class InfoslicerActivity(SharedActivity):
def _init_cb(self, sender):
book.init()
- self.library = library.View()
- self.library.show()
- self.notebook.append_page(self.library)
-
+ self.edit_page = 1
self.edit = edit.View()
- self.edit.show()
- self.notebook.append_page(self.edit)
+ self.edit_bar = edit.Toolbar(self.edit)
+
+ self.library = library.View(self._set_edit_sensitive)
+ library_bar = library.Toolbar(self.library)
toolbox = ActivityToolbox(self)
- toolbox.show()
toolbox.connect('current-toolbar-changed', self._toolbar_changed_cb)
self.set_toolbox(toolbox)
-
- library_bar = library.Toolbar(self.library)
- library_bar.show()
toolbox.add_toolbar(_('Library'), library_bar)
+ toolbox.add_toolbar(_('Edit'), self.edit_bar)
- edit_bar = edit.Toolbar(self.edit)
- edit_bar.show()
- toolbox.add_toolbar(_('Edit'), edit_bar)
+ edit_fake = gtk.EventBox()
+
+ self.notebook.append_page(self.library)
+ self.notebook.append_page(self.edit)
+ self.notebook.append_page(edit_fake)
toolbox.set_current_toolbar(1)
+ self.show_all()
+
+ def _set_edit_sensitive(self, enable):
+ self.edit_bar.props.sensitive = enable
+ self.edit_page = (enable and 1 or 2)
def _tube_cb(self, activity, tube_conn, initiating):
pass
def _toolbar_changed_cb(self, widget, index):
if index > 0:
- self.notebook.set_current_page(index-1)
+ if index == 1:
+ index = 0
+ else:
+ self.library.sync()
+ index = self.edit_page
+ self.notebook.set_current_page(index)
diff --git a/activity/activity.info b/activity/activity.info
index f6d1a4d..84186b9 100644
--- a/activity/activity.info
+++ b/activity/activity.info
@@ -3,7 +3,7 @@ name = InfoSlicer
activity_version = 2
host_version = 1
icon = slicelogo
-bundle_id = org.sugarlabs.infoslicer
+bundle_id = org.sugarlabs.InfoSlicer
exec = sugar-activity activity.InfoslicerActivity
show_launcher = yes
license = GPLv2+
diff --git a/book.py b/book.py
index d02741a..33ea2c2 100644
--- a/book.py
+++ b/book.py
@@ -14,58 +14,125 @@
import os
import gtk
+import uuid
import logging
import gobject
import cjson
+import shutil
from gobject import SIGNAL_RUN_FIRST, TYPE_PYOBJECT
from gettext import gettext as _
from sugar.activity.activity import get_bundle_path, get_activity_root
-from Processing.IO_Manager import IO_Manager
+import net
+from Processing.Article.Article import Article
+from Processing.Article_Builder import Article_Builder
logger = logging.getLogger('infoslicer')
wiki = None
custom = None
-class Book(IO_Manager):
+class Book(gobject.GObject):
__gsignals__ = {
- 'article-changed' : (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]) }
+ 'article-selected' : (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]),
+ 'article-added' : (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]),
+ 'article-deleted' : (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]) }
def get_article(self):
return self._article
- def set_article(self, name):
- if self._article.article_title == name:
+ def set_article(self, title):
+ if self._article and self._article.article_title == title:
return
- new = [i for i in self.map if i['title'] == name]
+ if self._article:
+ # save current copy of article
+ self.find_by_uuid(self._article.uid)['title'] = \
+ self._article.article_title
+ contents = Article_Builder(self.root).get_dita_from_article(
+ self._article)
+ self._save(self._article.uid, contents)
- if not new:
- logger.debug('cannot find article %s' % name)
+ if title is None:
return
- self._article = self.load_article(new[0]['title'])
- self.emit('article-changed', self._article)
+ index, entry = self.find(title)
+
+ if entry:
+ content = self._load(entry['uid'])
+ if content:
+ data = Article_Builder(self.root).get_article_from_dita(content)
+ self._article = Article(data)
+ else:
+ self._article = Article()
+ else:
+ entry = self._create(title, uuid.uuid1())
+ self._article = Article()
+
+ self._article.uid = entry['uid']
+ self._article.article_title = title
+ self.emit('article-selected', self._article)
article = gobject.property(type=object,
getter=get_article, setter=set_article)
+ def create(self, title, content):
+ uid = str(uuid.uuid1())
+ content = net.image_handler(self.root, uid, content)
+ self._save(uid, content)
+ self._create(title, uid)
+
+ def remove(self, title):
+ index, entry = self.find(title)
+
+ if not entry:
+ logger.debug('cannot find %s to remove' % title)
+ return
+
+ if self._article and self._article.article_title == title:
+ self._article = None
+
+ shutil.rmtree(os.path.join(self.root, entry['uid']), True)
+ del self.map[index]
+ self.emit('article-deleted', title)
+
+ def find(self, title):
+ for i, entry in enumerate(self.map):
+ if entry['title'] == title:
+ return (i, entry)
+ return (None, None)
+
+ def find_by_uuid(self, uid):
+ for i in self.map:
+ if i['uid'] == uid:
+ return i
+ return None
+
+ def save_map(self):
+ mapfile = file(os.path.join(self.root, 'map'), 'w')
+ mapfile.write(cjson.encode(self.map))
+ mapfile.close()
+
def __init__(self, preinstalled, dirname):
- IO_Manager.__init__(self, 0)
- self.workingDir = os.path.join(get_activity_root(), dirname)
+ gobject.GObject.__init__(self)
+ self.root = os.path.join(get_activity_root(), dirname)
self.map = []
-
- if os.path.exists(self.workingDir):
- mapfile = file(os.path.join(self.workingDir, 'map'), 'r')
- self.map = cjson.decode(mapfile.read())
+ self._article = None
+
+ if os.path.exists(self.root):
+ try:
+ mapfile = file(os.path.join(self.root, 'map'), 'r')
+ self.map = cjson.decode(mapfile.read())
+ if self.map:
+ self.props.article = self.map[0]['title']
+ except:
+ logger.debug('cannot find map file; use empty')
else:
- os.makedirs(self.workingDir, 0777)
+ os.makedirs(self.root, 0777)
for i in preinstalled:
- filepath = os.path.join(get_bundle_path(), 'Processing',
- 'demolibrary', i[1])
+ filepath = os.path.join(get_bundle_path(), 'examples', i[1])
logger.debug("install library: opening %s" % filepath)
open_file = open(filepath, "r")
@@ -73,28 +140,45 @@ class Book(IO_Manager):
open_file.close()
logger.debug("install library: saving page %s" % i[0])
- self.save_page(i[0], contents, get_images=True)
+ self.create(i[0], contents)
logger.debug("install library: save successful")
+ self.save_map()
- if self.map:
- self._article = self.load_article(self.map[0]['title'])
- else:
- self._article = None
+ def _create(self, title, uid):
+ entry = { 'title': title, 'uid': str(uid), 'ready': False }
+ self.map.append(entry)
+ self.emit('article-added', title)
+ return entry
- 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
+ def _load(self, uid):
+ logger.debug('load article %s' % uid)
- def save_map(self):
- mapfile = file(os.path.join(self.workingDir, 'map'), 'w')
- mapfile.write(cjson.encode(self.map))
- mapfile.close()
+ path = os.path.join(self.root, str(uid), 'page.dita')
+ if not os.access(path, os.F_OK):
+ logger.debug('_load: cannot find %s' % path)
+ return None
+
+ page = open(path, "r")
+ output = page.read()
+ page.close()
+
+ return output
+
+ def _save(self, uid, contents):
+ directory = os.path.join(self.root, str(uid))
+
+ if not os.path.exists(directory):
+ os.makedirs(directory, 0777)
+
+ contents = contents.replace(
+ '<prolog>', '<prolog>\n<resourceid id="%s" />'
+ % uuid.uuid1(), 1)
+
+ file = open(os.path.join(directory, 'page.dita'), 'w')
+ file.write(contents)
+ file.close()
- # backward compatibility with IO_Manager
- def load_map(self):
- return self.map
+ logger.debug('save: %s' % directory)
class WikiBook(Book):
def __init__(self):
@@ -117,5 +201,7 @@ def init():
custom = CustomBook()
def teardown():
+ wiki.props.article = None
wiki.save_map()
+ custom.props.article = None
custom.save_map()
diff --git a/edit.py b/edit.py
index 8089bdb..856966f 100644
--- a/edit.py
+++ b/edit.py
@@ -42,8 +42,11 @@ class View(gtk.Notebook):
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)
+
+ if book.wiki.article:
+ TABS[index].set_source_article(book.wiki.article)
+ if book.custom.article:
+ TABS[index].set_working_article(book.custom.article)
class Toolbar(gtk.Toolbar):
def __init__(self, edit):
@@ -88,7 +91,9 @@ class Toolbar(gtk.Toolbar):
for i in TABS[index].toolitems:
i.show()
- TABS[index].set_source_article(book.wiki.article)
- TABS[index].set_working_article(book.custom.article)
+ if book.wiki.article:
+ TABS[index].set_source_article(book.wiki.article)
+ if book.custom.article:
+ TABS[index].set_working_article(book.custom.article)
self.edit.set_current_page(index)
diff --git a/Processing/demolibrary/giraffe-blank.dita b/examples/giraffe-blank.dita
index 3014c58..3014c58 100644
--- a/Processing/demolibrary/giraffe-blank.dita
+++ b/examples/giraffe-blank.dita
diff --git a/Processing/demolibrary/giraffe-wikipedia.dita b/examples/giraffe-wikipedia.dita
index ff1ba20..ff1ba20 100644
--- a/Processing/demolibrary/giraffe-wikipedia.dita
+++ b/examples/giraffe-wikipedia.dita
diff --git a/Processing/demolibrary/images/120px-Siberian-Tiger.jpg b/examples/images/120px-Siberian-Tiger.jpg
index 38c7459..38c7459 100644
--- a/Processing/demolibrary/images/120px-Siberian-Tiger.jpg
+++ b/examples/images/120px-Siberian-Tiger.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/120px-Siberischer_tiger_de_edit02.jpg b/examples/images/120px-Siberischer_tiger_de_edit02.jpg
index ba8b9ad..ba8b9ad 100644
--- a/Processing/demolibrary/images/120px-Siberischer_tiger_de_edit02.jpg
+++ b/examples/images/120px-Siberischer_tiger_de_edit02.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/120px-Tiger_cooling_off_at_Bandhavghar.jpg b/examples/images/120px-Tiger_cooling_off_at_Bandhavghar.jpg
index e5db9b5..e5db9b5 100644
--- a/Processing/demolibrary/images/120px-Tiger_cooling_off_at_Bandhavghar.jpg
+++ b/examples/images/120px-Tiger_cooling_off_at_Bandhavghar.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/120px-Vibrissae_of_a_Tiger_at_Chester_Zoo.jpg b/examples/images/120px-Vibrissae_of_a_Tiger_at_Chester_Zoo.jpg
index 59bc825..59bc825 100644
--- a/Processing/demolibrary/images/120px-Vibrissae_of_a_Tiger_at_Chester_Zoo.jpg
+++ b/examples/images/120px-Vibrissae_of_a_Tiger_at_Chester_Zoo.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/140px-GD-EG-KomOmbo016.JPG b/examples/images/140px-GD-EG-KomOmbo016.JPG
index 3ce203e..3ce203e 100644
--- a/Processing/demolibrary/images/140px-GD-EG-KomOmbo016.JPG
+++ b/examples/images/140px-GD-EG-KomOmbo016.JPG
Binary files differ
diff --git a/Processing/demolibrary/images/140px-Jerusalem-coat-of-arms.svg.png b/examples/images/140px-Jerusalem-coat-of-arms.svg.png
index 7acb7ad..7acb7ad 100644
--- a/Processing/demolibrary/images/140px-Jerusalem-coat-of-arms.svg.png
+++ b/examples/images/140px-Jerusalem-coat-of-arms.svg.png
Binary files differ
diff --git a/Processing/demolibrary/images/140px-Lion_pair2.jpg b/examples/images/140px-Lion_pair2.jpg
index 1f20c96..1f20c96 100644
--- a/Processing/demolibrary/images/140px-Lion_pair2.jpg
+++ b/examples/images/140px-Lion_pair2.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/140px-P_l_Bleyenberghi.jpg b/examples/images/140px-P_l_Bleyenberghi.jpg
index b2eda88..b2eda88 100644
--- a/Processing/demolibrary/images/140px-P_l_Bleyenberghi.jpg
+++ b/examples/images/140px-P_l_Bleyenberghi.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/150px-Climacoceras_gentryi_e.jpg b/examples/images/150px-Climacoceras_gentryi_e.jpg
index ad542d2..ad542d2 100644
--- a/Processing/demolibrary/images/150px-Climacoceras_gentryi_e.jpg
+++ b/examples/images/150px-Climacoceras_gentryi_e.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/150px-Giraffa_camelopardalis_angolensis_%28mating%29.jpg b/examples/images/150px-Giraffa_camelopardalis_angolensis_%28mating%29.jpg
index 6786bee..6786bee 100644
--- a/Processing/demolibrary/images/150px-Giraffa_camelopardalis_angolensis_%28mating%29.jpg
+++ b/examples/images/150px-Giraffa_camelopardalis_angolensis_%28mating%29.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/150px-Giraffes_IMG_9614.JPG b/examples/images/150px-Giraffes_IMG_9614.JPG
index decd5b6..decd5b6 100644
--- a/Processing/demolibrary/images/150px-Giraffes_IMG_9614.JPG
+++ b/examples/images/150px-Giraffes_IMG_9614.JPG
Binary files differ
diff --git a/Processing/demolibrary/images/150px-Kuniyoshi_Utagawa%2C_Tiger.jpg b/examples/images/150px-Kuniyoshi_Utagawa%2C_Tiger.jpg
index 9631529..9631529 100644
--- a/Processing/demolibrary/images/150px-Kuniyoshi_Utagawa%2C_Tiger.jpg
+++ b/examples/images/150px-Kuniyoshi_Utagawa%2C_Tiger.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/150px-Mare_and_foal_%28Kvetina-Marie%29.jpg b/examples/images/150px-Mare_and_foal_%28Kvetina-Marie%29.jpg
index 4b5fc4a..4b5fc4a 100644
--- a/Processing/demolibrary/images/150px-Mare_and_foal_%28Kvetina-Marie%29.jpg
+++ b/examples/images/150px-Mare_and_foal_%28Kvetina-Marie%29.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/150px-Tigergebiss.jpg b/examples/images/150px-Tigergebiss.jpg
index d9444be..d9444be 100644
--- a/Processing/demolibrary/images/150px-Tigergebiss.jpg
+++ b/examples/images/150px-Tigergebiss.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/150px-Zebra_eating.JPG b/examples/images/150px-Zebra_eating.JPG
index 3464f6f..3464f6f 100644
--- a/Processing/demolibrary/images/150px-Zebra_eating.JPG
+++ b/examples/images/150px-Zebra_eating.JPG
Binary files differ
diff --git a/Processing/demolibrary/images/150px-Zoo_UL%2C_Hartmann%27s_mountain_zebra.jpg b/examples/images/150px-Zoo_UL%2C_Hartmann%27s_mountain_zebra.jpg
index 7f835f2..7f835f2 100644
--- a/Processing/demolibrary/images/150px-Zoo_UL%2C_Hartmann%27s_mountain_zebra.jpg
+++ b/examples/images/150px-Zoo_UL%2C_Hartmann%27s_mountain_zebra.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-1990tiger.PNG b/examples/images/180px-1990tiger.PNG
index cd1f25d..cd1f25d 100644
--- a/Processing/demolibrary/images/180px-1990tiger.PNG
+++ b/examples/images/180px-1990tiger.PNG
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Asiatic.lioness.arp.jpg b/examples/images/180px-Asiatic.lioness.arp.jpg
index 3554c45..3554c45 100644
--- a/Processing/demolibrary/images/180px-Asiatic.lioness.arp.jpg
+++ b/examples/images/180px-Asiatic.lioness.arp.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Bertramliger.jpg b/examples/images/180px-Bertramliger.jpg
index d725f15..d725f15 100644
--- a/Processing/demolibrary/images/180px-Bertramliger.jpg
+++ b/examples/images/180px-Bertramliger.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Circus_Lion_Tamer.jpg b/examples/images/180px-Circus_Lion_Tamer.jpg
index f6e0ac8..f6e0ac8 100644
--- a/Processing/demolibrary/images/180px-Circus_Lion_Tamer.jpg
+++ b/examples/images/180px-Circus_Lion_Tamer.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Durer_lions_%28sketch%29.jpg b/examples/images/180px-Durer_lions_%28sketch%29.jpg
index 7b5ccc7..7b5ccc7 100644
--- a/Processing/demolibrary/images/180px-Durer_lions_%28sketch%29.jpg
+++ b/examples/images/180px-Durer_lions_%28sketch%29.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Female_Lion.JPG b/examples/images/180px-Female_Lion.JPG
index 554b29c..554b29c 100644
--- a/Processing/demolibrary/images/180px-Female_Lion.JPG
+++ b/examples/images/180px-Female_Lion.JPG
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Giraffe08_-_melbourne_zoo_edit.jpg b/examples/images/180px-Giraffe08_-_melbourne_zoo_edit.jpg
index be7f5df..be7f5df 100644
--- a/Processing/demolibrary/images/180px-Giraffe08_-_melbourne_zoo_edit.jpg
+++ b/examples/images/180px-Giraffe08_-_melbourne_zoo_edit.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-GiraffeSkelLyd2.png b/examples/images/180px-GiraffeSkelLyd2.png
index ecd3ba1..ecd3ba1 100644
--- a/Processing/demolibrary/images/180px-GiraffeSkelLyd2.png
+++ b/examples/images/180px-GiraffeSkelLyd2.png
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Giraffe_%28head%29.jpg b/examples/images/180px-Giraffe_%28head%29.jpg
index 5a8503f..5a8503f 100644
--- a/Processing/demolibrary/images/180px-Giraffe_%28head%29.jpg
+++ b/examples/images/180px-Giraffe_%28head%29.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Giraffe_Ithala_KZN_South_Africa_Luca_Galuzzi_2004.JPG b/examples/images/180px-Giraffe_Ithala_KZN_South_Africa_Luca_Galuzzi_2004.JPG
index 1b4c128..1b4c128 100644
--- a/Processing/demolibrary/images/180px-Giraffe_Ithala_KZN_South_Africa_Luca_Galuzzi_2004.JPG
+++ b/examples/images/180px-Giraffe_Ithala_KZN_South_Africa_Luca_Galuzzi_2004.JPG
Binary files differ
diff --git a/Processing/demolibrary/images/180px-HansomeLion_002.jpg b/examples/images/180px-HansomeLion_002.jpg
index 368cbc2..368cbc2 100644
--- a/Processing/demolibrary/images/180px-HansomeLion_002.jpg
+++ b/examples/images/180px-HansomeLion_002.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Lightmatter_lioness.jpg b/examples/images/180px-Lightmatter_lioness.jpg
index e98ee60..e98ee60 100644
--- a/Processing/demolibrary/images/180px-Lightmatter_lioness.jpg
+++ b/examples/images/180px-Lightmatter_lioness.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Lion_-_melbourne_zoo.jpg b/examples/images/180px-Lion_-_melbourne_zoo.jpg
index 0a50336..0a50336 100644
--- a/Processing/demolibrary/images/180px-Lion_-_melbourne_zoo.jpg
+++ b/examples/images/180px-Lion_-_melbourne_zoo.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Lion_at_zoo.jpg b/examples/images/180px-Lion_at_zoo.jpg
index 179a438..179a438 100644
--- a/Processing/demolibrary/images/180px-Lion_at_zoo.jpg
+++ b/examples/images/180px-Lion_at_zoo.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Lion_cub_with_mother.jpg b/examples/images/180px-Lion_cub_with_mother.jpg
index b0474bd..b0474bd 100644
--- a/Processing/demolibrary/images/180px-Lion_cub_with_mother.jpg
+++ b/examples/images/180px-Lion_cub_with_mother.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Lion_cubs_Serengeti.jpg b/examples/images/180px-Lion_cubs_Serengeti.jpg
index 6f24863..6f24863 100644
--- a/Processing/demolibrary/images/180px-Lion_cubs_Serengeti.jpg
+++ b/examples/images/180px-Lion_cubs_Serengeti.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Male_Lion_and_Cub_Chitwa_South_Africa_Luca_Galuzzi_2004.JPG b/examples/images/180px-Male_Lion_and_Cub_Chitwa_South_Africa_Luca_Galuzzi_2004.JPG
index 9c653dc..9c653dc 100644
--- a/Processing/demolibrary/images/180px-Male_Lion_and_Cub_Chitwa_South_Africa_Luca_Galuzzi_2004.JPG
+++ b/examples/images/180px-Male_Lion_and_Cub_Chitwa_South_Africa_Luca_Galuzzi_2004.JPG
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Maneating_lion.jpg b/examples/images/180px-Maneating_lion.jpg
index 272fa19..272fa19 100644
--- a/Processing/demolibrary/images/180px-Maneating_lion.jpg
+++ b/examples/images/180px-Maneating_lion.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Maneless_lion_from_Tsavo_East_National_Park.png b/examples/images/180px-Maneless_lion_from_Tsavo_East_National_Park.png
index e9f8017..e9f8017 100644
--- a/Processing/demolibrary/images/180px-Maneless_lion_from_Tsavo_East_National_Park.png
+++ b/examples/images/180px-Maneless_lion_from_Tsavo_East_National_Park.png
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Map_Guj_Nat_Parks_Sanctuary.png b/examples/images/180px-Map_Guj_Nat_Parks_Sanctuary.png
index eb58c04..eb58c04 100644
--- a/Processing/demolibrary/images/180px-Map_Guj_Nat_Parks_Sanctuary.png
+++ b/examples/images/180px-Map_Guj_Nat_Parks_Sanctuary.png
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Matha.png b/examples/images/180px-Matha.png
index 2bab22d..2bab22d 100644
--- a/Processing/demolibrary/images/180px-Matha.png
+++ b/examples/images/180px-Matha.png
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Panthera_leo_Kruger_Skull.jpg b/examples/images/180px-Panthera_leo_Kruger_Skull.jpg
index d82237b..d82237b 100644
--- a/Processing/demolibrary/images/180px-Panthera_leo_Kruger_Skull.jpg
+++ b/examples/images/180px-Panthera_leo_Kruger_Skull.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Panthera_tigris_amoyensis.jpg b/examples/images/180px-Panthera_tigris_amoyensis.jpg
index b549171..b549171 100644
--- a/Processing/demolibrary/images/180px-Panthera_tigris_amoyensis.jpg
+++ b/examples/images/180px-Panthera_tigris_amoyensis.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Panthera_tigris_balica.jpg b/examples/images/180px-Panthera_tigris_balica.jpg
index d58bcdb..d58bcdb 100644
--- a/Processing/demolibrary/images/180px-Panthera_tigris_balica.jpg
+++ b/examples/images/180px-Panthera_tigris_balica.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Panthera_tigris_sondaica_01.jpg b/examples/images/180px-Panthera_tigris_sondaica_01.jpg
index 229a2e3..229a2e3 100644
--- a/Processing/demolibrary/images/180px-Panthera_tigris_sondaica_01.jpg
+++ b/examples/images/180px-Panthera_tigris_sondaica_01.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Panthera_tigris_sumatran_subspecies.jpg b/examples/images/180px-Panthera_tigris_sumatran_subspecies.jpg
index 8b4cfcf..8b4cfcf 100644
--- a/Processing/demolibrary/images/180px-Panthera_tigris_sumatran_subspecies.jpg
+++ b/examples/images/180px-Panthera_tigris_sumatran_subspecies.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Panthera_tigris_virgata.jpg b/examples/images/180px-Panthera_tigris_virgata.jpg
index 79c42ed..79c42ed 100644
--- a/Processing/demolibrary/images/180px-Panthera_tigris_virgata.jpg
+++ b/examples/images/180px-Panthera_tigris_virgata.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-PregnantLioness.jpg b/examples/images/180px-PregnantLioness.jpg
index f0b5ac1..f0b5ac1 100644
--- a/Processing/demolibrary/images/180px-PregnantLioness.jpg
+++ b/examples/images/180px-PregnantLioness.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Royal_Arms_of_Scotland.svg.png b/examples/images/180px-Royal_Arms_of_Scotland.svg.png
index 5f48733..5f48733 100644
--- a/Processing/demolibrary/images/180px-Royal_Arms_of_Scotland.svg.png
+++ b/examples/images/180px-Royal_Arms_of_Scotland.svg.png
Binary files differ
diff --git a/Processing/demolibrary/images/180px-ShenDuGiraffePainting.jpg b/examples/images/180px-ShenDuGiraffePainting.jpg
index eefd92c..eefd92c 100644
--- a/Processing/demolibrary/images/180px-ShenDuGiraffePainting.jpg
+++ b/examples/images/180px-ShenDuGiraffePainting.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Status_iucn2.3_CD.svg.png b/examples/images/180px-Status_iucn2.3_CD.svg.png
index 78f21bf..78f21bf 100644
--- a/Processing/demolibrary/images/180px-Status_iucn2.3_CD.svg.png
+++ b/examples/images/180px-Status_iucn2.3_CD.svg.png
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Status_iucn2.3_EN.svg.png b/examples/images/180px-Status_iucn2.3_EN.svg.png
index 1c3b4da..1c3b4da 100644
--- a/Processing/demolibrary/images/180px-Status_iucn2.3_EN.svg.png
+++ b/examples/images/180px-Status_iucn2.3_EN.svg.png
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Status_iucn3.1_VU.svg.png b/examples/images/180px-Status_iucn3.1_VU.svg.png
index eee9fbf..eee9fbf 100644
--- a/Processing/demolibrary/images/180px-Status_iucn3.1_VU.svg.png
+++ b/examples/images/180px-Status_iucn3.1_VU.svg.png
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Tiger_032.jpg b/examples/images/180px-Tiger_032.jpg
index d1418a4..d1418a4 100644
--- a/Processing/demolibrary/images/180px-Tiger_032.jpg
+++ b/examples/images/180px-Tiger_032.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Tiger_Bandavgarh_adjusted_levels.jpg b/examples/images/180px-Tiger_Bandavgarh_adjusted_levels.jpg
index 6cdde7d..6cdde7d 100644
--- a/Processing/demolibrary/images/180px-Tiger_Bandavgarh_adjusted_levels.jpg
+++ b/examples/images/180px-Tiger_Bandavgarh_adjusted_levels.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Tiger_in_the_snow_at_the_Detroit_Zoo_March_2008_pic_2.jpg b/examples/images/180px-Tiger_in_the_snow_at_the_Detroit_Zoo_March_2008_pic_2.jpg
index 3ef7b7f..3ef7b7f 100644
--- a/Processing/demolibrary/images/180px-Tiger_in_the_snow_at_the_Detroit_Zoo_March_2008_pic_2.jpg
+++ b/examples/images/180px-Tiger_in_the_snow_at_the_Detroit_Zoo_March_2008_pic_2.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Tiger_in_the_water.jpg b/examples/images/180px-Tiger_in_the_water.jpg
index fad050a..fad050a 100644
--- a/Processing/demolibrary/images/180px-Tiger_in_the_water.jpg
+++ b/examples/images/180px-Tiger_in_the_water.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Tigress-Jowlagiri.jpg b/examples/images/180px-Tigress-Jowlagiri.jpg
index 333901f..333901f 100644
--- a/Processing/demolibrary/images/180px-Tigress-Jowlagiri.jpg
+++ b/examples/images/180px-Tigress-Jowlagiri.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-White_Lion.jpg b/examples/images/180px-White_Lion.jpg
index e5643ec..e5643ec 100644
--- a/Processing/demolibrary/images/180px-White_Lion.jpg
+++ b/examples/images/180px-White_Lion.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/180px-Zebra_Dallas_Zoo_1974.jpg b/examples/images/180px-Zebra_Dallas_Zoo_1974.jpg
index 998db2b..998db2b 100644
--- a/Processing/demolibrary/images/180px-Zebra_Dallas_Zoo_1974.jpg
+++ b/examples/images/180px-Zebra_Dallas_Zoo_1974.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/200px-Lions_and_a_Zebra_a.jpg b/examples/images/200px-Lions_and_a_Zebra_a.jpg
index 28a2cda..28a2cda 100644
--- a/Processing/demolibrary/images/200px-Lions_and_a_Zebra_a.jpg
+++ b/examples/images/200px-Lions_and_a_Zebra_a.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/200px-Zebra-tame-jumping.jpg b/examples/images/200px-Zebra-tame-jumping.jpg
index 763d6f5..763d6f5 100644
--- a/Processing/demolibrary/images/200px-Zebra-tame-jumping.jpg
+++ b/examples/images/200px-Zebra-tame-jumping.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/200px-Zebra2.jpg b/examples/images/200px-Zebra2.jpg
index 9391c1d..9391c1d 100644
--- a/Processing/demolibrary/images/200px-Zebra2.jpg
+++ b/examples/images/200px-Zebra2.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/200px-Zebra_Botswana_edit02.jpg b/examples/images/200px-Zebra_Botswana_edit02.jpg
index 9659609..9659609 100644
--- a/Processing/demolibrary/images/200px-Zebra_Botswana_edit02.jpg
+++ b/examples/images/200px-Zebra_Botswana_edit02.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/200px-Zebra_rownikowa_Equus_burchelli_boehmi_RB3.jpg b/examples/images/200px-Zebra_rownikowa_Equus_burchelli_boehmi_RB3.jpg
index 9b4635f..9b4635f 100644
--- a/Processing/demolibrary/images/200px-Zebra_rownikowa_Equus_burchelli_boehmi_RB3.jpg
+++ b/examples/images/200px-Zebra_rownikowa_Equus_burchelli_boehmi_RB3.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/220px-Tiger_distribution3.PNG b/examples/images/220px-Tiger_distribution3.PNG
index c127055..c127055 100644
--- a/Processing/demolibrary/images/220px-Tiger_distribution3.PNG
+++ b/examples/images/220px-Tiger_distribution3.PNG
Binary files differ
diff --git a/Processing/demolibrary/images/225px-Una-lion.jpg b/examples/images/225px-Una-lion.jpg
index 43538a0..43538a0 100644
--- a/Processing/demolibrary/images/225px-Una-lion.jpg
+++ b/examples/images/225px-Una-lion.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/230px-037tiger.jpg b/examples/images/230px-037tiger.jpg
index 6ca077e..6ca077e 100644
--- a/Processing/demolibrary/images/230px-037tiger.jpg
+++ b/examples/images/230px-037tiger.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/230px-Giraffa_camelopardalis_subspecies_map.jpg b/examples/images/230px-Giraffa_camelopardalis_subspecies_map.jpg
index a603eb1..a603eb1 100644
--- a/Processing/demolibrary/images/230px-Giraffa_camelopardalis_subspecies_map.jpg
+++ b/examples/images/230px-Giraffa_camelopardalis_subspecies_map.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/230px-Giraffe_standing.jpg b/examples/images/230px-Giraffe_standing.jpg
index 53ca8e4..53ca8e4 100644
--- a/Processing/demolibrary/images/230px-Giraffe_standing.jpg
+++ b/examples/images/230px-Giraffe_standing.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/230px-Golden_tiger_1_-_Buffalo_Zoo.jpg b/examples/images/230px-Golden_tiger_1_-_Buffalo_Zoo.jpg
index 6f4e63a..6f4e63a 100644
--- a/Processing/demolibrary/images/230px-Golden_tiger_1_-_Buffalo_Zoo.jpg
+++ b/examples/images/230px-Golden_tiger_1_-_Buffalo_Zoo.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/230px-Singapore_Zoo_Tigers.jpg b/examples/images/230px-Singapore_Zoo_Tigers.jpg
index 55ec159..55ec159 100644
--- a/Processing/demolibrary/images/230px-Singapore_Zoo_Tigers.jpg
+++ b/examples/images/230px-Singapore_Zoo_Tigers.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/230px-TigerSkelLyd1.png b/examples/images/230px-TigerSkelLyd1.png
index b80671f..b80671f 100644
--- a/Processing/demolibrary/images/230px-TigerSkelLyd1.png
+++ b/examples/images/230px-TigerSkelLyd1.png
Binary files differ
diff --git a/Processing/demolibrary/images/240px-7_lions.jpg b/examples/images/240px-7_lions.jpg
index 380ce53..380ce53 100644
--- a/Processing/demolibrary/images/240px-7_lions.jpg
+++ b/examples/images/240px-7_lions.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/240px-ElephantbackTigerHunt.jpg b/examples/images/240px-ElephantbackTigerHunt.jpg
index 21dea46..21dea46 100644
--- a/Processing/demolibrary/images/240px-ElephantbackTigerHunt.jpg
+++ b/examples/images/240px-ElephantbackTigerHunt.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/240px-Flag_of_Sri_Lanka.svg.png b/examples/images/240px-Flag_of_Sri_Lanka.svg.png
index 15a3428..15a3428 100644
--- a/Processing/demolibrary/images/240px-Flag_of_Sri_Lanka.svg.png
+++ b/examples/images/240px-Flag_of_Sri_Lanka.svg.png
Binary files differ
diff --git a/Processing/demolibrary/images/240px-Stud_327_with_Blesbuck.jpg b/examples/images/240px-Stud_327_with_Blesbuck.jpg
index b1cc57c..b1cc57c 100644
--- a/Processing/demolibrary/images/240px-Stud_327_with_Blesbuck.jpg
+++ b/examples/images/240px-Stud_327_with_Blesbuck.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/240px-TigerSkinning.jpg b/examples/images/240px-TigerSkinning.jpg
index 38b8bad..38b8bad 100644
--- a/Processing/demolibrary/images/240px-TigerSkinning.jpg
+++ b/examples/images/240px-TigerSkinning.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/250px-Beautiful_Zebra_in_South_Africa.JPG b/examples/images/250px-Beautiful_Zebra_in_South_Africa.JPG
index 2bf7caa..2bf7caa 100644
--- a/Processing/demolibrary/images/250px-Beautiful_Zebra_in_South_Africa.JPG
+++ b/examples/images/250px-Beautiful_Zebra_in_South_Africa.JPG
Binary files differ
diff --git a/Processing/demolibrary/images/250px-Equus_grevyi_in_Kenya_%28male%29.jpg b/examples/images/250px-Equus_grevyi_in_Kenya_%28male%29.jpg
index 5326a3a..5326a3a 100644
--- a/Processing/demolibrary/images/250px-Equus_grevyi_in_Kenya_%28male%29.jpg
+++ b/examples/images/250px-Equus_grevyi_in_Kenya_%28male%29.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/250px-LAzooZebra.jpg b/examples/images/250px-LAzooZebra.jpg
index 74f6444..74f6444 100644
--- a/Processing/demolibrary/images/250px-LAzooZebra.jpg
+++ b/examples/images/250px-LAzooZebra.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/250px-Lion_distribution.svg.png b/examples/images/250px-Lion_distribution.svg.png
index ac049dd..ac049dd 100644
--- a/Processing/demolibrary/images/250px-Lion_distribution.svg.png
+++ b/examples/images/250px-Lion_distribution.svg.png
Binary files differ
diff --git a/Processing/demolibrary/images/250px-Lion_in_Ngorongoro_Crater%2C_Tanzania.jpg b/examples/images/250px-Lion_in_Ngorongoro_Crater%2C_Tanzania.jpg
index bd41836..bd41836 100644
--- a/Processing/demolibrary/images/250px-Lion_in_Ngorongoro_Crater%2C_Tanzania.jpg
+++ b/examples/images/250px-Lion_in_Ngorongoro_Crater%2C_Tanzania.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/250px-Lion_in_masai_mara.jpg b/examples/images/250px-Lion_in_masai_mara.jpg
index 0bf38af..0bf38af 100644
--- a/Processing/demolibrary/images/250px-Lion_in_masai_mara.jpg
+++ b/examples/images/250px-Lion_in_masai_mara.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/250px-Lionesses%2C_Masai_Mara%2C_Kenya.jpg b/examples/images/250px-Lionesses%2C_Masai_Mara%2C_Kenya.jpg
index a850cde..a850cde 100644
--- a/Processing/demolibrary/images/250px-Lionesses%2C_Masai_Mara%2C_Kenya.jpg
+++ b/examples/images/250px-Lionesses%2C_Masai_Mara%2C_Kenya.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/250px-Map_Guj_Nat_Parks_Sanctuary.png b/examples/images/250px-Map_Guj_Nat_Parks_Sanctuary.png
index 0482d8e..0482d8e 100644
--- a/Processing/demolibrary/images/250px-Map_Guj_Nat_Parks_Sanctuary.png
+++ b/examples/images/250px-Map_Guj_Nat_Parks_Sanctuary.png
Binary files differ
diff --git a/Processing/demolibrary/images/250px-Mycenae_lion_gate_detail_dsc06384.jpg b/examples/images/250px-Mycenae_lion_gate_detail_dsc06384.jpg
index 5978b1d..5978b1d 100644
--- a/Processing/demolibrary/images/250px-Mycenae_lion_gate_detail_dsc06384.jpg
+++ b/examples/images/250px-Mycenae_lion_gate_detail_dsc06384.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/250px-Pride_of_lions.JPG b/examples/images/250px-Pride_of_lions.JPG
index e99ee11..e99ee11 100644
--- a/Processing/demolibrary/images/250px-Pride_of_lions.JPG
+++ b/examples/images/250px-Pride_of_lions.JPG
Binary files differ
diff --git a/Processing/demolibrary/images/250px-Serengeti_Lion_Running_saturated.jpg b/examples/images/250px-Serengeti_Lion_Running_saturated.jpg
index 0f8ce9b..0f8ce9b 100644
--- a/Processing/demolibrary/images/250px-Serengeti_Lion_Running_saturated.jpg
+++ b/examples/images/250px-Serengeti_Lion_Running_saturated.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/250px-Siberian_Tiger_sf.jpg b/examples/images/250px-Siberian_Tiger_sf.jpg
index e58eebc..e58eebc 100644
--- a/Processing/demolibrary/images/250px-Siberian_Tiger_sf.jpg
+++ b/examples/images/250px-Siberian_Tiger_sf.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/250px-Tanzanian_Animals.jpg b/examples/images/250px-Tanzanian_Animals.jpg
index d176247..d176247 100644
--- a/Processing/demolibrary/images/250px-Tanzanian_Animals.jpg
+++ b/examples/images/250px-Tanzanian_Animals.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/250px-Tiger_map.jpg b/examples/images/250px-Tiger_map.jpg
index f91c25e..f91c25e 100644
--- a/Processing/demolibrary/images/250px-Tiger_map.jpg
+++ b/examples/images/250px-Tiger_map.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/250px-Tigerramki.jpg b/examples/images/250px-Tigerramki.jpg
index c220611..c220611 100644
--- a/Processing/demolibrary/images/250px-Tigerramki.jpg
+++ b/examples/images/250px-Tigerramki.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/250px-Tipu_Sultan%27s_Tiger.JPG b/examples/images/250px-Tipu_Sultan%27s_Tiger.JPG
index 18c42d1..18c42d1 100644
--- a/Processing/demolibrary/images/250px-Tipu_Sultan%27s_Tiger.JPG
+++ b/examples/images/250px-Tipu_Sultan%27s_Tiger.JPG
Binary files differ
diff --git a/Processing/demolibrary/images/250px-WalterRothschildWithZebras.jpg b/examples/images/250px-WalterRothschildWithZebras.jpg
index 302dddb..302dddb 100644
--- a/Processing/demolibrary/images/250px-WalterRothschildWithZebras.jpg
+++ b/examples/images/250px-WalterRothschildWithZebras.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/250px-Wiki_lion.jpg b/examples/images/250px-Wiki_lion.jpg
index 3f0b106..3f0b106 100644
--- a/Processing/demolibrary/images/250px-Wiki_lion.jpg
+++ b/examples/images/250px-Wiki_lion.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/250px-Wildlifephotography.jpg b/examples/images/250px-Wildlifephotography.jpg
index 6d1c072..6d1c072 100644
--- a/Processing/demolibrary/images/250px-Wildlifephotography.jpg
+++ b/examples/images/250px-Wildlifephotography.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/300px-Lascaux-diverticule-f%C3%A9lins.jpg b/examples/images/300px-Lascaux-diverticule-f%C3%A9lins.jpg
index 78bba60..78bba60 100644
--- a/Processing/demolibrary/images/300px-Lascaux-diverticule-f%C3%A9lins.jpg
+++ b/examples/images/300px-Lascaux-diverticule-f%C3%A9lins.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/300px-Namibie_Etosha_Girafe_01.jpg b/examples/images/300px-Namibie_Etosha_Girafe_01.jpg
index 3cb11b1..3cb11b1 100644
--- a/Processing/demolibrary/images/300px-Namibie_Etosha_Girafe_01.jpg
+++ b/examples/images/300px-Namibie_Etosha_Girafe_01.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/80px-India_tiger.jpg b/examples/images/80px-India_tiger.jpg
index f671bb5..f671bb5 100644
--- a/Processing/demolibrary/images/80px-India_tiger.jpg
+++ b/examples/images/80px-India_tiger.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/83px-Indischer_Maler_um_1650_%28II%29_001.jpg b/examples/images/83px-Indischer_Maler_um_1650_%28II%29_001.jpg
index f3a89b2..f3a89b2 100644
--- a/Processing/demolibrary/images/83px-Indischer_Maler_um_1650_%28II%29_001.jpg
+++ b/examples/images/83px-Indischer_Maler_um_1650_%28II%29_001.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/84px-Brehms_Het_Leven_der_Dieren_Zoogdieren_Orde_4_Tijger_%28Felis_tigris%29.jpg b/examples/images/84px-Brehms_Het_Leven_der_Dieren_Zoogdieren_Orde_4_Tijger_%28Felis_tigris%29.jpg
index 51e06f3..51e06f3 100644
--- a/Processing/demolibrary/images/84px-Brehms_Het_Leven_der_Dieren_Zoogdieren_Orde_4_Tijger_%28Felis_tigris%29.jpg
+++ b/examples/images/84px-Brehms_Het_Leven_der_Dieren_Zoogdieren_Orde_4_Tijger_%28Felis_tigris%29.jpg
Binary files differ
diff --git a/Processing/demolibrary/images/97px-Sumatratiger-004.jpg b/examples/images/97px-Sumatratiger-004.jpg
index 43a5c02..43a5c02 100644
--- a/Processing/demolibrary/images/97px-Sumatratiger-004.jpg
+++ b/examples/images/97px-Sumatratiger-004.jpg
Binary files differ
diff --git a/Processing/demolibrary/lion-wikipedia.dita b/examples/lion-wikipedia.dita
index f7b73ff..f7b73ff 100644
--- a/Processing/demolibrary/lion-wikipedia.dita
+++ b/examples/lion-wikipedia.dita
diff --git a/Processing/demolibrary/tiger-wikipedia.dita b/examples/tiger-wikipedia.dita
index 9f59b18..9f59b18 100644
--- a/Processing/demolibrary/tiger-wikipedia.dita
+++ b/examples/tiger-wikipedia.dita
diff --git a/Processing/demolibrary/zebra-wikipedia.dita b/examples/zebra-wikipedia.dita
index d9af33c..d9af33c 100644
--- a/Processing/demolibrary/zebra-wikipedia.dita
+++ b/examples/zebra-wikipedia.dita
diff --git a/icons/white-search.svg b/icons/white-search.svg
new file mode 100644
index 0000000..a060b47
--- /dev/null
+++ b/icons/white-search.svg
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ id="Layer_1"
+ x="0px"
+ y="0px"
+ width="22.156px"
+ height="22.156px"
+ viewBox="0 0 22.156 22.156"
+ enable-background="new 0 0 22.156 22.156"
+ xml:space="preserve"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docname="white-search.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
+ id="metadata12"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs10"><inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 11.078 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="22.156 : 11.078 : 1"
+ inkscape:persp3d-origin="11.078 : 7.3853334 : 1"
+ id="perspective14" /></defs><sodipodi:namedview
+ inkscape:window-height="719"
+ inkscape:window-width="1278"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ showgrid="false"
+ inkscape:zoom="20.852139"
+ inkscape:cx="2.6855758"
+ inkscape:cy="11.078"
+ inkscape:window-x="0"
+ inkscape:window-y="48"
+ inkscape:current-layer="g3" />
+<g
+ id="g3">
+ <path
+ fill="none"
+ stroke="#4C4D4F"
+ stroke-width="3.5"
+ d="M1.75,9.216c0,4.125,3.342,7.47,7.468,7.47 c4.121,0,7.466-3.345,7.466-7.47c0-4.123-3.345-7.466-7.466-7.466C5.092,1.75,1.75,5.093,1.75,9.216z"
+ id="path5"
+ style="stroke:#ffffff;stroke-opacity:1" />
+ <line
+ fill="none"
+ stroke="#4C4D4F"
+ stroke-width="3.5"
+ x1="14.498"
+ y1="14.497"
+ x2="20.918"
+ y2="20.919"
+ id="line7"
+ style="stroke:#ffffff;stroke-opacity:1" />
+</g>
+</svg> \ No newline at end of file
diff --git a/library.py b/library.py
index fea1f56..37be603 100644
--- a/library.py
+++ b/library.py
@@ -13,120 +13,168 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import gtk
+from threading import Timer
from gettext import gettext as _
from sugar.graphics.toolbutton import ToolButton
from sugar.graphics.toggletoolbutton import ToggleToolButton
from sugar.activity.activity import ActivityToolbox
from sugar.graphics.toolcombobox import ToolComboBox
+from sugar.graphics.icon import Icon
+import sugar.graphics.style as style
-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
+import net
-class View(gtk.EventBox): #Library_View):
- def __init__(self):
+class View(gtk.EventBox):
+ def sync(self):
+ self.wiki.sync()
+ self.custom.sync()
+
+ def __init__(self, set_edit_sensitive):
gtk.EventBox.__init__(self)
+ self._set_edit_sensitive = set_edit_sensitive
+
+ # books
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)
+ self.wiki = BookView(book.wiki,
+ _('Wiki'), _('Wiki articles'), False)
+ books.pack_start(self.wiki)
+ self.custom = BookView(book.custom,
+ _('Custom'), _('Custom articles'), True)
+ books.pack_start(self.custom)
+
+ # stubs for empty articles
+
+ def create_stub(icon_name, head_text, tail_text):
+ head_label = gtk.Label(head_text)
+ head_label_a = gtk.Alignment(0.5, 1, 0, 0)
+ head_label_a.add(head_label)
+ icon = Icon(icon_name=icon_name,
+ icon_size=gtk.ICON_SIZE_LARGE_TOOLBAR)
+ tail_label = gtk.Label(tail_text)
+ tail_label_a = gtk.Alignment(0.5, 0, 0, 0)
+ tail_label_a.add(tail_label)
+ stub = gtk.VBox()
+ stub.pack_start(head_label_a)
+ stub.pack_start(icon, False)
+ stub.pack_start(tail_label_a)
+ return stub
+
+ wiki_stub = create_stub('white-search',
+ _('To download Wiki article\ntype "Article name" and click'),
+ _('button on top "Library" panel'))
+ custom_stub = create_stub('add',
+ _('To create custom article click'),
+ _('button on left "Custom" panel'))
+
+ # articles viewers
+
+ wiki_widget = Reading_View()
+ wiki = gtk.Notebook()
+ wiki.props.show_border = False
+ wiki.props.show_tabs = False
+ wiki.append_page(wiki_widget)
+ wiki.append_page(wiki_stub)
+
+ custom_widget = Reading_View()
+ custom = gtk.Notebook()
+ custom.props.show_border = False
+ custom.props.show_tabs = False
+ custom.append_page(custom_widget)
+ custom.append_page(custom_stub)
+ custom.set_size_request(gtk.gdk.screen_width()/4*3/2, -1)
+
+ # workspace
articles = gtk.HBox()
- articles.pack_start(self.wiki_arcticle)
- articles.pack_start(self.custom_arcticle, False)
-
- desktop = gtk.HBox()
- 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)
-
- """
-
- def get_source_article(self):
- return self.librarypanel.get_source()
-
- def set_source_article(self, article):
- self.librarypanel.set_source(article)
-
- def get_working_article(self):
- return self.librarypanel.get_working()
-
- def set_working_article(self, article):
- self.librarypanel.set_working(article)
-
-
- # Set up dummy library if appropriate
- IO_Manager().install_library()
-
- themes = IO_Manager().get_themes()
- if "Wikipedia Articles" in themes:
- i = themes.index("Wikipedia Articles")
- del themes[i]
-
- wikiarticles = IO_Manager().get_pages_in_theme("Wikipedia Articles")
- for theme in themes:
- articles = IO_Manager().get_pages_in_theme(theme)
- for article in articles:
- if ignore == True:
- break
- for wikiarticle in wikiarticles:
- if article in wikiarticle:
- self.source = IO_Manager().load_article(wikiarticle, "Wikipedia Articles")
- self.working = IO_Manager().load_article(article, theme)
- logger.debug("loading source %s from %s" %
- (wikiarticle, "Wikipedia Articles"))
- logger.debug("loading edit %s from %s" %
- (article, theme))
- ignore = True
- """
+ articles.pack_start(wiki)
+ articles.pack_start(gtk.VSeparator(), False)
+ articles.pack_start(custom, False)
+
+ self.progress = gtk.Label()
+ self.progress.set_size_request(-1, style.SMALL_ICON_SIZE+4)
+ progress_box = gtk.VBox()
+ progress_box.pack_start(articles)
+ progress_box.pack_start(gtk.HSeparator(), False)
+ progress_box.pack_start(self.progress, False)
+
+ workspace = gtk.HBox()
+ workspace.pack_start(books, False)
+ workspace.pack_start(gtk.VSeparator(), False)
+ workspace.pack_start(progress_box)
+ workspace.show_all()
+
+ self.add(workspace)
+
+ # init components
+
+ book.wiki.connect('article-selected', self._article_selected_cb,
+ wiki, wiki_widget)
+ book.wiki.connect('article-deleted', self._article_deleted_cb, wiki)
+ book.custom.connect('article-selected', self._article_selected_cb,
+ custom, custom_widget)
+ book.custom.connect('article-deleted', self._article_deleted_cb, custom)
+
+ self._edit_sensitive = 0
+ self._set_edit_sensitive(False)
+
+ if not book.wiki.article:
+ wiki.set_current_page(1)
+ else:
+ self._article_selected_cb(None, book.wiki.article,
+ wiki, wiki_widget)
+
+ if not book.custom.article:
+ custom.set_current_page(1)
+ else:
+ self._article_selected_cb(None, book.custom.article,
+ custom, custom_widget)
+
+ def _article_selected_cb(self, book, article, notebook, article_widget):
+ notebook.set_current_page(0)
+ article_widget.textbox.set_article(article)
+
+ self._edit_sensitive += 1
+ if self._edit_sensitive == 2:
+ self._set_edit_sensitive(True)
+
+ def _article_deleted_cb(self, abook, article, notebook):
+ if abook.map:
+ return
+ notebook.set_current_page(1)
+ self._edit_sensitive -= 1
+ self._set_edit_sensitive(False)
class Toolbar(gtk.Toolbar):
def __init__(self, library):
gtk.Toolbar.__init__(self)
self.library = library
- return
- wikimenu = ToolComboBox(label_text=_('Get article from:'))
- wikimenu.combo.connect('changed', self._wikimenu_changed_cb)
+ self.wikimenu = ToolComboBox(label_text=_('Get article from:'))
for i in sorted(WIKI.keys()):
- wikimenu.combo.append_item(WIKI[i], i)
- self.insert(wikimenu, -1)
- wikimenu.show()
-
- searchentry = gtk.Entry()
- searchentry.set_size_request(int(gtk.gdk.screen_width() / 4), -1)
- searchentry.set_text(_("Article name"))
- searchentry.connect('changed', self._search_activate_cb)
- searchentry_item = WidgetItem(searchentry)
+ self.wikimenu.combo.append_item(WIKI[i], i)
+ self.wikimenu.combo.set_active(0)
+ self.insert(self.wikimenu, -1)
+ self.wikimenu.show()
+
+ self.searchentry = gtk.Entry()
+ self.searchentry.set_size_request(int(gtk.gdk.screen_width() / 4), -1)
+ self.searchentry.set_text(_("Article name"))
+ self.searchentry.select_region(0, -1)
+ self.searchentry.connect('activate', self._search_activate_cb)
+ searchentry_item = WidgetItem(self.searchentry)
self.insert(searchentry_item, -1)
searchentry_item.show()
- self.searchbutton = ToolButton('search', tooltip=_('Find article'))
- self.searchbutton.connect("clicked", self.library.commence_retrieval,
- searchentry, self.library.statusbar, wikimenu, WIKI)
+ self.searchbutton = ToolButton('white-search',
+ tooltip=_('Find article'))
+ self.searchbutton.connect('clicked', self._search_clicked_cb)
self.insert(self.searchbutton, -1)
self.searchbutton.show()
@@ -134,39 +182,41 @@ class Toolbar(gtk.Toolbar):
self.insert(separator, -1)
separator.show()
- new = ToolButton('add', tooltip=_('New article'))
- new.connect("clicked", self._new_clicked_cb)
- self.insert(new, -1)
- new.show()
-
- erase = ToolButton('edit-delete', tooltip=_('Delete selected articles'))
- erase.connect("clicked", self._erase_clicked_cb)
- self.insert(erase, -1)
- erase.show()
-
- separator = gtk.SeparatorToolItem()
- self.insert(separator, -1)
- separator.show()
-
publish = ToolButton('filesave', tooltip=_('Publish selected articles'))
publish.connect("clicked", self._publish_clicked_cb)
self.insert(publish, -1)
publish.show()
- def _publish_clicked_cb(self):
- pass
+ self.connect('map', self._map_cb)
- def _erase_clicked_cb(self):
- pass
+ def _map_cb(self, widget):
+ self.searchentry.grab_focus()
- def _new_clicked_cb(self):
+ def _publish_clicked_cb(self):
pass
def _search_activate_cb(self, widget):
self.searchbutton.emit("clicked")
- def _wikimenu_changed_cb(self, widget, data):
- self.searchbutton.emit("clicked")
+ def _search_clicked_cb(self, widget):
+ title = self.searchentry.get_text()
+ wiki = self.wikimenu.combo.props.value
+
+ if not title:
+ return
+
+ if book.wiki.find('%s (from %s)' % (title, wiki))[0]:
+ self.library.progress.set_label(_('"%s" article already exists') % title)
+ Timer(10, self._clear_progress).start()
+ else:
+ Timer(0, self._download, [title, wiki]).start()
+
+ def _download(self, title, wiki):
+ net.download_wiki_article(title, wiki, self.library.progress)
+ Timer(10, self._clear_progress).start()
+
+ def _clear_progress(self):
+ self.library.progress.set_label('')
WIKI = { _("English Wikipedia") : "en.wikipedia.org",
_("Simple English Wikipedia") : "simple.wikipedia.org",
diff --git a/net.py b/net.py
new file mode 100644
index 0000000..8f43009
--- /dev/null
+++ b/net.py
@@ -0,0 +1,138 @@
+# 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 shutil
+import urllib
+import logging
+from gettext import gettext as _
+
+from sugar.activity.activity import get_bundle_path
+
+import book
+from Processing.NewtifulSoup import NewtifulStoneSoup as BeautifulStoneSoup
+from Processing.MediaWiki_Parser import MediaWiki_Parser
+from Processing.MediaWiki_Helper import MediaWiki_Helper, PageNotFoundError
+
+logger = logging.getLogger('infoslicer')
+elogger = logging.getLogger('infoslicer::except')
+
+proxies = None
+
+def download_wiki_article(title, wiki, progress):
+ try:
+ progress.set_label(_('"%s" download in progress...') % title)
+ article, url = MediaWiki_Helper().getArticleAsHTMLByTitle(title, wiki)
+
+ progress.set_label(_('Processing "%s"...') % title)
+ parser = MediaWiki_Parser(article, title, url)
+ contents = parser.parse()
+
+ progress.set_label(_('Downloading "%s" images...') % title)
+ book.wiki.create(title + _(' (from %s)') % wiki, contents)
+
+ progress.set_label(_('"%s" successfully downloaded') % title)
+
+ except PageNotFoundError, e:
+ elogger.debug('download_and_add: %s' % e)
+ progress.set_label(_('"%s" could not be found') % title)
+
+ except Exception, e:
+ elogger.debug('download_and_add: %s' % e)
+ progress.set_label(_('Error downloading "%s"; check your connection') % title)
+
+def image_handler(root, uid, document):
+ """
+ Takes a DITA article and downloads images referenced in it
+ (finding all <image> tags).
+ Attemps to fix incomplete paths using source url.
+ @param document: DITA to work on
+ @return: The document with image tags adjusted to point to local paths
+ """
+ document = BeautifulStoneSoup(document)
+ dir_path = os.path.join(root, uid, "images")
+
+ logger.debug('image_handler: %s' % dir_path)
+
+ if not os.path.exists(dir_path):
+ os.makedirs(dir_path, 0777)
+
+ for image in document.findAll("image"):
+ fail = False
+ path = image['href']
+ if "#DEMOLIBRARY#" in path:
+ path = path.replace("#DEMOLIBRARY#",
+ os.path.join(get_bundle_path(), 'examples'))
+ image_title = os.path.split(path)[1]
+ shutil.copyfile(path, os.path.join(dir_path, image_title))
+ else:
+ image_title = path.rsplit("/", 1)[-1]
+ # attempt to fix incomplete paths
+ if (not path.startswith("http://")) and document.source != None and document.source.has_key("href"):
+ if path.startswith("/"):
+ path = document.source['href'].rsplit("/", 1)[0] + path
+ else:
+ path = document.source['href'].rsplit("/", 1)[0] + "/" + path
+ logger.debug("Retrieving image: " + path)
+ file = open(os.path.join(dir_path, image_title), 'wb')
+ image_contents = _open_url(path)
+ if image_contents == None:
+ fail = True
+ else:
+ file.write(image_contents)
+ file.close()
+ #change to relative paths:
+ if not fail:
+ image['href'] = os.path.join(dir_path.replace(os.path.join(root, ""), "", 1), image_title)
+ else:
+ image.extract()
+
+ return document.prettify()
+
+def _open_url(url):
+ """
+ retrieves content from specified url
+ """
+ urllib._urlopener = _new_url_opener()
+ try:
+ logger.debug("opening " + url)
+ logger.debug("proxies: " + str(proxies))
+ doc = urllib.urlopen(url, proxies=proxies)
+ output = doc.read()
+ doc.close()
+ logger.debug("url opened succesfully")
+ return output
+ except IOError, e:
+ elogger.debug('_open_url: %s' % e)
+
+class _new_url_opener(urllib.FancyURLopener):
+ version = "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1b2)" \
+ "Gecko/20081218 Gentoo Iceweasel/3.1b2"
+
+# http proxy
+
+_proxy_file = os.path.join(os.path.split(os.path.split(__file__)[0])[0],
+ 'proxy.cfg')
+_proxylist = {}
+
+if os.access(_proxy_file, os.F_OK):
+ proxy_file_handle = open(_proxy_file, "r")
+ for line in proxy_file_handle.readlines():
+ parts = line.split(':', 1)
+ #logger.debug("setting " + parts[0] + " proxy to " + parts[1])
+ _proxylist[parts[0].strip()] = parts[1].strip()
+ proxy_file_handle.close()
+
+if _proxylist:
+ proxies = _proxylist