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
=== modified file '.quickly'
--- .quickly 2012-05-28 11:05:50 +0000
+++ .quickly 2012-10-28 16:08:21 +0000
@@ -1,5 +1,5 @@
1project = qreator1project = qreator
2version = 12.042version = 12.08.1
3template = ubuntu-application3template = ubuntu-application
4lp_id = qreator4lp_id = qreator
5dependencies = software-center5dependencies = software-center
66
=== modified file 'bin/qreator'
--- bin/qreator 2012-05-28 09:38:22 +0000
+++ bin/qreator 2012-10-28 16:08:21 +0000
@@ -15,9 +15,13 @@
15# with this program. If not, see <http://www.gnu.org/licenses/>.15# with this program. If not, see <http://www.gnu.org/licenses/>.
16### END LICENSE16### END LICENSE
1717
18### DO NOT EDIT THIS FILE ###
19
18import sys20import sys
19import os21import os
2022
23import locale
24locale.textdomain('qreator')
2125
22# Add project root directory (enable symlink and trunk execution)26# Add project root directory (enable symlink and trunk execution)
23PROJECT_ROOT_DIRECTORY = os.path.abspath(27PROJECT_ROOT_DIRECTORY = os.path.abspath(
@@ -25,18 +29,19 @@
2529
26python_path = []30python_path = []
27if os.path.abspath(__file__).startswith('/opt'):31if os.path.abspath(__file__).startswith('/opt'):
28 syspath = sys.path[:] # copy to avoid infinite loop in pending objects32 locale.bindtextdomain('qreator', '/opt/extras.ubuntu.com/qreator/share/locale')
33 syspath = sys.path[:] # copy to avoid infinite loop in pending objects
29 for path in syspath:34 for path in syspath:
30 opt_path = path.replace('/usr', '/opt/extras.ubuntu.com/qreator')35 opt_path = path.replace('/usr', '/opt/extras.ubuntu.com/qreator')
31 python_path.insert(0, opt_path)36 python_path.insert(0, opt_path)
32 sys.path.insert(0, opt_path)37 sys.path.insert(0, opt_path)
38 os.putenv("XDG_DATA_DIRS", "%s:%s" % ("/opt/extras.ubuntu.com/qreator/share/", os.getenv("XDG_DATA_DIRS", "/usr/local/share/:/usr/share/")))
33if (os.path.exists(os.path.join(PROJECT_ROOT_DIRECTORY, 'qreator'))39if (os.path.exists(os.path.join(PROJECT_ROOT_DIRECTORY, 'qreator'))
34 and PROJECT_ROOT_DIRECTORY not in sys.path):40 and PROJECT_ROOT_DIRECTORY not in sys.path):
35 python_path.insert(0, PROJECT_ROOT_DIRECTORY)41 python_path.insert(0, PROJECT_ROOT_DIRECTORY)
36 sys.path.insert(0, PROJECT_ROOT_DIRECTORY)42 sys.path.insert(0, PROJECT_ROOT_DIRECTORY)
37if python_path:43if python_path:
38 os.putenv('PYTHONPATH', "%s:%s" % (os.getenv('PYTHONPATH', ''),44 os.putenv('PYTHONPATH', "%s:%s" % (os.getenv('PYTHONPATH', ''), ':'.join(python_path))) # for subprocesses
39 ':'.join(python_path))) # for subprocesses
4045
41import qreator46import qreator
42qreator.main()47qreator.main()
4348
=== modified file 'data/ui/QrCodeURL.ui'
--- data/ui/QrCodeURL.ui 2012-05-30 08:33:06 +0000
+++ data/ui/QrCodeURL.ui 2012-10-28 16:08:21 +0000
@@ -8,10 +8,15 @@
8 <object class="GtkEntry" id="entryURL">8 <object class="GtkEntry" id="entryURL">
9 <property name="visible">True</property>9 <property name="visible">True</property>
10 <property name="can_focus">True</property>10 <property name="can_focus">True</property>
11 <property name="margin_top">3</property>
12 <property name="margin_bottom">3</property>
13 <property name="hexpand">True</property>
14 <property name="placeholder_text">[URL]</property>
15 <property name="visible">True</property>
16 <property name="can_focus">True</property>
11 <property name="hexpand">True</property>17 <property name="hexpand">True</property>
12 <property name="invisible_char">•</property>18 <property name="invisible_char">•</property>
13 <property name="invisible_char_set">True</property>19 <property name="invisible_char_set">True</property>
14 <property name="placeholder_text">[URL]</property>
15 <signal name="changed" handler="on_entryURL_changed" swapped="no"/>20 <signal name="changed" handler="on_entryURL_changed" swapped="no"/>
16 <signal name="icon-press" handler="on_entryURL_icon_press" swapped="no"/>21 <signal name="icon-press" handler="on_entryURL_icon_press" swapped="no"/>
17 </object>22 </object>
@@ -43,5 +48,91 @@
43 <property name="height">1</property>48 <property name="height">1</property>
44 </packing>49 </packing>
45 </child>50 </child>
51 <child>
52 <object class="GtkToggleButton" id="togglebuttonURLShortener">
53 <property name="label" translatable="yes">Shorten URL</property>
54 <property name="use_action_appearance">False</property>
55 <property name="visible">True</property>
56 <property name="can_focus">True</property>
57 <property name="receives_default">True</property>
58 <property name="use_action_appearance">False</property>
59 <signal name="toggled" handler="on_togglebuttonURLShortener_toggled" swapped="no"/>
60 </object>
61 <packing>
62 <property name="left_attach">0</property>
63 <property name="top_attach">1</property>
64 <property name="width">1</property>
65 <property name="height">1</property>
66 </packing>
67 </child>
68 <child>
69 <object class="GtkBox" id="box1">
70 <property name="visible">True</property>
71 <property name="can_focus">False</property>
72 <child>
73 <object class="GtkLabel" id="label1">
74 <property name="visible">True</property>
75 <property name="can_focus">False</property>
76 <property name="xpad">5</property>
77 <property name="label" translatable="yes">with</property>
78 </object>
79 <packing>
80 <property name="expand">False</property>
81 <property name="fill">True</property>
82 <property name="position">0</property>
83 </packing>
84 </child>
85 <child>
86 <object class="GtkComboBoxText" id="comboboxtextURLShortener">
87 <property name="visible">True</property>
88 <property name="can_focus">False</property>
89 <property name="entry_text_column">0</property>
90 <property name="id_column">1</property>
91 </object>
92 <packing>
93 <property name="expand">False</property>
94 <property name="fill">True</property>
95 <property name="position">1</property>
96 </packing>
97 </child>
98 <child>
99 <object class="GtkLinkButton" id="linkbuttonUrlShortener">
100 <property name="label" translatable="yes">[shortened URL]</property>
101 <property name="use_action_appearance">False</property>
102 <property name="sensitive">False</property>
103 <property name="can_focus">True</property>
104 <property name="receives_default">True</property>
105 <property name="has_tooltip">True</property>
106 <property name="margin_right">6</property>
107 <property name="hexpand">True</property>
108 <property name="use_action_appearance">False</property>
109 <property name="relief">none</property>
110 </object>
111 <packing>
112 <property name="expand">False</property>
113 <property name="fill">False</property>
114 <property name="position">2</property>
115 </packing>
116 </child>
117 <child>
118 <object class="GtkLabel" id="messagelabelUrlShortener">
119 <property name="can_focus">False</property>
120 <property name="label" translatable="yes">label</property>
121 <property name="justify">center</property>
122 </object>
123 <packing>
124 <property name="expand">False</property>
125 <property name="fill">True</property>
126 <property name="position">3</property>
127 </packing>
128 </child>
129 </object>
130 <packing>
131 <property name="left_attach">1</property>
132 <property name="top_attach">1</property>
133 <property name="width">1</property>
134 <property name="height">1</property>
135 </packing>
136 </child>
46 </object>137 </object>
47</interface>138</interface>
48139
=== modified file 'qreator/QreatorWindow.py'
--- qreator/QreatorWindow.py 2012-06-24 07:59:42 +0000
+++ qreator/QreatorWindow.py 2012-10-28 16:08:21 +0000
@@ -25,7 +25,7 @@
2525
26from qreator_lib.i18n import _26from qreator_lib.i18n import _
27from qreator_lib import Window27from qreator_lib import Window
28from qreator_lib.helpers import get_media_file28from qreator.tools import get_media_path
2929
30from QRCode import QRCode30from QRCode import QRCode
31from QRCode import QRCodeOutput31from QRCode import QRCodeOutput
@@ -71,7 +71,7 @@
7171
72 # Load the background texture in the QR code page72 # Load the background texture in the QR code page
73 self.texture = cairo.ImageSurface.create_from_png(73 self.texture = cairo.ImageSurface.create_from_png(
74 get_media_file("pattern.png"))74 get_media_path("pattern.png"))
7575
76 # Time to wait in milliseconds before switching to the next view76 # Time to wait in milliseconds before switching to the next view
77 # after having clicked once on an iconview icon77 # after having clicked once on an iconview icon
@@ -161,8 +161,7 @@
161 self.qr_types_store.clear()161 self.qr_types_store.clear()
162162
163 for qr_type in self.qr_types:163 for qr_type in self.qr_types:
164 icon = GdkPixbuf.Pixbuf.new_from_file(get_media_file(164 icon = GdkPixbuf.Pixbuf.new_from_file(qr_type.icon_path)
165 qr_type.icon_path))
166 self.qr_types_store.append([qr_type.description,165 self.qr_types_store.append([qr_type.description,
167 icon,166 icon,
168 qr_type.id])167 qr_type.id])
169168
=== modified file 'qreator/__init__.py'
--- qreator/__init__.py 2012-06-23 08:42:52 +0000
+++ qreator/__init__.py 2012-10-28 16:08:21 +0000
@@ -1,16 +1,16 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2### BEGIN LICENSE2### BEGIN LICENSE
3# Copyright (C) 2012 David Planella <david.planella@ubuntu.com>3# Copyright (C) 2012 David Planella <david.planella@ubuntu.com>
4# This program is free software: you can redistribute it and/or modify it4# This program is free software: you can redistribute it and/or modify it
5# under the terms of the GNU General Public License version 3, as published5# under the terms of the GNU General Public License version 3, as published
6# by the Free Software Foundation.6# by the Free Software Foundation.
7#7#
8# This program is distributed in the hope that it will be useful, but8# This program is distributed in the hope that it will be useful, but
9# WITHOUT ANY WARRANTY; without even the implied warranties of9# WITHOUT ANY WARRANTY; without even the implied warranties of
10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11# PURPOSE. See the GNU General Public License for more details.11# PURPOSE. See the GNU General Public License for more details.
12#12#
13# You should have received a copy of the GNU General Public License along13# You should have received a copy of the GNU General Public License along
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
1717
=== modified file 'qreator/qrcodes/GtkHelpers.py'
--- qreator/qrcodes/GtkHelpers.py 2012-05-30 10:19:57 +0000
+++ qreator/qrcodes/GtkHelpers.py 2012-10-28 16:08:21 +0000
@@ -1,16 +1,16 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2### BEGIN LICENSE2### BEGIN LICENSE
3# Copyright (C) 2012 David Planella <david.planella@ubuntu.com>3# Copyright (C) 2012 David Planella <david.planella@ubuntu.com>
4# This program is free software: you can redistribute it and/or modify it4# This program is free software: you can redistribute it and/or modify it
5# under the terms of the GNU General Public License version 3, as published5# under the terms of the GNU General Public License version 3, as published
6# by the Free Software Foundation.6# by the Free Software Foundation.
7#7#
8# This program is distributed in the hope that it will be useful, but8# This program is distributed in the hope that it will be useful, but
9# WITHOUT ANY WARRANTY; without even the implied warranties of9# WITHOUT ANY WARRANTY; without even the implied warranties of
10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11# PURPOSE. See the GNU General Public License for more details.11# PURPOSE. See the GNU General Public License for more details.
12#12#
13# You should have received a copy of the GNU General Public License along13# You should have received a copy of the GNU General Public License along
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
1717
=== modified file 'qreator/qrcodes/QRCodeLocation.py'
--- qreator/qrcodes/QRCodeLocation.py 2012-05-30 08:33:06 +0000
+++ qreator/qrcodes/QRCodeLocation.py 2012-10-28 16:08:21 +0000
@@ -14,14 +14,14 @@
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
17from qreator_lib.helpers import get_media_file17from qreator.tools import get_media_path
18#from qreator_lib import QRCodeType as QRCodeType18#from qreator_lib import QRCodeType as QRCodeType
19from QRCodeLocationGtk import QRCodeLocationGtk19from QRCodeLocationGtk import QRCodeLocationGtk
2020
21class QRCodeLocation(object):21class QRCodeLocation(object):
22 def __init__(self, qr_code_update_func, icon_path, description, id):22 def __init__(self, qr_code_update_func, icon_path, description, id):
23 self.qr_code_update_func = qr_code_update_func23 self.qr_code_update_func = qr_code_update_func
24 self.icon_path = get_media_file(icon_path)24 self.icon_path = get_media_path(icon_path)
25 self.description = description25 self.description = description
26 self.id = id26 self.id = id
2727
2828
=== modified file 'qreator/qrcodes/QRCodeLocationGtk.py'
--- qreator/qrcodes/QRCodeLocationGtk.py 2012-06-23 16:49:09 +0000
+++ qreator/qrcodes/QRCodeLocationGtk.py 2012-10-28 16:08:21 +0000
@@ -1,16 +1,16 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2### BEGIN LICENSE2### BEGIN LICENSE
3# Copyright (C) 2012 David Planella <david.planella@ubuntu.com>3# Copyright (C) 2012 David Planella <david.planella@ubuntu.com>
4# This program is free software: you can redistribute it and/or modify it4# This program is free software: you can redistribute it and/or modify it
5# under the terms of the GNU General Public License version 3, as published5# under the terms of the GNU General Public License version 3, as published
6# by the Free Software Foundation.6# by the Free Software Foundation.
7#7#
8# This program is distributed in the hope that it will be useful, but8# This program is distributed in the hope that it will be useful, but
9# WITHOUT ANY WARRANTY; without even the implied warranties of9# WITHOUT ANY WARRANTY; without even the implied warranties of
10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11# PURPOSE. See the GNU General Public License for more details.11# PURPOSE. See the GNU General Public License for more details.
12#12#
13# You should have received a copy of the GNU General Public License along13# You should have received a copy of the GNU General Public License along
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
1717
=== modified file 'qreator/qrcodes/QRCodeSoftwareCenterApp.py'
--- qreator/qrcodes/QRCodeSoftwareCenterApp.py 2012-05-30 08:33:06 +0000
+++ qreator/qrcodes/QRCodeSoftwareCenterApp.py 2012-10-28 16:08:21 +0000
@@ -14,7 +14,7 @@
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
17from qreator_lib.helpers import get_media_file17from qreator.tools import get_media_path
18#from qreator_lib import QRCodeType as QRCodeType18#from qreator_lib import QRCodeType as QRCodeType
19from QRCodeSoftwareCenterAppGtk import QRCodeSoftwareCenterAppGtk19from QRCodeSoftwareCenterAppGtk import QRCodeSoftwareCenterAppGtk
2020
@@ -22,7 +22,7 @@
22class QRCodeSoftwareCenterApp(object):22class QRCodeSoftwareCenterApp(object):
23 def __init__(self, qr_code_update_func, icon_path, description, id):23 def __init__(self, qr_code_update_func, icon_path, description, id):
24 self.qr_code_update_func = qr_code_update_func24 self.qr_code_update_func = qr_code_update_func
25 self.icon_path = get_media_file(icon_path)25 self.icon_path = get_media_path(icon_path)
26 self.description = description26 self.description = description
27 self.id = id27 self.id = id
2828
2929
=== modified file 'qreator/qrcodes/QRCodeSoftwareCenterAppGtk.py'
--- qreator/qrcodes/QRCodeSoftwareCenterAppGtk.py 2012-05-30 10:19:57 +0000
+++ qreator/qrcodes/QRCodeSoftwareCenterAppGtk.py 2012-10-28 16:08:21 +0000
@@ -1,16 +1,16 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2### BEGIN LICENSE2### BEGIN LICENSE
3# Copyright (C) 2012 David Planella <david.planella@ubuntu.com>3# Copyright (C) 2012 David Planella <david.planella@ubuntu.com>
4# This program is free software: you can redistribute it and/or modify it4# This program is free software: you can redistribute it and/or modify it
5# under the terms of the GNU General Public License version 3, as published5# under the terms of the GNU General Public License version 3, as published
6# by the Free Software Foundation.6# by the Free Software Foundation.
7#7#
8# This program is distributed in the hope that it will be useful, but8# This program is distributed in the hope that it will be useful, but
9# WITHOUT ANY WARRANTY; without even the implied warranties of9# WITHOUT ANY WARRANTY; without even the implied warranties of
10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11# PURPOSE. See the GNU General Public License for more details.11# PURPOSE. See the GNU General Public License for more details.
12#12#
13# You should have received a copy of the GNU General Public License along13# You should have received a copy of the GNU General Public License along
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
1717
=== modified file 'qreator/qrcodes/QRCodeText.py'
--- qreator/qrcodes/QRCodeText.py 2012-05-30 08:33:06 +0000
+++ qreator/qrcodes/QRCodeText.py 2012-10-28 16:08:21 +0000
@@ -14,14 +14,14 @@
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
17from qreator_lib.helpers import get_media_file17from qreator.tools import get_media_path
18#from qreator_lib import QRCodeType as QRCodeType18#from qreator_lib import QRCodeType as QRCodeType
19from QRCodeTextGtk import QRCodeTextGtk19from QRCodeTextGtk import QRCodeTextGtk
2020
21class QRCodeText(object):21class QRCodeText(object):
22 def __init__(self, qr_code_update_func, icon_path, description, id):22 def __init__(self, qr_code_update_func, icon_path, description, id):
23 self.qr_code_update_func = qr_code_update_func23 self.qr_code_update_func = qr_code_update_func
24 self.icon_path = get_media_file(icon_path)24 self.icon_path = get_media_path(icon_path)
25 self.description = description25 self.description = description
26 self.id = id26 self.id = id
2727
2828
=== modified file 'qreator/qrcodes/QRCodeTextGtk.py'
--- qreator/qrcodes/QRCodeTextGtk.py 2012-05-30 08:33:06 +0000
+++ qreator/qrcodes/QRCodeTextGtk.py 2012-10-28 16:08:21 +0000
@@ -1,16 +1,16 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2### BEGIN LICENSE2### BEGIN LICENSE
3# Copyright (C) 2012 David Planella <david.planella@ubuntu.com>3# Copyright (C) 2012 David Planella <david.planella@ubuntu.com>
4# This program is free software: you can redistribute it and/or modify it4# This program is free software: you can redistribute it and/or modify it
5# under the terms of the GNU General Public License version 3, as published5# under the terms of the GNU General Public License version 3, as published
6# by the Free Software Foundation.6# by the Free Software Foundation.
7#7#
8# This program is distributed in the hope that it will be useful, but8# This program is distributed in the hope that it will be useful, but
9# WITHOUT ANY WARRANTY; without even the implied warranties of9# WITHOUT ANY WARRANTY; without even the implied warranties of
10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11# PURPOSE. See the GNU General Public License for more details.11# PURPOSE. See the GNU General Public License for more details.
12#12#
13# You should have received a copy of the GNU General Public License along13# You should have received a copy of the GNU General Public License along
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
1717
=== modified file 'qreator/qrcodes/QRCodeType.py'
--- qreator/qrcodes/QRCodeType.py 2012-05-30 08:33:06 +0000
+++ qreator/qrcodes/QRCodeType.py 2012-10-28 16:08:21 +0000
@@ -19,7 +19,7 @@
19 id):19 id):
20 self.parent_widget = parent_widget20 self.parent_widget = parent_widget
21 self.drawing_area = drawing_area21 self.drawing_area = drawing_area
22 self.icon_path = get_media_file(icon_path)22 self.icon_path = get_media_path(icon_path)
23 self.description = description23 self.description = description
24 self.id = id24 self.id = id
2525
2626
=== modified file 'qreator/qrcodes/QRCodeURL.py'
--- qreator/qrcodes/QRCodeURL.py 2012-05-30 08:33:06 +0000
+++ qreator/qrcodes/QRCodeURL.py 2012-10-28 16:08:21 +0000
@@ -14,14 +14,14 @@
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
17from qreator_lib.helpers import get_media_file17from qreator.tools import get_media_path
18#from qreator_lib import QRCodeType as QRCodeType18#from qreator_lib import QRCodeType as QRCodeType
19from QRCodeURLGtk import QRCodeURLGtk19from QRCodeURLGtk import QRCodeURLGtk
2020
21class QRCodeURL(object):21class QRCodeURL(object):
22 def __init__(self, qr_code_update_func, icon_path, description, id):22 def __init__(self, qr_code_update_func, icon_path, description, id):
23 self.qr_code_update_func = qr_code_update_func23 self.qr_code_update_func = qr_code_update_func
24 self.icon_path = get_media_file(icon_path)24 self.icon_path = get_media_path(icon_path)
25 self.description = description25 self.description = description
26 self.id = id26 self.id = id
2727
2828
=== modified file 'qreator/qrcodes/QRCodeURLGtk.py'
--- qreator/qrcodes/QRCodeURLGtk.py 2012-08-02 13:15:02 +0000
+++ qreator/qrcodes/QRCodeURLGtk.py 2012-10-28 16:08:21 +0000
@@ -1,16 +1,16 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2### BEGIN LICENSE2### BEGIN LICENSE
3# Copyright (C) 2012 David Planella <david.planella@ubuntu.com>3# Copyright (C) 2012 David Planella <david.planella@ubuntu.com>
4# This program is free software: you can redistribute it and/or modify it4# This program is free software: you can redistribute it and/or modify it
5# under the terms of the GNU General Public License version 3, as published5# under the terms of the GNU General Public License version 3, as published
6# by the Free Software Foundation.6# by the Free Software Foundation.
7#7#
8# This program is distributed in the hope that it will be useful, but8# This program is distributed in the hope that it will be useful, but
9# WITHOUT ANY WARRANTY; without even the implied warranties of9# WITHOUT ANY WARRANTY; without even the implied warranties of
10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11# PURPOSE. See the GNU General Public License for more details.11# PURPOSE. See the GNU General Public License for more details.
12#12#
13# You should have received a copy of the GNU General Public License along13# You should have received a copy of the GNU General Public License along
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
@@ -18,6 +18,53 @@
18from GtkHelpers import clear_text_entry, show_clear_icon18from GtkHelpers import clear_text_entry, show_clear_icon
19from qreator_lib.helpers import get_data_file19from qreator_lib.helpers import get_data_file
20from qreator_lib.i18n import _20from qreator_lib.i18n import _
21import requests
22import json
23from urllib import urlencode
24
25
26class TinyUrlShortener(object):
27 def __init__(self, url=None):
28 self.api_url = "http://tinyurl.com/api-create.php"
29 self.url = url
30
31 def short_url(self):
32 self.r = requests.get("{0}?url={1}".format(self.api_url, self.url))
33 return self.r.content
34
35class BitlyShortener(object):
36 def __init__(self, url=None):
37 self.api_url = 'http://api.bit.ly/v3/shorten'
38 self.url = url
39 self.data = {"login": "xubuntix",
40 "apiKey": "R_9b35d5ecdee200a89e3ca16b312bf4a1",
41 "longUrl": self.url}
42
43 def short_url(self):
44 self.r = requests.get(self.api_url, params=self.data)
45 self.results = json.loads(self.r.content)
46 return self.results["data"]["url"]
47
48
49class GoogleShortener(object):
50 def __init__(self, url=None):
51 self.api_key = "AIzaSyCU_pFNpACW4luWEZRgNnfWMEUdlnZyYQI"
52 self.api_url = 'https://www.googleapis.com/urlshortener/v1/url'
53 self.url = url
54 self.params = {"key": self.api_key,
55 'Content-Type' : 'application/json'}
56 self.data = {"longUrl": self.url}
57
58 def short_url(self):
59 self.r = requests.post(self.api_url, headers=self.params, data=json.dumps(self.data))
60 self.results = json.loads(self.r.content)
61 return self.results["id"]
62
63
64SHORTENER_TYPES = [(_("Google"), GoogleShortener),
65 (_("Bitly"), BitlyShortener),
66 (_("TinyUrl"), TinyUrlShortener),
67 ]
2168
2269
23class QRCodeURLGtk(object):70class QRCodeURLGtk(object):
@@ -38,9 +85,52 @@
38 self.entry.set_placeholder_text(_('[URL]'))85 self.entry.set_placeholder_text(_('[URL]'))
39 self.combobox.set_active(0)86 self.combobox.set_active(0)
4087
88 # Currently three shortener options are available: google tinyurl bitly
89 # The selected service is stored in self.Shortener
90 self.shorten_options = self.builder.get_object('comboboxtextURLShortener')
91 for s in SHORTENER_TYPES:
92 self.shorten_options.append_text(s[0])
93 self.shorten_options.set_active(0)
94 self.shorten_options.connect("changed", self.on_shortener_changed)
95 self.Shortener = SHORTENER_TYPES[self.shorten_options.get_active()][1]
96
41 self.entry.connect("changed", self.on_entryURL_changed)97 self.entry.connect("changed", self.on_entryURL_changed)
42 self.combobox.connect("changed", self.on_comboboxtextProtocol_changed)98 self.combobox.connect("changed", self.on_comboboxtextProtocol_changed)
4399
100 def on_shortener_changed(self, widget):
101 self.Shortener = SHORTENER_TYPES[widget.get_active()][1]
102 self.on_togglebuttonURLShortener_toggled(
103 self.builder.get_object('togglebuttonURLShortener'))
104
105
106 def on_togglebuttonURLShortener_toggled(self, widget):
107 if widget.get_active():
108 s = self.Shortener(url=self.adress)
109 try:
110 short_adress = s.short_url()
111 except requests.exceptions.ConnectionError:
112 self.builder.get_object('linkbuttonUrlShortener').set_visible(False)
113 self.builder.get_object('linkbuttonUrlShortener').set_sensitive(False)
114 self.builder.get_object('messagelabelUrlShortener').set_text(
115 _("A network connection error occured."))
116 self.builder.get_object('messagelabelUrlShortener').set_visible(True)
117 return()
118 except:
119 self.builder.get_object('linkbuttonUrlShortener').set_visible(False)
120 self.builder.get_object('linkbuttonUrlShortener').set_sensitive(False)
121 self.builder.get_object('messagelabelUrlShortener').set_text(
122 _("An error occured while trying to shorten the url."))
123 self.builder.get_object('messagelabelUrlShortener').set_visible(True)
124 return()
125 self.builder.get_object('linkbuttonUrlShortener').set_uri(short_adress)
126 self.builder.get_object('linkbuttonUrlShortener').set_label(short_adress)
127 self.builder.get_object('linkbuttonUrlShortener').set_sensitive(True)
128 self.builder.get_object('linkbuttonUrlShortener').set_visible(True)
129 self.qr_code_update_func(short_adress)
130 else:
131 self.builder.get_object('linkbuttonUrlShortener').set_visible(False)
132 self.builder.get_object('linkbuttonUrlShortener').set_sensitive(False)
133 self.builder.get_object('messagelabelUrlShortener').set_visible(False)
44 def on_activated(self):134 def on_activated(self):
45 pass135 pass
46136
@@ -53,7 +143,10 @@
53 if not protocol or www == '':143 if not protocol or www == '':
54 return144 return
55145
56 self.qr_code_update_func(protocol + www)146 self.adress = protocol + www
147
148 self.qr_code_update_func(self.adress)
149 return False
57150
58 def on_entryURL_icon_press(self, widget, icon, mouse_button):151 def on_entryURL_icon_press(self, widget, icon, mouse_button):
59 clear_text_entry(widget, icon)152 clear_text_entry(widget, icon)
@@ -73,7 +166,12 @@
73 def on_entryURL_changed(self, widget, data=None):166 def on_entryURL_changed(self, widget, data=None):
74 show_clear_icon(widget)167 show_clear_icon(widget)
75 self.check_and_remove_protocol(widget)168 self.check_and_remove_protocol(widget)
76 self.update_url_qr_code(www=widget.get_text())169 self.clear_shortener()
170 self.update_url_qr_code()
77171
78 def on_comboboxtextProtocol_changed(self, widget, data=None):172 def on_comboboxtextProtocol_changed(self, widget, data=None):
79 self.update_url_qr_code(protocol=widget.get_active_text())173 self.update_url_qr_code(protocol=widget.get_active_text())
174
175 def clear_shortener(self):
176 self.builder.get_object('linkbuttonUrlShortener').set_visible(False)
177 self.builder.get_object('togglebuttonURLShortener').set_active(False)
80178
=== modified file 'qreator/qrcodes/QRCodeVCard.py'
--- qreator/qrcodes/QRCodeVCard.py 2012-06-02 08:59:55 +0000
+++ qreator/qrcodes/QRCodeVCard.py 2012-10-28 16:08:21 +0000
@@ -14,7 +14,7 @@
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
17from qreator_lib.helpers import get_media_file17from qreator.tools import get_media_path
18#from qreator_lib import QRCodeType as QRCodeType18#from qreator_lib import QRCodeType as QRCodeType
19from QRCodeVCardGtk import QRCodeVCardGtk19from QRCodeVCardGtk import QRCodeVCardGtk
20import vobject20import vobject
@@ -22,7 +22,7 @@
22class QRCodeVCard(object):22class QRCodeVCard(object):
23 def __init__(self, qr_code_update_func, icon_path, description, id):23 def __init__(self, qr_code_update_func, icon_path, description, id):
24 self.qr_code_update_func = qr_code_update_func24 self.qr_code_update_func = qr_code_update_func
25 self.icon_path = get_media_file(icon_path)25 self.icon_path = get_media_path(icon_path)
26 self.description = description26 self.description = description
27 self.id = id27 self.id = id
2828
2929
=== modified file 'qreator/qrcodes/QRCodeVCardGtk.py'
--- qreator/qrcodes/QRCodeVCardGtk.py 2012-06-09 00:06:51 +0000
+++ qreator/qrcodes/QRCodeVCardGtk.py 2012-10-28 16:08:21 +0000
@@ -1,16 +1,16 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2### BEGIN LICENSE2### BEGIN LICENSE
3# Copyright (C) 2012 Stefan Schwarzburg <stefan.schwarzburg@googlemail.com>3# Copyright (C) 2012 David Planella <david.planella@ubuntu.com>
4# This program is free software: you can redistribute it and/or modify it4# This program is free software: you can redistribute it and/or modify it
5# under the terms of the GNU General Public License version 3, as published5# under the terms of the GNU General Public License version 3, as published
6# by the Free Software Foundation.6# by the Free Software Foundation.
7#7#
8# This program is distributed in the hope that it will be useful, but8# This program is distributed in the hope that it will be useful, but
9# WITHOUT ANY WARRANTY; without even the implied warranties of9# WITHOUT ANY WARRANTY; without even the implied warranties of
10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11# PURPOSE. See the GNU General Public License for more details.11# PURPOSE. See the GNU General Public License for more details.
12#12#
13# You should have received a copy of the GNU General Public License along13# You should have received a copy of the GNU General Public License along
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
1717
=== modified file 'qreator/qrcodes/QRCodeWifi.py'
--- qreator/qrcodes/QRCodeWifi.py 2012-05-30 08:33:06 +0000
+++ qreator/qrcodes/QRCodeWifi.py 2012-10-28 16:08:21 +0000
@@ -14,14 +14,14 @@
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
17from qreator_lib.helpers import get_media_file17from qreator.tools import get_media_path
18#from qreator_lib import QRCodeType as QRCodeType18#from qreator_lib import QRCodeType as QRCodeType
19from QRCodeWifiGtk import QRCodeWifiGtk19from QRCodeWifiGtk import QRCodeWifiGtk
2020
21class QRCodeWifi(object):21class QRCodeWifi(object):
22 def __init__(self, qr_code_update_func, icon_path, description, id):22 def __init__(self, qr_code_update_func, icon_path, description, id):
23 self.qr_code_update_func = qr_code_update_func23 self.qr_code_update_func = qr_code_update_func
24 self.icon_path = get_media_file(icon_path)24 self.icon_path = get_media_path(icon_path)
25 self.description = description25 self.description = description
26 self.id = id26 self.id = id
2727
2828
=== modified file 'qreator/qrcodes/QRCodeWifiGtk.py'
--- qreator/qrcodes/QRCodeWifiGtk.py 2012-05-30 10:19:57 +0000
+++ qreator/qrcodes/QRCodeWifiGtk.py 2012-10-28 16:08:21 +0000
@@ -1,16 +1,16 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2### BEGIN LICENSE2### BEGIN LICENSE
3# Copyright (C) 2012 David Planella <david.planella@ubuntu.com>3# Copyright (C) 2012 David Planella <david.planella@ubuntu.com>
4# This program is free software: you can redistribute it and/or modify it4# This program is free software: you can redistribute it and/or modify it
5# under the terms of the GNU General Public License version 3, as published5# under the terms of the GNU General Public License version 3, as published
6# by the Free Software Foundation.6# by the Free Software Foundation.
7#7#
8# This program is distributed in the hope that it will be useful, but8# This program is distributed in the hope that it will be useful, but
9# WITHOUT ANY WARRANTY; without even the implied warranties of9# WITHOUT ANY WARRANTY; without even the implied warranties of
10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11# PURPOSE. See the GNU General Public License for more details.11# PURPOSE. See the GNU General Public License for more details.
12#12#
13# You should have received a copy of the GNU General Public License along13# You should have received a copy of the GNU General Public License along
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
1717
=== added file 'qreator/tools.py'
--- qreator/tools.py 1970-01-01 00:00:00 +0000
+++ qreator/tools.py 2012-10-28 16:08:21 +0000
@@ -0,0 +1,9 @@
1import os
2from qreator_lib.qreatorconfig import get_data_file
3
4def get_media_path(media_file_name):
5 media_filename = get_data_file('media', '%s' % (media_file_name,))
6 if not os.path.exists(media_filename):
7 media_filename = None
8
9 return media_filename
010
=== added file 'qreator_lib/AboutDialog.py'
--- qreator_lib/AboutDialog.py 1970-01-01 00:00:00 +0000
+++ qreator_lib/AboutDialog.py 2012-10-28 16:08:21 +0000
@@ -0,0 +1,50 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2### BEGIN LICENSE
3# Copyright (C) 2012 David Planella <david.planella@ubuntu.com>
4# This program is free software: you can redistribute it and/or modify it
5# under the terms of the GNU General Public License version 3, as published
6# by the Free Software Foundation.
7#
8# This program is distributed in the hope that it will be useful, but
9# WITHOUT ANY WARRANTY; without even the implied warranties of
10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11# PURPOSE. See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along
14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE
16
17### DO NOT EDIT THIS FILE ###
18
19from gi.repository import Gtk # pylint: disable=E0611
20
21from . helpers import get_builder
22
23class AboutDialog(Gtk.AboutDialog):
24 __gtype_name__ = "AboutDialog"
25
26 def __new__(cls):
27 """Special static method that's automatically called by Python when
28 constructing a new instance of this class.
29
30 Returns a fully instantiated AboutDialog object.
31 """
32 builder = get_builder('AboutQreatorDialog')
33 new_object = builder.get_object("about_qreator_dialog")
34 new_object.finish_initializing(builder)
35 return new_object
36
37 def finish_initializing(self, builder):
38 """Called while initializing this instance in __new__
39
40 finish_initalizing should be called after parsing the ui definition
41 and creating a AboutDialog object with it in order
42 to finish initializing the start of the new AboutQreatorDialog
43 instance.
44
45 Put your initialization code in here and leave __init__ undefined.
46 """
47 # Get a reference to the builder and set up the signals.
48 self.builder = builder
49 self.ui = builder.get_ui(self)
50
051
=== modified file 'qreator_lib/Builder.py'
--- qreator_lib/Builder.py 2012-05-19 14:45:57 +0000
+++ qreator_lib/Builder.py 2012-10-28 16:08:21 +0000
@@ -14,6 +14,8 @@
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
17### DO NOT EDIT THIS FILE ###
18
17'''Enhances builder connections, provides object to access glade objects'''19'''Enhances builder connections, provides object to access glade objects'''
1820
19from gi.repository import GObject, Gtk # pylint: disable=E061121from gi.repository import GObject, Gtk # pylint: disable=E0611
@@ -273,14 +275,14 @@
273 # Now, automatically find any the user didn't specify in glade275 # Now, automatically find any the user didn't specify in glade
274 for sig in signal_names:276 for sig in signal_names:
275 # using convention suggested by glade277 # using convention suggested by glade
276 sigpy = sig.replace("-", "_")278 sig = sig.replace("-", "_")
277 handler_names = ["on_%s_%s" % (widget_name, sigpy)]279 handler_names = ["on_%s_%s" % (widget_name, sig)]
278280
279 # Using the convention that the top level window is not281 # Using the convention that the top level window is not
280 # specified in the handler name. That is use282 # specified in the handler name. That is use
281 # on_destroy() instead of on_windowname_destroy()283 # on_destroy() instead of on_windowname_destroy()
282 if widget is callback_obj:284 if widget is callback_obj:
283 handler_names.append("on_%s" % sigpy)285 handler_names.append("on_%s" % sig)
284286
285 do_connect(item, sig, handler_names,287 do_connect(item, sig, handler_names,
286 callback_handler_dict, builder.connections)288 callback_handler_dict, builder.connections)
287289
=== added file 'qreator_lib/PreferencesDialog.py'
--- qreator_lib/PreferencesDialog.py 1970-01-01 00:00:00 +0000
+++ qreator_lib/PreferencesDialog.py 2012-10-28 16:08:21 +0000
@@ -0,0 +1,64 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2### BEGIN LICENSE
3# Copyright (C) 2012 David Planella <david.planella@ubuntu.com>
4# This program is free software: you can redistribute it and/or modify it
5# under the terms of the GNU General Public License version 3, as published
6# by the Free Software Foundation.
7#
8# This program is distributed in the hope that it will be useful, but
9# WITHOUT ANY WARRANTY; without even the implied warranties of
10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11# PURPOSE. See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along
14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE
16
17### DO NOT EDIT THIS FILE ###
18
19"""this dialog adjusts values in gsettings
20"""
21
22from gi.repository import Gtk # pylint: disable=E0611
23import logging
24logger = logging.getLogger('qreator_lib')
25
26from . helpers import get_builder, show_uri, get_help_uri
27
28class PreferencesDialog(Gtk.Dialog):
29 __gtype_name__ = "PreferencesDialog"
30
31 def __new__(cls):
32 """Special static method that's automatically called by Python when
33 constructing a new instance of this class.
34
35 Returns a fully instantiated PreferencesDialog object.
36 """
37 builder = get_builder('PreferencesQreatorDialog')
38 new_object = builder.get_object("preferences_qreator_dialog")
39 new_object.finish_initializing(builder)
40 return new_object
41
42 def finish_initializing(self, builder):
43 """Called while initializing this instance in __new__
44
45 finish_initalizing should be called after parsing the ui definition
46 and creating a PreferencesDialog object with it in order to
47 finish initializing the start of the new PerferencesQreatorDialog
48 instance.
49
50 Put your initialization code in here and leave __init__ undefined.
51 """
52
53 # Get a reference to the builder and set up the signals.
54 self.builder = builder
55 self.ui = builder.get_ui(self, True)
56
57 # code for other initialization actions should be added here
58
59 def on_btn_close_clicked(self, widget, data=None):
60 self.destroy()
61
62 def on_btn_help_clicked(self, widget, data=None):
63 show_uri(self, "ghelp:%s" % get_help_uri('preferences'))
64
065
=== modified file 'qreator_lib/Window.py'
--- qreator_lib/Window.py 2012-05-19 14:45:57 +0000
+++ qreator_lib/Window.py 2012-10-28 16:08:21 +0000
@@ -14,11 +14,13 @@
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
17from gi.repository import Gtk # pylint: disable=E061117### DO NOT EDIT THIS FILE ###
18
19from gi.repository import Gio, Gtk # pylint: disable=E0611
18import logging20import logging
19logger = logging.getLogger('qreator_lib')21logger = logging.getLogger('qreator_lib')
2022
21from . helpers import get_builder23from . helpers import get_builder, show_uri, get_help_uri
2224
23# This class is meant to be subclassed by QreatorWindow. It provides25# This class is meant to be subclassed by QreatorWindow. It provides
24# common functions and some boilerplate.26# common functions and some boilerplate.
@@ -60,8 +62,8 @@
60 self.preferences_dialog = None # instance62 self.preferences_dialog = None # instance
61 self.AboutDialog = None # class63 self.AboutDialog = None # class
6264
63 ##self.settings = Gio.Settings("net.launchpad.qreator")65 self.settings = Gio.Settings("net.launchpad.qreator")
64 ##self.settings.connect('changed', self.on_preferences_changed)66 self.settings.connect('changed', self.on_preferences_changed)
6567
66 # Optional application indicator support68 # Optional application indicator support
67 # Run 'quickly add indicator' to get started.69 # Run 'quickly add indicator' to get started.
@@ -76,6 +78,34 @@
76 except ImportError:78 except ImportError:
77 pass79 pass
7880
81 def on_mnu_contents_activate(self, widget, data=None):
82 show_uri(self, "ghelp:%s" % get_help_uri())
83
84 def on_mnu_about_activate(self, widget, data=None):
85 """Display the about box for qreator."""
86 if self.AboutDialog is not None:
87 about = self.AboutDialog() # pylint: disable=E1102
88 response = about.run()
89 about.destroy()
90
91 def on_mnu_preferences_activate(self, widget, data=None):
92 """Display the preferences window for qreator."""
93
94 """ From the PyGTK Reference manual
95 Say for example the preferences dialog is currently open,
96 and the user chooses Preferences from the menu a second time;
97 use the present() method to move the already-open dialog
98 where the user can see it."""
99 if self.preferences_dialog is not None:
100 logger.debug('show existing preferences_dialog')
101 self.preferences_dialog.present()
102 elif self.PreferencesDialog is not None:
103 logger.debug('create new preferences_dialog')
104 self.preferences_dialog = self.PreferencesDialog() # pylint: disable=E1102
105 self.preferences_dialog.connect('destroy', self.on_preferences_dialog_destroyed)
106 self.preferences_dialog.show()
107 # destroy command moved into dialog to allow for a help button
108
79 def on_mnu_close_activate(self, widget, data=None):109 def on_mnu_close_activate(self, widget, data=None):
80 """Signal handler for closing the QreatorWindow."""110 """Signal handler for closing the QreatorWindow."""
81 self.destroy()111 self.destroy()
@@ -85,3 +115,15 @@
85 # Clean up code for saving application state should be added here.115 # Clean up code for saving application state should be added here.
86 Gtk.main_quit()116 Gtk.main_quit()
87117
118 def on_preferences_changed(self, settings, key, data=None):
119 logger.debug('preference changed: %s = %s' % (key, str(settings.get_value(key))))
120
121 def on_preferences_dialog_destroyed(self, widget, data=None):
122 '''only affects gui
123
124 logically there is no difference between the user closing,
125 minimising or ignoring the preferences dialog'''
126 logger.debug('on_preferences_dialog_destroyed')
127 # to determine whether to create or present preferences_dialog
128 self.preferences_dialog = None
129
88130
=== modified file 'qreator_lib/__init__.py'
--- qreator_lib/__init__.py 2012-05-19 14:45:57 +0000
+++ qreator_lib/__init__.py 2012-10-28 16:08:21 +0000
@@ -14,6 +14,8 @@
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
17### DO NOT EDIT THIS FILE ###
18
17'''facade - makes qreator_lib package easy to refactor19'''facade - makes qreator_lib package easy to refactor
1820
19while keeping its api constant'''21while keeping its api constant'''
2022
=== modified file 'qreator_lib/helpers.py'
--- qreator_lib/helpers.py 2012-05-28 09:38:22 +0000
+++ qreator_lib/helpers.py 2012-10-28 16:08:21 +0000
@@ -14,6 +14,8 @@
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
17### DO NOT EDIT THIS FILE ###
18
17"""Helpers for an Ubuntu application."""19"""Helpers for an Ubuntu application."""
18import logging20import logging
19import os21import os
@@ -21,11 +23,12 @@
21from . qreatorconfig import get_data_file23from . qreatorconfig import get_data_file
22from . Builder import Builder24from . Builder import Builder
2325
26from locale import gettext as _
2427
25def get_builder(builder_file_name):28def get_builder(builder_file_name):
26 """Return a fully-instantiated Gtk.Builder instance from specified ui 29 """Return a fully-instantiated Gtk.Builder instance from specified ui
27 file30 file
2831
29 :param builder_file_name: The name of the builder file, without extension.32 :param builder_file_name: The name of the builder file, without extension.
30 Assumed to be in the 'ui' directory under the data path.33 Assumed to be in the 'ui' directory under the data path.
31 """34 """
@@ -46,22 +49,19 @@
46 if not os.path.exists(media_filename):49 if not os.path.exists(media_filename):
47 media_filename = None50 media_filename = None
4851
49 return media_filename52 return "file:///"+media_filename
50
5153
52class NullHandler(logging.Handler):54class NullHandler(logging.Handler):
53 def emit(self, record):55 def emit(self, record):
54 pass56 pass
5557
56
57def set_up_logging(opts):58def set_up_logging(opts):
58 # add a handler to prevent basicConfig59 # add a handler to prevent basicConfig
59 root = logging.getLogger()60 root = logging.getLogger()
60 null_handler = NullHandler()61 null_handler = NullHandler()
61 root.addHandler(null_handler)62 root.addHandler(null_handler)
6263
63 formatter = logging.Formatter(64 formatter = logging.Formatter("%(levelname)s:%(name)s: %(funcName)s() '%(message)s'")
64 "%(levelname)s:%(name)s: %(funcName)s() '%(message)s'")
6565
66 logger = logging.getLogger('qreator')66 logger = logging.getLogger('qreator')
67 logger_sh = logging.StreamHandler()67 logger_sh = logging.StreamHandler()
@@ -80,7 +80,6 @@
80 if opts.verbose > 1:80 if opts.verbose > 1:
81 lib_logger.setLevel(logging.DEBUG)81 lib_logger.setLevel(logging.DEBUG)
8282
83
84def get_help_uri(page=None):83def get_help_uri(page=None):
85 # help_uri from source tree - default language84 # help_uri from source tree - default language
86 here = os.path.dirname(__file__)85 here = os.path.dirname(__file__)
@@ -96,13 +95,11 @@
9695
97 return help_uri96 return help_uri
9897
99
100def show_uri(parent, link):98def show_uri(parent, link):
101 from gi.repository import Gtk # pylint: disable=E061199 from gi.repository import Gtk # pylint: disable=E0611
102 screen = parent.get_screen()100 screen = parent.get_screen()
103 Gtk.show_uri(screen, link, Gtk.get_current_event_time())101 Gtk.show_uri(screen, link, Gtk.get_current_event_time())
104102
105
106def alias(alternative_function_name):103def alias(alternative_function_name):
107 '''see http://www.drdobbs.com/web-development/184406073#l9'''104 '''see http://www.drdobbs.com/web-development/184406073#l9'''
108 def decorator(function):105 def decorator(function):
109106
=== modified file 'qreator_lib/qreatorconfig.py'
--- qreator_lib/qreatorconfig.py 2012-05-28 09:38:22 +0000
+++ qreator_lib/qreatorconfig.py 2012-10-28 16:08:21 +0000
@@ -14,10 +14,7 @@
14# with this program. If not, see <http://www.gnu.org/licenses/>.14# with this program. If not, see <http://www.gnu.org/licenses/>.
15### END LICENSE15### END LICENSE
1616
17# THIS IS Qreator CONFIGURATION FILE17### DO NOT EDIT THIS FILE ###
18# YOU CAN PUT THERE SOME GLOBAL VALUE
19# Do not touch unless you know what you're doing.
20# you're warned :)
2118
22__all__ = [19__all__ = [
23 'project_path_not_found',20 'project_path_not_found',
@@ -33,6 +30,7 @@
3330
34import os31import os
3532
33from locale import gettext as _
3634
37class project_path_not_found(Exception):35class project_path_not_found(Exception):
38 """Raised when we can't find the project directory."""36 """Raised when we can't find the project directory."""
3937
=== modified file 'setup.py'
--- setup.py 2012-05-28 11:15:51 +0000
+++ setup.py 2012-10-28 16:08:21 +0000
@@ -15,7 +15,7 @@
15# with this program. If not, see <http://www.gnu.org/licenses/>.15# with this program. If not, see <http://www.gnu.org/licenses/>.
16### END LICENSE16### END LICENSE
1717
18###################### DO NOT TOUCH THIS (HEAD TO THE SECOND PART) ###########18###################### DO NOT TOUCH THIS (HEAD TO THE SECOND PART) ######################
1919
20import os20import os
21import sys21import sys
@@ -27,16 +27,16 @@
27 sys.exit(1)27 sys.exit(1)
28assert DistUtilsExtra.auto.__version__ >= '2.18', 'needs DistUtilsExtra.auto >= 2.18'28assert DistUtilsExtra.auto.__version__ >= '2.18', 'needs DistUtilsExtra.auto >= 2.18'
2929
3030def update_config(libdir, values = {}):
31def update_config(values = {}):31
3232 filename = os.path.join(libdir, 'qreator_lib/qreatorconfig.py')
33 oldvalues = {}33 oldvalues = {}
34 try:34 try:
35 fin = file('qreator_lib/qreatorconfig.py', 'r')35 fin = file(filename, 'r')
36 fout = file(fin.name + '.new', 'w')36 fout = file(filename + '.new', 'w')
3737
38 for line in fin:38 for line in fin:
39 fields = line.split(' = ') # Separate variable from value39 fields = line.split(' = ') # Separate variable from value
40 if fields[0] in values:40 if fields[0] in values:
41 oldvalues[fields[0]] = fields[1].strip()41 oldvalues[fields[0]] = fields[1].strip()
42 line = "%s = %s\n" % (fields[0], values[fields[0]])42 line = "%s = %s\n" % (fields[0], values[fields[0]])
@@ -47,42 +47,92 @@
47 fin.close()47 fin.close()
48 os.rename(fout.name, fin.name)48 os.rename(fout.name, fin.name)
49 except (OSError, IOError), e:49 except (OSError, IOError), e:
50 print ("ERROR: Can't find qreator_lib/qreatorconfig.py")50 print ("ERROR: Can't find %s" % filename)
51 sys.exit(1)51 sys.exit(1)
52 return oldvalues52 return oldvalues
5353
5454
55def update_desktop_file(datadir):55def move_desktop_file(root, target_data, prefix):
56 # The desktop file is rightly installed into install_data. But it should
57 # always really be installed into prefix, because while we can install
58 # normal data files anywhere we want, the desktop file needs to exist in
59 # the main system to be found. Only actually useful for /opt installs.
60
61 old_desktop_path = os.path.normpath(root + target_data +
62 '/share/applications')
63 old_desktop_file = old_desktop_path + '/qreator.desktop'
64 desktop_path = os.path.normpath(root + prefix + '/share/applications')
65 desktop_file = desktop_path + '/qreator.desktop'
66
67 if not os.path.exists(old_desktop_file):
68 print ("ERROR: Can't find", old_desktop_file)
69 sys.exit(1)
70 elif target_data != prefix + '/':
71 # This is an /opt install, so rename desktop file to use extras-
72 desktop_file = desktop_path + '/extras-qreator.desktop'
73 try:
74 os.makedirs(desktop_path)
75 os.rename(old_desktop_file, desktop_file)
76 os.rmdir(old_desktop_path)
77 except OSError as e:
78 print ("ERROR: Can't rename", old_desktop_file, ":", e)
79 sys.exit(1)
80
81 return desktop_file
82
83def update_desktop_file(filename, target_pkgdata, target_scripts):
5684
57 try:85 try:
58 fin = file('qreator.desktop.in', 'r')86 fin = file(filename, 'r')
59 fout = file(fin.name + '.new', 'w')87 fout = file(filename + '.new', 'w')
6088
61 for line in fin:89 for line in fin:
62 if 'Icon=' in line:90 if 'Icon=' in line:
63 line = "Icon=%s\n" % (datadir + 'media/qreator.svg')91 line = "Icon=%s\n" % (target_pkgdata + 'media/qreator.svg')
92 elif 'Exec=' in line:
93 cmd = line.split("=")[1].split(None, 1)
94 line = "Exec=%s" % (target_scripts + 'qreator')
95 if len(cmd) > 1:
96 line += " %s" % cmd[1].strip() # Add script arguments back
97 line += "\n"
64 fout.write(line)98 fout.write(line)
65 fout.flush()99 fout.flush()
66 fout.close()100 fout.close()
67 fin.close()101 fin.close()
68 os.rename(fout.name, fin.name)102 os.rename(fout.name, fin.name)
69 except (OSError, IOError), e:103 except (OSError, IOError), e:
70 print ("ERROR: Can't find qreator.desktop.in")104 print ("ERROR: Can't find %s" % filename)
71 sys.exit(1)105 sys.exit(1)
72106
107def compile_schemas(root, target_data):
108 if target_data == '/usr/':
109 return # /usr paths don't need this, they will be handled by dpkg
110 schemadir = os.path.normpath(root + target_data + 'share/glib-2.0/schemas')
111 if (os.path.isdir(schemadir) and
112 os.path.isfile('/usr/bin/glib-compile-schemas')):
113 os.system('/usr/bin/glib-compile-schemas "%s"' % schemadir)
114
73115
74class InstallAndUpdateDataDirectory(DistUtilsExtra.auto.install_auto):116class InstallAndUpdateDataDirectory(DistUtilsExtra.auto.install_auto):
75 def run(self):117 def run(self):
76 values = {'__qreator_data_directory__': "'%s'" % (self.prefix + '/share/qreator/'),118 DistUtilsExtra.auto.install_auto.run(self)
119
120 target_data = '/' + os.path.relpath(self.install_data, self.root) + '/'
121 target_pkgdata = target_data + 'share/qreator/'
122 target_scripts = '/' + os.path.relpath(self.install_scripts, self.root) + '/'
123
124 values = {'__qreator_data_directory__': "'%s'" % (target_pkgdata),
77 '__version__': "'%s'" % self.distribution.get_version()}125 '__version__': "'%s'" % self.distribution.get_version()}
78 previous_values = update_config(values)126 update_config(self.install_lib, values)
79 update_desktop_file(self.prefix + '/share/qreator/')127
80 DistUtilsExtra.auto.install_auto.run(self)128 desktop_file = move_desktop_file(self.root, target_data, self.prefix)
81 update_config(previous_values)129 update_desktop_file(desktop_file, target_pkgdata, target_scripts)
82130 compile_schemas(self.root, target_data)
83##############################################################################131
84###################### YOU SHOULD MODIFY ONLY WHAT IS BELOW ##################132
85##############################################################################133#########################################################################################
134###################### YOU SHOULD MODIFY ONLY WHAT IS BELOW #############################
135#########################################################################################
86136
87DistUtilsExtra.auto.setup(137DistUtilsExtra.auto.setup(
88 name='qreator',138 name='qreator',

Subscribers

People subscribed via source and target branches

to all changes: