Tuesday, October 25, 2005

Add the property page to a view.

To add a property page to the view:
1) Create extendion of org.eclipse.ui.propertyPages. Define the object class (select which the property page will be available) and the page class.
2) Add PropertyDialogAction to the context menu. So that when the object class is selected, the action will be available.

Monday, October 24, 2005

Write to console in Eclipse.


private MessageConsole findConsole(String name){
ConsolePlugin plugin=ConsolePlugin.getDefault();
IConsoleManager conMan=plugin.getConsoleManager();
IConsole[] existing=conMan.getConsoles();
for(int i=0;i<existing.length;i++){
if(name.equals(existing[i].getName())){
return (MessageConsole) existing[i];
}
}
// no console found, create a new one.
MessageConsole console=new MessageConsole(name,null);
conMan.addConsoles(new IConsole[]{console});
return console;
}

private void writeConsole(){
MessageConsole console=findConsole("lpid=10");
MessageConsoleStream out=console.newMessageStream();
out.println("hello from generic console");
}

private void showConsole(){
IConsole console=....console;
IWorkbenchPage page=...;
String id=IConsoleConstants.ID_CONSOLE_VIEW;
IConsoleView view=(IConsoleView) page.showView(id);
view.display(console);
}


The org.eclipse.debug.ui.console.IConsole has a method connect(IStreamsProxy streamsProxy), which will connects this console to the given streams proxy. This associates the standard in, out, and error streams with the console. Keyboard input will be written to the given proxy.


//////////////////////////////////////////////////////////
Note:
In the following, all "process" means the real process, not the Java wrapper Process. It is in fact is the wrapped process. And the outputStream of wrapper is piped into the inputStream of the wrapped process. The stdout of the wrapped process is piped into the wrapper's inputStream.

IStreamMonitor : manages the contents of the stream a process is writing to, and notifies registered listeners of changes in the stream.
public void addListener(IStreamListener listener);
public String getContents();
public void removeListener(IStreamListener listener);

IStreamListener: has only one method which will be called when text has been appended to the given stream monitor.
public void streamAppended(String text, IStreamMonitor monitor);

IStreamProxy : Acts as proxy between the streams of a process and interested clients. It allows implementation of IProcess to handle I/O related to the stdin/out/err associated with a process.
public IStreamMonitor getErrorStreamMonitor();
public IStreamMonitor getOutputStreamMonitor(); // The monitor is connected to the output stream of the associated process.
public void write(String input) throws IOException; // Writes the given text to the stdin of the proxy's process.

IProcess (1)---->(1) IStreamProxy (1)---->(2) IStreamMonitor (1)---->(m) IStreamListener

org.eclipse.debug.ui.console.IConsole: A console displays output and writes input to a process.
public void connect(IStreamsProxy streamsProxy); // associates the stdin/out/err with console.
public void connect(IStreamMonitor streamMonitor, String streamIdentifer);
public void addLink(IHyperlink link, int offset, int length);
public IRegion getRegion(IHyperlink link);
public IDocument getDocument();
public IProcess getProcess();
public void addPatternMatchListener(IPatternMatchListener matchListener);
public void removePatternMatchListener(IPatternMatchListener matchListener);
public IOConsoleOutputStream getStream(String streamIdentifier);


When connect(), the stream listener will be created and added to the fStreamListners list. The StreamListener will be called later when the process outputstream changes, and then the listener will write (anything he wants) to the Console throught the output stream which is passed when the listener's constructor.

To summary, to output the process' output message to the Console, you must first create a IConsole, and register it to the ConsoleManager. You should also monitor the process's output stream, so that when there is any output message from the process, you can then write the message to the console.
To implement the StreamsProxy, please refer to the org.eclipse.debug.internal.core.StreamsProxy.

Wednesday, October 19, 2005

How RegisterView is updated.

RemoteTreeViewer is allows deferred updating.
DeferredRegisterGroup is tied to the RemoteTreeViewer.The children of the DefferedRegisterGroup has children IVariable.

The CRegister implements the IVariable, and the interface method getValue() is used to get the value.

Inside the CRegister, there is an internal interface InternalVariable to encapsulate an Register variable.

The getValue() method of InternalVariable will create a shadow variable in the current statck frame, then change to other stack frame. And finally it add the created shadow register to the variable map. At the same time, remove the oldest shadow varaible.

LaunchView and DelegatinModelPresentation

org.eclipse.debug.internal.ui.views.launch.LaunchView contains a LaunchViewer (which is a subclass of RemoteTreeViewer which retrive in background job and update incrementally on a refresh). THe LaunchView uses an extension point org.eclipse.debug.ui.debugModelPresentation to delegate the view presentation.

The org.eclipse.cdt.debug.internal.ui.CDebugModelPresentaion extend this point and is used to decorate the tree viewer in LaunchView.

Sunday, October 16, 2005

CDT Breakpoint management

Eclipse provides a IBreakpointManager to maintain all the breakpoints. You can get the IBreakpointManager by DebugPlugin.getDefault.getBreakpointManager().


