17 июля 2009 г.

Текстовый редактор. Часть 3

Текстовый редактор. Часть 1
Текстовый редактор. Часть 2

Сегодня добавим к текстовому редактору подсветку синтаксиса.


За подсветку синтаксиса отвечает модуль GtkSourceView. Для его установки на Linux при компиляции необходимо указать параметр --enable-sourceview.
Если же у Вас Windows, то в файл php.ini необходимо добавить строчку:
php-gtk.extensions = php_gtk_sourceview2.dll

А также положить в корень дистрибьютива файлы iconv.dll, libgtksourceview-1.0-0.dll, libxml2.dll.

Так как этот модуль может быть отключён, то мы проверим наличие классов GtkSourceBuffer, GtkSourceView и GtkSourceLanguagesManager. Если они существуют, то реализуем подсветку синтаксиса, иначе используем версию из второй части.
if (class_exists('GtkSourceBuffer') AND
class_exists('GtkSourceView') AND
class_exists('GtkSourceLanguagesManager'))
{
$lang = new GtkSourceLanguagesManager();
$lang = $lang->get_language_from_mime_type("application/x-php");
 
$this->buffer = GtkSourceBuffer::new_with_language($lang);
$this->buffer->set_highlight(TRUE);
 
$text = GtkSourceView::new_with_buffer($this->buffer);
$text->set_highlight_current_line(TRUE);
$text->set_show_line_numbers(TRUE);
}


Класс GtkSourceLanguagesManager содержит информацию о языке, для которого необходимо произвести подсветку. Язык указывается с помощью mime-типа. Для PHP это application/x-php.
Метод set_highlight() производит подсветку синтаксиса, set_highlight_current_line() - подсветку текущей строки, set_show_line_numbers() нумерует строки.
Методы open_file() и save_file() остунуться без изменений.

Полный код программы:

<?php
 
class TextEditor
{
private $buffer, $filename;
 
public function __construct()
{
$window = new GtkWindow;
$window->set_default_size(600, 300);
$window->set_title('PHP-GTK2::Текстовый редактор');
$window->set_position(Gtk::WIN_POS_CENTER);
$window->connect_simple('destroy', array('Gtk', 'main_quit'));
 
$menubar = new GtkMenuBar();
$file_menu_item = new GtkMenuItem('_Файл');
$menubar->append($file_menu_item);
$sub_file = new GtkMenu();
$file_menu_item->set_submenu($sub_file);
 
$open = new GtkImageMenuItem(Gtk::STOCK_OPEN);
$open->connect_simple('activate', array($this, 'open_file'));
$sub_file->append($open);
 
$save = new GtkImageMenuItem(Gtk::STOCK_SAVE);
$save->connect_simple('activate', array($this, 'save_file'));
$sub_file->append($save);
 
$sub_file->append(new GtkSeparatorMenuItem());
 
$close = new GtkImageMenuItem(Gtk::STOCK_CLOSE);
$close->connect_simple('activate', array('Gtk', 'main_quit'));
$sub_file->append($close);
 
if (class_exists('GtkSourceBuffer') AND
class_exists('GtkSourceView') AND
class_exists('GtkSourceLanguagesManager'))
{
$lang = new GtkSourceLanguagesManager();
$lang = $lang->get_language_from_mime_type("application/x-php");
 
$this->buffer = GtkSourceBuffer::new_with_language($lang);
$this->buffer->set_highlight(TRUE);
 
$text = GtkSourceView::new_with_buffer($this->buffer);
$text->set_highlight_current_line(TRUE);
$text->set_show_line_numbers(TRUE);
}
else
{
$this->buffer = new GtkTextBuffer();
$text = new GtkTextView();
$text->set_buffer($this->buffer);
}
 
$scroll = new GtkScrolledWindow();
$scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
$scroll->add($text);
 
$vbox = new GtkVBox();
$vbox->pack_start($menubar, FALSE, FALSE, 0);
$vbox->pack_start($scroll, TRUE, TRUE);
 
$window->add($vbox);
$window->show_all();
}
 
public function open_file()
{
$dialog = new GtkFileChooserDialog(
'Выбрать файл',
NULL,
Gtk::FILE_CHOOSER_ACTION_OPEN,
array(
Gtk::STOCK_CANCEL, Gtk::RESPONSE_CANCEL,
Gtk::STOCK_OK, Gtk::RESPONSE_OK
)
);
$dialog->show_all();
$result = $dialog->run();
if ($result == Gtk::RESPONSE_OK)
{
$this->filename = $dialog->get_filename();
$text = trim(file_get_contents($this->filename));
$this->buffer->set_text($text);
}
$dialog->destroy();
}
 
public function save_file()
{
$start = $this->buffer->get_start_iter();
$end = $this->buffer->get_end_iter();
$text = $this->buffer->get_text($start, $end);
$fopen = fopen($this->filename, 'w+');
fwrite($fopen, $text);
fclose($fopen);
}
}
 
new TextEditor();
Gtk::main();

5 комментариев:

LegioNemesis комментирует...

Под Виндовс запустилась со следующими библиотеками в php-cli.ini:
php-gtk.extensions = php_gtk_sourceview2.dll
Так же в корневую папку необходимо положить:
iconv.dll
libgtksourceview-1.0-0.dll
libxml2.dll

Shecspi комментирует...

LegioNemesis, мне не удалось запустить данную программу проделав указанные Вами действия. Может нужно что-то ещё?

LegioNemesis комментирует...

Shecspi, именно этих библиотек у меня не хватало на момент запуска, об этом сообщил интерпретатор. Я предлагаю сделать свою сборку PHP-GTK для Виндовс, ибо каждый запуск тестовых программ чреват поисками не хватающих библиотек и прочего.

Shecspi комментирует...

У меня запустилась, просто нужно было в папку ext поместить php_gtk_sourceview2.dll :) Нужно было с оф.сайта качать "php-gtk-2.0.1 Windows binary extensions pack", а не просто "binary pack", т.к. в нём также имеются модули для работы с Glade и HTML.

На счёт пака хорошая идея, в него необходимо объединить как библиотеки для работы PHP-GTK, так и из стандартной поставки PHP, а также полностью сконфигурированный файл php.ini, чтобы от пользователей ничего дополнительно не требовалось.

Shecspi комментирует...

Библиотеки то для Glade и HTML имеются, а вот подключить их у меня не получается. А без них, думаю, пак выпускать нельзя. Поэтому сборка пока откладывается.