Creating a dynamic eclipse "Welcome" page button - java

i am wondering, whether the code to create the buttons shown at the eclipse "Welcome" page can be found somewhere.
When you create a new workspace in eclipse, a "Welcome" page is shown at the very beginning. The page shows different type of buttons like, "What is new", "Tutorials", ...
I want to use these type of buttons, but was not able to find the source code inside eclipse.
Does somebody know how to create such a button, with hide composites and dynimic components.

You can try and explore the org.eclipse.ui.internal.WorkbenchIntroManager class, in charge of building a ViewIntroAdapterPart, based on informations found in the ViewIntroAdapterSite
From getViewIntroAdapterPart():
* #return the <code>ViewIntroAdapterPart</code> for this workbench, <code>null</code> if it
* cannot be found.
*/
/*package*/ViewIntroAdapterPart getViewIntroAdapterPart() {
IWorkbenchWindow[] windows = this.workbench.getWorkbenchWindows();
for (int i = 0; i < windows.length; i++) {
IWorkbenchWindow window = windows[i];
WorkbenchPage page = (WorkbenchPage) window.getActivePage();
if (page == null) {
continue;
}
IPerspectiveDescriptor[] perspDescs = page.getOpenPerspectives();
for (int j = 0; j < perspDescs.length; j++) {
IPerspectiveDescriptor descriptor = perspDescs[j];
IViewReference reference = page.findPerspective(descriptor)
.findView(IIntroConstants.INTRO_VIEW_ID);
if (reference != null) {
IViewPart part = reference.getView(false);
if (part != null && part instanceof ViewIntroAdapterPart) {
return (ViewIntroAdapterPart) part;
}
}
}
}
return null;
}
Each perspective contributes to the IntroPart, based on its IPerspectiveDescriptor, if it includes a ViewIntroAdapterPart.
The ViewPart will create IIntroPart, which contains the graphical visible elements.

Related

How to add text outlines to text within Powerpoint via Apache POI:

Does anyone have an idea how we can add outlines to text (text outline) within powerpoint templates (ppxt) using Apache POI? What I have gathered so far is that the XSLFTextRun class does not have a method to get/ set the text outline for a given run element.
And as such, I could only persist the following font/ text styles:
def fontStyles(textBox: XSLFTextBox, textRun: XSLFTextRun): Unit = {
val fontFamily = textRun.getFontFamily
val fontColor = textRun.getFontColor
val fontSize = textRun.getFontSize
val fontBold = textRun.isBold
val fontItalic = textRun.isItalic
val textAlign = textRun.getParagraph.getTextAlign
textBox.getTextParagraphs.foreach { p =>
p.getTextRuns.foreach { tr =>
tr.setFontFamily(fontFamily)
tr.setFontColor(fontColor)
tr.setFontSize(fontSize)
tr.setBold(fontBold)
tr.setItalic(fontItalic)
tr.getParagraph.setTextAlign(textAlign)
}
}
}
Is it possible to add text outline?
Any assistance/ suggestions would be highly appreciated.
Apache poi uses underlying ooxml-schemas classes. Those are auto generated from Office Open XML standard. So they are more complete than the high level XSLF classes. Of course they are much less convenient.
So if somewhat is not implemented in high level XSLF classes, we can get the underlying CT classes and do it using those. In case of XSLFTextRun we can get the CTRegularTextRun object. Then we can look whether there are run properties already. If not, we add one. Then we look whether there is outline set already. If so, we unset it, because we want set it new. Then we set a new outline. This simply is a line having a special color. That line is represented by CTLineProperties object. So we need to have methods to create that CTLineProperties, to set CTLineProperties to the XSLFTextRun and get CTLineProperties from XSLFTextRun.
Complete example using Java code:
import java.io.FileOutputStream;
import java.io.FileInputStream;
import org.apache.poi.xslf.usermodel.*;
import org.apache.poi.sl.usermodel.*;
import java.awt.Rectangle;
public class PPTXTextRunOutline {
static org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties createSolidFillLineProperties(java.awt.Color color) {
// create new CTLineProperties
org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties lineProperties
= org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties.Factory.newInstance();
// set line solid fill color
lineProperties.addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()});
return lineProperties;
}
static void setOutline(XSLFTextRun run, org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties lineProperties) {
// get underlying CTRegularTextRun object
org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun ctRegularTextRun
= (org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun)run.getXmlObject();
// Are there run properties already? If not, add one.
if (ctRegularTextRun.getRPr() == null) ctRegularTextRun.addNewRPr();
// Is there outline set already? If so, unset it, because we are creating it new.
if (ctRegularTextRun.getRPr().isSetLn()) ctRegularTextRun.getRPr().unsetLn();
// set a new outline
ctRegularTextRun.getRPr().setLn(lineProperties);
}
static org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties getOutline(XSLFTextRun run) {
// get underlying CTRegularTextRun object
org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun ctRegularTextRun
= (org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun)run.getXmlObject();
// Are there run properties already? If not, return null.
if (ctRegularTextRun.getRPr() == null) return null;
// get outline, may be null
org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties lineProperties = ctRegularTextRun.getRPr().getLn();
// make a copy to avoid orphaned exceptions or value disconnected exception when set to its own XML parent
if (lineProperties != null) lineProperties = (org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties)lineProperties.copy();
return lineProperties;
}
// your method fontStyles taken to Java code
static void fontStyles(XSLFTextRun templateRun, XSLFTextShape textShape) {
String fontFamily = templateRun.getFontFamily();
PaintStyle fontColor = templateRun.getFontColor();
Double fontSize = templateRun.getFontSize();
boolean fontBold = templateRun.isBold();
boolean fontItalic = templateRun.isItalic();
TextParagraph.TextAlign textAlign = templateRun.getParagraph().getTextAlign();
org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties lineProperties = getOutline(templateRun);
for (XSLFTextParagraph paragraph : textShape.getTextParagraphs()) {
for (XSLFTextRun run : paragraph.getTextRuns()) {
run.setFontFamily(fontFamily);
if(run != templateRun) run.setFontColor(fontColor); // set PaintStyle has the issue which I am avoiding by using a copy of the underlying XML
run.setFontSize(fontSize);
run.setBold(fontBold);
run.setItalic(fontItalic);
run.getParagraph().setTextAlign(textAlign);
setOutline(run, lineProperties);
}
}
}
public static void main(String[] args) throws Exception {
XMLSlideShow slideShow = new XMLSlideShow(new FileInputStream("./PPTXIn.pptx"));
XSLFSlide slide = slideShow.getSlides().get(0);
//as in your code, get a template text run and set its font style to all other runs in text shape
if (slide.getShapes().size() > 0) {
XSLFShape shape = slide.getShapes().get(0);
if (shape instanceof XSLFTextShape) {
XSLFTextShape textShape = (XSLFTextShape) shape;
XSLFTextParagraph paragraph = null;
if(textShape.getTextParagraphs().size() > 0) paragraph = textShape.getTextParagraphs().get(0);
if (paragraph != null) {
XSLFTextRun run = null;
if(paragraph.getTextRuns().size() > 0) run = paragraph.getTextRuns().get(0);
if (run != null) {
fontStyles(run, textShape);
}
}
}
}
//new text box having outlined text from scratch
XSLFTextBox textbox = slide.createTextBox();
textbox.setAnchor(new Rectangle(100, 300, 570, 80));
XSLFTextParagraph paragraph = null;
if(textbox.getTextParagraphs().size() > 0) paragraph = textbox.getTextParagraphs().get(0);
if(paragraph == null) paragraph = textbox.addNewTextParagraph();
XSLFTextRun run = paragraph.addNewTextRun();
run.setText("Test text outline");
run.setFontSize(60d);
run.setFontColor(java.awt.Color.YELLOW);
setOutline(run, createSolidFillLineProperties(java.awt.Color.BLUE));
FileOutputStream out = new FileOutputStream("./PPTXOit.pptx");
slideShow.write(out);
out.close();
}
}
Tested and works using current apache poi 5.0.0.

Below code is not woking with Chrome browser

