15
15
'NewSpecificationFromSprintView',
16
16
'SpecificationActionMenu',
17
17
'SpecificationContextMenu',
18
'SpecificationNavigation',
20
'SpecificationSimpleView',
18
21
'SpecificationEditMilestoneView',
19
22
'SpecificationEditPeopleView',
20
23
'SpecificationEditPriorityView',
21
24
'SpecificationEditStatusView',
22
25
'SpecificationEditView',
23
26
'SpecificationEditWhiteboardView',
27
'SpecificationGoalProposeView',
24
28
'SpecificationGoalDecideView',
25
'SpecificationGoalProposeView',
26
29
'SpecificationLinkBranchView',
27
'SpecificationNavigation',
28
30
'SpecificationProductSeriesGoalProposeView',
29
31
'SpecificationRetargetingView',
30
'SpecificationSetView',
31
'SpecificationSimpleView',
32
32
'SpecificationSprintAddView',
33
'SpecificationSubscriptionView',
33
34
'SpecificationSupersedingView',
34
35
'SpecificationTreePNGView',
35
36
'SpecificationTreeImageTag',
36
37
'SpecificationTreeDotOutput',
38
'SpecificationSetView',
40
41
from operator import attrgetter
412
413
links = ['edit', 'people', 'status', 'priority',
413
414
'whiteboard', 'proposegoal',
414
415
'milestone', 'requestfeedback', 'givefeedback', 'subscription',
416
417
'linkbug', 'unlinkbug', 'linkbranch',
417
418
'adddependency', 'removedependency',
418
419
'dependencytree', 'linksprint', 'supersede',
463
464
text = 'Change status'
464
465
return Link('+status', text, icon='edit')
466
def addsubscriber(self):
467
def subscribeanother(self):
467
468
"""Return the 'Subscribe someone else' Link."""
468
469
text = 'Subscribe someone else'
469
470
return Link('+addsubscriber', text, icon='add')
472
473
"""Return the 'Edit Subscription' Link."""
475
return Link('+subscribe', 'Edit subscription', icon='edit')
477
if self.context.isSubscribed(user):
479
'+subscription/%s' % user.name,
480
'Update subscription', icon='edit')
476
text = 'Edit subscription'
478
elif self.context.isSubscribed(user):
479
text = 'Update subscription'
482
return Link('+subscribe', 'Subscribe', icon='add')
484
return Link('+subscribe', text, icon=icon)
484
486
@enabled_with_permission('launchpad.AnyPerson')
485
487
def linkbug(self):
538
540
return list(self.context.getFeedbackRequests(self.user))
543
def subscription(self):
544
"""whether the current user has a subscription to the spec."""
545
if self.user is None:
547
return self.context.subscription(self.user)
541
550
def has_dep_tree(self):
542
551
return self.context.dependencies or self.context.blocked_specs
569
578
if not self.user:
581
request = self.request
582
if request.method == 'POST':
583
# establish if a subscription form was posted.
584
sub = request.form.get('subscribe')
585
upd = request.form.get('update')
586
unsub = request.form.get('unsubscribe')
587
essential = request.form.get('essential') == 'yes'
589
self.context.subscribe(self.user, self.user, essential)
591
"You have subscribed to this blueprint.")
592
elif upd is not None:
593
self.context.subscribe(self.user, self.user, essential)
594
self.notices.append('Your subscription has been updated.')
595
elif unsub is not None:
596
self.context.unsubscribe(self.user)
598
"You have unsubscribed from this blueprint.")
572
600
if self.feedbackrequests:
573
601
msg = "You have %d feedback request(s) on this blueprint."
574
602
msg %= len(self.feedbackrequests)
652
680
header='Change approval of basic direction')
683
class SpecificationSubscriptionView(SpecificationView):
687
if self.subscription is not None:
688
return "Modify subscription"
689
return "Subscribe to blueprint"
655
692
class SpecificationEditSchema(ISpecification):
656
693
"""Provide overrides for the implementaion and definition status."""
991
1028
get_related_specs_fn = attrgetter('dependencies')
993
1029
def link_nodes_fn(node, dependency):
994
1030
self.link(dependency, node)
995
1031
self.walkSpecsMakingNodes(spec, get_related_specs_fn, link_nodes_fn)
997
1033
def addBlockedNodes(self, spec):
998
1034
"""Add nodes for specs that the given spec blocks, transitively."""
999
1035
get_related_specs_fn = attrgetter('blocked_specs')
1001
1036
def link_nodes_fn(node, blocked_spec):
1002
1037
self.link(node, blocked_spec)
1003
1038
self.walkSpecsMakingNodes(spec, get_related_specs_fn, link_nodes_fn)
1071
1106
size='9.2,9', # Width fits of 2 col layout, 1024x768.
1072
1107
ratio='compress',
1074
nodesep=0.01 # Separation between nodes
1109
nodesep=0.01 # Separation between nodes
1077
1112
# Global node and edge attributes.