<body><div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000;text-align: left" dir="ltr">
                                        Merged.<div class="mb_sig"></div><blockquote class='history_container' type='cite' style='border-left-style:solid;border-width:1px; margin-top:20px; margin-left:0px;padding-left:10px;'>
                        <p style='color: #AAAAAA; margin-top: 10px;'>Am 06.11.2021 21:47:16 schrieb christoph.thiede@student.hpi.uni-potsdam.de <christoph.thiede@student.hpi.uni-potsdam.de>:</p><div style='font-family:Arial,Helvetica,sans-serif'>
<b>==================== Summary ====================</b><br>
<br>
Change Set:        pbKeyboard<br>
Date:            2 November 2021<br>
Author:            Christoph Thiede<br>
<br>
This changeset improves keyboard shortcut for preference button in the PreferenceBrowser. You can now select a preference in the browser and press escape to trigger the menu or cmd + (m|b | n | i | c | C) to browse senders/implementors / inspect the preference, or copy its content, resp. Also fixes up a few Law of Demeter violations in PBPreferenceView and improves multilingual support.<br>
<br>
<b>=============== Diff ===============</b><br>
<br>
<b>PBPreferenceButtonMorph>>handlesKeyboard: {event handling} · ct 11/1/2021 22:54</b><br>
<span style="color: #FF0000">+ handlesKeyboard: anEvent<br>
+ <br>
+     ^ anEvent isKeystroke</span><br>
<br>
<b>PBPreferenceButtonMorph>>highlightOn {highlighting} · ct 11/1/2021 23:14 (changed)</b><br>
highlightOn<br>
    <br>
    self color: ((UserInterfaceTheme current get: #selectionColor for: PluggableListMorph) ifNil: [Color gray alpha: 0.1]).<br>
<br>
    self label<br>
        color: ((UserInterfaceTheme current get: #selectionTextColor for: PluggableListMorph) ifNil: [Color black]);<br>
        font: (((UserInterfaceTheme current get: #font for: PluggableListMorph) ifNil: [TextStyle defaultFont])<br>
            emphasized: TextEmphasis bold emphasisCode).<br>
    <br>
<span style="color: #0000FF">-     self addExtraControls.<br>
</span><span style="color: #FF0000">+     self addExtraControls.<br>
+     <br>
+     self currentHand newKeyboardFocus: self.</span><br>
<br>
<b>PBPreferenceButtonMorph>>keyStroke: {event handling} · ct 11/1/2021 23:02</b><br>
<span style="color: #FF0000">+ keyStroke: anEvent<br>
+ <br>
+     ^ self preferenceView keyStroke: anEvent browser: self model</span><br>
<br>
<b>PBPreferenceView>>keyStroke:browser: {user interface} · ct 11/2/2021 15:41</b><br>
<span style="color: #FF0000">+ keyStroke: anEvent browser: aPreferenceBrowser<br>
+ <br>
+     anEvent commandKeyPressed<br>
+         ifFalse: [<br>
+             anEvent keyCharacter = Character escape<br>
+                 ifTrue: [^ self offerPreferenceNameMenu: aPreferenceBrowser].<br>
+             ^ anEvent wasHandled: false].<br>
+     <br>
+     anEvent keyCharacter<br>
+         caseOf: {<br>
+             [$b] -> [aPreferenceBrowser findCategoryFromPreference: self preference].<br>
+             [$c] -> [self copyName].<br>
+             [$C] -> [self copyCode].<br>
+             [$i] -> [self preference inspect].<br>
+             [$m] -> [self browse].<br>
+             [$n] -> [self browseSenders]}<br>
+         otherwise: [anEvent wasHandled: false].</span><br>
<br>
<b>PBPreferenceView>>offerPreferenceNameMenu: {user interface} · ct 11/2/2021 15:44 (changed)</b><br>
offerPreferenceNameMenu: aPreferenceBrowser<br>
    "the user clicked on a preference name -- put up a menu"<br>
<br>
    | aMenu readableName |<br>
    readableName := self preference readableName.<br>
    aMenu := MenuMorph new <br>
        defaultTarget: self preference;<br>
        addTitle: readableName.<br>
<br>
    (Preferences okayToChangeProjectLocalnessOf: self preference name) ifTrue:<br>
        [aMenu<br>
            addUpdating: #isProjectLocalString target: self preference action: #toggleProjectLocalness;<br>
<span style="color: #0000FF">-             balloonTextForLastItem: 'Some preferences are best applied uniformly to all projects, and others are best set by each individual project. If this item is checked, then this preference will be printed in bold and will have a separate value for each project'].<br>
</span><span style="color: #FF0000">+             balloonTextForLastItem: 'Some preferences are best applied uniformly to all projects, and others are best set by each individual project. If this item is checked, then this preference will be printed in bold and will have a separate value for each project' translated].<br>
</span><br>
    aMenu<br>
        addLine;<br>
<span style="color: #0000FF">-         add: 'browse senders' translated<br>
-             target: self systemNavigation<br>
-             selector: #browseAllSelect:name:autoSelect:<br>
-             argumentList: {<br>
-                 [:m | self preference selectors anySatisfy: [:sel | m hasLiteral: sel]].<br>
-                 'Preference senders: {1}' translated format: {self preference name}.<br>
-                 self preference selectors first };<br>
-         balloonTextForLastItem: 'This will open a method-list browser on all methods that the send the preference "'<br>
-             , readableName , '".'.<br>
</span><span style="color: #FF0000">+         add: 'browse senders (n)' translated<br>
+             action: #browseSenders;<br>
+         balloonTextForLastItem: ('This will open a method-list browser on all methods that the send the preference "{1}".' translated format: {readableName}).<br>
</span>    self preference provider ifNotNil: [<br>
        aMenu<br>
<span style="color: #0000FF">-             add: 'browse implementation' translated<br>
-                 target: ToolSet<br>
-                 selector: #browse:selector:<br>
-                 argumentList: {<br>
-                     self preference provider class.<br>
-                     self preference selectors first };<br>
-             balloonTextForLastItem: 'This will open a browser on the method that stores the preference "' , readableName , '".'].<br>
</span><span style="color: #FF0000">+             add: 'browse implementation (m)' translated<br>
+                 action: #browse;<br>
+             balloonTextForLastItem: ('This will open a browser on the method that stores the preference "{1}".' translated format: {readableName})].<br>
</span>    aMenu<br>
<span style="color: #0000FF">-         add: 'inspect preference' translated<br>
-             target: self preference<br>
-             selector: #inspect;<br>
-         balloonTextForLastItem: 'This will open an Inspector on the preference "' , readableName , '".'.<br>
</span><span style="color: #FF0000">+         add: 'inspect preference (i)' translated<br>
+             action: #inspect;<br>
+         balloonTextForLastItem: ('This will open an inspector on the preference "{1}".' translated format: {readableName}).<br>
</span>    aMenu<br>
        addLine;<br>
<span style="color: #0000FF">-         add: 'show category'<br>
</span><span style="color: #FF0000">+         add: 'show category (b)' translated<br>
</span>            target: aPreferenceBrowser<br>
            selector: #findCategoryFromPreference:<br>
            argument: self preference;<br>
<span style="color: #0000FF">-         balloonTextForLastItem: 'Allows you to find out which category, or categories, this preference belongs to.'.<br>
</span><span style="color: #FF0000">+         balloonTextForLastItem: 'Allows you to find out which category, or categories, this preference belongs to.' translated.<br>
</span><br>
    Smalltalk isMorphic ifTrue:<br>
        [aMenu<br>
<span style="color: #0000FF">-             add: 'hand me a button for this preference'<br>
</span><span style="color: #FF0000">+             add: 'hand me a button for this preference' translated<br>
</span>                target: self<br>
                selector: #tearOffButton;<br>
<span style="color: #0000FF">-             balloonTextForLastItem: 'Will give you a button that governs this preference, which you may deposit wherever you wish'].<br>
</span><span style="color: #FF0000">+             balloonTextForLastItem: 'Will give you a button that governs this preference, which you may deposit wherever you wish' translated].<br>
</span><br>
    aMenu<br>
<span style="color: #0000FF">-         add: 'copy name to clipboard'<br>
-             target: self preference<br>
-             selector: #copyName;<br>
-         balloonTextForLastItem: 'Copy the name of the preference to the text clipboard, so that you can paste into code somewhere'.<br>
</span><span style="color: #FF0000">+         add: 'copy name to clipboard (c)' translated<br>
+             action: #copyName;<br>
+         balloonTextForLastItem: 'Copy the name of the preference to the text clipboard, so that you can paste into code somewhere' translated.<br>
</span>    aMenu<br>
<span style="color: #0000FF">-         add: 'copy code to clipboard'<br>
-             target: self preference<br>
-             selector: #copyCode;<br>
-         balloonTextForLastItem: 'Copy the code to access the current preference value to the clipboard, so that you can paste into code somewhere'.<br>
</span><span style="color: #FF0000">+         add: 'copy code to clipboard (C)' translated<br>
+             action: #copyCode;<br>
+         balloonTextForLastItem: 'Copy the code to access the current preference value to the clipboard, so that you can paste into code somewhere' translated.<br>
</span><br>
    aMenu popUpInWorld<br>
<br>
<b>PragmaPreference>>browse {browsing} · ct 11/1/2021 22:56</b><br>
<span style="color: #FF0000">+ browse<br>
+ <br>
+     ToolSet<br>
+         browse: self provider class<br>
+         selector: self selectors first.</span><br>
<br>
<b>Preference>>browse {browsing} · ct 11/1/2021 22:56</b><br>
<span style="color: #FF0000">+ browse<br>
+ <br>
+     ToolSet<br>
+         browse: Preferences class<br>
+         selector: self selectors first.</span><br>
<br>
<b>Preference>>browseSenders {browsing} · ct 11/1/2021 22:42</b><br>
<span style="color: #FF0000">+ browseSenders<br>
+ <br>
+     self systemNavigation<br>
+         browseAllSelect: [:m | self selectors anySatisfy: [:sel | m hasLiteral: sel]]<br>
+         name: ('Preference senders: {1}' translated format: {self name})<br>
+         autoSelect: self selectors first.</span><br>
<br>
<b>PreferenceBrowser>>findCategoryFromPreference: {find} · ct 11/2/2021 15:03 (changed)</b><br>
findCategoryFromPreference: aPreference<br>
    "Find all categories in which the preference occurs"<br>
<br>
<span style="color: #0000FF">-     | aMenu| <br>
-     aMenu := MenuMorph new defaultTarget: self.<br>
</span><span style="color: #FF0000">+     | categories menu | <br>
+     categories := aPreference categoryList.<br>
+     categories size = 0<br>
+         ifTrue: [^ self].<br>
+     categories size = 1<br>
+         ifTrue: [^ self selectedCategory: categories first].<br>
+     <br>
+     menu := MenuMorph new defaultTarget: self.<br>
</span>    aPreference categoryList do:<br>
<span style="color: #0000FF">-         [:aCategory | aMenu add: aCategory target: self selector: #selectedCategory: argument: aCategory].<br>
-     aMenu popUpInWorld<br>
</span><span style="color: #FF0000">+         [:aCategory | menu add: aCategory target: self selector: #selectedCategory: argument: aCategory].<br>
+     menu popUpInWorld</span><br>
<br>
<b>PreferenceBrowserMorph>>assureKeyboardFocus: {event handling} · ct 11/1/2021 23:14</b><br>
<span style="color: #FF0000">+ assureKeyboardFocus: aHandMorph<br>
+ <br>
+     aHandMorph keyboardFocus = self<br>
+         ifTrue: [^ self].<br>
+     <br>
+     (aHandMorph keyboardFocus notNil and: [aHandMorph keyboardFocus hasOwner: self])<br>
+         ifTrue: [^ self].<br>
+     <br>
+     aHandMorph newKeyboardFocus: self.</span><br>
<br>
<b>PreferenceBrowserMorph>>mouseDownOn:event: {event handling} · ct 11/1/2021 23:13 (changed)</b><br>
mouseDownOn: aPreferenceView event: anEvent<br>
<span style="color: #0000FF">-     anEvent hand newKeyboardFocus: self preferenceList scroller.<br>
</span><span style="color: #FF0000">+     self assureKeyboardFocus: anEvent hand.<br>
</span>    anEvent yellowButtonPressed<br>
        ifTrue: [aPreferenceView offerPreferenceNameMenu: self model]<br>
<br>
<b>PreferenceView>>browse {user interface} · ct 11/1/2021 22:43</b><br>
<span style="color: #FF0000">+ browse<br>
+ <br>
+     ^ self preference browse</span><br>
<br>
<b>PreferenceView>>browseSenders {user interface} · ct 11/1/2021 22:42</b><br>
<span style="color: #FF0000">+ browseSenders<br>
+ <br>
+     ^ self preference browseSenders</span><br>
<br>
<br>
<span style="color: #808080">---<br>
</span><i><span style="color: #808080">Sent from </span></i><i><u><a href="https://github.com/hpi-swa-lab/squeak-inbox-talk"><span style="color: #808080">Squeak Inbox Talk</span></a></u></i>
</div></blockquote>
                                        </div></body>