Browse Source

Helios: Models refactorings

Nicolas Petton 11 years ago
parent
commit
c37a3b589f

+ 28 - 19
js/Helios-Browser.deploy.js

@@ -477,6 +477,34 @@ return self}, function($ctx1) {$ctx1.fill(self,"activateListItem:",{anItem:anIte
 messageSends: ["withChangesDo:", "activateListItem:", "model"]}),
 smalltalk.HLBrowserListWidget);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "activateNextListItem",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(_st(self)._model())._withChangesDo_((function(){
+return smalltalk.withContext(function($ctx2) {
+return smalltalk.HLNavigationListWidget.fn.prototype._activateNextListItem.apply(_st(self), []);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"activateNextListItem",{},smalltalk.HLBrowserListWidget)})},
+messageSends: ["withChangesDo:", "activateNextListItem", "model"]}),
+smalltalk.HLBrowserListWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "activatePreviousListItem",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(_st(self)._model())._withChangesDo_((function(){
+return smalltalk.withContext(function($ctx2) {
+return smalltalk.HLNavigationListWidget.fn.prototype._activatePreviousListItem.apply(_st(self), []);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"activatePreviousListItem",{},smalltalk.HLBrowserListWidget)})},
+messageSends: ["withChangesDo:", "activatePreviousListItem", "model"]}),
+smalltalk.HLBrowserListWidget);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "commandCategory",
@@ -3070,25 +3098,6 @@ return "as yet unclassified";
 messageSends: []}),
 smalltalk.HLBrowserModel);
 
