Merge lp:~erduende/gwibber/bitly-support into lp:gwibber
- bitly-support
- Merge into trunk
Status: | Rejected | ||||
---|---|---|---|---|---|
Rejected by: | Ken VanDine | ||||
Proposed branch: | lp:~erduende/gwibber/bitly-support | ||||
Merge into: | lp:gwibber | ||||
Diff against target: |
443 lines (+209/-26) 6 files modified
gwibber/microblog/dispatcher.py (+10/-0) gwibber/microblog/urlshorter/__init__.py (+2/-1) gwibber/microblog/urlshorter/bitly.py (+81/-0) gwibber/microblog/util/const.py (+1/-0) gwibber/preferences.py (+52/-1) ui/gwibber-preferences-dialog.ui (+63/-24) |
||||
To merge this branch: | bzr merge lp:~erduende/gwibber/bitly-support | ||||
Related bugs: |
|
||||
Related blueprints: |
Support for Bit.ly URL shortening
(Undefined)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ken VanDine | Needs Resubmitting | ||
Omer Akram (community) | Needs Resubmitting | ||
Review via email: mp+26412@code.launchpad.net |
Commit message
Description of the change
This patch adds bit.ly urlshorter support. In order to implement urlshorten service account authentication i have done some changes to preference window layout. Preferences windows now has a new tab named 'services' where you can find urlshorten configuration and perhaps add photo upload services in the future.
I have tried to follow your coding style but if you think something has to be changed, i'll change it to accomplish your requirements.
Waiting your considerations, i still have to finish text translations.
Sorry about my bad english ;)
- 749. By Jesús Carmona
-
Removed merge conflict tags from code
Ken VanDine (ken-vandine) wrote : | # |
It would be great to support bit.ly, could you update this to work with current trunk and make it use oauth instead of username/password? Perhaps if you select bit.ly from the drop down you can show a link authorize it in a browser.
Unmerged revisions
- 749. By Jesús Carmona
-
Removed merge conflict tags from code
- 748. By Jesus Carmona <pixie@pixie-desktop>
-
Bazaar conflicts corrections??
- 747. By Jesús Carmona
-
Added auth error window before saving username and api key if validation data is incorrect
- 746. By Jesús Carmona
-
Removed gwibber's bitly account API KEY because it is not needed for validation
- 745. By Jesús Carmona
-
Added bit.ly account validation befrore preferences saving
- Created bit.ly gwibber account (gwibberservice)
- Added API KEY to bitly.py - 744. By Jesus Carmona <pixie@pixie-desktop>
-
- Added support for Bit.ly url shorter service
- Added "services" tab to preferences ui
- Moved url shorter preferences to "services" tab
- Show/hide login and api key fields if protocol needs them
- Added "Get api key" link to bit.ly service
- Stores bit.ly username in couchdb settings db and api key in gnomekeyring
Preview Diff
1 | === modified file 'gwibber/microblog/dispatcher.py' | |||
2 | --- gwibber/microblog/dispatcher.py 2010-04-14 15:30:37 +0000 | |||
3 | +++ gwibber/microblog/dispatcher.py 2010-05-31 11:52:27 +0000 | |||
4 | @@ -20,6 +20,11 @@ | |||
5 | 20 | from util.const import * | 20 | from util.const import * |
6 | 21 | 21 | ||
7 | 22 | try: | 22 | try: |
8 | 23 | import gnomekeyring | ||
9 | 24 | except: | ||
10 | 25 | gnomekeyring = None | ||
11 | 26 | |||
12 | 27 | try: | ||
13 | 23 | import indicate | 28 | import indicate |
14 | 24 | except: | 29 | except: |
15 | 25 | indicate = None | 30 | indicate = None |
16 | @@ -613,6 +618,11 @@ | |||
17 | 613 | if self.IsShort(url): return url | 618 | if self.IsShort(url): return url |
18 | 614 | try: | 619 | try: |
19 | 615 | s = urlshorter.PROTOCOLS[service].URLShorter() | 620 | s = urlshorter.PROTOCOLS[service].URLShorter() |
20 | 621 | |||
21 | 622 | if urlshorter.PROTOCOLS[service].PROTOCOL_INFO.get('authtype') == 'login': | ||
22 | 623 | urlshorter_key = gnomekeyring.find_items_sync(gnomekeyring.ITEM_GENERIC_SECRET,{"id": SETTINGS['urlshorter_user']})[0].secret | ||
23 | 624 | s.auth(SETTINGS['urlshorter_user'], urlshorter_key) | ||
24 | 625 | |||
25 | 616 | return s.short(url) | 626 | return s.short(url) |
26 | 617 | except: return url | 627 | except: return url |
27 | 618 | 628 | ||
28 | 619 | 629 | ||
29 | === modified file 'gwibber/microblog/urlshorter/__init__.py' | |||
30 | --- gwibber/microblog/urlshorter/__init__.py 2009-04-15 22:56:03 +0000 | |||
31 | +++ gwibber/microblog/urlshorter/__init__.py 2010-05-31 11:52:27 +0000 | |||
32 | @@ -1,5 +1,5 @@ | |||
33 | 1 | 1 | ||
35 | 2 | import cligs, isgd, tinyurlcom, trim, ur1ca | 2 | import cligs, isgd, tinyurlcom, trim, ur1ca, bitly |
36 | 3 | #import snipurlcom, zima | 3 | #import snipurlcom, zima |
37 | 4 | 4 | ||
38 | 5 | PROTOCOLS = { | 5 | PROTOCOLS = { |
39 | @@ -10,4 +10,5 @@ | |||
40 | 10 | "tr.im": trim, | 10 | "tr.im": trim, |
41 | 11 | "ur1.ca": ur1ca, | 11 | "ur1.ca": ur1ca, |
42 | 12 | #"zi.ma": zima, | 12 | #"zi.ma": zima, |
43 | 13 | "bit.ly": bitly, | ||
44 | 13 | } | 14 | } |
45 | 14 | 15 | ||
46 | === added file 'gwibber/microblog/urlshorter/bitly.py' | |||
47 | --- gwibber/microblog/urlshorter/bitly.py 1970-01-01 00:00:00 +0000 | |||
48 | +++ gwibber/microblog/urlshorter/bitly.py 2010-05-31 11:52:27 +0000 | |||
49 | @@ -0,0 +1,81 @@ | |||
50 | 1 | |||
51 | 2 | """ | ||
52 | 3 | |||
53 | 4 | Bit.ly interface for Gwibber | ||
54 | 5 | erduende (Jesus Carmona) - 05/14/2010 | ||
55 | 6 | |||
56 | 7 | """ | ||
57 | 8 | |||
58 | 9 | import gtk | ||
59 | 10 | import urllib2 | ||
60 | 11 | import json | ||
61 | 12 | |||
62 | 13 | |||
63 | 14 | PROTOCOL_INFO = { | ||
64 | 15 | |||
65 | 16 | "name": "bit.ly", | ||
66 | 17 | "version": 0.1, | ||
67 | 18 | "fqdn" : "http://bit.ly", | ||
68 | 19 | |||
69 | 20 | "config": [ | ||
70 | 21 | "private:api_key", | ||
71 | 22 | "username", | ||
72 | 23 | ], | ||
73 | 24 | |||
74 | 25 | "authtype": "login", | ||
75 | 26 | |||
76 | 27 | } | ||
77 | 28 | |||
78 | 29 | API_SERVER = 'http://api.bit.ly/v3' | ||
79 | 30 | API_KEY = "R_58b2b15d49b0f84f90fb03fcf8f82d23" | ||
80 | 31 | |||
81 | 32 | class URLShorter: | ||
82 | 33 | |||
83 | 34 | def short(self, text): | ||
84 | 35 | shorten = json.loads(urllib2.urlopen(API_SERVER+"/shorten?login="+self.user+"&apiKey="+self.key+"&uri=%s&format=json" % urllib2.quote(text)).read()) | ||
85 | 36 | if shorten.get('status_code') == 200: | ||
86 | 37 | return shorten['data']['url'] | ||
87 | 38 | else: | ||
88 | 39 | return text | ||
89 | 40 | |||
90 | 41 | def validate(self): | ||
91 | 42 | validate = json.loads(urllib2.urlopen(API_SERVER+"/validate?x_login=%s&x_apiKey=%s&login=%s&apiKey=%s&format=json" % (self.urlshorter_login_entry.get_text(), self.urlshorter_apikey_entry.get_text(), self.urlshorter_login_entry.get_text(), self.urlshorter_apikey_entry.get_text())).read()) | ||
92 | 43 | if validate.get('status_code') == 200: | ||
93 | 44 | return validate['data']['valid'] | ||
94 | 45 | else: | ||
95 | 46 | return False | ||
96 | 47 | |||
97 | 48 | def auth(self, user=None, key=None): | ||
98 | 49 | self.user = user | ||
99 | 50 | self.key = key | ||
100 | 51 | |||
101 | 52 | |||
102 | 53 | def auth_ui(self, login=None, api_key=None): | ||
103 | 54 | self.urlshorter_auth_table = gtk.Table(3, 2, True) | ||
104 | 55 | urlshorter_login_label = gtk.Label("bit.ly login:") | ||
105 | 56 | self.urlshorter_login_entry = gtk.Entry() | ||
106 | 57 | if login: | ||
107 | 58 | self.urlshorter_login_entry.set_text(login) | ||
108 | 59 | self.urlshorter_auth_table.attach(urlshorter_login_label, 0, 1, 0, 1) | ||
109 | 60 | self.urlshorter_auth_table.attach(self.urlshorter_login_entry, 1, 2, 0, 1) | ||
110 | 61 | |||
111 | 62 | urlshorter_apikey_label = gtk.Label("bit.ly API key:") | ||
112 | 63 | self.urlshorter_apikey_entry = gtk.Entry() | ||
113 | 64 | if api_key: | ||
114 | 65 | self.urlshorter_apikey_entry.set_text(api_key) | ||
115 | 66 | self.urlshorter_auth_table.attach(urlshorter_apikey_label, 0, 1, 1, 2) | ||
116 | 67 | self.urlshorter_auth_table.attach(self.urlshorter_apikey_entry, 1, 2, 1, 2) | ||
117 | 68 | |||
118 | 69 | urlshorter_getkey_link = gtk.LinkButton("http://bit.ly/a/your_api_key", "Get your API key") | ||
119 | 70 | self.urlshorter_auth_table.attach(urlshorter_getkey_link, 1, 2, 2, 3, gtk.EXPAND) | ||
120 | 71 | |||
121 | 72 | return self.urlshorter_auth_table | ||
122 | 73 | |||
123 | 74 | def clear_ui(self): | ||
124 | 75 | self.urlshorter_auth_table.destroy() | ||
125 | 76 | |||
126 | 77 | def get_username(self): | ||
127 | 78 | return self.urlshorter_login_entry.get_text() | ||
128 | 79 | |||
129 | 80 | def get_password(self): | ||
130 | 81 | return self.urlshorter_apikey_entry.get_text() | ||
131 | 0 | 82 | ||
132 | === modified file 'gwibber/microblog/util/const.py' | |||
133 | --- gwibber/microblog/util/const.py 2010-04-15 05:47:35 +0000 | |||
134 | +++ gwibber/microblog/util/const.py 2010-05-31 11:52:27 +0000 | |||
135 | @@ -13,6 +13,7 @@ | |||
136 | 13 | "show_fullname": True, | 13 | "show_fullname": True, |
137 | 14 | "shorten_urls": True, | 14 | "shorten_urls": True, |
138 | 15 | "urlshorter": "is.gd", | 15 | "urlshorter": "is.gd", |
139 | 16 | "urlshorter_user": None, | ||
140 | 16 | "reply_append_colon": True, | 17 | "reply_append_colon": True, |
141 | 17 | "retweet_style": "recycle", | 18 | "retweet_style": "recycle", |
142 | 18 | "global_retweet": False, | 19 | "global_retweet": False, |
143 | 19 | 20 | ||
144 | === modified file 'gwibber/preferences.py' | |||
145 | --- gwibber/preferences.py 2010-05-03 04:25:30 +0000 | |||
146 | +++ gwibber/preferences.py 2010-05-31 11:52:27 +0000 | |||
147 | @@ -29,6 +29,11 @@ | |||
148 | 29 | from gwibber import util | 29 | from gwibber import util |
149 | 30 | import gtk, gconf | 30 | import gtk, gconf |
150 | 31 | 31 | ||
151 | 32 | try: | ||
152 | 33 | import gnomekeyring | ||
153 | 34 | except: | ||
154 | 35 | gnomekeyring = None | ||
155 | 36 | |||
156 | 32 | import gettext | 37 | import gettext |
157 | 33 | from gettext import lgettext as _ | 38 | from gettext import lgettext as _ |
158 | 34 | if hasattr(gettext, 'bind_textdomain_codeset'): | 39 | if hasattr(gettext, 'bind_textdomain_codeset'): |
159 | @@ -37,6 +42,8 @@ | |||
160 | 37 | 42 | ||
161 | 38 | from microblog.util.const import * | 43 | from microblog.util.const import * |
162 | 39 | from microblog.urlshorter import PROTOCOLS as urlshorters | 44 | from microblog.urlshorter import PROTOCOLS as urlshorters |
163 | 45 | from microblog.util.exceptions import GwibberProtocolError | ||
164 | 46 | import microblog.urlshorter | ||
165 | 40 | 47 | ||
166 | 41 | from dbus.mainloop.glib import DBusGMainLoop | 48 | from dbus.mainloop.glib import DBusGMainLoop |
167 | 42 | 49 | ||
168 | @@ -84,8 +91,24 @@ | |||
169 | 84 | for urlshorter in urlshorters.keys(): self.urlshorter_selector.append_text(urlshorter) | 91 | for urlshorter in urlshorters.keys(): self.urlshorter_selector.append_text(urlshorter) |
170 | 85 | self.ui.get_object("urlshorter_container").pack_start(self.urlshorter_selector, True, True) | 92 | self.ui.get_object("urlshorter_container").pack_start(self.urlshorter_selector, True, True) |
171 | 86 | self.urlshorter_selector.set_active_iter(dict([(x[0].strip(), x.iter) for x in self.urlshorter_selector.get_model()]).get(self.settings["urlshorter"], self.urlshorter_selector.get_model().get_iter_root())) | 93 | self.urlshorter_selector.set_active_iter(dict([(x[0].strip(), x.iter) for x in self.urlshorter_selector.get_model()]).get(self.settings["urlshorter"], self.urlshorter_selector.get_model().get_iter_root())) |
172 | 94 | self.urlshorter_selector.connect("changed", self.on_urlshorter_selector_changed, None) | ||
173 | 87 | self.urlshorter_selector.show_all() | 95 | self.urlshorter_selector.show_all() |
174 | 88 | 96 | ||
175 | 97 | active_urlshorter = urlshorters.get(self.urlshorter_selector.get_active_text()) | ||
176 | 98 | if active_urlshorter.PROTOCOL_INFO.get('authtype') == 'login': | ||
177 | 99 | try: | ||
178 | 100 | urlshorter_user = str(self.settings.get("urlshorter_user")) | ||
179 | 101 | urlshorter_key = gnomekeyring.find_items_sync(gnomekeyring.ITEM_GENERIC_SECRET, {"id": urlshorter_user})[0].secret | ||
180 | 102 | except gnomekeyring.NoMatchError: | ||
181 | 103 | urlshorter_user = None | ||
182 | 104 | urlshorter_key = None | ||
183 | 105 | |||
184 | 106 | self.urlshorter_authenticated = active_urlshorter.URLShorter() | ||
185 | 107 | #self.urlshorter_auth_ui = self.urlshorter_authenticated.auth_ui(urlshorter_user, urlshorter_key) | ||
186 | 108 | self.ui.get_object("urlshorter_table").attach(self.urlshorter_authenticated.auth_ui(urlshorter_user, urlshorter_key), 0, 1, 2, 3) | ||
187 | 109 | else: | ||
188 | 110 | self.urlshorter_authenticated = None | ||
189 | 111 | |||
190 | 89 | self.retweet_style_selector = gtk.combo_box_new_text() | 112 | self.retweet_style_selector = gtk.combo_box_new_text() |
191 | 90 | for format in RETWEET_FORMATS: self.retweet_style_selector.append_text(format) | 113 | for format in RETWEET_FORMATS: self.retweet_style_selector.append_text(format) |
192 | 91 | self.ui.get_object("retweet_style_container").pack_start(self.retweet_style_selector, True, True) | 114 | self.ui.get_object("retweet_style_container").pack_start(self.retweet_style_selector, True, True) |
193 | @@ -94,7 +117,26 @@ | |||
194 | 94 | 117 | ||
195 | 95 | def on_save_button_clicked(self, widget, data=None): | 118 | def on_save_button_clicked(self, widget, data=None): |
196 | 96 | self.settings["interval"] = int(self.ui.get_object("interval").get_value()) | 119 | self.settings["interval"] = int(self.ui.get_object("interval").get_value()) |
198 | 97 | 120 | ||
199 | 121 | # Only process authenticated url shorten service if url shorten is enabled | ||
200 | 122 | if self.ui.get_object("shorten_urls").get_property("active"): | ||
201 | 123 | if self.urlshorter_authenticated: | ||
202 | 124 | if self.urlshorter_authenticated.validate(): | ||
203 | 125 | self.settings["urlshorter_user"] = self.urlshorter_authenticated.get_username() | ||
204 | 126 | gnomekeyring.item_create_sync( | ||
205 | 127 | gnomekeyring.get_default_keyring_sync(), | ||
206 | 128 | gnomekeyring.ITEM_GENERIC_SECRET, | ||
207 | 129 | "Gwibber pref: %s" % ('urlshorter'), | ||
208 | 130 | {"id": self.urlshorter_authenticated.get_username()}, | ||
209 | 131 | self.urlshorter_authenticated.get_password(), True) | ||
210 | 132 | else: | ||
211 | 133 | GwibberProtocolError(type='auth', protocol='bit.ly', username=self.urlshorter_authenticated.get_username()) | ||
212 | 134 | return | ||
213 | 135 | else: | ||
214 | 136 | # TODO: Erease urlshorter key from keyring | ||
215 | 137 | self.settings["urlshorter_user"] = None | ||
216 | 138 | |||
217 | 139 | |||
218 | 98 | # Only change autostart if it was already set before or if the user enabled it | 140 | # Only change autostart if it was already set before or if the user enabled it |
219 | 99 | if self.gc.get("/apps/gwibber/autostart") is None: | 141 | if self.gc.get("/apps/gwibber/autostart") is None: |
220 | 100 | if self.ui.get_object("autostart").get_property("active"): | 142 | if self.ui.get_object("autostart").get_property("active"): |
221 | @@ -120,3 +162,12 @@ | |||
222 | 120 | def on_prefs_dialog_destroy_event(self, widget, data=None): | 162 | def on_prefs_dialog_destroy_event(self, widget, data=None): |
223 | 121 | gtk.main_quit() | 163 | gtk.main_quit() |
224 | 122 | 164 | ||
225 | 165 | def on_urlshorter_selector_changed(self, widget, data=None): | ||
226 | 166 | if urlshorters.get(widget.get_active_text()).PROTOCOL_INFO.get('authtype') == 'login': | ||
227 | 167 | self.urlshorter_authenticated = urlshorters.get(widget.get_active_text()).URLShorter() | ||
228 | 168 | self.ui.get_object("urlshorter_table").attach(self.urlshorter_authenticated.auth_ui(), 0, 1, 2, 3) | ||
229 | 169 | self.ui.get_object("urlshorter_table").show_all() | ||
230 | 170 | else: | ||
231 | 171 | if self.urlshorter_authenticated: | ||
232 | 172 | self.urlshorter_authenticated.clear_ui() | ||
233 | 173 | self.urlshorter_authenticated = None | ||
234 | 123 | 174 | ||
235 | === modified file 'ui/gwibber-preferences-dialog.ui' | |||
236 | --- ui/gwibber-preferences-dialog.ui 2010-03-05 17:54:43 +0000 | |||
237 | +++ ui/gwibber-preferences-dialog.ui 2010-05-31 11:52:27 +0000 | |||
238 | @@ -19,7 +19,6 @@ | |||
239 | 19 | <child internal-child="vbox"> | 19 | <child internal-child="vbox"> |
240 | 20 | <object class="GtkVBox" id="dialog-vbox1"> | 20 | <object class="GtkVBox" id="dialog-vbox1"> |
241 | 21 | <property name="visible">True</property> | 21 | <property name="visible">True</property> |
242 | 22 | <property name="orientation">vertical</property> | ||
243 | 23 | <property name="spacing">2</property> | 22 | <property name="spacing">2</property> |
244 | 24 | <child> | 23 | <child> |
245 | 25 | <object class="GtkNotebook" id="notebook1"> | 24 | <object class="GtkNotebook" id="notebook1"> |
246 | @@ -30,7 +29,6 @@ | |||
247 | 30 | <property name="visible">True</property> | 29 | <property name="visible">True</property> |
248 | 31 | <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> | 30 | <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
249 | 32 | <property name="border_width">5</property> | 31 | <property name="border_width">5</property> |
250 | 33 | <property name="orientation">vertical</property> | ||
251 | 34 | <property name="spacing">10</property> | 32 | <property name="spacing">10</property> |
252 | 35 | <child> | 33 | <child> |
253 | 36 | <object class="GtkFrame" id="frame1"> | 34 | <object class="GtkFrame" id="frame1"> |
254 | @@ -217,13 +215,11 @@ | |||
255 | 217 | <object class="GtkVBox" id="vbox1"> | 215 | <object class="GtkVBox" id="vbox1"> |
256 | 218 | <property name="visible">True</property> | 216 | <property name="visible">True</property> |
257 | 219 | <property name="border_width">5</property> | 217 | <property name="border_width">5</property> |
258 | 220 | <property name="orientation">vertical</property> | ||
259 | 221 | <property name="spacing">5</property> | 218 | <property name="spacing">5</property> |
260 | 222 | <child> | 219 | <child> |
261 | 223 | <object class="GtkVBox" id="vbox7"> | 220 | <object class="GtkVBox" id="vbox7"> |
262 | 224 | <property name="visible">True</property> | 221 | <property name="visible">True</property> |
263 | 225 | <property name="border_width">5</property> | 222 | <property name="border_width">5</property> |
264 | 226 | <property name="orientation">vertical</property> | ||
265 | 227 | <property name="spacing">5</property> | 223 | <property name="spacing">5</property> |
266 | 228 | <child> | 224 | <child> |
267 | 229 | <object class="GtkCheckButton" id="show_fullname"> | 225 | <object class="GtkCheckButton" id="show_fullname"> |
268 | @@ -257,7 +253,6 @@ | |||
269 | 257 | <child> | 253 | <child> |
270 | 258 | <object class="GtkVBox" id="vbox3"> | 254 | <object class="GtkVBox" id="vbox3"> |
271 | 259 | <property name="visible">True</property> | 255 | <property name="visible">True</property> |
272 | 260 | <property name="orientation">vertical</property> | ||
273 | 261 | <child> | 256 | <child> |
274 | 262 | <object class="GtkCheckButton" id="global_retweet"> | 257 | <object class="GtkCheckButton" id="global_retweet"> |
275 | 263 | <property name="label" translatable="yes">Send retweets to all services</property> | 258 | <property name="label" translatable="yes">Send retweets to all services</property> |
276 | @@ -273,7 +268,6 @@ | |||
277 | 273 | <child> | 268 | <child> |
278 | 274 | <object class="GtkVBox" id="retweet_style_container"> | 269 | <object class="GtkVBox" id="retweet_style_container"> |
279 | 275 | <property name="visible">True</property> | 270 | <property name="visible">True</property> |
280 | 276 | <property name="orientation">vertical</property> | ||
281 | 277 | <child> | 271 | <child> |
282 | 278 | <placeholder/> | 272 | <placeholder/> |
283 | 279 | </child> | 273 | </child> |
284 | @@ -315,7 +309,6 @@ | |||
285 | 315 | <object class="GtkTable" id="table16"> | 309 | <object class="GtkTable" id="table16"> |
286 | 316 | <property name="visible">True</property> | 310 | <property name="visible">True</property> |
287 | 317 | <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> | 311 | <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
288 | 318 | <property name="n_rows">3</property> | ||
289 | 319 | <property name="homogeneous">True</property> | 312 | <property name="homogeneous">True</property> |
290 | 320 | <child> | 313 | <child> |
291 | 321 | <object class="GtkCheckButton" id="reply_append_colon"> | 314 | <object class="GtkCheckButton" id="reply_append_colon"> |
292 | @@ -326,11 +319,57 @@ | |||
293 | 326 | <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> | 319 | <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
294 | 327 | <property name="draw_indicator">True</property> | 320 | <property name="draw_indicator">True</property> |
295 | 328 | </object> | 321 | </object> |
296 | 329 | <packing> | ||
297 | 330 | <property name="top_attach">2</property> | ||
298 | 331 | <property name="bottom_attach">3</property> | ||
299 | 332 | </packing> | ||
300 | 333 | </child> | 322 | </child> |
301 | 323 | </object> | ||
302 | 324 | </child> | ||
303 | 325 | </object> | ||
304 | 326 | </child> | ||
305 | 327 | <child type="label"> | ||
306 | 328 | <object class="GtkLabel" id="label79"> | ||
307 | 329 | <property name="visible">True</property> | ||
308 | 330 | <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> | ||
309 | 331 | <property name="label" translatable="yes"><b>Advanced</b></property> | ||
310 | 332 | <property name="use_markup">True</property> | ||
311 | 333 | </object> | ||
312 | 334 | </child> | ||
313 | 335 | </object> | ||
314 | 336 | <packing> | ||
315 | 337 | <property name="expand">False</property> | ||
316 | 338 | <property name="position">2</property> | ||
317 | 339 | </packing> | ||
318 | 340 | </child> | ||
319 | 341 | </object> | ||
320 | 342 | <packing> | ||
321 | 343 | <property name="position">1</property> | ||
322 | 344 | </packing> | ||
323 | 345 | </child> | ||
324 | 346 | <child type="tab"> | ||
325 | 347 | <object class="GtkLabel" id="messages_label"> | ||
326 | 348 | <property name="visible">True</property> | ||
327 | 349 | <property name="label" translatable="yes">Messages</property> | ||
328 | 350 | </object> | ||
329 | 351 | <packing> | ||
330 | 352 | <property name="position">1</property> | ||
331 | 353 | <property name="tab_fill">False</property> | ||
332 | 354 | </packing> | ||
333 | 355 | </child> | ||
334 | 356 | <child> | ||
335 | 357 | <object class="GtkVBox" id="vbox6"> | ||
336 | 358 | <property name="visible">True</property> | ||
337 | 359 | <child> | ||
338 | 360 | <object class="GtkFrame" id="frame6"> | ||
339 | 361 | <property name="visible">True</property> | ||
340 | 362 | <property name="label_xalign">0</property> | ||
341 | 363 | <property name="shadow_type">none</property> | ||
342 | 364 | <child> | ||
343 | 365 | <object class="GtkAlignment" id="alignment5"> | ||
344 | 366 | <property name="visible">True</property> | ||
345 | 367 | <property name="left_padding">12</property> | ||
346 | 368 | <child> | ||
347 | 369 | <object class="GtkTable" id="urlshorter_table"> | ||
348 | 370 | <property name="visible">True</property> | ||
349 | 371 | <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> | ||
350 | 372 | <property name="n_rows">3</property> | ||
351 | 334 | <child> | 373 | <child> |
352 | 335 | <object class="GtkCheckButton" id="shorten_urls"> | 374 | <object class="GtkCheckButton" id="shorten_urls"> |
353 | 336 | <property name="label" translatable="yes">Automatically shorten pasted URLs using:</property> | 375 | <property name="label" translatable="yes">Automatically shorten pasted URLs using:</property> |
354 | @@ -344,7 +383,6 @@ | |||
355 | 344 | <child> | 383 | <child> |
356 | 345 | <object class="GtkVBox" id="urlshorter_container"> | 384 | <object class="GtkVBox" id="urlshorter_container"> |
357 | 346 | <property name="visible">True</property> | 385 | <property name="visible">True</property> |
358 | 347 | <property name="orientation">vertical</property> | ||
359 | 348 | <property name="spacing">5</property> | 386 | <property name="spacing">5</property> |
360 | 349 | <child> | 387 | <child> |
361 | 350 | <placeholder/> | 388 | <placeholder/> |
362 | @@ -355,36 +393,39 @@ | |||
363 | 355 | <property name="bottom_attach">2</property> | 393 | <property name="bottom_attach">2</property> |
364 | 356 | </packing> | 394 | </packing> |
365 | 357 | </child> | 395 | </child> |
366 | 396 | <child> | ||
367 | 397 | <placeholder/> | ||
368 | 398 | </child> | ||
369 | 358 | </object> | 399 | </object> |
370 | 359 | </child> | 400 | </child> |
371 | 360 | </object> | 401 | </object> |
372 | 361 | </child> | 402 | </child> |
373 | 362 | <child type="label"> | 403 | <child type="label"> |
375 | 363 | <object class="GtkLabel" id="label79"> | 404 | <object class="GtkLabel" id="label2"> |
376 | 364 | <property name="visible">True</property> | 405 | <property name="visible">True</property> |
379 | 365 | <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> | 406 | <property name="label" translatable="yes"><b>URL Shortener</b></property> |
378 | 366 | <property name="label" translatable="yes"><b>Advanced</b></property> | ||
380 | 367 | <property name="use_markup">True</property> | 407 | <property name="use_markup">True</property> |
381 | 368 | </object> | 408 | </object> |
382 | 369 | </child> | 409 | </child> |
383 | 370 | </object> | 410 | </object> |
384 | 371 | <packing> | 411 | <packing> |
385 | 372 | <property name="expand">False</property> | 412 | <property name="expand">False</property> |
387 | 373 | <property name="position">2</property> | 413 | <property name="fill">False</property> |
388 | 414 | <property name="position">0</property> | ||
389 | 374 | </packing> | 415 | </packing> |
390 | 375 | </child> | 416 | </child> |
391 | 376 | </object> | 417 | </object> |
392 | 377 | <packing> | 418 | <packing> |
394 | 378 | <property name="position">1</property> | 419 | <property name="position">2</property> |
395 | 379 | </packing> | 420 | </packing> |
396 | 380 | </child> | 421 | </child> |
397 | 381 | <child type="tab"> | 422 | <child type="tab"> |
399 | 382 | <object class="GtkLabel" id="messages_label"> | 423 | <object class="GtkLabel" id="services_label"> |
400 | 383 | <property name="visible">True</property> | 424 | <property name="visible">True</property> |
402 | 384 | <property name="label" translatable="yes">Messages</property> | 425 | <property name="label" translatable="yes">Services</property> |
403 | 385 | </object> | 426 | </object> |
404 | 386 | <packing> | 427 | <packing> |
406 | 387 | <property name="position">1</property> | 428 | <property name="position">2</property> |
407 | 388 | <property name="tab_fill">False</property> | 429 | <property name="tab_fill">False</property> |
408 | 389 | </packing> | 430 | </packing> |
409 | 390 | </child> | 431 | </child> |
410 | @@ -392,7 +433,6 @@ | |||
411 | 392 | <object class="GtkVBox" id="vbox5"> | 433 | <object class="GtkVBox" id="vbox5"> |
412 | 393 | <property name="visible">True</property> | 434 | <property name="visible">True</property> |
413 | 394 | <property name="border_width">5</property> | 435 | <property name="border_width">5</property> |
414 | 395 | <property name="orientation">vertical</property> | ||
415 | 396 | <property name="spacing">10</property> | 436 | <property name="spacing">10</property> |
416 | 397 | <child> | 437 | <child> |
417 | 398 | <object class="GtkFrame" id="frame3"> | 438 | <object class="GtkFrame" id="frame3"> |
418 | @@ -408,7 +448,6 @@ | |||
419 | 408 | <object class="GtkVBox" id="theme_container"> | 448 | <object class="GtkVBox" id="theme_container"> |
420 | 409 | <property name="visible">True</property> | 449 | <property name="visible">True</property> |
421 | 410 | <property name="tooltip_text" translatable="yes">Select a message theme</property> | 450 | <property name="tooltip_text" translatable="yes">Select a message theme</property> |
422 | 411 | <property name="orientation">vertical</property> | ||
423 | 412 | <property name="spacing">5</property> | 451 | <property name="spacing">5</property> |
424 | 413 | <child> | 452 | <child> |
425 | 414 | <placeholder/> | 453 | <placeholder/> |
426 | @@ -432,7 +471,7 @@ | |||
427 | 432 | </child> | 471 | </child> |
428 | 433 | </object> | 472 | </object> |
429 | 434 | <packing> | 473 | <packing> |
431 | 435 | <property name="position">2</property> | 474 | <property name="position">3</property> |
432 | 436 | </packing> | 475 | </packing> |
433 | 437 | </child> | 476 | </child> |
434 | 438 | <child type="tab"> | 477 | <child type="tab"> |
435 | @@ -441,7 +480,7 @@ | |||
436 | 441 | <property name="label" translatable="yes">Style</property> | 480 | <property name="label" translatable="yes">Style</property> |
437 | 442 | </object> | 481 | </object> |
438 | 443 | <packing> | 482 | <packing> |
440 | 444 | <property name="position">2</property> | 483 | <property name="position">3</property> |
441 | 445 | <property name="tab_fill">False</property> | 484 | <property name="tab_fill">False</property> |
442 | 446 | </packing> | 485 | </packing> |
443 | 447 | </child> | 486 | </child> |
Can you please only make the branch for bit.ly currently there is no scope for an extra tab.