~nik90/ubuntu/precise/software-center/add_keywords

« back to all changes in this revision

Viewing changes to softwarecenter/ui/gtk3/views/appdetailsview.py

  • Committer: Package Import Robot
  • Author(s): Michael Vogt, Michael Vogt, Brendan Donegan, Gary Lasker
  • Date: 2012-02-03 18:34:43 UTC
  • Revision ID: package-import@ubuntu.com-20120203183443-1r39x52ozrb1revz
Tags: 5.1.8
[ Michael Vogt ]
* softwarecenter/db/update.py:
  - trivial fix to skip unreadable app-install-data files
* lp:~mvo/software-center/device-profiles:
  - implement the hardware-requirements display in
    the detailsview
* lp:~mvo/software-center/arb-partner-channels:
  - add support for extras.ubuntu.com and archive.canonical.com
    channel detection and adding via software-center-agent
* data/software-center.menu.in:
  - do not show "X-Publishing" in education because the
    software-center-agent will send "X-Publishing;Education" for
    compatibility with the old clients
* lp:~mvo/software-center/fix-cachedir-for-public-api:
  - add missing cachedir argument
* lp:~mvo/software-center/region-support:
  - add support for a region tag and display a warning to
    the user if an application is not suitable for their
    region

[ Brendan Donegan ]
* lp:~brendan-donegan/software-center/test_utils_get_nice_date_string:
  - add a test function in test_utils.py which covers all of
    get_nice_date_string

