• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

moosetechnology / MooseIDE / 12912430061

22 Jan 2025 04:15PM UTC coverage: 67.268% (-0.003%) from 67.271%
12912430061

push

github

ClotildeToullec
Update browsers menu.

0 of 26 new or added lines in 5 files covered. (0.0%)

2 existing lines in 2 files now uncovered.

20605 of 30631 relevant lines covered (67.27%)

1.34 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

46.85
/src/MooseIDE-Core/MiAbstractBrowser.class.st
1
"
2
I am superclass for all browsers in Midas.
3
I provide a toolBar with:
4
        - Radio buttons to choose a reception mode: Follow, Freeze and Highlight.
5
        - Buttons to inspect and propagate the current selection.
6
        - A help button that shows the class comment for each browser. 
7

8
Concrete browsers should use my instance variable #model (MVC model, not Moose model).
9
It is created by the default #open method on class side. 
10
The model should inherit from MiAbstractModel and override:
11
Instance side:
12
        - #canFollowEntity: | which entities the browser can receive
13
        - #followEntity | what to do with the received entity in Follow mode
14
        - #highlightEntity | what to do with the received entity in Highlight mode
15
        - #miSelectedItem | entity (or entities) to propagate
16
Class side:        
17
        - #title | The browser window title
18
        - #menuCommandOn: | To be integrated into Midas Browsers menu
19
Spec2 methods: 
20
        #initializePresenters, #defaultLayout, ...
21

22
Please comment your browser as follow: 
23
*************************************************
24
A few lines describing the browser purpose.
25

26
- Follow:
27
Entities accepted and associated behavior.
28

29
- Highlight:
30
Highlight behavior.
31

32
- Propagate:
33
Propagated entities.
34
*************************************************
35
"
36
Class {
37
        #name : #MiAbstractBrowser,
38
        #superclass : #MiPresenter,
39
        #instVars : [
40
                'buses',
41
                'receivingMode',
42
                'specModel',
43
                'inspector'
44
        ],
45
        #category : #'MooseIDE-Core-Browser'
46
}
47

