2011-10-27 4 views
0

저는 썬더 버드 코드베이스로 놀고 있습니다. 목표는 인라인 연락처 편집을 구현하는 것입니다. 현재 코드는 XUL 트리에서 Click 이벤트를 포착하고 더블 클릭 (events.detail == 2)이면 프로필 편집기를 엽니 다. 현재 treeCell의 편집을 시작하기 위해 수정했으며, 을 해당 XUL 문서에 추가했습니다. 업데이트 된 코드는 코드가 startEditing 부분에 도달하면, 내가 꽤 많이 여기 잃었어요XUL/Thunderbird : startEditing return

Error: uncaught exception: [Exception... "Component returned failure code: 0x80004001 (NS_ERROR_NOT_IMPLEMENTED) [nsITreeView.isEditable]" nsresult: "0x80004001 (NS_ERROR_NOT_IMPLEMENTED)" location: "JS frame :: chrome://global/content/bindings/tree.xml :: startEditing :: line 337" data: no]

를 반환, 불행히도

var orow = {}, ocolumn = {}, opart = {}; 
gAbResultsTree.treeBoxObject.getCellAt(event.clientX, event.clientY, 
             orow, ocolumn, opart); 

var row = orow.value, column = ocolumn.value.index;   
if (row == -1) 
    return; 

if (event.detail == 2) 
    gAbResultsTree.startEditing(row, column); 

읽습니다. 더 많은 XUL 경험을 가진 사람이 도움이 될 수 있습니까? 감사합니다.

+0

사이드 질문 : Thunderbird가 스크립트 파일을 캐시하고있는 것처럼 보입니다. 새로운 프로필을 만들 때 tb 스크립트 파일의 모든 변경 사항이 올바르게 등록됩니다. 그러나 더 이상의 변경 사항은 적용되지 않습니다. 따라서 프로필을 만든 후에 js 소스를 수정하면 이러한 새로운 변경 사항을 고려하여 새 프로필을 다시 만들어야합니다. –

답변

2

나는 비슷한 것을 시도하고 있었고 같은 문제가 있습니다.

원래 abview가있는 래퍼는 abResultsTree의 뷰로 설정 될 때까지는 함수가 오버라이드 된 __proto__으로 잘 설정됩니다.

드디어 우아한 해결책을 찾았습니다.

원본 abview를 대체하기위한 구성 요소로 구현되었지만 래퍼를 만들기 위해 수정할 수 있습니다.

+0

데이비드에게 감사드립니다. 이 코드가 어떻게 작동하는지 조금 확장 할 수 있습니까? –

+0

기본적으로 : 1. 원래 abview의 인스턴스를 만듭니다. 2. abview에 의해 구현 된 모든 인터페이스 찾기 3. abview 래퍼를 만듭니다 : - 인터페이스가 지원되는 경우 래퍼를 반환해야하며, QueryInterface 함수를 정의하십시오. 래핑 된 인스턴스 - 재정의하려는 함수/속성을 정의하십시오. - 다른 함수/속성이 래핑 된 인스턴스에서 사용됩니다 (이것은'generatePropertyProxy' 함수에 의해 구현됩니다). –

+0

'generatePropertyProxy'는 가장 까다로운 단계입니다. 래핑 된 인스턴스가 래퍼의 프로토 타입으로 설정 될 때와 비슷한 동작을하지만 '__proto__'가 사용 된 것처럼 작동하지 않습니다. –

1

<tree> 위젯은 nsITreeView 객체를 사용하여 표시해야하는 데이터를 검색하거나 조작합니다. 사전 정의 된 nsITreeView 구현이 DOM 또는 RDF 데이터 소스에서 데이터를 읽지 만 자신의 트리보기를 사용하도록 선택할 수 있습니다. 문제의 구성 요소는 파일 nsAbView.cpp에, C++로 구현, 당신을 위해 불행하게도

gAbView = Components.classes["@mozilla.org/addressbook/abview;1"] 
        .createInstance(Components.interfaces.nsIAbView); 

... 

gAbResultsTree.treeBoxObject.view = 
    gAbView.QueryInterface(Components.interfaces.nsITreeView); 

: 썬더 버드의 주소록은 후자를 선택합니다. 즉, Thunderbird를 다시 컴파일하지 않고 변경하는 것은 불가능합니다. 그리고 기존 구성 요소는 트리 셀을 편집하는 데 필요한 isEditable()setCellText() 메서드를 구현하지 않습니다.

아직 C++을 사용하고 싶지 않은 경우에는 해당 구성 요소를 자신의 개체로 래핑 할 수 있습니다. 이런 식으로 뭔가 :이 특정 셀을 편집 할 수 있는지 여부를 다시 확인해야합니다 isEditable()

gAbView = Components.classes["@mozilla.org/addressbook/abview;1"] 
        .createInstance(Components.interfaces.nsIAbView); 
gAbViewWrapper = { 
    __proto__: gAbView, 
    QueryInterface: function(iid) 
    { 
    gAbView.QueryInterface(iid); 
    return this; 
    }, 
    isEditable: function(row, col) 
    { 
    // Do something here 
    }, 
    setCellText: function(row, col, value) 
    { 
    // Do something here 
    } 
}; 

... 

gAbResultsTree.treeBoxObject.view = 
    gAbViewWrapper.QueryInterface(Components.interfaces.nsITreeView); 

방법 - 열이 편집 가능한 경우에도 각각의 세포가 될 필요가 없습니다. setCellText()은 셀의 새 값을 저장해야합니다.

+0

고맙습니다 =) 단지 하나의 질문입니다 :'gAbResultsTree.treeBoxObject.view = gAbViewWrapper.QueryInterface (...)'에 어떤 영향이 있습니까? 'QueryInterface'가 무언가를 반환하면,'gAbViewWrapper'의 호출은 무엇을합니까? –

+0

이 방법을 시도했지만 제대로 작동하지 않습니다. gAbViewWrapper의 IsEditable 함수는 절대로 호출되지 않습니다 :/ –

+0

@ Clément :이 메소드는 JavaScript에서 isEditable()이라고 불리며, C++에서는 단지 IsEditable()입니다.'QueryInterface()'에 대해서는 [JavaScript 팁] (https://developer.mozilla.org/en/JavaScript_Tips#XPConnect)을 참조하십시오. JavaScript에서는 반환 값을 사용할 필요가 없으므로 호출은 원래 객체를 수정합니다. 'gAbResultsTree'의 호출은 원래의 객체가이 인터페이스를 구현하는지 확인합니다. 그렇지 않으면 호출이 예외를 throw하고 아무런 값도 반환되지 않습니다. –