-smalltalk.addMethod(
-smalltalk.method({
-selector: "withChangesDo:",
-fn: function (aBlock){
-var self=this;
-function $HLChangeForbidden(){return smalltalk.HLChangeForbidden||(typeof HLChangeForbidden=="undefined"?nil:HLChangeForbidden)}
-function $HLAboutToChange(){return smalltalk.HLAboutToChange||(typeof HLAboutToChange=="undefined"?nil:HLAboutToChange)}
-return smalltalk.withContext(function($ctx1) { 
-_st((function(){
-return smalltalk.withContext(function($ctx2) {
-_st(_st(self)._announcer())._announce_(_st(_st($HLAboutToChange())._new())._actionBlock_(aBlock));
-return _st(aBlock)._value();
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_($HLChangeForbidden(),(function(ex){
-return smalltalk.withContext(function($ctx2) {
-}, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"withChangesDo:",{aBlock:aBlock},smalltalk.HLBrowserModel)})},
-messageSends: ["on:do:", "announce:", "actionBlock:", "new", "announcer", "value"]}),
-smalltalk.HLBrowserModel);
-
 smalltalk.addMethod(
 smalltalk.method({
 selector: "withCompileErrorHandling:",

+ 38 - 24
js/Helios-Browser.js

@@ -632,6 +632,44 @@ referencedClasses: []
 }),
 smalltalk.HLBrowserListWidget);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "activateNextListItem",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(_st(self)._model())._withChangesDo_((function(){
+return smalltalk.withContext(function($ctx2) {
+return smalltalk.HLNavigationListWidget.fn.prototype._activateNextListItem.apply(_st(self), []);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"activateNextListItem",{},smalltalk.HLBrowserListWidget)})},
+args: [],
+source: "activateNextListItem\x0a\x09self model withChangesDo: [ super activateNextListItem ]",
+messageSends: ["withChangesDo:", "activateNextListItem", "model"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserListWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "activatePreviousListItem",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(_st(self)._model())._withChangesDo_((function(){
+return smalltalk.withContext(function($ctx2) {
+return smalltalk.HLNavigationListWidget.fn.prototype._activatePreviousListItem.apply(_st(self), []);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"activatePreviousListItem",{},smalltalk.HLBrowserListWidget)})},
+args: [],
+source: "activatePreviousListItem\x0a\x09self model withChangesDo: [ super activatePreviousListItem ]",
+messageSends: ["withChangesDo:", "activatePreviousListItem", "model"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserListWidget);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "commandCategory",
@@ -3950,30 +3988,6 @@ referencedClasses: []
 }),
 smalltalk.HLBrowserModel);
 
-smalltalk.addMethod(
-smalltalk.method({
-selector: "withChangesDo:",
-category: 'error handling',
-fn: function (aBlock){
-var self=this;
-function $HLChangeForbidden(){return smalltalk.HLChangeForbidden||(typeof HLChangeForbidden=="undefined"?nil:HLChangeForbidden)}
-function $HLAboutToChange(){return smalltalk.HLAboutToChange||(typeof HLAboutToChange=="undefined"?nil:HLAboutToChange)}
-return smalltalk.withContext(function($ctx1) { 
-_st((function(){
-return smalltalk.withContext(function($ctx2) {
-_st(_st(self)._announcer())._announce_(_st(_st($HLAboutToChange())._new())._actionBlock_(aBlock));
-return _st(aBlock)._value();
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_($HLChangeForbidden(),(function(ex){
-return smalltalk.withContext(function($ctx2) {
-}, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"withChangesDo:",{aBlock:aBlock},smalltalk.HLBrowserModel)})},
-args: ["aBlock"],
-source: "withChangesDo: aBlock\x0a\x09[ \x0a\x09\x09self announcer announce: (HLAboutToChange new\x0a\x09\x09\x09actionBlock: aBlock).\x0a\x09\x09aBlock value.\x0a\x09]\x0a\x09\x09on: HLChangeForbidden \x0a\x09\x09do: [ :ex | ]",
-messageSends: ["on:do:", "announce:", "actionBlock:", "new", "announcer", "value"],
-referencedClasses: ["HLChangeForbidden", "HLAboutToChange"]
-}),
-smalltalk.HLBrowserModel);
-
 smalltalk.addMethod(
 smalltalk.method({
 selector: "withCompileErrorHandling:",

+ 24 - 1
js/Helios-Core.deploy.js

@@ -76,6 +76,25 @@ return $1;
 messageSends: ["systemAnnouncer", "environment"]}),
 smalltalk.HLModel);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "withChangesDo:",
+fn: function (aBlock){
+var self=this;
+function $HLChangeForbidden(){return smalltalk.HLChangeForbidden||(typeof HLChangeForbidden=="undefined"?nil:HLChangeForbidden)}
+function $HLAboutToChange(){return smalltalk.HLAboutToChange||(typeof HLAboutToChange=="undefined"?nil:HLAboutToChange)}
+return smalltalk.withContext(function($ctx1) { 
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
+_st(_st(self)._announcer())._announce_(_st(_st($HLAboutToChange())._new())._actionBlock_(aBlock));
+return _st(aBlock)._value();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_($HLChangeForbidden(),(function(ex){
+return smalltalk.withContext(function($ctx2) {
+}, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"withChangesDo:",{aBlock:aBlock},smalltalk.HLModel)})},
+messageSends: ["on:do:", "announce:", "actionBlock:", "new", "announcer", "value"]}),
+smalltalk.HLModel);
+
 
 
 smalltalk.addClass('HLTab', smalltalk.Widget, ['widget', 'label', 'root'], 'Helios-Core');
@@ -902,8 +921,12 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self)._activateListItem_(_st(_st(window)._jQuery_(".focused .nav-pills .active"))._next());
+_st(_st(_st(window)._jQuery_(".focused .nav-pills .active"))._get())._ifEmpty_((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(self)._activateFirstListItem();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"activateNextListItem",{},smalltalk.HLListWidget)})},
-messageSends: ["activateListItem:", "next", "jQuery:"]}),
+messageSends: ["activateListItem:", "next", "jQuery:", "ifEmpty:", "activateFirstListItem", "get"]}),
 smalltalk.HLListWidget);
 
 smalltalk.addMethod(

+ 30 - 2
js/Helios-Core.js

@@ -101,6 +101,30 @@ referencedClasses: []
 }),
 smalltalk.HLModel);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "withChangesDo:",
+category: 'error handling',
+fn: function (aBlock){
+var self=this;
+function $HLChangeForbidden(){return smalltalk.HLChangeForbidden||(typeof HLChangeForbidden=="undefined"?nil:HLChangeForbidden)}
+function $HLAboutToChange(){return smalltalk.HLAboutToChange||(typeof HLAboutToChange=="undefined"?nil:HLAboutToChange)}
+return smalltalk.withContext(function($ctx1) { 
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
+_st(_st(self)._announcer())._announce_(_st(_st($HLAboutToChange())._new())._actionBlock_(aBlock));
+return _st(aBlock)._value();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_($HLChangeForbidden(),(function(ex){
+return smalltalk.withContext(function($ctx2) {
+}, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"withChangesDo:",{aBlock:aBlock},smalltalk.HLModel)})},
+args: ["aBlock"],
+source: "withChangesDo: aBlock\x0a\x09[ \x0a\x09\x09self announcer announce: (HLAboutToChange new\x0a\x09\x09\x09actionBlock: aBlock).\x0a\x09\x09aBlock value.\x0a\x09]\x0a\x09\x09on: HLChangeForbidden \x0a\x09\x09do: [ :ex | ]",
+messageSends: ["on:do:", "announce:", "actionBlock:", "new", "announcer", "value"],
+referencedClasses: ["HLChangeForbidden", "HLAboutToChange"]
+}),
+smalltalk.HLModel);
+
 
 
 smalltalk.addClass('HLTab', smalltalk.Widget, ['widget', 'label', 'root'], 'Helios-Core');
@@ -1193,10 +1217,14 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self)._activateListItem_(_st(_st(window)._jQuery_(".focused .nav-pills .active"))._next());
+_st(_st(_st(window)._jQuery_(".focused .nav-pills .active"))._get())._ifEmpty_((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(self)._activateFirstListItem();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"activateNextListItem",{},smalltalk.HLListWidget)})},
 args: [],
-source: "activateNextListItem\x0a\x09self activateListItem: (window jQuery: '.focused .nav-pills .active') next",
-messageSends: ["activateListItem:", "next", "jQuery:"],
+source: "activateNextListItem\x0a\x09self activateListItem: (window jQuery: '.focused .nav-pills .active') next.\x0a\x09\x0a\x09\x22select the first item if none is selected\x22\x0a\x09(window jQuery: '.focused .nav-pills .active') get ifEmpty: [\x0a\x09\x09self activateFirstListItem ]",
+messageSends: ["activateListItem:", "next", "jQuery:", "ifEmpty:", "activateFirstListItem", "get"],
 referencedClasses: []
 }),
 smalltalk.HLListWidget);

+ 130 - 51
js/Helios-References.deploy.js

@@ -162,19 +162,22 @@ smalltalk.method({
 selector: "sourceCodeWidget",
 fn: function (){
 var self=this;
-function $HLNavigationCodeWidget(){return smalltalk.HLNavigationCodeWidget||(typeof HLNavigationCodeWidget=="undefined"?nil:HLNavigationCodeWidget)}
+function $HLBrowserCodeWidget(){return smalltalk.HLBrowserCodeWidget||(typeof HLBrowserCodeWidget=="undefined"?nil:HLBrowserCodeWidget)}
 return smalltalk.withContext(function($ctx1) { 
-var $2,$1;
+var $2,$3,$4,$1;
 $2=self["@sourceCodeWidget"];
 if(($receiver = $2) == nil || $receiver == undefined){
-self["@sourceCodeWidget"]=_st($HLNavigationCodeWidget())._new();
+$3=_st($HLBrowserCodeWidget())._new();
+_st($3)._browserModel_(_st(self)._model());
+$4=_st($3)._yourself();
+self["@sourceCodeWidget"]=$4;
 $1=self["@sourceCodeWidget"];
 } else {
 $1=$2;
 };
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"sourceCodeWidget",{},smalltalk.HLReferences)})},
-messageSends: ["ifNil:", "new"]}),
+messageSends: ["ifNil:", "browserModel:", "model", "new", "yourself"]}),
 smalltalk.HLReferences);
 
 
@@ -214,41 +217,41 @@ messageSends: []}),
 smalltalk.HLReferences.klass);
 
 
-smalltalk.addClass('HLReferencesListWidget', smalltalk.HLNavigationListWidget, ['model'], 'Helios-References');
+smalltalk.addClass('HLReferencesListWidget', smalltalk.HLBrowserListWidget, ['model'], 'Helios-References');
 smalltalk.addMethod(
 smalltalk.method({
-selector: "label",
-fn: function (){
+selector: "activateListItem:",
+fn: function (anItem){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-return "List";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLReferencesListWidget)})},
-messageSends: []}),
+_st(_st(self)._model())._withChangesDo_((function(){
+return smalltalk.withContext(function($ctx2) {
+return smalltalk.HLBrowserListWidget.fn.prototype._activateListItem_.apply(_st(self), [anItem]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"activateListItem:",{anItem:anItem},smalltalk.HLReferencesListWidget)})},
+messageSends: ["withChangesDo:", "activateListItem:", "model"]}),
 smalltalk.HLReferencesListWidget);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "model",
+selector: "commandCategory",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=self["@model"];
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"model",{},smalltalk.HLReferencesListWidget)})},
+return "Methods";
+}, function($ctx1) {$ctx1.fill(self,"commandCategory",{},smalltalk.HLReferencesListWidget)})},
 messageSends: []}),
 smalltalk.HLReferencesListWidget);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "model:",
-fn: function (aModel){
+selector: "label",
+fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self["@model"]=aModel;
-_st(self)._observeModel();
-return self}, function($ctx1) {$ctx1.fill(self,"model:",{aModel:aModel},smalltalk.HLReferencesListWidget)})},
-messageSends: ["observeModel"]}),
+return "List";
+}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLReferencesListWidget)})},
+messageSends: []}),
 smalltalk.HLReferencesListWidget);
 
 smalltalk.addMethod(
@@ -257,64 +260,86 @@ selector: "observeModel",
 fn: function (){
 var self=this;
 function $HLSearchReferences(){return smalltalk.HLSearchReferences||(typeof HLSearchReferences=="undefined"?nil:HLSearchReferences)}
+function $HLMethodSelected(){return smalltalk.HLMethodSelected||(typeof HLMethodSelected=="undefined"?nil:HLMethodSelected)}
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(_st(self)._model())._announcer())._on_do_($HLSearchReferences(),(function(ann){
+var $1,$2;
+$1=_st(_st(self)._model())._announcer();
+_st($1)._on_do_($HLSearchReferences(),(function(ann){
 return smalltalk.withContext(function($ctx2) {
 return _st(self)._onSearchReferences_(_st(ann)._searchString());
 }, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+$2=_st($1)._on_do_($HLMethodSelected(),(function(ann){
+return smalltalk.withContext(function($ctx2) {
+return _st(self)._onMethodSelected_(_st(ann)._item());
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"observeModel",{},smalltalk.HLReferencesListWidget)})},
-messageSends: ["on:do:", "onSearchReferences:", "searchString", "announcer", "model"]}),
+messageSends: ["on:do:", "onSearchReferences:", "searchString", "announcer", "model", "onMethodSelected:", "item"]}),
 smalltalk.HLReferencesListWidget);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "onSearchReferences:",
-fn: function (aString){
+selector: "onMethodSelected:",
+fn: function (aMethod){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(self)._subclassResponsibility();
-return self}, function($ctx1) {$ctx1.fill(self,"onSearchReferences:",{aString:aString},smalltalk.HLReferencesListWidget)})},
-messageSends: ["subclassResponsibility"]}),
+var $1,$2,$3,$4,$5;
+var $early={};
+try {
+$1=aMethod;
+if(($receiver = $1) == nil || $receiver == undefined){
+$2=self;
+return $2;
+} else {
+$1;
+};
+_st(_st(self)._items())._detect_ifNone_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(each).__eq(_st(aMethod)._selector());
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx2) {
+$3=self;
+throw $early=[$3];
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$4=self;
+_st($4)._selectedItem_(_st(aMethod)._selector());
+$5=_st($4)._activateItem_(_st(aMethod)._selector());
+return self}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"onMethodSelected:",{aMethod:aMethod},smalltalk.HLReferencesListWidget)})},
+messageSends: ["ifNil:", "detect:ifNone:", "=", "selector", "items", "selectedItem:", "activateItem:"]}),
 smalltalk.HLReferencesListWidget);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "renderContentOn:",
-fn: function (html){
+selector: "onSearchReferences:",
+fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(self)._renderHeadOn_(html);
-smalltalk.HLNavigationListWidget.fn.prototype._renderContentOn_.apply(_st(self), [html]);
-return self}, function($ctx1) {$ctx1.fill(self,"renderContentOn:",{html:html},smalltalk.HLReferencesListWidget)})},
-messageSends: ["renderHeadOn:", "renderContentOn:"]}),
+_st(self)._subclassResponsibility();
+return self}, function($ctx1) {$ctx1.fill(self,"onSearchReferences:",{aString:aString},smalltalk.HLReferencesListWidget)})},
+messageSends: ["subclassResponsibility"]}),
 smalltalk.HLReferencesListWidget);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "renderHeadOn:",
-fn: function (html){
+selector: "renderItemLabel:on:",
+fn: function (aMethod,html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
-$1=_st(html)._div();
-_st($1)._class_("list-label");
-$2=_st($1)._with_((function(){
-return smalltalk.withContext(function($ctx2) {
-return _st(html)._with_(_st(self)._label());
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"renderHeadOn:",{html:html},smalltalk.HLReferencesListWidget)})},
-messageSends: ["class:", "div", "with:", "label"]}),
+_st(html)._with_(_st(_st(_st(_st(aMethod)._methodClass())._name()).__comma(" >> #")).__comma(_st(aMethod)._selector()));
+return self}, function($ctx1) {$ctx1.fill(self,"renderItemLabel:on:",{aMethod:aMethod,html:html},smalltalk.HLReferencesListWidget)})},
+messageSends: ["with:", ",", "selector", "name", "methodClass"]}),
 smalltalk.HLReferencesListWidget);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "renderItemLabel:on:",
-fn: function (aMethod,html){
+selector: "selectItem:",
+fn: function (aMethod){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(html)._with_(_st(_st(_st(_st(aMethod)._methodClass())._name()).__comma(" >> #")).__comma(_st(aMethod)._selector()));
-return self}, function($ctx1) {$ctx1.fill(self,"renderItemLabel:on:",{aMethod:aMethod,html:html},smalltalk.HLReferencesListWidget)})},
-messageSends: ["with:", ",", "selector", "name", "methodClass"]}),
+_st(_st(self)._model())._selectedMethod_(aMethod);
+return self}, function($ctx1) {$ctx1.fill(self,"selectItem:",{aMethod:aMethod},smalltalk.HLReferencesListWidget)})},
+messageSends: ["selectedMethod:", "model"]}),
 smalltalk.HLReferencesListWidget);
 
 
@@ -443,7 +468,7 @@ smalltalk.HLSendersListWidget);
 
 
 
-smalltalk.addClass('HLReferencesModel', smalltalk.HLModel, ['methodsCache', 'classesAndMetaclassesCache'], 'Helios-References');
+smalltalk.addClass('HLReferencesModel', smalltalk.HLModel, ['methodsCache', 'classesAndMetaclassesCache', 'selectedMethod'], 'Helios-References');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "allMethods",
@@ -599,6 +624,60 @@ return self}, function($ctx1) {$ctx1.fill(self,"search:",{aString:aString},small
 messageSends: ["updateCaches", "announce:", "searchString:", "new", "yourself", "announcer"]}),
 smalltalk.HLReferencesModel);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "selectedClass",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=_st(self)._selectedMethod();
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=$2;
+} else {
+var method;
+method=$receiver;
+$1=_st(method)._methodClass();
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"selectedClass",{},smalltalk.HLReferencesModel)})},
+messageSends: ["ifNotNil:", "methodClass", "selectedMethod"]}),
+smalltalk.HLReferencesModel);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "selectedMethod",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@selectedMethod"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"selectedMethod",{},smalltalk.HLReferencesModel)})},
+messageSends: []}),
+smalltalk.HLReferencesModel);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "selectedMethod:",
+fn: function (aMethod){
+var self=this;
+function $HLMethodSelected(){return smalltalk.HLMethodSelected||(typeof HLMethodSelected=="undefined"?nil:HLMethodSelected)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+_st(self)._withChangesDo_((function(){
+return smalltalk.withContext(function($ctx2) {
+self["@selectedMethod"]=aMethod;
+self["@selectedMethod"];
+$1=_st($HLMethodSelected())._new();
+_st($1)._item_(aMethod);
+$2=_st($1)._yourself();
+return _st(_st(self)._announcer())._announce_($2);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"selectedMethod:",{aMethod:aMethod},smalltalk.HLReferencesModel)})},
+messageSends: ["withChangesDo:", "announce:", "item:", "new", "yourself", "announcer"]}),
+smalltalk.HLReferencesModel);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "sendersOf:",

+ 165 - 71
js/Helios-References.js

@@ -208,12 +208,15 @@ selector: "sourceCodeWidget",
 category: 'accessing',
 fn: function (){
 var self=this;
-function $HLNavigationCodeWidget(){return smalltalk.HLNavigationCodeWidget||(typeof HLNavigationCodeWidget=="undefined"?nil:HLNavigationCodeWidget)}
+function $HLBrowserCodeWidget(){return smalltalk.HLBrowserCodeWidget||(typeof HLBrowserCodeWidget=="undefined"?nil:HLBrowserCodeWidget)}
 return smalltalk.withContext(function($ctx1) { 
-var $2,$1;
+var $2,$3,$4,$1;
 $2=self["@sourceCodeWidget"];
 if(($receiver = $2) == nil || $receiver == undefined){
-self["@sourceCodeWidget"]=_st($HLNavigationCodeWidget())._new();
+$3=_st($HLBrowserCodeWidget())._new();
+_st($3)._browserModel_(_st(self)._model());
+$4=_st($3)._yourself();
+self["@sourceCodeWidget"]=$4;
 $1=self["@sourceCodeWidget"];
 } else {
 $1=$2;
@@ -221,9 +224,9 @@ $1=$2;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"sourceCodeWidget",{},smalltalk.HLReferences)})},
 args: [],
-source: "sourceCodeWidget\x0a\x09^ sourceCodeWidget ifNil: [\x0a      \x09sourceCodeWidget := HLNavigationCodeWidget new ]",
-messageSends: ["ifNil:", "new"],
-referencedClasses: ["HLNavigationCodeWidget"]
+source: "sourceCodeWidget\x0a\x09^ sourceCodeWidget ifNil: [\x0a      \x09sourceCodeWidget := HLBrowserCodeWidget new\x0a\x09\x09\x09browserModel: self model;\x0a\x09\x09\x09yourself ]",
+messageSends: ["ifNil:", "browserModel:", "model", "new", "yourself"],
+referencedClasses: ["HLBrowserCodeWidget"]
 }),
 smalltalk.HLReferences);
 
@@ -279,36 +282,37 @@ referencedClasses: []
 smalltalk.HLReferences.klass);
 
 
-smalltalk.addClass('HLReferencesListWidget', smalltalk.HLNavigationListWidget, ['model'], 'Helios-References');
+smalltalk.addClass('HLReferencesListWidget', smalltalk.HLBrowserListWidget, ['model'], 'Helios-References');
 smalltalk.addMethod(
 smalltalk.method({
-selector: "label",
-category: 'accessing',
-fn: function (){
+selector: "activateListItem:",
+category: 'actions',
+fn: function (anItem){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-return "List";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLReferencesListWidget)})},
-args: [],
-source: "label\x0a\x09^ 'List'",
-messageSends: [],
+_st(_st(self)._model())._withChangesDo_((function(){
+return smalltalk.withContext(function($ctx2) {
+return smalltalk.HLBrowserListWidget.fn.prototype._activateListItem_.apply(_st(self), [anItem]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"activateListItem:",{anItem:anItem},smalltalk.HLReferencesListWidget)})},
+args: ["anItem"],
+source: "activateListItem: anItem\x0a\x09self model withChangesDo: [ super activateListItem: anItem ]",
+messageSends: ["withChangesDo:", "activateListItem:", "model"],
 referencedClasses: []
 }),
 smalltalk.HLReferencesListWidget);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "model",
+selector: "commandCategory",
 category: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=self["@model"];
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"model",{},smalltalk.HLReferencesListWidget)})},
+return "Methods";
+}, function($ctx1) {$ctx1.fill(self,"commandCategory",{},smalltalk.HLReferencesListWidget)})},
 args: [],
-source: "model\x0a\x09^ model",
+source: "commandCategory\x0a\x09^ 'Methods'",
 messageSends: [],
 referencedClasses: []
 }),
@@ -316,17 +320,16 @@ smalltalk.HLReferencesListWidget);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "model:",
+selector: "label",
 category: 'accessing',
-fn: function (aModel){
+fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self["@model"]=aModel;
-_st(self)._observeModel();
-return self}, function($ctx1) {$ctx1.fill(self,"model:",{aModel:aModel},smalltalk.HLReferencesListWidget)})},
-args: ["aModel"],
-source: "model: aModel\x0a\x09model := aModel.\x0a\x09\x0a\x09self observeModel",
-messageSends: ["observeModel"],
+return "List";
+}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLReferencesListWidget)})},
+args: [],
+source: "label\x0a\x09^ 'List'",
+messageSends: [],
 referencedClasses: []
 }),
 smalltalk.HLReferencesListWidget);
@@ -338,86 +341,108 @@ category: 'actions',
 fn: function (){
 var self=this;
 function $HLSearchReferences(){return smalltalk.HLSearchReferences||(typeof HLSearchReferences=="undefined"?nil:HLSearchReferences)}
+function $HLMethodSelected(){return smalltalk.HLMethodSelected||(typeof HLMethodSelected=="undefined"?nil:HLMethodSelected)}
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(_st(self)._model())._announcer())._on_do_($HLSearchReferences(),(function(ann){
+var $1,$2;
+$1=_st(_st(self)._model())._announcer();
+_st($1)._on_do_($HLSearchReferences(),(function(ann){
 return smalltalk.withContext(function($ctx2) {
 return _st(self)._onSearchReferences_(_st(ann)._searchString());
 }, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+$2=_st($1)._on_do_($HLMethodSelected(),(function(ann){
+return smalltalk.withContext(function($ctx2) {
+return _st(self)._onMethodSelected_(_st(ann)._item());
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"observeModel",{},smalltalk.HLReferencesListWidget)})},
 args: [],
-source: "observeModel\x0a\x09self model announcer\x0a\x09\x09on: HLSearchReferences\x0a\x09\x09do: [ :ann | self onSearchReferences: ann searchString ]",
-messageSends: ["on:do:", "onSearchReferences:", "searchString", "announcer", "model"],
-referencedClasses: ["HLSearchReferences"]
+source: "observeModel\x0a\x09self model announcer\x0a\x09\x09on: HLSearchReferences\x0a\x09\x09do: [ :ann | self onSearchReferences: ann searchString ];\x0a\x09\x09on: HLMethodSelected\x0a\x09\x09do: [ :ann | self onMethodSelected: ann item ]",
+messageSends: ["on:do:", "onSearchReferences:", "searchString", "announcer", "model", "onMethodSelected:", "item"],
+referencedClasses: ["HLSearchReferences", "HLMethodSelected"]
 }),
 smalltalk.HLReferencesListWidget);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "onSearchReferences:",
+selector: "onMethodSelected:",
 category: 'reactions',
-fn: function (aString){
+fn: function (aMethod){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(self)._subclassResponsibility();
-return self}, function($ctx1) {$ctx1.fill(self,"onSearchReferences:",{aString:aString},smalltalk.HLReferencesListWidget)})},
-args: ["aString"],
-source: "onSearchReferences: aString\x0a\x09self subclassResponsibility",
-messageSends: ["subclassResponsibility"],
+var $1,$2,$3,$4,$5;
+var $early={};
+try {
+$1=aMethod;
+if(($receiver = $1) == nil || $receiver == undefined){
+$2=self;
+return $2;
+} else {
+$1;
+};
+_st(_st(self)._items())._detect_ifNone_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(each).__eq(_st(aMethod)._selector());
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx2) {
+$3=self;
+throw $early=[$3];
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$4=self;
+_st($4)._selectedItem_(_st(aMethod)._selector());
+$5=_st($4)._activateItem_(_st(aMethod)._selector());
+return self}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"onMethodSelected:",{aMethod:aMethod},smalltalk.HLReferencesListWidget)})},
+args: ["aMethod"],
+source: "onMethodSelected: aMethod\x0a\x09aMethod ifNil: [ ^ self ].\x0a\x09self items detect: [ :each | each = aMethod selector ] ifNone: [ ^ self ].\x0a\x09\x0a\x09self \x0a\x09\x09selectedItem: aMethod selector;\x0a\x09\x09activateItem: aMethod selector\x09",
+messageSends: ["ifNil:", "detect:ifNone:", "=", "selector", "items", "selectedItem:", "activateItem:"],
 referencedClasses: []
 }),
 smalltalk.HLReferencesListWidget);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "renderContentOn:",
-category: 'rendering',
-fn: function (html){
+selector: "onSearchReferences:",
+category: 'reactions',
+fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(self)._renderHeadOn_(html);
-smalltalk.HLNavigationListWidget.fn.prototype._renderContentOn_.apply(_st(self), [html]);
-return self}, function($ctx1) {$ctx1.fill(self,"renderContentOn:",{html:html},smalltalk.HLReferencesListWidget)})},
-args: ["html"],
-source: "renderContentOn: html\x0a\x09self renderHeadOn: html.\x09\x0a\x09super renderContentOn: html",
-messageSends: ["renderHeadOn:", "renderContentOn:"],
+_st(self)._subclassResponsibility();
+return self}, function($ctx1) {$ctx1.fill(self,"onSearchReferences:",{aString:aString},smalltalk.HLReferencesListWidget)})},
+args: ["aString"],
+source: "onSearchReferences: aString\x0a\x09self subclassResponsibility",
+messageSends: ["subclassResponsibility"],
 referencedClasses: []
 }),
 smalltalk.HLReferencesListWidget);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "renderHeadOn:",
+selector: "renderItemLabel:on:",
 category: 'rendering',
-fn: function (html){
+fn: function (aMethod,html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
-$1=_st(html)._div();
-_st($1)._class_("list-label");
-$2=_st($1)._with_((function(){
-return smalltalk.withContext(function($ctx2) {
-return _st(html)._with_(_st(self)._label());
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"renderHeadOn:",{html:html},smalltalk.HLReferencesListWidget)})},
-args: ["html"],
-source: "renderHeadOn: html\x0a\x09html div \x0a\x09\x09class: 'list-label';\x0a\x09\x09with: [\x0a\x09\x09\x09html with: self label ]",
-messageSends: ["class:", "div", "with:", "label"],
+_st(html)._with_(_st(_st(_st(_st(aMethod)._methodClass())._name()).__comma(" >> #")).__comma(_st(aMethod)._selector()));
+return self}, function($ctx1) {$ctx1.fill(self,"renderItemLabel:on:",{aMethod:aMethod,html:html},smalltalk.HLReferencesListWidget)})},
+args: ["aMethod", "html"],
+source: "renderItemLabel: aMethod on: html\x0a\x09html with: aMethod methodClass name, ' >> #', aMethod selector",
+messageSends: ["with:", ",", "selector", "name", "methodClass"],
 referencedClasses: []
 }),
 smalltalk.HLReferencesListWidget);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "renderItemLabel:on:",
-category: 'rendering',
-fn: function (aMethod,html){
+selector: "selectItem:",
+category: 'actions',
+fn: function (aMethod){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(html)._with_(_st(_st(_st(_st(aMethod)._methodClass())._name()).__comma(" >> #")).__comma(_st(aMethod)._selector()));
-return self}, function($ctx1) {$ctx1.fill(self,"renderItemLabel:on:",{aMethod:aMethod,html:html},smalltalk.HLReferencesListWidget)})},
-args: ["aMethod", "html"],
-source: "renderItemLabel: aMethod on: html\x0a\x09html with: aMethod methodClass name, ' >> #', aMethod selector",
-messageSends: ["with:", ",", "selector", "name", "methodClass"],
+_st(_st(self)._model())._selectedMethod_(aMethod);
+return self}, function($ctx1) {$ctx1.fill(self,"selectItem:",{aMethod:aMethod},smalltalk.HLReferencesListWidget)})},
+args: ["aMethod"],
+source: "selectItem: aMethod\x0a\x09self model selectedMethod: aMethod",
+messageSends: ["selectedMethod:", "model"],
 referencedClasses: []
 }),
 smalltalk.HLReferencesListWidget);
@@ -593,7 +618,7 @@ smalltalk.HLSendersListWidget);
 
 
 
-smalltalk.addClass('HLReferencesModel', smalltalk.HLModel, ['methodsCache', 'classesAndMetaclassesCache'], 'Helios-References');
+smalltalk.addClass('HLReferencesModel', smalltalk.HLModel, ['methodsCache', 'classesAndMetaclassesCache', 'selectedMethod'], 'Helios-References');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "allMethods",
@@ -794,6 +819,75 @@ referencedClasses: ["HLSearchReferences"]
 }),
 smalltalk.HLReferencesModel);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "selectedClass",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=_st(self)._selectedMethod();
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=$2;
+} else {
+var method;
+method=$receiver;
+$1=_st(method)._methodClass();
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"selectedClass",{},smalltalk.HLReferencesModel)})},
+args: [],
+source: "selectedClass\x0a\x09^ self selectedMethod ifNotNil: [ :method |\x0a\x09\x09method methodClass ]",
+messageSends: ["ifNotNil:", "methodClass", "selectedMethod"],
+referencedClasses: []
+}),
+smalltalk.HLReferencesModel);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "selectedMethod",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@selectedMethod"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"selectedMethod",{},smalltalk.HLReferencesModel)})},
+args: [],
+source: "selectedMethod\x0a\x09^ selectedMethod",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLReferencesModel);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "selectedMethod:",
+category: 'accessing',
+fn: function (aMethod){
+var self=this;
+function $HLMethodSelected(){return smalltalk.HLMethodSelected||(typeof HLMethodSelected=="undefined"?nil:HLMethodSelected)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+_st(self)._withChangesDo_((function(){
+return smalltalk.withContext(function($ctx2) {
+self["@selectedMethod"]=aMethod;
+self["@selectedMethod"];
+$1=_st($HLMethodSelected())._new();
+_st($1)._item_(aMethod);
+$2=_st($1)._yourself();
+return _st(_st(self)._announcer())._announce_($2);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"selectedMethod:",{aMethod:aMethod},smalltalk.HLReferencesModel)})},
+args: ["aMethod"],
+source: "selectedMethod: aMethod\x0a\x09self withChangesDo: [ \x0a\x09\x09selectedMethod := aMethod.\x0a\x09\x09\x0a\x09\x09self announcer announce: (HLMethodSelected new\x0a\x09\x09\x09item: aMethod;\x0a\x09\x09\x09yourself) ]\x0a\x09",
+messageSends: ["withChangesDo:", "announce:", "item:", "new", "yourself", "announcer"],
+referencedClasses: ["HLMethodSelected"]
+}),
+smalltalk.HLReferencesModel);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "sendersOf:",

+ 8 - 10
st/Helios-Browser.st

@@ -238,6 +238,14 @@ activateListItem: anItem
 	self model withChangesDo: [ super activateListItem: anItem ]
 !
 