48
{ #category : #accessing }
NEW
49
MiAbstractBrowser class >> allBrowsers [
×
NEW
50

×
NEW
51
        ^ self allSubclasses reject: #isAbstract
×
NEW
52
]
×
53

54
{ #category : #menu }
NEW
55
MiAbstractBrowser class >> allBrowsersMenuRoot: aRootMenu action: aBlock [
×
NEW
56

×
NEW
57
        (self allBrowsers sortAscending: #menuPriority) do: [ :browserClass |
×
NEW
58
                browserClass buildItemInMenu: aRootMenu action: aBlock ].
×
NEW
59

×
NEW
60
        ^ aRootMenu
×
NEW
61
]
×
62

63
{ #category : #keymaps }
64
MiAbstractBrowser class >> browserKey [
×
65

×
66
        "Override with a character to be used after m (for Moose) to open your browser"
×
67

×
68
        ^ nil
×
69
]
×
70

71
{ #category : #menu }
72
MiAbstractBrowser class >> buildItemInMenu: aMenuGroupPresenter action: aBlock [
×
73

×
74
        self isAbstract ifTrue: [ ^ self ].
×
75

×
76
        aMenuGroupPresenter addItem: [ :item |
×
77
                item
×
78
                        name: self title;
×
NEW
79
                        action: [ aBlock cull: self ];
×
80
                        help: self helpMessage;
×
81
                        icon: self menuIcon ]
×
82
]
×
83

84
{ #category : #'world menu' }
85
MiAbstractBrowser class >> buildMenuItemIn: aBuilder [
×
86

×
87
        "Method used in subclasses"
×
88

×
89
        ^ (aBuilder item: self menuItem)
×
90
                  parent: self menuParent;
×
91
                  label: self menuLabel;
×
92
                  icon: self menuIcon;
×
93
                  help: self helpMessage;
×
94
                  order: self menuPriority;
×
95
                  action: [ self open ];
×
96
                  keyText: self keyText;
×
97
                  yourself
×
98
]
×
99

100
{ #category : #'world menu' }
101
MiAbstractBrowser class >> buildMenuItemIn: aBuilder action: aBlock [
×
102
        "Method used in subclasses"
×
103

×
104
        ^ (aBuilder item: self menuItem)
×
105
                  parent: self menuParent;
×
106
                  label: self menuLabel;
×
107
                  icon: self menuIcon;
×
108
                  help: self helpMessage;
×
109
                  order: self menuPriority;
×
110
                  action: aBlock;
×
111
                  keyText: self keyText;
×
112
                  yourself
×
113
]
×
114

115
{ #category : #'world menu' }
116
MiAbstractBrowser class >> famixMenuRoot [
×
117

×
118
        ^ #Famix
×
119
]
×
120

121
{ #category : #'world menu' }
122
MiAbstractBrowser class >> helpMessage [
×
123

×
124
        ^ self comment ifNil: [ '' ] ifNotNil: [ :comment |
×
125
                  String streamContents: [ :s |
×
126
                          comment lineIndicesDo: [ :start :end :ignored |
×
127
                                  start = (end + 1) ifTrue: [ "stop at empty line" ^ s contents ].
×
128
                                  start = 1 ifFalse: [ s nextPut: Character cr ].
×
129
                                  start to: end do: [ :i | s nextPut: (comment at: i) ] ] ] ]
×
130
]
×
131

132
{ #category : #testing }
133
MiAbstractBrowser class >> isAbstract [ 
×
134
        ^ self == MiAbstractBrowser
×
135
]
×
136

137
{ #category : #testing }
138
MiAbstractBrowser class >> isModelImporter [
×
139
        ^false
×
140
]
×
141

142
{ #category : #keymaps }
143
MiAbstractBrowser class >> keyText [
×
144

×
145
        ^ self browserKey ifNotNil: [ :aCharacter |
×
146
                  'M, {1}' format: { aCharacter asUppercase } ]
×
147
]
×
148

149
{ #category : #'world menu' }
150
MiAbstractBrowser class >> menuCodeToolsPriority [
×
151

×
152
        ^ 20
×
153
]
×
154

155
{ #category : #'world menu' }
156
MiAbstractBrowser class >> menuCommandOn: aBuilder [
×
157
        "Library > Famix > Old browsers"
×
158

×
159
        <worldMenu>
×
160
        (aBuilder item: self oldBrowserMenuRoot)
×
161
                parent: self famixMenuRoot;
×
162
                icon: self menuIcon;
×
NEW
163
                order: self menuOldBrowsersPriority
×
164
]
×
165

166
{ #category : #'world menu' }
167
MiAbstractBrowser class >> menuIcon [
×
168

×
169
        ^ self iconNamed: self menuIconName
×
170
]
×
171

172
{ #category : #'world menu' }
173
MiAbstractBrowser class >> menuIconName [
×
174

×
175
        "Override if needed"
×
176

×
177
        ^ #blank
×
178
]
×
179

180
{ #category : #'world menu' }
181
MiAbstractBrowser class >> menuItem [
182

183
        self subclassResponsibility
184
]
185

186
{ #category : #'world menu' }
187
MiAbstractBrowser class >> menuLabel [
×
188

×
189
        "Override if necessary"
×
190

×
191
        ^ self title
×
192
]
×
193

194
{ #category : #'world menu' }
195
MiAbstractBrowser class >> menuMainToolsPriority [
×
196

×
197
        ^ 0
×
198
]
×
199

200
{ #category : #'world menu' }
201
MiAbstractBrowser class >> menuMetaToolsPriority [
×
202

×
203
        ^ 40
×
204
]
×
205

206
{ #category : #'world menu' }
NEW
207
MiAbstractBrowser class >> menuOldBrowsersPriority [
×
NEW
208

×
NEW
209
        ^ 200
×
NEW
210
]
×
211

212
{ #category : #'world menu' }
213
MiAbstractBrowser class >> menuParent [
×
214

×
215
        "Override if necessary"
×
216

×
217
        ^ self mooseMenuRoot
×
218
]
×
219

220
{ #category : #'world menu' }
221
MiAbstractBrowser class >> menuPharoToolsPriority [
×
222

×
223
        ^ 30
×
224
]
×
225

226
{ #category : #'world menu' }
227
MiAbstractBrowser class >> menuPriority [
×
228

×
229
        ^ 100
×
230
]
×
231

232
{ #category : #'world menu' }
233
MiAbstractBrowser class >> menuVisualizationToolsPriority [
×
234

×
235
        ^ 10
×
236
]
×
237

238
{ #category : #menu }
239
MiAbstractBrowser class >> miBrowsersMenuPresenter [
×
240

×
NEW
241
        ^ self
×
NEW
242
                  allBrowsersMenuRoot: SpMenuPresenter new
×
NEW
243
                  action: [ :browserClass | browserClass open ]
×
UNCOV
244
]
×
245

246
{ #category : #'world menu' }
247
MiAbstractBrowser class >> mooseMenuRoot [
×
248

×
249
        ^ #Moose
×
250
]
×
251

252
{ #category : #'instance creation' }
253
MiAbstractBrowser class >> new [
×
254

×
255
        ^ self on: self newModel
×
256
]
×
257

258
{ #category : #'world menu' }
259
MiAbstractBrowser class >> newBrowser: aBrowserClass [
×
260

×
261
        aBrowserClass open
×
262
]
×
263

264
{ #category : #'instance creation' }
265
MiAbstractBrowser class >> newModel [
×
266
        "Override to return a model (in the MVC sense) for your browser"
×
267

×
268
        ^ nil
×
269
]
×
270

271
{ #category : #'world menu' }
272
MiAbstractBrowser class >> oldBrowserMenuRoot [
×
273

×
274
        ^ #'Old browsers'
×
275
]
×
276

277
{ #category : #'instance creation' }
278
MiAbstractBrowser class >> open [
2✔
279

2✔
280
        ^ (self on: self newModel)
2✔
281
                  open;
2✔
282
                  followBus: self currentApplication defaultBus;
2✔
283
                  yourself
2✔
284
]
2✔
285

286
{ #category : #keymaps }
287
MiAbstractBrowser class >> openKeyMap [
×
288

×
289
        ^ self browserKey ifNotNil: [
×
290
                  KMKeymap shortcut: self shortcut action: [ self open ] ]
×
291
]
×
292

293
{ #category : #'instance creation' }
294
MiAbstractBrowser class >> openOn: anEntity [
×
295

×
296
        ^ (self on: self newModel)
×
297
                  open;
×
298
                  receiveEntity: anEntity;
×
299
                  beFrozen;
×
300
                  followBus: self currentApplication defaultBus;
×
301
                  yourself
×
302
]
×
303

304
{ #category : #keymaps }
305
MiAbstractBrowser class >> shortcut [
×
306

×
307
        ^ self browserKey ifNotNil: [ :aCharacter |
×
308
                  $m shift meta , aCharacter shift meta ]
×
309
]
×
310

311
{ #category : #accessing }
312
MiAbstractBrowser class >> taskbarIcon [
×
313
        ^MooseIcons mooseIcon
×
314

×
315
]
×
316

317
{ #category : #accessing }
318
MiAbstractBrowser class >> titleForModelName: mooseModelName [
2✔
319

2✔
320
        ^ self title , ' (' , mooseModelName , ')'
2✔
321
]
2✔
322

323
{ #category : #specs }
324
MiAbstractBrowser class >> windowSize [
2✔
325

2✔
326
        ^ 500 @ 400
2✔
327
]
2✔
328

329
{ #category : #testing }
330
MiAbstractBrowser >> acceptsDropFileExtension: aString [
×
331
        ^false
×
332
]
×
333

334
{ #category : #actions }
335
MiAbstractBrowser >> beFrozen [
2✔
336

2✔
337
        self receivingMode: MiFreezeMode.
2✔
338
        self window updateReceivingModeButtons
2✔
339
]
2✔
340

341
{ #category : #'window control' }
342
MiAbstractBrowser >> browserClosed [
2✔
343
        buses do: [ :bus | bus unregisterBrowser: self ]
2✔
344
]
2✔
345

346
{ #category : #'window control' }
347
MiAbstractBrowser >> browserCollapsed [
2✔
348

2✔
349
        self beFrozen
2✔
350
]
2✔
351

352
{ #category : #'window control' }
353
MiAbstractBrowser >> browserExpanded [
×
354
        "should we 'unfroze' ?"
×
355
]
×
356

357
{ #category : #accessing }
358
MiAbstractBrowser >> buses [
2✔
359

2✔
360
        ^ buses ifNil: [ Set new ]
2✔
361
]
2✔
362

363
{ #category : #testing }
364
MiAbstractBrowser >> canEditBuses [
2✔
365

2✔
366
        ^ true
2✔
367
]
2✔
368

369
{ #category : #testing }
370
MiAbstractBrowser >> canFollow [
2✔
371

2✔
372
        ^ true
2✔
373
]
2✔
374

375
{ #category : #testing }
376
MiAbstractBrowser >> canFollowEntity: anObject [
377

378
        "whether the browser accepts to deal with anObject"
379

380
        self subclassResponsibility
381
]
382

383
{ #category : #testing }
384
MiAbstractBrowser >> canHighlight [
2✔
385

2✔
386
        "Override to retrun true if you want to give your browser a highlight behavior. 
2✔
387
        This behavior should be define by overriding #highlightEntity:"
2✔
388

2✔
389
        ^ false
2✔
390
]
2✔
391

392
{ #category : #testing }
393
MiAbstractBrowser >> canPropagate [
2✔
394

2✔
395
        | entity |
2✔
396
        "Ideally we should use miSelectedItemToPropagate but this would make the models browser really slow since it would copy the whole model and reject the stubs each time I'm called. So we do not care about checking the stubs here by calling #miSelectedItem.."
2✔
397
        entity := self miSelectedItem.
2✔
398
        ^ (entity isCollection and: [ entity isNotEmpty ]) or: [
2✔
399
                  entity isMooseObject and: [ entity isCollection not ] ]
2✔
400
]
2✔
401

402
{ #category : #testing }
403
MiAbstractBrowser >> canTagEntities [
2✔
404

2✔
405
        ^ true
2✔
406
]
2✔
407

408
{ #category : #'private - for tests' }
409
MiAbstractBrowser >> closeSettings [
2✔
410
        "to close the settings window when testing
2✔
411
        Should not be used otherwise"
2✔
412

2✔
413
        self hasSettings 
2✔
414
        ifTrue: [ self model settings window close]
2✔
415
]
2✔
416

417
{ #category : #layout }
418
MiAbstractBrowser >> defaultLayout [
2✔
419

2✔
420
        ^ SpBoxLayout newVertical
2✔
421
                  add: #mainPresenter;
2✔
422
                  yourself
2✔
423
]
2✔
424

425
{ #category : #buses }
426
MiAbstractBrowser >> followBus: aBus [
2✔
427

2✔
428
        (self buses includes: aBus) ifTrue: [
2✔
429
                application defaultBus: aBus.
2✔
430
                ^ self ].
2✔
431

2✔
432
        self buses add: aBus.
2✔
433
        aBus registerBrowser: self.
2✔
434
        self window ifNotNil: [ :window | window updateBusButton ].
2✔
435
        self receiveEntity: aBus logger mostRecentEntity.
2✔
436
        application defaultBus: aBus
2✔
437
]
2✔
438

439
{ #category : #actions }
440
MiAbstractBrowser >> followEntity: anEntity [
2✔
441
   anEntity ifNotNil: [ self updateWindowTitleWith: anEntity ].
2✔
442
        
2✔
443
]
2✔
444

445
{ #category : #actions }
446
MiAbstractBrowser >> freezeDuring: aBlock [
×
447

×
448
        | previousMode |
×
449
        previousMode := receivingMode.
×
450

×
451
        receivingMode := MiFreezeMode.
×
452

×
453
        aBlock ensure: [ receivingMode := previousMode ]
×
454
]
×
455

456
{ #category : #testing }
457
MiAbstractBrowser >> hasSettings [
2✔
458

2✔
459
        ^false
2✔
460
]
2✔
461

462
{ #category : #testing }
463
MiAbstractBrowser >> hasVisualization [
2✔
464
        
2✔
465
        ^ false
2✔
466
]
2✔
467

468
{ #category : #highlighting }
469
MiAbstractBrowser >> highlightEntity: anEntity [
2✔
470

2✔
471
        "Override to add behavior on highlight. 
2✔
472
        Don't forget to override #canHighlight to return true"
2✔
473

2✔
474
        
2✔
475
]
2✔
476

477
{ #category : #testing }
478
MiAbstractBrowser >> ifAutonomous: aBlock [
×
479
        
×
480
        self owner isNotNil and: [ 
×
481
                self owner isWindowPresenter ifTrue: aBlock ]
×
482
]
×
483

484
{ #category : #initialization }
485
MiAbstractBrowser >> initialize [
2✔
486

2✔
487
        super initialize.
2✔
488
        self setDefaultReceivingMode.
2✔
489
        buses := Set new
2✔
490
]
2✔
491

492
{ #category : #initialization }
493
MiAbstractBrowser >> initializeWindow: aMiWindowPresenter [
2✔
494

2✔
495
        super initializeWindow: aMiWindowPresenter.
2✔
496

2✔
497
        self shouldBuildToolbar ifTrue: [ aMiWindowPresenter buildToolbar ].
2✔
498

2✔
499
        aMiWindowPresenter whenClosedDo: [ self browserClosed ].
2✔
500
        aMiWindowPresenter withAdapterPerformOrDefer: [ :anAdapter |
2✔
501
                self registerToAdapterEvents: anAdapter ].
2✔
502

2✔
503
        aMiWindowPresenter initialExtent: self class windowSize.
2✔
504
        aMiWindowPresenter setContextBindingKeys
2✔
505
]
2✔
506

507
{ #category : #'private - for tests' }
508
MiAbstractBrowser >> inspector [
2✔
509

2✔
510
        ^ inspector ifNil: [ inspector := MiInspectorBrowser ]
2✔
511
]
2✔
512

513
{ #category : #testing }
514
MiAbstractBrowser >> isMiBrowser [
2✔
515
        ^ true
2✔
516
]
2✔
517

518
{ #category : #testing }
519
MiAbstractBrowser >> isModelImporter [
×
520
        ^self class isModelImporter
×
521
]
×
522

523
{ #category : #accessing }
524
MiAbstractBrowser >> miSelectedItem [
×
525

×
526
        ^ (MiNoSelectedElementToPropagateException browser: self) signal
×
527
]
×
528

529
{ #category : #accessing }
530
MiAbstractBrowser >> miSelectedItemToPropagate [
×
531
        "Hook to be able to add some filters in the model browser."
×
532

×
533
        ^ self miSelectedItem
×
534
]
×
535

536
{ #category : #accessing }
537
MiAbstractBrowser >> model [
2✔
538
        ^ specModel
2✔
539
]
2✔
540

541
{ #category : #accessing }
542
MiAbstractBrowser >> model: anObject [
×
543
        specModel := anObject
×
544
]
×
545

546
{ #category : #testing }
547
MiAbstractBrowser >> needUpdate: anEntity [
×
548

×
549
        ^ anEntity ~= specModel selected
×
550
]
×
551

552
{ #category : #'private - accessing' }
553
MiAbstractBrowser >> receiveEntity: anEntity [
2✔
554

2✔
555
        "I am used by the Mi Application. You should use #globallySelect: anEntity that will transmit the message to me and the other browsers"
2✔
556

2✔
557
        receivingMode browser: self actOnEntity: anEntity.
2✔
558
        self updateToolbar
2✔
559
]
2✔
560

561
{ #category : #accessing }
562
MiAbstractBrowser >> receivingMode [
2✔
563

2✔
564
        ^ receivingMode
2✔
565
]
2✔
566

567
{ #category : #accessing }
568
MiAbstractBrowser >> receivingMode: aReceivingMode [
2✔
569

2✔
570
        receivingMode := aReceivingMode
2✔
571
]
2✔
572

573
{ #category : #'window control' }
574
MiAbstractBrowser >> registerToAdapterEvents: anAdapter [
2✔
575
        "spec does not give access to window collapsing/expanding events
2✔
576
         This is a hack to get them on Morph backend"
2✔
577

2✔
578
        anAdapter widget announcer when: WindowCollapsed do: [ self browserCollapsed ] for: self.
2✔
579
        anAdapter widget announcer when: WindowExpanded do: [ self browserExpanded ] for: self
2✔
580
]
2✔
581

582
{ #category : #accessing }
583
MiAbstractBrowser >> selectedTag [
2✔
584

2✔
585
        ^ self model ifNil: [ nil ] ifNotNil: [ :model | model selectedTag ]
2✔
586
]
2✔
587

588
{ #category : #accessing }
589
MiAbstractBrowser >> selectedTag: aTag [
2✔
590

2✔
591
        self model
2✔
592
                ifNil: [ nil ]
2✔
593
                ifNotNil: [ :model | model selectedTag: aTag ].
2✔
594
        self updateToolbar
2✔
595
]
2✔
596

597
{ #category : #initialization }
598
MiAbstractBrowser >> setDefaultReceivingMode [
2✔
599

2✔
600
        self receivingMode: MiFollowMode
2✔
601
]
2✔
602

603
{ #category : #initialization }
604
MiAbstractBrowser >> setModelBeforeInitialization: aBrowserModel [
2✔
605
        aBrowserModel ifNil: [ ^self ].
2✔
606

2✔
607
        specModel := aBrowserModel.
2✔
608
        specModel browser: self
2✔
609
]
2✔
610

611
{ #category : #actions }
612
MiAbstractBrowser >> settings [
2✔
613

2✔
614
        self hasSettings ifTrue: [ specModel openSettings ]
2✔
615
]
2✔
616

617
{ #category : #testing }
618
MiAbstractBrowser >> shouldBuildToolbar [
2✔
619

2✔
620
        ^ true
2✔
621
]
2✔
622

623
{ #category : #accessing }
624
MiAbstractBrowser >> tagList [
2✔
625

2✔
626
        ^self model
2✔
627
                ifNil: [ #() ]
2✔
628
                ifNotNil: [ :model | model tagList ]
2✔
629
]
2✔
630

631
{ #category : #accessing }
632
MiAbstractBrowser >> tagName [
×
633
        ^self selectedTag
×
634
                ifNil: [ '' ]
×
635
                ifNotNil: [ :tag | tag name ]
×
636
]
×
637

638
{ #category : #actions }
639
MiAbstractBrowser >> tagSelectedEntities [
×
640

×
641
        self model ifNotNil: [ :model | model tagSelectedEntities ]
×
642
]
×
643

644
{ #category : #buses }
645
MiAbstractBrowser >> unfollowBus: aBus [
2✔
646

2✔
647
        (self buses includes: aBus) ifFalse: [ ^ self ].
2✔
648
        self buses remove: aBus.
2✔
649
        aBus unregisterBrowser: self.
2✔
650
        self window ifNotNil: [ :window | window updateBusButton ]
2✔
651
]
2✔
652

653
{ #category : #actions }
654
MiAbstractBrowser >> updateToolbar [
2✔
655

2✔
656
        self window ifNotNil: [ :window | window updateToolbar ]
2✔
657
]
2✔
658

659
{ #category : #actions }
660
MiAbstractBrowser >> updateWindowTitleWith: anEntity [
2✔
661

2✔
662
        | modelName |
2✔
663
        modelName := (anEntity isMooseObject and: [ anEntity isMooseModel ])
2✔
664
                             ifTrue: [ anEntity name ]
2✔
665
                             ifFalse: [ anEntity printString ].
2✔
666
        self withWindowDo: [ :window |
2✔
667
                window title: (self class titleForModelName: modelName) ]
2✔
668
]
2✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc