19
from gi.repository import Gtk, Gdk, GdkPixbuf, GLib # pylint: disable=E0611
20
from gi.repository import GtkChamplain, Clutter, Champlain
21
from gi.repository import NetworkManager, NMClient
19
from gi.repository import Gtk, Gdk, GdkPixbuf # pylint: disable=E0611
23
21
logger = logging.getLogger('qreator')
25
23
from qreator_lib.i18n import _
26
24
from qreator_lib import Window
27
from qreator_lib.helpers import get_media_file as get_media_file
30
sys.path.insert(0, "/usr/share/software-center/")
31
import softwarecenter.db.database
34
from QRCode import QRCode as QRCode
35
from QRCode import QRCodeOutput as QRCodeOutput
25
from qreator_lib.helpers import get_media_file
27
from QRCode import QRCode
28
from QRCode import QRCodeOutput
68
60
# Hide the notebook tabs
69
61
self.ui.notebook1.set_show_tabs(False)
71
# Initialize combo boxes
72
self.ui.comboboxtextSecurity.set_active(0)
73
self.ui.comboboxtextProtocol.set_active(0)
75
# Initialize placeholder text (we need to do that because due to
76
# a Glade bug they are otherwise not marked as translatable)
77
self.ui.entryURL.set_placeholder_text(_('[URL]'))
78
# TRANSLATORS: 'expand' refers to expanding the drop-down menu
79
# that shows autodetected wireless network identifiers
80
self.ui.entrySSID.set_placeholder_text(
81
_('[Network identifier - expand for autodetection]'))
82
self.ui.entryPassword.set_placeholder_text(_('[Network password]'))
84
63
# Initialize about dialog
85
about = Gtk.AboutDialog()
86
about.set_program_name("Qreator")
88
"Copyright (c) 2012 David Planella" +
89
"\nhttp://about.me/david.planella")
90
about.set_website("https://launchpad.net/qreator")
92
about.set_version('12.05.6')
94
'David Planella <david.planella@ubuntu.com>',
95
'Michael Hall <mhall119@ubuntu.com>',
96
'Andrew Starr-Bochicchio <andrewsomething@ubuntu.com >',
98
about.set_license(_('Distributed under the GPL v3 license.') +
99
'\nhttp://www.opensource.org/licenses/gpl-3.0.html')
101
about.set_translator_credits(_("translator-credits"))
103
box = builder.get_object("about_box")
104
about.vbox.reparent(box)
106
# Get rid of the 'Close' button
107
for button in about.action_area.get_children():
108
if button.get_property('label') == 'gtk-close':
111
# Initialize the Software Center apps autocompletion
112
self.softwarecenterapps = None
114
self.usc_apps_complete = Complete()
116
self.usc_apps_complete.set_hexpand(True)
117
self.usc_apps_complete.connect("changed",
118
self.on_usc_apps_complete_changed, None)
119
self.usc_apps_complete.connect("icon-press",
120
self.on_usc_apps_complete_icon_pressed)
121
self.usc_apps_complete.set_icon_from_icon_name(
122
Gtk.EntryIconPosition.PRIMARY, 'edit-find-symbolic')
123
self.usc_apps_complete.set_icon_from_stock(
124
Gtk.EntryIconPosition.SECONDARY, None)
126
#self.get_softwarecenterapps()
127
#self.on_get_softwarecenterapps()
128
#deferred = defer.defer(self.get_softwarecenterapps)
129
#deferred.add_callback(self.on_get_softwarecenterapps)
131
self.ui.qr_app.attach(self.usc_apps_complete, 1, 0, 1, 1)
132
self.softwarecenter_apps_init = False
134
# Load the background texture
64
self.init_about_dialog()
66
# Initialize the QR types icon view
69
# Load the background texture in the QR code page
135
70
self.texture = cairo.ImageSurface.create_from_png(
136
71
get_media_file("pattern.png"))
73
# Add an initial text, so that there is an initial QR code
74
self.qr_code_placeholder = 'http://launchpad.net/qreator'
76
def init_qr_types(self):
138
77
# Set up the QR types shown in the main icon view
139
78
self.ui.qr_types_view.set_text_column(COL_DESC)
140
79
self.ui.qr_types_view.set_pixbuf_column(COL_PIXBUF)
81
from qrcodes.QRCodeText import QRCodeText
82
from qrcodes.QRCodeURL import QRCodeURL
83
from qrcodes.QRCodeLocation import QRCodeLocation
84
from qrcodes.QRCodeWifi import QRCodeWifi
85
from qrcodes.QRCodeSoftwareCenterApp import QRCodeSoftwareCenterApp
144
'icon': GdkPixbuf.Pixbuf.new_from_file(get_media_file(
146
'callback': 'on_qr_url_clicked'},
148
'icon': GdkPixbuf.Pixbuf.new_from_file(get_media_file(
150
'callback': 'on_qr_text_clicked'},
151
{'desc': _('Geolocation'),
152
'icon': GdkPixbuf.Pixbuf.new_from_file(get_media_file(
154
'callback': 'on_qr_location_clicked'},
155
{'desc': _('Wifi network'),
156
'icon': GdkPixbuf.Pixbuf.new_from_file(get_media_file(
158
'callback': 'on_qr_wifi_clicked'},
159
{'desc': _('Ubuntu Software Center app'),
160
'icon': GdkPixbuf.Pixbuf.new_from_file(get_media_file(
161
'softwarecentre.png')),
162
'callback': 'on_qr_softwarecenterapp_clicked'},
88
QRCodeURL(self.update_qr_code, 'url.png', _('URL'), 0),
89
QRCodeText(self.update_qr_code, 'text.png', _('Text'), 1),
90
QRCodeLocation(self.update_qr_code, 'location.png',
92
QRCodeWifi(self.update_qr_code, 'wifi.png', _('Wifi network'), 3),
93
QRCodeSoftwareCenterApp(self.update_qr_code, 'softwarecentre.png',
94
_('Ubuntu Software Center app'), 4),
165
self.qr_types_store = Gtk.ListStore(str, GdkPixbuf.Pixbuf, str)
166
# ^ desc, icon, callback ^
97
self.qr_types_store = Gtk.ListStore(str, GdkPixbuf.Pixbuf, int)
167
99
self.qr_types_store.set_sort_column_id(COL_DESC,
168
100
Gtk.SortType.ASCENDING)
169
101
self.ui.qr_types_view.set_model(self.qr_types_store)
172
104
self.curr_height = 0
173
105
self.curr_width = 0
175
# Add an initial text, so that there is an initial QR code
176
self.qr_code_placeholder = 'http://launchpad.net/qreator'
178
def on_usc_apps_complete_icon_pressed(self, widget, icon, mouse_button):
179
self._clear_text_entry(widget, icon)
181
def _clear_text_entry(self, widget, icon):
182
if icon == Gtk.EntryIconPosition.SECONDARY:
184
self._check_style(widget)
186
elif icon == Gtk.EntryIconPosition.PRIMARY:
187
widget.select_region(0, -1)
190
def _check_style(self, widget):
192
Show the clear icon whenever the field is not empty
194
if widget.get_text() != "":
195
widget.set_icon_from_stock(Gtk.EntryIconPosition.SECONDARY,
197
# reverse the icon if we are in an rtl environment
198
if widget.get_direction() == Gtk.TextDirection.RTL:
199
pb = widget.get_icon_pixbuf(
200
Gtk.EntryIconPosition.SECONDARY).flip(True)
201
widget.set_icon_from_pixbuf(Gtk.EntryIconPosition.SECONDARY,
204
widget.set_icon_from_stock(Gtk.EntryIconPosition.SECONDARY, None)
206
def init_softwarecenter_apps(self):
207
deferred = defer.defer(self.get_softwarecenterapps)
208
deferred.add_callback(self.on_get_softwarecenterapps)
209
self.softwarecenter_apps_init = True
107
for qr_type in self.qr_types:
108
self.ui.qr_input_notebook.append_page(qr_type.widget.grid, None)
211
110
def fill_qr_types_store(self):
212
111
self.qr_types_store.clear()
214
113
for qr_type in self.qr_types:
215
self.qr_types_store.append([qr_type['desc'],
217
qr_type['callback']])
114
icon = GdkPixbuf.Pixbuf.new_from_file(get_media_file(
116
self.qr_types_store.append([qr_type.description,
219
120
def on_qreator_window_check_resize(self, widget):
220
121
'''We need this function to fix the issue described at
232
133
# and refill iconviews with icons to adjust columns number
233
134
self.fill_qr_types_store()
235
def on_entryText_changed(self, widget, data=None):
236
self.update_qr_code(widget.get_text(widget.get_start_iter(),
237
widget.get_end_iter(),
240
def on_map_widget_button_press_event(self, actor, event, view):
241
x, y = event.get_coords()
242
lat, lon = view.x_to_longitude(x), view.y_to_latitude(y)
244
self.ui.lat_entry.set_text(str(lat))
245
self.ui.lon_entry.set_text(str(lon))
247
self.update_qr_code('geo:{0},{1}'.format(str(lon), str(lat)))
136
def init_about_dialog(self):
137
# Initialize about dialog
138
about = Gtk.AboutDialog()
139
about.set_program_name("Qreator")
141
"Copyright (c) 2012 David Planella" +
142
"\nhttp://about.me/david.planella")
143
about.set_website("https://launchpad.net/qreator")
145
about.set_version('12.05.6')
147
'David Planella <david.planella@ubuntu.com>',
148
'Michael Hall <mhall119@ubuntu.com>',
149
'Andrew Starr-Bochicchio <andrewsomething@ubuntu.com >',
151
about.set_license(_('Distributed under the GPL v3 license.') +
152
'\nhttp://www.opensource.org/licenses/gpl-3.0.html')
154
about.set_translator_credits(_("translator-credits"))
156
box = self.ui.about_box
157
about.vbox.reparent(box)
159
# Get rid of the 'Close' button
160
for button in about.action_area.get_children():
161
if button.get_property('label') == 'gtk-close':
164
##########################################
251
166
def on_toolbuttonNew_clicked(self, widget, data=None):
252
167
'''Shows the home page'''
256
171
'''Shows the history page'''
257
172
pass # self.ui.notebook1.set_current_page(PAGE_HISTORY)
259
def on_toolbuttonSettings_clicked(self, widget, data=None):
260
'''Shows the settings page'''
261
pass # self.ui.notebook1.set_current_page(PAGE_SETTINGS)
263
174
def on_toolbuttonAbout_clicked(self, widget, data=None):
264
175
'''Shows the about page'''
265
176
self.ui.notebook1.set_current_page(PAGE_ABOUT)
267
def _hide_children(self, widget):
268
for child in widget.get_children():
271
def on_qr_url_clicked(self):
272
self._hide_children(self.ui.qr_input)
273
self.ui.qr_url.show_all()
275
def on_qr_wifi_clicked(self):
276
self._hide_children(self.ui.qr_input)
277
self.ui.qr_wifi.show_all()
281
self.ui.comboboxtextSSID.append_text(ssid)
283
def on_qr_softwarecenterapp_clicked(self):
284
# We're now loading the UI for the Software Center app QR type
285
self._hide_children(self.ui.qr_input)
286
self.ui.qr_app.show_all()
287
if not self.softwarecenter_apps_init:
288
GLib.idle_add(self.init_softwarecenter_apps)
290
def on_qr_text_clicked(self):
291
# Initialize multi-line text entry
292
textbuffer = self.ui.entryText.get_buffer()
293
textbuffer.connect("changed", self.on_entryText_changed, None)
295
self._hide_children(self.ui.qr_input)
296
self.ui.qr_text.show_all()
298
def on_qr_location_clicked(self):
299
# We're now loading the UI for the location QR type
300
self._hide_children(self.ui.qr_input)
301
self.ui.qr_location.show_all()
303
map_widget = GtkChamplain.Embed()
304
map_widget.set_hexpand(True)
305
map_widget.set_vexpand(True)
307
map_grid = self.ui.qr_location
309
map_grid.set_size_request(-1, 250)
310
map_grid.attach(map_widget, 0, 0, 1, 1)
312
self.map_view = map_widget.get_view()
313
self.map_view.set_reactive(True)
314
map_widget.connect('button-release-event',
315
self.on_map_widget_button_press_event,
318
# Get the current location, center the map on it, and initialize
320
latitude, longitude = get_current_location()
321
self.map_view.center_on(latitude, longitude)
322
if latitude == 0 and longitude == 0:
323
# In case something went wrong in getting the current location
324
self.map_view.set_zoom_level(1)
326
self.map_view.set_zoom_level(15)
327
self.map_view.set_kinetic_mode(True)
329
scale = Champlain.Scale()
330
scale.connect_view(self.map_view)
331
self.map_view.bin_layout_add(scale, Clutter.BinAlignment.START,
332
Clutter.BinAlignment.END)
334
self.ui.qr_location.show_all()
178
##########################################
336
180
def on_qr_types_view_item_activated(self, widget, item):
337
181
'''Loads the UI for the appropriate QR type'''
339
183
model = widget.get_model()
340
qr_callback = getattr(QreatorWindow, model[item][COL_CALLBACK])
184
qr_id = model[item][COL_ID]
185
self.qr_types[qr_id].widget.on_activated()
344
187
self.ui.notebook1.set_current_page(PAGE_QR)
188
self.ui.qr_input_notebook.set_current_page(qr_id)
190
##########################################
346
192
def get_pixbuf_from_drawing_area(self):
347
193
window = self.ui.qr_drawingarea.get_window()
391
239
pixbuf = self.get_pixbuf_from_drawing_area()
392
240
self.clipboard.set_image(pixbuf)
242
##########################################
394
244
def update_qr_code(self, text):
395
245
self.qr_code_placeholder = text
396
246
self.ui.qr_drawingarea.queue_draw()
398
def on_usc_apps_complete_changed(self, widget, data=None):
399
self._check_style(widget)
400
USC_APPS_BASE_URL = 'https://apps.ubuntu.com/cat/applications/'
401
self.update_qr_code(USC_APPS_BASE_URL + widget.get_text())
403
def on_entryURL_icon_press(self, widget, icon, mouse_button):
404
self._clear_text_entry(widget, icon)
406
def on_entryURL_changed(self, widget, data=None):
407
self._check_style(widget)
408
self.update_url_qr_code(www=widget.get_text())
410
def on_comboboxtextProtocol_changed(self, widget, data=None):
411
self.update_url_qr_code(protocol=widget.get_active_text())
413
def update_url_qr_code(self, protocol=None, www=None):
415
protocol = self.ui.comboboxtextProtocol.get_active_text()
417
www = self.ui.entryURL.get_text()
419
if not protocol or www == '':
422
self.update_qr_code(protocol + www)
424
def update_wifi_qr_code(self, security=None, ssid=None, password=None):
426
security = self.ui.comboboxtextSecurity.get_active_text()
428
ssid = self.ui.entrySSID.get_text()
430
password = self.ui.entryPassword.get_text()
432
if not security or ssid == '' or password == '':
435
wifi_qr_code = 'WIFI:T:{0};S:{1};P:{2};;'.format(security, ssid,
437
self.update_qr_code(wifi_qr_code)
439
def on_comboboxtextSecurity_changed(self, widget, data=None):
440
self.update_wifi_qr_code(security=widget.get_active_text())
442
def on_entrySSID_icon_press(self, widget, icon, mouse_button):
443
self._clear_text_entry(widget, icon)
445
def on_comboboxtextSSID_changed(self, widget, data=None):
446
self._check_style(self.ui.entrySSID)
447
self.update_wifi_qr_code(ssid=widget.get_active_text())
449
def on_entryPassword_icon_press(self, widget, icon, mouse_button):
450
self._clear_text_entry(widget, icon)
452
def on_entryPassword_changed(self, widget, data=None):
453
self._check_style(widget)
454
self.update_wifi_qr_code(password=widget.get_text())
456
def on_checkbutton1_clicked(self, widget):
457
if widget.get_active():
458
self.ui.entryPassword.set_visibility(True)
460
self.ui.entryPassword.set_visibility(False)
462
248
def get_centered_coordinates(self, drawing_area, surface):
464
250
drawing_area_height = drawing_area.get_allocated_height()
525
311
# Render the image
528
def get_softwarecenterapps(self):
529
print 'Task STARTED!'
530
db = softwarecenter.db.database.StoreDatabase()
532
db.open(use_axi=False, use_agent=False)
535
app = db.get_application(doc)
536
appdetails = app.get_details(db)
537
appinfo = App(app.appname, app.pkgname, appdetails.icon)
539
self.softwarecenterapps = apps
542
def on_get_softwarecenterapps(self, result):
543
print 'Task FINISHED!'
544
self.usc_apps_complete.add(self.softwarecenterapps)
547
def get_current_location():
548
'''Gets the current location from geolocation via IP (only method
549
currently supported)'''
551
#POS_PROVIDER = 'Ubuntu GeoIP'
552
#location = Geoclue.DiscoverLocation()
554
#location.set_position_provider(POS_PROVIDER)
555
#position = location.get_location_info()
558
bus = dbus.SessionBus()
559
geoclue = bus.get_object(
560
'org.freedesktop.Geoclue.Providers.UbuntuGeoIP',
561
'/org/freedesktop/Geoclue/Providers/UbuntuGeoIP')
562
position_info = geoclue.GetPosition(
563
dbus_interface='org.freedesktop.Geoclue.Position')
566
position['timestamp'] = position_info[1]
567
position['latitude'] = position_info[2]
568
position['longitude'] = position_info[3]
569
position['altitude'] = position_info[4]
571
return position['latitude'], position['longitude']
575
nmc = NMClient.Client.new()
576
devs = nmc.get_devices()
580
if dev.get_device_type() == NetworkManager.DeviceType.WIFI:
581
for ap in dev.get_access_points():
582
ssids.append(ap.get_ssid())
588
def __init__(self, name, package, icon):
590
self.package = package
594
class Complete(Gtk.Entry):
595
'''a class to autocomplete'''
597
def __init__(self, apps=None):
598
Gtk.Entry.__init__(self)
599
self.completion = Gtk.EntryCompletion()
600
self.set_completion(self.completion)
601
self.model = Gtk.ListStore(str, GdkPixbuf.Pixbuf, str)
602
self.completion.set_model(self.model)
603
self.completion_img = Gtk.CellRendererPixbuf()
604
self.completion.pack_start(self.completion_img, True)
605
self.completion.add_attribute(self.completion_img, "pixbuf", 1)
606
self.completion.set_text_column(0)
607
self.completion.set_popup_set_width(False)
608
self.completion.set_inline_completion(True)
609
self.icons = Gtk.IconTheme.get_default()
610
self.icons.append_search_path("/usr/share/app-install/icons/")
615
# TRANSLATORS: this message appears for a few seconds on the
616
# Software Center apps text entry until the app names to
617
# suggest for autocompletion have been read from the Software
619
self.set_placeholder_text(
620
_('[Wait a few seconds to enable autocompletion...]'))
625
self.set_placeholder_text(
626
_('[Type the name of an app]'))
628
def _remember(self, app):
629
'''Add a value to the list of strings to suggest'''
631
icon = self.icons.load_icon(
632
"{0}".format(app.icon),
633
16, Gtk.IconLookupFlags.USE_BUILTIN)
635
icon = self.icons.load_icon(
637
16, Gtk.IconLookupFlags.USE_BUILTIN)
638
self.model.append([app.package, icon, app.name])