Merge lp:~stefan-schwarzburg/qreator/qreator_sms_mms_tel into lp:~dpm/qreator/trunk
- qreator_sms_mms_tel
- Merge into trunk
Status: | Superseded | ||||
---|---|---|---|---|---|
Proposed branch: | lp:~stefan-schwarzburg/qreator/qreator_sms_mms_tel | ||||
Merge into: | lp:~dpm/qreator/trunk | ||||
Diff against target: |
1482 lines (+803/-131) 31 files modified
.quickly (+1/-1) bin/qreator (+8/-3) data/media/sms.svg (+119/-0) data/ui/QrCodeSMS.ui (+123/-0) qreator/QreatorWindow.py (+8/-5) qreator/__init__.py (+14/-9) qreator/qrcodes/GtkHelpers.py (+8/-8) qreator/qrcodes/QRCodeLocation.py (+2/-2) qreator/qrcodes/QRCodeLocationGtk.py (+8/-8) qreator/qrcodes/QRCodeSMS.py (+32/-0) qreator/qrcodes/QRCodeSMSGtk.py (+171/-0) 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 (+8/-8) 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_sms_mms_tel | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
David Planella | Needs Fixing | ||
Review via email: mp+132190@code.launchpad.net |
This proposal has been superseded by a proposal from 2012-11-10.
Commit message
Description of the change
This branch implements the three data formats: SMS, MMS and tel (call).
The data format is not standardized (see https:/
I'm open to all suggestions (including a different icon or separating the "tel" type from the "SMS" and "MMS".
A minor bug fix is included in this branch: adding QR Code types increases the main window height, but this can be fixed a simple line that hides the individual windows before adding them to the main window. I can of cause separate this little fix in a different branch.
When you have reviewed the branches, you might want to ask me to get the branches up to date with trunk after each merge...
David Planella (dpm) wrote : | # |
Also, if it's not too much trouble, would you mind, as you're suggesting, separating the window height bug into a dedicated branch?
I don't mind minor unrelated fixes to be put in feature branches, but this particular one, as it's got to do with window sizing, which I remember to be a bit of a nightmare for Qreator in GTK, I'd like to keep track of.
Thanks!
Schwarzburg (stefan-schwarzburg) wrote : | # |
I'll add the "Type:" label.
The space is good as well.
Explamation mark icon will be changed.
Very good point with the MMS :-) I never used them. So I'll remove them.
the number box should allow all signs that locale phone numbers have. I have looked at a great library https:/
So maybe until this can be done, we should restrict to numbers and +
Multiline message box is fine, do you think a numbers counter would be imporant (e.g. "137 [3 letters left]")?
The exclamation mark: I think it necessary to inform the user that if a message is entered, many QR Code scanners will behave badly. On many, it will not work at all (even the phonenumber will be useless then).
SO my question to you would be: how is this best communicated to the user and if by a message dialog, should the sign disappear after the user has read the warning?
David Planella (dpm) wrote : | # |
Al 09/11/12 14:18, En/na Schwarzburg ha escrit:
> I'll add the "Type:" label.
>
> The space is good as well.
>
> Explamation mark icon will be changed.
>
> Very good point with the MMS :-) I never used them. So I'll remove them.
>
Ack, thanks.
> the number box should allow all signs that locale phone numbers have. I have looked at a great library https:/
> So maybe until this can be done, we should restrict to numbers and +
>
I agree, let's keep the scope down for now.
> Multiline message box is fine, do you think a numbers counter would be imporant (e.g. "137 [3 letters left]")?
>
Ah, yeah, good idea, this might be a nice feature.
> The exclamation mark: I think it necessary to inform the user that if a message is entered, many QR Code scanners will behave badly. On many, it will not work at all (even the phonenumber will be useless then).
> SO my question to you would be: how is this best communicated to the user and if by a message dialog, should the sign disappear after the user has read the warning?
>
Ah, gotcha, I understand it now. A quick question first: assuming we're
restricting the target QR scanners to the most popular ones (e.g.
QrDroid and whichever popular app they use on the iPhone) - if we find
out that they support the non-standard SMS code, do you still think that
we should show a message?
If you still think so, then my suggestion would be to show the message
in a manner that it's visible but does not get in the way. For example:
1. Inside the text box: [Message. WARNING not all code readers might
support it]
2. Additionally, an exclamation mark icon inside the textbox that goes
away as soon as you type. I know single-line text boxes support it, not
sure about the multi-line ones, though.
I'd be up for keeping it lightweight, as users tend to freak out when
they see warning signs and exclamation marks :)
Let me know what you think.
Schwarzburg (stefan-schwarzburg) wrote : | # |
As for the message:
- I have a N900 (with Debian based Maemo OS)
- I have access to an iPhone, where I installed 12 free QR scanners for testing purposes
If you have access to an android phone, we might be able to determine how often the format
SMSTO:<
fails.
- I have also tested 20 freely available online QR Code creaters, which allow the message type. All of them use this format. But I forgot to count the number of creators I found which only support sms:<number>. Probably about 5.
What do you think?
David Planella (dpm) wrote : | # |
Sounds good, I'll add the results of my experiments with Android too.
In the meantime, and as with the other MP, would you mind resubmitting it against the qreator-hackers branch? Thanks!
- 134. By Schwarzburg
-
try to import libphonenumbers
- 135. By Schwarzburg
-
merged with lates trunk
- 136. By Schwarzburg
-
updated the new phone type to the refactored qrcode type system
- 137. By Schwarzburg
-
updated glade file
- 138. By Schwarzburg
-
removed the tools file; added phone option to the desktop file
- 139. By Schwarzburg
-
changed the entry to a multiline textview
- 140. By Schwarzburg
-
working placeholder text for textview; still wrong color though
- 141. By Schwarzburg
-
blocked handlers when placeholders text is reinserted or message type is changed without message or number
- 142. By Schwarzburg
-
restrict phonenumber to + and digits
- 143. By Schwarzburg
-
cleanup of unused code
- 144. By Schwarzburg
-
fixed another update bug
- 145. By Schwarzburg
-
added the clear entry icon to the number field
- 146. By Schwarzburg
-
merged with latest trunk
- 147. By Schwarzburg
-
merged davids changes
- 148. By Schwarzburg
-
replaced the last occurence of SMS with 'Text Message'
- 149. By Schwarzburg
-
made qrcode/
QRCodeSMS* .py pep8 complient and removed pylint errors and warnings - 150. By Schwarzburg
-
merged with latest trunk
- 151. By Schwarzburg
-
added short translator guides
Unmerged revisions
- 151. By Schwarzburg
-
added short translator guides
- 150. By Schwarzburg
-
merged with latest trunk
- 149. By Schwarzburg
-
made qrcode/
QRCodeSMS* .py pep8 complient and removed pylint errors and warnings - 148. By Schwarzburg
-
replaced the last occurence of SMS with 'Text Message'
- 147. By Schwarzburg
-
merged davids changes
- 146. By Schwarzburg
-
merged with latest trunk
- 145. By Schwarzburg
-
added the clear entry icon to the number field
- 144. By Schwarzburg
-
fixed another update bug
- 143. By Schwarzburg
-
cleanup of unused code
- 142. By Schwarzburg
-
restrict phonenumber to + and digits
Preview Diff
1 | === modified file '.quickly' |
2 | --- .quickly 2012-05-28 11:05:50 +0000 |
3 | +++ .quickly 2012-10-30 18:41:18 +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-30 18:41:18 +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 | === added file 'data/media/sms.png' |
54 | Binary files data/media/sms.png 1970-01-01 00:00:00 +0000 and data/media/sms.png 2012-10-30 18:41:18 +0000 differ |
55 | === added file 'data/media/sms.svg' |
56 | --- data/media/sms.svg 1970-01-01 00:00:00 +0000 |
57 | +++ data/media/sms.svg 2012-10-30 18:41:18 +0000 |
58 | @@ -0,0 +1,119 @@ |
59 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
60 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
61 | + |
62 | +<svg |
63 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
64 | + xmlns:cc="http://creativecommons.org/ns#" |
65 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
66 | + xmlns:svg="http://www.w3.org/2000/svg" |
67 | + xmlns="http://www.w3.org/2000/svg" |
68 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
69 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
70 | + id="svg2" |
71 | + version="1.1" |
72 | + inkscape:version="0.48.3.1 r9886" |
73 | + width="64" |
74 | + height="64" |
75 | + sodipodi:docname="sms.svg" |
76 | + inkscape:export-filename="/home/schwarz/Projects/Qreator/qreator_sms/data/media/sms.png" |
77 | + inkscape:export-xdpi="90" |
78 | + inkscape:export-ydpi="90"> |
79 | + <metadata |
80 | + id="metadata8"> |
81 | + <rdf:RDF> |
82 | + <cc:Work |
83 | + rdf:about=""> |
84 | + <dc:format>image/svg+xml</dc:format> |
85 | + <dc:type |
86 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
87 | + <dc:title></dc:title> |
88 | + </cc:Work> |
89 | + </rdf:RDF> |
90 | + </metadata> |
91 | + <defs |
92 | + id="defs6" /> |
93 | + <sodipodi:namedview |
94 | + pagecolor="#ffffff" |
95 | + bordercolor="#666666" |
96 | + borderopacity="1" |
97 | + objecttolerance="10" |
98 | + gridtolerance="10" |
99 | + guidetolerance="10" |
100 | + inkscape:pageopacity="0" |
101 | + inkscape:pageshadow="2" |
102 | + inkscape:window-width="1301" |
103 | + inkscape:window-height="744" |
104 | + id="namedview4" |
105 | + showgrid="false" |
106 | + inkscape:zoom="2.6074563" |
107 | + inkscape:cx="-58.933414" |
108 | + inkscape:cy="17.187981" |
109 | + inkscape:window-x="65" |
110 | + inkscape:window-y="24" |
111 | + inkscape:window-maximized="1" |
112 | + inkscape:current-layer="svg2" /> |
113 | + <path |
114 | + sodipodi:type="arc" |
115 | + style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.99249995000000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" |
116 | + id="path3926" |
117 | + sodipodi:cx="-152.44742" |
118 | + sodipodi:cy="7.8149738" |
119 | + sodipodi:rx="20.518082" |
120 | + sodipodi:ry="17.066441" |
121 | + d="m -131.92934,7.8149738 a 20.518082,17.066441 0 1 1 -41.03616,0 20.518082,17.066441 0 1 1 41.03616,0 z" |
122 | + transform="matrix(1.4807658,0,0,1.7802466,257.73892,18.08742)" /> |
123 | + <path |
124 | + style="fill:#dd4814;fill-opacity:1;stroke:none" |
125 | + d="M 32,4e-8 C 20.68115,4e-8 10.75154,5.8813601 5.0624999,14.75 l 21.9687501,0 c 0.90143,0 1.625,0.623814 1.625,1.375 l 0,42.03125 c 0,0.751186 -0.72357,1.34375 -1.625,1.34375 L 15.625,59.5 C 20.41587,62.359411 26.01528,64 32,64 49.673109,64 64,49.67311 64,32 64,14.326887 49.673109,4e-8 32,4e-8 z M 1.8124998,21.375 C 0.64061985,24.702084 -1.5e-7,28.272078 -1.5e-7,32 c 0,3.725289 0.6422,7.29991 1.81249995,10.625 l 0,-21.25 z" |
126 | + id="path2987" |
127 | + inkscape:connector-curvature="0" /> |
128 | + <path |
129 | + inkscape:connector-curvature="0" |
130 | + style="fill:#dd4814;fill-opacity:1;stroke:none" |
131 | + d="m 5.66702,18.440675 18.98305,0 c 0.90143,0 1.62712,0.78743 1.62712,1.765537 l 0,30.367235 c 0,0.978107 -0.72569,1.765536 -1.62712,1.765536 l -18.98305,0 c -0.90142,0 -1.62712,-0.787429 -1.62712,-1.765536 l 0,-30.367235 c 0,-0.978107 0.7257,-1.765537 1.62712,-1.765537 z" |
132 | + id="rect3759" /> |
133 | + <path |
134 | + inkscape:connector-curvature="0" |
135 | + style="fill:#dd4814;fill-opacity:1;stroke:none" |
136 | + d="m 21.53142,16.677966 c 0,0.299544 -2.85324,0.542373 -6.37288,0.542373 -3.51965,0 -6.37288,-0.242829 -6.37288,-0.542373 0,-0.299544 2.85323,-0.542373 6.37288,-0.542373 3.51964,0 6.37288,0.242829 6.37288,0.542373 z" |
137 | + id="path3761-2" /> |
138 | + <path |
139 | + inkscape:connector-curvature="0" |
140 | + style="fill:#dd4814;fill-opacity:1;stroke:none" |
141 | + d="m 13.80261,53.152542 2.71187,0 c 0.90142,0 1.62712,0.787429 1.62712,1.765536 l 0,1.62147 c 0,0.978107 -0.7257,1.765536 -1.62712,1.765536 l -2.71187,0 c -0.90142,0 -1.62712,-0.787429 -1.62712,-1.765536 l 0,-1.62147 c 0,-0.978107 0.7257,-1.765536 1.62712,-1.765536 z" |
142 | + id="rect3781" /> |
143 | + <path |
144 | + style="fill:#ffffff;fill-opacity:1;stroke:none" |
145 | + d="m 20.677967,21.864405 32.271187,0 0,20.338983 -32.271187,0 z" |
146 | + id="rect3795" |
147 | + inkscape:connector-curvature="0" /> |
148 | + <path |
149 | + style="fill:none;stroke:#dd4814;stroke-width:1.99249995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" |
150 | + d="m 20.737831,21.924265 16.71,11.066721 15.37367,-11.003611" |
151 | + id="path3797" |
152 | + inkscape:connector-curvature="0" |
153 | + sodipodi:nodetypes="ccc" /> |
154 | + <path |
155 | + style="fill:none;stroke:#dd4814;stroke-width:1.99249995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" |
156 | + d="M 20.671149,42.142414 33.430555,31.077924" |
157 | + id="path3799" |
158 | + inkscape:connector-curvature="0" |
159 | + sodipodi:nodetypes="cc" /> |
160 | + <path |
161 | + style="fill:none;stroke:#dd4814;stroke-width:1.99249995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" |
162 | + d="M 52.606159,41.860391 40.953172,30.817574" |
163 | + id="path3801" |
164 | + inkscape:connector-curvature="0" /> |
165 | + <path |
166 | + style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" |
167 | + d="m 28.077497,9.009053 c 0,0 2.368569,-0.579447 5.033641,1.965518 2.665072,2.544964 1.965517,5.417157 1.965517,5.417157" |
168 | + id="path3803" |
169 | + inkscape:connector-curvature="0" |
170 | + sodipodi:nodetypes="czc" /> |
171 | + <path |
172 | + style="fill:none;stroke:#ffffff;stroke-width:1.65370095px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" |
173 | + d="m 29.561382,3.508059 c 0,0 3.785323,-0.9915414 8.044504,3.3633638 4.259179,4.3549052 3.141186,9.2697582 3.141186,9.2697582" |
174 | + id="path3803-7" |
175 | + inkscape:connector-curvature="0" |
176 | + sodipodi:nodetypes="czc" /> |
177 | +</svg> |
178 | |
179 | === added file 'data/ui/QrCodeSMS.ui' |
180 | --- data/ui/QrCodeSMS.ui 1970-01-01 00:00:00 +0000 |
181 | +++ data/ui/QrCodeSMS.ui 2012-10-30 18:41:18 +0000 |
182 | @@ -0,0 +1,123 @@ |
183 | +<?xml version="1.0" encoding="UTF-8"?> |
184 | +<interface> |
185 | + <!-- interface-requires gtk+ 3.0 --> |
186 | + <object class="GtkGrid" id="qr_code_sms"> |
187 | + <property name="visible">True</property> |
188 | + <property name="can_focus">False</property> |
189 | + <child> |
190 | + <object class="GtkEntry" id="entryText"> |
191 | + <property name="visible">True</property> |
192 | + <property name="can_focus">True</property> |
193 | + <property name="margin_top">3</property> |
194 | + <property name="margin_bottom">3</property> |
195 | + <property name="hexpand">True</property> |
196 | + <property name="invisible_char">•</property> |
197 | + <property name="invisible_char_set">True</property> |
198 | + <property name="placeholder_text">[prefilled message text]</property> |
199 | + <signal name="changed" handler="on_entryText_changed" swapped="no"/> |
200 | + </object> |
201 | + <packing> |
202 | + <property name="left_attach">1</property> |
203 | + <property name="top_attach">2</property> |
204 | + <property name="width">1</property> |
205 | + <property name="height">1</property> |
206 | + </packing> |
207 | + </child> |
208 | + <child> |
209 | + <object class="GtkBox" id="boxMessage"> |
210 | + <property name="visible">True</property> |
211 | + <property name="can_focus">False</property> |
212 | + <child> |
213 | + <object class="GtkLabel" id="labelMessage"> |
214 | + <property name="visible">True</property> |
215 | + <property name="can_focus">False</property> |
216 | + <property name="xalign">0</property> |
217 | + <property name="label" translatable="yes">Message: </property> |
218 | + </object> |
219 | + <packing> |
220 | + <property name="expand">False</property> |
221 | + <property name="fill">True</property> |
222 | + <property name="position">0</property> |
223 | + </packing> |
224 | + </child> |
225 | + <child> |
226 | + <object class="GtkEventBox" id="eventboxmessage"> |
227 | + <property name="visible">True</property> |
228 | + <property name="can_focus">False</property> |
229 | + <signal name="button-press-event" handler="on_eventboxmessage_press_event" swapped="no"/> |
230 | + <child> |
231 | + <object class="GtkImage" id="image1"> |
232 | + <property name="visible">True</property> |
233 | + <property name="can_focus">False</property> |
234 | + <property name="yalign">0.50999999046325684</property> |
235 | + <property name="xpad">4</property> |
236 | + <property name="stock">gtk-dialog-warning</property> |
237 | + </object> |
238 | + </child> |
239 | + </object> |
240 | + <packing> |
241 | + <property name="expand">False</property> |
242 | + <property name="fill">True</property> |
243 | + <property name="position">1</property> |
244 | + </packing> |
245 | + </child> |
246 | + </object> |
247 | + <packing> |
248 | + <property name="left_attach">0</property> |
249 | + <property name="top_attach">2</property> |
250 | + <property name="width">1</property> |
251 | + <property name="height">1</property> |
252 | + </packing> |
253 | + </child> |
254 | + <child> |
255 | + <object class="GtkLabel" id="label2"> |
256 | + <property name="visible">True</property> |
257 | + <property name="can_focus">False</property> |
258 | + <property name="xalign">0</property> |
259 | + <property name="label" translatable="yes">Number: </property> |
260 | + </object> |
261 | + <packing> |
262 | + <property name="left_attach">0</property> |
263 | + <property name="top_attach">1</property> |
264 | + <property name="width">1</property> |
265 | + <property name="height">1</property> |
266 | + </packing> |
267 | + </child> |
268 | + <child> |
269 | + <object class="GtkEntry" id="entryNumber"> |
270 | + <property name="visible">True</property> |
271 | + <property name="can_focus">True</property> |
272 | + <property name="margin_top">3</property> |
273 | + <property name="margin_bottom">3</property> |
274 | + <property name="hexpand">True</property> |
275 | + <property name="invisible_char">•</property> |
276 | + <property name="invisible_char_set">True</property> |
277 | + <property name="placeholder_text">[phone number (international format)]</property> |
278 | + <signal name="changed" handler="on_entryNumber_changed" swapped="no"/> |
279 | + </object> |
280 | + <packing> |
281 | + <property name="left_attach">1</property> |
282 | + <property name="top_attach">1</property> |
283 | + <property name="width">1</property> |
284 | + <property name="height">1</property> |
285 | + </packing> |
286 | + </child> |
287 | + <child> |
288 | + <object class="GtkComboBoxText" id="comboboxType"> |
289 | + <property name="visible">True</property> |
290 | + <property name="can_focus">False</property> |
291 | + <property name="entry_text_column">0</property> |
292 | + <property name="id_column">1</property> |
293 | + </object> |
294 | + <packing> |
295 | + <property name="left_attach">1</property> |
296 | + <property name="top_attach">0</property> |
297 | + <property name="width">1</property> |
298 | + <property name="height">1</property> |
299 | + </packing> |
300 | + </child> |
301 | + <child> |
302 | + <placeholder/> |
303 | + </child> |
304 | + </object> |
305 | +</interface> |
306 | |
307 | === modified file 'qreator/QreatorWindow.py' |
308 | --- qreator/QreatorWindow.py 2012-06-24 07:59:42 +0000 |
309 | +++ qreator/QreatorWindow.py 2012-10-30 18:41:18 +0000 |
310 | @@ -25,7 +25,7 @@ |
311 | |
312 | from qreator_lib.i18n import _ |
313 | from qreator_lib import Window |
314 | -from qreator_lib.helpers import get_media_file |
315 | +from qreator.tools import get_media_path |
316 | |
317 | from QRCode import QRCode |
318 | from QRCode import QRCodeOutput |
319 | @@ -71,7 +71,7 @@ |
320 | |
321 | # Load the background texture in the QR code page |
322 | self.texture = cairo.ImageSurface.create_from_png( |
323 | - get_media_file("pattern.png")) |
324 | + get_media_path("pattern.png")) |
325 | |
326 | # Time to wait in milliseconds before switching to the next view |
327 | # after having clicked once on an iconview icon |
328 | @@ -119,6 +119,7 @@ |
329 | from qrcodes.QRCodeLocation import QRCodeLocation |
330 | from qrcodes.QRCodeWifi import QRCodeWifi |
331 | from qrcodes.QRCodeVCard import QRCodeVCard |
332 | + from qrcodes.QRCodeSMS import QRCodeSMS |
333 | try: |
334 | from qrcodes.QRCodeSoftwareCenterApp import \ |
335 | QRCodeSoftwareCenterApp |
336 | @@ -139,10 +140,12 @@ |
337 | self.qr_types.append( |
338 | QRCodeVCard(self.update_qr_code, 'vcard.png', |
339 | _('Business card'), 4)) |
340 | + self.qr_types.append( |
341 | + QRCodeSMS(self.update_qr_code, 'sms.png', _('Call & SMS'), 5)) |
342 | if use_usc_qr_type: |
343 | self.qr_types.append( |
344 | QRCodeSoftwareCenterApp(self.update_qr_code, |
345 | - 'softwarecentre.png', _('Ubuntu Software Center app'), 5)) |
346 | + 'softwarecentre.png', _('Ubuntu Software Center app'), 6)) |
347 | |
348 | self.qr_types_store = Gtk.ListStore(str, GdkPixbuf.Pixbuf, int) |
349 | # ^ desc, icon, id ^ |
350 | @@ -155,14 +158,14 @@ |
351 | self.curr_width = 0 |
352 | |
353 | for qr_type in self.qr_types: |
354 | + qr_type.widget.grid.hide() # otherwise the main window gets too large! |
355 | self.ui.qr_input_box.add(qr_type.widget.grid) |
356 | |
357 | def fill_qr_types_store(self): |
358 | self.qr_types_store.clear() |
359 | |
360 | for qr_type in self.qr_types: |
361 | - icon = GdkPixbuf.Pixbuf.new_from_file(get_media_file( |
362 | - qr_type.icon_path)) |
363 | + icon = GdkPixbuf.Pixbuf.new_from_file(qr_type.icon_path) |
364 | self.qr_types_store.append([qr_type.description, |
365 | icon, |
366 | qr_type.id]) |
367 | |
368 | === modified file 'qreator/__init__.py' |
369 | --- qreator/__init__.py 2012-06-23 08:42:52 +0000 |
370 | +++ qreator/__init__.py 2012-10-30 18:41:18 +0000 |
371 | @@ -1,16 +1,16 @@ |
372 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
373 | ### BEGIN LICENSE |
374 | # Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
375 | -# This program is free software: you can redistribute it and/or modify it |
376 | -# under the terms of the GNU General Public License version 3, as published |
377 | +# This program is free software: you can redistribute it and/or modify it |
378 | +# under the terms of the GNU General Public License version 3, as published |
379 | # by the Free Software Foundation. |
380 | -# |
381 | -# This program is distributed in the hope that it will be useful, but |
382 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
383 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
384 | +# |
385 | +# This program is distributed in the hope that it will be useful, but |
386 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
387 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
388 | # PURPOSE. See the GNU General Public License for more details. |
389 | -# |
390 | -# You should have received a copy of the GNU General Public License along |
391 | +# |
392 | +# You should have received a copy of the GNU General Public License along |
393 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
394 | ### END LICENSE |
395 | |
396 | @@ -50,6 +50,9 @@ |
397 | parser.add_option( |
398 | "-b", "--businesscard", dest="view", action="store_const", const="vcard", |
399 | help=UTF8_("Create a QR code for a business card")) |
400 | + parser.add_option( |
401 | + "-m", "--sms", dest="view", action="store_const", const="sms", |
402 | + help=UTF8_("Create a QR code for a SMS")) |
403 | (options, args) = parser.parse_args() |
404 | |
405 | set_up_logging(options) |
406 | @@ -74,8 +77,10 @@ |
407 | qr_id = 3 |
408 | elif options.view == 'vcard': |
409 | qr_id = 4 |
410 | + elif options.view == 'sms': |
411 | + qr_id = 5 |
412 | elif options.view == 'software': |
413 | - qr_id = 5 |
414 | + qr_id = 6 |
415 | window.switch_qrcode_view(qr_id) |
416 | window.ui.notebook1.set_current_page(QreatorWindow.PAGE_QR) |
417 | Gtk.main() |
418 | |
419 | === modified file 'qreator/qrcodes/GtkHelpers.py' |
420 | --- qreator/qrcodes/GtkHelpers.py 2012-05-30 10:19:57 +0000 |
421 | +++ qreator/qrcodes/GtkHelpers.py 2012-10-30 18:41:18 +0000 |
422 | @@ -1,16 +1,16 @@ |
423 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
424 | ### BEGIN LICENSE |
425 | # Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
426 | -# This program is free software: you can redistribute it and/or modify it |
427 | -# under the terms of the GNU General Public License version 3, as published |
428 | +# This program is free software: you can redistribute it and/or modify it |
429 | +# under the terms of the GNU General Public License version 3, as published |
430 | # by the Free Software Foundation. |
431 | -# |
432 | -# This program is distributed in the hope that it will be useful, but |
433 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
434 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
435 | +# |
436 | +# This program is distributed in the hope that it will be useful, but |
437 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
438 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
439 | # PURPOSE. See the GNU General Public License for more details. |
440 | -# |
441 | -# You should have received a copy of the GNU General Public License along |
442 | +# |
443 | +# You should have received a copy of the GNU General Public License along |
444 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
445 | ### END LICENSE |
446 | |
447 | |
448 | === modified file 'qreator/qrcodes/QRCodeLocation.py' |
449 | --- qreator/qrcodes/QRCodeLocation.py 2012-05-30 08:33:06 +0000 |
450 | +++ qreator/qrcodes/QRCodeLocation.py 2012-10-30 18:41:18 +0000 |
451 | @@ -14,14 +14,14 @@ |
452 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
453 | ### END LICENSE |
454 | |
455 | -from qreator_lib.helpers import get_media_file |
456 | +from qreator.tools import get_media_path |
457 | #from qreator_lib import QRCodeType as QRCodeType |
458 | from QRCodeLocationGtk import QRCodeLocationGtk |
459 | |
460 | class QRCodeLocation(object): |
461 | def __init__(self, qr_code_update_func, icon_path, description, id): |
462 | self.qr_code_update_func = qr_code_update_func |
463 | - self.icon_path = get_media_file(icon_path) |
464 | + self.icon_path = get_media_path(icon_path) |
465 | self.description = description |
466 | self.id = id |
467 | |
468 | |
469 | === modified file 'qreator/qrcodes/QRCodeLocationGtk.py' |
470 | --- qreator/qrcodes/QRCodeLocationGtk.py 2012-06-23 16:49:09 +0000 |
471 | +++ qreator/qrcodes/QRCodeLocationGtk.py 2012-10-30 18:41:18 +0000 |
472 | @@ -1,16 +1,16 @@ |
473 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
474 | ### BEGIN LICENSE |
475 | # Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
476 | -# This program is free software: you can redistribute it and/or modify it |
477 | -# under the terms of the GNU General Public License version 3, as published |
478 | +# This program is free software: you can redistribute it and/or modify it |
479 | +# under the terms of the GNU General Public License version 3, as published |
480 | # by the Free Software Foundation. |
481 | -# |
482 | -# This program is distributed in the hope that it will be useful, but |
483 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
484 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
485 | +# |
486 | +# This program is distributed in the hope that it will be useful, but |
487 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
488 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
489 | # PURPOSE. See the GNU General Public License for more details. |
490 | -# |
491 | -# You should have received a copy of the GNU General Public License along |
492 | +# |
493 | +# You should have received a copy of the GNU General Public License along |
494 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
495 | ### END LICENSE |
496 | |
497 | |
498 | === added file 'qreator/qrcodes/QRCodeSMS.py' |
499 | --- qreator/qrcodes/QRCodeSMS.py 1970-01-01 00:00:00 +0000 |
500 | +++ qreator/qrcodes/QRCodeSMS.py 2012-10-30 18:41:18 +0000 |
501 | @@ -0,0 +1,32 @@ |
502 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
503 | +### BEGIN LICENSE |
504 | +# Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
505 | +# This program is free software: you can redistribute it and/or modify it |
506 | +# under the terms of the GNU General Public License version 3, as published |
507 | +# by the Free Software Foundation. |
508 | +# |
509 | +# This program is distributed in the hope that it will be useful, but |
510 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
511 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
512 | +# PURPOSE. See the GNU General Public License for more details. |
513 | +# |
514 | +# You should have received a copy of the GNU General Public License along |
515 | +# with this program. If not, see <http://www.gnu.org/licenses/>. |
516 | +### END LICENSE |
517 | + |
518 | +from qreator.tools import get_media_path |
519 | +#from qreator_lib import QRCodeType as QRCodeType |
520 | +from QRCodeSMSGtk import QRCodeSMSGtk |
521 | + |
522 | +class QRCodeSMS(object): |
523 | + def __init__(self, qr_code_update_func, icon_path, description, id): |
524 | + self.qr_code_update_func = qr_code_update_func |
525 | + self.icon_path = get_media_path(icon_path) |
526 | + self.description = description |
527 | + self.id = id |
528 | + |
529 | + self.data = {'text': ''} |
530 | + self.textdata = '' |
531 | + |
532 | + # Create widget instance |
533 | + self.widget = QRCodeSMSGtk(self.qr_code_update_func) |
534 | |
535 | === added file 'qreator/qrcodes/QRCodeSMSGtk.py' |
536 | --- qreator/qrcodes/QRCodeSMSGtk.py 1970-01-01 00:00:00 +0000 |
537 | +++ qreator/qrcodes/QRCodeSMSGtk.py 2012-10-30 18:41:18 +0000 |
538 | @@ -0,0 +1,171 @@ |
539 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
540 | +### BEGIN LICENSE |
541 | +# Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
542 | +# This program is free software: you can redistribute it and/or modify it |
543 | +# under the terms of the GNU General Public License version 3, as published |
544 | +# by the Free Software Foundation. |
545 | +# |
546 | +# This program is distributed in the hope that it will be useful, but |
547 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
548 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
549 | +# PURPOSE. See the GNU General Public License for more details. |
550 | +# |
551 | +# You should have received a copy of the GNU General Public License along |
552 | +# with this program. If not, see <http://www.gnu.org/licenses/>. |
553 | +### END LICENSE |
554 | + |
555 | +from gi.repository import Gtk |
556 | +from qreator_lib.i18n import _ |
557 | +from qreator_lib.helpers import get_data_file |
558 | + |
559 | + |
560 | +MESSAGE_TYPES = [ |
561 | + (_("Call"), "tel"), |
562 | + (_("SMS"), "SMS"), |
563 | + (_("MMS"), "MMS"), |
564 | + ] |
565 | + |
566 | + |
567 | +class QRCodeSMSGtk(object): |
568 | + def __init__(self, qr_code_update_func): |
569 | + self.qr_code_update_func = qr_code_update_func |
570 | + self.builder = Gtk.Builder() |
571 | + |
572 | + self.builder.add_from_file( |
573 | + get_data_file('ui', '%s.ui' % ('QrCodeSMS',))) |
574 | + self.grid = self.builder.get_object('qr_code_sms') |
575 | + |
576 | + self.messagecombo = self.builder.get_object('comboboxType') |
577 | + for t in MESSAGE_TYPES: |
578 | + self.messagecombo.append_text(t[0]) |
579 | + self.messagecombo.set_active(0) |
580 | + self.messagecombo.connect("changed", self.on_comboboxType_changed, None) |
581 | + |
582 | + self.text = self.builder.get_object('entryText') |
583 | + self.text.connect("changed", self.on_entryText_changed, None) |
584 | + |
585 | + # tel is the default message type |
586 | + self.text.hide() |
587 | + self.builder.get_object('boxMessage').hide() |
588 | + |
589 | + self.number = self.builder.get_object('entryNumber') |
590 | + self.number.connect("changed", self.on_entryNumber_changed, None) |
591 | + |
592 | + self.builder.get_object('eventboxmessage').connect("button-press-event", self.on_eventboxmessage_press_event, None) |
593 | + |
594 | + def on_activated(self): |
595 | + pass |
596 | + |
597 | + def on_comboboxType_changed(self, widget, data=None): |
598 | + if not MESSAGE_TYPES[widget.get_active()][1] == "tel": |
599 | + self.text.show() |
600 | + self.builder.get_object('boxMessage').show() |
601 | + else: |
602 | + self.text.hide() |
603 | + self.builder.get_object('boxMessage').hide() |
604 | + self.on_entryText_changed(self.text) |
605 | + |
606 | + def on_entryNumber_changed(self, widget, data=None): |
607 | + self.on_entryText_changed(self.text) |
608 | + |
609 | + def on_entryText_changed(self, widget, data=None): |
610 | + # The SMS data format is not standardized. |
611 | + # Possible formats are: |
612 | + # sms:number |
613 | + # smsto:number |
614 | + # sms:number:message |
615 | + # smsto:number:message |
616 | + # sms:number?body=message |
617 | + |
618 | + # the same with capital SMS or SMSTO |
619 | + |
620 | + # Comparison of data formats used by other QR Code creators |
621 | + |
622 | + # http://qrcode.notixtech.com/ |
623 | + # smsto:<number>:<message> |
624 | + |
625 | + # http://www.i-nigma.com/CreateBarcodes.html |
626 | + # SMSTO:<number>:<message> |
627 | + |
628 | + # http://www.azonmedia.com/en/qrcode-generator |
629 | + # SMSTO:<number>:<message> |
630 | + |
631 | + # http://www.mqr.kr/generate/sms/ |
632 | + # smsto:<number>:<message> |
633 | + |
634 | + # http://www.unitaglive.com/qrcode |
635 | + # SMSTO:<number>:<message> |
636 | + |
637 | + # http://www.sparqcode.com/static/maestro |
638 | + # SMSTO:<number>:<message> |
639 | + |
640 | + # http://www.qrzilla.com/ |
641 | + # smsto:<number>:<message> |
642 | + |
643 | + # https://zxing.appspot.com/generator/ |
644 | + # smsto:<number>:<message> |
645 | + |
646 | + # http://delivr.com/qr-code-generator |
647 | + # smsto:<number>:<message> |
648 | + |
649 | + # http://www.snapmaze.com/ |
650 | + # SMSTO:<number>:<message> |
651 | + |
652 | + # http://app.qreateandtrack.com/#/create/phonesms |
653 | + # sms:<number>:<message> |
654 | + |
655 | + # http://www.esponce.com/ |
656 | + # SMSTO:<number>:<message> |
657 | + |
658 | + # http://www.onlineqrlab.com/ |
659 | + # sms:<number>:<message> |
660 | + |
661 | + # http://goqr.me/ |
662 | + # SMSTO:<number>:<message> |
663 | + |
664 | + # http://blog.qr4.nl/QR-Code-SMS.aspx |
665 | + # SMSTO:<number>:<message> |
666 | + |
667 | + # http://beqrious.com/qr-code-generator/ |
668 | + # smsto:<number>:<message> |
669 | + |
670 | + # http://demo.j-plant.com/qrcode-plant.html#type_sms |
671 | + # smsto:<number>:<message> |
672 | + |
673 | + # http://qrcode.kaywa.com/ |
674 | + # SMSTO:<number>:<message> |
675 | + |
676 | + # http://yourfreeqrcode.com/sms.php |
677 | + # smsto:<number>:<message> |
678 | + |
679 | + # http://keremerkan.net/qr-code-and-2d-code-generator/ |
680 | + # SMSTO:<number>:<message> |
681 | + |
682 | + # => we should probably go with SMSTO:number:message |
683 | + |
684 | + ty = MESSAGE_TYPES[self.builder.get_object('comboboxType').get_active()][1] |
685 | + n = self.builder.get_object('entryNumber').get_text() |
686 | + te = widget.get_text() |
687 | + if ty == "tel" or te == "": |
688 | + self.qr_code_update_func("{0}:{1}".format(ty, n)) |
689 | + else: |
690 | + self.qr_code_update_func("{0}:{1}:{2}".format(ty, n, te)) |
691 | + |
692 | + def on_eventboxmessage_press_event(self, widget, event, data=None): |
693 | + print widget, event, data |
694 | + dialog = Gtk.MessageDialog( |
695 | + message_type=Gtk.MessageType.INFO, |
696 | + buttons=Gtk.ButtonsType.OK, |
697 | + message_format="Not all QR Code readers can handle SMS codes with message!") |
698 | + dialog.format_secondary_text( |
699 | + """Some QR Code readers accept SMS with predefined message, while others might either ignore the text or get the whole data wrong. |
700 | + |
701 | +The format Qreator uses is: |
702 | + |
703 | +SMSTO:<phone number>:<message> |
704 | + |
705 | +or |
706 | + |
707 | +SMSTO:<phone number>.""") |
708 | + dialog.run() |
709 | + dialog.destroy() |
710 | |
711 | === modified file 'qreator/qrcodes/QRCodeSoftwareCenterApp.py' |
712 | --- qreator/qrcodes/QRCodeSoftwareCenterApp.py 2012-05-30 08:33:06 +0000 |
713 | +++ qreator/qrcodes/QRCodeSoftwareCenterApp.py 2012-10-30 18:41:18 +0000 |
714 | @@ -14,7 +14,7 @@ |
715 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
716 | ### END LICENSE |
717 | |
718 | -from qreator_lib.helpers import get_media_file |
719 | +from qreator.tools import get_media_path |
720 | #from qreator_lib import QRCodeType as QRCodeType |
721 | from QRCodeSoftwareCenterAppGtk import QRCodeSoftwareCenterAppGtk |
722 | |
723 | @@ -22,7 +22,7 @@ |
724 | class QRCodeSoftwareCenterApp(object): |
725 | def __init__(self, qr_code_update_func, icon_path, description, id): |
726 | self.qr_code_update_func = qr_code_update_func |
727 | - self.icon_path = get_media_file(icon_path) |
728 | + self.icon_path = get_media_path(icon_path) |
729 | self.description = description |
730 | self.id = id |
731 | |
732 | |
733 | === modified file 'qreator/qrcodes/QRCodeSoftwareCenterAppGtk.py' |
734 | --- qreator/qrcodes/QRCodeSoftwareCenterAppGtk.py 2012-05-30 10:19:57 +0000 |
735 | +++ qreator/qrcodes/QRCodeSoftwareCenterAppGtk.py 2012-10-30 18:41:18 +0000 |
736 | @@ -1,16 +1,16 @@ |
737 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
738 | ### BEGIN LICENSE |
739 | # Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
740 | -# This program is free software: you can redistribute it and/or modify it |
741 | -# under the terms of the GNU General Public License version 3, as published |
742 | +# This program is free software: you can redistribute it and/or modify it |
743 | +# under the terms of the GNU General Public License version 3, as published |
744 | # by the Free Software Foundation. |
745 | -# |
746 | -# This program is distributed in the hope that it will be useful, but |
747 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
748 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
749 | +# |
750 | +# This program is distributed in the hope that it will be useful, but |
751 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
752 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
753 | # PURPOSE. See the GNU General Public License for more details. |
754 | -# |
755 | -# You should have received a copy of the GNU General Public License along |
756 | +# |
757 | +# You should have received a copy of the GNU General Public License along |
758 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
759 | ### END LICENSE |
760 | |
761 | |
762 | === modified file 'qreator/qrcodes/QRCodeText.py' |
763 | --- qreator/qrcodes/QRCodeText.py 2012-05-30 08:33:06 +0000 |
764 | +++ qreator/qrcodes/QRCodeText.py 2012-10-30 18:41:18 +0000 |
765 | @@ -14,14 +14,14 @@ |
766 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
767 | ### END LICENSE |
768 | |
769 | -from qreator_lib.helpers import get_media_file |
770 | +from qreator.tools import get_media_path |
771 | #from qreator_lib import QRCodeType as QRCodeType |
772 | from QRCodeTextGtk import QRCodeTextGtk |
773 | |
774 | class QRCodeText(object): |
775 | def __init__(self, qr_code_update_func, icon_path, description, id): |
776 | self.qr_code_update_func = qr_code_update_func |
777 | - self.icon_path = get_media_file(icon_path) |
778 | + self.icon_path = get_media_path(icon_path) |
779 | self.description = description |
780 | self.id = id |
781 | |
782 | |
783 | === modified file 'qreator/qrcodes/QRCodeTextGtk.py' |
784 | --- qreator/qrcodes/QRCodeTextGtk.py 2012-05-30 08:33:06 +0000 |
785 | +++ qreator/qrcodes/QRCodeTextGtk.py 2012-10-30 18:41:18 +0000 |
786 | @@ -1,16 +1,16 @@ |
787 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
788 | ### BEGIN LICENSE |
789 | # Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
790 | -# This program is free software: you can redistribute it and/or modify it |
791 | -# under the terms of the GNU General Public License version 3, as published |
792 | +# This program is free software: you can redistribute it and/or modify it |
793 | +# under the terms of the GNU General Public License version 3, as published |
794 | # by the Free Software Foundation. |
795 | -# |
796 | -# This program is distributed in the hope that it will be useful, but |
797 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
798 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
799 | +# |
800 | +# This program is distributed in the hope that it will be useful, but |
801 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
802 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
803 | # PURPOSE. See the GNU General Public License for more details. |
804 | -# |
805 | -# You should have received a copy of the GNU General Public License along |
806 | +# |
807 | +# You should have received a copy of the GNU General Public License along |
808 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
809 | ### END LICENSE |
810 | |
811 | |
812 | === modified file 'qreator/qrcodes/QRCodeType.py' |
813 | --- qreator/qrcodes/QRCodeType.py 2012-05-30 08:33:06 +0000 |
814 | +++ qreator/qrcodes/QRCodeType.py 2012-10-30 18:41:18 +0000 |
815 | @@ -19,7 +19,7 @@ |
816 | id): |
817 | self.parent_widget = parent_widget |
818 | self.drawing_area = drawing_area |
819 | - self.icon_path = get_media_file(icon_path) |
820 | + self.icon_path = get_media_path(icon_path) |
821 | self.description = description |
822 | self.id = id |
823 | |
824 | |
825 | === modified file 'qreator/qrcodes/QRCodeURL.py' |
826 | --- qreator/qrcodes/QRCodeURL.py 2012-05-30 08:33:06 +0000 |
827 | +++ qreator/qrcodes/QRCodeURL.py 2012-10-30 18:41:18 +0000 |
828 | @@ -14,14 +14,14 @@ |
829 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
830 | ### END LICENSE |
831 | |
832 | -from qreator_lib.helpers import get_media_file |
833 | +from qreator.tools import get_media_path |
834 | #from qreator_lib import QRCodeType as QRCodeType |
835 | from QRCodeURLGtk import QRCodeURLGtk |
836 | |
837 | class QRCodeURL(object): |
838 | def __init__(self, qr_code_update_func, icon_path, description, id): |
839 | self.qr_code_update_func = qr_code_update_func |
840 | - self.icon_path = get_media_file(icon_path) |
841 | + self.icon_path = get_media_path(icon_path) |
842 | self.description = description |
843 | self.id = id |
844 | |
845 | |
846 | === modified file 'qreator/qrcodes/QRCodeURLGtk.py' |
847 | --- qreator/qrcodes/QRCodeURLGtk.py 2012-08-02 13:15:02 +0000 |
848 | +++ qreator/qrcodes/QRCodeURLGtk.py 2012-10-30 18:41:18 +0000 |
849 | @@ -1,16 +1,16 @@ |
850 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
851 | ### BEGIN LICENSE |
852 | # Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
853 | -# This program is free software: you can redistribute it and/or modify it |
854 | -# under the terms of the GNU General Public License version 3, as published |
855 | +# This program is free software: you can redistribute it and/or modify it |
856 | +# under the terms of the GNU General Public License version 3, as published |
857 | # by the Free Software Foundation. |
858 | -# |
859 | -# This program is distributed in the hope that it will be useful, but |
860 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
861 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
862 | +# |
863 | +# This program is distributed in the hope that it will be useful, but |
864 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
865 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
866 | # PURPOSE. See the GNU General Public License for more details. |
867 | -# |
868 | -# You should have received a copy of the GNU General Public License along |
869 | +# |
870 | +# You should have received a copy of the GNU General Public License along |
871 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
872 | ### END LICENSE |
873 | |
874 | |
875 | === modified file 'qreator/qrcodes/QRCodeVCard.py' |
876 | --- qreator/qrcodes/QRCodeVCard.py 2012-06-02 08:59:55 +0000 |
877 | +++ qreator/qrcodes/QRCodeVCard.py 2012-10-30 18:41:18 +0000 |
878 | @@ -14,7 +14,7 @@ |
879 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
880 | ### END LICENSE |
881 | |
882 | -from qreator_lib.helpers import get_media_file |
883 | +from qreator.tools import get_media_path |
884 | #from qreator_lib import QRCodeType as QRCodeType |
885 | from QRCodeVCardGtk import QRCodeVCardGtk |
886 | import vobject |
887 | @@ -22,7 +22,7 @@ |
888 | class QRCodeVCard(object): |
889 | def __init__(self, qr_code_update_func, icon_path, description, id): |
890 | self.qr_code_update_func = qr_code_update_func |
891 | - self.icon_path = get_media_file(icon_path) |
892 | + self.icon_path = get_media_path(icon_path) |
893 | self.description = description |
894 | self.id = id |
895 | |
896 | |
897 | === modified file 'qreator/qrcodes/QRCodeVCardGtk.py' |
898 | --- qreator/qrcodes/QRCodeVCardGtk.py 2012-06-09 00:06:51 +0000 |
899 | +++ qreator/qrcodes/QRCodeVCardGtk.py 2012-10-30 18:41:18 +0000 |
900 | @@ -1,16 +1,16 @@ |
901 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
902 | ### BEGIN LICENSE |
903 | -# Copyright (C) 2012 Stefan Schwarzburg <stefan.schwarzburg@googlemail.com> |
904 | -# This program is free software: you can redistribute it and/or modify it |
905 | -# under the terms of the GNU General Public License version 3, as published |
906 | +# Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
907 | +# This program is free software: you can redistribute it and/or modify it |
908 | +# under the terms of the GNU General Public License version 3, as published |
909 | # by the Free Software Foundation. |
910 | -# |
911 | -# This program is distributed in the hope that it will be useful, but |
912 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
913 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
914 | +# |
915 | +# This program is distributed in the hope that it will be useful, but |
916 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
917 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
918 | # PURPOSE. See the GNU General Public License for more details. |
919 | -# |
920 | -# You should have received a copy of the GNU General Public License along |
921 | +# |
922 | +# You should have received a copy of the GNU General Public License along |
923 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
924 | ### END LICENSE |
925 | |
926 | |
927 | === modified file 'qreator/qrcodes/QRCodeWifi.py' |
928 | --- qreator/qrcodes/QRCodeWifi.py 2012-05-30 08:33:06 +0000 |
929 | +++ qreator/qrcodes/QRCodeWifi.py 2012-10-30 18:41:18 +0000 |
930 | @@ -14,14 +14,14 @@ |
931 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
932 | ### END LICENSE |
933 | |
934 | -from qreator_lib.helpers import get_media_file |
935 | +from qreator.tools import get_media_path |
936 | #from qreator_lib import QRCodeType as QRCodeType |
937 | from QRCodeWifiGtk import QRCodeWifiGtk |
938 | |
939 | class QRCodeWifi(object): |
940 | def __init__(self, qr_code_update_func, icon_path, description, id): |
941 | self.qr_code_update_func = qr_code_update_func |
942 | - self.icon_path = get_media_file(icon_path) |
943 | + self.icon_path = get_media_path(icon_path) |
944 | self.description = description |
945 | self.id = id |
946 | |
947 | |
948 | === modified file 'qreator/qrcodes/QRCodeWifiGtk.py' |
949 | --- qreator/qrcodes/QRCodeWifiGtk.py 2012-05-30 10:19:57 +0000 |
950 | +++ qreator/qrcodes/QRCodeWifiGtk.py 2012-10-30 18:41:18 +0000 |
951 | @@ -1,16 +1,16 @@ |
952 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
953 | ### BEGIN LICENSE |
954 | # Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
955 | -# This program is free software: you can redistribute it and/or modify it |
956 | -# under the terms of the GNU General Public License version 3, as published |
957 | +# This program is free software: you can redistribute it and/or modify it |
958 | +# under the terms of the GNU General Public License version 3, as published |
959 | # by the Free Software Foundation. |
960 | -# |
961 | -# This program is distributed in the hope that it will be useful, but |
962 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
963 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
964 | +# |
965 | +# This program is distributed in the hope that it will be useful, but |
966 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
967 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
968 | # PURPOSE. See the GNU General Public License for more details. |
969 | -# |
970 | -# You should have received a copy of the GNU General Public License along |
971 | +# |
972 | +# You should have received a copy of the GNU General Public License along |
973 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
974 | ### END LICENSE |
975 | |
976 | |
977 | === added file 'qreator/tools.py' |
978 | --- qreator/tools.py 1970-01-01 00:00:00 +0000 |
979 | +++ qreator/tools.py 2012-10-30 18:41:18 +0000 |
980 | @@ -0,0 +1,9 @@ |
981 | +import os |
982 | +from qreator_lib.qreatorconfig import get_data_file |
983 | + |
984 | +def get_media_path(media_file_name): |
985 | + media_filename = get_data_file('media', '%s' % (media_file_name,)) |
986 | + if not os.path.exists(media_filename): |
987 | + media_filename = None |
988 | + |
989 | + return media_filename |
990 | |
991 | === added file 'qreator_lib/AboutDialog.py' |
992 | --- qreator_lib/AboutDialog.py 1970-01-01 00:00:00 +0000 |
993 | +++ qreator_lib/AboutDialog.py 2012-10-30 18:41:18 +0000 |
994 | @@ -0,0 +1,50 @@ |
995 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
996 | +### BEGIN LICENSE |
997 | +# Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
998 | +# This program is free software: you can redistribute it and/or modify it |
999 | +# under the terms of the GNU General Public License version 3, as published |
1000 | +# by the Free Software Foundation. |
1001 | +# |
1002 | +# This program is distributed in the hope that it will be useful, but |
1003 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
1004 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1005 | +# PURPOSE. See the GNU General Public License for more details. |
1006 | +# |
1007 | +# You should have received a copy of the GNU General Public License along |
1008 | +# with this program. If not, see <http://www.gnu.org/licenses/>. |
1009 | +### END LICENSE |
1010 | + |
1011 | +### DO NOT EDIT THIS FILE ### |
1012 | + |
1013 | +from gi.repository import Gtk # pylint: disable=E0611 |
1014 | + |
1015 | +from . helpers import get_builder |
1016 | + |
1017 | +class AboutDialog(Gtk.AboutDialog): |
1018 | + __gtype_name__ = "AboutDialog" |
1019 | + |
1020 | + def __new__(cls): |
1021 | + """Special static method that's automatically called by Python when |
1022 | + constructing a new instance of this class. |
1023 | + |
1024 | + Returns a fully instantiated AboutDialog object. |
1025 | + """ |
1026 | + builder = get_builder('AboutQreatorDialog') |
1027 | + new_object = builder.get_object("about_qreator_dialog") |
1028 | + new_object.finish_initializing(builder) |
1029 | + return new_object |
1030 | + |
1031 | + def finish_initializing(self, builder): |
1032 | + """Called while initializing this instance in __new__ |
1033 | + |
1034 | + finish_initalizing should be called after parsing the ui definition |
1035 | + and creating a AboutDialog object with it in order |
1036 | + to finish initializing the start of the new AboutQreatorDialog |
1037 | + instance. |
1038 | + |
1039 | + Put your initialization code in here and leave __init__ undefined. |
1040 | + """ |
1041 | + # Get a reference to the builder and set up the signals. |
1042 | + self.builder = builder |
1043 | + self.ui = builder.get_ui(self) |
1044 | + |
1045 | |
1046 | === modified file 'qreator_lib/Builder.py' |
1047 | --- qreator_lib/Builder.py 2012-05-19 14:45:57 +0000 |
1048 | +++ qreator_lib/Builder.py 2012-10-30 18:41:18 +0000 |
1049 | @@ -14,6 +14,8 @@ |
1050 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
1051 | ### END LICENSE |
1052 | |
1053 | +### DO NOT EDIT THIS FILE ### |
1054 | + |
1055 | '''Enhances builder connections, provides object to access glade objects''' |
1056 | |
1057 | from gi.repository import GObject, Gtk # pylint: disable=E0611 |
1058 | @@ -273,14 +275,14 @@ |
1059 | # Now, automatically find any the user didn't specify in glade |
1060 | for sig in signal_names: |
1061 | # using convention suggested by glade |
1062 | - sigpy = sig.replace("-", "_") |
1063 | - handler_names = ["on_%s_%s" % (widget_name, sigpy)] |
1064 | + sig = sig.replace("-", "_") |
1065 | + handler_names = ["on_%s_%s" % (widget_name, sig)] |
1066 | |
1067 | # Using the convention that the top level window is not |
1068 | # specified in the handler name. That is use |
1069 | # on_destroy() instead of on_windowname_destroy() |
1070 | if widget is callback_obj: |
1071 | - handler_names.append("on_%s" % sigpy) |
1072 | + handler_names.append("on_%s" % sig) |
1073 | |
1074 | do_connect(item, sig, handler_names, |
1075 | callback_handler_dict, builder.connections) |
1076 | |
1077 | === added file 'qreator_lib/PreferencesDialog.py' |
1078 | --- qreator_lib/PreferencesDialog.py 1970-01-01 00:00:00 +0000 |
1079 | +++ qreator_lib/PreferencesDialog.py 2012-10-30 18:41:18 +0000 |
1080 | @@ -0,0 +1,64 @@ |
1081 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
1082 | +### BEGIN LICENSE |
1083 | +# Copyright (C) 2012 David Planella <david.planella@ubuntu.com> |
1084 | +# This program is free software: you can redistribute it and/or modify it |
1085 | +# under the terms of the GNU General Public License version 3, as published |
1086 | +# by the Free Software Foundation. |
1087 | +# |
1088 | +# This program is distributed in the hope that it will be useful, but |
1089 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
1090 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1091 | +# PURPOSE. See the GNU General Public License for more details. |
1092 | +# |
1093 | +# You should have received a copy of the GNU General Public License along |
1094 | +# with this program. If not, see <http://www.gnu.org/licenses/>. |
1095 | +### END LICENSE |
1096 | + |
1097 | +### DO NOT EDIT THIS FILE ### |
1098 | + |
1099 | +"""this dialog adjusts values in gsettings |
1100 | +""" |
1101 | + |
1102 | +from gi.repository import Gtk # pylint: disable=E0611 |
1103 | +import logging |
1104 | +logger = logging.getLogger('qreator_lib') |
1105 | + |
1106 | +from . helpers import get_builder, show_uri, get_help_uri |
1107 | + |
1108 | +class PreferencesDialog(Gtk.Dialog): |
1109 | + __gtype_name__ = "PreferencesDialog" |
1110 | + |
1111 | + def __new__(cls): |
1112 | + """Special static method that's automatically called by Python when |
1113 | + constructing a new instance of this class. |
1114 | + |
1115 | + Returns a fully instantiated PreferencesDialog object. |
1116 | + """ |
1117 | + builder = get_builder('PreferencesQreatorDialog') |
1118 | + new_object = builder.get_object("preferences_qreator_dialog") |
1119 | + new_object.finish_initializing(builder) |
1120 | + return new_object |
1121 | + |
1122 | + def finish_initializing(self, builder): |
1123 | + """Called while initializing this instance in __new__ |
1124 | + |
1125 | + finish_initalizing should be called after parsing the ui definition |
1126 | + and creating a PreferencesDialog object with it in order to |
1127 | + finish initializing the start of the new PerferencesQreatorDialog |
1128 | + instance. |
1129 | + |
1130 | + Put your initialization code in here and leave __init__ undefined. |
1131 | + """ |
1132 | + |
1133 | + # Get a reference to the builder and set up the signals. |
1134 | + self.builder = builder |
1135 | + self.ui = builder.get_ui(self, True) |
1136 | + |
1137 | + # code for other initialization actions should be added here |
1138 | + |
1139 | + def on_btn_close_clicked(self, widget, data=None): |
1140 | + self.destroy() |
1141 | + |
1142 | + def on_btn_help_clicked(self, widget, data=None): |
1143 | + show_uri(self, "ghelp:%s" % get_help_uri('preferences')) |
1144 | + |
1145 | |
1146 | === modified file 'qreator_lib/Window.py' |
1147 | --- qreator_lib/Window.py 2012-05-19 14:45:57 +0000 |
1148 | +++ qreator_lib/Window.py 2012-10-30 18:41:18 +0000 |
1149 | @@ -14,11 +14,13 @@ |
1150 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
1151 | ### END LICENSE |
1152 | |
1153 | -from gi.repository import Gtk # pylint: disable=E0611 |
1154 | +### DO NOT EDIT THIS FILE ### |
1155 | + |
1156 | +from gi.repository import Gio, Gtk # pylint: disable=E0611 |
1157 | import logging |
1158 | logger = logging.getLogger('qreator_lib') |
1159 | |
1160 | -from . helpers import get_builder |
1161 | +from . helpers import get_builder, show_uri, get_help_uri |
1162 | |
1163 | # This class is meant to be subclassed by QreatorWindow. It provides |
1164 | # common functions and some boilerplate. |
1165 | @@ -60,8 +62,8 @@ |
1166 | self.preferences_dialog = None # instance |
1167 | self.AboutDialog = None # class |
1168 | |
1169 | - ##self.settings = Gio.Settings("net.launchpad.qreator") |
1170 | - ##self.settings.connect('changed', self.on_preferences_changed) |
1171 | + self.settings = Gio.Settings("net.launchpad.qreator") |
1172 | + self.settings.connect('changed', self.on_preferences_changed) |
1173 | |
1174 | # Optional application indicator support |
1175 | # Run 'quickly add indicator' to get started. |
1176 | @@ -76,6 +78,34 @@ |
1177 | except ImportError: |
1178 | pass |
1179 | |
1180 | + def on_mnu_contents_activate(self, widget, data=None): |
1181 | + show_uri(self, "ghelp:%s" % get_help_uri()) |
1182 | + |
1183 | + def on_mnu_about_activate(self, widget, data=None): |
1184 | + """Display the about box for qreator.""" |
1185 | + if self.AboutDialog is not None: |
1186 | + about = self.AboutDialog() # pylint: disable=E1102 |
1187 | + response = about.run() |
1188 | + about.destroy() |
1189 | + |
1190 | + def on_mnu_preferences_activate(self, widget, data=None): |
1191 | + """Display the preferences window for qreator.""" |
1192 | + |
1193 | + """ From the PyGTK Reference manual |
1194 | + Say for example the preferences dialog is currently open, |
1195 | + and the user chooses Preferences from the menu a second time; |
1196 | + use the present() method to move the already-open dialog |
1197 | + where the user can see it.""" |
1198 | + if self.preferences_dialog is not None: |
1199 | + logger.debug('show existing preferences_dialog') |
1200 | + self.preferences_dialog.present() |
1201 | + elif self.PreferencesDialog is not None: |
1202 | + logger.debug('create new preferences_dialog') |
1203 | + self.preferences_dialog = self.PreferencesDialog() # pylint: disable=E1102 |
1204 | + self.preferences_dialog.connect('destroy', self.on_preferences_dialog_destroyed) |
1205 | + self.preferences_dialog.show() |
1206 | + # destroy command moved into dialog to allow for a help button |
1207 | + |
1208 | def on_mnu_close_activate(self, widget, data=None): |
1209 | """Signal handler for closing the QreatorWindow.""" |
1210 | self.destroy() |
1211 | @@ -85,3 +115,15 @@ |
1212 | # Clean up code for saving application state should be added here. |
1213 | Gtk.main_quit() |
1214 | |
1215 | + def on_preferences_changed(self, settings, key, data=None): |
1216 | + logger.debug('preference changed: %s = %s' % (key, str(settings.get_value(key)))) |
1217 | + |
1218 | + def on_preferences_dialog_destroyed(self, widget, data=None): |
1219 | + '''only affects gui |
1220 | + |
1221 | + logically there is no difference between the user closing, |
1222 | + minimising or ignoring the preferences dialog''' |
1223 | + logger.debug('on_preferences_dialog_destroyed') |
1224 | + # to determine whether to create or present preferences_dialog |
1225 | + self.preferences_dialog = None |
1226 | + |
1227 | |
1228 | === modified file 'qreator_lib/__init__.py' |
1229 | --- qreator_lib/__init__.py 2012-05-19 14:45:57 +0000 |
1230 | +++ qreator_lib/__init__.py 2012-10-30 18:41:18 +0000 |
1231 | @@ -14,6 +14,8 @@ |
1232 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
1233 | ### END LICENSE |
1234 | |
1235 | +### DO NOT EDIT THIS FILE ### |
1236 | + |
1237 | '''facade - makes qreator_lib package easy to refactor |
1238 | |
1239 | while keeping its api constant''' |
1240 | |
1241 | === modified file 'qreator_lib/helpers.py' |
1242 | --- qreator_lib/helpers.py 2012-05-28 09:38:22 +0000 |
1243 | +++ qreator_lib/helpers.py 2012-10-30 18:41:18 +0000 |
1244 | @@ -14,6 +14,8 @@ |
1245 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
1246 | ### END LICENSE |
1247 | |
1248 | +### DO NOT EDIT THIS FILE ### |
1249 | + |
1250 | """Helpers for an Ubuntu application.""" |
1251 | import logging |
1252 | import os |
1253 | @@ -21,11 +23,12 @@ |
1254 | from . qreatorconfig import get_data_file |
1255 | from . Builder import Builder |
1256 | |
1257 | +from locale import gettext as _ |
1258 | |
1259 | def get_builder(builder_file_name): |
1260 | """Return a fully-instantiated Gtk.Builder instance from specified ui |
1261 | file |
1262 | - |
1263 | + |
1264 | :param builder_file_name: The name of the builder file, without extension. |
1265 | Assumed to be in the 'ui' directory under the data path. |
1266 | """ |
1267 | @@ -46,22 +49,19 @@ |
1268 | if not os.path.exists(media_filename): |
1269 | media_filename = None |
1270 | |
1271 | - return media_filename |
1272 | - |
1273 | + return "file:///"+media_filename |
1274 | |
1275 | class NullHandler(logging.Handler): |
1276 | def emit(self, record): |
1277 | pass |
1278 | |
1279 | - |
1280 | def set_up_logging(opts): |
1281 | # add a handler to prevent basicConfig |
1282 | root = logging.getLogger() |
1283 | null_handler = NullHandler() |
1284 | root.addHandler(null_handler) |
1285 | |
1286 | - formatter = logging.Formatter( |
1287 | - "%(levelname)s:%(name)s: %(funcName)s() '%(message)s'") |
1288 | + formatter = logging.Formatter("%(levelname)s:%(name)s: %(funcName)s() '%(message)s'") |
1289 | |
1290 | logger = logging.getLogger('qreator') |
1291 | logger_sh = logging.StreamHandler() |
1292 | @@ -80,7 +80,6 @@ |
1293 | if opts.verbose > 1: |
1294 | lib_logger.setLevel(logging.DEBUG) |
1295 | |
1296 | - |
1297 | def get_help_uri(page=None): |
1298 | # help_uri from source tree - default language |
1299 | here = os.path.dirname(__file__) |
1300 | @@ -96,13 +95,11 @@ |
1301 | |
1302 | return help_uri |
1303 | |
1304 | - |
1305 | def show_uri(parent, link): |
1306 | - from gi.repository import Gtk # pylint: disable=E0611 |
1307 | + from gi.repository import Gtk # pylint: disable=E0611 |
1308 | screen = parent.get_screen() |
1309 | Gtk.show_uri(screen, link, Gtk.get_current_event_time()) |
1310 | |
1311 | - |
1312 | def alias(alternative_function_name): |
1313 | '''see http://www.drdobbs.com/web-development/184406073#l9''' |
1314 | def decorator(function): |
1315 | |
1316 | === modified file 'qreator_lib/qreatorconfig.py' |
1317 | --- qreator_lib/qreatorconfig.py 2012-05-28 09:38:22 +0000 |
1318 | +++ qreator_lib/qreatorconfig.py 2012-10-30 18:41:18 +0000 |
1319 | @@ -14,10 +14,7 @@ |
1320 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
1321 | ### END LICENSE |
1322 | |
1323 | -# THIS IS Qreator CONFIGURATION FILE |
1324 | -# YOU CAN PUT THERE SOME GLOBAL VALUE |
1325 | -# Do not touch unless you know what you're doing. |
1326 | -# you're warned :) |
1327 | +### DO NOT EDIT THIS FILE ### |
1328 | |
1329 | __all__ = [ |
1330 | 'project_path_not_found', |
1331 | @@ -33,6 +30,7 @@ |
1332 | |
1333 | import os |
1334 | |
1335 | +from locale import gettext as _ |
1336 | |
1337 | class project_path_not_found(Exception): |
1338 | """Raised when we can't find the project directory.""" |
1339 | |
1340 | === modified file 'setup.py' |
1341 | --- setup.py 2012-05-28 11:15:51 +0000 |
1342 | +++ setup.py 2012-10-30 18:41:18 +0000 |
1343 | @@ -15,7 +15,7 @@ |
1344 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
1345 | ### END LICENSE |
1346 | |
1347 | -###################### DO NOT TOUCH THIS (HEAD TO THE SECOND PART) ########### |
1348 | +###################### DO NOT TOUCH THIS (HEAD TO THE SECOND PART) ###################### |
1349 | |
1350 | import os |
1351 | import sys |
1352 | @@ -27,16 +27,16 @@ |
1353 | sys.exit(1) |
1354 | assert DistUtilsExtra.auto.__version__ >= '2.18', 'needs DistUtilsExtra.auto >= 2.18' |
1355 | |
1356 | - |
1357 | -def update_config(values = {}): |
1358 | - |
1359 | +def update_config(libdir, values = {}): |
1360 | + |
1361 | + filename = os.path.join(libdir, 'qreator_lib/qreatorconfig.py') |
1362 | oldvalues = {} |
1363 | try: |
1364 | - fin = file('qreator_lib/qreatorconfig.py', 'r') |
1365 | - fout = file(fin.name + '.new', 'w') |
1366 | + fin = file(filename, 'r') |
1367 | + fout = file(filename + '.new', 'w') |
1368 | |
1369 | for line in fin: |
1370 | - fields = line.split(' = ') # Separate variable from value |
1371 | + fields = line.split(' = ') # Separate variable from value |
1372 | if fields[0] in values: |
1373 | oldvalues[fields[0]] = fields[1].strip() |
1374 | line = "%s = %s\n" % (fields[0], values[fields[0]]) |
1375 | @@ -47,42 +47,92 @@ |
1376 | fin.close() |
1377 | os.rename(fout.name, fin.name) |
1378 | except (OSError, IOError), e: |
1379 | - print ("ERROR: Can't find qreator_lib/qreatorconfig.py") |
1380 | + print ("ERROR: Can't find %s" % filename) |
1381 | sys.exit(1) |
1382 | return oldvalues |
1383 | |
1384 | |
1385 | -def update_desktop_file(datadir): |
1386 | +def move_desktop_file(root, target_data, prefix): |
1387 | + # The desktop file is rightly installed into install_data. But it should |
1388 | + # always really be installed into prefix, because while we can install |
1389 | + # normal data files anywhere we want, the desktop file needs to exist in |
1390 | + # the main system to be found. Only actually useful for /opt installs. |
1391 | + |
1392 | + old_desktop_path = os.path.normpath(root + target_data + |
1393 | + '/share/applications') |
1394 | + old_desktop_file = old_desktop_path + '/qreator.desktop' |
1395 | + desktop_path = os.path.normpath(root + prefix + '/share/applications') |
1396 | + desktop_file = desktop_path + '/qreator.desktop' |
1397 | + |
1398 | + if not os.path.exists(old_desktop_file): |
1399 | + print ("ERROR: Can't find", old_desktop_file) |
1400 | + sys.exit(1) |
1401 | + elif target_data != prefix + '/': |
1402 | + # This is an /opt install, so rename desktop file to use extras- |
1403 | + desktop_file = desktop_path + '/extras-qreator.desktop' |
1404 | + try: |
1405 | + os.makedirs(desktop_path) |
1406 | + os.rename(old_desktop_file, desktop_file) |
1407 | + os.rmdir(old_desktop_path) |
1408 | + except OSError as e: |
1409 | + print ("ERROR: Can't rename", old_desktop_file, ":", e) |
1410 | + sys.exit(1) |
1411 | + |
1412 | + return desktop_file |
1413 | + |
1414 | +def update_desktop_file(filename, target_pkgdata, target_scripts): |
1415 | |
1416 | try: |
1417 | - fin = file('qreator.desktop.in', 'r') |
1418 | - fout = file(fin.name + '.new', 'w') |
1419 | + fin = file(filename, 'r') |
1420 | + fout = file(filename + '.new', 'w') |
1421 | |
1422 | for line in fin: |
1423 | if 'Icon=' in line: |
1424 | - line = "Icon=%s\n" % (datadir + 'media/qreator.svg') |
1425 | + line = "Icon=%s\n" % (target_pkgdata + 'media/qreator.svg') |
1426 | + elif 'Exec=' in line: |
1427 | + cmd = line.split("=")[1].split(None, 1) |
1428 | + line = "Exec=%s" % (target_scripts + 'qreator') |
1429 | + if len(cmd) > 1: |
1430 | + line += " %s" % cmd[1].strip() # Add script arguments back |
1431 | + line += "\n" |
1432 | fout.write(line) |
1433 | fout.flush() |
1434 | fout.close() |
1435 | fin.close() |
1436 | os.rename(fout.name, fin.name) |
1437 | except (OSError, IOError), e: |
1438 | - print ("ERROR: Can't find qreator.desktop.in") |
1439 | + print ("ERROR: Can't find %s" % filename) |
1440 | sys.exit(1) |
1441 | |
1442 | +def compile_schemas(root, target_data): |
1443 | + if target_data == '/usr/': |
1444 | + return # /usr paths don't need this, they will be handled by dpkg |
1445 | + schemadir = os.path.normpath(root + target_data + 'share/glib-2.0/schemas') |
1446 | + if (os.path.isdir(schemadir) and |
1447 | + os.path.isfile('/usr/bin/glib-compile-schemas')): |
1448 | + os.system('/usr/bin/glib-compile-schemas "%s"' % schemadir) |
1449 | + |
1450 | |
1451 | class InstallAndUpdateDataDirectory(DistUtilsExtra.auto.install_auto): |
1452 | def run(self): |
1453 | - values = {'__qreator_data_directory__': "'%s'" % (self.prefix + '/share/qreator/'), |
1454 | + DistUtilsExtra.auto.install_auto.run(self) |
1455 | + |
1456 | + target_data = '/' + os.path.relpath(self.install_data, self.root) + '/' |
1457 | + target_pkgdata = target_data + 'share/qreator/' |
1458 | + target_scripts = '/' + os.path.relpath(self.install_scripts, self.root) + '/' |
1459 | + |
1460 | + values = {'__qreator_data_directory__': "'%s'" % (target_pkgdata), |
1461 | '__version__': "'%s'" % self.distribution.get_version()} |
1462 | - previous_values = update_config(values) |
1463 | - update_desktop_file(self.prefix + '/share/qreator/') |
1464 | - DistUtilsExtra.auto.install_auto.run(self) |
1465 | - update_config(previous_values) |
1466 | - |
1467 | -############################################################################## |
1468 | -###################### YOU SHOULD MODIFY ONLY WHAT IS BELOW ################## |
1469 | -############################################################################## |
1470 | + update_config(self.install_lib, values) |
1471 | + |
1472 | + desktop_file = move_desktop_file(self.root, target_data, self.prefix) |
1473 | + update_desktop_file(desktop_file, target_pkgdata, target_scripts) |
1474 | + compile_schemas(self.root, target_data) |
1475 | + |
1476 | + |
1477 | +######################################################################################### |
1478 | +###################### YOU SHOULD MODIFY ONLY WHAT IS BELOW ############################# |
1479 | +######################################################################################### |
1480 | |
1481 | DistUtilsExtra.auto.setup( |
1482 | name='qreator', |
Thanks again for this feature!
I'm planning to do the thorough review that it deserves, but for now, after having tested if from a user point of view (i.e. not having looked at the code yet), here are a few things that I've noticed:
- The Call/SMS/MMS dropdown needs a label on the right, to keep consistency with the other code type layouts (e.g. VCard, Wifi, etc) and not leave an empty space. It could simply be "Type:" for example.
- The extra space for the exclamation sign next to the 'Message:' text box in the 'SMS:' or 'MMS:' types should be taken into account in the 'Call:' type, so that when switching from one type to another we don't have widget sizes moving around. In fact, it should either be put inside the textbox, or next to it on the right, as we do with the VCard code
- The exclamation mark icon should be the same one as we use for the VCard code
- I could not manage to make the exclamation mark go away in the 'SMS:' type, even after having entered a correct phone number and message
- [Optional] we should probably only allow numbers and the '+' sign in the Number text box
- [Optional, discussion] shall we have a multi-line textbox to enter the message in SMS?
- [Optional, discussion] I could not see any noticeable difference between the SMS and MMS types. Do you think we really need MMS?, do people still use them?