Merge lp:~stefan-schwarzburg/qreator/qreator_url_shortener into lp:~dpm/qreator/trunk
- qreator_url_shortener
- Merge into trunk
Status: | Superseded | ||||
---|---|---|---|---|---|
Proposed branch: | lp:~stefan-schwarzburg/qreator/qreator_url_shortener | ||||
Merge into: | lp:~dpm/qreator/trunk | ||||
Diff against target: |
1210 lines (+539/-132) 28 files modified
.quickly (+1/-1) bin/qreator (+8/-3) data/ui/QrCodeURL.ui (+92/-1) qreator/QreatorWindow.py (+3/-4) qreator/__init__.py (+8/-8) qreator/qrcodes/GtkHelpers.py (+8/-8) qreator/qrcodes/QRCodeLocation.py (+2/-2) qreator/qrcodes/QRCodeLocationGtk.py (+8/-8) qreator/qrcodes/QRCodeSoftwareCenterApp.py (+2/-2) qreator/qrcodes/QRCodeSoftwareCenterAppGtk.py (+8/-8) qreator/qrcodes/QRCodeText.py (+2/-2) qreator/qrcodes/QRCodeTextGtk.py (+8/-8) qreator/qrcodes/QRCodeType.py (+1/-1) qreator/qrcodes/QRCodeURL.py (+2/-2) qreator/qrcodes/QRCodeURLGtk.py (+108/-10) qreator/qrcodes/QRCodeVCard.py (+2/-2) qreator/qrcodes/QRCodeVCardGtk.py (+9/-9) qreator/qrcodes/QRCodeWifi.py (+2/-2) qreator/qrcodes/QRCodeWifiGtk.py (+8/-8) qreator/tools.py (+9/-0) qreator_lib/AboutDialog.py (+50/-0) qreator_lib/Builder.py (+5/-3) qreator_lib/PreferencesDialog.py (+64/-0) qreator_lib/Window.py (+46/-4) qreator_lib/__init__.py (+2/-0) qreator_lib/helpers.py (+7/-10) qreator_lib/qreatorconfig.py (+2/-4) setup.py (+72/-22) |
||||
To merge this branch: | bzr merge lp:~stefan-schwarzburg/qreator/qreator_url_shortener | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
David Planella | Needs Information | ||
Review via email: mp+130106@code.launchpad.net |
This proposal has been superseded by a proposal from 2012-11-10.
Commit message
Description of the change
This branch implements the option to directly shorten URLs via Goo.gl, Bit.ly or TinyURL.com.
The conversion option is visible all the time, but has to be activated manually.
If the URL was shortened and then the URL is changed, the shortened version is removed and must be activated again.
The visual components are:
- a conversion button
- a combobox to select the service
- a link button for the shortened url which can be used to check that the shortening worked as expected
- a label that can display errors.
This feature was not meantioned in the next milestone, but since it is complete and working, we might want to include it as well.
David: it would be great if you could simply have a look at the layout and tell me if you like it :-)
- 125. By Schwarzburg
-
added label to make the combobox meaning more clear
- 126. By Schwarzburg
-
Pre-upgrade checkpoint
- 127. By Schwarzburg
-
Pre-upgrade checkpoint
- 128. By Schwarzburg
-
Pre-upgrade checkpoint
- 129. By Schwarzburg
-
Pre-upgrade checkpoint
- 130. By Schwarzburg
-
updates due to quickly update
- 131. By Schwarzburg
-
now in sync with possible future trunk :-)
- 132. By Schwarzburg
-
minor cosnmetical changes; added missing tools.py file
David Planella (dpm) wrote : | # |
Now that we've switched the trunk branch from my personal one to the team-owned one, would you mind clicking on the "Resubmit proposal" link at the top of the page, change the "Target branch" to be ~qreator-
Launchpad will then show the diff against the right branch. Thanks!
- 133. By Schwarzburg
-
merged with latest trunk
- 134. By Schwarzburg
-
simplified interface; implemented all suggested changes
- 135. By Schwarzburg
-
nicer feedback to the user what is shortened
- 136. By Schwarzburg
-
implemented user interface suggestion by david
- 137. By Schwarzburg
-
updated to latest trunk
- 138. By Schwarzburg
-
added messagedialog to show network connection problems
- 139. By Schwarzburg
-
removed ramains from older branches. Do not know why 'merge' with trunk did not remove them
- 140. By Schwarzburg
-
removed my api key from bitly, added isdg (as default), made the error message slightly more useful
Unmerged revisions
- 140. By Schwarzburg
-
removed my api key from bitly, added isdg (as default), made the error message slightly more useful
- 139. By Schwarzburg
-
removed ramains from older branches. Do not know why 'merge' with trunk did not remove them
- 138. By Schwarzburg
-
added messagedialog to show network connection problems
- 137. By Schwarzburg
-
updated to latest trunk
- 136. By Schwarzburg
-
implemented user interface suggestion by david
- 135. By Schwarzburg
-
nicer feedback to the user what is shortened
- 134. By Schwarzburg
-
simplified interface; implemented all suggested changes
- 133. By Schwarzburg
-
merged with latest trunk
- 132. By Schwarzburg
-
minor cosnmetical changes; added missing tools.py file
- 131. By Schwarzburg
-
now in sync with possible future trunk :-)
Preview Diff
1 | === modified file '.quickly' |
2 | --- .quickly 2012-05-28 11:05:50 +0000 |
3 | +++ .quickly 2012-10-28 16:08:21 +0000 |
4 | @@ -1,5 +1,5 @@ |
5 | project = qreator |
6 | -version = 12.04 |
7 | +version = 12.08.1 |
8 | template = ubuntu-application |
9 | lp_id = qreator |
10 | dependencies = software-center |
11 | |
12 | === modified file 'bin/qreator' |
13 | --- bin/qreator 2012-05-28 09:38:22 +0000 |
14 | +++ bin/qreator 2012-10-28 16:08:21 +0000 |
15 | @@ -15,9 +15,13 @@ |
16 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | ### END LICENSE |
18 | |
19 | +### DO NOT EDIT THIS FILE ### |
20 | + |
21 | import sys |
22 | import os |
23 | |
24 | +import locale |
25 | +locale.textdomain('qreator') |
26 | |
27 | # Add project root directory (enable symlink and trunk execution) |
28 | PROJECT_ROOT_DIRECTORY = os.path.abspath( |
29 | @@ -25,18 +29,19 @@ |
30 | |
31 | python_path = [] |
32 | if os.path.abspath(__file__).startswith('/opt'): |
33 | - syspath = sys.path[:] # copy to avoid infinite loop in pending objects |
34 | + locale.bindtextdomain('qreator', '/opt/extras.ubuntu.com/qreator/share/locale') |
35 | + syspath = sys.path[:] # copy to avoid infinite loop in pending objects |
36 | for path in syspath: |
37 | opt_path = path.replace('/usr', '/opt/extras.ubuntu.com/qreator') |
38 | python_path.insert(0, opt_path) |
39 | sys.path.insert(0, opt_path) |
40 | + os.putenv("XDG_DATA_DIRS", "%s:%s" % ("/opt/extras.ubuntu.com/qreator/share/", os.getenv("XDG_DATA_DIRS", "/usr/local/share/:/usr/share/"))) |
41 | if (os.path.exists(os.path.join(PROJECT_ROOT_DIRECTORY, 'qreator')) |
42 | and PROJECT_ROOT_DIRECTORY not in sys.path): |
43 | python_path.insert(0, PROJECT_ROOT_DIRECTORY) |
44 | sys.path.insert(0, PROJECT_ROOT_DIRECTORY) |
45 | if python_path: |
46 | - os.putenv('PYTHONPATH', "%s:%s" % (os.getenv('PYTHONPATH', ''), |
47 | - ':'.join(python_path))) # for subprocesses |
48 | + os.putenv('PYTHONPATH', "%s:%s" % (os.getenv('PYTHONPATH', ''), ':'.join(python_path))) # for subprocesses |
49 | |
50 | import qreator |
51 | qreator.main() |
52 | |
53 | === modified file 'data/ui/QrCodeURL.ui' |
54 | --- data/ui/QrCodeURL.ui 2012-05-30 08:33:06 +0000 |
55 | +++ data/ui/QrCodeURL.ui 2012-10-28 16:08:21 +0000 |
56 | @@ -8,10 +8,15 @@ |
57 | <object class="GtkEntry" id="entryURL"> |
58 | <property name="visible">True</property> |
59 | <property name="can_focus">True</property> |
60 | + <property name="margin_top">3</property> |
61 | + <property name="margin_bottom">3</property> |
62 | + <property name="hexpand">True</property> |
63 | + <property name="placeholder_text">[URL]</property> |
64 | + <property name="visible">True</property> |
65 | + <property name="can_focus">True</property> |
66 | <property name="hexpand">True</property> |
67 | <property name="invisible_char">•</property> |
68 | <property name="invisible_char_set">True</property> |
69 | - <property name="placeholder_text">[URL]</property> |
70 | <signal name="changed" handler="on_entryURL_changed" swapped="no"/> |
71 | <signal name="icon-press" handler="on_entryURL_icon_press" swapped="no"/> |
72 | </object> |
73 | @@ -43,5 +48,91 @@ |
74 | <property name="height">1</property> |
75 | </packing> |
76 | </child> |
77 | + <child> |
78 | + <object class="GtkToggleButton" id="togglebuttonURLShortener"> |
79 | + <property name="label" translatable="yes">Shorten URL</property> |
80 | + <property name="use_action_appearance">False</property> |
81 | + <property name="visible">True</property> |
82 | + <property name="can_focus">True</property> |
83 | + <property name="receives_default">True</property> |
84 | + <property name="use_action_appearance">False</property> |
85 | + <signal name="toggled" handler="on_togglebuttonURLShortener_toggled" swapped="no"/> |
86 | + </object> |
87 | + <packing> |
88 | + <property name="left_attach">0</property> |
89 | + <property name="top_attach">1</property> |
90 | + <property name="width">1</property> |
91 | + <property name="height">1</property> |
92 | + </packing> |
93 | + </child> |
94 | + <child> |
95 | + <object class="GtkBox" id="box1"> |
96 | + <property name="visible">True</property> |
97 | + <property name="can_focus">False</property> |
98 | + <child> |
99 | + <object class="GtkLabel" id="label1"> |
100 | + <property name="visible">True</property> |
101 | + <property name="can_focus">False</property> |
102 | + <property name="xpad">5</property> |
103 | + <property name="label" translatable="yes">with</property> |
104 | + </object> |
105 | + <packing> |
106 | + <property name="expand">False</property> |
107 | + <property name="fill">True</property> |
108 | + <property name="position">0</property> |
109 | + </packing> |
110 | + </child> |
111 | + <child> |
112 | + <object class="GtkComboBoxText" id="comboboxtextURLShortener"> |
113 | + <property name="visible">True</property> |
114 | + <property name="can_focus">False</property> |
115 | + <property name="entry_text_column">0</property> |
116 | + <property name="id_column">1</property> |
117 | + </object> |
118 | + <packing> |
119 | + <property name="expand">False</property> |
120 | + <property name="fill">True</property> |
121 | + <property name="position">1</property> |
122 | + </packing> |
123 | + </child> |
124 | + <child> |
125 | + <object class="GtkLinkButton" id="linkbuttonUrlShortener"> |
126 | + <property name="label" translatable="yes">[shortened URL]</property> |
127 | + <property name="use_action_appearance">False</property> |
128 | + <property name="sensitive">False</property> |
129 | + <property name="can_focus">True</property> |
130 | + <property name="receives_default">True</property> |
131 | + <property name="has_tooltip">True</property> |
132 | + <property name="margin_right">6</property> |
133 | + <property name="hexpand">True</property> |
134 | + <property name="use_action_appearance">False</property> |
135 | + <property name="relief">none</property> |
136 | + </object> |
137 | + <packing> |
138 | + <property name="expand">False</property> |
139 | + <property name="fill">False</property> |
140 | + <property name="position">2</property> |
141 | + </packing> |
142 | + </child> |
143 | + <child> |
144 | + <object class="GtkLabel" id="messagelabelUrlShortener"> |
145 | + <property name="can_focus">False</property> |
146 | + <property name="label" translatable="yes">label</property> |
147 | + <property name="justify">center</property> |
148 | + </object> |
149 | + <packing> |
150 | + <property name="expand">False</property> |
151 | + <property name="fill">True</property> |
152 | + <property name="position">3</property> |
153 | + </packing> |
154 | + </child> |
155 | + </object> |
156 | + <packing> |
157 | + <property name="left_attach">1</property> |
158 | + <property name="top_attach">1</property> |
159 | + <property name="width">1</property> |
160 | + <property name="height">1</property> |
161 | + </packing> |
162 | + </child> |
163 | </object> |
164 | </interface> |
165 | |
166 | === modified file 'qreator/QreatorWindow.py' |
167 | --- qreator/QreatorWindow.py 2012-06-24 07:59:42 +0000 |
168 | +++ qreator/QreatorWindow.py 2012-10-28 16:08:21 +0000 |
169 | @@ -25,7 +25,7 @@ |
170 | |
171 | from qreator_lib.i18n import _ |
172 | from qreator_lib import Window |
173 | -from qreator_lib.helpers import get_media_file |
174 | +from qreator.tools import get_media_path |
175 | |
176 | from QRCode import QRCode |
177 | from QRCode import QRCodeOutput |
178 | @@ -71,7 +71,7 @@ |
179 | |
180 | # Load the background texture in the QR code page |
181 | self.texture = cairo.ImageSurface.create_from_png( |
182 | - get_media_file("pattern.png")) |
183 | + get_media_path("pattern.png")) |
184 | |
185 | # Time to wait in milliseconds before switching to the next view |
186 | # after having clicked once on an iconview icon |
187 | @@ -161,8 +161,7 @@ |
188 | self.qr_types_store.clear() |
189 | |
190 | for qr_type in self.qr_types: |
191 | - icon = GdkPixbuf.Pixbuf.new_from_file(get_media_file( |
192 | - qr_type.icon_path)) |
193 | + icon = GdkPixbuf.Pixbuf.new_from_file(qr_type.icon_path) |
194 | self.qr_types_store.append([qr_type.description, |
195 | icon, |
196 | qr_type.id]) |
197 | |
198 | === modified file 'qreator/__init__.py' |
199 | --- qreator/__init__.py 2012-06-23 08:42:52 +0000 |
200 | +++ qreator/__init__.py 2012-10-28 16:08:21 +0000 |
201 | @@ -1,16 +1,16 @@ |
202 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
203 | ### BEGIN LICENSE |
204 | # Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
205 | -# This program is free software: you can redistribute it and/or modify it |
206 | -# under the terms of the GNU General Public License version 3, as published |
207 | +# This program is free software: you can redistribute it and/or modify it |
208 | +# under the terms of the GNU General Public License version 3, as published |
209 | # by the Free Software Foundation. |
210 | -# |
211 | -# This program is distributed in the hope that it will be useful, but |
212 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
213 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
214 | +# |
215 | +# This program is distributed in the hope that it will be useful, but |
216 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
217 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
218 | # PURPOSE. See the GNU General Public License for more details. |
219 | -# |
220 | -# You should have received a copy of the GNU General Public License along |
221 | +# |
222 | +# You should have received a copy of the GNU General Public License along |
223 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
224 | ### END LICENSE |
225 | |
226 | |
227 | === modified file 'qreator/qrcodes/GtkHelpers.py' |
228 | --- qreator/qrcodes/GtkHelpers.py 2012-05-30 10:19:57 +0000 |
229 | +++ qreator/qrcodes/GtkHelpers.py 2012-10-28 16:08:21 +0000 |
230 | @@ -1,16 +1,16 @@ |
231 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
232 | ### BEGIN LICENSE |
233 | # Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
234 | -# This program is free software: you can redistribute it and/or modify it |
235 | -# under the terms of the GNU General Public License version 3, as published |
236 | +# This program is free software: you can redistribute it and/or modify it |
237 | +# under the terms of the GNU General Public License version 3, as published |
238 | # by the Free Software Foundation. |
239 | -# |
240 | -# This program is distributed in the hope that it will be useful, but |
241 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
242 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
243 | +# |
244 | +# This program is distributed in the hope that it will be useful, but |
245 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
246 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
247 | # PURPOSE. See the GNU General Public License for more details. |
248 | -# |
249 | -# You should have received a copy of the GNU General Public License along |
250 | +# |
251 | +# You should have received a copy of the GNU General Public License along |
252 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
253 | ### END LICENSE |
254 | |
255 | |
256 | === modified file 'qreator/qrcodes/QRCodeLocation.py' |
257 | --- qreator/qrcodes/QRCodeLocation.py 2012-05-30 08:33:06 +0000 |
258 | +++ qreator/qrcodes/QRCodeLocation.py 2012-10-28 16:08:21 +0000 |
259 | @@ -14,14 +14,14 @@ |
260 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
261 | ### END LICENSE |
262 | |
263 | -from qreator_lib.helpers import get_media_file |
264 | +from qreator.tools import get_media_path |
265 | #from qreator_lib import QRCodeType as QRCodeType |
266 | from QRCodeLocationGtk import QRCodeLocationGtk |
267 | |
268 | class QRCodeLocation(object): |
269 | def __init__(self, qr_code_update_func, icon_path, description, id): |
270 | self.qr_code_update_func = qr_code_update_func |
271 | - self.icon_path = get_media_file(icon_path) |
272 | + self.icon_path = get_media_path(icon_path) |
273 | self.description = description |
274 | self.id = id |
275 | |
276 | |
277 | === modified file 'qreator/qrcodes/QRCodeLocationGtk.py' |
278 | --- qreator/qrcodes/QRCodeLocationGtk.py 2012-06-23 16:49:09 +0000 |
279 | +++ qreator/qrcodes/QRCodeLocationGtk.py 2012-10-28 16:08:21 +0000 |
280 | @@ -1,16 +1,16 @@ |
281 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
282 | ### BEGIN LICENSE |
283 | # Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
284 | -# This program is free software: you can redistribute it and/or modify it |
285 | -# under the terms of the GNU General Public License version 3, as published |
286 | +# This program is free software: you can redistribute it and/or modify it |
287 | +# under the terms of the GNU General Public License version 3, as published |
288 | # by the Free Software Foundation. |
289 | -# |
290 | -# This program is distributed in the hope that it will be useful, but |
291 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
292 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
293 | +# |
294 | +# This program is distributed in the hope that it will be useful, but |
295 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
296 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
297 | # PURPOSE. See the GNU General Public License for more details. |
298 | -# |
299 | -# You should have received a copy of the GNU General Public License along |
300 | +# |
301 | +# You should have received a copy of the GNU General Public License along |
302 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
303 | ### END LICENSE |
304 | |
305 | |
306 | === modified file 'qreator/qrcodes/QRCodeSoftwareCenterApp.py' |
307 | --- qreator/qrcodes/QRCodeSoftwareCenterApp.py 2012-05-30 08:33:06 +0000 |
308 | +++ qreator/qrcodes/QRCodeSoftwareCenterApp.py 2012-10-28 16:08:21 +0000 |
309 | @@ -14,7 +14,7 @@ |
310 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
311 | ### END LICENSE |
312 | |
313 | -from qreator_lib.helpers import get_media_file |
314 | +from qreator.tools import get_media_path |
315 | #from qreator_lib import QRCodeType as QRCodeType |
316 | from QRCodeSoftwareCenterAppGtk import QRCodeSoftwareCenterAppGtk |
317 | |
318 | @@ -22,7 +22,7 @@ |
319 | class QRCodeSoftwareCenterApp(object): |
320 | def __init__(self, qr_code_update_func, icon_path, description, id): |
321 | self.qr_code_update_func = qr_code_update_func |
322 | - self.icon_path = get_media_file(icon_path) |
323 | + self.icon_path = get_media_path(icon_path) |
324 | self.description = description |
325 | self.id = id |
326 | |
327 | |
328 | === modified file 'qreator/qrcodes/QRCodeSoftwareCenterAppGtk.py' |
329 | --- qreator/qrcodes/QRCodeSoftwareCenterAppGtk.py 2012-05-30 10:19:57 +0000 |
330 | +++ qreator/qrcodes/QRCodeSoftwareCenterAppGtk.py 2012-10-28 16:08:21 +0000 |
331 | @@ -1,16 +1,16 @@ |
332 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
333 | ### BEGIN LICENSE |
334 | # Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
335 | -# This program is free software: you can redistribute it and/or modify it |
336 | -# under the terms of the GNU General Public License version 3, as published |
337 | +# This program is free software: you can redistribute it and/or modify it |
338 | +# under the terms of the GNU General Public License version 3, as published |
339 | # by the Free Software Foundation. |
340 | -# |
341 | -# This program is distributed in the hope that it will be useful, but |
342 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
343 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
344 | +# |
345 | +# This program is distributed in the hope that it will be useful, but |
346 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
347 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
348 | # PURPOSE. See the GNU General Public License for more details. |
349 | -# |
350 | -# You should have received a copy of the GNU General Public License along |
351 | +# |
352 | +# You should have received a copy of the GNU General Public License along |
353 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
354 | ### END LICENSE |
355 | |
356 | |
357 | === modified file 'qreator/qrcodes/QRCodeText.py' |
358 | --- qreator/qrcodes/QRCodeText.py 2012-05-30 08:33:06 +0000 |
359 | +++ qreator/qrcodes/QRCodeText.py 2012-10-28 16:08:21 +0000 |
360 | @@ -14,14 +14,14 @@ |
361 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
362 | ### END LICENSE |
363 | |
364 | -from qreator_lib.helpers import get_media_file |
365 | +from qreator.tools import get_media_path |
366 | #from qreator_lib import QRCodeType as QRCodeType |
367 | from QRCodeTextGtk import QRCodeTextGtk |
368 | |
369 | class QRCodeText(object): |
370 | def __init__(self, qr_code_update_func, icon_path, description, id): |
371 | self.qr_code_update_func = qr_code_update_func |
372 | - self.icon_path = get_media_file(icon_path) |
373 | + self.icon_path = get_media_path(icon_path) |
374 | self.description = description |
375 | self.id = id |
376 | |
377 | |
378 | === modified file 'qreator/qrcodes/QRCodeTextGtk.py' |
379 | --- qreator/qrcodes/QRCodeTextGtk.py 2012-05-30 08:33:06 +0000 |
380 | +++ qreator/qrcodes/QRCodeTextGtk.py 2012-10-28 16:08:21 +0000 |
381 | @@ -1,16 +1,16 @@ |
382 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
383 | ### BEGIN LICENSE |
384 | # Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
385 | -# This program is free software: you can redistribute it and/or modify it |
386 | -# under the terms of the GNU General Public License version 3, as published |
387 | +# This program is free software: you can redistribute it and/or modify it |
388 | +# under the terms of the GNU General Public License version 3, as published |
389 | # by the Free Software Foundation. |
390 | -# |
391 | -# This program is distributed in the hope that it will be useful, but |
392 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
393 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
394 | +# |
395 | +# This program is distributed in the hope that it will be useful, but |
396 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
397 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
398 | # PURPOSE. See the GNU General Public License for more details. |
399 | -# |
400 | -# You should have received a copy of the GNU General Public License along |
401 | +# |
402 | +# You should have received a copy of the GNU General Public License along |
403 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
404 | ### END LICENSE |
405 | |
406 | |
407 | === modified file 'qreator/qrcodes/QRCodeType.py' |
408 | --- qreator/qrcodes/QRCodeType.py 2012-05-30 08:33:06 +0000 |
409 | +++ qreator/qrcodes/QRCodeType.py 2012-10-28 16:08:21 +0000 |
410 | @@ -19,7 +19,7 @@ |
411 | id): |
412 | self.parent_widget = parent_widget |
413 | self.drawing_area = drawing_area |
414 | - self.icon_path = get_media_file(icon_path) |
415 | + self.icon_path = get_media_path(icon_path) |
416 | self.description = description |
417 | self.id = id |
418 | |
419 | |
420 | === modified file 'qreator/qrcodes/QRCodeURL.py' |
421 | --- qreator/qrcodes/QRCodeURL.py 2012-05-30 08:33:06 +0000 |
422 | +++ qreator/qrcodes/QRCodeURL.py 2012-10-28 16:08:21 +0000 |
423 | @@ -14,14 +14,14 @@ |
424 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
425 | ### END LICENSE |
426 | |
427 | -from qreator_lib.helpers import get_media_file |
428 | +from qreator.tools import get_media_path |
429 | #from qreator_lib import QRCodeType as QRCodeType |
430 | from QRCodeURLGtk import QRCodeURLGtk |
431 | |
432 | class QRCodeURL(object): |
433 | def __init__(self, qr_code_update_func, icon_path, description, id): |
434 | self.qr_code_update_func = qr_code_update_func |
435 | - self.icon_path = get_media_file(icon_path) |
436 | + self.icon_path = get_media_path(icon_path) |
437 | self.description = description |
438 | self.id = id |
439 | |
440 | |
441 | === modified file 'qreator/qrcodes/QRCodeURLGtk.py' |
442 | --- qreator/qrcodes/QRCodeURLGtk.py 2012-08-02 13:15:02 +0000 |
443 | +++ qreator/qrcodes/QRCodeURLGtk.py 2012-10-28 16:08:21 +0000 |
444 | @@ -1,16 +1,16 @@ |
445 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
446 | ### BEGIN LICENSE |
447 | # Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
448 | -# This program is free software: you can redistribute it and/or modify it |
449 | -# under the terms of the GNU General Public License version 3, as published |
450 | +# This program is free software: you can redistribute it and/or modify it |
451 | +# under the terms of the GNU General Public License version 3, as published |
452 | # by the Free Software Foundation. |
453 | -# |
454 | -# This program is distributed in the hope that it will be useful, but |
455 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
456 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
457 | +# |
458 | +# This program is distributed in the hope that it will be useful, but |
459 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
460 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
461 | # PURPOSE. See the GNU General Public License for more details. |
462 | -# |
463 | -# You should have received a copy of the GNU General Public License along |
464 | +# |
465 | +# You should have received a copy of the GNU General Public License along |
466 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
467 | ### END LICENSE |
468 | |
469 | @@ -18,6 +18,53 @@ |
470 | from GtkHelpers import clear_text_entry, show_clear_icon |
471 | from qreator_lib.helpers import get_data_file |
472 | from qreator_lib.i18n import _ |
473 | +import requests |
474 | +import json |
475 | +from urllib import urlencode |
476 | + |
477 | + |
478 | +class TinyUrlShortener(object): |
479 | + def __init__(self, url=None): |
480 | + self.api_url = "http://tinyurl.com/api-create.php" |
481 | + self.url = url |
482 | + |
483 | + def short_url(self): |
484 | + self.r = requests.get("{0}?url={1}".format(self.api_url, self.url)) |
485 | + return self.r.content |
486 | + |
487 | +class BitlyShortener(object): |
488 | + def __init__(self, url=None): |
489 | + self.api_url = 'http://api.bit.ly/v3/shorten' |
490 | + self.url = url |
491 | + self.data = {"login": "xubuntix", |
492 | + "apiKey": "R_9b35d5ecdee200a89e3ca16b312bf4a1", |
493 | + "longUrl": self.url} |
494 | + |
495 | + def short_url(self): |
496 | + self.r = requests.get(self.api_url, params=self.data) |
497 | + self.results = json.loads(self.r.content) |
498 | + return self.results["data"]["url"] |
499 | + |
500 | + |
501 | +class GoogleShortener(object): |
502 | + def __init__(self, url=None): |
503 | + self.api_key = "AIzaSyCU_pFNpACW4luWEZRgNnfWMEUdlnZyYQI" |
504 | + self.api_url = 'https://www.googleapis.com/urlshortener/v1/url' |
505 | + self.url = url |
506 | + self.params = {"key": self.api_key, |
507 | + 'Content-Type' : 'application/json'} |
508 | + self.data = {"longUrl": self.url} |
509 | + |
510 | + def short_url(self): |
511 | + self.r = requests.post(self.api_url, headers=self.params, data=json.dumps(self.data)) |
512 | + self.results = json.loads(self.r.content) |
513 | + return self.results["id"] |
514 | + |
515 | + |
516 | +SHORTENER_TYPES = [(_("Google"), GoogleShortener), |
517 | + (_("Bitly"), BitlyShortener), |
518 | + (_("TinyUrl"), TinyUrlShortener), |
519 | + ] |
520 | |
521 | |
522 | class QRCodeURLGtk(object): |
523 | @@ -38,9 +85,52 @@ |
524 | self.entry.set_placeholder_text(_('[URL]')) |
525 | self.combobox.set_active(0) |
526 | |
527 | + # Currently three shortener options are available: google tinyurl bitly |
528 | + # The selected service is stored in self.Shortener |
529 | + self.shorten_options = self.builder.get_object('comboboxtextURLShortener') |
530 | + for s in SHORTENER_TYPES: |
531 | + self.shorten_options.append_text(s[0]) |
532 | + self.shorten_options.set_active(0) |
533 | + self.shorten_options.connect("changed", self.on_shortener_changed) |
534 | + self.Shortener = SHORTENER_TYPES[self.shorten_options.get_active()][1] |
535 | + |
536 | self.entry.connect("changed", self.on_entryURL_changed) |
537 | self.combobox.connect("changed", self.on_comboboxtextProtocol_changed) |
538 | |
539 | + def on_shortener_changed(self, widget): |
540 | + self.Shortener = SHORTENER_TYPES[widget.get_active()][1] |
541 | + self.on_togglebuttonURLShortener_toggled( |
542 | + self.builder.get_object('togglebuttonURLShortener')) |
543 | + |
544 | + |
545 | + def on_togglebuttonURLShortener_toggled(self, widget): |
546 | + if widget.get_active(): |
547 | + s = self.Shortener(url=self.adress) |
548 | + try: |
549 | + short_adress = s.short_url() |
550 | + except requests.exceptions.ConnectionError: |
551 | + self.builder.get_object('linkbuttonUrlShortener').set_visible(False) |
552 | + self.builder.get_object('linkbuttonUrlShortener').set_sensitive(False) |
553 | + self.builder.get_object('messagelabelUrlShortener').set_text( |
554 | + _("A network connection error occured.")) |
555 | + self.builder.get_object('messagelabelUrlShortener').set_visible(True) |
556 | + return() |
557 | + except: |
558 | + self.builder.get_object('linkbuttonUrlShortener').set_visible(False) |
559 | + self.builder.get_object('linkbuttonUrlShortener').set_sensitive(False) |
560 | + self.builder.get_object('messagelabelUrlShortener').set_text( |
561 | + _("An error occured while trying to shorten the url.")) |
562 | + self.builder.get_object('messagelabelUrlShortener').set_visible(True) |
563 | + return() |
564 | + self.builder.get_object('linkbuttonUrlShortener').set_uri(short_adress) |
565 | + self.builder.get_object('linkbuttonUrlShortener').set_label(short_adress) |
566 | + self.builder.get_object('linkbuttonUrlShortener').set_sensitive(True) |
567 | + self.builder.get_object('linkbuttonUrlShortener').set_visible(True) |
568 | + self.qr_code_update_func(short_adress) |
569 | + else: |
570 | + self.builder.get_object('linkbuttonUrlShortener').set_visible(False) |
571 | + self.builder.get_object('linkbuttonUrlShortener').set_sensitive(False) |
572 | + self.builder.get_object('messagelabelUrlShortener').set_visible(False) |
573 | def on_activated(self): |
574 | pass |
575 | |
576 | @@ -53,7 +143,10 @@ |
577 | if not protocol or www == '': |
578 | return |
579 | |
580 | - self.qr_code_update_func(protocol + www) |
581 | + self.adress = protocol + www |
582 | + |
583 | + self.qr_code_update_func(self.adress) |
584 | + return False |
585 | |
586 | def on_entryURL_icon_press(self, widget, icon, mouse_button): |
587 | clear_text_entry(widget, icon) |
588 | @@ -73,7 +166,12 @@ |
589 | def on_entryURL_changed(self, widget, data=None): |
590 | show_clear_icon(widget) |
591 | self.check_and_remove_protocol(widget) |
592 | - self.update_url_qr_code(www=widget.get_text()) |
593 | + self.clear_shortener() |
594 | + self.update_url_qr_code() |
595 | |
596 | def on_comboboxtextProtocol_changed(self, widget, data=None): |
597 | self.update_url_qr_code(protocol=widget.get_active_text()) |
598 | + |
599 | + def clear_shortener(self): |
600 | + self.builder.get_object('linkbuttonUrlShortener').set_visible(False) |
601 | + self.builder.get_object('togglebuttonURLShortener').set_active(False) |
602 | |
603 | === modified file 'qreator/qrcodes/QRCodeVCard.py' |
604 | --- qreator/qrcodes/QRCodeVCard.py 2012-06-02 08:59:55 +0000 |
605 | +++ qreator/qrcodes/QRCodeVCard.py 2012-10-28 16:08:21 +0000 |
606 | @@ -14,7 +14,7 @@ |
607 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
608 | ### END LICENSE |
609 | |
610 | -from qreator_lib.helpers import get_media_file |
611 | +from qreator.tools import get_media_path |
612 | #from qreator_lib import QRCodeType as QRCodeType |
613 | from QRCodeVCardGtk import QRCodeVCardGtk |
614 | import vobject |
615 | @@ -22,7 +22,7 @@ |
616 | class QRCodeVCard(object): |
617 | def __init__(self, qr_code_update_func, icon_path, description, id): |
618 | self.qr_code_update_func = qr_code_update_func |
619 | - self.icon_path = get_media_file(icon_path) |
620 | + self.icon_path = get_media_path(icon_path) |
621 | self.description = description |
622 | self.id = id |
623 | |
624 | |
625 | === modified file 'qreator/qrcodes/QRCodeVCardGtk.py' |
626 | --- qreator/qrcodes/QRCodeVCardGtk.py 2012-06-09 00:06:51 +0000 |
627 | +++ qreator/qrcodes/QRCodeVCardGtk.py 2012-10-28 16:08:21 +0000 |
628 | @@ -1,16 +1,16 @@ |
629 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
630 | ### BEGIN LICENSE |
631 | -# Copyright (C) 2012 Stefan Schwarzburg <stefan.schwarzburg@googlemail.com> |
632 | -# This program is free software: you can redistribute it and/or modify it |
633 | -# under the terms of the GNU General Public License version 3, as published |
634 | +# Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
635 | +# This program is free software: you can redistribute it and/or modify it |
636 | +# under the terms of the GNU General Public License version 3, as published |
637 | # by the Free Software Foundation. |
638 | -# |
639 | -# This program is distributed in the hope that it will be useful, but |
640 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
641 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
642 | +# |
643 | +# This program is distributed in the hope that it will be useful, but |
644 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
645 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
646 | # PURPOSE. See the GNU General Public License for more details. |
647 | -# |
648 | -# You should have received a copy of the GNU General Public License along |
649 | +# |
650 | +# You should have received a copy of the GNU General Public License along |
651 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
652 | ### END LICENSE |
653 | |
654 | |
655 | === modified file 'qreator/qrcodes/QRCodeWifi.py' |
656 | --- qreator/qrcodes/QRCodeWifi.py 2012-05-30 08:33:06 +0000 |
657 | +++ qreator/qrcodes/QRCodeWifi.py 2012-10-28 16:08:21 +0000 |
658 | @@ -14,14 +14,14 @@ |
659 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
660 | ### END LICENSE |
661 | |
662 | -from qreator_lib.helpers import get_media_file |
663 | +from qreator.tools import get_media_path |
664 | #from qreator_lib import QRCodeType as QRCodeType |
665 | from QRCodeWifiGtk import QRCodeWifiGtk |
666 | |
667 | class QRCodeWifi(object): |
668 | def __init__(self, qr_code_update_func, icon_path, description, id): |
669 | self.qr_code_update_func = qr_code_update_func |
670 | - self.icon_path = get_media_file(icon_path) |
671 | + self.icon_path = get_media_path(icon_path) |
672 | self.description = description |
673 | self.id = id |
674 | |
675 | |
676 | === modified file 'qreator/qrcodes/QRCodeWifiGtk.py' |
677 | --- qreator/qrcodes/QRCodeWifiGtk.py 2012-05-30 10:19:57 +0000 |
678 | +++ qreator/qrcodes/QRCodeWifiGtk.py 2012-10-28 16:08:21 +0000 |
679 | @@ -1,16 +1,16 @@ |
680 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
681 | ### BEGIN LICENSE |
682 | # Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
683 | -# This program is free software: you can redistribute it and/or modify it |
684 | -# under the terms of the GNU General Public License version 3, as published |
685 | +# This program is free software: you can redistribute it and/or modify it |
686 | +# under the terms of the GNU General Public License version 3, as published |
687 | # by the Free Software Foundation. |
688 | -# |
689 | -# This program is distributed in the hope that it will be useful, but |
690 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
691 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
692 | +# |
693 | +# This program is distributed in the hope that it will be useful, but |
694 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
695 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
696 | # PURPOSE. See the GNU General Public License for more details. |
697 | -# |
698 | -# You should have received a copy of the GNU General Public License along |
699 | +# |
700 | +# You should have received a copy of the GNU General Public License along |
701 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
702 | ### END LICENSE |
703 | |
704 | |
705 | === added file 'qreator/tools.py' |
706 | --- qreator/tools.py 1970-01-01 00:00:00 +0000 |
707 | +++ qreator/tools.py 2012-10-28 16:08:21 +0000 |
708 | @@ -0,0 +1,9 @@ |
709 | +import os |
710 | +from qreator_lib.qreatorconfig import get_data_file |
711 | + |
712 | +def get_media_path(media_file_name): |
713 | + media_filename = get_data_file('media', '%s' % (media_file_name,)) |
714 | + if not os.path.exists(media_filename): |
715 | + media_filename = None |
716 | + |
717 | + return media_filename |
718 | |
719 | === added file 'qreator_lib/AboutDialog.py' |
720 | --- qreator_lib/AboutDialog.py 1970-01-01 00:00:00 +0000 |
721 | +++ qreator_lib/AboutDialog.py 2012-10-28 16:08:21 +0000 |
722 | @@ -0,0 +1,50 @@ |
723 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
724 | +### BEGIN LICENSE |
725 | +# Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
726 | +# This program is free software: you can redistribute it and/or modify it |
727 | +# under the terms of the GNU General Public License version 3, as published |
728 | +# by the Free Software Foundation. |
729 | +# |
730 | +# This program is distributed in the hope that it will be useful, but |
731 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
732 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
733 | +# PURPOSE. See the GNU General Public License for more details. |
734 | +# |
735 | +# You should have received a copy of the GNU General Public License along |
736 | +# with this program. If not, see <http://www.gnu.org/licenses/>. |
737 | +### END LICENSE |
738 | + |
739 | +### DO NOT EDIT THIS FILE ### |
740 | + |
741 | +from gi.repository import Gtk # pylint: disable=E0611 |
742 | + |
743 | +from . helpers import get_builder |
744 | + |
745 | +class AboutDialog(Gtk.AboutDialog): |
746 | + __gtype_name__ = "AboutDialog" |
747 | + |
748 | + def __new__(cls): |
749 | + """Special static method that's automatically called by Python when |
750 | + constructing a new instance of this class. |
751 | + |
752 | + Returns a fully instantiated AboutDialog object. |
753 | + """ |
754 | + builder = get_builder('AboutQreatorDialog') |
755 | + new_object = builder.get_object("about_qreator_dialog") |
756 | + new_object.finish_initializing(builder) |
757 | + return new_object |
758 | + |
759 | + def finish_initializing(self, builder): |
760 | + """Called while initializing this instance in __new__ |
761 | + |
762 | + finish_initalizing should be called after parsing the ui definition |
763 | + and creating a AboutDialog object with it in order |
764 | + to finish initializing the start of the new AboutQreatorDialog |
765 | + instance. |
766 | + |
767 | + Put your initialization code in here and leave __init__ undefined. |
768 | + """ |
769 | + # Get a reference to the builder and set up the signals. |
770 | + self.builder = builder |
771 | + self.ui = builder.get_ui(self) |
772 | + |
773 | |
774 | === modified file 'qreator_lib/Builder.py' |
775 | --- qreator_lib/Builder.py 2012-05-19 14:45:57 +0000 |
776 | +++ qreator_lib/Builder.py 2012-10-28 16:08:21 +0000 |
777 | @@ -14,6 +14,8 @@ |
778 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
779 | ### END LICENSE |
780 | |
781 | +### DO NOT EDIT THIS FILE ### |
782 | + |
783 | '''Enhances builder connections, provides object to access glade objects''' |
784 | |
785 | from gi.repository import GObject, Gtk # pylint: disable=E0611 |
786 | @@ -273,14 +275,14 @@ |
787 | # Now, automatically find any the user didn't specify in glade |
788 | for sig in signal_names: |
789 | # using convention suggested by glade |
790 | - sigpy = sig.replace("-", "_") |
791 | - handler_names = ["on_%s_%s" % (widget_name, sigpy)] |
792 | + sig = sig.replace("-", "_") |
793 | + handler_names = ["on_%s_%s" % (widget_name, sig)] |
794 | |
795 | # Using the convention that the top level window is not |
796 | # specified in the handler name. That is use |
797 | # on_destroy() instead of on_windowname_destroy() |
798 | if widget is callback_obj: |
799 | - handler_names.append("on_%s" % sigpy) |
800 | + handler_names.append("on_%s" % sig) |
801 | |
802 | do_connect(item, sig, handler_names, |
803 | callback_handler_dict, builder.connections) |
804 | |
805 | === added file 'qreator_lib/PreferencesDialog.py' |
806 | --- qreator_lib/PreferencesDialog.py 1970-01-01 00:00:00 +0000 |
807 | +++ qreator_lib/PreferencesDialog.py 2012-10-28 16:08:21 +0000 |
808 | @@ -0,0 +1,64 @@ |
809 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
810 | +### BEGIN LICENSE |
811 | +# Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
812 | +# This program is free software: you can redistribute it and/or modify it |
813 | +# under the terms of the GNU General Public License version 3, as published |
814 | +# by the Free Software Foundation. |
815 | +# |
816 | +# This program is distributed in the hope that it will be useful, but |
817 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
818 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
819 | +# PURPOSE. See the GNU General Public License for more details. |
820 | +# |
821 | +# You should have received a copy of the GNU General Public License along |
822 | +# with this program. If not, see <http://www.gnu.org/licenses/>. |
823 | +### END LICENSE |
824 | + |
825 | +### DO NOT EDIT THIS FILE ### |
826 | + |
827 | +"""this dialog adjusts values in gsettings |
828 | +""" |
829 | + |
830 | +from gi.repository import Gtk # pylint: disable=E0611 |
831 | +import logging |
832 | +logger = logging.getLogger('qreator_lib') |
833 | + |
834 | +from . helpers import get_builder, show_uri, get_help_uri |
835 | + |
836 | +class PreferencesDialog(Gtk.Dialog): |
837 | + __gtype_name__ = "PreferencesDialog" |
838 | + |
839 | + def __new__(cls): |
840 | + """Special static method that's automatically called by Python when |
841 | + constructing a new instance of this class. |
842 | + |
843 | + Returns a fully instantiated PreferencesDialog object. |
844 | + """ |
845 | + builder = get_builder('PreferencesQreatorDialog') |
846 | + new_object = builder.get_object("preferences_qreator_dialog") |
847 | + new_object.finish_initializing(builder) |
848 | + return new_object |
849 | + |
850 | + def finish_initializing(self, builder): |
851 | + """Called while initializing this instance in __new__ |
852 | + |
853 | + finish_initalizing should be called after parsing the ui definition |
854 | + and creating a PreferencesDialog object with it in order to |
855 | + finish initializing the start of the new PerferencesQreatorDialog |
856 | + instance. |
857 | + |
858 | + Put your initialization code in here and leave __init__ undefined. |
859 | + """ |
860 | + |
861 | + # Get a reference to the builder and set up the signals. |
862 | + self.builder = builder |
863 | + self.ui = builder.get_ui(self, True) |
864 | + |
865 | + # code for other initialization actions should be added here |
866 | + |
867 | + def on_btn_close_clicked(self, widget, data=None): |
868 | + self.destroy() |
869 | + |
870 | + def on_btn_help_clicked(self, widget, data=None): |
871 | + show_uri(self, "ghelp:%s" % get_help_uri('preferences')) |
872 | + |
873 | |
874 | === modified file 'qreator_lib/Window.py' |
875 | --- qreator_lib/Window.py 2012-05-19 14:45:57 +0000 |
876 | +++ qreator_lib/Window.py 2012-10-28 16:08:21 +0000 |
877 | @@ -14,11 +14,13 @@ |
878 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
879 | ### END LICENSE |
880 | |
881 | -from gi.repository import Gtk # pylint: disable=E0611 |
882 | +### DO NOT EDIT THIS FILE ### |
883 | + |
884 | +from gi.repository import Gio, Gtk # pylint: disable=E0611 |
885 | import logging |
886 | logger = logging.getLogger('qreator_lib') |
887 | |
888 | -from . helpers import get_builder |
889 | +from . helpers import get_builder, show_uri, get_help_uri |
890 | |
891 | # This class is meant to be subclassed by QreatorWindow. It provides |
892 | # common functions and some boilerplate. |
893 | @@ -60,8 +62,8 @@ |
894 | self.preferences_dialog = None # instance |
895 | self.AboutDialog = None # class |
896 | |
897 | - ##self.settings = Gio.Settings("net.launchpad.qreator") |
898 | - ##self.settings.connect('changed', self.on_preferences_changed) |
899 | + self.settings = Gio.Settings("net.launchpad.qreator") |
900 | + self.settings.connect('changed', self.on_preferences_changed) |
901 | |
902 | # Optional application indicator support |
903 | # Run 'quickly add indicator' to get started. |
904 | @@ -76,6 +78,34 @@ |
905 | except ImportError: |
906 | pass |
907 | |
908 | + def on_mnu_contents_activate(self, widget, data=None): |
909 | + show_uri(self, "ghelp:%s" % get_help_uri()) |
910 | + |
911 | + def on_mnu_about_activate(self, widget, data=None): |
912 | + """Display the about box for qreator.""" |
913 | + if self.AboutDialog is not None: |
914 | + about = self.AboutDialog() # pylint: disable=E1102 |
915 | + response = about.run() |
916 | + about.destroy() |
917 | + |
918 | + def on_mnu_preferences_activate(self, widget, data=None): |
919 | + """Display the preferences window for qreator.""" |
920 | + |
921 | + """ From the PyGTK Reference manual |
922 | + Say for example the preferences dialog is currently open, |
923 | + and the user chooses Preferences from the menu a second time; |
924 | + use the present() method to move the already-open dialog |
925 | + where the user can see it.""" |
926 | + if self.preferences_dialog is not None: |
927 | + logger.debug('show existing preferences_dialog') |
928 | + self.preferences_dialog.present() |
929 | + elif self.PreferencesDialog is not None: |
930 | + logger.debug('create new preferences_dialog') |
931 | + self.preferences_dialog = self.PreferencesDialog() # pylint: disable=E1102 |
932 | + self.preferences_dialog.connect('destroy', self.on_preferences_dialog_destroyed) |
933 | + self.preferences_dialog.show() |
934 | + # destroy command moved into dialog to allow for a help button |
935 | + |
936 | def on_mnu_close_activate(self, widget, data=None): |
937 | """Signal handler for closing the QreatorWindow.""" |
938 | self.destroy() |
939 | @@ -85,3 +115,15 @@ |
940 | # Clean up code for saving application state should be added here. |
941 | Gtk.main_quit() |
942 | |
943 | + def on_preferences_changed(self, settings, key, data=None): |
944 | + logger.debug('preference changed: %s = %s' % (key, str(settings.get_value(key)))) |
945 | + |
946 | + def on_preferences_dialog_destroyed(self, widget, data=None): |
947 | + '''only affects gui |
948 | + |
949 | + logically there is no difference between the user closing, |
950 | + minimising or ignoring the preferences dialog''' |
951 | + logger.debug('on_preferences_dialog_destroyed') |
952 | + # to determine whether to create or present preferences_dialog |
953 | + self.preferences_dialog = None |
954 | + |
955 | |
956 | === modified file 'qreator_lib/__init__.py' |
957 | --- qreator_lib/__init__.py 2012-05-19 14:45:57 +0000 |
958 | +++ qreator_lib/__init__.py 2012-10-28 16:08:21 +0000 |
959 | @@ -14,6 +14,8 @@ |
960 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
961 | ### END LICENSE |
962 | |
963 | +### DO NOT EDIT THIS FILE ### |
964 | + |
965 | '''facade - makes qreator_lib package easy to refactor |
966 | |
967 | while keeping its api constant''' |
968 | |
969 | === modified file 'qreator_lib/helpers.py' |
970 | --- qreator_lib/helpers.py 2012-05-28 09:38:22 +0000 |
971 | +++ qreator_lib/helpers.py 2012-10-28 16:08:21 +0000 |
972 | @@ -14,6 +14,8 @@ |
973 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
974 | ### END LICENSE |
975 | |
976 | +### DO NOT EDIT THIS FILE ### |
977 | + |
978 | """Helpers for an Ubuntu application.""" |
979 | import logging |
980 | import os |
981 | @@ -21,11 +23,12 @@ |
982 | from . qreatorconfig import get_data_file |
983 | from . Builder import Builder |
984 | |
985 | +from locale import gettext as _ |
986 | |
987 | def get_builder(builder_file_name): |
988 | """Return a fully-instantiated Gtk.Builder instance from specified ui |
989 | file |
990 | - |
991 | + |
992 | :param builder_file_name: The name of the builder file, without extension. |
993 | Assumed to be in the 'ui' directory under the data path. |
994 | """ |
995 | @@ -46,22 +49,19 @@ |
996 | if not os.path.exists(media_filename): |
997 | media_filename = None |
998 | |
999 | - return media_filename |
1000 | - |
1001 | + return "file:///"+media_filename |
1002 | |
1003 | class NullHandler(logging.Handler): |
1004 | def emit(self, record): |
1005 | pass |
1006 | |
1007 | - |
1008 | def set_up_logging(opts): |
1009 | # add a handler to prevent basicConfig |
1010 | root = logging.getLogger() |
1011 | null_handler = NullHandler() |
1012 | root.addHandler(null_handler) |
1013 | |
1014 | - formatter = logging.Formatter( |
1015 | - "%(levelname)s:%(name)s: %(funcName)s() '%(message)s'") |
1016 | + formatter = logging.Formatter("%(levelname)s:%(name)s: %(funcName)s() '%(message)s'") |
1017 | |
1018 | logger = logging.getLogger('qreator') |
1019 | logger_sh = logging.StreamHandler() |
1020 | @@ -80,7 +80,6 @@ |
1021 | if opts.verbose > 1: |
1022 | lib_logger.setLevel(logging.DEBUG) |
1023 | |
1024 | - |
1025 | def get_help_uri(page=None): |
1026 | # help_uri from source tree - default language |
1027 | here = os.path.dirname(__file__) |
1028 | @@ -96,13 +95,11 @@ |
1029 | |
1030 | return help_uri |
1031 | |
1032 | - |
1033 | def show_uri(parent, link): |
1034 | - from gi.repository import Gtk # pylint: disable=E0611 |
1035 | + from gi.repository import Gtk # pylint: disable=E0611 |
1036 | screen = parent.get_screen() |
1037 | Gtk.show_uri(screen, link, Gtk.get_current_event_time()) |
1038 | |
1039 | - |
1040 | def alias(alternative_function_name): |
1041 | '''see http://www.drdobbs.com/web-development/184406073#l9''' |
1042 | def decorator(function): |
1043 | |
1044 | === modified file 'qreator_lib/qreatorconfig.py' |
1045 | --- qreator_lib/qreatorconfig.py 2012-05-28 09:38:22 +0000 |
1046 | +++ qreator_lib/qreatorconfig.py 2012-10-28 16:08:21 +0000 |
1047 | @@ -14,10 +14,7 @@ |
1048 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
1049 | ### END LICENSE |
1050 | |
1051 | -# THIS IS Qreator CONFIGURATION FILE |
1052 | -# YOU CAN PUT THERE SOME GLOBAL VALUE |
1053 | -# Do not touch unless you know what you're doing. |
1054 | -# you're warned :) |
1055 | +### DO NOT EDIT THIS FILE ### |
1056 | |
1057 | __all__ = [ |
1058 | 'project_path_not_found', |
1059 | @@ -33,6 +30,7 @@ |
1060 | |
1061 | import os |
1062 | |
1063 | +from locale import gettext as _ |
1064 | |
1065 | class project_path_not_found(Exception): |
1066 | """Raised when we can't find the project directory.""" |
1067 | |
1068 | === modified file 'setup.py' |
1069 | --- setup.py 2012-05-28 11:15:51 +0000 |
1070 | +++ setup.py 2012-10-28 16:08:21 +0000 |
1071 | @@ -15,7 +15,7 @@ |
1072 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
1073 | ### END LICENSE |
1074 | |
1075 | -###################### DO NOT TOUCH THIS (HEAD TO THE SECOND PART) ########### |
1076 | +###################### DO NOT TOUCH THIS (HEAD TO THE SECOND PART) ###################### |
1077 | |
1078 | import os |
1079 | import sys |
1080 | @@ -27,16 +27,16 @@ |
1081 | sys.exit(1) |
1082 | assert DistUtilsExtra.auto.__version__ >= '2.18', 'needs DistUtilsExtra.auto >= 2.18' |
1083 | |
1084 | - |
1085 | -def update_config(values = {}): |
1086 | - |
1087 | +def update_config(libdir, values = {}): |
1088 | + |
1089 | + filename = os.path.join(libdir, 'qreator_lib/qreatorconfig.py') |
1090 | oldvalues = {} |
1091 | try: |
1092 | - fin = file('qreator_lib/qreatorconfig.py', 'r') |
1093 | - fout = file(fin.name + '.new', 'w') |
1094 | + fin = file(filename, 'r') |
1095 | + fout = file(filename + '.new', 'w') |
1096 | |
1097 | for line in fin: |
1098 | - fields = line.split(' = ') # Separate variable from value |
1099 | + fields = line.split(' = ') # Separate variable from value |
1100 | if fields[0] in values: |
1101 | oldvalues[fields[0]] = fields[1].strip() |
1102 | line = "%s = %s\n" % (fields[0], values[fields[0]]) |
1103 | @@ -47,42 +47,92 @@ |
1104 | fin.close() |
1105 | os.rename(fout.name, fin.name) |
1106 | except (OSError, IOError), e: |
1107 | - print ("ERROR: Can't find qreator_lib/qreatorconfig.py") |
1108 | + print ("ERROR: Can't find %s" % filename) |
1109 | sys.exit(1) |
1110 | return oldvalues |
1111 | |
1112 | |
1113 | -def update_desktop_file(datadir): |
1114 | +def move_desktop_file(root, target_data, prefix): |
1115 | + # The desktop file is rightly installed into install_data. But it should |
1116 | + # always really be installed into prefix, because while we can install |
1117 | + # normal data files anywhere we want, the desktop file needs to exist in |
1118 | + # the main system to be found. Only actually useful for /opt installs. |
1119 | + |
1120 | + old_desktop_path = os.path.normpath(root + target_data + |
1121 | + '/share/applications') |
1122 | + old_desktop_file = old_desktop_path + '/qreator.desktop' |
1123 | + desktop_path = os.path.normpath(root + prefix + '/share/applications') |
1124 | + desktop_file = desktop_path + '/qreator.desktop' |
1125 | + |
1126 | + if not os.path.exists(old_desktop_file): |
1127 | + print ("ERROR: Can't find", old_desktop_file) |
1128 | + sys.exit(1) |
1129 | + elif target_data != prefix + '/': |
1130 | + # This is an /opt install, so rename desktop file to use extras- |
1131 | + desktop_file = desktop_path + '/extras-qreator.desktop' |
1132 | + try: |
1133 | + os.makedirs(desktop_path) |
1134 | + os.rename(old_desktop_file, desktop_file) |
1135 | + os.rmdir(old_desktop_path) |
1136 | + except OSError as e: |
1137 | + print ("ERROR: Can't rename", old_desktop_file, ":", e) |
1138 | + sys.exit(1) |
1139 | + |
1140 | + return desktop_file |
1141 | + |
1142 | +def update_desktop_file(filename, target_pkgdata, target_scripts): |
1143 | |
1144 | try: |
1145 | - fin = file('qreator.desktop.in', 'r') |
1146 | - fout = file(fin.name + '.new', 'w') |
1147 | + fin = file(filename, 'r') |
1148 | + fout = file(filename + '.new', 'w') |
1149 | |
1150 | for line in fin: |
1151 | if 'Icon=' in line: |
1152 | - line = "Icon=%s\n" % (datadir + 'media/qreator.svg') |
1153 | + line = "Icon=%s\n" % (target_pkgdata + 'media/qreator.svg') |
1154 | + elif 'Exec=' in line: |
1155 | + cmd = line.split("=")[1].split(None, 1) |
1156 | + line = "Exec=%s" % (target_scripts + 'qreator') |
1157 | + if len(cmd) > 1: |
1158 | + line += " %s" % cmd[1].strip() # Add script arguments back |
1159 | + line += "\n" |
1160 | fout.write(line) |
1161 | fout.flush() |
1162 | fout.close() |
1163 | fin.close() |
1164 | os.rename(fout.name, fin.name) |
1165 | except (OSError, IOError), e: |
1166 | - print ("ERROR: Can't find qreator.desktop.in") |
1167 | + print ("ERROR: Can't find %s" % filename) |
1168 | sys.exit(1) |
1169 | |
1170 | +def compile_schemas(root, target_data): |
1171 | + if target_data == '/usr/': |
1172 | + return # /usr paths don't need this, they will be handled by dpkg |
1173 | + schemadir = os.path.normpath(root + target_data + 'share/glib-2.0/schemas') |
1174 | + if (os.path.isdir(schemadir) and |
1175 | + os.path.isfile('/usr/bin/glib-compile-schemas')): |
1176 | + os.system('/usr/bin/glib-compile-schemas "%s"' % schemadir) |
1177 | + |
1178 | |
1179 | class InstallAndUpdateDataDirectory(DistUtilsExtra.auto.install_auto): |
1180 | def run(self): |
1181 | - values = {'__qreator_data_directory__': "'%s'" % (self.prefix + '/share/qreator/'), |
1182 | + DistUtilsExtra.auto.install_auto.run(self) |
1183 | + |
1184 | + target_data = '/' + os.path.relpath(self.install_data, self.root) + '/' |
1185 | + target_pkgdata = target_data + 'share/qreator/' |
1186 | + target_scripts = '/' + os.path.relpath(self.install_scripts, self.root) + '/' |
1187 | + |
1188 | + values = {'__qreator_data_directory__': "'%s'" % (target_pkgdata), |
1189 | '__version__': "'%s'" % self.distribution.get_version()} |
1190 | - previous_values = update_config(values) |
1191 | - update_desktop_file(self.prefix + '/share/qreator/') |
1192 | - DistUtilsExtra.auto.install_auto.run(self) |
1193 | - update_config(previous_values) |
1194 | - |
1195 | -############################################################################## |
1196 | -###################### YOU SHOULD MODIFY ONLY WHAT IS BELOW ################## |
1197 | -############################################################################## |
1198 | + update_config(self.install_lib, values) |
1199 | + |
1200 | + desktop_file = move_desktop_file(self.root, target_data, self.prefix) |
1201 | + update_desktop_file(desktop_file, target_pkgdata, target_scripts) |
1202 | + compile_schemas(self.root, target_data) |
1203 | + |
1204 | + |
1205 | +######################################################################################### |
1206 | +###################### YOU SHOULD MODIFY ONLY WHAT IS BELOW ############################# |
1207 | +######################################################################################### |
1208 | |
1209 | DistUtilsExtra.auto.setup( |
1210 | name='qreator', |
I love the feature, good work (as usual)! :-)
I like the fact that you've reduced the layout to the minimal number of elements, and I'd like to try to see if we can squeeze even more out of simplicity and usability. Here's my suggestion:
http:// ubuntuone. com/5yaGY5klw7B qbPCnyV5LPy
In summary:
- Keeping all widgets in a single row
- Collapsing the original URL and the shortened URL into a single entry
- Hiding away the shortener service selector (*)
There is also the question whether we update the QR code with the shortened URL, which I think might make sense for those shorteners (e.g. bit.ly) that keep track of click stats through analytics. I think we should probably update it, but I don't feel strongly about it, either.
What do you think?
(*) I've been reluctant to add a preferences page up until now, as I'm a firm believer of "sane defaults for everyone" and "preferences are maintenance burden", but I think in this case we might want to add a preferences page to select the shortener service. Mainly because of 2 reasons: a) most users won't change shorteners that often, so I believe we should not show it directly to them and b) to work well with shorteners with analytics, we might want to have a text box preference to add their API keys. If we are going to add a preferences page, I'd like to keep it inside the main window as the about page (instead of a pop-up dialog), to keep the self-contained, mobile, feel of the app (even though we're far from becoming a mobile app).
Now if having a preferences page is going to be a non-trivial amount of work, we might just want to pick one shortener service and go with that for the first cut. On a next release we can then feature the preferences page.