I have created a reusable function which clicks the check box of a particular row and returns the text of that row.
CheckBoxXpath-> private static final String XPATH_JOBRATECATEGORIES_CHECKBOX_LIST = "//kendo-grid-list//table/tbody/tr/td[1]/label";
RowXpath -> private static final String XPATH_JOBRATECATEGORIES_LIST = "//kendo-grid-list//table/tbody/tr/td[2]//div//div";
count-> 0 (I want to click only first row check box)
public String Select_CheckBox_Return_SelectedText(String CheckBoxXpath,String RowXpath, int Count) {
List<WebElementFacade> listOfCheckBox = findAll(By.xpath(CheckBoxXpath));
List<WebElementFacade> listOfrow = findAll(By.xpath(RowXpath));
if(listOfCheckBox.size()>Count) {
for (int i = 0; i <= Count; i++) {
listOfCheckBox.get(i).click();
String Actual=listOfrow.get(i).getText();
}
}else {
Assert.fail("Need to have more rows to fullfill the requirement");
return null;
}
return Actual;
}
This is working fine with Firefox browser, but not working with Chrome browser.
On debugging code is throwing exception on -> "listOfCheckBox.get(i).click();"
I am not able to understand why it is behaving so weired.
Need help. Thanks in advance.
You need to target the checkboxes, not the labels in your xpath:
//kendo-grid-list//table/tbody/tr/td[1]/input[#type='checkbox']

eclipse - How to remove Switch Workspace in File menu -

