Scout Eclipse extends Menu - menu

I have one Core project and some other project that extends core.
I know how to extend outline and how to add pages to extended outlines, but my problems are menus.
I would like to extend menu on extended project.
I find some example on web and I think that I understand, but this is not working for me.
What I have is :
<extension
name=""
point="org.eclipse.scout.rt.extension.client.desktopExtensions">
<desktopExtension
class="com.sixt.leasing.pd.scout.client.ui.desktop.DesktopExtension"
active="true">
</desktopExtension>
</extension>
<extension
point="org.eclipse.scout.rt.extension.client.menus">
<menuContribution
active="true"
class="com.sixt.leasing.pd.scout.client.menu.JobRunnerMenu"
order="22">
<desktop
class="com.sixt.leasing.core.scout.client.ui.desktop.Desktop">
</desktop>
</menuContribution>
</extension>
inside plugin.xml
and my JobRunnerMenu look like :
public class JobRunnerMenu extends AbstractExtensibleMenu {
#Override
protected String getConfiguredText() {
return TEXTS.get("Job");
}
#Override
protected void execAction() throws ProcessingException {
// TODO Auto-generated method stub.
super.execAction();
}
#Override
protected void execToggleAction(final boolean selected) throws ProcessingException {
// TODO Auto-generated method stub.
super.execToggleAction(selected);
}
}
What am I missing ? Why this don't work?

Related forum thread: Multi Modul - Menu Extension
I just tested this pattern and it works as expected.
Here is the content of my plugin.xml (in the client extension):
<extension
point="org.eclipse.scout.rt.extension.client.menus">
<menuContribution
active="true"
class="myapp.extension.client.menu.MyMenu"
order="22">
<desktop
class="myapp.client.ui.desktop.Desktop">
</desktop>
</menuContribution>
</extension>
Because the “menuContribution” defines a “desktop” as container, the menu you will add is contributed to the Desktop. Usually those menus are top-level menus and contain child menus.
public class MyMenu extends AbstractExtensibleMenu {
#Override
protected String getConfiguredText() {
return "My Menu";
}
public class MessageBoxTestMenu extends AbstractExtensibleMenu {
#Override
protected String getConfiguredText() {
return "Test MessageBox";
}
#Override
protected void execAction() throws ProcessingException {
MessageBox.showOkMessage(null, "This is a test", null);
}
}
}
The result:
Are the absolute class names in your XML correct?
Is your extension correctly started?

Make that your desktop extends the base class AbstractExtensibleDesktop. The regular AbstractDesktop class does not load extensions.
Should that be the case, a breakpoint at AbstractExtensibleDesktop#AbstractExtensibleDesktop should provide for a good starting point to debug.

I am sorry to mislead with this question.
The above code work, my problem was, that I didn't have added a client in product file. This cause client not to be available so extension could't be added.
Thanks for answer anyway, and yes AbstractExtensibleDesktop is absolutely needed.

Related

Overlay toolbar with other toolbar when item is selected in RecyclerView which is inside a fragment

To illustrate what I mean with this, it is similar to WhatsApp, where various options are displayed in the toolbar when a chat is selected.
I have a similar layout, so a MainActivity with Fragments containing RecyclerViews. Now when an item in a RecyclerView is selected I would like to get a similar behaviour as in WhatsApp. The RecyclerViews have an Adapter that implements an OnClickListener.
However, from this Adapter I do not seem to have access to Views from the MainActivity. I tried the following (inside the OnClick method in the Adapter), but it did not work since the view could not be found.
View view = getActivity().findViewById(R.id.toolbar_main_activity);
if( view instanceof Toolbar) {
Toolbar toolbar = (Toolbar) view;
toolbar.setTitle("TestTitle");
}
Does anyone know how to get the intended behavior or have a reference to a tutorial?
UPDATE: for who is also stuck with this and this is still quite confusing, here is how I solved it in my own words
My Fragment contains the Interface by adding the following code to it;
OnItemsSelected mCallBack;
public interface OnItemsSelected {
void onToolbarOptions(String title);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
mCallback = (OnItemsSelected) getActivity();
}
Also I passed 'mCallback' to the adapter like this;
MyAdapter adapter = new MyAdapter(myList, mCallback);
The RecyclerView adapter implements OnClickListener. In the OnClick method I called; 'mCallBack.onToolbarOptions("someTitle");'. And finally I made my MainActivity implement the method; 'implements myFragment.onItemsSelected' and I added the following code to it also;
#Override
public void onToolbarOptions(String title) {
toolbar.setTitle(title);
}
With this, only the title is changed, but from this it is quite easy to make other changes to the toolbar, such as changing the menu items.
Inside your Fragment you make an Interface and a global variable like this:
OnItemsSelected mCallBack;
public interface OnItemsSelected {
public void onToolbarOptions();
}
Then when in your RecyclerView items are selected or clicked you call:
mCallBack.onToolbarOptions();
In your Activity implement the Interface like this plus the method onToolbarOptions():
public static class YourActivityName extends AppCompatActivity
implements YourFragmentName.OnItemsSelected {
public void onToolbarOptions(){
// CHANGE YOUR TOOLBAR HERE
}
//.....OTHER STUFFS IN YOUR ACTIVITY
}

Install a plugin to Liferay's editor

I have a Liferay DXP installation and I would like to install a plugin to the editor. The plugin is base64image.
I was following this official guide so I created a class generally like this:
#Component(immediate = true, service = DynamicInclude.class)
public class CKEditorBase64ImageDynamicInclude implements DynamicInclude {
private BundleContext bundleContext;
#Override
public void include(HttpServletRequest request, HttpServletResponse response, String key) throws IOException {
Bundle bundle = bundleContext.getBundle();
URL entryURL = bundle.getEntry("/META-INF/resources/html/editors/ckeditor/extension/base64_images.js");
StreamUtil.transfer(entryURL.openStream(), response.getOutputStream());
}
#Override
public void register(DynamicIncludeRegistry dynamicIncludeRegistry) {
dynamicIncludeRegistry.register("com.liferay.frontend.editors.web#ckeditor#onEditorCreate");
}
#Activate
protected void activate(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
}
It should include the base64_images.js file where it initializes the editor. But it never works, regardless what the content of the file is. What is wrong with that?
I would like to add that the plugin files (JavaScript code) are part of my Liferay theme. I wanted base64_images.js to call its API but it also might not be the correct way how to do it.

ASP.NET MVC (Content-language http header)

I'm developing content site (internationalised) using ASP.NET MVC. I use web.config (not clientbrowser setttings) to deliver region specific content.
<globalization culture="fr" uiCulture="fr" enableClientBasedCulture="false" />
I don't see ASP.net MVC framework is appending "Content-language" header automatically, is there a way to do that, and if yes than how. And if now than how can we put customised code most efficiently.
Regards.
In your controller, add:
Response.AddHeader("Content-language",
Thread.CurrentThread.CurrentUICulture.Name);
you can apply it to all actions by creating a base class for all your controllers, and including this in overridden OnActionExecuting. Such as:
public class MyController : BaseController
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
Response.AddHeader("Content-language",
Thread.CurrentThread.CurrentUICulture.Name);
base.OnActionExecuting(filterContext);
}
}
Your controllers should then be changed to use MyController instead of BaseController as their base class.
you can apply it to all actions by add this code to global.asax.cs
protected void Application_BeginRequest(object sender, EventArgs e)
{
Response.AddHeader("Content-language", Thread.CurrentThread.CurrentUICulture.Name);
}

Nested presenters with GWTP

I have content slots in my mainpresenter, how can i put, when app load, put the home presenter in one slot and the menu slot in the another ?
or isn't possible?
thanks in advance.
Yes you can ! In the following example code, I assume that your HomePresenter is a place and extends Presenter, and your MenuPresenter extends PresenterWidget.
In your MainPresenter :
#ContentSlot public static final Type<RevealContentHandler<?>> MAIN_SLOT = new Type<RevealContentHandler<?>>();
#ContentSlot public static final Type<RevealContentHandler<?>> MENU_SLOT = new Type<RevealContentHandler<?>>();
#Override
protected void onReveal() {
super.onReveal();
setInSlot(MENU_SLOT, menuPresenter);
}
In your HomePresenter :
#Override
protected void revealInParent() {
RevealContentEvent.fire(this, MainPresenter.MAIN_SLOT, this);
}
Then in MainView :
#UiField Panel mainContainer;
#UiField Panel menuContainer;
#Override
public void setInSlot(Object slot, Widget content) {
if (slot == MainPresenter.MAIN_SLOT) {
mainContainer.clear();
mainContainer.add(content);
} else if (slot == MainPresenter.MENU_SLOT) {
menuContainer.clear();
menuContainer.add(content);
} else {
super.setInSlot(slot, content);
}
}
For users of GWTP 1.5+, note that a lot of new changes have been introduced to slots, and revealing presenters. The case in question may now be accomplished using a NestedSlot for the page content and a PermanentSlot for a menu that you want displayed on all of your pages.
Fortunately, these changes are well documented. See the GWTP slot documentation for an explanation on the new slot types with examples on how to use them.

How To Make UserControl In MasterPage Public For All Child Pages

I have a UserControl which I have added to my web.config
<add tagPrefix="BCF" src="~/controls/MyMessageBox.ascx" tagName="error"/>
and added to my master page
<BCF:error ID="BCError" runat="server" Visible="false" />
Now I need to be able to reference this control AND its public properties from all child pages that use that masterpage. I did this is my BasePage OnLoad event
public UserControl BCError;
BCError = (UserControl)Master.FindControl("BCError");
Problem is, although I can do this in the .aspx page
BCError.Visible = true;
I cannot reference any of the Controls properties I have put in? Such as ShowError .. If I do
BCError.ShowError = "Error Message";
I just get an error saying
'System.Web.UI.UserControl' does not contain a definition for 'ShowInfo' and no extension method 'ShowInfo'
Can you please point me in the right direction!
This is the code for the user control... I can use the properties in the masterpage code behind (And in a page if I put the control directly into it) but cannot use them in the child page code behind?? It doesn't even show the properties or wrapper methods in the intellisense?
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
public partial class MyMessageBox : System.Web.UI.UserControl
{
#region Properties
public bool ShowCloseButton { get; set; }
#endregion
#region Load
protected void Page_Load(object sender, EventArgs e)
{
if (ShowCloseButton)
CloseButton.Attributes.Add("onclick", "document.getElementById('" + MessageBox.ClientID + "').style.display = 'none'");
}
#endregion
#region Wrapper methods
public void ShowError(string message)
{
Show(MessageType.Error, message);
}
public void ShowInfo(string message)
{
Show(MessageType.Info, message);
}
public void ShowSuccess(string message)
{
Show(MessageType.Success, message);
}
public void ShowWarning(string message)
{
Show(MessageType.Warning, message);
}
#endregion
#region Show control
public void Show(MessageType messageType, string message)
{
CloseButton.Visible = ShowCloseButton;
litMessage.Text = message;
MessageBox.CssClass = messageType.ToString().ToLower();
this.Visible = true;
}
#endregion
#region Enum
public enum MessageType
{
Error = 1,
Info = 2,
Success = 3,
Warning = 4
}
#endregion
}
Ok I think I reproduced roughly what your describing and I deleted my original answer cause it was way off.
What I found is that when you want a content page to reference a user control being used in a master page and the control is accesible and what not, you will get an error indicating that you need to reference a specific assembly, and then you get errors indicating that no Method exists of type such and such.
By adding the Register page directive on the child page to the user control resolved this issue. I reproduced this even with the control defined in the web.config or on the page. In both cases I still had to explicitly add a Register on the content page.
This doesn't make sense to me but it allowed my code to compile and work. Give it a shot let me know.
Once you do this you can reference the control like
this.Master.MessageBox.ShowInfo();
This assumes that you have a public property called MessageBox on the Master Page.
Edit
I've also found that this works much better if you register the control on both the master and the content page and not use the web.config.
Edit
If you don't want your child page to reference the user control your other option is expose methods on the master page like ShowInfo() which would delegate to the user control.
You need to declare it as your control type to access it's properties.
public MyMessageBox BCError;
BCError = (MyMessageBox )Master.FindControl("BCError");
Try using this in the pages that inherit from your master page:
<%# MasterType VirtualPath="~/MasterPageName.Master" %>

Resources