diff options
author | Simon Schampijer <erikos@laptop.pennylane> | 2009-09-09 10:41:50 (GMT) |
---|---|---|
committer | Simon Schampijer <erikos@laptop.pennylane> | 2009-09-09 10:41:50 (GMT) |
commit | f9e678cfab43cec6f9245c9c1af8fc8bb0a948fb (patch) | |
tree | 698f35c73cd02b433b83ca1f990d1f74eb112cff | |
parent | 62496f82ec339e3dd6f2cd1ee42be610b9f3aa4b (diff) | |
parent | 7dd80456aa89f97ad15261f7b86a4bce7bb086c5 (diff) |
Merge branch 'master' of git://git.sugarlabs.org/write/garycmartins-toolbar-clone
-rw-r--r-- | AbiWordActivity.py | 146 | ||||
-rw-r--r-- | icons/format-text.svg | 8 | ||||
-rw-r--r-- | icons/insert-picture.svg | 40 | ||||
-rw-r--r-- | icons/list-bullet.svg | 3 | ||||
-rw-r--r-- | icons/list-dashed.svg | 3 | ||||
-rw-r--r-- | icons/list-lower-case.svg | 2 | ||||
-rw-r--r-- | icons/list-none.svg | 20 | ||||
-rw-r--r-- | icons/list-numbered.svg | 2 | ||||
-rw-r--r-- | icons/list-upper-case.svg | 2 | ||||
-rw-r--r-- | icons/paragraph-bar.svg | 4 | ||||
-rw-r--r-- | icons/paragraph-blocktext.svg | 12 | ||||
-rw-r--r-- | icons/paragraph-h1.svg | 13 | ||||
-rw-r--r-- | icons/paragraph-h2.svg | 13 | ||||
-rw-r--r-- | icons/paragraph-h3.svg | 13 | ||||
-rw-r--r-- | icons/paragraph-h4.svg | 13 | ||||
-rw-r--r-- | icons/paragraph-plaintext.svg | 18 | ||||
-rw-r--r-- | icons/search-bar.svg | 103 | ||||
-rw-r--r-- | icons/toolbar-bulletlist.svg | 14 | ||||
-rw-r--r-- | toolbar.py | 312 | ||||
-rw-r--r-- | widgets.py | 129 |
20 files changed, 455 insertions, 415 deletions
diff --git a/AbiWordActivity.py b/AbiWordActivity.py index 69eb967..f6c54fa 100644 --- a/AbiWordActivity.py +++ b/AbiWordActivity.py @@ -19,8 +19,6 @@ from gettext import gettext as _ import logging import os -import time -import shutil # Abiword needs this to happen as soon as possible import gobject @@ -31,17 +29,27 @@ import gtk import telepathy import telepathy.client -from sugar.graphics.toolcombobox import ToolComboBox -from sugar.graphics.toolbarbox import ToolbarButton, ToolbarBox +from abiword import Canvas + from sugar.activity import activity -from sugar.activity.widgets import * +from sugar.activity.widgets import StopButton +from sugar.activity.widgets import ActivityToolbarButton +from sugar.activity.activity import get_bundle_path + from sugar.presence import presenceservice + +from sugar.graphics.toolbarbox import ToolbarButton, ToolbarBox +from sugar.graphics.toggletoolbutton import ToggleToolButton +from sugar.graphics.colorbutton import ColorToolButton from sugar.graphics import style -from abiword import Canvas -from toolbar import * -from widgets import * -from sugar.activity.activity import get_bundle_path +from toolbar import EditToolbar +from toolbar import ViewToolbar +from toolbar import TextToolbar +from toolbar import ListToolbar +from toolbar import InsertToolbar +from toolbar import ParagraphToolbar +from widgets import ExportButton logger = logging.getLogger('write-activity') @@ -68,12 +76,24 @@ class AbiWordActivity (activity.Activity): activity_button.props.page.insert(export_button, 2) toolbar_box.toolbar.insert(activity_button, 0) + edit_toolbar = ToolbarButton() + edit_toolbar.props.page = EditToolbar(self, toolbar_box) + edit_toolbar.props.icon_name = 'toolbar-edit' + edit_toolbar.props.label = _('Edit') + toolbar_box.toolbar.insert(edit_toolbar, -1) + + 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() toolbar_box.toolbar.insert(separator, -1) text_toolbar = ToolbarButton() text_toolbar.props.page = TextToolbar(self.abiword_canvas) - text_toolbar.props.icon_name = 'format-text-size' + text_toolbar.props.icon_name = 'format-text' text_toolbar.props.label = _('Text') toolbar_box.toolbar.insert(text_toolbar, -1) @@ -83,60 +103,55 @@ class AbiWordActivity (activity.Activity): 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) + list_toolbar = ToolbarButton() + list_toolbar.props.page = ListToolbar(self.abiword_canvas) + list_toolbar.props.icon_name = 'toolbar-bulletlist' + list_toolbar.props.label = _('Bullet List') + toolbar_box.toolbar.insert(list_toolbar, -1) + + insert_toolbar = ToolbarButton() + insert_toolbar.props.page = InsertToolbar(self.abiword_canvas) + insert_toolbar.props.icon_name = 'insert-table' + insert_toolbar.props.label = _('Table') + toolbar_box.toolbar.insert(insert_toolbar, -1) separator = gtk.SeparatorToolItem() toolbar_box.toolbar.insert(separator, -1) - undo = UndoButton(sensitive=False) - undo.connect('clicked', lambda button: self.abiword_canvas.undo()) - self.abiword_canvas.connect("can-undo", lambda abi, can_undo: - undo.set_sensitive(can_undo)) - toolbar_box.toolbar.insert(undo, -1) - - redo = RedoButton(sensitive=False) - redo.connect('clicked', lambda button: self.abiword_canvas.redo()) - self.abiword_canvas.connect("can-redo", lambda abi, can_redo: - redo.set_sensitive(can_redo)) - toolbar_box.toolbar.insert(redo, -1) + bold = ToggleToolButton('format-text-bold') + bold.set_tooltip(_('Bold')) + bold_id = bold.connect('clicked', lambda sender: + self.abiword_canvas.toggle_bold()) + self.abiword_canvas.connect('bold', lambda abi, b: + self._setToggleButtonState(bold, b, bold_id)) + toolbar_box.toolbar.insert(bold, -1) + + italic = ToggleToolButton('format-text-italic') + italic.set_tooltip(_('Italic')) + italic_id = italic.connect('clicked', lambda sender: + self.abiword_canvas.toggle_italic()) + self.abiword_canvas.connect('italic', lambda abi, b: + self._setToggleButtonState(italic, b, italic_id)) + toolbar_box.toolbar.insert(italic, -1) + + underline = ToggleToolButton('format-text-underline') + underline.set_tooltip(_('Underline')) + underline_id = underline.connect('clicked', lambda sender: + self.abiword_canvas.toggle_underline()) + self.abiword_canvas.connect('underline', lambda abi, b: + self._setToggleButtonState(underline, b, underline_id)) + toolbar_box.toolbar.insert(underline, -1) separator = gtk.SeparatorToolItem() toolbar_box.toolbar.insert(separator, -1) - self.abiword_canvas.connect('text-selected', lambda abi, b: - copy.set_sensitive(True)) - self.abiword_canvas.connect('image-selected', lambda abi, b: - copy.set_sensitive(True)) - self.abiword_canvas.connect('selection-cleared', lambda abi, b: - copy.set_sensitive(False)) - - 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() - 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() - 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) + color = ColorToolButton() + color.connect('color-set', self._text_color_cb, self.abiword_canvas) + tool_item = gtk.ToolItem() + tool_item.add(color) + toolbar_box.toolbar.insert(tool_item, -1) + self.abiword_canvas.connect('color', lambda abi, r, g, b: + color.set_color(gtk.gdk.Color(r * 256, g * 256, b * 256))) separator = gtk.SeparatorToolItem() separator.props.draw = False @@ -156,6 +171,17 @@ class AbiWordActivity (activity.Activity): self._zoom_handler = self.abiword_canvas.connect("zoom", self.__zoom_cb) + 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 __zoom_cb(self, abi, zoom): abi.disconnect(self._zoom_handler) @@ -322,7 +348,7 @@ class AbiWordActivity (activity.Activity): if state == telepathy.TUBE_STATE_LOCAL_PENDING: self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].AcceptDBusTube(id) - initiator_path = None; + initiator_path = None contacts = self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].GetDBusNames(id) #print 'dbus contact mapping',self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].GetDBusNames(id) for i, struct in enumerate(contacts): @@ -331,7 +357,7 @@ class AbiWordActivity (activity.Activity): if handle == initiator: logger.debug('found initiator dbus path: %s', path) initiator_path = path - break; + break if initiator_path is None: logger.error('Unable to get the dbus path of the tube initiator') @@ -415,10 +441,10 @@ class AbiWordActivity (activity.Activity): # if we were viewing the source of a file, # then always save as plain text - actual_mimetype = self.metadata['mime_type']; + actual_mimetype = self.metadata['mime_type'] if 'source' in self.metadata and self.metadata['source'] == '1': logger.debug('Writing file as type source (text/plain)') actual_mimetype = 'text/plain' self.metadata['fulltext'] = self.abiword_canvas.get_content(extension_or_mimetype=".txt")[:3000] - self.abiword_canvas.save('file://' + file_path, actual_mimetype, ''); + self.abiword_canvas.save('file://' + file_path, actual_mimetype, '') diff --git a/icons/format-text.svg b/icons/format-text.svg new file mode 100644 index 0000000..075465b --- /dev/null +++ b/icons/format-text.svg @@ -0,0 +1,8 @@ +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'> +<svg enable-background="new 0 0 55 54.696" height="54.696px" version="1.1" viewBox="0 0 55 54.696" width="55px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="0px"> +<g display="block" id="format-text-size"> + <g display="inline"> + <path d="M22.263,12.435 h24.656 v3.562 H36.575 V41.59 h-3.969 V15.996 H22.263 V12.435z" fill="#FFFFFF"/> + <path d="M8.953,22.435 h16.656 v3.562 h-6.344 V41.59 h-3.969 V25.997 h-6.344 V24.435z" fill="#FFFFFF"/> + </g> +</g></svg> diff --git a/icons/insert-picture.svg b/icons/insert-picture.svg new file mode 100644 index 0000000..b8d4cf4 --- /dev/null +++ b/icons/insert-picture.svg @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [ + <!ENTITY fill_color "#FFFFFF"> + <!ENTITY stroke_color "#010101"> +]> +<svg xmlns="http://www.w3.org/2000/svg" width="55" height="55" id="insert-image.svg"> + <defs> + <mask id="Mask" maskUnits="userSpaceOnUse" x="0" y="0" width="55" height="55"> + <rect x="0" y="0" width="55" height="55" fill="white" /> + <line x1="35" y1="4" x2="35" y2="26" stroke-width="10.0" stroke="black" /> + <line x1="24" y1="15" x2="46" y2="15" stroke-width="10.0" stroke="black" /> + <polyline points="17.7,38.7 26.3,31 21,38.7" style="fill:black;;stroke:none;;stroke-width:0" /> + </mask> + </defs> + <g transform="translate(2,2)"> + <rect + style="opacity:1;fill:#000000;fill-opacity:0;stroke:#ffffff;stroke-width:2.89933752999999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3161" + width="37.150295" + height="28.059385" + x="7.0200901" + y="12.647797" /> + <polyline + points="13,39.7 27.6,29.6 34.3,33.6 34.3,39.7" + mask="url(#Mask)" + style="fill:#ffffff;stroke:#ffffff;stroke-width:3;stroke-opacity:1" + id="polyline23" + transform="matrix(0.9827085,0,0,0.9742491,10.040979,0.9463818)" /> + <polyline + points="5,35 13.7,32.3 20.3,34.1" + mask="url(#Mask)" + style="fill:none;stroke:#ffffff;stroke-width:2.50000000000000000;stroke-opacity:1" + id="polyline21" + transform="translate(3.3549781,4.1125541)" /> + </g> + <line fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="7" x1="28.376" x2="28.376" y1="30.664" y2="5.712"/> + <polyline fill="none" points="36.098,21.51 28.376,30.664 20.653,21.51" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="7"/> + <line fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.5" x1="28.376" x2="28.376" y1="30.664" y2="5.712"/> + <polyline fill="none" points="36.098,21.51 28.376,30.664 20.653,21.51" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.5"/> +</svg> diff --git a/icons/list-bullet.svg b/icons/list-bullet.svg index 02f1981..d812f52 100644 --- a/icons/list-bullet.svg +++ b/icons/list-bullet.svg @@ -93,4 +93,5 @@ sodipodi:rx="2.7942522" sodipodi:ry="2.7942522" d="M -23.899775,23.126896 A 2.7942522,2.7942522 0 1 1 -29.488279,23.126896 A 2.7942522,2.7942522 0 1 1 -23.899775,23.126896 z" - transform="matrix(0.87874,0,0,0.8787401,31.083695,-2.2657739)" /></svg>
\ No newline at end of file + transform="matrix(0.87874,0,0,0.8787401,31.083695,-2.2657739)" /> +</svg> diff --git a/icons/list-dashed.svg b/icons/list-dashed.svg index 7ee2ca8..855baf4 100644 --- a/icons/list-dashed.svg +++ b/icons/list-dashed.svg @@ -88,4 +88,5 @@ y1="18.90579" x2="13.115018" x1="3.0559719" - display="inline" /></svg>
\ No newline at end of file + display="inline" /> +</svg> diff --git a/icons/list-lower-case.svg b/icons/list-lower-case.svg index 8857a7c..bec734c 100644 --- a/icons/list-lower-case.svg +++ b/icons/list-lower-case.svg @@ -94,4 +94,4 @@ id="tspan3780" x="2.615895" y="23.543058">a</tspan></text> -</svg>
\ No newline at end of file +</svg> diff --git a/icons/list-none.svg b/icons/list-none.svg index fd4fe1c..dfee7f4 100644 --- a/icons/list-none.svg +++ b/icons/list-none.svg @@ -55,30 +55,32 @@ inkscape:current-layer="svg2" /><g id="g3212"><line display="inline" - x1="19.163853" - x2="50.163853" + x1="12.163853" + x2="43.163853" y1="14.47" y2="14.47" id="line5" style="fill:#4c4d4f;stroke:#ffffff;stroke-width:3.5;display:inline" /><line display="inline" - x1="19.163853" - x2="50.163853" + x1="12.163853" + x2="43.163853" y1="23.056" y2="23.056" id="line7" style="fill:#4c4d4f;stroke:#ffffff;stroke-width:3.5;display:inline" /><line display="inline" - x1="19.163853" - x2="50.163853" + x1="12.163853" + x2="43.163853" y1="31.641001" y2="31.641001" id="line9" style="fill:#4c4d4f;stroke:#ffffff;stroke-width:3.5;display:inline" /><line display="inline" - x1="19.163853" - x2="50.163853" + x1="12.163853" + x2="43.163853" y1="40.227001" y2="40.227001" id="line11" - style="fill:#4c4d4f;stroke:#ffffff;stroke-width:3.5;display:inline" /></g></svg>
\ No newline at end of file + style="fill:#4c4d4f;stroke:#ffffff;stroke-width:3.5;display:inline" /> + </g> +</svg> diff --git a/icons/list-numbered.svg b/icons/list-numbered.svg index acd0b51..cf49f5f 100644 --- a/icons/list-numbered.svg +++ b/icons/list-numbered.svg @@ -94,4 +94,4 @@ id="tspan3847" x="1.7835652" y="24.969913">1</tspan></text> -</svg>
\ No newline at end of file +</svg> diff --git a/icons/list-upper-case.svg b/icons/list-upper-case.svg index d94c2dc..0ac1bc5 100644 --- a/icons/list-upper-case.svg +++ b/icons/list-upper-case.svg @@ -94,4 +94,4 @@ id="tspan3914" x="2.2591829" y="24.494293">A</tspan></text> -</svg>
\ No newline at end of file +</svg> diff --git a/icons/paragraph-bar.svg b/icons/paragraph-bar.svg index d9203a1..7bcf016 100644 --- a/icons/paragraph-bar.svg +++ b/icons/paragraph-bar.svg @@ -66,7 +66,5 @@ id="tspan2387" x="4.5538874" y="15.777756">ΒΆ</tspan></text> - - </g> -</svg>
\ No newline at end of file +</svg> diff --git a/icons/paragraph-blocktext.svg b/icons/paragraph-blocktext.svg new file mode 100644 index 0000000..4ef08a5 --- /dev/null +++ b/icons/paragraph-blocktext.svg @@ -0,0 +1,12 @@ +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [ + <!ENTITY stroke_color "#010101"> + <!ENTITY fill_color "#FFFFFF"> +]> +<svg enable-background="new 0 0 55 55" height="55px" style="" version="1.1" viewBox="0 0 55 55" width="55px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" y="0px"> + <g display="block" id="paragraph-blocktext"> + <line fill="none" stroke="&fill_color;" stroke-width="3.5" x1="11.16" x2="44.16" y1="14.47" y2="14.47"/> + <line fill="none" stroke="&fill_color;" stroke-width="3.5" x1="11.16" x2="44.16" y1="23.06" y2="23.06"/> + <line fill="none" stroke="&fill_color;" stroke-width="3.5" x1="22.16" x2="44.16" y1="31.64" y2="31.64"/> + <line fill="none" stroke="&fill_color;" stroke-width="3.5" x1="22.16" x2="44.16" y1="40.23" y2="40.23"/> + </g> +</svg> diff --git a/icons/paragraph-h1.svg b/icons/paragraph-h1.svg new file mode 100644 index 0000000..2adb36c --- /dev/null +++ b/icons/paragraph-h1.svg @@ -0,0 +1,13 @@ +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [ + <!ENTITY stroke_color "#010101"> + <!ENTITY fill_color "#FFFFFF"> +]> +<svg enable-background="new 0 0 55 55" height="55px" style="" version="1.1" viewBox="0 0 55 55" width="55px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" y="0px"> + <g display="block" id="paragraph-h1"> + <text x="10" y="18.5" font-size="10" font-family="Bitstream Vera Sans" font-weight="bold" fill="&fill_color;" stroke="none">H1</text> + <line fill="none" stroke="&fill_color;" stroke-width="5" x1="26.16" x2="44.16" y1="14.47" y2="14.47"/> + <line fill="none" stroke="&fill_color;" stroke-width="5" x1="11.16" x2="44.16" y1="23.06" y2="23.06"/> + <line fill="none" stroke="&fill_color;" stroke-width="5" x1="11.16" x2="44.16" y1="31.64" y2="31.64"/> + <line fill="none" stroke="&fill_color;" stroke-width="5" x1="11.16" x2="44.16" y1="40.23" y2="40.23"/> + </g> +</svg> diff --git a/icons/paragraph-h2.svg b/icons/paragraph-h2.svg new file mode 100644 index 0000000..e8d3ee7 --- /dev/null +++ b/icons/paragraph-h2.svg @@ -0,0 +1,13 @@ +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [ + <!ENTITY stroke_color "#010101"> + <!ENTITY fill_color "#FFFFFF"> +]> +<svg enable-background="new 0 0 55 55" height="55px" style="" version="1.1" viewBox="0 0 55 55" width="55px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" y="0px"> + <g display="block" id="paragraph-h2"> + <text x="10" y="27.5" font-size="10" font-family="Bitstream Vera Sans" font-weight="bold" fill="&fill_color;" stroke="none">H2</text> + <line fill="none" stroke="&fill_color;" stroke-width="4" x1="11.16" x2="44.16" y1="14.47" y2="14.47"/> + <line fill="none" stroke="&fill_color;" stroke-width="4" x1="26.16" x2="44.16" y1="23.06" y2="23.06"/> + <line fill="none" stroke="&fill_color;" stroke-width="4" x1="11.16" x2="44.16" y1="31.64" y2="31.64"/> + <line fill="none" stroke="&fill_color;" stroke-width="4" x1="11.16" x2="44.16" y1="40.23" y2="40.23"/> + </g> +</svg> diff --git a/icons/paragraph-h3.svg b/icons/paragraph-h3.svg new file mode 100644 index 0000000..b7579ed --- /dev/null +++ b/icons/paragraph-h3.svg @@ -0,0 +1,13 @@ +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [ + <!ENTITY stroke_color "#010101"> + <!ENTITY fill_color "#FFFFFF"> +]> +<svg enable-background="new 0 0 55 55" height="55px" style="" version="1.1" viewBox="0 0 55 55" width="55px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" y="0px"> + <g display="block" id="paragraph-h3"> + <text x="10" y="35.5" font-size="10" font-family="Bitstream Vera Sans" font-weight="bold" fill="&fill_color;" stroke="none">H3</text> + <line fill="none" stroke="&fill_color;" stroke-width="3" x1="11.16" x2="44.16" y1="14.47" y2="14.47"/> + <line fill="none" stroke="&fill_color;" stroke-width="3" x1="11.16" x2="44.16" y1="23.06" y2="23.06"/> + <line fill="none" stroke="&fill_color;" stroke-width="3" x1="26.16" x2="44.16" y1="31.64" y2="31.64"/> + <line fill="none" stroke="&fill_color;" stroke-width="3" x1="11.16" x2="44.16" y1="40.23" y2="40.23"/> + </g> +</svg> diff --git a/icons/paragraph-h4.svg b/icons/paragraph-h4.svg new file mode 100644 index 0000000..1b9d1ce --- /dev/null +++ b/icons/paragraph-h4.svg @@ -0,0 +1,13 @@ +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [ + <!ENTITY stroke_color "#010101"> + <!ENTITY fill_color "#FFFFFF"> +]> +<svg enable-background="new 0 0 55 55" height="55px" style="" version="1.1" viewBox="0 0 55 55" width="55px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" y="0px"> + <g display="block" id="paragraph-h4"> + <text x="10" y="44" font-size="10" font-family="Bitstream Vera Sans" font-weight="bold" fill="&fill_color;" stroke="none">H4</text> + <line fill="none" stroke="&fill_color;" stroke-width="2" x1="11.16" x2="44.16" y1="14.47" y2="14.47"/> + <line fill="none" stroke="&fill_color;" stroke-width="2" x1="11.16" x2="44.16" y1="23.06" y2="23.06"/> + <line fill="none" stroke="&fill_color;" stroke-width="2" x1="11.16" x2="44.16" y1="31.64" y2="31.64"/> + <line fill="none" stroke="&fill_color;" stroke-width="2" x1="26.16" x2="44.16" y1="40.23" y2="40.23"/> + </g> +</svg> diff --git a/icons/paragraph-plaintext.svg b/icons/paragraph-plaintext.svg new file mode 100644 index 0000000..7ef2050 --- /dev/null +++ b/icons/paragraph-plaintext.svg @@ -0,0 +1,18 @@ +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [ + <!ENTITY stroke_color "#010101"> + <!ENTITY fill_color "#FFFFFF"> +]> +<svg enable-background="new 0 0 55 55" height="55px" style="" version="1.1" viewBox="0 0 55 55" width="55px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" y="0px"> + <g display="block" id="paragraph-plaintext"> + <text x="8" y="31.5" font-size="28" font-family="Bitstream Vera" font-weight="bold" font-style="italic" fill="&fill_color;" stroke="none">T</text> + <text x="31" y="42.5" font-size="28" font-family="Bitstream Vera Sans" font-weight="normal" fill="&fill_color;" stroke="none">T</text> + <g transform="translate(8,34)"> + <g transform="rotate(-45)"> + <g transform="scale(0.6)"> + <line fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.5" x1="28.376" x2="28.376" y1="30.664" y2="5.712"/> + <polyline fill="none" points="36.098,21.51 28.376,30.664 20.653,21.51" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.5"/> + </g> + </g> + </g> + </g> +</svg> diff --git a/icons/search-bar.svg b/icons/search-bar.svg deleted file mode 100644 index 34e4d5e..0000000 --- a/icons/search-bar.svg +++ /dev/null @@ -1,103 +0,0 @@ -<?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="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.90196078" - guidetolerance="10.0" - gridtolerance="10.0" - objecttolerance="10.0" - borderopacity="1.0" - bordercolor="#666666" - pagecolor="#a1a1a1" - id="base" - showgrid="false" - inkscape:zoom="41.704278" - inkscape:cx="17.054208" - inkscape:cy="9.0460986" - inkscape:window-x="0" - inkscape:window-y="16" - inkscape:current-layer="g3" - borderlayer="false" - showborder="true" - inkscape:showpageshadow="true" /> -<g - id="g3"> - - <rect - style="opacity:1;fill:#ffffff;fill-opacity:0.9;fill-rule:nonzero;stroke:#3f3f3f;stroke-width:0.99999964;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.9" - id="rect3245" - width="3.1647084" - height="7.8021984" - x="-1.8735586" - y="20.465549" - transform="matrix(0.6999914,-0.7141512,0.7141512,0.6999914,0,0)" /><path - d="M 2.7712159,9.5270226 C 2.7712159,13.233154 5.7738562,16.23849 9.480886,16.23849 C 13.183424,16.23849 16.188759,13.233154 16.188759,9.5270226 C 16.188759,5.8226881 13.183424,2.8191494 9.480886,2.8191494 C 5.7738562,2.8191494 2.7712159,5.8226881 2.7712159,9.5270226 z" - id="path5" - style="fill:none;stroke:#ffffff;stroke-width:3.14459634000000010;stroke-opacity:0.89999998" /> -<path - sodipodi:type="arc" - style="opacity:1;fill:#ffffff;fill-opacity:0;fill-rule:nonzero;stroke:#3f3f3f;stroke-width:0.37737417000000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.89999998" - id="path3758" - sodipodi:cx="-5.7568049" - sodipodi:cy="10.262735" - sodipodi:rx="3.2130997" - sodipodi:ry="2.8774025" - d="M -2.5437052,10.262735 A 3.2130997,2.8774025 0 1 1 -8.9699047,10.262735 A 3.2130997,2.8774025 0 1 1 -2.5437052,10.262735 z" - transform="matrix(2.5076449,0,0,2.8002036,23.987204,-19.204298)" /><path - sodipodi:type="arc" - style="opacity:1;fill:#ffffff;fill-opacity:0;fill-rule:nonzero;stroke:#3f3f3f;stroke-width:0.6316339;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.90000000000000002" - id="path3760" - sodipodi:cx="-5.7568049" - sodipodi:cy="10.262735" - sodipodi:rx="3.2130997" - sodipodi:ry="2.8774025" - d="M -2.5437052,10.262735 A 3.2130997,2.8774025 0 1 1 -8.9699047,10.262735 A 3.2130997,2.8774025 0 1 1 -2.5437052,10.262735 z" - transform="matrix(1.4982103,0,0,1.6730016,18.022419,-7.6261876)" /><path - sodipodi:type="arc" - style="opacity:1;fill:#ffffff;fill-opacity:0;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.9" - id="path2385" - sodipodi:cx="-18.08168" - sodipodi:cy="9.3755369" - sodipodi:rx="1.9182684" - sodipodi:ry="1.7024633" - d="M -16.163412,9.3755369 A 1.9182684,1.7024633 0 0 1 -17.387355,10.962566" - sodipodi:start="0" - sodipodi:end="1.2004329" - sodipodi:open="true" /><path - style="fill:none;fill-rule:evenodd;stroke:#f5f5f5;stroke-width:2.15084887px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.96078431" - d="M 14.456402,14.583424 L 16.158553,16.233575" - id="path3163" - inkscape:connector-type="polyline" /></g> -</svg>
\ No newline at end of file diff --git a/icons/toolbar-bulletlist.svg b/icons/toolbar-bulletlist.svg new file mode 100644 index 0000000..ed3b386 --- /dev/null +++ b/icons/toolbar-bulletlist.svg @@ -0,0 +1,14 @@ +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [ + <!ENTITY stroke_color "#010101"> + <!ENTITY fill_color "#FFFFFF"> +]> +<svg enable-background="new 0 0 55 55" height="55px" style="" version="1.1" viewBox="0 0 55 55" width="55px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" y="0px"> + <g display="block" id="toolbar-bulletlist"> + <circle cx="13.5" cy="14.47" r="3" fill="&fill_color;" stroke="none"/> + <text x="10" y="28.7" font-size="10" font-family="Bitstream Vera Sans" font-weight="bold" fill="&fill_color;" stroke="none">1</text> + <text x="10" y="39.5" font-size="10" font-family="Bitstream Vera Sans" font-weight="bold" fill="&fill_color;" stroke="none">A</text> + <line fill="none" stroke="&fill_color;" stroke-width="4" x1="21.16" x2="44.16" y1="14.57" y2="14.57"/> + <line fill="none" stroke="&fill_color;" stroke-width="4" x1="21.16" x2="44.16" y1="25.26" y2="25.26"/> + <line fill="none" stroke="&fill_color;" stroke-width="4" x1="21.16" x2="44.16" y1="35.64" y2="35.64"/> + </g> +</svg> @@ -22,33 +22,76 @@ import logging import abiword import gtk -from sugar.graphics.radiopalette import RadioMenuButton -from sugar.graphics.icon import Icon from sugar.graphics.toolbutton import ToolButton -from sugar.graphics.toggletoolbutton import ToggleToolButton -from sugar.graphics.colorbutton import ColorToolButton from sugar.graphics.toolcombobox import ToolComboBox -from sugar.graphics.objectchooser import ObjectChooser from sugar.graphics import iconentry -from sugar.activity import activity -from sugar.activity.widgets import * -from sugar.graphics.palette import Palette -from sugar import mime +from sugar.graphics import style +from sugar.activity.widgets import CopyButton +from sugar.activity.widgets import PasteButton +from sugar.activity.widgets import UndoButton +from sugar.activity.widgets import RedoButton from port import chooser -import sugar.profile -import widgets +from widgets import AbiButton +from widgets import FontCombo +from widgets import FontSizeCombo logger = logging.getLogger('write-activity') -class SearchToolbar(gtk.Toolbar): +class EditToolbar(gtk.Toolbar): + def __init__(self, pc, toolbar_box): + + gtk.Toolbar.__init__(self) - def __init__(self, abiword_canvas, text_toolbar): + self._abiword_canvas = pc.abiword_canvas - gtk.Toolbar.__init__(self) + copy = CopyButton() + copy.props.accelerator = '<Ctrl>C' + copy.connect('clicked', lambda button: pc.abiword_canvas.copy()) + self.insert(copy, -1) + copy.show() - self._abiword_canvas = abiword_canvas - self._text_toolbar = text_toolbar + paste = PasteButton() + paste.props.accelerator = '<Ctrl>V' + paste.connect('clicked', lambda button: pc.abiword_canvas.paste()) + self.insert(paste, -1) + paste.show() + + separator = gtk.SeparatorToolItem() + self.insert(separator, -1) + separator.show() + + undo = UndoButton(sensitive=False) + undo.connect('clicked', lambda button: pc.abiword_canvas.undo()) + pc.abiword_canvas.connect("can-undo", lambda abi, can_undo: + undo.set_sensitive(can_undo)) + self.insert(undo, -1) + undo.show() + + redo = RedoButton(sensitive=False) + redo.connect('clicked', lambda button: pc.abiword_canvas.redo()) + pc.abiword_canvas.connect("can-redo", lambda abi, can_redo: + redo.set_sensitive(can_redo)) + self.insert(redo, -1) + redo.show() + + pc.abiword_canvas.connect('text-selected', lambda abi, b: + copy.set_sensitive(True)) + pc.abiword_canvas.connect('image-selected', lambda abi, b: + copy.set_sensitive(True)) + pc.abiword_canvas.connect('selection-cleared', lambda abi, b: + copy.set_sensitive(False)) + + separator = gtk.SeparatorToolItem() + self.insert(separator, -1) + separator.show() + + search_label = gtk.Label(_("Search") + ": ") + search_label.show() + search_item_page_label = gtk.ToolItem() + search_item_page_label.add(search_label) + self.insert(search_item_page_label, -1) + search_item_page_label.show() # setup the search options self._search_entry = iconentry.IconEntry() @@ -56,20 +99,20 @@ class SearchToolbar(gtk.Toolbar): 'system-search') self._search_entry.connect('activate', self._search_entry_activated_cb) self._search_entry.connect('changed', self._search_entry_changed_cb) - self._search_entry.add_clear_button(); + self._search_entry.add_clear_button() self._add_widget(self._search_entry, expand=True) - self._findprev = ToolButton('go-previous') + self._findprev = ToolButton('go-previous-paired') self._findprev.set_tooltip(_('Find previous')) self.insert(self._findprev, -1) self._findprev.show() - self._findprev.connect('clicked', self._findprev_cb); + self._findprev.connect('clicked', self._findprev_cb) - self._findnext = ToolButton('go-next') + self._findnext = ToolButton('go-next-paired') self._findnext.set_tooltip(_('Find next')) self.insert(self._findnext, -1) self._findnext.show() - self._findnext.connect('clicked', self._findnext_cb); + self._findnext.connect('clicked', self._findnext_cb) # set the initial state of the search controls # note: we won't simple call self._search_entry_changed_cb @@ -141,6 +184,10 @@ class InsertToolbar(gtk.Toolbar): self._table = abiword.TableCreator() self._table.set_labels(_('Table'), _('Cancel')) self._table_id = self._table.connect('selected', self._table_cb) + image = gtk.Image() + image.set_from_icon_name('insert-table', -1) + self._table.set_image(image) + self._table.set_relief(gtk.RELIEF_NONE) tool_item = gtk.ToolItem() tool_item.add(self._table) self.insert(tool_item, -1) @@ -148,28 +195,32 @@ class InsertToolbar(gtk.Toolbar): self._table_rows_after = ToolButton('row-insert') self._table_rows_after.set_tooltip(_('Insert Row')) - self._table_rows_after_id = self._table_rows_after.connect('clicked', self._table_rows_after_cb) + self._table_rows_after_id = self._table_rows_after.connect( \ + 'clicked', self._table_rows_after_cb) self.insert(self._table_rows_after, -1) self._table_delete_rows = ToolButton('row-remove') self._table_delete_rows.set_tooltip(_('Delete Row')) - self._table_delete_rows_id = self._table_delete_rows.connect('clicked', self._table_delete_rows_cb) + self._table_delete_rows_id = self._table_delete_rows.connect( \ + 'clicked', self._table_delete_rows_cb) self.insert(self._table_delete_rows, -1) self._table_cols_after = ToolButton('column-insert') self._table_cols_after.set_tooltip(_('Insert Column')) - self._table_cols_after_id = self._table_cols_after.connect('clicked', self._table_cols_after_cb) + self._table_cols_after_id = self._table_cols_after.connect( \ + 'clicked', self._table_cols_after_cb) self.insert(self._table_cols_after, -1) self._table_delete_cols = ToolButton('column-remove') self._table_delete_cols.set_tooltip(_('Delete Column')) - self._table_delete_cols_id = self._table_delete_cols.connect('clicked', self._table_delete_cols_cb) + self._table_delete_cols_id = self._table_delete_cols.connect( \ + 'clicked', self._table_delete_cols_cb) self.insert(self._table_delete_cols, -1) separator = gtk.SeparatorToolItem() self.insert(separator, -1) - image = ToolButton('insert-image') + image = ToolButton('insert-picture') image.set_tooltip(_('Insert Image')) self._image_id = image.connect('clicked', self._image_cb) self.insert(image, -1) @@ -186,7 +237,7 @@ class InsertToolbar(gtk.Toolbar): chooser.pick(what=chooser.IMAGE, cb=cb) def _table_cb(self, abi, rows, cols): - self._abiword_canvas.insert_table(rows,cols) + self._abiword_canvas.insert_table(rows, cols) def _table_rows_after_cb(self, button): self._abiword_canvas.invoke_cmd('insertRowsAfter', '', 0, 0) @@ -211,7 +262,7 @@ class ViewToolbar(gtk.Toolbar): gtk.Toolbar.__init__(self) self._abiword_canvas = abiword_canvas - self._zoom_percentage = 0; + self._zoom_percentage = 0 self._zoom_out = ToolButton('zoom-out') self._zoom_out.set_tooltip(_('Zoom Out')) @@ -228,7 +279,8 @@ class ViewToolbar(gtk.Toolbar): # TODO: fix the initial value self._zoom_spin_adj = gtk.Adjustment(0, 25, 400, 25, 50, 0) self._zoom_spin = gtk.SpinButton(self._zoom_spin_adj, 0, 0) - self._zoom_spin_id = self._zoom_spin.connect('value-changed', self._zoom_spin_cb) + self._zoom_spin_id = self._zoom_spin.connect('value-changed', + self._zoom_spin_cb) self._zoom_spin.set_numeric(True) self._zoom_spin.show() tool_item_zoom = gtk.ToolItem() @@ -255,9 +307,10 @@ class ViewToolbar(gtk.Toolbar): self.insert(tool_item_page_label, -1) tool_item_page_label.show() - self._page_spin_adj = gtk.Adjustment(0, 1, 0, 1, 1, 0) + self._page_spin_adj = gtk.Adjustment(0, 1, 0, -1, -1, 0) self._page_spin = gtk.SpinButton(self._page_spin_adj, 0, 0) - self._page_spin_id = self._page_spin.connect('value-changed', self._page_spin_cb) + self._page_spin_id = self._page_spin.connect('value-changed', + self._page_spin_cb) self._page_spin.set_numeric(True) self._page_spin.show() tool_item_page = gtk.ToolItem() @@ -304,12 +357,12 @@ class ViewToolbar(gtk.Toolbar): self._abiword_canvas.set_zoom_percentage(self._zoom_percentage) def _page_spin_cb(self, button): - self._page_num = self._page_spin.get_value_as_int() - self._abiword_canvas.set_current_page(self._page_num) + page_num = self._page_spin.get_value_as_int() + self._abiword_canvas.set_current_page(page_num) def _page_count_cb(self, canvas, count): current_page = canvas.get_current_page_num() - self._page_spin_adj.set_all(current_page, 1, count, 1, 1, 0) + self._page_spin_adj.set_all(current_page, 1, count, -1, -1, 0) self._total_page_label.props.label = \ ' / ' + str(count) @@ -324,95 +377,134 @@ class TextToolbar(gtk.Toolbar): def __init__(self, abiword_canvas): gtk.Toolbar.__init__(self) - font_name = ToolComboBox(widgets.FontCombo(abiword_canvas)) + font_name = ToolComboBox(FontCombo(abiword_canvas)) self.insert(font_name, -1) - font_size = ToolComboBox(widgets.FontSizeCombo(abiword_canvas)) + font_size = ToolComboBox(FontSizeCombo(abiword_canvas)) self.insert(font_size, -1) - separator = gtk.SeparatorToolItem() - self.insert(separator, -1) - - bold = ToggleToolButton('format-text-bold') - bold.set_tooltip(_('Bold')) - bold_id = bold.connect('clicked', lambda sender: - abiword_canvas.toggle_bold()) - 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()) - 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()) - abiword_canvas.connect('underline', lambda abi, b: - self._setToggleButtonState(underline, b, underline_id)) - self.insert(underline, -1) - - separator = gtk.SeparatorToolItem() - self.insert(separator, -1) - - color = ColorToolButton() - color.connect('color-set', self._text_color_cb, abiword_canvas) - tool_item = gtk.ToolItem() - tool_item.add(color) - self.insert(tool_item, -1) - abiword_canvas.connect('color', lambda abi, r, g, b: - color.set_color(gtk.gdk.Color(r * 256, g * 256, b * 256))) + # MAGIC NUMBER WARNING: Secondary toolbars are not a standard height? + self.set_size_request(-1, style.GRID_CELL_SIZE) self.show_all() - 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) - class ParagraphToolbar(gtk.Toolbar): def __init__(self, abi): gtk.Toolbar.__init__(self) - self.insert(ToolComboBox(widgets.StyleCombo(abi)), -1) + def append_style(icon_name, tooltip, do_abi_cb, on_abi_cb): + button = AbiButton(abi, 'style-name', do_abi_cb, on_abi_cb) + button.props.icon_name = icon_name + button.props.group = group + button.props.tooltip = tooltip + self.insert(button, -1) + return button + + group = None + + group = append_style('list-none', _('Normal'), + lambda: + abi.set_style('Normal'), + lambda abi, style: + style not in ['Heading 1', + 'Heading 2', + 'Heading 3', + 'Heading 4', + 'Block Text', + 'Plain Text']) + + append_style('paragraph-h1', _('Heading 1'), + lambda: abi.set_style('Heading 1'), + lambda abi, style: style == 'Heading 1') + + append_style('paragraph-h2', _('Heading 2'), + lambda: abi.set_style('Heading 2'), + lambda abi, style: style == 'Heading 2') + + append_style('paragraph-h3', _('Heading 3'), + lambda: abi.set_style('Heading 3'), + lambda abi, style: style == 'Heading 3') + + append_style('paragraph-h4', _('Heading 4'), + lambda: abi.set_style('Heading 4'), + lambda abi, style: style == 'Heading 4') + + append_style('paragraph-blocktext', _('Block Text'), + lambda: abi.set_style('Block Text'), + lambda abi, style: style == 'Block Text') + + append_style('paragraph-plaintext', _('Plain Text'), + lambda: abi.set_style('Plain Text'), + lambda abi, style: style == 'Plain Text') + 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) + def append_align(icon_name, tooltip, do_abi_cb, style_name): + button = AbiButton(abi, style_name, do_abi_cb) + button.props.icon_name = icon_name + button.props.group = group + button.props.tooltip = tooltip + self.insert(button, -1) + return button - self.insert(gtk.SeparatorToolItem(), -1) - lists = RadioMenuButton(palette=widgets.ListsPalette(abi)) - self.insert(lists, -1) + group = None + + group = append_align('format-justify-left', _('Left justify'), + abi.align_left, 'left-align') + + append_align('format-justify-center', _('Center justify'), + abi.align_center, 'center-align') + + append_align('format-justify-right', _('Right justify'), + abi.align_right, 'right-align') + + append_align('format-justify-fill', _('Fill justify'), + abi.align_justify, 'justify-align') + + self.show_all() + +class ListToolbar(gtk.Toolbar): + def __init__(self, abi): + gtk.Toolbar.__init__(self) + + def append(icon_name, tooltip, do_abi_cb, on_abi_cb): + button = AbiButton(abi, 'style-name', do_abi_cb, on_abi_cb) + button.props.icon_name = icon_name + button.props.group = group + button.props.tooltip = tooltip + self.insert(button, -1) + return button + + group = None + + 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']) + + append('list-bullet', _('Bullet List'), + lambda: abi.set_style('Bullet List'), + lambda abi, style: style == 'Bullet List') + + append('list-dashed', _('Dashed List'), + lambda: abi.set_style('Dashed List'), + lambda abi, style: style == 'Dashed List') + + append('list-numbered', _('Numbered List'), + lambda: abi.set_style('Numbered List'), + lambda abi, style: style == 'Numbered List') + + append('list-lower-case', _('Lower Case List'), + lambda: abi.set_style('Lower Case List'), + lambda abi, style: style == 'Lower Case List') + + append('list-upper-case', _('Upper Case List'), + lambda: abi.set_style('Upper Case List'), + lambda abi, style: style == 'Upper Case List') self.show_all() @@ -13,7 +13,6 @@ # 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 _ @@ -22,7 +21,6 @@ import logging 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.toolbutton import ToolButton from sugar.graphics.menuitem import MenuItem from sugar.datastore import datastore @@ -61,7 +59,7 @@ class FontCombo(ComboBox): for i, f in enumerate(self._fonts): if f == font_family: font_index = i - break; + break # if we don't know this font yet, then add it (temporary) to the list if font_index == -1: @@ -120,80 +118,7 @@ class FontSizeCombo(ComboBox): self.handler_block(self._changed_id) self.set_active(i) self.handler_unblock(self._changed_id) - break; - -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')], - ['Heading 4', _('Heading 4')], - ['Bullet List', _('Bullet List')], - ['Dashed List', _('Dashed List')], - ['Numbered List', _('Numbered List')], - ['Lower Case List', _('Lower Case List')], - ['Upper Case List', _('Upper Case List')], - ['Block Text', _('Block Text')], - ['Normal', _('Normal')], - ['Plain Text', _('Plain Text')] ] - - self._has_custom_styles = False - self._style_changed_id = self.connect('changed', self._style_changed_cb, - abi) - - for i, s in enumerate(self._styles): - self.append_item(i, s[1], None) - if s[0] == 'Normal': - self.set_active(i) - - def _style_changed_cb(self, combobox, abi): - if self.get_active() != -1: - logger.debug('Set style: %s', 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': - style_name = 'Normal' - - style_index = -1 - for i, s in enumerate(self._styles): - if s[0] == style_name: - style_index = i - break; - - # if we don't know this style yet, then add it (temporary) to the list - if style_index == -1: - logger.debug('Style not found in style list: %s', style_name) - - if not self._has_custom_styles: - # add a separator to seperate the non-available styles from - # the available ones - self._styles.append(['','']) # ugly - self.append_separator() - self._has_custom_styles = True - - # add the new style - self._styles.append([style_name, style_name]) - self.append_item(0, style_name, None) - - # see how many styles we have now, so we can select the last one - model = self.get_model() - num_children = model.iter_n_children(None) - logger.debug('Number of styles in the list: %d', num_children) - style_index = num_children-1 - - if style_index > -1: - self.handler_block(self._style_changed_id) - self.set_active(style_index) - self.handler_unblock(self._style_changed_id) + break class AbiButton(RadioToolButton): def __init__(self, abi, abi_signal, do_abi_cb, on_abi_cb=None, **kwargs): @@ -227,52 +152,6 @@ class AbiButton(RadioToolButton): finally: self.handler_unblock(self._toggled_handler) -class ListsPalette(RadioPalette): - def __init__(self, abi): - RadioPalette.__init__(self) - - 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 - - group = None - - 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']) - - append('list-bullet', _('Bullet List'), - lambda: abi.set_style('Bullet List'), - lambda abi, style: style == 'Bullet List') - - append('list-dashed', _('Dashed List'), - lambda: abi.set_style('Dashed List'), - lambda abi, style: style == 'Dashed List') - - append('list-numbered', _('Numbered List'), - lambda: abi.set_style('Numbered List'), - lambda abi, style: style == 'Numbered List') - - append('list-lower-case', _('Lower Case List'), - lambda: abi.set_style('Lower Case List'), - lambda abi, style: style == 'Lower Case List') - - append('list-upper-case', _('Upper Case List'), - lambda: abi.set_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)'), @@ -314,13 +193,13 @@ class ExportButton(ToolButton): # 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'] + ';'; + 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'] + ')'; + 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( |