Inserting an Action button from an AbstractPropertySection - eclipse-plugin

I have a tabbed propertiesContributor (and a few propertySections to go with it) using the org.eclipse.ui.views.properties.tabbed.propertySections extension point
I should like to place a tab-specific 'refresh' action-button into the action-bar, and cannot see how it should be done. There is a very tantalising method ..
TabbedPropertySheetPage.setActionBars( ... )
... available in 'createControls()' but I cannot see how I make use of that.
Can anyone point me at some working example code on how to achieve this?
Your clues & boos are most welcome.
M.

The solution was to use an instance of org.eclipse.ui.SubActionBars and add the tab-specific Actions to it, like this ...
#Override
public void createControls(Composite parent, final TabbedPropertySheetPage aTabbedPropertySheetPage)
{
...
makeActions();
subActionBars = new SubActionBars( tabbedPropertySheetPage.getSite().getActionBars() );
subActionBars.getToolBarManager().add( refreshAction );
subActionBars.getMenuManager().add( refreshAction );
}
.. then override aboutToBeShown() and aboutToBeHidden() like this ...
#Override
public void aboutToBeShown()
{
super.aboutToBeShown();
subActionBars.activate();
subActionBars.updateActionBars();
}
#Override
public void aboutToBeHidden()
{
super.aboutToBeHidden();
subActionBars.deactivate();
subActionBars.updateActionBars();
}

I don't think there is a way to add a Tab specific action to the view's action bar. You may have to add the action in a section of that tab only.

Related

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 :)

Using RedirectToAction to break out of a controller/action

In every action in every controller, I would like to have a check that, in certain cases, would return the app to another controller/action. I would like the check to be as simple as possible, something like TestForExit( );
Here's my problem: all my actions return ActionResult, and here is a sample:
public ActionResult Partial()
{
TestForExit( );
...
return PartialView( "ViewPartial", data );
}
If TextForExit returns RedirectToAction( "Index", "Home" ) I have to have something like this:
public ActionResult Partial()
{
var result = TestForExit( );
if( result == null )
{
...
result = PartialView( "ViewPartial", data );
}
return result;
}
But, as I am going to have this everywhere, I'd really like to have TestForExit( ) itself be able to send me to Home/Index rather than return an ActionResult that my Action has to return.
In other words, how can I have TestForExit ACTUALLY go to Home/Index, instead of just returning an ActionResult the the original Action must return?
You will want to use an custom ActionFilter. You can apply this action filter globally. Then in the OnActionExecuting, you can perform the TestForExit check, and redirect if needed.
For example.
public void TestForExitActionFilterAttribute : ActionFilterAttribute, IActionFilter
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if(TextForExit())
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary {{ "Controller", "ExitController" },
{ "Action", "ExitAction" } });
}
base.OnActionExecuting(filterContext);
}
}
Now apply your [TestForExitActionFilter] attribute to your controllers, or individual actions. Or, to add it everywhere, add the following line to FilterConfig.RegisterGlobalFilters filters.Add(new TextForExitActionFilterAttribute()).
Here are some related links.
Redirecting to specified controller and action in asp.net mvc action filter
http://www.asp.net/mvc/tutorials/hands-on-labs/aspnet-mvc-4-custom-action-filters
Alternatively, you can just override the OnActionExecuting method directly in your controller class and add the logic there. This would make more sense than a custom attribute if you only need this exit logic for one particular controller.
Well your controller action method has to return eventually, so you still have to return an ActionResult no matter what if the action is executed.
If you want to avoid adding that code to every action, you could think about creating a custom Action Filter and then marking your actions with that filter, or applying a global filter if you need it for EVERY action.
Then in your action filter, you check your exit condition and redirect if necessary.

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

How to create new instance of a view/viewmodel when navigation occurs with Prism

