How to display an additional info popup next to the content assist popup in an Eclipse plugin? - eclipse-plugin

I'm trying to implement my own content assist and I can't add a popup with additional information for every proposal I get in the content assist popup.
I tried using the following implementation, but it didn't worked:
public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) {
ICompletionProposal[] result= new ICompletionProposal[fgProposals.length];
for (int i= 0; i < fgProposals.length; i++) {
result[i]= new CompletionProposal(fgProposals[i], documentOffset, 0, fgProposals[i].length(), null, fgProposals[i], info, MessageFormat.format(JavaEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { fgProposals[i]})); //$NON-NLS-1$
}
return result;
}
I also tried using Context Information, but I don't think it is what I'm looking for and also I couldn't display the Context Information and the Content Assist at the same time.

If you are using the default ContentAssistant you need to call setInformationControlCreator to set the code used to create this additional information popup.
The usual way to do this in the SourceViewerConfiguration is:
public IContentAssistant getContentAssistant(final ISourceViewer sourceViewer)
{
final ContentAssistant assistant = new ContentAssistant();
.. other setup ...
assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
return assistant;
}

Related

How to attach pdf from trigger to an object?

I'm a bit lost trying to attach a pdf with populated values from an opportunity record
Here is the code:
Trigger:
trigger OpportunityTrigger on Opportunity (after insert)
if(trigger.isAfter && trigger.isUpdate) {
opportunityTriggerHelper.attachFileToOpportunityRecord(trigger.new);
}
Helper Class:
private void attachFileToOpportunityRecord(List<Opportunity> lstOpp) {
List<Id> oppListIdsForAttach = new List<Id>();
for(Opportunity opp : lstOpp) {
oppListIdsForAttach .add(opp.Id);
}
attachFileToOpportunities(oppListIdsForAttach);
}
#future(callout=true)
private static void attachFileToOppotunities(List<Id> OpportunityIds) {
List<Attachment> attachList = new List<Attachment>();
for(Id oppId : opportunityIds) {
OpportunityPdfController file = new OpportunityPdfController();
file.getData(oppId);
PageReference pdfPage = Page.PdfAttachmentForOpp;
blob pdfBody;
pdfBody = pdfPage.getContent();
Attachment attach = new Attachment();
attach.Body = pdfBody;
attach.Name = 'Pdf file';
attach.IsPrivate = false;
attach.ParenId = oppId;
attachList.add(attach);
}
insert attachList;
}
VF Page:
<apex:page controller="OpportunityPdfController" renderAs="pdf">
<apex:repeat value="{!pricingDetails}" var="pd">
<apex:outputText>{!pd.basePrice}</apex:outputText>
</apex:repeat>
</apex:page>
VF Page Controller:
public with sharing class OpportunityPdfController {
public List<PricingDetailWrapper> pricingDetails {get;set;}
public void getData(Id opportunityId) {
List<Pricing_Detail__c> pdList = [
SELECT basePrice
FROM Pricing_Detail__c
WHERE OpportunityId =: opportunityId
];
for(Pricing_Detail__c pd : pdList) {
PricingDetailWrapper pdw = new PricingDetailWrapper();
pdw.basePrice = pd.basePrice;
pricingDetails.add(pdw);
}
}
public class PricingDetailWrapper {
public String basePrice {get;set;}
}
}
The result is whenever I update an opportunity it attaches the corresponding pdf file but it is blank and if I add for example the following to vf page body: "<h1> hello World!</h1>" this works and shows as expected, but this is not happening to what I required above.
You didn't really pass the opportunity id to the VF page. And I doubt this actually works at all? If you manually access the VF page as /apex/PdfAttachmentForOpp?id=006... does it render the content ok? I'm assuming it doesn't.
Fixing the page
You didn't specify constructor so SF generates one for you, fine. I think you need to add something like
public OpportunityPdfController(){
if(ApexPages.currentPage() != null){
Id oppId = ApexPages.currentPage().getParameters().get('id');
System.debug(oppId);
getData(oppId);
}
}
Add this, try to access the page passing valid opp id and see if it renders ok, if right stuff shows in debug log. /apex/PdfAttachmentForOpp?id=006...
(VF page constructors are bigger topic, this might be simpler with standardController + extension class)
Fixing the callout
VF page (especially accessed as callout) will not share memory with the OpportunityPdfController controller you've created in the code. New object of this class will be created to support the page and your file will be ignored. You might try to make-do with some static variable holding current opportunity's id but it feels bit yucky.
In normal execute anonymous try if this returns correct pdf:
PageReference pdfPage = Page.PdfAttachmentForOpp;
pdfPage.getParameters().put('id', '006...');
Blob pdfBody = pdfPage.getContent();
System.debug(pdfBody.toString());
If it works - use similar trick in the actual code, pass the id as url parameter.