[ Gary Lasker ]
* lp:~gary-lasker/software-center/launcher-integration-lp761851:
  - update to the Unity launcher integration implementation to
    support the revamped functionality on the Unity side (LP: #761851) 
* lp:~gary-lasker/software-center/recommends-ui-lobby:
  - initial recommends UI implementation, limited to non-personalized
    recommends currently
* lp:~gary-lasker/software-center/appdetailsview-button-focus-fix:
  - make sure the action button in the applications details view
    always gets the initial focus (LP: #925613)

Show diffs side-by-side

added added

removed removed

Lines of Context:
53
53
from softwarecenter.ui.gtk3.em import StockEms, em
54
54
from softwarecenter.ui.gtk3.drawing import color_to_hex
55
55
from softwarecenter.ui.gtk3.session.appmanager import get_appmanager
 
56
from softwarecenter.ui.gtk3.widgets.labels import HardwareRequirementsBox
56
57
from softwarecenter.ui.gtk3.widgets.separators import HBar
57
58
from softwarecenter.ui.gtk3.widgets.viewport import Viewport
58
59
from softwarecenter.ui.gtk3.widgets.reviews import UIReviewsList
66
67
 
67
68
import softwarecenter.ui.gtk3.dialogs as dialogs
68
69
 
 
70
from softwarecenter.hw import get_hw_missing_long_description
 
71
from softwarecenter.region import REGION_WARNING_STRING
 
72
 
69
73
from softwarecenter.backend.reviews import get_review_loader
70
74
from softwarecenter.backend import get_install_backend
71
75
 
86
90
        self.add(self.hbox)
87
91
 
88
92
        self.view = view
 
93
        # default bg
 
94
        self._bg = [1, 1, 1, 0.3]
89
95
 
90
96
        self.connect("style-updated", self.on_style_updated)
91
97
        return
105
111
 
106
112
        # fill bg
107
113
        cr.rectangle(-width, 0, a.width+2*width, a.height)
108
 
        cr.set_source_rgba(1, 1, 1, 0.3)
 
114
        cr.set_source_rgba(*self._bg)
109
115
        cr.fill_preserve()
110
116
 
111
117
        # paint dashed top/bottom borders
124
130
        for child in self: 
125
131
            self.propagate_draw(child, cr)
126
132
 
 
133
class WarningStatusBar(StatusBar):
 
134
 
 
135
    def __init__(self, view):
 
136
        StatusBar.__init__(self, view)
 
137
        self.label = Gtk.Label()
 
138
        self.label.set_line_wrap(True)
 
139
        self.label.set_alignment(0.0, 0.5)
 
140
        self.warn = Gtk.Label()
 
141
        self.warn.set_markup(
 
142
            '<span foreground="red" size="x-large">%s</span>' % u'\u26A0')
 
143
        self.hbox.pack_start(self.label, True, True, 0)
 
144
        self.hbox.pack_end(self.warn, False, False, 0)
 
145
        # override _bg
 
146
        self._bg = [1, 1, 0, 0.3]
127
147
 
128
148
class PackageStatusBar(StatusBar):
129
149
    """ Package specific status bar that contains a state label,
193
213
        self.label.set_markup(m)
194
214
        return
195
215
 
 
216
    def get_label(self):
 
217
        return self.label.get_text()
 
218
 
196
219
    def set_button_label(self, label):
197
220
        self.button.set_label(label)
198
221
        return
 
222
    
 
223
    def get_button_label(self):
 
224
        return self.button.get_label()
199
225
 
200
226
    def configure(self, app_details, state):
201
227
        LOG.debug("configure %s state=%s pkgstate=%s" % (
283
309
            #        won't vary based on locale and as such we don't want
284
310
            #        it translated
285
311
            self.set_label("US$ %s" % app_details.price)
286
 
            self.set_button_label(_(u'Buy\u2026'))
 
312
            if (app_details.hardware_requirements_satisfied and
 
313
                app_details.region_requirements_satisfied):
 
314
                self.set_button_label(_(u'Buy\u2026'))
 
315
            else:
 
316
                self.set_button_label(_(u'Buy Anyway\u2026'))
287
317
        elif state in (
288
318
            PkgStates.PURCHASED_BUT_REPO_MUST_BE_ENABLED,
289
319
            PkgStates.PURCHASED_BUT_NOT_AVAILABLE_FOR_SERIES):
310
340
            if app_details.pkgname== SOFTWARE_CENTER_PKGNAME:
311
341
                self.set_label(_("Removed (close it and it'll be gone)"))
312
342
            else:
313
 
                if app_details.price:
314
 
                    self.set_label(app_details.price)
315
 
                else:
316
 
                    # TRANSLATORS: Free here means Gratis
317
 
                    self.set_label(_("Free"))
318
 
            self.set_button_label(_('Install'))
 
343
                # TRANSLATORS: Free here means Gratis
 
344
                self.set_label(_("Free"))
 
345
            if (app_details.hardware_requirements_satisfied and
 
346
                app_details.region_requirements_satisfied):
 
347
                self.set_button_label(_('Install'))
 
348
            else:
 
349
                self.set_button_label(_('Install Anyway'))
319
350
        elif state == PkgStates.UPGRADABLE:
320
351
            self.set_label(_('Upgrade Available'))
321
352
            self.set_button_label(_('Upgrade'))
363
394
            return datetime.datetime.strptime(
364
395
                purchase_date, "%Y-%m-%d %H:%M:%S")
365
396
 
366
 
 
367
397
class PackageInfo(Gtk.HBox):
368
398
    """ Box with labels for package specific information like version info
369
399
    """
377
407
        self.info_keys.append(key)
378
408
        self.value_label = Gtk.Label()
379
409
        self.value_label.set_selectable(True)
 
410
        self.value_label.set_line_wrap(True)
 
411
        self.value_label.set_alignment(0, 0.5)
380
412
        self.a11y = self.get_accessible()
381
413
 
382
414
        self.connect('realize', self._on_realize)
401
433
        self.pack_start(k, False, False, 0)
402
434
 
403
435
        # value
404
 
        v = self.value_label
405
 
        v.set_line_wrap(True)
406
 
        v.set_selectable(True)
407
 
        v.set_alignment(0, 0.5)
408
 
        self.pack_start(v, False, False, 0)
 
436
        self.pack_start(self.value_label, False, False, 0)
409
437
 
410
438
        # a11y
411
439
        kacc = k.get_accessible()
412
 
        vacc = v.get_accessible()
 
440
        vacc = self.value_label.get_accessible()
413
441
        kacc.add_relationship(Atk.RelationType.LABEL_FOR, vacc)
414
442
        vacc.add_relationship(Atk.RelationType.LABELLED_BY, kacc)
415
443
 
416
444
        self.set_property("can-focus", True)
417
445
        self.show_all()
418
446
        return
419
 
 
 
447
    
420
448
    def set_width(self, width):
421
449
        return
422
450
 
424
452
        self.value_label.set_markup(value)
425
453
        self.a11y.set_name(utf8(self.key) + ' ' + utf8(value))
426
454
 
 
455
class PackageInfoHW(PackageInfo):
 
456
    """ special version of packageinfo that uses the custom 
 
457
        HardwareRequirementsBox as the "label"
 
458
    """
 
459
    def __init__(self, *args):
 
460
        super(PackageInfoHW, self).__init__(*args)
 
461
        self.value_label = HardwareRequirementsBox()
 
462
    def set_value(self, value):
 
463
        self.value_label.set_hardware_requirements(value)
 
464
 
427
465
 
428
466
class Addon(Gtk.HBox):
429
467
    """ Widget to select addons: CheckButton - Icon - Title (pkgname) """
1013
1051
 
1014
1052
    def _on_realize(self, widget):
1015
1053
        self.addons_statusbar.hide()
 
1054
        # the install button gets initial focus
 
1055
        self.pkg_statusbar.button.grab_focus()
1016
1056
        return
1017
1057
 
1018
1058
    def _on_homepage_clicked(self, label, link):
1063
1103
        self.title.a11y.set_role(Atk.Role.PANEL)
1064
1104
        hb.pack_start(vb_inner, False, False, 0)
1065
1105
 
 
1106
        # a warning bar (e.g. for HW incompatible packages)
 
1107
        self.pkg_warningbar = WarningStatusBar(self)
 
1108
        vb.pack_start(self.pkg_warningbar, False, False, 0)
 
1109
 
1066
1110
        # the package status bar
1067
1111
        self.pkg_statusbar = PackageStatusBar(self)
1068
1112
        vb.pack_start(self.pkg_statusbar, False, False, 0)
1162
1206
        self.version_info = PackageInfo(_("Version"), self.info_keys)
1163
1207
        info_vb.pack_start(self.version_info, False, False, 0)
1164
1208
 
 
1209
        self.hardware_info = PackageInfoHW(_("Also requires"), self.info_keys)
 
1210
        info_vb.pack_start(self.hardware_info, False, False, 0)
 
1211
 
1165
1212
        self.totalsize_info = PackageInfo(_("Total size"), self.info_keys)
1166
1213
        info_vb.pack_start(self.totalsize_info, False, False, 0)
1167
1214
 
1314
1361
            self.test_drive.show()
1315
1362
        return
1316
1363
 
 
1364
    def _update_warning_bar(self, app_details):
 
1365
        if (app_details.hardware_requirements_satisfied and
 
1366
            app_details.region_requirements_satisfied):
 
1367
            self.pkg_warningbar.hide()
 
1368
        else:
 
1369
            s = get_hw_missing_long_description(
 
1370
                app_details.hardware_requirements)
 
1371
            if not app_details.region_requirements_satisfied:
 
1372
                if len(s) > 0:
 
1373
                    s += "\n"+REGION_WARNING_STRING
 
1374
                else:
 
1375
                    s = REGION_WARNING_STRING
 
1376
            self.pkg_warningbar.label.set_text(s)
 
1377
            self.pkg_warningbar.show()
 
1378
 
1317
1379
    def _update_pkg_info_table(self, app_details):
1318
1380
        # set the strings in the package info table
1319
1381
        if app_details.version:
1329
1391
            support = app_details.maintenance_status
1330
1392
        else:
1331
1393
            support = _("Unknown")
 
1394
        # regular label updates
1332
1395
        self.version_info.set_value(version)
1333
1396
        self.license_info.set_value(license)
1334
1397
        self.support_info.set_value(support)
 
1398
        # this is slightly special as its not using a label but a special
 
1399
        # widget
 
1400
        self.hardware_info.set_value(app_details.hardware_requirements)
 
1401
        if self.app_details.hardware_requirements:
 
1402
            self.hardware_info.show()
 
1403
        else:
 
1404
            self.hardware_info.hide()
1335
1405
        return
1336
1406
 
1337
1407
    def _update_addons(self, app_details):
1386
1456
        self._update_app_video(app_details)
1387
1457
        self._update_weblive(app_details)
1388
1458
        self._update_pkg_info_table(app_details)
 
1459
        self._update_warning_bar(app_details)
1389
1460
        if not skip_update_addons:
1390
1461
            self._update_addons(app_details)
1391
1462
        else:
1407
1478
    def _update_minimal(self, app_details):
1408
1479
        self._update_app_icon(app_details)
1409
1480
        self._update_pkg_info_table(app_details)
 
1481
        self._update_warning_bar(app_details)
1410
1482
#        self._update_addons_minimal(app_details)
1411
1483
 
1412
1484
        # depending on pkg install state set action labels
1582
1654
        # this is a bit silly, but without it and self.title being selectable
1583
1655
        # gtk will select the entire title (which looks ugly). this grab works
1584
1656
        # around that
1585
 
        self.icon.grab_focus()
 
1657
        self.pkg_statusbar.button.grab_focus()
1586
1658
 
1587
1659
        self.emit("selected", self.app)
1588
1660
        return