I am trying to control when a new view is created and when an existing view is shown.
This is a very similar scenario as outlined in the "Navigating to Existing Views" section in the Prism documentation, but I can't get it to work fully:
http://msdn.microsoft.com/en-us/library/gg430861(v=pandp.40).aspx
I am finding I can create the view/view model to begin with ok, but I am then unable to create a new instance of it. I.e. I want more than one instance to exist at once.
Here's an example of the view model:
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class DataEntryPageViewModel : INavigationAware, IRegionMemberLifetime
{
private Guid id;
[ImportingConstructor]
public DataEntryPageViewModel()
{
id = Guid.NewGuid();
}
public bool IsNavigationTarget(NavigationContext navigationContext)
{
// In actual fact there would be more logic here to determine
// whether this should be shown to the user
return false;
}
public void OnNavigatedFrom(NavigationContext navigationContext)
{
}
public void OnNavigatedTo(NavigationContext navigationContext)
{
}
public bool KeepAlive
{
// For the purposes of this example we don't want the view or the viewModel
// to be disposed of.
get { return true; }
}
}
I am navigating to this as follows:
m_RegionManager.RequestNavigate(
"MainRegion",
new Uri("/DataEntryPageView", UriKind.Relative));
So the first time I call the above the view is shown.
The next time I call RequestNavigate the IsNavigationTarget is hit and it returns false. What I then want it to do is to create a new instance but that doesn't happen. I know it's not happening because the constructor does not get hit and the UI does not update to show the new instance of the view.
Any ideas how I can make it create a new instance?
Many thanks,
Paul
Edit
I have noticed that the second time I call RequestNavigate (to request another instance of the same view) the callback reports an error "View already exists in region." It therefore seems that I can have multiple instances of different views in a region, but not multiple instances of the same view. My understand of this isn't great though so I could be wrong.
Why are you not creating the view when you want a new one to be created? It looks to me like you are using MEF.
Use the container to resolve a new instance of your view
Add the new instance of the view to the MainRegion
Then call Navigate and handle the appropriate logic in IsNavigationTarget
You should use the [Export] attribute in your view with a contract name: [Export("DataEntryPageView")].
I have now been able to get this to work, it was because I didn't have
[PartCreationPolicy(CreationPolicy.NonShared)]
on the class declaration of the view. I had it on the ViewModel.
So this is now resulting in the behaviour I expected.
Thanks though to Zabavsky and Alan for your suggestions.

Apache Wicket - Implementing AbstractToolbar with DefaultDataTable

I am trying to add an AbstractToolBar to a DefaultDataTable.
The toolbar has a button on click of which the selected rows should get deleted.
My table has a checkbox column, to select the rows.
AbstractToolBar implementation looks like this -
public class GridToolBar extends AbstractToolbar {
/**
*
*/
private static final long serialVersionUID = -2126515338632353253L;
Button btnDelete;
List<Contact> selected;
public GridToolBar(final DataTable<?> table) {
super(table);
// TODO Auto-generated constructor stub
btnDelete = new Button("delete",new Model("Delete"));
btnDelete.setOutputMarkupId(true);
btnDelete.add(new AjaxEventBehavior("onclick") {
private static final long serialVersionUID = 6720512493017210281L;
#Override
protected void onEvent(AjaxRequestTarget target) {
System.out.println(selected);
((UserProvider)table.getDataProvider()).remove(selected);
target.add(table);
}
});
add(btnDelete);
}
public void setSelected(List inList){
selected = inList;
}
}
The toolbar has been added to table as follows -
GridToolBar tb = new GridToolBar(table);
tb.setOutputMarkupId(true);
table.addTopToolbar(tb);
The code works fine, except on click of delete button it adds an additional delete button below the table. On inspecting it with firebug, the ids of both the buttons match exactly. On sorting the table though, the extra button is removed from the view.
Could someone help me how can I avoid creation of extra button on every click?
Why is it being created in the first place?
Any help is appreciated.
Thanks,
Sonam
You add the button directly to the table. This is incorrect, as you cannot have a button in a table. You need a <td> element. You can create one using a WebMarkupContainer. See also the source of for example NoRecordsToolbar