1 # Copyright (C) 2007, One Laptop Per Child
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 from gettext
import gettext
as _
24 from sugar
.graphics
import style
25 from sugar
.graphics
.toolbutton
import ToolButton
26 from sugar
.datastore
import datastore
28 from listview
import ListView
29 from collapsedentry
import BaseCollapsedEntry
30 from journaltoolbox
import SearchToolbar
31 from volumestoolbar
import VolumesToolbar
33 class ObjectChooser(gtk
.Window
):
35 __gtype_name__
= 'ObjectChooser'
38 'response': (gobject
.SIGNAL_RUN_FIRST
,
43 def __init__(self
, parent
=None):
44 gtk
.Window
.__init
__(self
)
45 self
.set_type_hint(gtk
.gdk
.WINDOW_TYPE_HINT_DIALOG
)
46 self
.set_decorated(False)
47 self
.set_position(gtk
.WIN_POS_CENTER_ALWAYS
)
48 self
.set_border_width(style
.LINE_WIDTH
)
50 self
._selected
_object
_id
= None
52 self
.add_events(gtk
.gdk
.VISIBILITY_NOTIFY_MASK
)
53 self
.connect('visibility-notify-event',
54 self
.__visibility
_notify
_event
_cb
)
55 self
.connect('delete-event', self
.__delete
_event
_cb
)
56 self
.connect('key-press-event', self
.__key
_press
_event
_cb
)
57 if parent
is not None:
58 self
.connect('realize', self
.__realize
_cb
, parent
)
64 title_box
= TitleBox()
65 title_box
.connect('volume-changed', self
.__volume
_changed
_cb
)
66 title_box
.close_button
.connect('clicked',
67 self
.__close
_button
_clicked
_cb
)
68 title_box
.set_size_request(-1, style
.GRID_CELL_SIZE
)
69 vbox
.pack_start(title_box
, expand
=False)
72 separator
= gtk
.HSeparator()
73 vbox
.pack_start(separator
, expand
=False)
76 self
._toolbar
= SearchToolbar()
77 self
._toolbar
.connect('query-changed', self
.__query
_changed
_cb
)
78 self
._toolbar
.set_size_request(-1, style
.GRID_CELL_SIZE
)
79 vbox
.pack_start(self
._toolbar
, expand
=False)
82 self
._list
_view
= ChooserListView()
83 self
._list
_view
.connect('entry-activated', self
.__entry
_activated
_cb
)
84 vbox
.pack_start(self
._list
_view
)
85 self
._list
_view
.show()
87 self
._toolbar
.set_volume_id(datastore
.mounts()[0]['id'])
89 width
= gtk
.gdk
.screen_width() - style
.GRID_CELL_SIZE
* 2
90 height
= gtk
.gdk
.screen_height() - style
.GRID_CELL_SIZE
* 2
91 self
.set_size_request(width
, height
)
93 def __realize_cb(self
, chooser
, parent
):
94 self
.window
.set_transient_for(parent
)
95 # TODO: Should we disconnect the signal here?
97 def __entry_activated_cb(self
, list_view
, entry
):
98 self
._selected
_object
_id
= entry
.jobject
.object_id
99 self
.emit('response', gtk
.RESPONSE_ACCEPT
)
101 def __delete_event_cb(self
, chooser
, event
):
102 self
.emit('response', gtk
.RESPONSE_DELETE_EVENT
)
104 def __key_press_event_cb(self
, widget
, event
):
105 keyname
= gtk
.gdk
.keyval_name(event
.keyval
)
106 if keyname
== 'Escape':
107 self
.emit('response', gtk
.RESPONSE_DELETE_EVENT
)
109 def __close_button_clicked_cb(self
, button
):
110 self
.emit('response', gtk
.RESPONSE_DELETE_EVENT
)
112 def get_selected_object_id(self
):
113 return self
._selected
_object
_id
115 def __query_changed_cb(self
, toolbar
, query
):
116 self
._list
_view
.update_with_query(query
)
118 def __volume_changed_cb(self
, volume_toolbar
, volume_id
):
119 logging
.debug('Selected volume: %r.' % volume_id
)
120 self
._toolbar
.set_volume_id(volume_id
)
122 def __visibility_notify_event_cb(self
, window
, event
):
123 logging
.debug('visibility_notify_event_cb %r' % self
)
124 visible
= event
.state
== gtk
.gdk
.VISIBILITY_FULLY_OBSCURED
125 self
._list
_view
.set_is_visible(visible
)
127 class TitleBox(VolumesToolbar
):
128 __gtype_name__
= 'TitleBox'
131 VolumesToolbar
.__init
__(self
)
134 label
.set_markup('<b>%s</b>' % _('Choose an object'))
135 label
.set_alignment(0, 0.5)
136 self
._add
_widget
(label
, expand
=True)
138 self
.close_button
= ToolButton(icon_name
='dialog-cancel')
139 self
.close_button
.set_tooltip(_('Close'))
140 self
.insert(self
.close_button
, -1)
141 self
.close_button
.show()
143 def _add_widget(self
, widget
, expand
=False):
144 tool_item
= gtk
.ToolItem()
145 tool_item
.set_expand(expand
)
147 tool_item
.add(widget
)
150 self
.insert(tool_item
, -1)
153 class ChooserCollapsedEntry(BaseCollapsedEntry
):
154 __gtype_name__
= 'ChooserCollapsedEntry'
157 'entry-activated': (gobject
.SIGNAL_RUN_FIRST
,
163 BaseCollapsedEntry
.__init
__(self
)
165 self
.connect_after('button-release-event',
166 self
.__button
_release
_event
_cb
)
167 self
.connect('motion-notify-event', self
.__motion
_notify
_event
_cb
)
169 def __button_release_event_cb(self
, entry
, event
):
170 self
.emit('entry-activated')
173 def __motion_notify_event_cb(self
, entry
, event
):
174 if event
.detail
== hippo
.MOTION_DETAIL_ENTER
:
175 self
.props
.background_color
= style
.COLOR_PANEL_GREY
.get_int()
176 elif event
.detail
== hippo
.MOTION_DETAIL_LEAVE
:
177 self
.props
.background_color
= style
.COLOR_WHITE
.get_int()
180 class ChooserListView(ListView
):
181 __gtype_name__
= 'ChooserListView'
184 'entry-activated': (gobject
.SIGNAL_RUN_FIRST
,
190 ListView
.__init
__(self
)
192 def create_entry(self
):
193 entry
= ChooserCollapsedEntry()
194 entry
.connect('entry-activated', self
.__entry
_activated
_cb
)
197 def __entry_activated_cb(self
, entry
):
198 self
.emit('entry-activated', entry
)