When my application loads up I don't want the File menu to have switch workspace option I am trying with hideActionSet() method but till now I am unable to find which plugin shall I write in that so that it hides switch Workspace option.
Goto Window > Perspective > Customize Perspective
Select Menu Visibility tab
Expand File
Uncheck Switch Workspace
And you can save it as a new perspective tagged with name -
Window > Perspective > Save Perspective as...
The following way this can be resolved:
for (int i = 0; i < menuManager.getItems().length; i++) {
IContributionItem item = menuManager.getItems()[i];
if (item instanceof MenuManager) {
hideSwitchWorkSpace((MenuManager) item);}
private void hideSwitchWorkSpace(MenuManager manager) {
if (manager.getMenuText() != null && manager.getId() != null
&& manager.getMenuText().equals("&File") && manager.getId().matches("file"))
{
for (int i = 0; i < manager.getItems().length; i++) {
IContributionItem item = manager.getItems()[i];
if (item.getId() != null
&&(item.getId().matches("openWorkspace"))) {
item.setVisible(false);
}
}
}

Cached elements do not exist in DOM anymore

Like in similar issue, I use appium + java. Trying to select elements
In mobile application I am go to page, and after that, have many elements android.widget.ImageView(0), I need to select 6 (for example) such elements and go with other steps. Byt can select only one element and then get such exception:
org.openqa.selenium.StaleElementReferenceException: Cached elements 'By.id: com.company:id/selector_view' do not exist in DOM anymore
public GalleryPage choosePhotosFromAlbum(int count) {
List<MobileElement> photos = driver.findElementsById(elements.get("photo from gallery album selector"));
for (int i = 0; i < count; i++) {
photos.get(i).click();
}
return new GalleryPage(device);
}
I had the same issue. I think this happens because every time you click on a photo, the DOM changes. So, when you try to click on the second photo, the cached elements are not on the DOM anymore.
Try putting the photos inside the for cycle, like this:
public GalleryPage choosePhotosFromAlbum(int count) {
for (int i = 0; i < count; i++) {
List<MobileElement> photos = driver.findElementsById(elements.get("photo from gallery album selector"));
photos.get(i).click();
}
return new GalleryPage(device);
}
This way the list of photos is retrieved from the refreshed DOM on every cycle.
And by the way, you're not checking if the count is bigger than the photos list size, which can result in an OutOfBounds exception or similar.
You can use explicit wait to solve this problem.
public GalleryPage choosePhotosFromAlbum(int count)
{
List<MobileElement> photos = driver.findElementsById(elements.get("photo from gallery album selector"));
for (int i = 0; i < count; i++)
{
new WebDriverWait(driver,10).until(ExpectedConditions.presenceOfAllElementsLocatedBy("Your object property"));
photos.get(i).click();
}
return new GalleryPage(device);
}
Try enableMultiWindows appium capability set to true https://github.com/appium/appium/blob/master/docs/en/advanced-concepts/settings.md
Or you can try finding elements via WebDriverWait. In Appium (C#), when the driver tries to find native elements, it can sometimes throw a StaleElementReferenceException. Thus you can ignore this exception and wait until elements exist in DOM:
public ReadOnlyCollection<IWebElement> WaitElements(By selector)
{
var wait = new WebDriverWait(this.Driver, new TimeSpan(0, 0, 10));
ReadOnlyCollection<IWebElement> results = null;
try
{
wait.Until(driver =>
{
try
{
var elements = driver.FindElements(selector);
if (elements.Any())
{
results = elements;
return true;
}
}
catch (StaleElementReferenceException)
{
// ignore
}
return false;
});
}
catch (WebDriverTimeoutException)
{
throw new NoSuchElementException("Elements not found");
}
return results;
}

How to edit a Hyperlink in a Word Document using Apache POI?

So I've been browsing around the source code / documentation for POI (specifically XWPF) and I can't seem to find anything that relates to editing a hyperlink in a .docx. I only see functionality to get the information for the currently set hyperlink. My goal is to change the hyperlink in a .docx to link to "http://yahoo.com" from "http://google.com" as an example. Any help would be greatly appreciated. Thanks!
I found a way to edit the url of the link in a "indirect way" (copy the previous hyperlink, modify the url, delete the previous hyperlink and add the new one in the paragraph).
Code is shown below:
private void editLinksOfParagraph(XWPFParagraph paragraph, XWPFDocument document) {
for (int rIndex = 0; rIndex < paragraph.getRuns().size(); rIndex++) {
XWPFRun run = paragraph.getRuns().get(rIndex);
if (run instanceof XWPFHyperlinkRun) {
// get the url of the link to edit it
XWPFHyperlink link = ((XWPFHyperlinkRun) run).getHyperlink(document);
String linkURL = link.getURL();
//get the xml representation of the hyperlink that includes all the information
XmlObject xmlObject = run.getCTR().copy();
linkURL += "-edited-link"; //edited url of the link, f.e add a '-edited-link' suffix
//remove the previous link from the paragraph
paragraph.removeRun(rIndex);
//add the new hyperlinked with updated url in the paragraph, in place of the previous deleted
XWPFHyperlinkRun hyperlinkRun = paragraph.insertNewHyperlinkRun(rIndex, linkURL);
hyperlinkRun.getCTR().set(xmlObject);
}
}
}
This requirement needs knowledge about how hyperlinks referring to an external reference get stored in Microsoft Word documents and how this gets represented in XWPF of Apache POI.
The XWPFHyperlinkRun is the representation of a linked text run in a IRunBody. This text run, or even multiple text runs, is/are wrapped with a XML object of type CTHyperlink. This contains a relation ID which points to a relation in the package relations part. This package relation contains the URI which is the hyperlink's target.
Currently (apache poi 5.2.2) XWPFHyperlinkRun provides access to a XWPFHyperlink. But this is very rudimentary. It only has getters for the Id and the URI. It neither provides access to it's XWPFHyperlinkRun and it's IRunBody nor it provides a setter for the target URI in the package relations part. It not even has internally access to it's the package relations part.
So only using Apache POI classes the only possibility currently is to delete the old XWPFHyperlinkRun and create a new one pointing to the new URI. But as the text runs also contain the text formatting, deleting them will also delete the text formatting. It would must be copied from the old XWPFHyperlinkRun to the new before deleting the old one. That's uncomfortable.
So the rudimentary XWPFHyperlink should be extended to provide a setter for the target URI in the package relations part. A new class XWPFHyperlinkExtended could look like so:
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
/**
* Extended XWPF hyperlink class
* Provides access to it's Id, URI, XWPFHyperlinkRun, IRunBody.
* Provides setting target URI in PackageRelationship.
*/
public class XWPFHyperlinkExtended {
private String id;
private String uri;
private XWPFHyperlinkRun hyperlinkRun;
private IRunBody runBody;
private PackageRelationship rel;
public XWPFHyperlinkExtended(XWPFHyperlinkRun hyperlinkRun, PackageRelationship rel) {
this.id = rel.getId();
this.uri = rel.getTargetURI().toString();
this.hyperlinkRun = hyperlinkRun;
this.runBody = hyperlinkRun.getParent();
this.rel = rel;
}
public String getId() {
return this.id;
}
public String getURI() {
return this.uri;
}
public IRunBody getIRunBody() {
return this.runBody;
}
public XWPFHyperlinkRun getHyperlinkRun() {
return this.hyperlinkRun;
}
/**
* Provides setting target URI in PackageRelationship.
* The old PackageRelationship gets removed.
* A new PackageRelationship gets added using the same Id.
*/
public void setTargetURI(String uri) {
this.runBody.getPart().getPackagePart().removeRelationship(this.getId());
this.uri = uri;
PackageRelationship rel = this.runBody.getPart().getPackagePart().addExternalRelationship(uri, XWPFRelation.HYPERLINK.getRelation(), this.getId());
this.rel = rel;
}
}
It does not extend XWPFHyperlink as this is so rudimentary it's not worth it. Furthermore after setTargetURI the String uri needs to be updated. But there is no setter in XWPFHyperlink and the field is only accessible from inside the package.
The new XWPFHyperlinkExtended can be got from XWPFHyperlinkRun like so:
/**
* If this HyperlinkRun refers to an external reference hyperlink,
* return the XWPFHyperlinkExtended object for it.
* May return null if no PackageRelationship found.
*/
/*modifiers*/ XWPFHyperlinkExtended getHyperlink(XWPFHyperlinkRun hyperlinkRun) {
try {
for (org.apache.poi.openxml4j.opc.PackageRelationship rel : hyperlinkRun.getParent().getPart().getPackagePart().getRelationshipsByType(XWPFRelation.HYPERLINK.getRelation())) {
if (rel.getId().equals(hyperlinkRun.getHyperlinkId())) {
return new XWPFHyperlinkExtended(hyperlinkRun, rel);
}
}
} catch (org.apache.poi.openxml4j.exceptions.InvalidFormatException ifex) {
// do nothing, simply do not return something
}
return null;
}
Once we have that XWPFHyperlinkExtended we can set an new target URI using it's method setTargetURI.
A further problem results from the fact, that the XML object of type CTHyperlink can wrap around multiple text runs, not only one. Then multiple XWPFHyperlinkRun are in one CTHyperlink and point to one target URI. For example this could look like:
... [this is a link to example.com]->https://example.com ...
This results in 6 XWPFHyperlinkRuns in one CTHyperlink linking to https://example.com.
This leads to problems when link text needs to be changed when the link target changes. The text of all the 6 text runs is the link text. So which text run shall be changed?
The best I have found is a method which sets the text of the first text run in the CTHyperlink.
/**
* Sets the text of the first text run in the CTHyperlink of this XWPFHyperlinkRun.
* Tries solving the problem when a CTHyperlink contains multiple text runs.
* Then the String value is set in first text run only. All other text runs are set empty.
*/
/*modifiers*/ void setTextInFirstRun(XWPFHyperlinkRun hyperlinkRun, String value) {
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHyperlink ctHyperlink = hyperlinkRun.getCTHyperlink();
for (int r = 0; r < ctHyperlink.getRList().size(); r++) {
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR ctR = ctHyperlink.getRList().get(r);
for (int t = 0; t < ctR.getTList().size(); t++) {
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText ctText = ctR.getTList().get(t);
if (r == 0 && t == 0) {
ctText.setStringValue(value);
} else {
ctText.setStringValue("");
}
}
}
}
There the String value is set in first text run only. All other text runs are set empty. The text formatting of the first text run remains.
This works, but need more some steps to get text formatting correctly:
try (var fis = new FileInputStream(fileName);
var doc = new XWPFDocument(fis)) {
var pList = doc.getParagraphs();
for (var p : pList) {
var runs = p.getRuns();
for (int i = 0; i < runs.size(); i++) {
var r = runs.get(i);
if (r instanceof XWPFHyperlinkRun) {
var run = (XWPFHyperlinkRun) r;
var link = run.getHyperlink(doc);
// To get text: link for checking
System.out.println(run.getText(0) + ": " + link.getURL());
// how i replace it
var run1 = p.insertNewHyperlinkRun(i, "http://google.com");
run1.setText(run.getText(0));
// remove the old link
p.removeRun(i + 1);
}
}
}
try (var fos = new FileOutputStream(outFileName)) {
doc.write(fos);
}
}
I'm using these libraries:
implementation 'org.apache.poi:poi:5.2.2'
implementation 'org.apache.poi:poi-ooxml:5.2.2'

Categories