2012-03-12 3 views
10

Я пытаюсь создать расширение Nautilus в C, но есть только примеры Python и помогает.Как создать расширения nautilus C

Практически нет документации и буквально нет примеров, но только некоторые полные расширения, которые долго и трудно понять для новичка.

Мне нужен простой пример кода, который создает новый столбец в виде списка Nautilus. Как написать и скомпилировать его.

Код Я попытался это:

#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); 
} 

и я построил его:

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) 

и я скопировал его в /usr/lib/nautilus/extensions-2.0/, то я попытался nautilus -q, но это не Работа.

+0

http://pastebin.com/gyCU2sti <- Это код. Я построил его с помощью: 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) и поместил его в «/usr/lib/nautilus/extensions-2.0/» так «nautilus -q», и он не сработал ... –

ответ

8

Вы также можете получить документацию, указанную в Nautilus Extension's wiki от the copy in archive.org. У копии в archive.org есть примеры в C.

EDIT: Я добавил полный рабочий пример, а также объяснение недостающих частей вашего кода.

У вас не хватает двух вещей:

  1. Добавить интерфейсы. Для провайдера столбцов будет foo_extension_column_provider_iface_init, и вам нужно связать ссылку, которую ожидали интерфейсы с вашей реализацией. В данном конкретном случае get_columns.
  2. С предыдущим вы получите только столбец, но с неизвестным значением для каждого файла. Поэтому вам необходимо также использовать InfoProvider . В частности, интерфейс update_file_info. В этом интерфейсе вы можете связать атрибут для своего столбца с каждым файлом через nautilus_file_info_add_string_attribute.

Ниже приведен рабочий пример. Опасайтесь NautilusFileInfoProvider является частью асинхронной системы ввода-вывода Nautilus. Следовательно, если операции будут медленными, вы заблокируете Nautilus. В приведенном ниже примере я просто установил фиксированную строку для каждого файла («Foo»). Однако, если вам нужно собрать другую информацию, вы должны также реализовать аргументы update_complete и ручкой и cancel_update. Проверьте 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); 
} 

Для его компиляции:

$ 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) 

Для тестирования расширения, сначала нужно остановить любой запущенный экземпляр наутилуса и повторного запуска Nautilus.То есть:

$ nautilus -q 
$ nautilus 

Обратите внимание, что без опции -q вы использовали, что для бросить.

Если вы хотели бы проверить, если Nautilus загружается ваше расширение, вы можете использовать Трассирование следующим образом:

$ strace -e trace=open nautilus 

И посмотреть, какие библиотеки и файлы Nautilus является погрузка/открытие.

При работе в вашем расширении вместо копирования файла расширения в [libdir] /nautilus/extensions-3.0 вы можете создать символическую ссылку на свой рабочий каталог. Если вы используете Nautilus 2.x, используйте вместо этого [libdir] /nautilus/extensions-2.0.

+0

Первая ссылка только примеры Python, второй - тот, который я использовал для моего кода, но безуспешно. nautilus-sendto не для ColumnView, просто для контекстного меню, поэтому, даже если я узнаю из него, прочитав код, вероятно, это будет бесполезно. –

+0

Вы просили написать и компилировать. У nautilus-sendto уже установлена ​​инструментальная цепочка, поэтому вы можете использовать ее в качестве шаблона для своего проекта. Начните с того, что вы знаете, это работает, и вы можете проверить. После того, как вы установили этот набор, начните применять ваши изменения. – gpoo

+0

Я попробую взглянуть, но, вероятно, (даже если это простой плагин) будет слишком сложно иметь «быструю обратную связь» о расширениях и будет бесполезным. Время назад я уже пробовал с другим простым проектом, и было слишком долго читать и понимать только то, что мне нужно. –

 Смежные вопросы

  • Нет связанных вопросов^_^