Новости

Обновление исправляет совместимость с Freenode после обновления этой сетью версии IRCd.

Вышел второй релиз-кандидат KVIrc 4.0

Ричард Столлман дал автограф проекту и пожелал успеха в разработке.

Image:Feed.png RSS

Материал из IRC клиент KVIrc.

Перейти к: навигация, поиск

Содержание

[править] Основы языка KVS

[править] Введение

KVS расшифровывается как KVirc Scripting. Это язык программирования, в котором совмещены принципы от C++,sh-скриптинга, perl, php. KVS создан как компромисс между скоростью, обширными возможностями и простотой реализации функций.

Он позволяет:

  • Создавать обработчики событий, генерируемых IRC сетью или действиями пользователя
  • Создавать новые команды(алиасы)
  • Изменять/добавлять/удалять элементы интерфейса, такие как всплывающие меню, панели инструментов, кнопки, диалоговые окна
  • Многое другое..

KVS содержит основные элементы как структурного, так и объектно-ориентированного программирования. В их число входят переменные, массивы, команды, объекты.

Для тестирования своих скриптов существует Тестер сценариев. Его можно открыть из главного меню Сценарии->Новый тестер сценариев

[править] Скрипты

Вы можете использовать KVS для реализации скриптов. Скрипт это конечное число KVS инструкций. Когда вы вводите команду в строке ввода KVIrc, вы фактически выполняете маленький однострочный скрипт. Вы можете сохранять более длинные скрипты в памяти KVIrc и выполнять их позднее. Скрипты также могут быть выполнены из внешних файлов при помощи команды parse.

[править] Hello world!

Эта документация содержит множество примеров скриптов. Они представлены в таких блоках кода:

echo Hello world!

Лучший способ эксперимента со скриптами это использование тестера сценариев, который можно вызвать из главного меню программы Сценарии->Новый тестер сценариев. Вы можете запускать сразу несколько тестеров, в каждом можно поместить по кусочку кода, и проверять его при разных условиях.

Некоторые простые примеры (как линия выше) могут быть введены в строке ввода любого окна. Помните что в таком случае команда должна быть предварена символом косой черты / для того чтобы была интерпретирована как скрипт. Окно ввода может быть сделано многострочным при помощи специальной кнопки справа от него.

[править] Основы синтаксиса

Скрипт содержит последовательность инструкций, разделенных при помощи перевода строки или символа ';'. Расположение инструкции в одной строке не требует символа ';' в конце, инструкции, расположенные в одну строку, обязательно должны быть разделены символом ';'. Самые часто используемые инструкции - это KVS команды. Команда выглядит как ключевое слово со списком параметров, разделенных пробелами. Самая простая команда в KVS это echo; она выводит весь свой список параметров в окно KVirc. Следующий пример скрипта использует только команду echo.

echo "This is the first line"
ECHO This is the second line;
echo "This is the third line"; echo This is still on the third line;
eChO "This is the fourth line"; Echo "This is still on the fourth line"

Как вы уже поняли знак ';' не обязателен в конце строки. Команды не чувствительны к регистру; 'echo' эквивалентно 'Echo', 'ECHO' или 'eChO'. Фактически, большая часть KVS регистронезависима. Другое интересное замечание, это то, что при выполнении данного скрипта вы не увидите кавычек, окружающих строки. Более подробная информация об этом будет описана далее.

Примечание (вы можете его пропустить):

Да, символ ';' может стать проблемой для тех, кто использует ';)' в конце IRC команд, таких как 'msg'. Она почти нерешаема (следует читать: ее решение слишком громоздко). Использование '|' или другого оператора разделения команд не решило бы проблему. Решение - экранирование этого символа:

echo You can do it now \;)

[править] Обработка параметров

Большинство команд принимает (а некоторые и требуют) список параметров. Например, команда join (которая используется для входа на IRC канал) принимает 2 параметра: первый это канал, на который нужно войти, второй это пароль канала. Упрощенный синтаксис для команды join выглядит следующим образом:

join <channel> [password]

Линия выше - пример синтаксиса команды. Все команды описаны подобным образом. join это команда и она полностью соответствует строке "join" в скрипте. <channel> это обязательный параметр: вы должны использовть вместо него реальное название канала, иначе запуск команды приведет к ошибке. Обязательные параметры здесь и далее будут заключаться в угловые скобки <>. [password] тоже является параметром. Употребление в квадратных скобках говорит о том, что параметр не обязателен: если вы его зададите, то он будет интерпретирован как пароль канала. Если вы его не зададите, то для канала не будет использован пароль.

Такой стиль описания параметров - это упрощенная форма BNF.

(Backus-Naur Form, Backus Normal Form) - Нормальная форма Бэкуса-Наура, БНФ. Текстовая нотация для формального определения синтаксиса языка.

Я назвал его упрощенным, потому что он используется строго не во всех местах документации. Это просто предпочтительная форма описания синтаксиса, потому что она легко и удобочитаема.

В конце концов вы можете войти на канал, используя:

join #kvirc kvircrocks

или с тех пор как #kvirc обычно не имеет пароля:

join #kvirc

В примере выше опциональный параметр [password] пропущен.

Фактически он не является пропущенным: KVIrc интерпретирует его как пустую строку которая сигнализирует "не отправлять пароль серверу". Пустые строки эквивалентны пропущенным параметрам.

[править] Параметры, пробелы и кавычки

Из примеров выше понятно что параметры KVS команд разделяются пробелами. Однако из вышесказанного пока не очевидно что если параметры разделены множеством пробелов, то KVirc все равно будет воспринимать их как единственный пробел (как HTML парсеры или интерпретаторы команды unix-шелла). Это поведение оправдано для IRC клиента т.к. пробелы не несут обычно никакой информации в IRC и такая их интерпретация делает код программы более легким :D.

Пробелы упрощаются в обычной интерпретации, но существует несколько способов заставить KVirc не упрощать их и использовать в первоначальном виде. Первый способ это заключение строки в кавычки. Пробелы внутри кавычек не подвергаются упрощению.

    echo Этот     текст     будет     иметь     упрощенные     пробелы
    echo Но     "этот       не     будет"

Первый пример выведет на экран строку с удалёнными множественными пробелами, второй же оставит пробелы внутри кавычек как есть. Кавычки также полезны для того чтобы передать в функцию или команду параметр, содержащий пробелы. Строка, заключенная в кавычки, не будет разделена на параметры.

 echo Параметр1 Параметр2 "Параметр  3 ( с пробелами )" Параметр4

Выполнив пример выше, вы сможете увидеть что пробелы будут сохранены, но кавычки будут удалены из сообщения при выводе. Это является нормальным поведением в KVS и будет рассмотрено подробнее в следующем разделе.

[править] Символ экранирования

Возможно вы уже обратили внимание на то, что некоторые символы интерпретируются в KVirc особым образом. Например, двойные кавычки используются для определения границ строк и могут быть пропущены парсером. Другой пример специального символа - это символ ';': он имеет специальное значение завершения команды. Если вы хотите чтобы ваш печатаемый текст содержал двойные кавычки, вы должны экранировать их. Как и в большинстве языков программирования, символом экранирования является обратный слеш ('\').

echo Так вы можете печатать смайлы! \;)

В примере выше ';' будет интерпретировано как часть строки и будет выведено на экран.

echo "And he said \"Hello world!\""

Пример выше сохранит экранированные кавычки при печати. Также может быть экранирован перевод строки:

    echo This text will be \
        printed on a single line!

После экранированного перевода строки все начальные пробелы и символы табуляции будут пропущены, поэтому, возможно, вам потребуется их добавить перед экранированным переводом строки. Предыдущий пример выведет на экран:

This text will be printed on a single line

Другой пример:

    echo "The new kvirc       \
                IS OUT!"
    echo Check it out at http://www.kvi\
                rc.net!

Будет напечатано:

The new kvirc       IS OUT!
Check it out at http://www.kvirc.net!

Наконец, вы можете и должны экранировать сам символ экранирования, если вы хотите чтобы он был включен в текст строки. Позже мы рассмотрим другое применение символа экранирования, например для запрещения интерпретации симола процента как начала переменной.

[править] Флаги команд

Многие команды имеют различные флаги. Флаги изменяют поведение команды. Многие флаги могут принимать параметры, которые могут быть опциональными. Параметры должны быть присвоены флагу с помощью символа '='

echo -i=2 Этот текст использует специальную цветовую схему
echo --icon=2 Этот текст использует специальную цветовую схему

Флаг -i или --icon изменяет атрибуты текста и его иконку. Флаги должны следовать сразу за ключевым словом команды.

echo Это -i = 2 не будет работать...

Если вы хотите начать первый параметр команды с символа '-', вы должны его экранировать

echo \--- Этот текст будет иметь 3 знака минуса слева

Или использовать кавычки:

echo "--- Этот текст будет иметь 3 знака минуса слева"

[править] Блоки команд

Команды могут быть "сгруппированы" в блоки, используя фигурные скобки в стиле C++.

Например:

{ echo Первая команда; echo Вторая команда; } echo Третья команда

Пример с несколькими линиями:

    {
        echo Первая команда
        echo Вторая команда
    }
    echo Третья команда

В данном примере блоки команд не вносят никакой функциональности, кроме того что делают код более удобочитаемым, но блоки команд будут иметь огромное значение позднее (смотри if, while...).

[править] Комментарии

KVirc поддерживает комментарии в блоках команд. Комментарий начинается с символа # и заканчивается переводом строки. Вы можете начать комментарий где вам угодно.

# Это комментарий, он занимает всю строку
echo After the comment!; # Этот комментарий занимает конец строки

Вы не можете экранировать окончание строки в блоке комментария. (точнее это экранирование не будет иметь никакого значения)

Так же, для коментирования можно использовать двойной слэш // или коментировать целые фрагменты кода символами /* и */ (обязательно в паре)

/*
echo все 
echo эти
echo строки 
echo закоментированы
*/
echo эта команда выполнится как и положено
//echo а это снова коментарий

[править] Отступы

Вам следует использовать пробелы или символы табуляции для стилизации вашего кода. Слово следует написано жирным потому что вам действительно следует это делать! Отступы помогают как автору, так и читателю скрипта понять написанное. Правильная расстановка отступов это первый шаг на вашем пути к славе великого программиста :)

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

Например:

{
<tab>echo Indented command
<tab>{
<tab><tab># Comment
<tab><tab>echo Really Really long indented \
<tab><tab><tab>command
<tab>}
}

Символы табуляции предпочтительней чем пробелы для отступов т.к. пользователь может настроить ширину табуляции по его вкусу. Я предпочитаю, например, ширину табуляции в 4 символа в то время как во многих редакторах по умолчанию стоят 8 символов.

[править] Переменные

Переменные в языке KVS должны начинаться с символа "%", например %var или %Var. Регистр переменной имеет значение. Также очень важно, что переменные, первая буква которой маленькая локальны. Глобальные переменные начинаются с заглавной буквы. Например:

%Var = test

Означает присваивание строки "test" глобальной переменной %Var

%var = test

Означает присваивание строки "test" локальной переменной %var. Например можно использовать:

%var = hello world
echo %var

Переменная, начинающаяся с маленькой буквы может быть сделана глобальной при использовании ключегого слова global. И, напротив, переменная, начинающаяся с заглавной буквы может быть сделана локальной с использованием ключевого слова local.

[править] Объявление и удаление

Переменные объявляются автоматически в месте их первого использования. Например при выполнении кода

%MyVar = some funky text
%X = 2445833
%SevenSpaces = "       "

будут созданы 3 глобальные переменные. Этот кусок кода справедлив и в случае использования локальных переменных. Следующий код

%MyVar = ""
%X = %MyVar
%SevenSpaces =

уничтожает переменные путем присваивания им пустых значений. Значение необъявленной переменной приравнивается по умолчанию к пустой строке.

[править] Присвоение

Справедливы следующие способы присваивания

%number = 1st; echo this is my %number variable test
%number = 1; echo this is my %numberst variable test
%number = 1; echo this is my %number\st variable test

первый пример присваивает переменной %number значение "1st" и после этого выводит на экран строку. Вывод будет выглядеть так:

this is my 1st variable test

второй пример присваивает переменной %number значение 1, при выводе мы увидим следующее:

this is my  variable test

Это произошло потому, что команда echo будет пытаться получить значение переменной %numberst, которая ранее не была объявлена, и значит ее значение будет равно пустой строке.

Третий пример решает проблему второго примера. Символ "\" отделяет имя переменной от текста и на выводе мы получим

this is my 1st variable test

[править] Массивы

Массив это коллекция элементов, каждый из которых имеет свой уникальный индекс.

Основной синтакс для создания массива это:

%<name>[<индекс>]

<name> это имя переменной массива, которое подчиняется всем правиалм именования обычных переменных: имя, начинающееся с большой буквы, обозначает глобальный масив, начинающееся с маленькой буквы - локальный.

<индекс> должен являся целым неотрицательным числом. Он определяет, какой из элементов массива будет выбран. Также он может быть задан с помощью математического выражения или иным способом, сводящимся к вычислению целого неотрицательного числа. Первый элемент имеет индекс 0, последний индекс на единицу меньше количества элементов в массиве.

Вы можете получить длину массива при помощи функции $length(%<name>) или используя конструкцию %<name>[]#. Нет необходимости вручную определять длину массива: она определяется автоматически. Когда вы присваиваете непустую строку элементу массива с индексом INDEX, то массив автоматически увеличивается, чтобы содержать как минимум INDEX+1 элемент. Если массив не существовал перед присваиванием, то он автоматически создается.

Если при первом присваивании задан индекс больший 0, то элементы с индексами от 0 до заданного будут иметь пустые незаданные значения.

# Создает массив из 21 элемента
%Names[20]=Pragma

Для того чтобы удалить элемент из массива вы должны присвоить ему пустое значение.

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

Пожалуйста, помните, что память, занимаемая массивом, зависит от его длины. при создании массива из 10000 элементов (с индексом 9999) вы создаете 10000 переменных! (фактически как минимум ((10000 * 4) + значеняи массива) байт для x86 архитектуры).

Массив уничтожается когда он не содержит больше элементов или когда закончилась его область видимости (например при завершении функции в которой объявлен этот локальный массив)

# Создаем массив из 800 элементов
%Array[799]=test
echo %Array[]#
%Array[299]=test
echo %Array[]#
%Array[799]=
echo %Array[]#
# Теперь он содержит 300 элементов

Вы можете использовать массив как обычную переменную, используя ее полное имя без квадратных скобок, или при помощи конструкции %<name>[] которая также является проверкой (что переменная %<name> явялется массивом). использование %<name>[] таким образом покажет предупреждение, если %<name> не будет являтся массивом. Вы можете присваивать массивы друг другу:

%A = $array(10,20,30)
%B[]=%A[]
%B=%A
echo %B[200]

Когда вы передаете имя массива в команду или функцию, то она может быть интерпретирована как разделенный запятыми список, в случае если этого требует команда или функция.

%Array[0]=Pippo
%Array[1]=Pluto
%Array[2]=Paperino
echo %Array
%Array[]=undefined
echo %Array

Это полезно когда вы хотите очистить значения всех переменных:

%Array[200]=Test
echo %Array[]#
%Array[]=
echo %Array[]#

Вы можете циклически перебрать все элементы массива при помощи команды [foreach]:

%Array[0]=Pippo
%Array[1]=Pluto
%Array[2]=Paperino
foreach(%item,%Array[])echo %item

Само собой, вы можете использовать и традиционный [for] и [while] циклы:

%Array[0]=Pippo
%Array[1]=Never show this
%Array[2]=Pluto
%Array[5]=Hidden again
%Array[8]=Paperino
for(%i=0;%i < %Array[]#;%i+=2)echo Entry %i: \"%Array[%i]\";

[править] Ассоциативные массивы(словари)

Ассоциативные массивы или словари реализованы подобно хешам в perl. Основной способ объявления словаря это:

%<name>{<key>}

<name> это имя переменной словаря, которое подчиняется всем правилам именования обычных переменных: имя, начинающееся с большой буквы, обозначает глобальный массив, начинающееся с маленькой буквы - локальный.

Словарь ассоцирует строку данных со строкой-ключом. Ключ может быть любой строкой, не содержащей неэкранированного символа '}'. Ключи регистронезависимы: "key" это одно и то же что "KEY" или "KeY".

%Ages{Pragma} = 24

Это присваивание ассоциирует с ключем "Pragma" число 24 в глобальном словаре "%Ages". Если словарь до этого не существовал, он создается. Если ключ "Pragma" уже существует в словаре, то значение, ассоциированное с ним, будет заменено на 24.

Для того чтобы удалить ассоциацию, вы можете просто присвоить пустую строку:

%Ages{pragma} =

Словарь автоматически уничтожается, если он больше не содержит ассоциаций (например когда вы присваиваете пустое значение последнему ключу).

Словари могут быть использованы для симуляции массива:

%Links{21} = "http://www.kvirc.net"

Даже многомерного:

%Pixels{324.312} = 1

Запомните что в примере выше "324.312" это одна строка.

Конечно, ключ может содержать переменные или функции.

Пустой ключ означает операцию со всем словарем (как и в массивах):

Вы можете присваивать словари:

%Test2{}=%Test1{}

Можно присваивать словарю значение строки:

%Data{} = "unspecified"

Пример выше присваивает значение строки "unspecified" всем существующим ключам словаря %Data. Таким способом можно просто уничтожить весь массив. Для этого достаточно присвоить значение пустой строки всем его элементам

%Data{} =

[править] Операторы

Операторы это такие же команды, как и все остальные. Все операторы работают с локальными и глобальными переменными. Общий синтаксис оператора это:

       <левый операнд> <оператор> [правый операнд]

где <левый операнд> это переменная, а [правый операнд] - переменная, константа или некоторое выражение. Некоторые операторы не используют [правый операнд] и их действие распространяется напрямую на <левый операнд>.

Оператор Раздел
= Оператор присвоения
++ Операторы увеличения и уменьшения
-- Операторы увеличения и уменьшения
+= Арифметические операторы с присвоением
-= Арифметические операторы с присвоением
*= Арифметические операторы с присвоением
/= Арифметические операторы с присвоением
%= Арифметические операторы с присвоением
|= Побитовые операторы с присвоением
&= Побитовые операторы с присвоением
^= Побитовые операторы с присвоением
<<= Побитовые операторы с присвоением
>>= Побитовые операторы с присвоением
.= Операторы объединения строк
<< Операторы объединения строк
<, Операторы объединения строк
=~ binding operator

[править] Оператор присвоения

Оператор присвоения - это самый известный из операторов. В KVS он работает аналогично тому, как это происходит в любом другом языке программирования. Синтаксис:

<цель> = <значение>

<цель> должна быть переменной, <назначение> может быть любым параметром.

Если переменная <цель> не существует,она создается. Если она уже существует, то преобразуется к типу выражения <значение>.

Если значение является пустой строкой, то переменная цели уничтожается.

# Присвоение константы переменной %Tmp
%Tmp = 1
echo %Tmp
# Присвоение строковой константы переменной %Tmp
%Tmp = some string
echo %Tmp
# Присвоение строковой константы переменной %Tmp
%Tmp = "some string with whitespace         preserved"
echo %Tmp
# Присвоение одной переменной другой копирует значение
%Someothervariable = "Contents"
%Tmp = %Someothervariable
echo %Tmp
# Присвоение переменной строки переменной %z
%color = blue
%z = my eyes are %color
echo %z
# Присвоение переменной строки (с вызовом функции внутри) переменной %x
%x = the system os is $system.osname
echo %x
# Присвоение пустой строки переменной %y уничтожает %y
%x =
echo %y
# Это эквивалент предыдущему примеру
%y = ""
# Это приведет к томуже результату если функция возвратит пустой результат
%y = $function()
# Присвоение переменной строки элементу словаря
%Dict{key} = $system.osname\ian
# Уничтожение элемента массива
%mydict[23] = ""
# Копирование словаря
%anotherdict{"The key"} = "Some dummy value"
%mydict = %anotherdict
echo %mydict{"The key"}
# Это сконвертирует словарь %mydict к строковой переменной с уничтожением всего содержимого
%mydict = "some default value"
# Уничтожение всего словаря
%anotherdict =

[править] Операторы увеличения и уменьшения

Эти 2 оператора работают только с численными операндами. Синтаксис:

<переменная>++
<переменная>--

++ увеличивает значение <переменной> на 1, -- уменьшает значение <переменной> на 1.

Это эквивалентно += 1 и -= 1.

<переменная> должна существовать и содержать целочисленное значение. Если <переменная> содержит не целое число (вещественное), то оно округляется до ближайшего целого и потом уменьшается/увеличивается.

Примеры

%a=10
echo "Увеличение"
while(%a < 20)
{
    echo %a
    %a++
}
echo "Уменьшение"
while(%a > 10)
{
    echo %a
    %a--
}
echo "тестирование в цикле"
for(%a=0;%a < 10;%a++)
{
    echo %a
}

[править] Арифметические операторы с присвоением

Арифметические операторы с присвоением работают только с численными операндами. Синтаксис:

<target> += <right_operand>
<target> -= <right_operand>
<target> *= <right_operand>
<target> /= <right_operand>
<target> %= <right_operand>

<target> должна быть существующей переменной с численным значением. <right_operand> также должен быть представлен числом. Учтите что если вы хотите, чтобы правый операнд был результатом некоторого математического выражения, то его нужно заключить в $(*) .

Оператор += увеличивает <target> на значение <right_operand> и сохраняет полученное значение в переменной <target>.

Оператор -= уменьшает <target> на значение <right_operand> и сохраняет полученное значение в переменной <target>.

Оператор *= умножает <target> на значение <right_operand> и сохраняет полученное значение в переменной <target>.

Оператор /= делит <target> на значение <right_operand> и сохраняет полученное значение в переменной <target>.

Оператор %= подсчитывает остаток при делении <target> на значение <right_operand> и сохраняет полученное значение в переменной <target>.

Операции деления вызывают ошибку в случае если <right_operand> равно 0.

Если оба выражения <target> и <right_operand> являются целыми числами, то результаты деления будут также округлены до целого числа. Если <target> или <right_operand> или оба выражения являются числами с плавающей точкой, то результатом также будет выражение с плавающей точкой. Примеры

    %a=10
    echo %a
    %a+=20
    echo %a
    %a-=$(%a - 1)
    echo %a
    %a *= 10
    echo %a
    %a /= 21
    echo %a
    %a *= 20
    echo %a
    %a /= 21.0
    echo %a
    %b = 10.0
    %a %= %b
    echo %a
    %a = 10
    %b = 3
    # nice trick
    %a /= %b.0
    echo %a

[править] Побитовые операторы с присвоением

Эти операторы работают только с целочисленными операндами. Синтаксис:

<target> |= <right_operand>
<target> &= <right_operand>
<target> ^= <right_operand>
<target> >>= <right_operand>
<target> <<= <right_operand>

<target> должна быть существующей целочисленной переменной.<right_operand> должен быть целочисленным значением. Если <target> или <right_operand> содержат значения с плавающей точкой, то они будут обрезаны до целого числа

Помните, что если вы хотите чтобы <right_operand> был результатом математического выражения, то вы должны заключить это выражение в $(*).

Оператор |= подсчитывает логическое или между <target> и <right_operand>, сохраняет результат в переменной <target>.

Оператор &= подсчитывает логическое и между <target> и <right_operand>, сохраняет результат в переменной <target>.

Оператор ^= подсчитывает логическое xor между <target> и <right_operand>, сохраняет результат в переменной <target>.

Оператор >>= сдвигает биты <target> на <right_operand> вправо, сохраняет результат в переменной <target>.

Оператор <<= сдвигает биты <target> на <right_operand> влево, сохраняет результат в переменной <target>.

Запомните что оператора "!=" не существует. Вместо него вы можете использовать %a = $(!%b).

Для операторов >>= и <<= <right_operand> должен быть положительным и целочисленным.

Примеры:

    %a = 1
    echo %a
    %a |= 2
    echo %a
    %a &= 2
    echo %a
    %a ^= 1
    echo %a
    %a >>= 2
    echo %a
    %a <<= 1
    echo %a

[править] Операторы объединения строк

Эти операторы служат для слияния строк.

Синтаксис:

<target> .= <right_operand>
<target> << <right_operand>
<target> <, <right_operand>

Оператор .= дописывает в конец <target> строку <right_operand>.

Оператор << если <target> не является пустой строкой, дописывает в конец <target> строку <right_operand>, разделяя строки пробелом. Если строка <target> пустая, то присваивает ей значение <right_operand>.

Оператор <, действует также как << но использует запятую в качестве разделителя.

Последние 2 оператора очень удобны при создании списков строк, разделенных пробелами или запятыми.

Примеры:

    %a = ""
    %a << free
    echo %a
    %a .= bsd
    echo %a
    %a << rox
    echo %a
    %a <, but linux is better!
    echo %a

[править] Пишем свой скрипт

[править] Алиасы

Алиас это определенная пользователем команда. Она может быть использована для того чтобы переименовать стандартную команду KVirc, для автоматизации некоторых задач, или как структурная единица программы. Алиасы могут быть созданы или удалены при помощи графического редактора алиасов, из командной строки или скрипта с использованием команды alias. Созданный однажды, алиас остается в конфигурации KVirc до тех пор, пока он не будет удален. Следующие примеры попробуют внести ясность в только что сказанное. Команда join очень часто используема. Хорошей идеей является использование простого "j" вместо слова join из-за того что писать 1 символ намного быстрее. Нет ничего проще в KVirc. Просто введите в командной строке:

alias(j){ join $0-; };

Это создаст алиас "j". После этого вы сможете использовать /j как обычную команду

j #kvirc

Вы, возможно заметили странную функцию $0- в теле алиаса: она означает "все параметры, переданные алиасу". Это значит, что когда вы вызываете

j #kvirc testpassword

Оба параметра (#kvirc и testpassword) будут переданы в команду join. Функции $N (где N-число) это специальные функции, которые возвращают значение параметра в заданной позиции. Она возвращает значение параметра в позиции N-1, а не N, т.к. параметры пронумерованы начиная с нуля ($0 это первый параметр!). $N-M возвращает параметры с N по M, а $N- возвращает параметры, начиная с N до конца списка параметров. В примере выше $0- предназначено для того чтобы передать все параметры, начиная с первого.

Для того чтобы удалить алиас из командной строки вы можете определить его как алиас с пустым телом:

   alias(j){}

Это удалит определенный ранее алиас.

Частой задачей в IRC является кик с последующим баном. Вы сначала баните пользователя, а потом кикаете его с канала. Это предполагает использование двух команд: кика и бана. Хорошая идея в этом случае создание алиаса "kb", котоырй будет выполнять эти 2 действия. Это просто:

alias(kb){ ban $0; kick $0-; };

Этот код создаст алиас "kb", который потом может быть вызван как обычная команда:

kb spammer Ты не нужен здесь!

Этот алиас сначала выполнит команду "ban spammer", а затем "kick spammer Ты не нужен здесь!". Наш алиас очень прост. Он не проверяет того, что параметры не пусты. Сервер может выдать ошибку при использовании такого алиаса.

Алиас может быть в любое время изменен повторным использованием команды alias. Давайте сделаем наш "kb" более умным, добавив проверку на непустые параметры. Совет: Вы можете использовать графический редактор алиасов.

    alias(kb)
    {
        if("$0" == "")
        {
            echo "Использование: /kb <ник> <причина кика>"
            return
        }
        ban $0
        %reason = $1-
        if("%reason" == "")%reason = "Ты не нужен здесь!"
        kick $0 %reason
    }

Пример выше сначала проверяет правильность первого параметра, переданного в алиас: если ник не задан, алиас сообщит об этом пользователю и прекратит обработку. Следующий шаг - вызов команды "ban <ник>". Другое улучшение это причина кика по умолчанию: мы сначала присваиваем переменной %reason значения оставшихся параметров, и если переменная остается пустой, то ей назначается значение по умолчанию. В конце концов вызывается команда "kick <ник> <причина>". Возможно вам нужно обратиться к документации по синтаксису языка, чтобы полностью понять этот код.

Алиасы могут быть использованы в целях структурного программирования. В больших скриптах вы обязательно встретитесь с тем, что будете выполнять одно и то же действие в нескольких местах (например цветной вывод или подсчет значения какой-либо переменной на основе некоторых данных). Алиасы могут решить эту проблему, выполняя роль известных в других языках программирования высокого уровня механизмов "процедур" или "функций". Алиас, как функция, может быть вызван из других скриптов или алиасов, которые будут нуждаться в функциональности этого алиаса.

Алиасы также могут быть использованы как функции, возвращающие значения. Представим, что вам часто нужно подсчитывать сумму трех переменных. Для этого можно написать функцию-алиас такого вида:

alias(sum3){ return $($0 + $1 + $2); };

Этот код создаст алиас "sum3" и сделает его доступным как команду и как функцию. Команда "return" установит возвращаемое последовательностью команд значение (помните что алиас это и есть последовательность команд) и остановит выполнение скрипта, передав управление вызвавшему алиас скрипту. Таким образом return $($0 + $1 + $2); установит возвращаемое алиасом значение в математическую сумму $($0 + $1 + $2). Потом вы можете использовать этот алиас следующим образом:

    ...
    %myfirstsum = $sum3(%somevalue,%someothervalue,4)
    %anothersum = $sum3(12,%somevalue,%anothervalue)
    ...

Здесь некоторые переменные даны без описания, но мы верим, что читатель поймет этот пример без дополнительных комментариев. Функции-алиасы сохраняют всю функциональность обычных алиасов. То есть возможно выполнение кода:

/sum3 1 2 3

Это абсолютно корректный вызов. Однако он не приведет к каким-либо видимым результатам потому что строка ввода игнорирует возвращаемый результат. Если команда return не была вызвана в теле алиаса, то его возвращаемое значение остается пустым.

Алиасы могут иметь флаги, как и любые другие команды. Для получения значений заданных флагов существует функция $sw.

[править] События

KVirc вызывает некоторое событие в тот момент, когда это событие происходит  :P

Вы можете определить несколько обработчиков одного и того же события.

Обработчик события это набор строк кода, определяемых пользователем, который выполняется в определенных условиях.

События могут быть созданы или удалены при помощи редактора событий или с испольованием команды event.

Например, OnIrc вызывается когда операции входа были завершены и вы можете считать, что Вы "уже полностью" в IRC. Например, Вы возможно хотите себе "авто-заход" на некоторые каналы. нет ничего проще! Следующий участок кода добавляет обработчик к событию OnIRC, который совершит заход на три канала:

event(OnIRC,autojoin)
{
    echo автоподключение к моим любимым каналам...
    join #kvirc,#siena,#linux
}

Теперь попробуйте приконнектиться к серверу и Вы убедитесь, что произойдёт автоматический заход на три канала! Вы, возможно, захотите совершить ещё несколько действий сразу же после установки соединения, например Вы вероятно захотите сразу же поискать своего друга выполнением команды whois (ну... конечно, Вы могли бы использовать для этого команду notify, но, в общем, такой вот пример).

Теперь добавьте запрос whois к тому обрабочику, что был указан выше, или просто создайте новый:

event(OnIRC,lookforfred)
{
    echo Ищем fred'a...
    whois fred
}

(Ещё более замечательной идеей было бы использовать команду awhois ... но это остаётся читателю для тренировки).

Чтобы удалить обработчик события, используйте всё ту же команду event, но с пустым блоком кода:

event(OnIRC,lookforfred){}

Некоторые события передают вам различные данные в своих позиционных параметрах.

Например, вы получаете бан в канале, KVIrc вызывает событие onmeban: вам, вероятно, будет интересно, кто же такой WHO, который забанил Вас. KVIrc передаст информацию об "источнике бана" через позиционные параметры $0,$1 и $2.

Вы можете посмотреть список доступных событий.

[править] Объектно-ориентированный скриптинг

[править] Введение

Язык сценариев KVIrc по сути не является объектно-ориентированным. Тем не менее, объекты являются абстракциями высокого уровня, которые позволяют писать сложный код "чисто". Потому я добавил по крайней мере какую-то поддержку псевдо-объектов.

[править] Общее представление

Объекты упорядочиваются в виде древовидных структур. Каждый созданный вами объект является объектом верхнего уровня или children (наследником, дочерним объектом) другого объекта. Объект верхнего уровня не имеет предков (родительских объектов). Очевидно, что у всех объектов могут быть дочерние объекты.

Когда объект уничтожается, все его наследники также уничтожаются. Объекты верхнего уровня автоматически уничтожаются при выходе из KVirc. Объекты являются глобальными для всего приложения (в этом отличие от предыдущих версий KVirc, где объекты были локальными для текущего окна и упорядочивались в единственное дерево с встроенным root-объектом).

Каждый объект это экземпляр класса, который определяет его возможности. Каждый объект также имеет имя, которое не обязательно должно быть уникальным и присваивается программистом; имя это всего лишь мнемоническая уловка (?) и вам оно возможно не понадобится (the name is just a mnemonic expedient, and you may also not need it).

Каждый объект идентифицируется с помощью OPAQUE UNIQUE ID. ID присваивается KVIrc и может удерживаться в любой переменной. Можно считать, что идентификатор объекта (id) - это "хэндл объекта" ("handle for the object") или указатель на объект. Любое действие, выполняемое над объектом, потребует ID объекта.

[править] Создание и уничтожение

Для создания объектов следует использовать функцию $new(). $new() принимает три параметра:

- Класс объекта (про классы будет сказано дальше в этой документации)

- ID родительского объекта , (может быть 0).

- Имя объекта (может быть пустым)

   %myobject = $new(object,0,theName)

$new() возвращает значение ID, присвоенное только что созданому объекту, или "0" если создание объекта завершилось неудачей (обратите внимание, что "0" это строка потому что идентификаторы объектов по большей части строки и 0 это неправильный идентификатор объекта). В правильно написаных скриптах, неудачное создание объектов это скорее исключения из правил. Но вы все равно можете проверить, что объект был создан без ошибок.

   if(%myobject)echo "Object created!"
   else echo "Object creation failed!"

Вы можете сравнивать объекты по их ID:

   if(%myobject == %anotherobject)echo "Это одинаковые объекты!";

Идентификатор родительского объекта опционален, и если он не указан то устанавливается в 0. Имя объекта также опционально, но оно может пригодиться, например для поиска, так что не пренебрегайте им.

Для удаления объекта используейте команду delete. (В прошлых версиях эта команда называлась "destroy").

   delete %myobject

Если удаляемый объект имеет дочерние объекты, то они также будут удалены.

Каждый объект может иметь свои переменные (поля). Вы можете обращаться к ним через оператор "->":

   %myobject->%fieldVariable = dataString

Для освобождения поля присвойте ему пустую строку (как и в случае с обычными переменными). Чтобы получить значение любого поля используйте :"->":

   echo %myobject->%fieldVariable

Оператор '->' заимствован из языка C. В скриптовом языке KVIrc он является переключателем с глобального пространства имен на пространство имен объекта. В примере выше поле %fieldVariable принадлежит объекту %myobject. Первый символ в названии переменной не имеет специального значения в пространстве имен объекта (в глобальном пространстве имен переменные названые с большой буквы являются глобальными для приложения, названые же с маленькой буквы являются локальными). Т.е. в пространстве имен объкта все переменные регистронезависимые.

Любой оператор можно применить к полям объекта:

   %myobject->%fieldVariable = 0
   %myobject->%fieldVarialbe ++
   if(%myobject->%fieldVariable != 1)echo KVIrc is drunk , maybe a reboot will help ?

Вы можете имитировать структуру языка С "на лету":

   # Create an user description on the fly
   %myobj = $new(object,0,userDescription)
   # Set the fields
   %myobj->%nickname = Pragma
   %myobj->%username = daemon
   %myobj->%hostname = pippo.pragma.org
   %myobj->%info = Pragma goes always sleep too late
   %myobj->%info << and wakes up too late too!
   # Call an (user defined) alias that stores the data to a file
   storetofile %myobj
   # Destroy the object
   delete %myobj

Поля могут быть массивами:

   %theobj->%field[key] = something

В отличии от С, в kvs не нужно заранее объявлять поля. Любой из объектов может иметь любое поле; уничтожение поля "unset", эквивалентно присваиванию ему пустого значения.

Примечание: Скриптовый язык KVIrc не типизирован. Любой идентификатор класса объекта (информация о классах будет приведена ниже) может храниться в обычной переменной KVIrc, и узнать о каких-либо присущих ему свойствах по идентификатору невозможно. Это может немного затруднить работу с объектами. Однако, при определенном умении, вполне возможно использовать все преимущества объектов. Идентификацию классов объектов можно, например, "эмулировать" при осторожном использовании имен объектов; так, в приведенном выше примере объект %myobj был создан с именем "userDescription". В таком случае алиас storetofile мог бы проверять присвоенное объекту имя, и в случае его несоответствия с "userDescription" прекращать выполнение.

Note: The KVIrc scripting language is not typed. Any object class (be patient...I'll explain classes in a while) identifier can be stored in any KVIrc variable: it is not possible to find out the object features by "examining" its identifier. This may make the usage of objects a bit "unclear"; Howewer, with some experience you will be able to use the objects in a very powerful way. The type-safety can be also simulated by a careful usage of object names; in the above example, the %myobj object was created with the "userDescription" name. The storetofile alias could check the passed object's name and refuse to work if that does not match "userDescription". A more complex use of fields will be described later in this document.

[править] Методы (функции-члены)

Как и в C++, объекты могут иметь функции-члены. Например, объекты класса "object" предоставляют функции $name() и $classname().

   %tmp = $new(object,0,myobject)
   echo The object's name is %tmp->$name() , the class name is %tmp->$classname()
   # Destroy the object
   delete %tmp

Кроме того, этим классом предоставляется функция $children(). Она возвращает разделенный запятыми список дочерних объектов.

   %tmp = $new(object,0,myobject)
   %tmpchild = $new(object,%tmp,child1)
   %tmpchild = $new(object,%tmp,child2)
   %tmpchild = $new(object,%tmp,child3)
   echo The object's children list is : %tmp->$children()
   # Destroy the object and the children
   delete %tmp

Также для любого объекта имеются две специальные функции: конструктор (constructor) и деструктор (destructor). Более подробную информацию о них Вы сможете найти далее в этом документе, а пока достаточно будет отметить, что они вызываются в KVIrc автоматически: constructor - при создании объекта, destructor - при уничтожении с помощью delete.

Функции объектов могут быть переопределены "на лету" при помощи команды privateimpl. (Это необычная возможность: в отличие от многих других языков, можно переопределять функции во время выполнения, когда объект уже создан.)

   %tmp = $new(object,0,myobject)
   foreach(%i,1,2,3)
   {
       %tmpchild = $new(object,%tmp,child%i)
       privateimpl(%tmpchild,destructor){ echo Object $this ($this->$name()) destroyed; }
   }
   privateimpl(%tmp,destructor)
   {
       %count = 0;
       foreach(%t,$this->$children())
       {
           echo Children : %t->$name() with class %t->$classname()
           %count++
       }
       echo Just before destroying my %count children.
   }
   # Destroy the object and the children
   delete %tmp

В этом примере создаются четыре объекта. "Родительский" объект с именами "myobject", и три дочерних. Для каждого из дочерних объектов переопределяются деструкторы таким образом, чтобы они сообщали свои имена (обратите внимание на использование $this). В деструкторе родительского объекта выполняется перечисление дочерних объектов. Затем родительский объект уничтожается, вызывая следующие действия:

- выполняется деструктор родительского объекта

- уничтожаются дочерние объекты (с последовательными вызовами всех их "индивидуальных" деструкторов)


Не все функции объектов обязаны возвращать какое-либо значение. Если функция не возвращает значение или возвращаемое значение не нужно, то можно вызвать ее следующим способом:

   %anyobject->$functionname()

[править] Классы

Все объекты являются экземплярами определенных классов. Эта концепция присутствует практически во всех объектно-ориентированных языках. Класс является набором методов, определяющих поведение объекта... не самая легкая задача все это объяснить, лучше покажу на примере:

class HostAddress
{
   field hostname
   function ipnumber()
   function isLocalhost()
}

Показанный класс представляет сетевое имя. После создания экземпляра этого класса можно задать его поле hostname, указав, например, "www.kernel.org". Теперь объект способен прозрачным путем выдавать информацию об указанном имени: посредством вызова функции ipnumber() можно получить IP-адрес, соответствующий указанному имени; функция isLocalhost() будет определять, не ссылается ли указанный адрес на текущий компьютер (localhost). Внутренняя работа объекта скрыта от пользователя, но она вполне может быть довольно велика. Чтобы получить IP-адрес компьютера, объекту возможно потребуется выполнить вызов DNS (обычно это непростая задача). Для проверки, ссылается ли указанное имя на текущий компьютер, объекту возможно потребуется получить имя текущего компьютера от операционной системы и затем сравнить его со значением, записанным в поле hostname.

Внутренняя работа объекта определяется реализацией класса. Соответственно, программист, создающий класс, должен написать его реализацию.

class HostAddress
{
   field hostname
   function ipnumber()
   {
       find the nearest DNS server
       make the dns call
       wait for the response
       decode the response
   }
   function isLocalhost()
   {
       query the kernel for the local hostname
       compare the obtained hostname with the hostname field
   }
}

В этом примере я реализовал функции, используя несуществующий "фантастический" язык.

Давайте теперь вернемся к реальному миру.

KVirc содержит множество встроенных и готовых к использованию классов. Основной класс - это "object": все остальные классы порождаются от него (подробнее о наследовании смотрите далее в этом документе).

Другой доступный класс - это "socket", являющийся интерфейсом к реальным сокетам системы. Экземпляр этого класса может соединяться и обмениваться информацией с другими компьютерами в сети.

Определения классов являются ГЛОБАЛЬНЫМИ для всего приложения, т.е. могут использоваться в любом месте.

Теперь можно сказать что в KVIrc класс - это набор возможностей, определяющих поведение объекта. Пользовательский интерфейс класса - это функции-члены и события.

[править] Наследование

Команда class позволяет определять новые классы объектов. В KVI++ новый класс всегда должен быть унаследован от другого класса. Минимальный уровень наследования - это наследование от класса object.

   class(helloworld,object)
   {
       sayhello()
       {
           echo Hello world!
       }
   }

Продемонстрированный класс назван "helloworld" и унаследован от класса "object". А это означает, что "helloworld" имеет также функции: $name() , $classname() , $children() ... , имеющиеся в классе "object". Кроме того, в классе имеется функция $sayhello() , выдающая в консоли фразу "Hello world!" . Теперь можно создавать экземпляры этого класса:

   %instance = $new(helloworld)
   %instance->$sayhello()

Это было очень просто... Давайте немного усложним задачу и сделаем немного больше: унаследуем от "helloworld" другой класс и заставим его выводить фразу "Hello world!" на двух разных языках:

class(localizedhelloworld,helloworld)
{
   # define the setlanguage function
   # note that <$0 = language> is just a programmer reminder
   setlanguage(<$0 = language>)
   {
       if(($0 == english) || ($0 == italian))
       {
           [fnc:$this]$$[/fnc]->%lang = $0
           return 1
       } else {
           echo I don't know that language ($0)
           echo defaulting to english
           [fnc:$this]$$[/fnc]->%lang = english
           return 0
       }
   }
   sayhello()
   {
       if([fnc:$this]$$[/fnc]->%lang == italian)echo Ciao mondo!
       else [fnc:$this]$$[/fnc]->$helloworld:sayhello()
   }
}

Теперь можно выполнить следующее:

 %m = $new(localizedhelloworld)
 %m->$setLanguage(italian)
 %m->$sayhello()
 %m->$setLanguage(english)
 %m->$sayhello()
 %m->$setLanguage(turkish)
 %m->$sayhello()
 delete %myobj

Данный класс унаследован от ранее определенного helloworld, и, соответственно, получает функции и события класса object, а также функцию sayhello класса helloworld. В новом классе определена также функция setlanguage, которая сохраняет в переменную название языка, переданное ей в качестве параметра (после проверки на правильность указания языка). ($0 - это первый переданный параметр) Если язык неизвестен, то функция setlanguage возвращает 0 (false). Теперь, мы хотим возможность выдавать "hello world" на итальянском и английском. Для этого переопределяется унаследованная функция sayhello, т.е. определяется ее новая реализация: если при вызове %object->$sayhello() переменная %object содержит ID объекта класса localizedhelloworld, то будет вызвана новая реализация этой функции. Унаследованная функция sayhello могла выдавать "hello world" только на английском, однако мы можем ее использовать в новой реализации, не выполняя написание ее кода еще раз: если указанный язык не итальянский (а кроме итальянского мы представили в этом классе только английский), то вызываем реализацию из базового класса.

   [fnc]$this/[fnc]->$helloworld:sayhello()
   # equivalent to $$->$helloworld:sayhello(),
   # to $this->$helloworld::sayhello(),
   # and to $$->$helloworld::sayhello()

В этом примере все значения %lang, которые не равны "italian" мы считаем равными "english". Это не всегда правильно. Однако, сразу после создания объекта переменная %lang будет пуста. Показанный класс будет работать нормально в любом случае, но если мы хотим, чтобы переменные всегда находились в корректном состоянии, то нужно использовать конструкторы, которые будут описаны ниже.

Примечание: множественное наследование (наследование от более чем одного базового класса) не реализовано, KVIrc это не компилятор :)

[править] Конструкторы и деструкторы

Конструктор класса - это функция, вызываемая в KVIrc автоматически сразу после создания объекта перед возвратом из функции $new(). Конструктор может быть использован для инициализации внутреннего состояния объекта. В отличие от C++, в KVIrc конструктор может возвращать значение: если конструктор возвращает 0, то это говорит о неудаче создания объекта - он незамедлительно уничтожается и функция $new() возвращает 0. Любое другое значение воспринимается как успешность создания объекта, и функция $new() возвращает ID созданного объекта. Во всех встроенныех в KVIrc классах конструкторы определены таким образом, что неудачи создания объекта никогда не бывает (за исключением случая нехватки памяти - "out of memory"), поэтому проверять возвращаемый $new() результат необязательно при создании объектов таких классов.

В унаследованных классах конструктор может быть переопределен для инициализации состояния объекта. Однако, следует не забывать вызывать из него конструктор базового класса, чтобы состояние базового класса было корректно установлено, и проверять возвращаемое им значение (вполне возможно, например, что инициализация в базовом классе будет успешна, а в унаследованном - неуспешна). Конструкторы встроенных классов ничего не делают кроме возврата значения 1, и поэтому их вызывать необязательно, но в некоторых случаях это может понадобиться. Такое поведение несколько отличается от таких языков как C++, где конструкторы вызываются автоматически.

[править] Сигналы и слоты

Сигналы и слоты -- мощное средство для организации взаимодействия между объектами.

Сигналы отправляются (emit) от одного объекта к другому. Например, объект класса кнопки (button) может испускать сигнал clicked при щелчке на этой кнопке.

Один объект отправляет (emit) сигналы. Например, у вас в программе есть кнопка, которая отправляет сигнал clicked, когда пользователь её нажимает. В другом объекте существуют так называемые слоты (slot), которые "срабаотывают" при получении очередного сигнала.

К одному сигналу можно подключить несколько слотов, и наоборот -- к одному слоту несколько сигналов. Это позволяет нескольким объектам узнавать об изменении состояния одного, и одному объекту -- о состоянии несокльких.

В принципе, механизм сигналов и слотов можно заменить аккуратным использованием обыкновенных методов классов. Почему сигналы и слоты лучше? Потому что они эффективнее. У сигналов и слотов нет эквивалента в C/C++, однако они реализованы как в библиотеках высокого уровня, так и на уровне операционных систем (там они обеспечивают межпроцессное взаимодействие).

[править] Классы объектов

[править] widget

Base class for all widgets


Inherits

object


Description

This object class is the rappresentation of a widget. All the other widget-type classes inherit from this one.


[править] Functions

$show()

Shows this widget and the children. See also $hide() and $isVisible.


$hide()

Hides this widget (and conseguently all the children). See also $show() and $isVisible.


$repaint(<bool erase>)

Repaints the widget directly by calling $paintEvent() immediately. If erase is TRUE, erases the widget before the $paintEvent() call.


$x()

Returns the x coordinate of the upper-left corner of this widget relative to the parent widget, or to the desktop if this widget is a toplevel one.


$y()

Returns the y coordinate of the uspper-left corner of this widget relative to the parent widget, or to the desktop if this widget is a toplevel one.


$width()

Returns the width of this widget in pixels.


$height()

Returns the height of this widget in pixels.


$geometry()

Returns the widget geometry in this form: x, y, width, height.


$setGeometry(<x>,<y>,<width>,<heigth>)

Sets the geometry of this widget. <x> and <y> are relative to the parent widget or to the desktop (if this widget is a toplevel one). All the parameters are in pixels.


$setMinimumWidth(<value>)

Sets the minimum width of this widget to <value>. The user will not be able to resize the widget to a smaller value. This value is also used by the layout class.


$setMinimumHeight(<value>)

Sets the minimum height of this widget to <value>. The user will not be able to resize the widget to a smaller value. This value is also used by the layout class.


$setMaximumWidth(<value>)

Sets the maximum width of this widget to <value>. The user will not be able to resize the widget to a bigger value. This value is also used by the layout class.


$setMaximumHeight(<value>)

Sets the maximum height of this widget to <value>. The user will not be able to resize the widget to a bigger value. This value is also used by the layout class.


$move(<x>,<y>)

Moves this widget to the coordinate <x> and <y> relative to its parent widget (or the desktop if this widget is a toplevel one). This is equivalent to $setGeometry(<x>,<y>, $width(),$height()).


$resize(<width>,<height>)

Changes the widget's width to <width> and height to <height>. See also $setGeometry().


$isEnabled()

Returns '1' if the widget is enabled , '0' otherwise. See also $setenabled().


$setEnabled(<bool>)

Sets the widget state to enabled or disabled if <bool> is 1 or 0 respectively. A disabled widget does not receive keyboard nor mouse input.


$setCaption(<text>)

Sets the caption of this widget to <text>. This is meaningful for toplevel widgets only.

$setToolTip(<tooltip_text>) Set the tooltip of this widget; the text can contain HTML formatting.


$caption()

Returns the caption text of this widget.


$isTopLevel()

Returns '1' if this widget is a toplevel (parentless) one, '0' otherwise.


$isVisible()

Returns '1' if this widget is currently visible (read: is managed by the window manager and displayed by the X server; the widget may be hidden behind other widgets). If the widget is not visible this function returns '0'. See also $show() and $hide().


$raise()

Moves this widget to the top of the stack of the widgets relative to its parent. See also $lower.


$lower()

Moves this widget to the bottom of the stack of the widgets relative to its parent. See also $raise


$hasFocus()

Returns '1' if this widget has the keyboard focus. See also $setFocus.


$setFocus()

Sets this widget to be the one that receives keyboard events. See also $hasFocus


$parentWidget()

Returns the object id of the parent widget, or '0' if this widget is a toplevel one.


$backgroundColor()

Returns the background color of this widget in hexadecimal html-like format. For example , for a black bacground you will get the string "000000" , for a red one , "FF0000", for a white one "FFFFFF". See also $setBackgroundColor()


$setBackgroundColor(<color>)

Sets the background color of this widget to <color>.


$setForegroundColor(<color>)

Sets the foreground color of this widget to <color>. <color> must be a string with 6 hexadecimal digits (like the ones used to specify colors in html pages). The first two digits specify the RED component, the third and fourth digit specify the GREEN component and the last two specify the BLUE component. For example "FFFF00" means full red, full green and no blue that gives a yellow color, "808000" designates a brown color (dark yellow), "A000A0" is a kind of violet. See also $foregroundColor.


$foregroundColor()

Returns the foreground color of this widget in hexadecimal html-like format. See also $setForegroundColor.


$setMouseTracking(<bool>)

Enables or disables the mouse tracking if <bool> is '1' or '0' respectively. When mouse tracking is enabled you will receive mouse move events even if no button is pressed, otherwise you will receive it only when a mouse button is being pressed (so after a mousePressEvent).


$mousePressEvent(<button>,<x>,<y>)

This function is called when a mouse button is pressed while the cursor is in this widget. <button> is 0 if the pressed button is the left one, 1 if the button is the right one and 2 if it is the middle one. The <x> and <y> coordinates are relative to this widget upper-left corner and are expressed in pixels. If you call "setreturn 1" you will stop the internal processing of this event. The default implementation does nothing.


$mouseReleaseEvent(<button>,<x>,<y>)

This function is called when a mouse button is released while the cursor is in this widget. <button> is 0 if the released button is the left one, 1 if the button is the right one and 2 if it is the middle one. The <x> and <y> coordinates are relative to this widget upper-left corner and are expressed in pixels. If you call "setreturn 1" you will stop the internal processing of this event. The default implementation does nothing.


$mouseDoubleClickEvent(<button>,<x>,<y>)

This function is called when a mouse button is double clicked while the cursor is in this widget. <button> is 0 if the double clicked button is the left one, 1 if the button is the right one and 2 if it is the middle one. The <x> and <y> coordinates are relative to this widget upper-left corner and are expressed in pixels. If you call "setreturn 1" you will stop the internal processing of this event. The default implementation does nothing.

$mouseMoveEvent(<button>,<x>,<y>) This function is called when the mouse cursor moves inside this widget. <button> is 0 if the pressed button is the left one, 1 if the button is the right one and 2 if it is the middle one. The special value of -1 indicates that no button is being pressed. The <x> and <y> coordinates are relative to this widget upper-left corner and are expressed in pixels. Normally you will receive this event only if a mouse button is being pressed while moving. If you want to receive it also when the mouse buttons are not pressed, call $setMouseTracking(). If you call "setreturn 1" you will stop the internal processing of this event. The default implementation does nothing.


$focusInEvent()

This function is called when this widget gains keyboard focus. If you call "setreturn 1" you will stop the internal processing of this event. The default implementation does nothing.


$focusOutEvent()

This function is called when this widget looses keyboard focus. If you call "setreturn 1" you will stop the internal processing of this event. The default implementation does nothing.


$mouseLeaveEvent()

This function is called when the mouse leaves this widget. If you call "setreturn 1" you will stop the internal processing of this event. The default implementation does nothing.


$mouseEnterEvent()

This function is called when the mouse enters this widget. If you call "setreturn 1" you will stop the internal processing of this event. The default implementation does nothing.


$showEvent()

This function is called when this widget is being shown. If you call "setreturn 1" you will stop the internal processing of this event. The default implementation does nothing.

$hideEvent() This function is called when this widget is being hidden. If you call "setreturn 1" you will stop the internal processing of this event. The default implementation does nothing.


$closeEvent()

This function is called when this widget is going to be closed. If you call "setreturn 1" you will ignore the close event. The default implementation does nothing.


$resizeEvent()

This function is called immediately after this widget has been resized. If you call "setreturn 1" you will stop the internal processing of this event. The default implementation does nothing.


$moveEvent()

This function is called immediately after this widget has been moved. If you call "setreturn 1" you will stop the internal processing of this event. The default implementation does nothing.


$paintEvent()

This event handler can be reimplemented to repaint all or part of the widget. It's needed by the Painter class. It's very useful for drawing flicker free animations or low level special graphic effects. The default implementation does nothing.


$setIcon(<image_id>)

Sets the icon for this widget. This is meaningful only for toplevel widgets. See the image identifier documentation for the explaination of the <image_id> parameter.


$setBackgroundImage(<image_id>)

Sets the background image for this widget. See the image identifier documentation for the explaination of the <image_id> parameter. For some kind of widgets, setting a background pixmap may have no effect or have strange results. Experiment with it. To unset the background image call $setBackgroundColor


$setFont(<size>,<family>,<style>)

Set the font's size, family and stile, valid flag for style are:

italic     
bold     
underline      
overline    
strikeout  
fixedpitch  


$setWFlags(<flag1>, <flag2>, ...)

This function sets widget flags, given as parameters. Valid flags are:

TopLevel  - indicates that this widget is a top-level widget
Dialog    - indicates that this widget is a top-level window that should be decorated as a dialog
Desktop   - indicates that this widget is the desktop
Popup      - indicates that this widget is a popup top-level window
Customize - let's the user to customize the style of the widget. Valid parameter for a customized widget are:
Title     - gives the window a title bar
StaysOnTop- window stays on top 
SysMenu      -    add a windows system menu
Minimize  - add a minimize button for the sysmenu style
Maximize  - add a maximixe button for the sysmenu style


$centerToScreen()

Centers the window on the screen (useful only for toplevel widgets). The best place to call this function is in $showEvent()


$setFocusPolicy(<key focus>)

Sets the way the widget accepts keyboard focus. Valid parameters are:

- TabFocus;    (widget accepts keyboard focus by tabbing)
- ClickFocus; (widget accepts keyboard focus by clicking)
- StrongFocus; (widget accepts both tabbing/clicking)
- No Focus;  (widget does not accept focus at all; this is the default value)


$keyPressEvent(<key>)

If widget accepts keyboard focus (see $setFocusPolicy ) this function handles for keys; In its argument the key pressed. Special keys are:

- Return 
- Enter    
- Down (cursor arrow down) 
- Up   (cursor arrow up) 
- Left (cursor arrow left) 
- Right (cursor arrow right) 
- Shift 
- Ctrl 
- Alt 
- CapsLock 
- Backspace 
- Del 
- Esc 
- 0 
- 1 
- 2 
- 3 
- 4 
- 5 
- 6 
- 7 
- 8 
- 9 
- + 
- - 
- * 
- / 
- ( 
- ) 
- = 
- . 
- ^ 


$mapFromGlobal(<x>,<y>)

Translates the global screen coordinate pos to widget coordinates.


$mapToGlobal(<x>,<y>)

Translates widget coordinates into the global screen coordinate pos.

[править] button

A simple, well-known button Inherits object widget Description A button - nothing more, nothing else... Functions $setText(<text:string>) This function sets the text for this button. <string> $text() Returns the current text of the button $setImage(<image_id:string>) Sets the image to be displayed on this label. Giving empty argument clears the pixmap See the image identifier documentation for the explaination of the <image_id> parameter. $clickEvent() This function is called by the framework when the button is clicked. You can reimplement it to handle the user click events. The default implementation emits the $clicked() signal, so it is easy to handle the clicks from many buttons without reimplementing the $clickEvent() for every one. Note: If you reimplement this function to catch the user click events, you will have to emit the signal by yourself (if you still need it , obviously). Signals $clicked() This signal is emitted by the default implementation of [classfnc]clickEvent[/classfnc](). If you reimplement that function you will have to emit the signal manually (if you still need it).

[править] Окна и оконные идентификаторы

[править] Введение

Начиная с релиза 3.0.0, оконная структура KVirc сильно усложнилась. Более старые релизы позволяли иметь 1 подключение в окне, и команды выполнялись для каждого окна отдельно. Поиск нужного окна в таком случае был достаточно прост: его можно было опрелелить по имени (канплп или привата) т.к. не было возможности обратиться к окнам, принадлежащим другому подключению к серверу. Окна имели уникальное имя в пределах одного подключения, что гарантировано IRC протоколом и ядром KVirc.

В текущей версии уникальность названий окон не гарантируется.

[править] Сценарий

Скриптинговый движок сейчас один для всего приложения. Он может оперировать с любым количством подключений к серверу.

  • Приложение (глобальный командный парсер
    • Фрейм X
      • + Консоль M (IRC context)
      • # Окна каналов
      • # Окна приватов
      • # Другие окна этого сервера
               +                  Console N (IRC context)             
                     #             Channel windows
                     #             Query windows
                     #             Other connection related windows
                                            
               +                  Other windows         
               +                  ...         
                              
         o          Frame Y         
               +                  Console O (IRC context)             
                     #             Channel windows
                     #             Query windows
                     #             Other connection related windows
                                            
               +                  Console P (IRC context)             
                     #             Channel windows
                     #             Query windows
                     #             Other connection related windows
                                            
               +                  Other windows         
               +                  ...         
                              
         o          ...     
               


A naming convention has becomed necessary to resolve ambiguities.

[править] Basic assumptions

Every KVIrc window has four main properties: -an unique numeric identifier -the logical name -the type identifier -the caption text The numeric identifier is unique to the whole application, and is the one returned by the $window function. The identifier is assigned by KVIrc when the window is created and is not changed until the window is destroyed. This identifier will be referred as window ID. The logical name is a property of some kind of windows. It usually corresponds to the first part of the window caption. For example, for channel windows it is the channel name, for queries it is the list of the targets. For some other windows the logical name corresponds to the caption text. This will be discussed later. The type identifier describes the properties of a certain window. For channel windows the type identifier is "channel" , for query windows is "query" , for console windows it is "console", etc..

[править] Irc contexts

The KVIrc frame windows are numbered starting from 0 and named "frame_<number>". Each frame can contain an unlimited number of consoles. Each console is bound to an IRC context. (The part "is bound to" could be substituted by "defines" or "is contained in"). An IRC context is a set of resources that can deal with a single IRC connection. The association between an IRC context and a console is bijective: each IRC context is associated to a single console window. An IRC context can be in connected or not-connected state. When in connected state, it contains a set of windows beside the console: mainly channels and query windows. The channels and query windows can exist ONLY if the associated IRC context exists. Channels and queries have unique names inside a connection so there is no way to confuse it. (Theoretically there can be more than one query window with the same name, but in fact all the windows refer to the same target so they are instances of the same resource). All this creates a sort of namespace: the channels and queries can be identified as "bound" to a specific IRC context. An IRC context can "contain" other windows, such as the "sockets" window or the "list" window. KVIrc takes care of making them unique inside the IRC context namespace. Each IRC context has its own unique IRC context ID (see $context). Since to a single IRC context may correspond only a single irc connection, when in connected state, the IRC context may be referred also as connection or connection context, and the associated IRC context Id can be referred as connection ID or connection context ID. There are classes of windows that are not bound to any IRC context: this includes user created windows, DCC windows, browsers etc. KVIrc will try to keep that windows with unique logical names.

[править] How to identify a window

So what we have until now is:

   * Each window has its own unique window ID: we will refer windows always using this identifier.
   * Each window has a set of properties including: window type, logical name.
   * Subsets of windows are bound to a single IRC context

The simplest (but also the less significant) method of looking for a window is to finding it by caption. The $window function finds the first KVIrc window matching the "caption text" and returns its window ID. This method will likely fail when there are more windows with the same caption text; for this reason several specific functions have been added to allow finding the correct window. The $console finds a console window bound to a specified IRC context. The $channel finds a channel window matching the specified name and bound to a specified IRC context. The $query finds a query window that has a specified target and is bound to a specified IRC context.

[править] Использование perl

[править] Introduction

Начиная с версии 3.0.2, вы можете использовать фрагменты кода perl в своих сценариях KVS, впрочем, как и команды KVS из perl. Эта возможность доступна только в том случае, если работающий perl был найден во время выполнения ./configure.

[править] Using perl from KVS

Using perl from KVIrc is really easy: just enclose your perl code snippet inside perl.begin and perl.end.

perl.begin <perl code goes here> perl.end

For example:

perl.begin open(MYFILE,'>>myfile.txt') or die "Can't open myfile.txt!"; print MYFILE "foo!\n"; close(MYFILE); perl.end

A perl code snippet can appear anywhere a KVS code snippet can with the only restriction that i must be enclosed in perl.begin and perl.end. This means that you can write perl code in the commandline, in the aliases, the event handlers, popups...anywhere. If you have already encountered the KVIrc's eval command that you probably also know how to execute a perl code snippet from a file :)

[править] Using KVS from perl

KVIrc exports several commands to the perl namespace that allow you to invoke KVIrc's functions from inside the perl code snippet. The nicest example is KVIrc::echo():

perl.begin KVIrc::echo("Hello KVIrc world from perl!"); perl.end

KVIrc::echo() is the counterpart of the echo. The exact syntax is:

   KVIrc::echo(<text>[,<colorset>[,<windowid>]])

<text> is obviously the text to be printed. <colorset> is the equivalent of the echo -i option and <windowid> is the equivalent of the -w option. Both <colorset> and <windowid> can be omitted (in this case KVIrc will use a default colorset and the current window).

[править] Perl execution contexts

The perl code snippets are executed by the means of a perl interpreter. Each perl interpreter has its own context and thus it's own variables, own function namespace etc.

In the example above KVIrc creates an interpreter when perl.begin is invoked and destroys it at perl.end parsing time. In fact, KVIrc can mantain multiple persistent interpreters that will allow you to preserve your context across perl.begin invocations. You can invoke a specific perl context by passing it as parameter to the perl.begin command.

[cmd]perl.begin("mycontext")[/cmd] $myvariable = "mycontext"; KVIrc::echo("This perl code is executed from ".$myvariable); perl.end

The nice thing is that at a later time you can invoke this context again and discover that $mycontext has preserved its value:

[cmd]perl.begin("mycontext")[/cmd] KVIrc::echo("myvariable is still equal to ".$myvariable); perl.end

The first time you invoke a named perl context it gets automatically created and it persists until KVIrc terminates or the perl context is explicitly destroyed by the means of perl.destroy.

In fact there is a third possibility to destroy a context: it's when the perlcore module is forcibly unloaded (by the means of /perlcore.unload) but this is really a rare case and should be threated just like a KVIrc restart (the user probably WANTS the contexts to be reinitialized).

The nice thing is that not only your variables will get preserved but also any perl function or class you declare in a context will persist. It's just like executing a long perl script file with pauses inside.

If you omit the perl context name in the perl.begin command (or if you use an empty string in it's place) then KVIrc will create a temporary context for the snippet execution and will destroy it immediately after perl.end has been called.

The major side effect of keeping persistent perl contexts is that the perl's symbol table will grow and if not used carefully the interpreter may become a memory hog. So if you're going to use persistent contexts either try to keep the symbol table clean or explicitly call perl.destroy once in a while to recreate the interpreter. If you just execute occasional perl code snippets and don't need to keep persistent variables then just use the nameless temporary context provided by perl.begin("").

[править] Passing parameters to the perl script

The easiest way to pass parameters to the perl code snippet is to put them as perl.begin arguments. In fact the complete syntax of perl.begin is: perl.begin(<perl context>,<arg0>,<arg1>,...) Where the <arg0>,<arg1>...<argN> parameters are passed to the perl context as elements of the $_[] array.

perl.begin("","Hello world!","Now I CAN",1,2,3) for($i=0;$i<5;$i++)

   KVIrc::echo($_,40);

perl.end


[править] Accessing the KVIrc scripting context from perl

KVIrc exposes the following functions that manipulate the variables of the KVIrc's current KVS execution context.

   KVIrc::getLocal(<x>)

Returns the value of the KVIrc's local variable %x.

   KVIrc::getGlobal(<Y>)

Returns the value of the KVIrc's global variable %Y.

   KVIrc::setLocal(<x>,<value>)

Sets the KVIrc's global variable %x to <value>

   KVIrc::setGlobal(<Y>,<value>)

Sets the KVIrc's global variable %Y to <value> The local variables interested belong to the current KVS exection context while the global variables are visible everywhere.

%pippo = test %Pluto = 12345 perl.begin $mypippo = KVIrc::getLocal("pippo"); $mypippo =~ s/^pi/ze/g; $mypluto = KVIrc::getGlobal("Pluto"); $mypluto =~ s/23/xx/g; KVIrc::setLocal("pippo",$mypluto); KVIrc::setGlobal("Pluto",$mypippo); perl.end echo "\%pippo is" %pippo echo "\%Pluto is" %Pluto


[править] Executing arbitrary KVIrc commands from perl

You can execute arbitrary KVS commands from perl by the means of:

   KVIrc::eval()

This function behaves exactly like the ${ <code> } KVS construct: it executes <code> in a child context and returns it's evaluation retult. The following two code snippets have equivalent visible effects:

echo ${ return "Yeah!"; }

perl.begin KVIrc::echo(KVIrc::eval("return \"Yeah!\"")); perl.end

You can "eval" composite command sequences and variable ones. Remember that the perl code snippet is evaluated in a child KVS context and thus the local variables are NOT visible!. The following code snippets may easily fool you:

%x = 10 perl.begin KVIrc::eval("echo \"The value is %x\""); perl.end

This will print "The value is " since %x is not accessible from the eval's context. If you have tried to write something like this then you probably need to rewrite it as:

%x = 10 perl.begin $x = KVIrc::getLocal("x"); KVIrc::eval("echo \"The value is ".$x."\""); perl.end


Note also that you must either escape the $ at the beginning of the KVIrc identifiers or use the single quotes to prevent perl from catching the $ as the beginning of a variable.

  1. This will not work as expected

perl.begin KVIrc::echo(KVIrc::eval("return $window.caption")); perl.end

  1. But these will do

perl.begin KVIrc::echo(KVIrc::eval("return \$window.caption")); KVIrc::echo(KVIrc::eval('return $window.caption')); perl.end

A shortcut for KVIrc::eval("/say...")

Since KVIrc::eval("/say...") is a common calling pattern then say has been added to the KVIrc perl namespace. You can now call

KVIrc::say("Hi all!");

and that will mimic the behaviour of

/say Hi all!

The complete syntax for KVIrc::say() is:

   KVIrc::say(<text>[,<windowid>])

and the semantics are obvious (see also /say). The perl script return values

The perl.begin command propagates the perl code return value to the KVIrc context (just like a setreturn() would do). In fact the perl snippet return value is the last "thing" that the interpreter evaluates. In this way you can write perl aliases that return values without doing any variable passing equilibrism.

[править] Executing perl scripts from files

alias(perlexec) {

   %tmp = "perl.begin(\"\",$1,$2,$3,$4,$5)";
   %tmp .= $file.read($0);
   %tmp .= "perl.end";
   eval %tmp;

} perlexec "/home/pragma/myperlscript.pl" "param1" "param2" "param3"

  1. or even

echo $perlexec("/home/pragma/computeprimelargerthan.pl","10000")


[править] Other tricks

An interesting feature of the persistent perl contexts is that you can prepare a context for a later fast execution. The idea is to declare perl functions in a single perl code snippet and to call the single functions when a fast execution is needed. For example you might parse the following snippet at KVIrc's startup:

perl.begin("persistent") sub handler_for_event_1 {

   do_complex_perl_stuff_here

} sub handler_for_event_2 {

   do_complex_perl_stuff_here

} perl.end

and later simply call:

perl.begin("persistent",param1,param2) handler_for_event_1($_[0],$_[1]) perl.end


[править] Curiosity

The perl support in KVIrc is implemented as a master-slave module pair. The perl.* module is the master while perlcore is the slave. When the perl support isn't compiled in, the perl.* commands print some warnings and exit gracefully while the perlcore module refuses to be loaded. When perl support is compiled in but for some reason the libperl.so can't be found or loaded then perlcore fails the dynamic loading stage but perl.* still fails gracefully with just some warning messages. This trick allows the scripters to check for perl support with $perl.isavailable and to embed perl code snippets in KVS even if the support is missing. The snippets will be just skipped.

Happy perl hacking :)

Личные инструменты
Инструменты
Наши кнопки
Размести кнопку KVirc у себя на сайте:
www.kvirc.ru - кроссплатформенный IRC клиент с богатым графическим интерфейсом и внутренним языком скриптинга
Друзья и спонсоры
  • Fireforge.net
Linux coutner