+activateNextListItem
+	self model withChangesDo: [ super activateNextListItem ]
+!
+
+activatePreviousListItem
+	self model withChangesDo: [ super activatePreviousListItem ]
+!
+
 observeModel
 !
 
@@ -1275,16 +1283,6 @@ handleParseError: anError
 		yourself)
 !
 
-withChangesDo: aBlock
-	[ 
-		self announcer announce: (HLAboutToChange new
-			actionBlock: aBlock).
-		aBlock value.
-	]
-		on: HLChangeForbidden 
-		do: [ :ex | ]
-!
-
 withCompileErrorHandling: aBlock
 	[
 		[

+ 17 - 1
st/Helios-Core.st

@@ -25,6 +25,18 @@ systemAnnouncer
 	^ self environment systemAnnouncer
 ! !
 
+!HLModel methodsFor: 'error handling'!
+
+withChangesDo: aBlock
+	[ 
+		self announcer announce: (HLAboutToChange new
+			actionBlock: aBlock).
+		aBlock value.
+	]
+		on: HLChangeForbidden 
+		do: [ :ex | ]
+! !
+
 Widget subclass: #HLTab
 	instanceVariableNames: 'widget label root'
 	package: 'Helios-Core'!
@@ -408,7 +420,11 @@ activateListItem: aListItem
 !
 
 activateNextListItem
-	self activateListItem: (window jQuery: '.focused .nav-pills .active') next
+	self activateListItem: (window jQuery: '.focused .nav-pills .active') next.
+	
+	"select the first item if none is selected"
+	(window jQuery: '.focused .nav-pills .active') get ifEmpty: [
+		self activateFirstListItem ]
 !
 
 activatePreviousListItem

+ 47 - 26
st/Helios-References.st

@@ -42,7 +42,9 @@ sendersListWidget
 
 sourceCodeWidget
 	^ sourceCodeWidget ifNil: [
-      	sourceCodeWidget := HLNavigationCodeWidget new ]
+      	sourceCodeWidget := HLBrowserCodeWidget new
+			browserModel: self model;
+			yourself ]
 ! !
 
 !HLReferences methodsFor: 'actions'!
@@ -87,54 +89,55 @@ canBeOpenAsTab
 	^ false
 ! !
 
-HLNavigationListWidget subclass: #HLReferencesListWidget
+HLBrowserListWidget subclass: #HLReferencesListWidget
 	instanceVariableNames: 'model'
 	package: 'Helios-References'!
 
 !HLReferencesListWidget methodsFor: 'accessing'!
 
-label
-	^ 'List'
-!
-
-model
-	^ model
+commandCategory
+	^ 'Methods'
 !
 
-model: aModel
-	model := aModel.
-	
-	self observeModel
+label
+	^ 'List'
 ! !
 
 !HLReferencesListWidget methodsFor: 'actions'!
 
+activateListItem: anItem
+	self model withChangesDo: [ super activateListItem: anItem ]
+!
+
 observeModel
 	self model announcer
 		on: HLSearchReferences
-		do: [ :ann | self onSearchReferences: ann searchString ]
+		do: [ :ann | self onSearchReferences: ann searchString ];
+		on: HLMethodSelected
+		do: [ :ann | self onMethodSelected: ann item ]
+!
+
+selectItem: aMethod
+	self model selectedMethod: aMethod
 ! !
 
 !HLReferencesListWidget methodsFor: 'reactions'!
 
+onMethodSelected: aMethod
+	aMethod ifNil: [ ^ self ].
+	self items detect: [ :each | each = aMethod selector ] ifNone: [ ^ self ].
+	
+	self 
+		selectedItem: aMethod selector;
+		activateItem: aMethod selector
+!
+
 onSearchReferences: aString
 	self subclassResponsibility
 ! !
 
 !HLReferencesListWidget methodsFor: 'rendering'!
 
-renderContentOn: html
-	self renderHeadOn: html.	
-	super renderContentOn: html
-!
-
-renderHeadOn: html
-	html div 
-		class: 'list-label';
-		with: [
-			html with: self label ]
-!
-
 renderItemLabel: aMethod on: html
 	html with: aMethod methodClass name, ' >> #', aMethod selector
 ! !
@@ -220,7 +223,7 @@ onSearchReferences: aString
 ! !
 
 HLModel subclass: #HLReferencesModel
-	instanceVariableNames: 'methodsCache classesAndMetaclassesCache'
+	instanceVariableNames: 'methodsCache classesAndMetaclassesCache selectedMethod'
 	package: 'Helios-References'!
 
 !HLReferencesModel methodsFor: 'accessing'!
@@ -264,6 +267,24 @@ regexpReferencesOf: aString
 		each source match: aString ]
 !
 
+selectedClass
+	^ self selectedMethod ifNotNil: [ :method |
+		method methodClass ]
+!
+
+selectedMethod
+	^ selectedMethod
+!
+
+selectedMethod: aMethod
+	self withChangesDo: [ 
+		selectedMethod := aMethod.
+		
+		self announcer announce: (HLMethodSelected new
+			item: aMethod;
+			yourself) ]
+!
+
 sendersOf: aString
 	^ self allMethods select: [ :each |
 		each messageSends includes: aString ]