A assistência de conteúdo permite facultar conclusão de conteúdos sensível a contextos a pedido do utilizador. Esta funcionalidade é implementada pelo quadro de texto da plataforma org.eclipse.jface.text.contentassist. São utilizadas janelas emergentes (infopops) para propor possíveis escolhas de texto para concluir uma frase. O utilizador pode seleccionar estas escolhas para inserção no texto. A assistência de conteúdo também suporta infopops contextuais para prestar informações ao utilizador que sejam relativas à actual posição no documento.
A implementação da assistência de conteúdo é opcional. Por predefinição, a SourceViewerConfiguration não instala um assistente de conteúdo visto que não sabe o modelo de documentos utilizado para determinado editor e não tem comportamento genérico para assistência de conteúdo.
Para poder implementar a assistência de conteúdo, a configuração do visualizador de fonte do editor deve ser configurada para definir um assistente de conteúdo. Tal realiza-se no exemplo de editor Java dentro da JavaSourceViewerConfiguration.
public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) { ContentAssistant assistant= new ContentAssistant(); assistant.setContentAssistProcessor(new JavaCompletionProcessor(), IDocument.DEFAULT_CONTENT_TYPE); assistant.setContentAssistProcessor(new JavaDocCompletionProcessor(), JavaPartitionScanner.JAVA_DOC); ... return assistant; }
O comportamento da assistência de conteúdo é definido na interface IContentAssistant. A configuração de um assistente de conteúdo é algo semelhante à configuração de destaques de sintaxe. O assistente deve ser configurado com diferentes estratégias de conclusão de frases para diferentes tipos de conteúdo de documentos. As estratégias de conclusão são implementadas com IContentAssistProcessor. Um processador propõe conclusões e calcula informações de contexto para uma deslocação dentro de um tipo de conteúdo particular.
Nem todos os tipos de conteúdo precisam de ter assistência de conteúdo. No editor exemplo Java, são fornecidos processadores de assistência de conteúdo para o tipo de conteúdo predefinido e javadoc, mas não para comentários multi-linha. Vamoa abordar agora cada um destes processadores.
O JavaCompletionProcessor é muito simples. Só pode propor palavras-chave como candidatas para conclusão. as palavras-chave são definidas num campo, fgProposals
, e são sempre propostas como candidatas as seguintes palavras-chave:
public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) { ICompletionProposal[] result= new ICompletionProposal[fgProposals.length]; for (int i= 0; i < fgProposals.length; i++) { IContextInformation info= new ContextInformation(fgProposals[i], MessageFormat.format(JavaEditorMessages.getString("CompletionProcessor.Proposal.ContextInfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$ 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; }
A conclusão pode ser desencadeada a pedido do utilizador ou desencadeada automaticamente quando for introduzido o carácter "(" ou ".":
public char[] getCompletionProposalAutoActivationCharacters() { return new char[] { '.', '(' }; }
Além de propor conclusões, o JavaCompletionProcessor define informações de contexto que podem ser pedidas pelo utilizador. As informações de contexto incluem uma descrição dos pedaços de informação disponíveis em dado contexto e a mensagem informativa detalhada.
No exemplo de editor Java, as informações não são realmente contextuais. Uma matriz que contém cinco objectos de informações de contexto semelhantes é calculada para a actual deslocação quando o utilizador pede informações de contexto. Todos estes objectos de informações de contexto definem um contexto que contém cinco caracteres à frente da deslocação e cinco depois da deslocação. Se for seleccionada uma destas cinco propostas, as informações detalhadas aparecem junto ao cursor e permanecem enquanto o cursor estiver dentro do contexto dois cinco caracteres em torno da deslocação.
public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) { IContextInformation[] result= new IContextInformation[5]; for (int i= 0; i < result.length; i++) result[i]= new ContextInformation( MessageFormat.format(JavaEditorMessages.getString("CompletionProcessor.ContextInfo.display.pattern"), new Object[] { new Integer(i), new Integer(documentOffset) }), MessageFormat.format(JavaEditorMessages.getString("CompletionProcessor.ContextInfo.value.pattern"), new Object[] { new Integer(i), new Integer(documentOffset - 5), new Integer(documentOffset + 5)})); return result; }
Estas informações de contexto são mostradas automaticamente quando é introduzido o carácter "#":
public char[] getContextInformationAutoActivationCharacters() { return new char[] { '#' }; }
A aparência e o comportamento da assistência de conteúdo podem ser configurados com IContentAssistant. Por exemplo, poderá configurar o tempo de espera de auto-activação e a orientação e cor dos popups informativos.
public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) { ContentAssistant assistant= new ContentAssistant(); ... assistant.enableAutoActivation(true); assistant.setAutoActivationDelay(500); assistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY); assistant.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE); assistant.setContextInformationPopupBackground(JavaEditorEnvironment.getJavaColorProvider().getColor(new RGB(150, 150, 0))); return assistant; }
Para permitir que os utilizadores invoquem a assistência de conteúdo, terá de
ser criada e configurada uma acção. Estas acção são normalmente efectuadas na
implementação de subclasse de AbstractTextEditor.createActions()
:
protected void createActions() { ... IAction action= new ContentAssistAction(aResourceBundle, "ContentAssistProposal.", this); //$NON-NLS-1$ action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS); setAction(actionId, action); //$NON-NLS-1$ markAsStateDependentAction(actionId, true); //$NON-NLS-1$ PlatformUI.getWorkbench().getHelpSystem().setHelp(action, helpContextId); ... }O contribuinte da barra de acções de editor tem de ser expandido, para que a acção seja apresentada no menu principal:
... private RetargetTextEditorAction fContentAssist; public MyEditorActionContributor() { fContentAssist= new RetargetTextEditorAction(); String commandId= ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS; fContentAssist.setActionDefinitionId(commandId); } public void contributeToMenu(IMenuManager menu) { IMenuManager editMenu= menu.findMenuUsingPath(M_EDIT); editMenu.appendToGroup(MB_ADDITIONS, fContentAssist); } public void setActiveEditor(IEditorPart part) { IAction editorAction= getAction(part, "ContentAssist"); fContentAssist.setAction(editorAction); } ...