Each debug architecture: Java or CDT, they provide their own IBreakpointManager, which registered as IBreakointsListener. For CDT, the CBreakpoingManager registers itself as a IBreakpointsListener, and whenever user inserts a new breakpoint, the Eclipse BreakpointManager will create and add a new breakpoint to its breakpoint list, and then notify the listeners:




When CBreakpointManagers insert a breakpoint, they always make it deferrable, since they are not sure whether the breakpoint is either for the running binary or for the unloaded DLL. When GDB fails to insert breakpoint, the breakpoints will be put into deferred breakpoint list. These deferred breakpoint list is supposed to be set over unloaded DLL. Later, when a new DLL is loaded, then the GDB will try to insert the breakpoint from the deferred breakpoint list.


The BreakpointsView will show different markers for different type of breakpoints. For breakpoints in the breakMap (which is already patched to the binary), BreakpointsView shows them as activated. For breakpoints in the deferredMap (which is not patched until the DLL is loaded), BreakpointsView shows them as deactivated.


The following is a call sequence:




User::ToggleBreakpointRulerAction.getAdapter(IToggleBreakpointsTarget)
ToggleBreakpointAdapter::CDIDebugModel.createLineBreakpoint()
CLineBreakPoint::BreakpointManager.addBreakpoint()
(Eclipse)BreakpointManager::BreakpointNotifier.notify(IBreakpointsListener)- sequential
CBreakpointManager::Target.setLinebreakpoint() { - parallel
(CDT)BreakpointManager.setNewLocationBreakpoint{
suspendInferior();
insertBreakpoint();
resumeInferior();
}
}

Saturday, October 15, 2005

Process Factory

The process factory is used to create RuntimeProcess, which will be associated with Launch.

A process factory is used to override default process (IProcess) creation by the debug plug-in, and can be contributed via plug-in XML. When a new process is created via DebugPlugin.newProcess(..), the launch configuration associated with the specified launch is consulted for a process factory attribute (DebugPlugin.ATTR_PROCESS_FACTORY_ID). If
present, the associated process factory is consulted to create a process for the launch. If not present a default process implementation is created and returned by the debug plug-in.

Following is example plug-in XML that contributes a process factory.

 <extension point="org.eclipse.debug.core.processFactories">
<processFactory
id="com.example.ExampleIdentifier"
class="com.example.ExampleProcessFactory">
</processFactory>
</extension>
The attributes are specified as follows:
  • id - a unique identifier for this extension point
  • class - the fully qualified name of a class the implements IProcessFactory
Clients contributing a process factory are intended to implement this interface.

To show the statusline for a multipage-editor

Please refer to PDEFormEditorContributor.


The basic idea is as following:
If the multipage editor has multiple editors, then these editor should edit different sources. For example, the plgin.xml editor has:

  • Plug-in Manifiest Editor

  • Extension Point Schema Editor

  • Build Properties Editor

  • Feature Manifest Editor

  • Site Manifest Editor

  • Product Configuration Editor

  • Code Sample Editor

  • Each editor operates on different sources. Each editor should have their own Editor contributor for customizing the actionbars.


    Some editor may have multipages to show different view of source, and it may allow the user to modify the source from different views. For example, the Plug-in Manifest Editor has an XML editor (page), which allow user to edit the XML source directly, and it also has an extension page, which allow user to graphically customize the XML source. In such case, the extension page and XML page share an XML editor contributor. If you want to show the statusline for different page, you can:

  • create an TextEditorActionContributor inside the MultiPageEditorActionBarContributor.

  • overwrite the init(IActionBars) and setActivePage(IEditorPart), call the TextEditorActionContributor's init and init(IActionBars) and setActiveEditor(IEditorParg).


  • Note:
  • It is not necessary for each page of an Multipage Editor to be an IEditorPart. Only the page created by addPage(IEditorPart editor, IEditorInput input) will be considered as an IEditorPart page.

  • page in Multipage editor is just a UI presentation, you can not retrieve a page directly, you can only get the index of active page.

  • inside the EditorContributor, when the setActivePage(IEditorPart) is called, if the current page has no editor inside(i.e., not created by addPage(IEditorPart)), then the IEditorPart will be null.
  • Sunday, October 02, 2005

    To add a property page to an object

    1) Add extension : org.eclipse.ui.propertyPages. In this extension, specify:
  • the object class with whom the property page will be associated.

  • the property page which extends the org.eclipse.ui.dialogs.PropertyPage. the property page will be shown in the property dialog.

  • 2) Add action org.eclipse.ui.dialogs.PropertyDialogAction to your context menu, so that it will be available for the selected object.

    Saturday, October 01, 2005

    To replace the delete action of IDebugView

    1) The AbstractDebugView registered a REMOVE_ACTION to handle the delete key event.
    2) IDebugView.getAction(actionID) can be used to retrive the REMOVE_ACTION.
    3) IDebugView.setAction(actionID, IAction) to register an action (null will remove the action);