Merge lp:~stefan-schwarzburg/qreator/qreator_url_shortener into lp:~dpm/qreator/trunk

Proposed by Schwarzburg
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
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.

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 :-)

To post a comment you must log in.
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

Revision history for this message
David Planella (dpm) wrote :

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/5yaGY5klw7BqbPCnyV5LPy

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.

review: Needs Information
Revision history for this message
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-hackers/qreator/trunk and press Resubmit?

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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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',

Subscribers

People subscribed via source and target branches

to all changes: