Merge lp:~bratsche/gwibber/input-focus into lp:gwibber
- input-focus
- Merge into trunk
Proposed by
Cody Russell
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~bratsche/gwibber/input-focus |
Merge into: | lp:gwibber |
Diff against target: |
482 lines (+61/-56) 2 files modified
gwibber/client.py (+18/-16) gwibber/gwui.py (+43/-40) |
To merge this branch: | bzr merge lp:~bratsche/gwibber/input-focus |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ken VanDine | Approve | ||
Review via email: mp+21578@code.launchpad.net |
Commit message
Description of the change
Sets the focus children so that the text input widget has the focus.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'gwibber/client.py' | |||
2 | --- gwibber/client.py 2010-03-17 17:17:13 +0000 | |||
3 | +++ gwibber/client.py 2010-03-17 17:37:30 +0000 | |||
4 | @@ -26,7 +26,7 @@ | |||
5 | 26 | self.ui = gtk.Builder() | 26 | self.ui = gtk.Builder() |
6 | 27 | 27 | ||
7 | 28 | self.model = gwui.Model() | 28 | self.model = gwui.Model() |
9 | 29 | 29 | ||
10 | 30 | self.service = self.model.daemon | 30 | self.service = self.model.daemon |
11 | 31 | self.service.connect_to_signal("LoadingStarted", self.on_loading_started) | 31 | self.service.connect_to_signal("LoadingStarted", self.on_loading_started) |
12 | 32 | self.service.connect_to_signal("LoadingComplete", self.on_loading_complete) | 32 | self.service.connect_to_signal("LoadingComplete", self.on_loading_complete) |
13 | @@ -51,7 +51,7 @@ | |||
14 | 51 | self.service.Refresh() | 51 | self.service.Refresh() |
15 | 52 | 52 | ||
16 | 53 | self.setup_ui() | 53 | self.setup_ui() |
18 | 54 | 54 | ||
19 | 55 | # set state online/offline | 55 | # set state online/offline |
20 | 56 | if not self.connection.isConnected(): | 56 | if not self.connection.isConnected(): |
21 | 57 | log.logger.info("Setting to Offline") | 57 | log.logger.info("Setting to Offline") |
22 | @@ -74,7 +74,7 @@ | |||
23 | 74 | resources.get_ui_asset("gwibber.svg"), 24, 24)) | 74 | resources.get_ui_asset("gwibber.svg"), 24, 24)) |
24 | 75 | self.set_icon_name("gwibber") | 75 | self.set_icon_name("gwibber") |
25 | 76 | self.connect("delete-event", self.on_window_close) | 76 | self.connect("delete-event", self.on_window_close) |
27 | 77 | 77 | ||
28 | 78 | # Load the application menu | 78 | # Load the application menu |
29 | 79 | menu_ui = self.setup_menu() | 79 | menu_ui = self.setup_menu() |
30 | 80 | self.add_accel_group(menu_ui.get_accel_group()) | 80 | self.add_accel_group(menu_ui.get_accel_group()) |
31 | @@ -92,7 +92,7 @@ | |||
32 | 92 | 92 | ||
33 | 93 | menubar = menu_ui.get_widget("/menubar_main") | 93 | menubar = menu_ui.get_widget("/menubar_main") |
34 | 94 | menubar.append(menu_spin) | 94 | menubar.append(menu_spin) |
36 | 95 | 95 | ||
37 | 96 | view_class = getattr(gwui, | 96 | view_class = getattr(gwui, |
38 | 97 | "MultiStreamUi" if len(self.model.settings["streams"]) > 1 | 97 | "MultiStreamUi" if len(self.model.settings["streams"]) > 1 |
39 | 98 | else "SingleStreamUi") | 98 | else "SingleStreamUi") |
40 | @@ -104,7 +104,7 @@ | |||
41 | 104 | self.stream_view.connect("stream-closed", self.on_stream_closed) | 104 | self.stream_view.connect("stream-closed", self.on_stream_closed) |
42 | 105 | if isinstance(self.stream_view, gwui.MultiStreamUi): | 105 | if isinstance(self.stream_view, gwui.MultiStreamUi): |
43 | 106 | self.stream_view.connect("pane-closed", self.on_pane_closed) | 106 | self.stream_view.connect("pane-closed", self.on_pane_closed) |
45 | 107 | 107 | ||
46 | 108 | self.input = gwui.Input() | 108 | self.input = gwui.Input() |
47 | 109 | self.input.connect("submit", self.on_input_activate) | 109 | self.input.connect("submit", self.on_input_activate) |
48 | 110 | self.input.connect("changed", self.on_input_changed) | 110 | self.input.connect("changed", self.on_input_changed) |
49 | @@ -113,6 +113,8 @@ | |||
50 | 113 | self.input_splitter.pack1(self.stream_view, resize=True) | 113 | self.input_splitter.pack1(self.stream_view, resize=True) |
51 | 114 | self.input_splitter.pack2(self.input, resize=False) | 114 | self.input_splitter.pack2(self.input, resize=False) |
52 | 115 | 115 | ||
53 | 116 | self.input_splitter.set_focus_child(self.input) | ||
54 | 117 | |||
55 | 116 | self.button_send = gtk.Button(_("Send")) | 118 | self.button_send = gtk.Button(_("Send")) |
56 | 117 | self.button_send.connect("clicked", self.on_button_send_clicked) | 119 | self.button_send.connect("clicked", self.on_button_send_clicked) |
57 | 118 | 120 | ||
58 | @@ -125,7 +127,7 @@ | |||
59 | 125 | content.pack_start(self.input_splitter, True) | 127 | content.pack_start(self.input_splitter, True) |
60 | 126 | content.pack_start(self.message_target, False) | 128 | content.pack_start(self.message_target, False) |
61 | 127 | content.set_border_width(5) | 129 | content.set_border_width(5) |
63 | 128 | 130 | ||
64 | 129 | layout = gtk.VBox() | 131 | layout = gtk.VBox() |
65 | 130 | layout.pack_start(menubar, False) | 132 | layout.pack_start(menubar, False) |
66 | 131 | layout.pack_start(content, True) | 133 | layout.pack_start(content, True) |
67 | @@ -147,16 +149,16 @@ | |||
68 | 147 | if self.stream_view: | 149 | if self.stream_view: |
69 | 148 | state = self.stream_view.get_state() | 150 | state = self.stream_view.get_state() |
70 | 149 | self.stream_view.destroy() | 151 | self.stream_view.destroy() |
72 | 150 | 152 | ||
73 | 151 | self.stream_view = self.view_class(self.model) | 153 | self.stream_view = self.view_class(self.model) |
74 | 152 | self.stream_view.connect("action", self.on_action) | 154 | self.stream_view.connect("action", self.on_action) |
75 | 153 | self.stream_view.connect("search", self.on_perform_search) | 155 | self.stream_view.connect("search", self.on_perform_search) |
76 | 154 | self.stream_view.connect("stream-changed", self.on_stream_changed) | 156 | self.stream_view.connect("stream-changed", self.on_stream_changed) |
77 | 155 | self.stream_view.connect("stream-closed", self.on_stream_closed) | 157 | self.stream_view.connect("stream-closed", self.on_stream_closed) |
79 | 156 | 158 | ||
80 | 157 | if isinstance(self.stream_view, gwui.MultiStreamUi): | 159 | if isinstance(self.stream_view, gwui.MultiStreamUi): |
81 | 158 | self.stream_view.connect("pane-closed", self.on_pane_closed) | 160 | self.stream_view.connect("pane-closed", self.on_pane_closed) |
83 | 159 | 161 | ||
84 | 160 | self.input_splitter.add1(self.stream_view) | 162 | self.input_splitter.add1(self.stream_view) |
85 | 161 | self.stream_view.show_all() | 163 | self.stream_view.show_all() |
86 | 162 | if state: self.stream_view.set_state(state) | 164 | if state: self.stream_view.set_state(state) |
87 | @@ -223,7 +225,7 @@ | |||
88 | 223 | ("help_report", None, _("Report A Problem..."), None, None, lambda *a: util.load_url(BUG_URL)), | 225 | ("help_report", None, _("Report A Problem..."), None, None, lambda *a: util.load_url(BUG_URL)), |
89 | 224 | ]) | 226 | ]) |
90 | 225 | 227 | ||
92 | 226 | 228 | ||
93 | 227 | ui = gtk.UIManager() | 229 | ui = gtk.UIManager() |
94 | 228 | ui.insert_action_group(self.actions, pos=0) | 230 | ui.insert_action_group(self.actions, pos=0) |
95 | 229 | ui.add_ui_from_string(ui_string) | 231 | ui.add_ui_from_string(ui_string) |
96 | @@ -243,7 +245,7 @@ | |||
97 | 243 | if "reply" in features: | 245 | if "reply" in features: |
98 | 244 | if message["sender"].get("nick", 0) and not "thread" in features: | 246 | if message["sender"].get("nick", 0) and not "thread" in features: |
99 | 245 | self.input.set_text("@%s: " % message["sender"]["nick"]) | 247 | self.input.set_text("@%s: " % message["sender"]["nick"]) |
101 | 246 | 248 | ||
102 | 247 | self.message_target.set_target(message) | 249 | self.message_target.set_target(message) |
103 | 248 | self.input.textview.grab_focus() | 250 | self.input.textview.grab_focus() |
104 | 249 | buf = self.input.textview.get_buffer() | 251 | buf = self.input.textview.get_buffer() |
105 | @@ -254,7 +256,7 @@ | |||
106 | 254 | 256 | ||
107 | 255 | def get_message(self, id): | 257 | def get_message(self, id): |
108 | 256 | return dict(self.model.messages.get_record(id).items()) | 258 | return dict(self.model.messages.get_record(id).items()) |
110 | 257 | 259 | ||
111 | 258 | def on_refresh(self, *args): | 260 | def on_refresh(self, *args): |
112 | 259 | self.service.Refresh() | 261 | self.service.Refresh() |
113 | 260 | 262 | ||
114 | @@ -262,7 +264,7 @@ | |||
115 | 262 | id = self.model.streams.put_record(CouchRecord(data, kind)) | 264 | id = self.model.streams.put_record(CouchRecord(data, kind)) |
116 | 263 | self.model.refresh() | 265 | self.model.refresh() |
117 | 264 | self.service.PerformOp('{"id": "%s"}' % id) | 266 | self.service.PerformOp('{"id": "%s"}' % id) |
119 | 265 | 267 | ||
120 | 266 | if "operation" in data: | 268 | if "operation" in data: |
121 | 267 | stream = str(self.model.features[data["operation"]]["stream"]) | 269 | stream = str(self.model.features[data["operation"]]["stream"]) |
122 | 268 | else: stream = "search" | 270 | else: stream = "search" |
123 | @@ -348,7 +350,7 @@ | |||
124 | 348 | def on_message_action_menu(self, msg): | 350 | def on_message_action_menu(self, msg): |
125 | 349 | theme = gtk.icon_theme_get_default() | 351 | theme = gtk.icon_theme_get_default() |
126 | 350 | menu = gtk.Menu() | 352 | menu = gtk.Menu() |
128 | 351 | 353 | ||
129 | 352 | for a in actions.MENU_ITEMS: | 354 | for a in actions.MENU_ITEMS: |
130 | 353 | if a.include(self, msg): | 355 | if a.include(self, msg): |
131 | 354 | image = gtk.image_new_from_icon_name(a.icon, gtk.ICON_SIZE_MENU) | 356 | image = gtk.image_new_from_icon_name(a.icon, gtk.ICON_SIZE_MENU) |
132 | @@ -399,14 +401,14 @@ | |||
133 | 399 | self.service.Send(json.dumps(data)) | 401 | self.service.Send(json.dumps(data)) |
134 | 400 | self.message_target.end() | 402 | self.message_target.end() |
135 | 401 | else: self.service.SendMessage(text) | 403 | else: self.service.SendMessage(text) |
137 | 402 | 404 | ||
138 | 403 | def on_new_stream(self, *args): | 405 | def on_new_stream(self, *args): |
139 | 404 | if isinstance(self.stream_view, gwui.MultiStreamUi): | 406 | if isinstance(self.stream_view, gwui.MultiStreamUi): |
140 | 405 | self.stream_view.new_stream() | 407 | self.stream_view.new_stream() |
141 | 406 | else: | 408 | else: |
142 | 407 | self.set_view("MultiStreamUi") | 409 | self.set_view("MultiStreamUi") |
143 | 408 | self.stream_view.new_stream() | 410 | self.stream_view.new_stream() |
145 | 409 | 411 | ||
146 | 410 | def on_loading_started(self, *args): | 412 | def on_loading_started(self, *args): |
147 | 411 | self.loading_spinner.set_from_animation( | 413 | self.loading_spinner.set_from_animation( |
148 | 412 | gtk.gdk.PixbufAnimation(resources.get_ui_asset("progress.gif"))) | 414 | gtk.gdk.PixbufAnimation(resources.get_ui_asset("progress.gif"))) |
149 | 413 | 415 | ||
150 | === modified file 'gwibber/gwui.py' | |||
151 | --- gwibber/gwui.py 2010-03-17 17:17:13 +0000 | |||
152 | +++ gwibber/gwui.py 2010-03-17 17:37:30 +0000 | |||
153 | @@ -30,11 +30,11 @@ | |||
154 | 30 | gobject.GObject.__init__(self) | 30 | gobject.GObject.__init__(self) |
155 | 31 | 31 | ||
156 | 32 | self.daemon = util.getbus("Service") | 32 | self.daemon = util.getbus("Service") |
158 | 33 | 33 | ||
159 | 34 | self.account_monitor = util.getbus("Accounts") | 34 | self.account_monitor = util.getbus("Accounts") |
160 | 35 | self.account_monitor.connect_to_signal("AccountChanged", self.on_stream_changed) | 35 | self.account_monitor.connect_to_signal("AccountChanged", self.on_stream_changed) |
161 | 36 | self.account_monitor.connect_to_signal("AccountDeleted", self.on_stream_changed) | 36 | self.account_monitor.connect_to_signal("AccountDeleted", self.on_stream_changed) |
163 | 37 | 37 | ||
164 | 38 | self.streams_monitor = util.getbus("Streams") | 38 | self.streams_monitor = util.getbus("Streams") |
165 | 39 | self.streams_monitor.connect_to_signal("StreamChanged", self.on_stream_changed) | 39 | self.streams_monitor.connect_to_signal("StreamChanged", self.on_stream_changed) |
166 | 40 | self.streams_monitor.connect_to_signal("StreamClosed", self.on_stream_changed) | 40 | self.streams_monitor.connect_to_signal("StreamClosed", self.on_stream_changed) |
167 | @@ -69,7 +69,7 @@ | |||
168 | 69 | def find_all(self, **params): | 69 | def find_all(self, **params): |
169 | 70 | for stream in self.get_streams(): | 70 | for stream in self.get_streams(): |
170 | 71 | if self.match(stream, params): yield stream | 71 | if self.match(stream, params): yield stream |
172 | 72 | 72 | ||
173 | 73 | if "items" in stream: | 73 | if "items" in stream: |
174 | 74 | for stream in stream["items"]: | 74 | for stream in stream["items"]: |
175 | 75 | if self.match(stream, params): yield stream | 75 | if self.match(stream, params): yield stream |
176 | @@ -130,7 +130,7 @@ | |||
177 | 130 | } | 130 | } |
178 | 131 | 131 | ||
179 | 132 | default_streams = self.services[account["protocol"]]["default_streams"] | 132 | default_streams = self.services[account["protocol"]]["default_streams"] |
181 | 133 | 133 | ||
182 | 134 | if len(default_streams) > 1: | 134 | if len(default_streams) > 1: |
183 | 135 | for feature in default_streams: | 135 | for feature in default_streams: |
184 | 136 | aname = self.features[feature]["stream"] | 136 | aname = self.features[feature]["stream"] |
185 | @@ -174,7 +174,7 @@ | |||
186 | 174 | "color": util.Color(account["color"]), | 174 | "color": util.Color(account["color"]), |
187 | 175 | "protocol": account["protocol"], | 175 | "protocol": account["protocol"], |
188 | 176 | }) | 176 | }) |
190 | 177 | 177 | ||
191 | 178 | items.append(item) | 178 | items.append(item) |
192 | 179 | 179 | ||
193 | 180 | searches = { | 180 | searches = { |
194 | @@ -192,13 +192,13 @@ | |||
195 | 192 | sId = search["_id"] | 192 | sId = search["_id"] |
196 | 193 | searches["items"].append({ | 193 | searches["items"].append({ |
197 | 194 | "name": search["name"], | 194 | "name": search["name"], |
199 | 195 | "account": None, | 195 | "account": None, |
200 | 196 | "view": self.messages.execute_view("transient_time", "messages")[[sId, {}]:[sId, 0]], | 196 | "view": self.messages.execute_view("transient_time", "messages")[[sId, {}]:[sId, 0]], |
201 | 197 | "stream": "search", | 197 | "stream": "search", |
202 | 198 | "transient": sId, | 198 | "transient": sId, |
203 | 199 | "color": None, | 199 | "color": None, |
204 | 200 | }) | 200 | }) |
206 | 201 | 201 | ||
207 | 202 | items.append(searches) | 202 | items.append(searches) |
208 | 203 | return items | 203 | return items |
209 | 204 | 204 | ||
210 | @@ -222,7 +222,7 @@ | |||
211 | 222 | 222 | ||
212 | 223 | def on_click_link(self, view, frame, req): | 223 | def on_click_link(self, view, frame, req): |
213 | 224 | uri = req.get_uri() | 224 | uri = req.get_uri() |
215 | 225 | 225 | ||
216 | 226 | if uri.startswith("file:///"): return False | 226 | if uri.startswith("file:///"): return False |
217 | 227 | elif uri.startswith("gwibber:"): | 227 | elif uri.startswith("gwibber:"): |
218 | 228 | url = urlparse.urlparse(uri) | 228 | url = urlparse.urlparse(uri) |
219 | @@ -230,7 +230,7 @@ | |||
220 | 230 | query = urlparse.parse_qs(url.query) | 230 | query = urlparse.parse_qs(url.query) |
221 | 231 | query = dict((x,y[0]) for x,y in query.items()) | 231 | query = dict((x,y[0]) for x,y in query.items()) |
222 | 232 | self.emit("action", uri, cmd, query) | 232 | self.emit("action", uri, cmd, query) |
224 | 233 | else: util.load_url(uri) | 233 | else: util.load_url(uri) |
225 | 234 | return True | 234 | return True |
226 | 235 | 235 | ||
227 | 236 | def render(self, theme, template, **kwargs): | 236 | def render(self, theme, template, **kwargs): |
228 | @@ -245,7 +245,7 @@ | |||
229 | 245 | theme_path = resources.get_theme_path(theme) | 245 | theme_path = resources.get_theme_path(theme) |
230 | 246 | template_path = resources.get_template_path(template, theme) | 246 | template_path = resources.get_template_path(template, theme) |
231 | 247 | lookup_paths = list(resources.get_template_dirs()) + [theme_path] | 247 | lookup_paths = list(resources.get_template_dirs()) + [theme_path] |
233 | 248 | 248 | ||
234 | 249 | template = open(template_path).read() | 249 | template = open(template_path).read() |
235 | 250 | template = Template(template, lookup=TemplateLookup(directories=lookup_paths)) | 250 | template = Template(template, lookup=TemplateLookup(directories=lookup_paths)) |
236 | 251 | content = template.render(theme=util.get_theme_colors(), resources=resources, _=_, **kwargs) | 251 | content = template.render(theme=util.get_theme_colors(), resources=resources, _=_, **kwargs) |
237 | @@ -253,7 +253,7 @@ | |||
238 | 253 | # Avoid navigation redraw crashes | 253 | # Avoid navigation redraw crashes |
239 | 254 | if isinstance(self, Navigation) and not self.get_property("visible"): | 254 | if isinstance(self, Navigation) and not self.get_property("visible"): |
240 | 255 | return content | 255 | return content |
242 | 256 | 256 | ||
243 | 257 | self.load_html_string(content, "file://%s/" % os.path.dirname(template_path)) | 257 | self.load_html_string(content, "file://%s/" % os.path.dirname(template_path)) |
244 | 258 | return content | 258 | return content |
245 | 259 | 259 | ||
246 | @@ -273,7 +273,7 @@ | |||
247 | 273 | self.selected_stream = None | 273 | self.selected_stream = None |
248 | 274 | self.tree_enabled = False | 274 | self.tree_enabled = False |
249 | 275 | self.small_icons = False | 275 | self.small_icons = False |
251 | 276 | 276 | ||
252 | 277 | def render(self): | 277 | def render(self): |
253 | 278 | return WebUi.render(self, self.model.settings["theme"], "navigation.mako", | 278 | return WebUi.render(self, self.model.settings["theme"], "navigation.mako", |
254 | 279 | streams=self.model.get_streams(), | 279 | streams=self.model.get_streams(), |
255 | @@ -334,7 +334,7 @@ | |||
256 | 334 | self.splitter = gtk.HPaned() | 334 | self.splitter = gtk.HPaned() |
257 | 335 | self.splitter.add1(self.navigation_scroll) | 335 | self.splitter.add1(self.navigation_scroll) |
258 | 336 | self.splitter.add2(layout) | 336 | self.splitter.add2(layout) |
260 | 337 | 337 | ||
261 | 338 | self.splitter.set_position(self.model.settings["sidebar_splitter"]) | 338 | self.splitter.set_position(self.model.settings["sidebar_splitter"]) |
262 | 339 | self.handle_splitter_position_change(self.model.settings["sidebar_splitter"]) | 339 | self.handle_splitter_position_change(self.model.settings["sidebar_splitter"]) |
263 | 340 | self.splitter.connect("notify", self.on_splitter_drag) | 340 | self.splitter.connect("notify", self.on_splitter_drag) |
264 | @@ -368,8 +368,8 @@ | |||
265 | 368 | def on_splitter_drag(self, pane, ev): | 368 | def on_splitter_drag(self, pane, ev): |
266 | 369 | if ev.name == 'position': | 369 | if ev.name == 'position': |
267 | 370 | pos = pane.get_position() | 370 | pos = pane.get_position() |
270 | 371 | self.handle_splitter_position_change(pos) | 371 | self.handle_splitter_position_change(pos) |
271 | 372 | 372 | ||
272 | 373 | def on_stream_closed(self, widget, id, kind): | 373 | def on_stream_closed(self, widget, id, kind): |
273 | 374 | self.emit("stream-closed", id, kind) | 374 | self.emit("stream-closed", id, kind) |
274 | 375 | 375 | ||
275 | @@ -378,7 +378,7 @@ | |||
276 | 378 | self.emit("stream-changed", stream) | 378 | self.emit("stream-changed", stream) |
277 | 379 | self.update_search_visibility() | 379 | self.update_search_visibility() |
278 | 380 | self.update() | 380 | self.update() |
280 | 381 | 381 | ||
281 | 382 | def update_search_visibility(self): | 382 | def update_search_visibility(self): |
282 | 383 | stream = self.navigation.selected_stream | 383 | stream = self.navigation.selected_stream |
283 | 384 | if stream is not None: | 384 | if stream is not None: |
284 | @@ -428,14 +428,14 @@ | |||
285 | 428 | self.scroll.add_with_viewport(self.container) | 428 | self.scroll.add_with_viewport(self.container) |
286 | 429 | 429 | ||
287 | 430 | self.pack_start(self.scroll, True) | 430 | self.pack_start(self.scroll, True) |
289 | 431 | 431 | ||
290 | 432 | def on_stream_closed(self, widget, id, kind): | 432 | def on_stream_closed(self, widget, id, kind): |
291 | 433 | self.emit("stream-closed", id, kind) | 433 | self.emit("stream-closed", id, kind) |
292 | 434 | 434 | ||
293 | 435 | def on_pane_closed(self, widget): | 435 | def on_pane_closed(self, widget): |
294 | 436 | widget.destroy() | 436 | widget.destroy() |
295 | 437 | self.emit("pane-closed", len(self.container)) | 437 | self.emit("pane-closed", len(self.container)) |
297 | 438 | 438 | ||
298 | 439 | def on_search(self, widget, query): | 439 | def on_search(self, widget, query): |
299 | 440 | self.emit("search", query) | 440 | self.emit("search", query) |
300 | 441 | 441 | ||
301 | @@ -483,7 +483,7 @@ | |||
302 | 483 | # Build the top navigation bar | 483 | # Build the top navigation bar |
303 | 484 | close_icon = gtk.image_new_from_stock("gtk-close", gtk.ICON_SIZE_MENU) | 484 | close_icon = gtk.image_new_from_stock("gtk-close", gtk.ICON_SIZE_MENU) |
304 | 485 | down_arrow = gtk.Arrow(gtk.ARROW_DOWN, gtk.SHADOW_NONE) | 485 | down_arrow = gtk.Arrow(gtk.ARROW_DOWN, gtk.SHADOW_NONE) |
306 | 486 | 486 | ||
307 | 487 | btn_arrow = gtk.Button() | 487 | btn_arrow = gtk.Button() |
308 | 488 | btn_arrow.set_relief(gtk.RELIEF_NONE) | 488 | btn_arrow.set_relief(gtk.RELIEF_NONE) |
309 | 489 | btn_arrow.add(down_arrow) | 489 | btn_arrow.add(down_arrow) |
310 | @@ -514,7 +514,7 @@ | |||
311 | 514 | # Build the main message view | 514 | # Build the main message view |
312 | 515 | self.message_view = MessageStreamView(self.model) | 515 | self.message_view = MessageStreamView(self.model) |
313 | 516 | self.message_view.connect("action", self.on_action) | 516 | self.message_view.connect("action", self.on_action) |
315 | 517 | 517 | ||
316 | 518 | self.message_scroll = gtk.ScrolledWindow() | 518 | self.message_scroll = gtk.ScrolledWindow() |
317 | 519 | self.message_scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) | 519 | self.message_scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) |
318 | 520 | self.message_scroll.set_shadow_type(gtk.SHADOW_IN) | 520 | self.message_scroll.set_shadow_type(gtk.SHADOW_IN) |
319 | @@ -530,7 +530,7 @@ | |||
320 | 530 | def on_dropdown(self, button): | 530 | def on_dropdown(self, button): |
321 | 531 | w, h = self.arrow.window.get_geometry()[2:4] | 531 | w, h = self.arrow.window.get_geometry()[2:4] |
322 | 532 | x, y = self.arrow.window.get_origin() | 532 | x, y = self.arrow.window.get_origin() |
324 | 533 | 533 | ||
325 | 534 | window = gtk.Window() | 534 | window = gtk.Window() |
326 | 535 | window.move(x, y + h) | 535 | window.move(x, y + h) |
327 | 536 | window.set_decorated(False) | 536 | window.set_decorated(False) |
328 | @@ -566,7 +566,7 @@ | |||
329 | 566 | 566 | ||
330 | 567 | is_search = stream["stream"] == "search" and stream["name"] == "Search" | 567 | is_search = stream["stream"] == "search" and stream["name"] == "Search" |
331 | 568 | self.search_box.set_visible(not is_search) | 568 | self.search_box.set_visible(not is_search) |
333 | 569 | 569 | ||
334 | 570 | if stream["account"]: | 570 | if stream["account"]: |
335 | 571 | fname = resources.get_ui_asset("icons/breakdance/16x16/%s.png" % stream["protocol"]) | 571 | fname = resources.get_ui_asset("icons/breakdance/16x16/%s.png" % stream["protocol"]) |
336 | 572 | self.icon_protocol.set_from_file(fname) | 572 | self.icon_protocol.set_from_file(fname) |
337 | @@ -604,10 +604,10 @@ | |||
338 | 604 | self.model = model | 604 | self.model = model |
339 | 605 | self.model.connect("changed", self.on_account_changed) | 605 | self.model.connect("changed", self.on_account_changed) |
340 | 606 | self.accounts = [] | 606 | self.accounts = [] |
342 | 607 | 607 | ||
343 | 608 | self.target = None | 608 | self.target = None |
344 | 609 | self.action = None | 609 | self.action = None |
346 | 610 | 610 | ||
347 | 611 | self.targetbar = WebUi() | 611 | self.targetbar = WebUi() |
348 | 612 | self.targetbar.connect("action", self.on_action) | 612 | self.targetbar.connect("action", self.on_action) |
349 | 613 | self.targetbar.set_size_request(0, 24) | 613 | self.targetbar.set_size_request(0, 24) |
350 | @@ -661,11 +661,11 @@ | |||
351 | 661 | 661 | ||
352 | 662 | def render(self, views): | 662 | def render(self, views): |
353 | 663 | accounts = CouchDatabase(COUCH_DB_ACCOUNTS).get_records(COUCH_TYPE_ACCOUNT, True) | 663 | accounts = CouchDatabase(COUCH_DB_ACCOUNTS).get_records(COUCH_TYPE_ACCOUNT, True) |
355 | 664 | 664 | ||
356 | 665 | accounts = dict((a.id, a.value) for a in accounts) | 665 | accounts = dict((a.id, a.value) for a in accounts) |
357 | 666 | messages = [] | 666 | messages = [] |
358 | 667 | seen = {} | 667 | seen = {} |
360 | 668 | 668 | ||
361 | 669 | for view in views: | 669 | for view in views: |
362 | 670 | view.options["descending"] = True | 670 | view.options["descending"] = True |
363 | 671 | view.options["limit"] = 100 | 671 | view.options["limit"] = 100 |
364 | @@ -698,8 +698,8 @@ | |||
365 | 698 | else: | 698 | else: |
366 | 699 | if message["txtid"]: | 699 | if message["txtid"]: |
367 | 700 | seen[message["txtid"]] = n | 700 | seen[message["txtid"]] = n |
370 | 701 | 701 | ||
371 | 702 | WebUi.render(self, self.model.settings["theme"], "template.mako", | 702 | WebUi.render(self, self.model.settings["theme"], "template.mako", |
372 | 703 | message_store=messages, | 703 | message_store=messages, |
373 | 704 | preferences=self.model.settings, | 704 | preferences=self.model.settings, |
374 | 705 | services=self.model.services, | 705 | services=self.model.services, |
375 | @@ -712,14 +712,14 @@ | |||
376 | 712 | 712 | ||
377 | 713 | def __init__(self): | 713 | def __init__(self): |
378 | 714 | gtk.HBox.__init__(self, spacing=2) | 714 | gtk.HBox.__init__(self, spacing=2) |
380 | 715 | 715 | ||
381 | 716 | self.entry = gtk.Entry() | 716 | self.entry = gtk.Entry() |
382 | 717 | self.entry.connect("activate", self.on_search) | 717 | self.entry.connect("activate", self.on_search) |
383 | 718 | self.entry.connect("changed", self.on_changed) | 718 | self.entry.connect("changed", self.on_changed) |
384 | 719 | 719 | ||
385 | 720 | self.button = gtk.Button("Search") | 720 | self.button = gtk.Button("Search") |
386 | 721 | self.button.connect("clicked", self.on_search) | 721 | self.button.connect("clicked", self.on_search) |
388 | 722 | 722 | ||
389 | 723 | self.pack_start(self.entry, True) | 723 | self.pack_start(self.entry, True) |
390 | 724 | self.pack_start(self.button, False) | 724 | self.pack_start(self.button, False) |
391 | 725 | 725 | ||
392 | @@ -731,7 +731,7 @@ | |||
393 | 731 | def on_search(self, *args): | 731 | def on_search(self, *args): |
394 | 732 | self.emit("search", self.entry.get_text()) | 732 | self.emit("search", self.entry.get_text()) |
395 | 733 | self.clear() | 733 | self.clear() |
397 | 734 | 734 | ||
398 | 735 | def clear(self): | 735 | def clear(self): |
399 | 736 | self.entry.set_text("") | 736 | self.entry.set_text("") |
400 | 737 | 737 | ||
401 | @@ -748,7 +748,7 @@ | |||
402 | 748 | 748 | ||
403 | 749 | def focus(self): | 749 | def focus(self): |
404 | 750 | self.entry.grab_focus() | 750 | self.entry.grab_focus() |
406 | 751 | 751 | ||
407 | 752 | class Input(gtk.Frame): | 752 | class Input(gtk.Frame): |
408 | 753 | __gsignals__ = { | 753 | __gsignals__ = { |
409 | 754 | "submit": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (str, int)), | 754 | "submit": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_ACTION, None, (str, int)), |
410 | @@ -767,6 +767,9 @@ | |||
411 | 767 | scroll.add(self.textview) | 767 | scroll.add(self.textview) |
412 | 768 | self.add(scroll) | 768 | self.add(scroll) |
413 | 769 | 769 | ||
414 | 770 | self.set_focus_child(scroll) | ||
415 | 771 | scroll.set_focus_child(self.textview) | ||
416 | 772 | |||
417 | 770 | def get_text(self): | 773 | def get_text(self): |
418 | 771 | return self.textview.get_text() | 774 | return self.textview.get_text() |
419 | 772 | 775 | ||
420 | @@ -780,7 +783,7 @@ | |||
421 | 780 | text = self.textview.get_text() | 783 | text = self.textview.get_text() |
422 | 781 | chars = self.textview.get_char_count() | 784 | chars = self.textview.get_char_count() |
423 | 782 | self.emit("changed", text, chars) | 785 | self.emit("changed", text, chars) |
425 | 783 | 786 | ||
426 | 784 | def do_submit_event(self, tv): | 787 | def do_submit_event(self, tv): |
427 | 785 | text = tv.get_text() | 788 | text = tv.get_text() |
428 | 786 | chars = tv.get_char_count() | 789 | chars = tv.get_char_count() |
429 | @@ -798,13 +801,13 @@ | |||
430 | 798 | 801 | ||
431 | 799 | self.overlay_color = util.get_theme_colors()["text"].darker(3).hex | 802 | self.overlay_color = util.get_theme_colors()["text"].darker(3).hex |
432 | 800 | self.overlay_text = '<span weight="bold" size="xx-large" foreground="%s">%s</span>' | 803 | self.overlay_text = '<span weight="bold" size="xx-large" foreground="%s">%s</span>' |
434 | 801 | 804 | ||
435 | 802 | self.shortener = util.getbus("URLShorten") | 805 | self.shortener = util.getbus("URLShorten") |
436 | 803 | 806 | ||
437 | 804 | self.connection = util.getbus("Connection") | 807 | self.connection = util.getbus("Connection") |
438 | 805 | self.connection.connect_to_signal("ConnectionOnline", self.on_connection_online) | 808 | self.connection.connect_to_signal("ConnectionOnline", self.on_connection_online) |
439 | 806 | self.connection.connect_to_signal("ConnectionOffline", self.on_connection_offline) | 809 | self.connection.connect_to_signal("ConnectionOffline", self.on_connection_offline) |
441 | 807 | 810 | ||
442 | 808 | self.get_buffer().connect("insert-text", self.on_add_text) | 811 | self.get_buffer().connect("insert-text", self.on_add_text) |
443 | 809 | self.get_buffer().connect("changed", self.on_text_changed) | 812 | self.get_buffer().connect("changed", self.on_text_changed) |
444 | 810 | self.connect("expose-event", self.expose_view) | 813 | self.connect("expose-event", self.expose_view) |
445 | @@ -820,7 +823,7 @@ | |||
446 | 820 | self.set_right_margin(2) | 823 | self.set_right_margin(2) |
447 | 821 | self.set_pixels_above_lines(2) | 824 | self.set_pixels_above_lines(2) |
448 | 822 | self.set_pixels_below_lines(2) | 825 | self.set_pixels_below_lines(2) |
450 | 823 | 826 | ||
451 | 824 | self.base_color = util.get_style().base[gtk.STATE_NORMAL] | 827 | self.base_color = util.get_style().base[gtk.STATE_NORMAL] |
452 | 825 | self.error_color = gtk.gdk.color_parse("indianred") | 828 | self.error_color = gtk.gdk.color_parse("indianred") |
453 | 826 | 829 | ||
454 | @@ -849,7 +852,7 @@ | |||
455 | 849 | buf = self.get_buffer() | 852 | buf = self.get_buffer() |
456 | 850 | buf.stop_emission("insert-text") | 853 | buf.stop_emission("insert-text") |
457 | 851 | service = self.model.settings["urlshorter"] or "is.gd" | 854 | service = self.model.settings["urlshorter"] or "is.gd" |
459 | 852 | 855 | ||
460 | 853 | def add_shortened(shortened_url): | 856 | def add_shortened(shortened_url): |
461 | 854 | "Internal add-shortened-url-to-buffer function: a closure" | 857 | "Internal add-shortened-url-to-buffer function: a closure" |
462 | 855 | iter_start = buf.get_iter_at_mark(mark_start) | 858 | iter_start = buf.get_iter_at_mark(mark_start) |
463 | @@ -860,7 +863,7 @@ | |||
464 | 860 | "Internal shortening-url-died function: a closure" | 863 | "Internal shortening-url-died function: a closure" |
465 | 861 | iter = buf.get_iter_at_mark(mark) | 864 | iter = buf.get_iter_at_mark(mark) |
466 | 862 | buf.insert(iter, text) # shortening failed | 865 | buf.insert(iter, text) # shortening failed |
468 | 863 | 866 | ||
469 | 864 | # set a mark at iter, so that the callback knows where to insert | 867 | # set a mark at iter, so that the callback knows where to insert |
470 | 865 | mark_start = buf.create_mark(None, iter, True) | 868 | mark_start = buf.create_mark(None, iter, True) |
471 | 866 | # insert a placeholder character | 869 | # insert a placeholder character |
472 | @@ -870,9 +873,9 @@ | |||
473 | 870 | iter_end = buf.get_iter_at_mark(buf.get_insert()) | 873 | iter_end = buf.get_iter_at_mark(buf.get_insert()) |
474 | 871 | mark_end = buf.create_mark(None, iter_end, True) | 874 | mark_end = buf.create_mark(None, iter_end, True) |
475 | 872 | self.shortener.Shorten(text, service, | 875 | self.shortener.Shorten(text, service, |
477 | 873 | reply_handler=add_shortened, | 876 | reply_handler=add_shortened, |
478 | 874 | error_handler=error_shortened) | 877 | error_handler=error_shortened) |
480 | 875 | 878 | ||
481 | 876 | def set_overlay_text(self, text): | 879 | def set_overlay_text(self, text): |
482 | 877 | self.pango_overlay.set_markup(self.overlay_text % (self.overlay_color, text)) | 880 | self.pango_overlay.set_markup(self.overlay_text % (self.overlay_color, text)) |
483 | 878 | 881 |
Awesome, thanks!