How to clear a cluttered workspace in Pharo? - smalltalk

In the Pharo MOOC there is a proposed challenge (section 2.15.2) that consists in taking a email address and getting the associated gravatar image, as a Morph object. I was able to do it, by running the following code in the playground:
| url email |
email := 'stephane.ducasse#inria.fr'.
url := 'http://www.gravatar.com/avatar/', (MD5 hashMessage: email) hex asString , '.jpg'.
(ZnEasy getJpeg: url) asMorph openInHand.
Now the problem is, I could not figure out how to properly clean my workspace of all the objects downloaded:
As you can see, now I have the image from the url (from a previous botched attempt where I did url asMorph openInHand without getting the jpg with ZnEasy first), and several lighthouse images (as every time I open the inspector a new one is generated).
I say properly clean because you can just exit Pharo without saving, and then open it again to have a clean workspace, but this is probably not ideal.
So far I tried to inspect the created objects, seeing they are instances of ImageMorph. Then in the associated methods I searched something including "erase", "del", "delete" or "clear", but could not find anything similar. These were the available methods for ImageMorph:
{ImageMorph>>#prepareForRotating.
ImageMorph>>#grabFromScreen.
ImageMorph>>#forwardDirection:.
ImageMorph>>#adoptPaneColor:.
ImageMorph>>#drawOnAthensCanvas:.
ImageMorph>>#extent:.
ImageMorph>>#setOptimalResizing.
ImageMorph>>#form:.
ImageMorph>>#shouldFlex.
ImageMorph>>#forwardDirection.
ImageMorph>>#resize:.
ImageMorph>>#areasRemainingToFill:.
ImageMorph>>#heading.
ImageMorph>>#imageExport.
ImageMorph>>#defaultImage.
ImageMorph>>#rotationDegrees.
ImageMorph>>#borderStyle:.
ImageMorph>>#opacityString.
ImageMorph>>#setDirectionFrom:.
ImageMorph>>#rotationDegrees:.
ImageMorph>>#borderWidth:.
ImageMorph>>#isOpaque.
ImageMorph>>#image:.
ImageMorph>>#readFromFile.
ImageMorph>>#drawOn:.
ImageMorph>>#basicExtent:.
ImageMorph>>#form.
ImageMorph>>#withSnapshotBorder.
ImageMorph>>#wantsRecolorHandle.
ImageMorph>>#changeOpacity.
ImageMorph>>#initialize.
ImageMorph>>#addCustomMenuItems:hand:.
ImageMorph>>#isOpaque:.
ImageMorph>>#releaseCachedState.
ImageMorph>>#color:}
I also tried to execute garbageCollect, and just click the images and press Delete.

After opening them in the hand, you have positioned them in the world. If you inspect the world, you'll see there are a number of ImageMorphs. You want to exclude the Pharo logo. If you inspect that, its extension tells you the logo is locked.
World submorphs select: [ :m |
m class = ImageMorph and: [
m isLocked not ] ]
thenDo: [ :m | m delete ]

Another way, which is not so practical in this case, but is unique to smalltalk, is to use #allInstances. You can do
ImageMorph allInstances inspect
which returns all those images. in the raw view of the inspector, you can then send them #delete. Here that is not so practical, as the icons in the windows are also ImageMorphs, so you'll get a long list

Based on the above I used Playground to inspect the World subMorphs. This allows you to identify the unwanted images.
I then used (work SubMorphs at: n) delete to remove them individually. You need to track the indices as they may change each time an image is deleted.

To find all messages an object will understand, have a look at its class and at its superclasses. You will find delete in the Morph class, a superclass of ImageMorph.
Try executing this line by line:
| url email morph |
email := 'stephane.ducasse#inria.fr'.
url := 'http://www.gravatar.com/avatar/', (MD5 hashMessage: email) hex asString , '.jpg'.
morph := (ZnEasy getJpeg: url) asMorph.
morph openInHand.
morph delete.

Related

videojs-thumbnails plugin shows thumbnails at incorrect time

I'm trying to use "videojs-thumbnails" plugin from https://github.com/brightcove/videojs-thumbnails and noticed that thumbnail's time, specified in the plugin configuration is not matching the timestamp in the seek bar. Coming across different comments regarding this issue I found suggestion at https://github.com/brightcove/videojs-thumbnails/issues/43 to replace line
mouseTime = Math.floor((left - progressControl.el().offsetLeft) / progressControl.width() * duration);
to
mouseTime = Math.floor((left) / progressControl.width() * duration);
By removing
- progressControl.el().offsetLeft
However, that produces still not exact time match.
Finally I came with redefined value for the
var left
Getting it from the current value of
.vjs-mouse-display
So, my final codes are:
left=parseInt((document.querySelector('.vjs-mouse-display').style.left),10);
mouseTime = Math.floor((left) / progressControl.width() * duration);
Now everything works correctly.
Greatly appreciate for comments/suggestions.
This is NOT an answer to your specific question / issue, but rather, an alternative implentation approach.
I, too, wanted thumbnails for my video(s), so I proto-typed a page
that used videoJS's plugin. I don't recall all the details of the
issues that I ran into trying to use that plugin, but I finally decided
to abandon the plugin, and design an alternative, which has its own
separate 'slider' just above the viewer. [ One 'drags' my slider,
(rather than hover along it, as you do on YouTube's videos), so that it
can work straight-forwardly on touch-screens...i.e. on Android, etc. ]
And, rather than try to extract images from the video in real-time,
(See: How to generate video preview thumbnails for use in VideoJS? ), I chose to prepare the images, ahead of time, using 'ffmpeg' and the cmd-line interface to 'ImageMagick'.
Details of that part are here:
http://weasel.firmfriends.us/GeeksHomePages/subj-video-and-audio.html#implementing-video-thumbnails
My 'proof-of-concept' webpage based on that approach is here:
https://weasel.firmfriends.us/Private3-BB/
I hope this is helpful.

How does the Global Image ID work ? - Linking Dual-EELS datasets

Is there a way to script a pair of dual-EELS SIs so that DM recognises them as siblings (say, for use in the "SI->Align SI by Peak" menu option)?
I have a script which performs a transformation on a pair of dualEELS SIs where the results are given in new images with all the tags copied from the original. The new SIs do not seem to be acknowledged by the SI options as a pair, however. A MWE of how this occurs is below:
image a, b
GetTwoLabeledImagesWithPrompt("Get SI", \
"Get DualEELS SIs", \
"Low-Loss", a, \
"High-Loss", b)
image LL, HL
LL := a.ImageClone()
HL := b.ImageClone()
LL.ShowImage()
HL.ShowImage()
Assuming that the two inputs are real dualEELS SIs. Attempting afterward to run a method like "SI->Align SI by Peak" on the outputs does not recognise the second SI as a sibling.
I suspect that my issue is in properly assigning the four EELS:Dual acquire sibling:UID tags highlighted in the image provided, however I have no idea how (or if) these are accessible from the scripting language.
Thanks in advance for any help you are able to render.
Yes, "siblings" in DigitalMicrograph are recognized by tag-checks and tagging of the Unique Image Id (UID).
Depending on the exact application/plugin, there might be additional tag-checks before a sibling can be accepted (i.e. "is it EELS data?", "is it spatially compatible?", etc.) but he prime-mechanism is using the UID.
A bit of background info
The UID is a set of four long-numbers generated at random whenever a new image data is created, and then subsequently stored with the data. It is "unique" by the assumption that a set of four randomly generated 8-byte longs are "unique".
If you create an image, save it to disc, and open it, the UID will be the same. (It is stored with the data.)
If you ImageClone() an image, it gets a new UID.
If you copy a image file on the hard drive and rename it, it will retain the UID.
Creating and using UIDs
The commands to get an image's UID are described in the F1 help documentation here:
And the example section even has a script showing how one uses UID to "link" data together:

Variable does not save event.response from network.request -Lua

I am trying to create a Lua program using Sublime and Corona. I want to fetch a webpage, use a pattern to extract certain text from the page, and then save the extracted text into a table. I am using the network.request method provided by Corona
The problem: The extracted text is not saving into the global variable I created. Whenever I try to reference it or print it outside of the function it returns nil. Any ideas why this is happening?
I have attached a screen shot of my event.response output. This is what I want to be saved into my Lua table
Event.response Output
Here is my code:
local restaurants = {}
yelpString = ""
--this method tells the program what to do once the website is retrieved
local function networkListener( event )
if ( event.isError ) then
print( "Network error: ", event.response )
else
yelpString = event.response
--loops through the website to find the pattern that extracts
restaurant names and prints it out
for i in string.gmatch(yelpString, "<span >(.-)<") do
table.insert(restaurants, i)
print(i)
end
end
end
-- retrieves the website
network.request( "https://www.yelp.com/search?
cflt=restaurants&find_loc=Cleveland%2C+OH%2C+US", "GET", networkListener )
This sounds like a scoping problem. From the output you give, it looks like networkListener is being called, and you are successfully adding the text into the restaurants table. Moreover, since you define restaurants as a table, it should be a table when you reference it, not nil. So by deduction, the issue must be that you are trying to access the restaurants table from somewhere where it is not in scope.
If you declare restaurants as "local" in the top level of a file (i.e. not within a function or a block), it will be accessible to the whole file, but it won't be accessible to anything outside the file. So the table.insert(restaurants, i) in your code will work, but if you try to reference restaurants from somewhere outside the file, it will be nil. I'm guessing this is the cause of the problems that you are running into.
For more details on scope, have a look at the Programming in Lua book. The book is for Lua 5.0, but the scoping rules for local variables have not changed in later versions of Lua (as of this writing, the latest is Lua 5.3).

Synchronize modification between SWT table and TextEditor

I'm facing a problem and want to ask for a solution.
I'm working on an eclipse plugin project, in which an editor for a type of resource file is required. The resource file has similar structure like CSV file. My idea is to provide user the option to edit this type of file both in plain text format and also in an SWT table. Plain text is required for examining data and table provides more flexibility to editing such as sorting by column.
I have been able to create a MultiPageEditorPart, with one page of org.eclipse.ui.editors.text.TextEditor, and another page with a org.eclipse.swt.widgets.Table and several other widgets like search bar. The content of the resource file can be shown in the TextEditor, can also be edited and saved. On the other hand, the content can be loaded in the table too, sorting and searching all work good.
The problem is: when I edit a cell in the table, I want the change also reflected in the TextEditor, and vice versa. Since the resource file can be very large, I want the saving action happen only on the TextEditor, i.e. I don't want any modification in the table directly stored to resource file, but to mark the file dirty, but I can't figure out how. How can I for example get the content of EditorInput, check it line by line, and modify it outside TextEditor?
Or, are there more efficient ways to do this? Can anyone give any hints?
The IDocument used by the TextEditor gives you access to the document contents. Get this with something like:
IDocumentProvider provider = editor.getDocumentProvider();
IEditorInput input = editor.getEditorInput();
IDocument document = provider.getDocument(input);
IDocument has many methods for accessing lines such as:
int getLineOffset(int line);
int getLineLength(int line);
and methods for modify the text:
void replace(int offset, int length, String text);

Eclipse RCP: How to order perspective buttons belonging to different plugins?

My application has 5 plugins. Each plugin has a perspective of it's own and hence each perspective extension definition is under individual plugin's plugin.xml.
Now, I want to control the order in which these perspectives appear in my application. How to do it?
There is one main plugin that holds "ApplicationWorkBenchAdvisor.java". This has initialize() method in which I am iterating through the perspective registry using
PlatformUI.getWorkbench().getPerspectiveRegistry().getPerspectives();
and then appending perspective ids in a comma separated fashion to a String variable (pbar) which is used later like this.
PlatformUI.getPreferenceStore().setDefault(IWorkbenchPreferenceConstants.PERSPECTIVE_BAR_EXTRAS, pbar);
PlatformUI.getPreferenceStore().setValue(IWorkbenchPreferenceConstants.PERSPECTIVE_BAR_EXTRAS, pbar);
When iterating thourgh the perspective registry, I can compare perspective ids and sort it(when adding to 'pbar' by comparing ids) the way I want it to appear but, I don't want to do this ordering here as it appears like a dirty way.
Is there any other place where we can fix the order in which perspectives appear? (Each perspective resides in different plugin).
ADDED
1) Could we also control the ordering in the perspective switcher?
2) Is there a way to control entry into perspective registry to in inflict the desired order. If not could we write back into perspective registry?
If your application is encapsulated as an eclipse product, you may tweak the plugin.properties/plugin_customization.ini file.
(file referenced by the 'preferenceCustomization' property in your product extension point.)
This file is a java.io.Properties format file. Typically this file is used to set the values for preferences that are published as part of a plug-in's public API.
(Example of such a file for org.eclipse.platform)
So if the string representing the order of perspective can be referenced as a property, you can define the default order in there.
Since the source code of IWorkbenchPreferenceConstants mentions:
/**
* Lists the extra perspectives to show in the perspective bar.
* The value is a comma-separated list of perspective ids.
* The default is the empty string.
*
* #since 3.2
*/
public static final String JavaDoc PERSPECTIVE_BAR_EXTRAS = "PERSPECTIVE_BAR_EXTRAS"; //$NON-NLS-1$
Maybe a line in the plugin_customization.ini file:
org.eclipse.ui/PERSPECTIVE_BAR_EXTRAS=perspectiveId1,perspectiveId2,perspectiveId3
would allow you to specify that order without having to hard-code it.
Additional notes:
IPerspectiveRegistry (or PerspectiveRegistry) is not made to write anything (especially for perspective defined in an extension)
Ordering may be found in the state of the workbench (stored in the workspace and then restored when its launched again, .metadata/.plugins/org.eclipse.ui.workbench/workbench.xml)
Do you confirm that:
IPerspectiveRegistry registry = PlatformUI.getWorkbench().getPerspectiveRegistry();
IPerspectiveDescriptor[] perspectives = registry.getPerspectives();
is not in the right order when the plugin_customization.ini does define that order correctly ?
Liverpool 5 - 0 Aston Villa does confirm that (in the comments), but also indicates the (ordered) ini file entries internally get recorded into preference store, which means they can be retrieved through the preference store API:
PatformUI.getPreferenceStore().getDefault(
IWorkbenchPreferenceConstants.PERSPECTIVE_BAR_EXTRAS)
Liverpool 5 - 0 Aston Villa then add:
perspective registry (the initial "PlatformUI.getWorkbench().getPerspectiveRegistry().getPerspectives();" bit) remains unaltered (and unordered).
But, you still can "readily access to ordered list of perspectives" through preference store.
So, for other tasks, instead of iterating though perspective registry (which is still unordered), we can use the ordered variable that stores list of ordered perpective ids.
.
.
.
.
Note: another possibility is to Replace the Perspective-Switcher in RCP apps
=> to:
You can more easily define the order in a menu or in buttons there.
Extreme solution: re-implement a perspective switcher.
To sum up all the observations and findings,
1) It is not possible to alter entries in the perspective registry. It is read-only.
2) To make perspective appear in the order that we want on perspective bar, we can achieve it by adding an entry in plugin_customization.ini (or preferences.ini) as shown below.
org.eclipse.ui/PERSPECTIVE_BAR_EXTRAS=perspectiveId1,perspectiveId2,perspectiveId3
3) If we want to fetch this ordered list, we can't fetch it directly. But as this ini file entry internally gets recorded in PreferenceStore we can fetch the same value from PreferenceStore using the following API as shown below.
PlatformUI.getPreferenceStore().getDefault(
IWorkbenchPreferenceConstants.PERSPECTIVE_BAR_EXTRAS);
Why would someone need to access the entry defined in ini file at all?
Well, in my case I had a view in which i had to display links to every perspective. As my perspective bar was sorted in desired order, I also wanted to maintain the same order in my view while displaying links to perspectives.
4) There is no known way to inflict the same sort order in the display of default perspective switcher. While a new custom perspective switcher can be written to achieve the desired effect.