2012-03-12 29 views
10

Tôi đang cố tạo một phần mở rộng Nautilus trong C, nhưng chỉ có các ví dụ Python và giúp.Cách tạo các phần mở rộng nautilus C

Hầu như không có tài liệu và nghĩa đen không có ví dụ nào, nhưng chỉ một số tiện ích hoàn chỉnh dài và khó hiểu đối với người mới bắt đầu.

Tôi chỉ cần một mã mẫu đơn giản tạo cột mới trong chế độ xem danh sách của Nautilus. Cách viết và biên dịch nó.

Mã Tôi đã thử là:

#include <libnautilus-extension/nautilus-column-provider.h> 

typedef struct _FooExtension FooExtension; 
typedef struct _FooExtensionClass FooExtensionClass; 

struct _FooExtension 
{ 
    GObject parent_slot; 
}; 

struct _FooExtensionClass 
{ 
    GObjectClass parent_slot; 
}; 

static void foo_extension_class_init (FooExtensionClass *class); 
static void foo_extension_instance_init (FooExtension  *img); 

static void foo_extension_class_init(FooExtensionClass *class) 
{ 
} 

static void foo_extension_instance_init(FooExtension *img) 
{ 
} 

static GType provider_types[1]; 

static GType foo_extension_type; 

static void foo_extension_register_type(GTypeModule *module) 
{ 
    static const GTypeInfo info = { 
       sizeof(FooExtensionClass), 
       (GBaseInitFunc) NULL, 
       (GBaseFinalizeFunc) NULL, 
       (GClassInitFunc) foo_extension_class_init, 
       NULL, 
       NULL, 
       sizeof (FooExtension), 
       0, 
       (GInstanceInitFunc) foo_extension_instance_init, 
       }; 
    foo_extension_type = g_type_module_register_type(module, 
           G_TYPE_OBJECT, 
           "FooExtension", 
           &info, 0); 
     /* ... add interfaces ... */ 
} 

GType foo_extension_get_type(void) 
{ 
    return foo_extension_type; 
} 

static GList *foo_extension_get_columns(NautilusColumnProvider *provider) 
{ 
    NautilusColumn *column; 
    GList *ret; 
    column = nautilus_column_new("FooExtension::foo_data_column", "FooExtension::foo_data", "Foo Data", "Foo Description"); 
/*     _("Foo Data"), 
         _("Information from the Foo Extension"));*/ 
    ret = g_list_append(NULL, column); 
    return ret; 
} 

void nautilus_module_initialize (GTypeModule *module) 
{ 
    foo_extension_register_type(module); 
    provider_types[0] = foo_extension_get_type(); 
} 

void nautilus_module_shutdown(void) 
{ 
    /* Any module-specific shutdown */ 
} 

void nautilus_module_list_types (const GType **types, int *num_types) 
{ 
    *types = provider_types; 
    *num_types = G_N_ELEMENTS (provider_types); 
} 

và tôi đã xây dựng nó với:

gcc-c foo_extension.c -o foo_extension.o -fPIC $(pkg-config libnautilus-extension --libs --cflags) 
gcc -shared foo_extension.o -o foo_extension.so $(pkg-config libnautilus-extension --libs --cflags) 

và tôi sao chép nó vào /usr/lib/nautilus/extensions-2.0/, sau đó tôi đã cố gắng nautilus -q nhưng nó không công việc.

+0

http://pastebin.com/gyCU2sti <- Đó là mã. Tôi đã xây dựng nó với: gcc-c foo_extension.c -o foo_extension.o -fPIC $ (pkg-config libnautilus-extension --libs --cflags) gcc -shared foo_extension.o -o foo_extension.so $ (pkg -config libnautilus-extension --libs --cflags) và putted nó trong "/usr/lib/nautilus/extensions-2.0/" vì vậy "nautilus -q" và nó không hoạt động ... –

Trả lời

8

Bạn cũng có thể truy xuất tài liệu được chỉ trong Nautilus Extension's wiki từ the copy in archive.org. Bản sao trong archive.org có các ví dụ trong C.

EDIT: Tôi đã thêm một ví dụ làm việc hoàn chỉnh, cũng như giải thích về các phần còn thiếu trong mã của bạn.

Bạn đang thiếu hai điều:

  1. Thêm các giao diện. Đối với nhà cung cấp cột sẽ là foo_extension_column_provider_iface_init và tại đó bạn cần liên kết liên kết các giao diện được mong đợi với việc triển khai của bạn. Trong trường hợp cụ thể này, get_columns.
  2. Với bước trước, bạn sẽ chỉ nhận được một cột nhưng có giá trị không xác định cho mỗi tệp. Do đó, bạn cũng phải sử dụng InfoProvider. Cụ thể, giao diện update_file_info. Trong giao diện đó, bạn có thể liên kết thuộc tính cho cột của mình với mỗi tệp qua nautilus_file_info_add_string_attribute.

Dưới đây là ví dụ làm việc. Hãy coi chừng NautilusFileInfoProvider là một phần của hệ thống IO không đồng bộ của Nautilus. Do đó, nếu các hoạt động chậm, bạn sẽ chặn Nautilus. Trong ví dụ bên dưới, tôi chỉ đặt một chuỗi cố định cho mỗi tệp ("Foo"). Tuy nhiên, nếu bạn cần thu thập thông tin khác, bạn cũng nên triển khai các đối số update_completexử lý và giao diện cancel_update. Kiểm tra documentation whose copy is available in archive.org

#include <libnautilus-extension/nautilus-column-provider.h> 
#include <libnautilus-extension/nautilus-info-provider.h> 

typedef struct _FooExtension FooExtension; 
typedef struct _FooExtensionClass FooExtensionClass; 

typedef struct { 
    GClosure *update_complete; 
    NautilusInfoProvider *provider; 
    NautilusFileInfo *file; 
    int operation_handle; 
    gboolean cancelled; 
} UpdateHandle; 

struct _FooExtension 
{ 
    GObject parent_slot; 
}; 

struct _FooExtensionClass 
{ 
    GObjectClass parent_slot; 
}; 

static void foo_extension_class_init (FooExtensionClass *class); 
static void foo_extension_instance_init (FooExtension  *img); 
static GList *foo_extension_get_columns (NautilusColumnProvider *provider); 
static NautilusOperationResult foo_extension_update_file_info (
             NautilusInfoProvider *provider, 
             NautilusFileInfo *file, 
             GClosure *update_complete, 
             NautilusOperationHandle **handle); 

/* Interfaces */ 
static void 
foo_extension_column_provider_iface_init (NautilusColumnProviderIface *iface) { 
    iface->get_columns = foo_extension_get_columns; 
    return; 
} 

static void 
foo_extension_info_provider_iface_init (NautilusInfoProviderIface *iface) { 
    iface->update_file_info = foo_extension_update_file_info; 
    return; 
} 

/* Extension */ 
static void foo_extension_class_init(FooExtensionClass *class) 
{ 
} 

static void foo_extension_instance_init(FooExtension *img) 
{ 
} 

static GType provider_types[1]; 

static GType foo_extension_type; 

static void foo_extension_register_type(GTypeModule *module) 
{ 
    static const GTypeInfo info = { 
       sizeof(FooExtensionClass), 
       (GBaseInitFunc) NULL, 
       (GBaseFinalizeFunc) NULL, 
       (GClassInitFunc) foo_extension_class_init, 
       NULL, 
       NULL, 
       sizeof (FooExtension), 
       0, 
       (GInstanceInitFunc) foo_extension_instance_init, 
       }; 

    static const GInterfaceInfo column_provider_iface_info = { 
     (GInterfaceInitFunc) foo_extension_column_provider_iface_init, 
     NULL, 
     NULL 
    }; 

    static const GInterfaceInfo info_provider_iface_info = { 
     (GInterfaceInitFunc) foo_extension_info_provider_iface_init, 
     NULL, 
     NULL 
    }; 

    foo_extension_type = g_type_module_register_type(module, 
           G_TYPE_OBJECT, 
           "FooExtension", 
           &info, 0); 

    /* ... add interfaces ... */ 
    g_type_module_add_interface (module, 
           foo_extension_type, 
           NAUTILUS_TYPE_COLUMN_PROVIDER, 
           &column_provider_iface_info); 

    g_type_module_add_interface (module, 
           foo_extension_type, 
           NAUTILUS_TYPE_INFO_PROVIDER, 
           &info_provider_iface_info); 
} 

GType foo_extension_get_type(void) 
{ 
    return foo_extension_type; 
} 

/* Column interfaces */ 
static GList *foo_extension_get_columns(NautilusColumnProvider *provider) 
{ 
    NautilusColumn *column; 
    GList *ret; 
    column = nautilus_column_new ("FooExtension::foo_data_column", 
            "FooExtension::foo_data", 
            "Foo Data", 
            "Foo Description"); 
    ret = g_list_append(NULL, column); 

    return ret; 
} 

/* Info interfaces */ 
static NautilusOperationResult 
foo_extension_update_file_info (NautilusInfoProvider *provider, 
           NautilusFileInfo *file, 
           GClosure *update_complete, 
           NautilusOperationHandle **handle) 
{ 
    char *data; 

    /* Check if we've previously cached the file info */ 
    data = g_object_get_data (G_OBJECT (file), "foo_extension_data"); 

    /* get and provide the information associated with the column. 
     If the operation is not fast enough, we should use the arguments 
     update_complete and handle for asyncrhnous operation. */ 
    if (!data) { 
     data = g_strdup ("Foo"); 
    } 

    nautilus_file_info_add_string_attribute (file, 
          "FooExtension::foo_data", 
          data); 
    return NAUTILUS_OPERATION_COMPLETE; 
} 

/* Extension initialization */ 
void nautilus_module_initialize (GTypeModule *module) 
{ 
    foo_extension_register_type(module); 
    provider_types[0] = foo_extension_get_type(); 
} 

void nautilus_module_shutdown(void) 
{ 
    /* Any module-specific shutdown */ 
} 

void nautilus_module_list_types (const GType **types, int *num_types) 
{ 
    *types = provider_types; 
    *num_types = G_N_ELEMENTS (provider_types); 
} 

Để biên dịch nó:

$ gcc -c foo-extension.c -o foo-extension.o -fPIC $(pkg-config libnautilus-extension --cflags) 
$ gcc -shared foo-extension.o -o foo-extension.so $(pkg-config libnautilus-extension --libs) 

Đối với thử nghiệm phần mở rộng, trước tiên bạn cần phải dừng lại bất kỳ trường hợp chạy của nautilus và tái khởi động nautilus.Đó là:

$ nautilus -q 
$ nautilus 

Lưu ý rằng là không có tùy chọn -q bạn sử dụng, đó là cho bỏ.

Nếu bạn muốn kiểm tra xem Nautilus đang tải phần mở rộng, bạn có thể sử dụng strace như sau:

$ strace -e trace=open nautilus 

Và xem những gì các thư viện và các tập tin Nautilus đang tải/mở.

Trong khi làm việc trong tiện ích, thay vì sao chép tệp mở rộng trong [libdir] /nautilus/extensions-3.0, bạn có thể tạo liên kết tượng trưng đến thư mục làm việc của mình. Nếu bạn đang sử dụng Nautilus 2.x, hãy sử dụng [libdir] /nautilus/extensions-2.0 để thay thế.

+0

Liên kết đầu tiên có chỉ các ví dụ Python, thứ hai là ví dụ mà tôi đã sử dụng cho mã của mình nhưng không thành công. nautilus-sendto không dành cho ColumnView, chỉ cho menu ngữ cảnh, vì vậy ngay cả khi tôi học từ nó đọc mã có lẽ nó sẽ vô dụng. –

+0

Bạn đã yêu cầu viết và biên dịch. nautilus-sendto đã thiết lập chuỗi công cụ, do đó, bạn có thể sử dụng nó làm mẫu cho dự án của mình. Bắt đầu với một cái gì đó bạn biết nó hoạt động và bạn có thể kiểm tra. Khi bạn đã đặt xong, hãy bắt đầu áp dụng các thay đổi của mình. – gpoo

+0

Tôi sẽ cố gắng đưa ra một cái nhìn, nhưng có lẽ (ngay cả khi nó là một plugin đơn giản) nó sẽ là quá phức tạp để có một "phản hồi nhanh" về các phần mở rộng và sẽ vô ích. Thời gian trước, tôi đã thử với một dự án đơn giản khác và quá lâu để đọc và hiểu chỉ vì những gì tôi cần. –

Các vấn đề liên quan