diff options
author | Pootle daemon <pootle@sugarlabs.org> | 2009-09-03 14:26:23 (GMT) |
---|---|---|
committer | Pootle daemon <pootle@sugarlabs.org> | 2009-09-03 14:26:23 (GMT) |
commit | 6d880fe917d184ff55992b5ac687f1e11f336930 (patch) | |
tree | c57e8b250bd49111e4777237f72498716b975ffb | |
parent | ed98842afbb767cbd3190b75606d36039f089412 (diff) | |
parent | 4c4b8058554cb91e83af699a2c0a6ee9c7997454 (diff) |
Merge branch 'master' of gitorious@git.sugarlabs.org:write/mainline
-rw-r--r-- | AbiWordActivity.py | 101 | ||||
-rw-r--r-- | MANIFEST | 185 | ||||
-rw-r--r-- | NEWS | 15 | ||||
-rw-r--r-- | activity/activity.info | 2 | ||||
-rw-r--r-- | icons/list-none.svg | 30 | ||||
-rw-r--r-- | icons/paragraph-bar.svg | 72 | ||||
-rw-r--r-- | po/Write.pot | 164 | ||||
-rw-r--r-- | po/en_US.po | 4 | ||||
-rw-r--r-- | toolbar.py | 145 | ||||
-rw-r--r-- | widgets.py | 218 |
10 files changed, 474 insertions, 462 deletions
diff --git a/AbiWordActivity.py b/AbiWordActivity.py index 1a02647..69eb967 100644 --- a/AbiWordActivity.py +++ b/AbiWordActivity.py @@ -39,8 +39,8 @@ from sugar.presence import presenceservice from sugar.graphics import style from abiword import Canvas -import toolbar -import widgets +from toolbar import * +from widgets import * from sugar.activity.activity import get_bundle_path logger = logging.getLogger('write-activity') @@ -59,20 +59,42 @@ class AbiWordActivity (activity.Activity): toolbar_box = ToolbarBox() activity_button = ActivityToolbarButton(self) + + separator = gtk.SeparatorToolItem() + separator.show() + activity_button.props.page.insert(separator, 2) + export_button = ExportButton(self, self.abiword_canvas) + export_button.show() + activity_button.props.page.insert(export_button, 2) toolbar_box.toolbar.insert(activity_button, 0) - toolbar_box.toolbar.insert( - ToolComboBox(widgets.FontCombo(self.abiword_canvas)), -1) - toolbar_box.toolbar.insert( - ToolComboBox(widgets.FontSizeCombo(self.abiword_canvas)), -1) + separator = gtk.SeparatorToolItem() + toolbar_box.toolbar.insert(separator, -1) - text_toolbar = ToolbarButton( - page=toolbar.TextToolbar(self.abiword_canvas), - icon_name='toolbar-edit') + text_toolbar = ToolbarButton() + text_toolbar.props.page = TextToolbar(self.abiword_canvas) + text_toolbar.props.icon_name = 'format-text-size' + text_toolbar.props.label = _('Text') toolbar_box.toolbar.insert(text_toolbar, -1) + para_toolbar = ToolbarButton() + para_toolbar.props.page = ParagraphToolbar(self.abiword_canvas) + para_toolbar.props.icon_name = 'paragraph-bar' + para_toolbar.props.label = _('Paragraph') + toolbar_box.toolbar.insert(para_toolbar, -1) + + separator = gtk.SeparatorToolItem() + toolbar_box.toolbar.insert(separator, -1) + + copy = CopyButton() + copy.connect('clicked', lambda button: self.abiword_canvas.copy()) + toolbar_box.toolbar.insert(copy, -1) + + paste = PasteButton() + paste.connect('clicked', lambda button: self.abiword_canvas.paste()) + toolbar_box.toolbar.insert(paste, -1) + separator = gtk.SeparatorToolItem() - separator.show() toolbar_box.toolbar.insert(separator, -1) undo = UndoButton(sensitive=False) @@ -87,13 +109,8 @@ class AbiWordActivity (activity.Activity): redo.set_sensitive(can_redo)) toolbar_box.toolbar.insert(redo, -1) - copy = CopyButton() - copy.connect('clicked', lambda button: self.abiword_canvas.copy()) - toolbar_box.toolbar.insert(copy, -1) - - paste = PasteButton() - paste.connect('clicked', lambda button: self.abiword_canvas.paste()) - toolbar_box.toolbar.insert(paste, -1) + separator = gtk.SeparatorToolItem() + toolbar_box.toolbar.insert(separator, -1) self.abiword_canvas.connect('text-selected', lambda abi, b: copy.set_sensitive(True)) @@ -102,23 +119,23 @@ class AbiWordActivity (activity.Activity): self.abiword_canvas.connect('selection-cleared', lambda abi, b: copy.set_sensitive(False)) - separator = gtk.SeparatorToolItem() - separator.show() - toolbar_box.toolbar.insert(separator, -1) - - insert_toolbar = ToolbarButton( - page=toolbar.InsertToolbar(self.abiword_canvas), - icon_name='transfer-from') + insert_toolbar = ToolbarButton() + insert_toolbar.props.page = InsertToolbar(self.abiword_canvas) + insert_toolbar.props.icon_name = 'transfer-from' + insert_toolbar.props.label = _('Insert') toolbar_box.toolbar.insert(insert_toolbar, -1) - search_toolbar = ToolbarButton( - page=toolbar.SearchToolbar(self.abiword_canvas, toolbar_box), - icon_name='search-bar') + search_toolbar = ToolbarButton() + search_toolbar.props.page = SearchToolbar(self.abiword_canvas, + toolbar_box) + search_toolbar.props.icon_name = 'search-bar' + search_toolbar.props.label = _('Search') toolbar_box.toolbar.insert(search_toolbar, -1) - view_toolbar = ToolbarButton( - page=toolbar.ViewToolbar(self.abiword_canvas), - icon_name='toolbar-view') + view_toolbar = ToolbarButton() + view_toolbar.props.page = ViewToolbar(self.abiword_canvas) + view_toolbar.props.icon_name = 'toolbar-view' + view_toolbar.props.label = _('View') toolbar_box.toolbar.insert(view_toolbar, -1) separator = gtk.SeparatorToolItem() @@ -134,16 +151,30 @@ class AbiWordActivity (activity.Activity): self.set_toolbar_box(toolbar_box) self.set_canvas(self.abiword_canvas) - #self.abiword_canvas.connect_after('map-event', self._map_event_cb) + self.abiword_canvas.connect_after('map-event', self.__map_event_cb) self.abiword_canvas.show() - def _map_event_cb(self, event, activity): - logger.debug('_map_event_cb') + self._zoom_handler = self.abiword_canvas.connect("zoom", self.__zoom_cb) + + def __zoom_cb(self, abi, zoom): + abi.disconnect(self._zoom_handler) + + # XXX workarond code to redraw abi document on every resize, see #1121 + def size_allocate_cb(abi, alloc): + zoom = abi.get_zoom_percentage() + abi.set_zoom_percentage(zoom) + abi.set_zoom_percentage(zoom) + abi.connect('size-allocate', size_allocate_cb) + + def __map_event_cb(self, event, activity): + logger.debug('__map_event_cb') # set custom keybindings for Write logger.debug("Loading keybindings") keybindings_file = os.path.join( get_bundle_path(), "keybindings.xml" ) - self.abiword_canvas.invoke_cmd('com.abisource.abiword.loadbindings.fromURI', keybindings_file, 0, 0) + self.abiword_canvas.invoke_cmd( + 'com.abisource.abiword.loadbindings.fromURI', + keybindings_file, 0, 0) # no ugly borders please self.abiword_canvas.set_property("shadow-type", gtk.SHADOW_NONE) @@ -202,7 +233,7 @@ class AbiWordActivity (activity.Activity): logger.debug('My Write activity was shared') self.initiating = True self._setup() - + self._shared_activity.connect('buddy-joined', self._buddy_joined_cb) self._shared_activity.connect('buddy-left', self._buddy_left_cb) diff --git a/MANIFEST b/MANIFEST deleted file mode 100644 index 3a5610b..0000000 --- a/MANIFEST +++ /dev/null @@ -1,185 +0,0 @@ -keybindings.xml -NEWS -setup.py -toolbar.py -AbiWordActivity.py -po/ur.po -po/th.po -po/bn.po -po/af.po -po/am.po -po/gu.po -po/pap.po -po/ay.po -po/ha.po -po/pt.po -po/es.po -po/fr.po -po/km.po -po/hi.po -po/fa.po -po/sl.po -po/tpi.po -po/en.po -po/mk.po -po/bn_IN.po -po/el.po -po/nl.po -po/Write.pot -po/pt_BR.po -po/mr.po -po/ff.po -po/mvo.po -po/ml.po -po/ro.po -po/mn.po -po/ht.po -po/zh_CN.po -po/nb.po -po/de.po -po/pseudo.po -po/ca.po -po/yo.po -po/ne.po -po/is.po -po/si.po -po/ja.po -po/ar.po -po/ps.po -po/tr.po -po/it.po -po/ig.po -po/ru.po -po/bg.po -po/pis.po -po/pl.po -po/ko.po -po/rw.po -po/vi.po -po/qu.po -po/pa.po -po/dz.po -po/sd.po -po/fa_AF.po -po/zh_TW.po -po/te.po -activity/activity.info -activity/activity-write.svg -locale/ca/activity.linfo -locale/ca/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/si/activity.linfo -locale/si/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/pseudo/activity.linfo -locale/pseudo/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/ro/activity.linfo -locale/ro/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/ha/activity.linfo -locale/ha/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/fa/activity.linfo -locale/fa/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/es/activity.linfo -locale/es/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/pap/activity.linfo -locale/pap/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/mk/activity.linfo -locale/mk/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/qu/activity.linfo -locale/qu/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/th/activity.linfo -locale/th/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/nb/activity.linfo -locale/nb/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/km/activity.linfo -locale/km/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/pt_BR/activity.linfo -locale/pt_BR/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/zh_CN/activity.linfo -locale/zh_CN/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/tr/activity.linfo -locale/tr/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/el/activity.linfo -locale/el/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/it/activity.linfo -locale/it/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/ff/activity.linfo -locale/ff/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/ig/activity.linfo -locale/ig/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/sl/activity.linfo -locale/sl/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/zh_TW/activity.linfo -locale/zh_TW/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/ml/activity.linfo -locale/ml/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/sd/activity.linfo -locale/sd/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/fr/activity.linfo -locale/fr/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/ja/activity.linfo -locale/ja/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/bn_IN/activity.linfo -locale/bn_IN/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/bn/activity.linfo -locale/bn/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/ay/activity.linfo -locale/ay/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/mvo/activity.linfo -locale/mvo/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/tpi/activity.linfo -locale/tpi/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/af/activity.linfo -locale/af/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/mr/activity.linfo -locale/mr/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/ar/activity.linfo -locale/ar/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/am/activity.linfo -locale/am/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/hi/activity.linfo -locale/hi/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/yo/activity.linfo -locale/yo/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/is/activity.linfo -locale/is/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/fa_AF/activity.linfo -locale/fa_AF/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/pa/activity.linfo -locale/pa/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/ko/activity.linfo -locale/ko/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/ur/activity.linfo -locale/ur/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/pt/activity.linfo -locale/pt/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/dz/activity.linfo -locale/dz/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/mn/activity.linfo -locale/mn/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/ne/activity.linfo -locale/ne/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/de/activity.linfo -locale/de/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/ps/activity.linfo -locale/ps/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/en/activity.linfo -locale/en/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/rw/activity.linfo -locale/rw/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/bg/activity.linfo -locale/bg/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/vi/activity.linfo -locale/vi/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/pl/activity.linfo -locale/pl/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/pis/activity.linfo -locale/pis/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/ru/activity.linfo -locale/ru/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/ht/activity.linfo -locale/ht/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/te/activity.linfo -locale/te/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/gu/activity.linfo -locale/gu/LC_MESSAGES/org.laptop.AbiWordActivity.mo -locale/nl/activity.linfo -locale/nl/LC_MESSAGES/org.laptop.AbiWordActivity.mo @@ -1,3 +1,18 @@ +66 + +* Revert export button + +65 + +* #1145 Do not propagate current paragraph format while moving cursor + +64 + +* Utilize new toolbars +* #1121 Write canvas redraw glitch when locking open a secondary toolbar +* #1120 Fix MANIFEST file +* #1122 New Write primary toolbar icon design does not all fit in the toolbar + 58 * Fix 6021: Write crash on buddy left diff --git a/activity/activity.info b/activity/activity.info index 70aff00..a107b64 100644 --- a/activity/activity.info +++ b/activity/activity.info @@ -3,7 +3,7 @@ name = Write bundle_id = org.laptop.AbiWordActivity exec = sugar-activity AbiWordActivity.AbiWordActivity icon = activity-write -activity_version = 63 +activity_version = 66 show_launcher = 1 mime_types = text/rtf;text/plain;application/x-abiword;text/x-xml-abiword;application/msword;application/rtf;application/xhtml+xml;text/html;application/vnd.oasis.opendocument.text license = GPLv2+ diff --git a/icons/list-none.svg b/icons/list-none.svg index 91ffebe..fd4fe1c 100644 --- a/icons/list-none.svg +++ b/icons/list-none.svg @@ -48,37 +48,37 @@ id="base" showgrid="false" inkscape:zoom="8.4101215" - inkscape:cx="24.745584" + inkscape:cx="6.6917394" inkscape:cy="27.348" inkscape:window-x="0" - inkscape:window-y="16" + inkscape:window-y="32" inkscape:current-layer="svg2" /><g - id="g3162"><line + id="g3212"><line display="inline" - x1="5.3933511" - x2="49.428024" + x1="19.163853" + x2="50.163853" y1="14.47" y2="14.47" id="line5" - style="fill:#4c4d4f;stroke:#ffffff;stroke-width:3.50000005;display:inline;stroke-miterlimit:4;stroke-dasharray:none" /><line + style="fill:#4c4d4f;stroke:#ffffff;stroke-width:3.5;display:inline" /><line display="inline" - x1="5.3933511" - x2="49.428024" + x1="19.163853" + x2="50.163853" y1="23.056" y2="23.056" id="line7" - style="fill:#4c4d4f;stroke:#ffffff;stroke-width:3.50000005;display:inline;stroke-miterlimit:4;stroke-dasharray:none" /><line + style="fill:#4c4d4f;stroke:#ffffff;stroke-width:3.5;display:inline" /><line display="inline" - x1="5.3933511" - x2="49.428024" + x1="19.163853" + x2="50.163853" y1="31.641001" y2="31.641001" id="line9" - style="fill:#4c4d4f;stroke:#ffffff;stroke-width:3.50000005;display:inline;stroke-miterlimit:4;stroke-dasharray:none" /><line + style="fill:#4c4d4f;stroke:#ffffff;stroke-width:3.5;display:inline" /><line display="inline" - x1="5.3933511" - x2="49.428024" + x1="19.163853" + x2="50.163853" y1="40.227001" y2="40.227001" id="line11" - style="fill:#4c4d4f;stroke:#ffffff;stroke-width:3.50000005;display:inline;stroke-miterlimit:4;stroke-dasharray:none" /></g></svg>
\ No newline at end of file + style="fill:#4c4d4f;stroke:#ffffff;stroke-width:3.5;display:inline" /></g></svg>
\ No newline at end of file diff --git a/icons/paragraph-bar.svg b/icons/paragraph-bar.svg new file mode 100644 index 0000000..d9203a1 --- /dev/null +++ b/icons/paragraph-bar.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.0" + id="Layer_1" + x="0px" + y="0px" + width="22.16" + height="22.156" + 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="paragraph-bar.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.90196078" + guidetolerance="10.0" + gridtolerance="10.0" + objecttolerance="10.0" + borderopacity="1.0" + bordercolor="#666666" + pagecolor="#a1a1a1" + id="base" + showgrid="false" + inkscape:zoom="20.852139" + inkscape:cx="17.054208" + inkscape:cy="10.964367" + inkscape:window-x="0" + inkscape:window-y="16" + inkscape:current-layer="g3" + borderlayer="false" + showborder="true" + inkscape:showpageshadow="true" /> +<g + id="g3"> + + +<text + xml:space="preserve" + style="font-size:16px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="4.5538874" + y="15.777756" + id="text2385"><tspan + sodipodi:role="line" + id="tspan2387" + x="4.5538874" + y="15.777756">ΒΆ</tspan></text> + + +</g> +</svg>
\ No newline at end of file diff --git a/po/Write.pot b/po/Write.pot index b323715..90bec7e 100644 --- a/po/Write.pot +++ b/po/Write.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-11-17 20:56+0100\n" +"POT-Creation-Date: 2009-08-06 18:26+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -20,166 +20,180 @@ msgstr "" msgid "Write" msgstr "" -#: AbiWordActivity.py:64 -msgid "Edit" +#: /home/sugar/src/activities/Write.activity/toolbar.py:52 +msgid "Rich Text (RTF)" msgstr "" -#: AbiWordActivity.py:67 -msgid "Text" +#: /home/sugar/src/activities/Write.activity/toolbar.py:52 +msgid "RTF" +msgstr "" + +#: /home/sugar/src/activities/Write.activity/toolbar.py:53 +msgid "Hypertext (HTML)" +msgstr "" + +#: /home/sugar/src/activities/Write.activity/toolbar.py:53 +msgid "HTML" +msgstr "" + +#: /home/sugar/src/activities/Write.activity/toolbar.py:54 +msgid "Plain Text (TXT)" +msgstr "" + +#: /home/sugar/src/activities/Write.activity/toolbar.py:54 +msgid "TXT" msgstr "" -#: AbiWordActivity.py:71 -msgid "Image" +#: /home/sugar/src/activities/Write.activity/toolbar.py:126 +msgid "Find previous" +msgstr "" + +#: /home/sugar/src/activities/Write.activity/toolbar.py:132 +msgid "Find next" msgstr "" -#: AbiWordActivity.py:75 toolbar.py:515 +#: /home/sugar/src/activities/Write.activity/toolbar.py:205 msgid "Table" msgstr "" -#: AbiWordActivity.py:79 -msgid "Format" +#: /home/sugar/src/activities/Write.activity/toolbar.py:205 +msgid "Cancel" msgstr "" -#: AbiWordActivity.py:83 -msgid "View" +#: /home/sugar/src/activities/Write.activity/toolbar.py:213 +msgid "Insert Row" msgstr "" -#: toolbar.py:51 -msgid "Rich Text (RTF)" +#: /home/sugar/src/activities/Write.activity/toolbar.py:218 +msgid "Delete Row" msgstr "" -#: toolbar.py:51 -msgid "RTF" +#: /home/sugar/src/activities/Write.activity/toolbar.py:223 +msgid "Insert Column" msgstr "" -#: toolbar.py:52 -msgid "Hypertext (HTML)" +#: /home/sugar/src/activities/Write.activity/toolbar.py:228 +msgid "Delete Column" msgstr "" -#: toolbar.py:52 -msgid "HTML" +#: /home/sugar/src/activities/Write.activity/toolbar.py:236 +msgid "Insert Image" msgstr "" -#: toolbar.py:53 -msgid "Plain Text (TXT)" +#: /home/sugar/src/activities/Write.activity/toolbar.py:280 +msgid "Zoom Out" msgstr "" -#: toolbar.py:53 -msgid "TXT" +#: /home/sugar/src/activities/Write.activity/toolbar.py:286 +msgid "Zoom In" msgstr "" -#: toolbar.py:128 -msgid "Find previous" +#: /home/sugar/src/activities/Write.activity/toolbar.py:302 +msgid "%" msgstr "" -#: toolbar.py:134 -msgid "Find next" +#: /home/sugar/src/activities/Write.activity/toolbar.py:314 +msgid "Page: " msgstr "" -#: toolbar.py:244 +#: /home/sugar/src/activities/Write.activity/toolbar.py:400 msgid "Bold" msgstr "" -#: toolbar.py:251 +#: /home/sugar/src/activities/Write.activity/toolbar.py:408 msgid "Italic" msgstr "" -#: toolbar.py:258 +#: /home/sugar/src/activities/Write.activity/toolbar.py:416 msgid "Underline" msgstr "" -#: toolbar.py:481 -msgid "Insert Image" +#: /home/sugar/src/activities/Write.activity/toolbar.py:456 +msgid "Left justify" msgstr "" -#: toolbar.py:489 -msgid "Choose image" +#: /home/sugar/src/activities/Write.activity/toolbar.py:463 +msgid "Center justify" msgstr "" -#: toolbar.py:515 -msgid "Cancel" +#: /home/sugar/src/activities/Write.activity/toolbar.py:470 +msgid "Right justify" msgstr "" -#: toolbar.py:524 -msgid "Insert Row" +#: /home/sugar/src/activities/Write.activity/toolbar.py:477 +msgid "Fill justify" msgstr "" -#: toolbar.py:530 -msgid "Delete Row" +#: /home/sugar/src/activities/Write.activity/AbiWordActivity.py:70 +msgid "Text" msgstr "" -#: toolbar.py:536 -msgid "Insert Column" +#: /home/sugar/src/activities/Write.activity/AbiWordActivity.py:76 +msgid "Paragraph" msgstr "" -#: toolbar.py:542 -msgid "Delete Column" +#: /home/sugar/src/activities/Write.activity/AbiWordActivity.py:118 +msgid "Insert" msgstr "" -#: toolbar.py:580 -msgid "Style: " +#: /home/sugar/src/activities/Write.activity/AbiWordActivity.py:125 +msgid "Search" msgstr "" -#: toolbar.py:590 +#: /home/sugar/src/activities/Write.activity/AbiWordActivity.py:131 +msgid "View" +msgstr "" + +#: /home/sugar/src/activities/Write.activity/widgets.py:114 msgid "Heading 1" msgstr "" -#: toolbar.py:591 +#: /home/sugar/src/activities/Write.activity/widgets.py:115 msgid "Heading 2" msgstr "" -#: toolbar.py:592 +#: /home/sugar/src/activities/Write.activity/widgets.py:116 msgid "Heading 3" msgstr "" -#: toolbar.py:593 +#: /home/sugar/src/activities/Write.activity/widgets.py:117 msgid "Heading 4" msgstr "" -#: toolbar.py:594 +#: /home/sugar/src/activities/Write.activity/widgets.py:118 +#: /home/sugar/src/activities/Write.activity/widgets.py:218 msgid "Bullet List" msgstr "" -#: toolbar.py:595 +#: /home/sugar/src/activities/Write.activity/widgets.py:119 +#: /home/sugar/src/activities/Write.activity/widgets.py:222 msgid "Dashed List" msgstr "" -#: toolbar.py:596 +#: /home/sugar/src/activities/Write.activity/widgets.py:120 +#: /home/sugar/src/activities/Write.activity/widgets.py:226 msgid "Numbered List" msgstr "" -#: toolbar.py:597 +#: /home/sugar/src/activities/Write.activity/widgets.py:121 +#: /home/sugar/src/activities/Write.activity/widgets.py:230 msgid "Lower Case List" msgstr "" -#: toolbar.py:598 +#: /home/sugar/src/activities/Write.activity/widgets.py:122 +#: /home/sugar/src/activities/Write.activity/widgets.py:234 msgid "Upper Case List" msgstr "" -#: toolbar.py:599 +#: /home/sugar/src/activities/Write.activity/widgets.py:123 msgid "Block Text" msgstr "" -#: toolbar.py:600 +#: /home/sugar/src/activities/Write.activity/widgets.py:124 +#: /home/sugar/src/activities/Write.activity/widgets.py:208 msgid "Normal" msgstr "" -#: toolbar.py:601 +#: /home/sugar/src/activities/Write.activity/widgets.py:125 msgid "Plain Text" msgstr "" - -#: toolbar.py:656 -msgid "Zoom Out" -msgstr "" - -#: toolbar.py:662 -msgid "Zoom In" -msgstr "" - -#: toolbar.py:678 -msgid "%" -msgstr "" - -#: toolbar.py:690 -msgid "Page: " -msgstr "" diff --git a/po/en_US.po b/po/en_US.po index e626794..a2c6f01 100644 --- a/po/en_US.po +++ b/po/en_US.po @@ -117,7 +117,7 @@ msgstr "Delete Column" #: toolbar.py:580 msgid "Style: " -msgstr "Style: _" +msgstr "Style: " #: toolbar.py:590 msgid "Heading 1" @@ -181,4 +181,4 @@ msgstr "%" #: toolbar.py:690 msgid "Page: " -msgstr "Page: _" +msgstr "Page: " @@ -18,9 +18,6 @@ from gettext import gettext as _ import logging -import os -import time -import dbus import abiword import gtk @@ -34,9 +31,8 @@ from sugar.graphics.toolcombobox import ToolComboBox from sugar.graphics.objectchooser import ObjectChooser from sugar.graphics import iconentry from sugar.activity import activity -from sugar.graphics.menuitem import MenuItem +from sugar.activity.widgets import * from sugar.graphics.palette import Palette -from sugar.datastore import datastore from sugar import mime from port import chooser import sugar.profile @@ -45,64 +41,6 @@ import widgets logger = logging.getLogger('write-activity') -class WriteActivityToolbarExtension: - - # file mime type, abiword exporter properties, drop down name, journal entry postfix - _EXPORT_FORMATS = [['application/rtf', _('Rich Text (RTF)'), _('RTF'), ""], - ['text/html', _('Hypertext (HTML)'), _('HTML'), "html4:yes; declare-xml:no; embed-css:yes; embed-images:yes;"], - ['text/plain', _('Plain Text (TXT)'), _('TXT'), ""]] - - def __init__(self, activity, toolbox, abiword_canvas): - - self._activity = activity - self._abiword_canvas = abiword_canvas - self._activity_toolbar = toolbox.get_activity_toolbar() - self._keep_palette = self._activity_toolbar.keep.get_palette() - - # hook up the export formats to the Keep button - for i, f in enumerate(self._EXPORT_FORMATS): - menu_item = MenuItem(f[1]) - menu_item.connect('activate', self._export_as_cb, f[0], f[2], f[3]) - self._keep_palette.menu.append(menu_item) - menu_item.show() - - def _export_as_cb(self, menu_item, mimetype, jpostfix, exp_props): - logger.debug('exporting file, mimetype: %s, exp_props: %s', mimetype, exp_props); - - # special case HTML export to set the activity name as the HTML title - if mimetype == "text/html": - exp_props += " title:" + self._activity.metadata['title'] + ';'; - - # create a new journal item - fileObject = datastore.create() - act_meta = self._activity.metadata - fileObject.metadata['title'] = act_meta['title'] + ' (' + jpostfix + ')'; - fileObject.metadata['title_set_by_user'] = act_meta['title_set_by_user'] - fileObject.metadata['mime_type'] = mimetype - fileObject.metadata['fulltext'] = \ - self._abiword_canvas.get_content(extension_or_mimetype=".txt")[:3000] - - fileObject.metadata['icon-color'] = act_meta['icon-color'] - fileObject.metadata['activity'] = act_meta['activity'] - fileObject.metadata['keep'] = act_meta['keep'] - -# TODO: Activity class should provide support for preview, see #5119 -# self._activity.take_screenshot() -# if self._activity._preview: -# preview = self._activity._get_preview() -# fileObject.metadata['preview'] = dbus.ByteArray(preview) - - fileObject.metadata['share-scope'] = act_meta['share-scope'] - - # write out the document contents in the requested format - fileObject.file_path = os.path.join(self._activity.get_activity_root(), 'instance', '%i' % time.time()) - self._abiword_canvas.save('file://' + fileObject.file_path, mimetype, exp_props) - - # store the journal item - datastore.write(fileObject, transfer_ownership=True) - fileObject.destroy() - del fileObject - class SearchToolbar(gtk.Toolbar): def __init__(self, abiword_canvas, text_toolbar): @@ -386,70 +324,95 @@ class TextToolbar(gtk.Toolbar): def __init__(self, abiword_canvas): gtk.Toolbar.__init__(self) - self._abiword_canvas = abiword_canvas + font_name = ToolComboBox(widgets.FontCombo(abiword_canvas)) + self.insert(font_name, -1) - self.insert(ToolComboBox(widgets.StyleCombo(abiword_canvas)), -1) + font_size = ToolComboBox(widgets.FontSizeCombo(abiword_canvas)) + self.insert(font_size, -1) separator = gtk.SeparatorToolItem() - separator.show() self.insert(separator, -1) bold = ToggleToolButton('format-text-bold') bold.set_tooltip(_('Bold')) bold_id = bold.connect('clicked', lambda sender: abiword_canvas.toggle_bold()) - self._abiword_canvas.connect('bold', lambda abi, b: - self.setToggleButtonState(bold, b, bold_id)) + abiword_canvas.connect('bold', lambda abi, b: + self._setToggleButtonState(bold, b, bold_id)) self.insert(bold, -1) italic = ToggleToolButton('format-text-italic') italic.set_tooltip(_('Italic')) italic_id = italic.connect('clicked', lambda sender: abiword_canvas.toggle_italic()) - self._abiword_canvas.connect('italic', lambda abi, b: - self.setToggleButtonState(italic, b, italic_id)) + abiword_canvas.connect('italic', lambda abi, b: + self._setToggleButtonState(italic, b, italic_id)) self.insert(italic, -1) underline = ToggleToolButton('format-text-underline') underline.set_tooltip(_('Underline')) underline_id = underline.connect('clicked', lambda sender: abiword_canvas.toggle_underline()) - self._abiword_canvas.connect('underline', lambda abi, b: - self.setToggleButtonState(underline, b, underline_id)) + abiword_canvas.connect('underline', lambda abi, b: + self._setToggleButtonState(underline, b, underline_id)) self.insert(underline, -1) separator = gtk.SeparatorToolItem() - separator.show() - self.insert(separator, -1) - - alignment = RadioMenuButton(palette=widgets.Alignment(abiword_canvas)) - self.insert(alignment, -1) - - lists = RadioMenuButton(palette=widgets.Lists(abiword_canvas)) - self.insert(lists, -1) - - separator = gtk.SeparatorToolItem() - separator.show() self.insert(separator, -1) color = ColorToolButton() - color.connect('color-set', self._text_color_cb) + color.connect('color-set', self._text_color_cb, abiword_canvas) tool_item = gtk.ToolItem() tool_item.add(color) self.insert(tool_item, -1) - self._abiword_canvas.connect('color', lambda abi, r, g, b: + abiword_canvas.connect('color', lambda abi, r, g, b: color.set_color(gtk.gdk.Color(r * 256, g * 256, b * 256))) self.show_all() - def setToggleButtonState(self,button,b,id): + def _text_color_cb(self, button, abiword_canvas): + newcolor = button.get_color() + abiword_canvas.set_text_color(int(newcolor.red / 256.0), + int(newcolor.green / 256.0), + int(newcolor.blue / 256.0)) + + def _setToggleButtonState(self,button,b,id): button.handler_block(id) button.set_active(b) button.handler_unblock(id) - def _text_color_cb(self, button): - newcolor = button.get_color() - self._abiword_canvas.set_text_color(int(newcolor.red / 256.0), - int(newcolor.green / 256.0), - int(newcolor.blue / 256.0)) +class ParagraphToolbar(gtk.Toolbar): + def __init__(self, abi): + gtk.Toolbar.__init__(self) + self.insert(ToolComboBox(widgets.StyleCombo(abi)), -1) + self.insert(gtk.SeparatorToolItem(), -1) + + group = widgets.AbiButton(abi, 'left-align', abi.align_left) + group.props.named_icon = 'format-justify-left' + group.props.tooltip = _('Left justify') + self.insert(group, -1) + + button = widgets.AbiButton(abi, 'center-align', abi.align_center) + button.props.group = group + button.props.named_icon = 'format-justify-center' + button.props.tooltip = _('Center justify') + self.insert(button, -1) + + button = widgets.AbiButton(abi, 'right-align', abi.align_right) + button.props.group = group + button.props.named_icon = 'format-justify-right' + button.props.tooltip = _('Right justify') + self.insert(button, -1) + + button = widgets.AbiButton(abi, 'justify-align', abi.align_justify) + button.props.group = group + button.props.named_icon = 'format-justify-fill' + button.props.tooltip = _('Fill justify') + self.insert(button, -1) + + self.insert(gtk.SeparatorToolItem(), -1) + lists = RadioMenuButton(palette=widgets.ListsPalette(abi)) + self.insert(lists, -1) + + self.show_all() @@ -12,17 +12,22 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +import os import gtk +import dbus +import time from gettext import gettext as _ - import logging -logger = logging.getLogger('write-activity') from sugar.graphics.radiotoolbutton import RadioToolButton from sugar.graphics.combobox import ComboBox from sugar.graphics.palette import Palette from sugar.graphics.radiopalette import RadioPalette -from sugar.graphics.radiotoolbutton import RadioToolButton +from sugar.graphics.toolbutton import ToolButton +from sugar.graphics.menuitem import MenuItem +from sugar.datastore import datastore + +logger = logging.getLogger('write-activity') class FontCombo(ComboBox): def __init__(self, abi): @@ -38,12 +43,16 @@ class FontCombo(ComboBox): if f == 'Times New Roman': self.set_active(i) - abi.connect('font-family', self._font_family_cb) + self._abi_handler = abi.connect('font-family', self._font_family_cb) def _font_changed_cb(self, combobox, abi): if self.get_active() != -1: logger.debug('Setting font: %s', self._fonts[self.get_active()]) - abi.set_font_name(self._fonts[self.get_active()]) + try: + abi.handler_block(self._abi_handler) + abi.set_font_name(self._fonts[self.get_active()]) + finally: + abi.handler_unblock(self._abi_handler) def _font_family_cb(self, abi, font_family): font_index = -1 @@ -82,6 +91,8 @@ class FontSizeCombo(ComboBox): def __init__(self, abi): ComboBox.__init__(self) + self._abi_handler = abi.connect('font-size', self._font_size_cb) + self._font_sizes = ['8', '9', '10', '11', '12', '14', '16', '20', \ '22', '24', '26', '28', '36', '48', '72'] self._changed_id = self.connect('changed', self._font_size_changed_cb, @@ -92,13 +103,16 @@ class FontSizeCombo(ComboBox): if s == '12': self.set_active(i) - abi.connect('font-size', self._font_size_cb) - def _font_size_changed_cb(self, combobox, abi): if self.get_active() != -1: logger.debug('Setting font size: %d', int(self._font_sizes[self.get_active()])) - abi.set_font_size(self._font_sizes[self.get_active()]) + + abi.handler_block(self._abi_handler) + try: + abi.set_font_size(self._font_sizes[self.get_active()]) + finally: + abi.handler_unblock(self._abi_handler) def _font_size_cb(self, abi, size): for i, s in enumerate(self._font_sizes): @@ -112,6 +126,8 @@ class StyleCombo(ComboBox): def __init__(self, abi): ComboBox.__init__(self) + self._abi_handler = abi.connect('style-name', self._style_cb) + self._styles = [ ['Heading 1', _('Heading 1')], ['Heading 2', _('Heading 2')], ['Heading 3', _('Heading 3')], @@ -134,12 +150,14 @@ class StyleCombo(ComboBox): if s[0] == 'Normal': self.set_active(i) - abi.connect('style-name', self._style_cb) - def _style_changed_cb(self, combobox, abi): if self.get_active() != -1: logger.debug('Set style: %s', self._styles[self.get_active()][0]) - abi.set_style(self._styles[self.get_active()][0]) + try: + abi.handler_block(self._abi_handler) + abi.set_style(self._styles[self.get_active()][0]) + finally: + abi.handler_unblock(self._abi_handler) def _style_cb(self, abi, style_name): if style_name is None or style_name == 'None': @@ -177,70 +195,154 @@ class StyleCombo(ComboBox): self.set_active(style_index) self.handler_unblock(self._style_changed_id) -class AbiPalette(RadioPalette): +class AbiButton(RadioToolButton): + def __init__(self, abi, abi_signal, do_abi_cb, on_abi_cb=None, **kwargs): + RadioToolButton.__init__(self, **kwargs) + + self._abi_handler = abi.connect(abi_signal, self.__abi_cb, + abi_signal, on_abi_cb) + self._toggled_handler = self.connect('toggled', self.__toggled_cb, + abi, do_abi_cb) + + def __toggled_cb(self, button, abi, do_abi_cb): + if not button.props.active: + return + + abi.handler_block(self._abi_handler) + try: + logging.debug('Do abi %s' % do_abi_cb) + do_abi_cb() + finally: + abi.handler_unblock(self._abi_handler) + + def __abi_cb(self, abi, prop, abi_signal, on_abi_cb): + if (on_abi_cb is None and not prop) or \ + (on_abi_cb is not None and not on_abi_cb(abi, prop)): + return + + self.handler_block(self._toggled_handler) + try: + logging.debug('On abi %s prop=%r' % (abi_signal, prop)) + self.set_active(True) + finally: + self.handler_unblock(self._toggled_handler) + +class ListsPalette(RadioPalette): def __init__(self, abi): RadioPalette.__init__(self) - self.abi = abi - def append(self, icon_name, tooltip, clicked_cb, abi_signal, abi_cb): - siblings = self.button_box.get_children() + def append(icon_name, tooltip, do_abi_cb, on_abi_cb): + button = AbiButton(abi, 'style-name', do_abi_cb, on_abi_cb) + button.show() + button.props.icon_name = icon_name + button.props.group = group + RadioPalette.append(self, button, tooltip) + return button - button = RadioToolButton( - icon_name=icon_name, - group=siblings and siblings[0] or None) - button.connect('clicked', lambda sender: clicked_cb()) - RadioPalette.append(self, button, tooltip) - - def cb(abi, prop): - if abi_cb(abi, prop): - button.set_active(True) - self.abi.connect(abi_signal, cb) - -class Alignment(AbiPalette): - def __init__(self, abi): - AbiPalette.__init__(self, abi) - - self.append('format-justify-left', _('Left justify'), - lambda: abi.align_left(), 'left-align', lambda abi, b: b) - - self.append('format-justify-center', _('Center justify'), - lambda: abi.align_center(), 'center-align', lambda abi, b: b) - - self.append('format-justify-right', _('Right justify'), - lambda: abi.align_right(), 'right-align', lambda abi, b: b) - - self.append('format-justify-fill', _('Fill justify'), - lambda: abi.align_justify(), 'justify-align', lambda abi, b: b) - -class Lists(AbiPalette): - def __init__(self, abi): - AbiPalette.__init__(self, abi) + group = None - self.append('list-none', _('Normal'), - lambda: abi.set_style('Normal'), - 'style-name', lambda abi, style: + group = append('list-none', _('Normal'), + lambda: + abi.set_style('Normal'), + lambda abi, style: style not in ['Bullet List', 'Dashed List', 'Numbered List', 'Lower Case List', 'Upper Case List']) - self.append('list-bullet', _('Bullet List'), + append('list-bullet', _('Bullet List'), lambda: abi.set_style('Bullet List'), - 'style-name', lambda abi, style: style == 'Bullet List') + lambda abi, style: style == 'Bullet List') - self.append('list-dashed', _('Dashed List'), + append('list-dashed', _('Dashed List'), lambda: abi.set_style('Dashed List'), - 'style-name', lambda abi, style: style == 'Dashed List') + lambda abi, style: style == 'Dashed List') - self.append('list-numbered', _('Numbered List'), + append('list-numbered', _('Numbered List'), lambda: abi.set_style('Numbered List'), - 'style-name', lambda abi, style: style == 'Numbered List') + lambda abi, style: style == 'Numbered List') - self.append('list-lower-case', _('Lower Case List'), + append('list-lower-case', _('Lower Case List'), lambda: abi.set_style('Lower Case List'), - 'style-name', lambda abi, style: style == 'Lower Case List') + lambda abi, style: style == 'Lower Case List') - self.append('list-upper-case', _('Upper Case List'), + append('list-upper-case', _('Upper Case List'), lambda: abi.set_style('Upper Case List'), - 'style-name', lambda abi, style: style == 'Upper Case List') + lambda abi, style: style == 'Upper Case List') + + self.show_all() + +class ExportButton(ToolButton): + _EXPORT_FORMATS = [{'mime_type' : 'application/rtf', + 'title' : _('Rich Text (RTF)'), + 'jpostfix' : _('RTF'), + 'exp_props' : ''}, + + {'mime_type' : 'text/html', + 'title' : _('Hypertext (HTML)'), + 'jpostfix' : _('HTML'), + 'exp_props' : 'html4:yes; declare-xml:no; ' \ + 'embed-css:yes; embed-images:yes;'}, + + {'mime_type' : 'text/plain', + 'title' : _('Plain Text (TXT)'), + 'jpostfix' : _('TXT'), + 'exp_props' : ''}] + + def __init__(self, activity, abi): + ToolButton.__init__(self, 'document-save') + self.props.tooltip = _('Export') + self.props.label = _('Export') + + for i in self._EXPORT_FORMATS: + menu_item = MenuItem(i['title']) + menu_item.connect('activate', self.__activate_cb, activity, abi, i) + self.props.palette.menu.append(menu_item) + menu_item.show() + + def do_clicked(self): + if self.props.palette.is_up(): + self.props.palette.popdown(immediate=True) + else: + self.props.palette.popup(immediate=True, state=Palette.SECONDARY) + + def __activate_cb(self, menu_item, activity, abi, format): + logger.debug('exporting file: %r' % format) + + exp_props = format['exp_props'] + + # special case HTML export to set the activity name as the HTML title + if format['mime_type'] == "text/html": + exp_props += " title:" + activity.metadata['title'] + ';'; + + # create a new journal item + fileObject = datastore.create() + act_meta = activity.metadata + fileObject.metadata['title'] = \ + act_meta['title'] + ' (' + format['jpostfix'] + ')'; + fileObject.metadata['title_set_by_user'] = act_meta['title_set_by_user'] + fileObject.metadata['mime_type'] = format['mime_type'] + fileObject.metadata['fulltext'] = abi.get_content( + extension_or_mimetype=".txt")[:3000] + + fileObject.metadata['icon-color'] = act_meta['icon-color'] + fileObject.metadata['activity'] = act_meta['activity'] + fileObject.metadata['keep'] = act_meta['keep'] + + preview = activity.get_preview() + if preview is not None: + fileObject.metadata['preview'] = dbus.ByteArray(preview) + + fileObject.metadata['share-scope'] = act_meta['share-scope'] + + # write out the document contents in the requested format + fileObject.file_path = os.path.join(activity.get_activity_root(), + 'instance', '%i' % time.time()) + abi.save('file://' + fileObject.file_path, + format['mime_type'], exp_props) + + # store the journal item + datastore.write(fileObject, transfer_ownership=True) + fileObject.destroy() + del fileObject |