Read a file from the cache in CEFSharp

I need to navigate to a web site that ultimately contains a .pdf file and I want to save that file locally. I am using CEFSharp to do this. The nature of this site is such that once the .pdf appears in the browser, it cannot be accessed again. For this reason, I was wondering if once you have a .pdf displayed in the browser, is there a way to access the source for that file in the cache?
I have tried implementing IDownloadHandler and that works, but you have to click the save button on the embedded .pdf. I am trying to get around that.
OK, here is how I got it to work. There is a function in CEFSharp that allows you to filter an incoming web response. Consequently, this gives you complete access to the incoming stream. My solution is a little on the dirty side and not particularly efficient, but it works for my situation. If anyone sees a better way, I am open for suggestions. There are two things I have to assume in order for my code to work.
GetResourceResponseFilter is called every time a new page is downloaded.
The PDF is that last thing to be downloaded during the navigation process.
Start with the CEF Minimal Example found here : https://github.com/cefsharp/CefSharp.MinimalExample
I used the WinForms version. Implement the IRequestHandler and IResponseFilter in the form definition as follows:
public partial class BrowserForm : Form, IRequestHandler, IResponseFilter
{
public readonly ChromiumWebBrowser browser;
public BrowserForm(string url)
{
InitializeComponent();
browser = new ChromiumWebBrowser(url)
{
Dock = DockStyle.Fill,
};
toolStripContainer.ContentPanel.Controls.Add(browser);
browser.BrowserSettings.FileAccessFromFileUrls = CefState.Enabled;
browser.BrowserSettings.UniversalAccessFromFileUrls = CefState.Enabled;
browser.BrowserSettings.WebSecurity = CefState.Disabled;
browser.BrowserSettings.Javascript = CefState.Enabled;
browser.LoadingStateChanged += OnLoadingStateChanged;
browser.ConsoleMessage += OnBrowserConsoleMessage;
browser.StatusMessage += OnBrowserStatusMessage;
browser.TitleChanged += OnBrowserTitleChanged;
browser.AddressChanged += OnBrowserAddressChanged;
browser.FrameLoadEnd += browser_FrameLoadEnd;
browser.LifeSpanHandler = this;
browser.RequestHandler = this;
The declaration and the last two lines are the most important for this explanation. I implemented the IRequestHandler using the template found here:
https://github.com/cefsharp/CefSharp/blob/master/CefSharp.Example/RequestHandler.cs
I changed everything to what it recommends as default except for GetResourceResponseFilter which I implemented as follows:
IResponseFilter IRequestHandler.GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
{
if (request.Url.EndsWith(".pdf"))
return this;
return null;
}
I then implemented IResponseFilter as follows:
FilterStatus IResponseFilter.Filter(Stream dataIn, out long dataInRead, Stream dataOut, out long dataOutWritten)
{
BinaryWriter sw;
if (dataIn == null)
{
dataInRead = 0;
dataOutWritten = 0;
return FilterStatus.Done;
}
dataInRead = dataIn.Length;
dataOutWritten = Math.Min(dataInRead, dataOut.Length);
byte[] buffer = new byte[dataOutWritten];
int bytesRead = dataIn.Read(buffer, 0, (int)dataOutWritten);
string s = System.Text.Encoding.UTF8.GetString(buffer);
if (s.StartsWith("%PDF"))
File.Delete(pdfFileName);
sw = new BinaryWriter(File.Open(pdfFileName, FileMode.Append));
sw.Write(buffer);
sw.Close();
dataOut.Write(buffer, 0, bytesRead);
return FilterStatus.Done;
}
bool IResponseFilter.InitFilter()
{
return true;
}
What I found is that the PDF is actually downloaded twice when it is loaded. In any case, there might be header information and what not at the beginning of the page. When I get a stream segment that begins with %PDF, I know it is the beginning of a PDF so I delete the file to discard any previous contents that might be there. Otherwise, I just keep appending each segment to the end of the file. Theoretically, the PDF file will be safe until you navigate to another PDF, but my recommendation is to do something with the file as soon as the page is loaded just to be safe.

Captcha in oracle adf project

I'm trying to use captcha as it's shown in this example:
http://www.oracle.com/technetwork/developer-tools/jdev/captcha-099103.html
And it works fine in .jspx page or in .jsff page fragment, but I have to place captcha onto the first page of taskflow, and there... it's not updated! /* I mean the button "can't read image" doesn't work */ I have no idea why. Can anybody help?
Actually, I figured out how to do it by myself:
we need captcha image binding in our bean and the resetting method:
private RichImage captchaImage;
public void setCaptchaImage(RichImage captchaImage) {
this.captchaImage = captchaImage;
}
public RichImage getCaptchaImage() {
return captchaImage;
}
public void resetCaptcha(ActionEvent actionEvent) {
captchaImage.setSource("/captchaservlet?rand=" +
String.valueOf(Math.random()));
AdfFacesContext.getCurrentInstance().addPartialTarget(captchaImage.getParent());
}
All, I didn't know how to do was adding parameter to "/captchaservlet"
And now it works fine :)
But the next problem appears: when returning to this page with captcha from the second one in task flow I need to refresh captcha image. Is there any method that is executed on page return or something?
Aaaaaaaaaaaand I found even more elegant solution: one should just set the source of the captcha image to this method using the expression builder:
public String getCaptchaSource() {
return "/captchaservlet?rand=" + String.valueOf(Math.random());
}
The button "Refresh", of course, should be set as a partial trigger for the image, as in the example.
And that's it :)

my zend session name spacing does not work

I am new to Zend and very keen to learn, so I would really appreciate some help and guidance.
I am trying to create a 'method in a class' that will save the session variables of product pages visited by members to a site i.e
i,e examplesite com/product/?producttype= 6
I want to save the number 6 in a session variable. I also do not want to have a global session for the entire site; I just want it for selected pages. So, I guess I have to have Zend_Session::start() on the selected page; but I am not clear how this should be done.
Should I instantiate it in the page view page. i.e products page or do this in the indexAction() method for the products page. I have attempted to instantiate it below but it did not work.
public function rememberLastProductSearched()
{ //my attempt to start a session start for this particular page.
Zend_Session::start();
}
$session->productSearchCategory = $this->_request->getParam('product-search-category');
return" $session->productSearchCategory ";
}
else
{
//echo " nothing there
return " $session->productSearchCategory";
//";
}
}
With the rememberLastProductSearched() method I was trying to get the method to first check whether the user had searched for a new product or just arrived at the page by default. i.e whether he had used the get() action to search for a new product. If the answer is no, then I wanted the system to check whether their had been a previous saved session variable. so in procedural syntax it would have gone like this:
if(isset($_Get['producttype']))
{
//$dbc database connection
$producttype = mysqli_real_escape_string($dbc,trim($_GET['producttype']));
}
else
if(isset($_SESSION['producttype'])){
$producttype = mysqli_real_escape_string($dbc,trim($_SESSION['producttype']));
}
Can you please help me with the Zend/oop syntax. I am totally confused how it should be?
you're asking about simple work flow in an action, it should begin something like:
//in any controller
public function anyAction()
{
//open seesion, start will be called if needed
$session = new Zend_Session_Namespace('products');
//get value
$productCategory = $this->getRequest()->getParam('producttype');
//save value to namespace
$session->productType = $productCategory;
//...
}
now to move this off to a separate method you have to pass the data to the method...
protected function rememberLastProductSearched($productType)
{
//open seesion, start will be called if needed
$session = new Zend_Session_Namespace('products');
$session->productType = $productType;
}
So now if you want to test for presence of a value...
//in any controller
public function anyAction()
{
//open seesion, call the namespace whenever you need to access it
$session = new Zend_Session_Namespace('products');
if (!isset($session->productType)) {
$productCategory = $this->getRequest()->getParam('producttype');
//save value to session
$this->rememberLastProductSearched($productCategory)
} else {
$productCategory = $session->productType;
}
}
That's the idea.
Be mindful of your work flow as it can sometimes be very simple to inadvertently overwrite your session values.
$session = new Zend_Session_Namespace("productSearch");
if ($this->getRequest()->getParam('producttype')) { //isset GET param ?
$session->productType = $this->getRequest()->getParam('producttype');
$searchedProductType = $session->productType;
} else { //take the session saved value
if ($session->productType) {
$searchedProductType = $session->productType;
}
}
//now use $searchedProductType for your query

How to click back button programatically in IWizardPage in Eclipse

I'm writing an Eclipse plugin, I want to create a wizard for my new project type. I created pages by classes extends org.eclipse.jface.wizard.WizardPage. My requirement is, based on some condition in one page, I need to go back to previous page without pressing back button on page(programmatically).
Is it possible?
Thanks a million in advance!
I don't think this is a good idea. The user will be confused by doing this. I would disable the finish and the next button and give an error, telling the user that he has to go back to the first page.
If you want to reuse some UI from the first page, define the UI as a new class and reuse it.
I implemented something similar using the WizardDialog:showPage() method:
MyWizard.java
public void createPageControls(Composite pageContainer) {
// TODO Auto-generated method stub
super.createPageControls(pageContainer);
wizardDialog = (WizardDialog) getContainer();
}
public void skipProcessPage() {
wizardDialog.showPage(workPage == arisDbPage ? focusPage : arisDbPage);
}
public void setWorkPage(IWizardPage workPage) {
this.workPage = workPage;
}
here the processPage does the lengthy db lookup!
HTH thomas