|
|
#include "ubl-utils.h"
|
|
|
|
|
|
// dictionary functions
|
|
|
|
|
|
/**yon_dictionary_create_empty():
|
|
|
* [EN]
|
|
|
* Creates and returns empty dictionary
|
|
|
* [RU]
|
|
|
* Создаёт и возвращает пустой словарь.
|
|
|
*/
|
|
|
dictionary *yon_dictionary_new()
|
|
|
{
|
|
|
dictionary *dict = malloc(sizeof(dictionary));
|
|
|
dict->data = NULL;
|
|
|
dict->key = NULL;
|
|
|
dict->next = NULL;
|
|
|
dict->prev = NULL;
|
|
|
dict->first = dict;
|
|
|
dict->data_type = DICTIONARY_OTHER_TYPE;
|
|
|
return dict;
|
|
|
}
|
|
|
|
|
|
/**yon_dictionary_copy(dictionary *dict)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Создаёт и возвращает копию элемента словаря [dict]
|
|
|
*/
|
|
|
dictionary *yon_dictinoary_copy(dictionary *dict){
|
|
|
dictionary *dct = yon_dictionary_new_with_data(dict->key,dict->data);
|
|
|
dct->data_type= dict->data_type;
|
|
|
}
|
|
|
|
|
|
/**yon_dictionary_copy_deep(dictionary *dict)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Создаёт полную копию словаря [dict] и возвращает первый элемент
|
|
|
*/
|
|
|
dictionary *yon_dictionary_copy_deep(dictionary *dict){
|
|
|
dictionary *dct = NULL;
|
|
|
dictionary *newone=NULL;
|
|
|
for_dictionaries(dct,dict){
|
|
|
yon_dictionary_add_or_create_if_exists_with_data(newone,dct->key,dct->data);
|
|
|
newone->data_type=dct->data_type;
|
|
|
}
|
|
|
return newone->first;
|
|
|
}
|
|
|
|
|
|
/**int yon_dictionary_set_data(dictionary *dict, void *data)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Установить элементу словаря [dict] значение [data]
|
|
|
*/
|
|
|
int yon_dictionary_set_data(dictionary *dict, void *data){
|
|
|
dict->data=data;
|
|
|
}
|
|
|
|
|
|
/**int yon_dictionary_set_key(dictionary *dict, char *key)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Изменяет ключ элемента словаря [dict] на [key]
|
|
|
*/
|
|
|
int yon_dictionary_set_key(dictionary *dict, char *key){
|
|
|
dict->key=key;
|
|
|
}
|
|
|
|
|
|
/** int yon_dictionary_set(dictionary *dict, char *key, void *data)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Устанавливает значение ключа элемента словаря [dict] на [key] и его данные на [data]
|
|
|
*/
|
|
|
int yon_dictionary_set(dictionary *dict, char *key, void *data){
|
|
|
dict->key=key;
|
|
|
dict->data=data;
|
|
|
}
|
|
|
|
|
|
/**int yon_dictionary_empty(dictionary *dict)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Очищает элемент словаря [dict] от данных
|
|
|
*/
|
|
|
int yon_dictionary_empty(dictionary *dict){
|
|
|
dict->data=NULL;
|
|
|
dict->data_type=DICTIONARY_OTHER_TYPE;
|
|
|
}
|
|
|
|
|
|
/**yon_dictionary_switch_to_last(dictionary **dict)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Переключает словарь [dict] на последний элемент.
|
|
|
*/
|
|
|
void yon_dictionary_switch_to_last(dictionary **dict)
|
|
|
{
|
|
|
dictionary *dct=NULL, *dact=*dict;
|
|
|
for_dictionaries(dct,dact);
|
|
|
}
|
|
|
|
|
|
/**yon_dictionary_create_conneced(dictionary *targetdict)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Создаёт новый элемент словаря [targetdict]
|
|
|
*/
|
|
|
dictionary *yon_dictionary_append(dictionary *targetdict)
|
|
|
{
|
|
|
targetdict = yon_dictionary_get_last(targetdict);
|
|
|
targetdict->next = yon_dictionary_new();
|
|
|
targetdict->next->prev = targetdict;
|
|
|
targetdict->next->first = targetdict->first;
|
|
|
targetdict->next->data_type = DICTIONARY_OTHER_TYPE;
|
|
|
return targetdict->next;
|
|
|
}
|
|
|
|
|
|
/**yon_dictionary_get_last(dictionary *dict)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Возвращает последний элемент словаря [dict].
|
|
|
* В отличае от yon_dictionary_switch_to_last()
|
|
|
* словарь [dict] остаётся на прежнем элементе.
|
|
|
*/
|
|
|
dictionary *yon_dictionary_get_last(dictionary *dict)
|
|
|
{
|
|
|
if (dict->next){
|
|
|
dictionary *dct = NULL;
|
|
|
for_dictionaries(dct,dict);
|
|
|
return dct;
|
|
|
} else return dict;
|
|
|
}
|
|
|
|
|
|
/**yon_dictionary_switch_places(dictionary *dict, int aim)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Меняет элемент словаря [dict] местами с другим элементом.
|
|
|
* если [aim]<0 элемент меняется местами с левым элементом;
|
|
|
* если [aim]>0 элемент меняется местами с правым элементом;
|
|
|
*/
|
|
|
dictionary *yon_dictionary_swap(dictionary *dict, int aim)
|
|
|
{
|
|
|
if (aim < 0)
|
|
|
{
|
|
|
if (dict->prev)
|
|
|
{
|
|
|
if (dict->prev->prev)
|
|
|
{
|
|
|
dictionary *next = dict->next, *prev = dict->prev, *preprev = prev->prev;
|
|
|
if (next)
|
|
|
{
|
|
|
preprev->next = dict;
|
|
|
dict->prev = preprev;
|
|
|
dict->next = prev;
|
|
|
prev->prev = dict;
|
|
|
prev->next = next;
|
|
|
next->prev = prev;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
preprev->next = dict;
|
|
|
dict->prev = preprev;
|
|
|
dict->next = prev;
|
|
|
prev->prev = dict;
|
|
|
prev->next = NULL;
|
|
|
}
|
|
|
return prev;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
dictionary *next = dict->next, *prev = dict->prev;
|
|
|
if (next)
|
|
|
{
|
|
|
yon_dictionary_make_first(dict);
|
|
|
dict->prev = NULL;
|
|
|
dict->next = prev;
|
|
|
prev->prev = dict;
|
|
|
prev->next = next;
|
|
|
next->prev = prev;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
dict->prev = NULL;
|
|
|
dict->next = prev;
|
|
|
prev->prev = dict;
|
|
|
prev->next = NULL;
|
|
|
}
|
|
|
return prev;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else if (aim > 0)
|
|
|
{
|
|
|
if (dict->next)
|
|
|
{
|
|
|
if (dict->next->next)
|
|
|
{
|
|
|
dictionary *next = dict->next, *prev = dict->prev, *afnext = next->next;
|
|
|
if (prev)
|
|
|
{
|
|
|
prev->next = next;
|
|
|
next->prev = prev;
|
|
|
next->next = dict;
|
|
|
dict->prev = next;
|
|
|
dict->next = afnext;
|
|
|
afnext->prev = dict;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
yon_dictionary_make_first(next);
|
|
|
next->prev = NULL;
|
|
|
next->next = dict;
|
|
|
dict->prev = next;
|
|
|
dict->next = afnext;
|
|
|
afnext->prev = dict;
|
|
|
}
|
|
|
return next;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
dictionary *next = dict->next, *prev = dict->prev;
|
|
|
if (prev)
|
|
|
{
|
|
|
prev->next = next;
|
|
|
next->prev = prev;
|
|
|
next->next = dict;
|
|
|
dict->prev = next;
|
|
|
dict->next = NULL;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
next->prev = NULL;
|
|
|
next->next = dict;
|
|
|
dict->prev = next;
|
|
|
dict->next = NULL;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**yon_dictionary_make_first(dictionary *dict)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Устанавливает указатель первого элемента словаря [dict]
|
|
|
* на текущий элемент. Не использовать.
|
|
|
*/
|
|
|
void yon_dictionary_make_first(dictionary *dict)
|
|
|
{
|
|
|
for (dictionary *dct = dict->first; dct != NULL; dct = dct->next)
|
|
|
{
|
|
|
dct->first = dict;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**yon_dictionary_make_nth(dictionary *dict, int nth)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Перемещает элемент словаря [dict] на позицию [nth].
|
|
|
*/
|
|
|
void yon_dictionary_make_nth(dictionary *dict, int nth)
|
|
|
{
|
|
|
dictionary *dct = dict->first;
|
|
|
for (int i = 0; i < nth; i++)
|
|
|
{
|
|
|
if (dct == NULL)
|
|
|
return;
|
|
|
else
|
|
|
dct = dct->next;
|
|
|
}
|
|
|
yon_dictionary_rip(dict);
|
|
|
dictionary *prev = dct->prev;
|
|
|
prev->next = dict;
|
|
|
dict->prev = prev;
|
|
|
dict->next = dct;
|
|
|
dct->prev = dict;
|
|
|
}
|
|
|
|
|
|
/**yon_dictionary_create_with_data(char *key, void *data)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Создаёт новый словарь с ключом [key] и указателем на данные [data]
|
|
|
*/
|
|
|
dictionary *yon_dictionary_new_with_data(char *key, void *data)
|
|
|
{
|
|
|
dictionary *dct = yon_dictionary_new();
|
|
|
dct->key = yon_char_new(key);
|
|
|
dct->data = data;
|
|
|
dct->data_type = DICTIONARY_OTHER_TYPE;
|
|
|
return dct;
|
|
|
}
|
|
|
|
|
|
/** void *yon_dictionary_free_all(dictionary *dictionary,void *data_manipulation)
|
|
|
* [EN]
|
|
|
* Frees whole [dictionary] and activates [data_manipulation] function if not NULL with [dictionary]->data argument for each dictionary.
|
|
|
* [RU]
|
|
|
* Освобождает память для всех элементов словаря [dictionary] и активирует функцию [data_manipulation], если она была передана, с аргументом [dictionary]->data на каждый элемент словаря.
|
|
|
*/
|
|
|
void *yon_dictionary_free_all(dictionary *dictionary_to_free,void (*data_manipulation)(void*)){
|
|
|
dictionary *dict=NULL;
|
|
|
for_dictionaries(dict,dictionary_to_free){
|
|
|
if(data_manipulation)
|
|
|
data_manipulation(dict->data);
|
|
|
if(dict->prev)
|
|
|
free(dict->prev);
|
|
|
}
|
|
|
free(dict);
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
/**yon_dictionary_create_with_data_connected(dictionary *dict, char *key, void *data)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Создаёт новый элемент словаря, присоединяемый в конец словаря [dict]
|
|
|
* с ключом [key] и указателем на данные [data]
|
|
|
*/
|
|
|
dictionary *yon_dictionary_append_with_data(dictionary *dict, char *key, void *data)
|
|
|
{
|
|
|
dictionary *dct = yon_dictionary_append(dict);
|
|
|
dct->key = yon_char_new(key);
|
|
|
dct->data = data;
|
|
|
dct->data_type = DICTIONARY_OTHER_TYPE;
|
|
|
return dct;
|
|
|
}
|
|
|
|
|
|
/**yon_dictionary_connect(dictionary *old, dictionary *toconnect)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Присоединяет словарь [toconnect] в конец словаря [old].
|
|
|
*/
|
|
|
dictionary *yon_dictionary_connect(dictionary *old, dictionary *toconnect)
|
|
|
{
|
|
|
dictionary *dict = yon_dictionary_get_last(old);
|
|
|
dict->next = toconnect;
|
|
|
toconnect->prev = dict;
|
|
|
toconnect->first = dict->first;
|
|
|
return toconnect;
|
|
|
}
|
|
|
|
|
|
/**yon_dictionary_get(dictionary **dict, char *key)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Возвращает элемент словаря [dict] с ключом [key].
|
|
|
* Если такого элемента не было обнаружено, возвращается NULL
|
|
|
*/
|
|
|
dictionary *yon_dictionary_get(dictionary **dict, char *key)
|
|
|
{
|
|
|
dictionary *dct = *dict;
|
|
|
for (dictionary *pointer = dct->first; pointer != NULL; pointer = pointer->next)
|
|
|
{
|
|
|
if (strcmp(pointer->key, key) == 0)
|
|
|
{
|
|
|
*dict = pointer;
|
|
|
return pointer;
|
|
|
}
|
|
|
}
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
/**yon_dictionary_rip(dictionary *dict)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Вырезает элемент из словаря и возвращает вырезанный элемент.
|
|
|
*/
|
|
|
dictionary *yon_dictionary_rip(dictionary *dict)
|
|
|
{
|
|
|
if (!dict->next&&!dict->prev) return NULL;
|
|
|
else if (!dict->next)
|
|
|
{
|
|
|
dictionary *prev = dict->prev;
|
|
|
if (prev)
|
|
|
{
|
|
|
prev->next = NULL;
|
|
|
return prev;
|
|
|
}
|
|
|
else
|
|
|
return dict;
|
|
|
}
|
|
|
else if (!dict->prev)
|
|
|
{
|
|
|
dictionary *next = dict->next;
|
|
|
if (next)
|
|
|
{
|
|
|
yon_dictionary_make_first(next);
|
|
|
next->prev = NULL;
|
|
|
return next;
|
|
|
}
|
|
|
else
|
|
|
return dict;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
dictionary *next = dict->next, *prev = dict->prev;
|
|
|
next->prev = prev;
|
|
|
prev->next = next;
|
|
|
return next;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**yon_dictionary_get_nth(dictionary *dict, int place)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Возвращает [place]-й элемент словаря [dict]
|
|
|
*/
|
|
|
dictionary *yon_dictionary_get_nth(dictionary *dict, int place)
|
|
|
{
|
|
|
if (dict){
|
|
|
dict = dict->first;
|
|
|
int i = 0;
|
|
|
for (i = 0; i < place; i++)
|
|
|
if (dict->next)
|
|
|
dict = dict->next;
|
|
|
else
|
|
|
break;
|
|
|
if (i == place)
|
|
|
return dict;
|
|
|
else
|
|
|
return NULL;
|
|
|
} else return NULL;
|
|
|
}
|
|
|
|
|
|
// char functions
|
|
|
|
|
|
/**[EN]
|
|
|
*
|
|
|
* creates new char string by combining two char strings.
|
|
|
*/
|
|
|
char *yon_char_append(char *source, char *append)
|
|
|
{
|
|
|
if (source && append)
|
|
|
{
|
|
|
int size = strlen(source) + strlen(append) + 1;
|
|
|
char *final = malloc(size);
|
|
|
memset(final, 0, size);
|
|
|
if (strstr(source, "%%"))
|
|
|
sprintf(final, source, append);
|
|
|
else
|
|
|
sprintf(final, "%s%s", source, append);
|
|
|
return final;
|
|
|
}
|
|
|
else
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
/**[EN]
|
|
|
*
|
|
|
* creates new char string by copying another char.
|
|
|
*/
|
|
|
char *yon_char_new(char *chr)
|
|
|
{
|
|
|
if (chr){
|
|
|
char *newchar = malloc(strlen(chr) + 1);
|
|
|
memset(newchar, 0, strlen(chr) + 1);
|
|
|
memcpy(newchar, chr, strlen(chr));
|
|
|
return newchar;
|
|
|
} else
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
/**yon_char_unite(char *source, ...)
|
|
|
* [En]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Объединяет строку [source] со всеми строками, написанными в [...]
|
|
|
*/
|
|
|
char *yon_char_unite(char *source, ...){
|
|
|
va_list arglist;
|
|
|
char *new_char=NULL;
|
|
|
char *unite_char=NULL;
|
|
|
new_char=yon_char_new(source);
|
|
|
va_start(arglist,source);
|
|
|
unite_char = va_arg(arglist,char*);
|
|
|
while(unite_char){
|
|
|
new_char = yon_char_append(new_char,unite_char);
|
|
|
unite_char = va_arg(arglist,char*);
|
|
|
}
|
|
|
va_end(arglist);
|
|
|
return new_char;
|
|
|
}
|
|
|
|
|
|
/**yon_cut(char *source, int size, int startpos)
|
|
|
* [EN]
|
|
|
* cuts source string by size length from startpos position.
|
|
|
*/
|
|
|
char *yon_cut(char *source, int size, int startpos)
|
|
|
{
|
|
|
char *cut = NULL;
|
|
|
cut = malloc(size + 1);
|
|
|
memset(cut, 0, size + 1);
|
|
|
memcpy(cut, source + startpos, size);
|
|
|
return cut;
|
|
|
}
|
|
|
|
|
|
/**yon_char_divide(char *source, int dividepos)
|
|
|
* [EN]
|
|
|
* divides source string in dividepos position,
|
|
|
* returning left part of divided string and
|
|
|
* inserting right part to source string.
|
|
|
*/
|
|
|
char *yon_char_divide(char *source, int dividepos)
|
|
|
{
|
|
|
char *cut = malloc(dividepos + 1);
|
|
|
memset(cut, 0, dividepos + 1);
|
|
|
memcpy(cut, source, dividepos);
|
|
|
char *left = malloc(strlen(source) - strlen(cut));
|
|
|
memset(left, 0, strlen(source) - strlen(cut));
|
|
|
memcpy(left, source + dividepos + 1, (strlen(source) - dividepos));
|
|
|
memset(source, 0, strlen(source));
|
|
|
memcpy(source, left, strlen(left));
|
|
|
return cut;
|
|
|
}
|
|
|
|
|
|
/**yon_char_find_count(char *source, char *find)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Считает количество символов [find] в строке [source]
|
|
|
*/
|
|
|
int yon_char_find_count(char *source, char *find){
|
|
|
char *working_string=yon_char_new(source);
|
|
|
int i=0;
|
|
|
int size=0;
|
|
|
int pos=0;
|
|
|
config_str rtn = yon_char_parse(working_string,&size,"\n");
|
|
|
for (int j=0;j<size;j++){
|
|
|
if(strstr(rtn[j],find))
|
|
|
i++;
|
|
|
}
|
|
|
printf("%d\n",i);
|
|
|
return i;
|
|
|
}
|
|
|
|
|
|
/**yon_char_divide_search(char *source, char *dividepos, int delete_divider)
|
|
|
* [EN]
|
|
|
* char *yon_char_divide_search(char *source, char *dividepos, int delete_divider)
|
|
|
* searches string [dividepos] in [source] string and divides it,
|
|
|
* returning left part of divided string and
|
|
|
* inserting right part to [source] string.
|
|
|
* if [delete_divider] is 0, left part will contain [delete_divider] substring, else
|
|
|
* if [delete_divider] is 1 it will stay in right part, else
|
|
|
* if [delete_divider] is -1 it will be deleted from string.
|
|
|
*
|
|
|
* [RU]
|
|
|
* char *yon_char_divide_search(char *source, char *dividepos, int delete_divider)
|
|
|
* Ищет строку [dividepos] в строке [source] и делит её в этом месте,
|
|
|
* возвращая левую часть разделённой строки и устанавливает в [source] правую часть.
|
|
|
* Если [delete_divider] равен 0, [dividepos] останется в левой строке, иначе
|
|
|
* если [delete_divider] равен 1, [dividepos] останется в правой строке, иначе
|
|
|
* если [delete_divider] равен -1, [dividepos] удаляется из строки.
|
|
|
*/
|
|
|
char *yon_char_divide_search(char *source, char *dividepos, int delete_divider)
|
|
|
{
|
|
|
if (source&÷pos){
|
|
|
char *cut = strstr(source, dividepos);
|
|
|
if (cut)
|
|
|
{
|
|
|
int leng = strlen(source) - strlen(cut);
|
|
|
cut = yon_char_divide(source, leng);
|
|
|
return cut;
|
|
|
}
|
|
|
else
|
|
|
return source;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**yon_char_from_int(int int_to_convert)
|
|
|
* [EN]
|
|
|
* char *yon_char_from_int(int int_to_convert)
|
|
|
* converts int to char*.
|
|
|
*
|
|
|
* [RU]
|
|
|
* char *yon_char_from_int(int int_to_convert)
|
|
|
* Конвертирует int в char*
|
|
|
*/
|
|
|
char *yon_char_from_int(int int_to_convert)
|
|
|
{
|
|
|
int i = 1;
|
|
|
float convert_check = (float)int_to_convert;
|
|
|
for (i = 1; convert_check >= 10; i++)
|
|
|
{
|
|
|
convert_check = convert_check / 10;
|
|
|
}
|
|
|
char *ch = g_malloc0(i * sizeof(char) + 1);
|
|
|
sprintf(ch, "%d", int_to_convert);
|
|
|
return ch;
|
|
|
}
|
|
|
|
|
|
/**yon_char_replace(char *source, char *find, char*replace)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Заменяет в строке [source] все вхождения строки [find] на [replace]
|
|
|
*/
|
|
|
char *yon_char_replace(char *source, char *find, char*replace){
|
|
|
char *final=NULL;
|
|
|
char *temp=NULL;
|
|
|
if(!strstr(replace,find)){
|
|
|
while ((final=strstr(source,find))){
|
|
|
temp=malloc(strlen(source)-strlen(final));
|
|
|
memset(temp,0,strlen(source)-strlen(final)+strlen(replace));
|
|
|
memcpy(temp,source,strlen(source)-strlen(final));
|
|
|
temp=yon_char_append(temp,replace);
|
|
|
source=yon_char_append(temp,final+1);
|
|
|
}
|
|
|
return source;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**yon_char_parse(char *parameters, int *size, char *divider)
|
|
|
* [EN]
|
|
|
* Parses string [parameters], divided by [divider],
|
|
|
* then returns parsed string array and sets [size] to
|
|
|
* size of returned array
|
|
|
*/
|
|
|
char **yon_char_parse(char *parameters, int *size, char *divider){
|
|
|
char **string=NULL;
|
|
|
int i=1;
|
|
|
string=malloc(sizeof(char*));
|
|
|
char *paramline=yon_char_new(parameters);
|
|
|
char *param;
|
|
|
while ((param=yon_char_divide_search(paramline,divider,1))){
|
|
|
string=realloc(string,sizeof(char*)*i);
|
|
|
string[i-1]=yon_char_new(param);
|
|
|
i++;
|
|
|
if (strcmp(param,paramline)==0) break;
|
|
|
}
|
|
|
string=realloc(string,sizeof(char*)*i);
|
|
|
string[i-1]=yon_char_new(paramline);
|
|
|
i++;
|
|
|
// printf("%d\n",i);
|
|
|
*size=i-1;
|
|
|
return string;
|
|
|
|
|
|
}
|
|
|
|
|
|
/**yon_char_parsed_rip(char **char_string, int *size, int item_to_delete)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Удаляет элемент [item_to_delete] из массива строк [char_string], размера [size]
|
|
|
* Возвращает получившийся массив, в [size] загружается размер нового массива.
|
|
|
*/
|
|
|
char **yon_char_parsed_rip(char **char_string, int *size, int item_to_delete){
|
|
|
char **new_char_parsed=NULL;
|
|
|
new_char_parsed=malloc(sizeof(char*)*((*size)-1));
|
|
|
int flag = 0;
|
|
|
for (int i=0;i < (*size);i++){
|
|
|
if (i==item_to_delete) {
|
|
|
flag = 1;
|
|
|
}
|
|
|
if (flag == 0) {
|
|
|
new_char_parsed[i]=yon_char_new(char_string[i]);
|
|
|
}
|
|
|
else if (flag == 1 && i!=item_to_delete) {
|
|
|
new_char_parsed[i-1]=yon_char_new(char_string[i]);
|
|
|
}
|
|
|
}
|
|
|
(*size)=(*size)-1;
|
|
|
return new_char_parsed;
|
|
|
}
|
|
|
|
|
|
/**yon_char_parsed_check_exist(char **parameters, int size, char *param)
|
|
|
* [EN]
|
|
|
* Checks if [parameters] string array of length [size]
|
|
|
* has [param] element;
|
|
|
* [RU]
|
|
|
* Проверяет есть ли в массиве строк [parameters], размера [size]
|
|
|
* элемент [param]
|
|
|
*/
|
|
|
int yon_char_parsed_check_exist(char **parameters, int size, char *param){
|
|
|
|
|
|
for (int i=0;i<size;i++){
|
|
|
if (parameters[i]){
|
|
|
if (strstr(parameters[i],param))
|
|
|
return i;
|
|
|
} else return -1;
|
|
|
}
|
|
|
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
/**yon_char_parsed_includes_char_parsed (config_str source, config_str to_check, int source_size, int check_size)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Проверяет, включает ли в себя [source] размера [source_size]
|
|
|
* массив строк [to_check] размера [check_size]
|
|
|
*/
|
|
|
int yon_char_parsed_includes_char_parsed (config_str source, config_str to_check, int source_size, int check_size){
|
|
|
int overall_found=0;
|
|
|
for (int i=0;i<source_size;i++){
|
|
|
int found=0;
|
|
|
for (int j=0;j<check_size;j++){
|
|
|
if (strcmp(source[i],to_check[j])==0&&found==0) { found=1; overall_found++; }
|
|
|
}
|
|
|
}
|
|
|
if (overall_found==check_size)
|
|
|
return 1;
|
|
|
else return 0;
|
|
|
}
|
|
|
|
|
|
/**yon_char_parsed_new (config_str old, int *old_size, ...)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Создаёт новый массив строк. В [size] выгружается его размер
|
|
|
* [...] - неограниченное количество строк.
|
|
|
*/
|
|
|
config_str yon_char_parsed_new (int *size, ...){
|
|
|
va_list arglist;
|
|
|
config_str new_parsed=NULL;
|
|
|
new_parsed=new(char*);
|
|
|
int new_size=0;
|
|
|
va_start(arglist,size);
|
|
|
char *newparse = va_arg(arglist,char*);
|
|
|
while (newparse){
|
|
|
new_size++;
|
|
|
new_parsed=realloc(new_parsed,new_size*sizeof(char*));
|
|
|
new_parsed[new_size-1]=yon_char_new(newparse);
|
|
|
newparse=va_arg(arglist,char*);
|
|
|
}
|
|
|
va_end(arglist);
|
|
|
*size=new_size;
|
|
|
return new_parsed;
|
|
|
}
|
|
|
|
|
|
/**yon_char_parsed_copy(config_str *source, config_str *to_copy)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Копирует массив строк [to_copy] в [source]
|
|
|
*/
|
|
|
void yon_char_parsed_copy(config_str *source, config_str *to_copy){
|
|
|
if (source&&!*source&&to_copy&&*to_copy){
|
|
|
int size=0;
|
|
|
config_str new_char = yon_char_parsed_new(&size,(*to_copy)[0]);
|
|
|
for (int i=0;(*to_copy)[i];i++){
|
|
|
new_char = yon_char_parsed_append(new_char,&size,yon_char_new((*to_copy)[i]));
|
|
|
}
|
|
|
if (new_char) *source = new_char;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**config_str yon_char_parsed_append(config_str parsed, int *size, char *string)
|
|
|
* [EN]
|
|
|
* Adds [string] at the end of [parsed] string array of [size] length.
|
|
|
* [RU]
|
|
|
* Добавляет строку [string] в конец массива строк [parsed] с длинной [size].
|
|
|
*/
|
|
|
config_str yon_char_parsed_append(config_str parsed, int *size, char *string){
|
|
|
config_str new_parsed=realloc(parsed,(*size+1)*sizeof(char*));
|
|
|
new_parsed[(*size)]=yon_char_new(string);
|
|
|
(*size)++;
|
|
|
return new_parsed;
|
|
|
}
|
|
|
|
|
|
/**yon_ubl_check_root()
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Возвращает 1 если приложение было запущено от root
|
|
|
*/
|
|
|
int yon_ubl_check_root(){
|
|
|
if (getuid()==0) return 1;
|
|
|
else return 0;
|
|
|
}
|
|
|
|
|
|
/**yon_ubl_root_user_get()
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Возвращает имя пользователя.
|
|
|
* Если пользователь запустил приложение через root, выводится имя пользователя, запустившего приложение через root
|
|
|
*/
|
|
|
char *yon_ubl_root_user_get(){
|
|
|
char *user=NULL;
|
|
|
if (yon_ubl_check_root()){
|
|
|
user=getenv("SUDO_USER");
|
|
|
if (user&&strcmp(user,"")!=0){
|
|
|
return user;
|
|
|
}else {
|
|
|
FILE *file = popen("getent passwd $PKEXEC_UID | cut -d: -f1","r");
|
|
|
user=g_malloc0(4096);
|
|
|
fgets(user,4096,file);
|
|
|
user=yon_char_divide_search(user,"\n",-1);
|
|
|
if (user) return user;
|
|
|
}
|
|
|
}
|
|
|
return getlogin();
|
|
|
}
|
|
|
|
|
|
// parsing functions
|
|
|
|
|
|
|
|
|
apps *yon_apps_scan_and_parse_desktops(int *sizef)
|
|
|
{
|
|
|
int size = 0;
|
|
|
struct apps *applist;
|
|
|
{
|
|
|
DIR *directory = opendir(DesktopPath);
|
|
|
struct dirent *de;
|
|
|
while ((de = readdir(directory)))
|
|
|
{
|
|
|
FILE *file;
|
|
|
char *path = yon_char_append(DesktopPath, de->d_name);
|
|
|
file = fopen(path, "r");
|
|
|
if (strlen(de->d_name) > 9)
|
|
|
{
|
|
|
char *extension = strstr(path, ".");
|
|
|
if (extension != NULL)
|
|
|
{
|
|
|
if (strcmp(extension, ".desktop") == 0)
|
|
|
{
|
|
|
apps tempapp;
|
|
|
GKeyFile *gfile = g_key_file_new();
|
|
|
GError *err = NULL;
|
|
|
g_key_file_load_from_file(gfile, path, G_KEY_FILE_KEEP_TRANSLATIONS, NULL);
|
|
|
char *Type = g_key_file_get_string(gfile, "Desktop Entry", "Type", &err);
|
|
|
if (err)
|
|
|
{
|
|
|
printf("%s\n", err->message);
|
|
|
}
|
|
|
if (strcmp(Type, "Application") == 0)
|
|
|
tempapp.Type = 1;
|
|
|
else if (strcmp(Type, "pyApplication") == 0)
|
|
|
tempapp.Type = 2;
|
|
|
else
|
|
|
continue;
|
|
|
tempapp.Name = g_key_file_get_locale_string(gfile, "Desktop Entry", "Name", setlocale(LC_ALL, NULL), NULL);
|
|
|
if (tempapp.Name == NULL)
|
|
|
continue;
|
|
|
tempapp.Categories = g_key_file_get_string(gfile, "Desktop Entry", "Categories", NULL);
|
|
|
if (tempapp.Categories == NULL)
|
|
|
continue;
|
|
|
tempapp.Exec = g_key_file_get_string(gfile, "Desktop Entry", "Exec", NULL);
|
|
|
if (tempapp.Exec == NULL)
|
|
|
continue;
|
|
|
tempapp.Icon = g_key_file_get_string(gfile, "Desktop Entry", "Icon", NULL);
|
|
|
if (tempapp.Icon == NULL)
|
|
|
continue;
|
|
|
tempapp.Pluggable = g_key_file_get_boolean(gfile, "Desktop Entry", "Pluggable", NULL);
|
|
|
if (!tempapp.Pluggable)
|
|
|
tempapp.Pluggable = g_key_file_get_boolean(gfile, "Desktop Entry", "X-XfcePluggable", NULL);
|
|
|
if (tempapp.Pluggable)
|
|
|
tempapp.DualPluggable = g_key_file_get_boolean(gfile, "Desktop Entry", "X-UBLPluggable", NULL);
|
|
|
if (g_key_file_get_boolean(gfile, "Desktop Entry", "X-UBL-SettingsManager-Hidden", NULL) == 0)
|
|
|
if (size == 0)
|
|
|
{
|
|
|
applist = (apps *)malloc(size + 1 * sizeof(apps));
|
|
|
applist[0].Name = yon_char_new(tempapp.Name);
|
|
|
applist[0].Categories = yon_char_new(tempapp.Categories);
|
|
|
applist[0].Exec = yon_char_new(tempapp.Exec);
|
|
|
applist[0].Icon = yon_char_new(tempapp.Icon);
|
|
|
applist[0].Type = tempapp.Type;
|
|
|
applist[0].Pluggable = tempapp.Pluggable;
|
|
|
applist[0].DualPluggable = tempapp.DualPluggable;
|
|
|
size++;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
applist = (apps *)realloc(applist, (size + 1) * sizeof(apps));
|
|
|
applist[size].Name = yon_char_new(tempapp.Name);
|
|
|
applist[size].Categories = yon_char_new(tempapp.Categories);
|
|
|
applist[size].Exec = yon_char_new(tempapp.Exec);
|
|
|
applist[size].Icon = yon_char_new(tempapp.Icon);
|
|
|
applist[size].Pluggable = tempapp.Pluggable;
|
|
|
applist[size].DualPluggable = tempapp.DualPluggable;
|
|
|
applist[size].Type = tempapp.Type;
|
|
|
size++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
*sizef = size;
|
|
|
return applist;
|
|
|
};
|
|
|
|
|
|
void yon_apps_sort(apps *applist, int size)
|
|
|
{
|
|
|
apps tmp;
|
|
|
if (size > 2)
|
|
|
{
|
|
|
for (int i = 1; i < size; i++)
|
|
|
{
|
|
|
for (int j = 1; j < size; j++)
|
|
|
{
|
|
|
if (strcmp(applist[j].Name, applist[j - 1].Name) < 0)
|
|
|
{
|
|
|
tmp = applist[j];
|
|
|
applist[j] = applist[j - 1];
|
|
|
applist[j - 1] = tmp;
|
|
|
};
|
|
|
}
|
|
|
};
|
|
|
}
|
|
|
};
|
|
|
|
|
|
apps *yon_apps_get_by_name(apps *applist, char *name, int size)
|
|
|
{
|
|
|
for (int i = 0; i < size; i++)
|
|
|
{
|
|
|
if (strcmp(applist[i].Name, name) == 0)
|
|
|
return &applist[i];
|
|
|
}
|
|
|
return NULL;
|
|
|
};
|
|
|
|
|
|
//config functions
|
|
|
|
|
|
/**yon_config_load_register(char *command)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Выполняет команду [command].
|
|
|
* Полученные данные парсятся и регистрируются в конфиг.
|
|
|
*/
|
|
|
int yon_config_load_register(char *command){
|
|
|
if (__yon__config__strings){
|
|
|
__yon__config__strings = yon_dictionary_free_all(__yon__config__strings,NULL);
|
|
|
}
|
|
|
FILE *output = popen(command, "r");
|
|
|
char **output_strings = NULL;
|
|
|
output_strings = malloc(sizeof(char));
|
|
|
int i = 0;
|
|
|
char str[4096];
|
|
|
memset(str, 0, 4096);
|
|
|
while (fgets(str, 4096, output))
|
|
|
{
|
|
|
if (strcmp(str, "") != 0&& strcmp(str,"(null)\n")!=0)
|
|
|
{
|
|
|
char *key = yon_char_divide_search(str,"=",-1);
|
|
|
yon_dictionary_add_or_create_if_exists_with_data(__yon__config__strings,key,str);
|
|
|
__yon__config__strings->data_type=DICTIONARY_CHAR_TYPE;
|
|
|
}
|
|
|
}
|
|
|
check_config
|
|
|
return 0;
|
|
|
else return 1;
|
|
|
}
|
|
|
|
|
|
/**yon_config_remove_by_key(char *key)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Удаляет параметр конфига по ключу [key]
|
|
|
*/
|
|
|
int yon_config_remove_by_key(char *key){
|
|
|
check_config{
|
|
|
dictionary *dict = yon_dictionary_get(&__yon__config__strings,key);
|
|
|
if (dict){
|
|
|
yon_dictionary_rip(dict);
|
|
|
return 1;
|
|
|
}else return 0;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
/**yon_config_remove_by_data(void *data)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Производит поиск по конфигу на наличие параметра со значением [data] и удаляет найденное значение из конфига.
|
|
|
*/
|
|
|
int yon_config_remove_by_data(void *data){
|
|
|
check_config{
|
|
|
dictionary *dict = NULL;
|
|
|
for_dictionaries(dict,__yon__config__strings){
|
|
|
if (dict->data==data){
|
|
|
yon_dictionary_rip(dict);
|
|
|
return 1;
|
|
|
}
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
/**yon_config_remove_element(char *key, char *deleted)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Удаляет элемент [deleted] из массива параметров с ключом [key]
|
|
|
*/
|
|
|
int yon_config_remove_element(char *key, char *deleted){
|
|
|
check_config{
|
|
|
dictionary *dict = yon_dictionary_get(&__yon__config__strings,key);
|
|
|
char *data = (char*)dict->data;
|
|
|
char *found = strstr(data,deleted);
|
|
|
int size=strlen(data)-strlen(found)+1;
|
|
|
char *new_data = malloc(size);
|
|
|
memset(new_data,0,size);
|
|
|
if (strlen(found)!=strlen(deleted)){
|
|
|
memcpy(new_data,data,size-1);
|
|
|
new_data = yon_char_append(new_data,found+strlen(deleted)+1);
|
|
|
} else {
|
|
|
memcpy(new_data,data,size-2);
|
|
|
new_data = yon_char_append(new_data,found+strlen(deleted));
|
|
|
}
|
|
|
dict->data=(void*)(new_data);
|
|
|
free(data);
|
|
|
dict->flag1=1;
|
|
|
return 1;
|
|
|
} else return 0;
|
|
|
}
|
|
|
|
|
|
/**yon_config_get_by_key(char *key)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Возвращает значение параметра конфига с ключом [key]
|
|
|
*/
|
|
|
void *yon_config_get_by_key(char *key){
|
|
|
check_config{
|
|
|
dictionary *dict = NULL;
|
|
|
for_dictionaries(dict, __yon__config__strings){
|
|
|
if (strcmp(dict->key,key)==0){
|
|
|
return dict->data;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
/**yon_config_get_key_by_data(char *data)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Возвращает ключ параметра конфига со значением [data].
|
|
|
* Если параметр с таким значением не найден, возвращается NULL
|
|
|
*/
|
|
|
char *yon_config_get_key_by_data(char *data){
|
|
|
check_config{
|
|
|
dictionary *dict = NULL;
|
|
|
for_dictionaries(dict, __yon__config__strings){
|
|
|
if (strcmp(((char*)dict->data),data)==0){
|
|
|
return dict->key;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
/**yon_config_set(char *key, void *data)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Производит поиск по конфигу и заменяет значение параметра с ключом [key] на новое значение [data];
|
|
|
*/
|
|
|
int yon_config_set(char *key, void *data){
|
|
|
check_config{
|
|
|
dictionary *dict = yon_dictionary_get(&__yon__config__strings,key);
|
|
|
dict->data=data;
|
|
|
return 1;
|
|
|
} else return 0;
|
|
|
}
|
|
|
|
|
|
/**yon_config_clean()
|
|
|
* [EN]
|
|
|
* Erase all parameters from config;
|
|
|
* [RU]
|
|
|
* Удаляет все параметры из конфига;
|
|
|
*/
|
|
|
int yon_config_clean(){
|
|
|
check_config{
|
|
|
__yon__config__strings = yon_dictionary_free_all(__yon__config__strings, NULL);
|
|
|
return 1;
|
|
|
}
|
|
|
else return 0;
|
|
|
}
|
|
|
|
|
|
/**yon_config_register(char *key, void *data)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Регистрирует новый параметр конфига.
|
|
|
* [key] - ключ параметра;
|
|
|
* [data] - значение параметра;
|
|
|
*/
|
|
|
void yon_config_register(char *key, void *data){
|
|
|
yon_dictionary_add_or_create_if_exists_with_data(__yon__config__strings,key,data);
|
|
|
__yon__config__strings->data_type=DICTIONARY_CHAR_TYPE;
|
|
|
}
|
|
|
|
|
|
/**yon_config_load(char *command, int *str_len)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Выполняет команду [command] и возвращает распаршеный результат выполнения команды.
|
|
|
* В [str_len] возвращается длина возвращаемого массива
|
|
|
*/
|
|
|
config_str yon_config_load(char *command, int *str_len){
|
|
|
FILE *output = popen(command, "r");
|
|
|
char **output_strings = NULL;
|
|
|
output_strings = malloc(sizeof(char));
|
|
|
int i = 0;
|
|
|
char str[4096];
|
|
|
memset(str, 0, 4096);
|
|
|
while (fgets(str, 4096, output))
|
|
|
{
|
|
|
if (strcmp(str, "") != 0)
|
|
|
{
|
|
|
output_strings = realloc(output_strings, sizeof(char *) * (i + 1));
|
|
|
// printf("%s\n", str);
|
|
|
output_strings[i] = NULL;
|
|
|
output_strings[i] = yon_char_new(str);
|
|
|
memset(str, 0, 4096);
|
|
|
i++;
|
|
|
}
|
|
|
}
|
|
|
if (i>0){
|
|
|
*str_len = i;
|
|
|
return output_strings;
|
|
|
} else{
|
|
|
*str_len=-1;
|
|
|
return NULL;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**int yon_config_save(char *command)
|
|
|
* [EN]
|
|
|
* Saves config with [command]
|
|
|
* [RU]
|
|
|
* Выполняет команду [command], добавляя в конец все записи конфига в таком виде:
|
|
|
* [ПАРАМЕТР1]="[значения1]" [ПАРАМЕТР2]="[значения2]"
|
|
|
*/
|
|
|
int yon_config_save_registered(char *command){
|
|
|
check_config{
|
|
|
dictionary *dict = NULL;
|
|
|
for_dictionaries(dict,__yon__config__strings){
|
|
|
command = yon_char_unite(command, " ", yon_dictionary_get_data(dict,char*), NULL);
|
|
|
}
|
|
|
if (popen(command, "r")) return 1;
|
|
|
else return 0;
|
|
|
} else return 0;
|
|
|
}
|
|
|
|
|
|
/**yon_config_get_all(int *size)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Возвращает массив со всеми параметрами конфига, оканчивающаяся NULL
|
|
|
* [size] - указатель, в который выгружается длина массива
|
|
|
*/
|
|
|
config_str yon_config_get_all(int *size){
|
|
|
check_config{
|
|
|
*size = 1;
|
|
|
config_str conf = NULL;
|
|
|
dictionary *dict = NULL;
|
|
|
for_dictionaries(dict,__yon__config__strings){
|
|
|
conf = yon_remalloc(conf,sizeof(char*)*(*size));
|
|
|
conf[(*size)-1] = yon_char_unite(dict->key,"=",(char*)dict->data,NULL);
|
|
|
size++;
|
|
|
}
|
|
|
conf = yon_remalloc(conf,sizeof(char*)*(*size+1));
|
|
|
conf[*size] = NULL;
|
|
|
return conf;
|
|
|
} else return NULL;
|
|
|
}
|
|
|
|
|
|
/**char *yon_config_get_parameter(config parameters, int size, char *param)
|
|
|
* [EN]
|
|
|
* Gets parameter [param] from parameter list [parameters] of size [size];
|
|
|
* or NULL if nothing were found
|
|
|
* [RU]
|
|
|
* Возвращает параметр [param] из массива строк [parameters] размером [size]
|
|
|
* или NULL если такой не был найден
|
|
|
*/
|
|
|
char *yon_config_get_parameter(config_str parameters, int size, char *param)
|
|
|
{
|
|
|
if (param[0]==' ')
|
|
|
yon_char_divide_search(param," ",-1);
|
|
|
param=yon_char_divide_search(yon_char_new(param)," ",-1);
|
|
|
|
|
|
char *str = NULL;
|
|
|
for (int j = 0; j < size; j++)
|
|
|
{
|
|
|
char *name = yon_char_divide_search(yon_char_new(parameters[j]), "=", 1);
|
|
|
if (name)
|
|
|
{
|
|
|
if (strcmp(name, param) == 0)
|
|
|
{
|
|
|
str = yon_char_divide_search(yon_char_new(parameters[j]), "\n", 1);
|
|
|
if (strcmp(str, "") != 0 && strcmp(str, "(null)") != 0)
|
|
|
return str;
|
|
|
else
|
|
|
return NULL;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// terminal-using functions
|
|
|
|
|
|
/**yon_launch_app_with_arguments(char *name, char *args)
|
|
|
* [EN]
|
|
|
* Execute [command] in separate thread;
|
|
|
* [RU]
|
|
|
* Выполнить команду [command] в отдельном потоке;
|
|
|
*/
|
|
|
int yon_launch_app_with_arguments(char *name, char *args)
|
|
|
{
|
|
|
char *path = yon_char_unite("/usr/bin/", name, " ", args,NULL);
|
|
|
pthread_t thread_id;
|
|
|
char *command = NULL;
|
|
|
command = path;
|
|
|
pthread_create(&thread_id, NULL, (void *)yon_launch, command);
|
|
|
};
|
|
|
|
|
|
/**yon_launch(char *command)
|
|
|
* [EN]
|
|
|
* Execute command [command]
|
|
|
* [RU]
|
|
|
* Выполнить команду [command]
|
|
|
*/
|
|
|
void yon_launch(char *command)
|
|
|
{
|
|
|
system(command);
|
|
|
}
|
|
|
|
|
|
// Gtk functions
|
|
|
|
|
|
|
|
|
#ifdef __GTK_H__
|
|
|
|
|
|
|
|
|
static render_data render;
|
|
|
|
|
|
#ifdef VTE_TERMINAL
|
|
|
|
|
|
static void child_ready(VteTerminal *terminal, GPid pid, GError *error, gpointer user_data)
|
|
|
{
|
|
|
if (!terminal) return;
|
|
|
if (pid == -1) printf("Error\n\n\n");
|
|
|
else vte_terminal_feed_child(VTE_TERMINAL(terminal),(char*)user_data,strlen((char*)user_data));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* void yon_terminal_integrated_launch(GtkWidget *place_to_show, void *endwork_function, void* endwork_function_argument)
|
|
|
* [EN]
|
|
|
* launches terminal with specific [command],
|
|
|
* terminal is shown in [place_to_show] container,
|
|
|
* after terminal done its work [endwork_function] is called with [endwork_function_argument] argument.
|
|
|
* [RU]
|
|
|
* Запускает терминал с командой [command],
|
|
|
* терминал добавляется в контейнер [place_to_show] виджета,
|
|
|
* после завершения работы терминала вызывается функция [endwork_function] с аргументом [endwork_function_argument].
|
|
|
*/
|
|
|
void yon_terminal_integrated_launch(GtkWidget *place_to_show, char* command, void *endwork_function, void* endwork_function_argument){
|
|
|
char **commands=new_arr(char*,2);
|
|
|
gchar **envp = g_get_environ();
|
|
|
commands[0]=(gchar *)g_strdup(g_environ_getenv(envp, "SHELL"));
|
|
|
commands[1]=NULL;
|
|
|
char **env=new_arr(char*,2);
|
|
|
env[0]="";
|
|
|
env[1]=NULL;
|
|
|
GtkWidget *terminal = vte_terminal_new();
|
|
|
vte_terminal_set_size(VTE_TERMINAL(terminal),10,15);
|
|
|
VtePty *pty = vte_pty_new_sync(VTE_PTY_DEFAULT,NULL,NULL);
|
|
|
vte_terminal_set_pty(VTE_TERMINAL(terminal),pty);
|
|
|
gtk_container_add(GTK_CONTAINER(place_to_show),terminal);
|
|
|
char *install_command=yon_char_unite("tput cup 0 0 && tput ed; ",command," ; sleep 5;exit 0","\n",NULL);
|
|
|
printf("%s\n",install_command);
|
|
|
if(endwork_function)
|
|
|
g_signal_connect(G_OBJECT(terminal), "child-exited", G_CALLBACK(endwork_function), endwork_function_argument);
|
|
|
vte_terminal_spawn_async(VTE_TERMINAL(terminal),
|
|
|
VTE_PTY_DEFAULT,
|
|
|
NULL,
|
|
|
commands,
|
|
|
NULL,
|
|
|
0,
|
|
|
NULL, NULL,
|
|
|
NULL,
|
|
|
-1,
|
|
|
NULL,
|
|
|
child_ready,
|
|
|
install_command);
|
|
|
vte_pty_spawn_async(pty,
|
|
|
NULL,
|
|
|
commands,
|
|
|
NULL,
|
|
|
0,
|
|
|
NULL, NULL,
|
|
|
NULL,
|
|
|
-1,
|
|
|
NULL,
|
|
|
NULL,
|
|
|
NULL);
|
|
|
vte_terminal_set_scrollback_lines(VTE_TERMINAL(terminal), -1);
|
|
|
vte_terminal_set_scroll_on_output(VTE_TERMINAL(terminal), TRUE);
|
|
|
vte_terminal_set_scroll_on_keystroke(VTE_TERMINAL(terminal), TRUE);
|
|
|
gtk_widget_show_all(terminal);
|
|
|
}
|
|
|
|
|
|
/**yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *endwork_function, void* endwork_function_argument)
|
|
|
* [EN]
|
|
|
* launches terminal with specific [command],
|
|
|
* terminal is shown in [place_to_show] container,
|
|
|
* after terminal done its work [endwork_function] is called with [endwork_function_argument] argument.
|
|
|
* [RU]
|
|
|
* Запускает терминал с командой [command],
|
|
|
* терминал добавляется в контейнер [place_to_show] виджета,
|
|
|
* после завершения работы терминала вызывается функция [endwork_function] с аргументом [endwork_function_argument].
|
|
|
*/
|
|
|
void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *endwork_function, void* endwork_function_argument){
|
|
|
char **commands=new_arr(char*,2);
|
|
|
gchar **envp = g_get_environ();
|
|
|
commands[0]=(gchar *)g_strdup(g_environ_getenv(envp, "SHELL"));
|
|
|
commands[1]=NULL;
|
|
|
char **env=new_arr(char*,2);
|
|
|
env[0]="";
|
|
|
env[1]=NULL;
|
|
|
vte_terminal_set_size(VTE_TERMINAL(terminal),10,15);
|
|
|
VtePty *pty = vte_pty_new_sync(VTE_PTY_DEFAULT,NULL,NULL);
|
|
|
vte_terminal_set_pty(VTE_TERMINAL(terminal),pty);
|
|
|
char *install_command=yon_char_unite("tput cup 0 0 && tput ed; ",command," ; sleep 5;exit 0","\n",NULL);
|
|
|
if(endwork_function)
|
|
|
g_signal_connect(G_OBJECT(terminal), "child-exited", G_CALLBACK(endwork_function), endwork_function_argument);
|
|
|
vte_terminal_spawn_async(VTE_TERMINAL(terminal),
|
|
|
VTE_PTY_DEFAULT,
|
|
|
NULL,
|
|
|
commands,
|
|
|
NULL,
|
|
|
0,
|
|
|
NULL, NULL,
|
|
|
NULL,
|
|
|
-1,
|
|
|
NULL,
|
|
|
child_ready,
|
|
|
install_command);
|
|
|
vte_pty_spawn_async(pty,
|
|
|
NULL,
|
|
|
commands,
|
|
|
NULL,
|
|
|
0,
|
|
|
NULL, NULL,
|
|
|
NULL,
|
|
|
-1,
|
|
|
NULL,
|
|
|
NULL,
|
|
|
NULL);
|
|
|
vte_terminal_set_scrollback_lines(VTE_TERMINAL(terminal), 100);
|
|
|
vte_terminal_set_scroll_on_output(VTE_TERMINAL(terminal), TRUE);
|
|
|
vte_terminal_set_scroll_on_keystroke(VTE_TERMINAL(terminal), TRUE);
|
|
|
gtk_widget_show_all(terminal);
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
// Window config functions
|
|
|
|
|
|
#define check_window_config_setup if(__yon_window_config_target_window)
|
|
|
|
|
|
struct {
|
|
|
int x;
|
|
|
int y;
|
|
|
int width;
|
|
|
int height;
|
|
|
int fullscreen;
|
|
|
} __yon_main_window_config;
|
|
|
|
|
|
static GtkWindow *__yon_window_config_target_window = NULL;
|
|
|
static GKeyFile *__yon_window_config_file = NULL;
|
|
|
static char *__yon_window_config_path = NULL;
|
|
|
|
|
|
void yon_window_config_save(){
|
|
|
g_key_file_set_integer(__yon_window_config_file,"window","WindowPosX",__yon_main_window_config.x);
|
|
|
g_key_file_set_integer(__yon_window_config_file,"window","WindowPosY",__yon_main_window_config.y);
|
|
|
g_key_file_set_integer(__yon_window_config_file,"window","WindowWidth",__yon_main_window_config.width);
|
|
|
g_key_file_set_integer(__yon_window_config_file,"window","WindowHeight",__yon_main_window_config.height);
|
|
|
g_key_file_set_integer(__yon_window_config_file,"window","fullscreen",__yon_main_window_config.fullscreen);
|
|
|
g_key_file_save_to_file(__yon_window_config_file,__yon_window_config_path,NULL);
|
|
|
}
|
|
|
|
|
|
void yon_get_is_fullscreen(){
|
|
|
gtk_window_is_maximized(__yon_window_config_target_window);
|
|
|
__yon_main_window_config.fullscreen = gtk_window_is_maximized(__yon_window_config_target_window);
|
|
|
}
|
|
|
|
|
|
/**yon_on_configured_window_destroy(GtkWidget* self,GdkEvent* event)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Сохраняет настройки основного окна. Вызывается когда основное окно уничтожается.
|
|
|
*/
|
|
|
void yon_on_configured_window_destroy(GtkWidget* self,GdkEvent* event){
|
|
|
check_window_config_setup{
|
|
|
yon_get_is_fullscreen();
|
|
|
yon_window_config_save();
|
|
|
}
|
|
|
gtk_main_quit();
|
|
|
}
|
|
|
|
|
|
void __yon_window_config_on_resize(){
|
|
|
int max=0;
|
|
|
max=gtk_window_is_maximized(__yon_window_config_target_window);
|
|
|
if(max==0){
|
|
|
gtk_window_get_size(__yon_window_config_target_window,&__yon_main_window_config.width,&__yon_main_window_config.height);
|
|
|
gtk_window_get_position(__yon_window_config_target_window,&__yon_main_window_config.x,&__yon_main_window_config.y);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**yon_window_config_setup(GtkWindow *window)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Устанавливает указатель на окно для отслеживания его положения и размера
|
|
|
*/
|
|
|
void yon_window_config_setup(GtkWindow *window){
|
|
|
__yon_window_config_target_window = window;
|
|
|
g_signal_connect(G_OBJECT(window),"delete-event",G_CALLBACK(yon_on_configured_window_destroy),NULL);
|
|
|
g_signal_connect(G_OBJECT(window),"check-resize"/*"configure-event"*/,G_CALLBACK(__yon_window_config_on_resize),NULL);
|
|
|
}
|
|
|
|
|
|
void _yon_maximize(void *data){
|
|
|
g_usleep(G_USEC_PER_SEC/10);
|
|
|
if(__yon_main_window_config.fullscreen ==1) gtk_window_maximize(__yon_window_config_target_window);
|
|
|
}
|
|
|
|
|
|
/**yon_window_config_load(char *path)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Загружает конфиг окна и инициализирует отслеживание его параметров
|
|
|
*/
|
|
|
int yon_window_config_load(char *path){
|
|
|
__yon_window_config_file = g_key_file_new();
|
|
|
__yon_window_config_path=yon_char_new(path);
|
|
|
if (!g_key_file_load_from_file(__yon_window_config_file,__yon_window_config_path,G_KEY_FILE_NONE,NULL)){
|
|
|
struct stat st;
|
|
|
int size;
|
|
|
config_str conf = yon_char_parse(yon_char_new(__yon_window_config_path),&size,"/");
|
|
|
char *path = yon_char_unite(conf[0],"/",conf[1],"/",conf[2],"/",conf[3],"/",conf[4],"/",NULL);
|
|
|
if (stat(path, &st) == -1) {
|
|
|
mkdir(path, 0777);
|
|
|
}
|
|
|
FILE *fp;
|
|
|
fp=fopen(__yon_window_config_path,"w");
|
|
|
fclose(fp);
|
|
|
g_key_file_load_from_file(__yon_window_config_file,__yon_window_config_path,G_KEY_FILE_NONE,NULL);
|
|
|
}
|
|
|
__yon_main_window_config.x = g_key_file_get_integer(__yon_window_config_file,"window","WindowPosX",NULL);
|
|
|
__yon_main_window_config.y = g_key_file_get_integer(__yon_window_config_file,"window","WindowPosY",NULL);
|
|
|
__yon_main_window_config.width = g_key_file_get_integer(__yon_window_config_file,"window","WindowWidth",NULL);
|
|
|
__yon_main_window_config.height = g_key_file_get_integer(__yon_window_config_file,"window","WindowHeight",NULL);
|
|
|
__yon_main_window_config.fullscreen = g_key_file_get_integer(__yon_window_config_file,"window","fullscreen",NULL);
|
|
|
if (__yon_main_window_config.width==0) __yon_main_window_config.width=800;
|
|
|
if (__yon_main_window_config.height==0) __yon_main_window_config.height=600;
|
|
|
gtk_window_resize(__yon_window_config_target_window,__yon_main_window_config.width,__yon_main_window_config.height);
|
|
|
gtk_window_move(__yon_window_config_target_window,__yon_main_window_config.x,__yon_main_window_config.y);
|
|
|
pthread_t tid;
|
|
|
pthread_create(&tid,NULL,(void *)_yon_maximize,NULL);
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
void yon_window_config_apply(){
|
|
|
dictionary *dict=NULL;
|
|
|
gtk_window_move(__yon_window_config_target_window,__yon_main_window_config.x,__yon_main_window_config.y);
|
|
|
gtk_window_resize(__yon_window_config_target_window,__yon_main_window_config.width,__yon_main_window_config.height);
|
|
|
}
|
|
|
|
|
|
GtkWidget *yon_ubl_menu_item_about_new(char *buttonname){
|
|
|
GtkWidget *menu_item = gtk_menu_item_new();
|
|
|
gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),"menuitembottom");
|
|
|
GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
|
|
|
GtkWidget *label = gtk_label_new(buttonname);
|
|
|
GtkWidget *image = gtk_image_new_from_icon_name("dialog-information-symbolic",GTK_ICON_SIZE_BUTTON);
|
|
|
gtk_label_set_xalign(GTK_LABEL(label),0.0);
|
|
|
gtk_box_pack_start(GTK_BOX(box),image,0,0,5);
|
|
|
gtk_box_pack_start(GTK_BOX(box),label,0,0,5);
|
|
|
gtk_container_add(GTK_CONTAINER(menu_item),box);
|
|
|
gtk_widget_show_all(menu_item);
|
|
|
return menu_item;
|
|
|
}
|
|
|
|
|
|
GtkWidget *yon_ubl_menu_item_documentation_new(char *buttonname){
|
|
|
GtkWidget *menu_item = gtk_menu_item_new();
|
|
|
gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),"menuitemtop");
|
|
|
GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
|
|
|
GtkWidget *label = gtk_label_new(buttonname);
|
|
|
GtkWidget *image = gtk_image_new_from_icon_name("dialog-question-symbolic",GTK_ICON_SIZE_BUTTON);
|
|
|
gtk_label_set_xalign(GTK_LABEL(label),0.0);
|
|
|
gtk_box_pack_start(GTK_BOX(box),image,0,0,5);
|
|
|
gtk_box_pack_start(GTK_BOX(box),label,0,0,5);
|
|
|
gtk_container_add(GTK_CONTAINER(menu_item),box);
|
|
|
gtk_widget_show_all(menu_item);
|
|
|
return menu_item;
|
|
|
}
|
|
|
|
|
|
|
|
|
// other Gtk functions
|
|
|
|
|
|
/**yon_gtk_combo_box_text_fill(GtkWidget *combo, config_str parameters,int size)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Добавляет в Комбобокс [combo] все строки из массива строк [parameters] размера [size]
|
|
|
*/
|
|
|
int yon_gtk_combo_box_text_fill(GtkWidget *combo, config_str parameters,int size){
|
|
|
if (combo&¶meters){
|
|
|
for (int i=0;i<size;i++){
|
|
|
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo),parameters[i]);
|
|
|
}
|
|
|
return 1;
|
|
|
} else
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
/**yon_gtk_combo_box_text_find(GtkWidget *combo_box, char *text_to_find)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Проивзодит поиск по GtkComboBoxText [combo_box]
|
|
|
* возвращает 1 если элемент [text_to_find] найден, иначе возвращает 0
|
|
|
*/
|
|
|
int yon_gtk_combo_box_text_find(GtkWidget *combo_box, char *text_to_find){
|
|
|
if (combo_box&&text_to_find){
|
|
|
int active=gtk_combo_box_get_active(GTK_COMBO_BOX(combo_box));
|
|
|
char *str="-1";
|
|
|
for (int i=0;strcmp(str,"")!=0;i++){
|
|
|
gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box),i);
|
|
|
str=gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combo_box));
|
|
|
if (!str) return -1;
|
|
|
if (strstr(str,text_to_find)) return i;
|
|
|
}
|
|
|
} return -1;
|
|
|
}
|
|
|
|
|
|
/**yon_dictionary_gtk_pack_start_multiple_widgets(GtkBox *destination, gboolean expand, gboolean fill, int padding, ...)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Добвляет [destination] все виджеты, прописанные после [padding]. Добавление происходит с начала контейнера.
|
|
|
* [expand] - расширяемость выделенного для виджетов места
|
|
|
* [fill] - заполнять ли виджетом всё ему выделенное место
|
|
|
* [padding] - отступ од других элементов
|
|
|
*/
|
|
|
int yon_dictionary_gtk_pack_start_multiple_widgets(GtkBox *destination, gboolean expand, gboolean fill, int padding, ...){
|
|
|
va_list args;
|
|
|
va_start(args,padding);
|
|
|
GtkWidget *widget = va_arg(args,GtkWidget*);
|
|
|
while (widget){
|
|
|
gtk_box_pack_start(GTK_BOX(destination), widget, expand, fill, padding);
|
|
|
}
|
|
|
va_end(args);
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
/**yon_dictionary_gtk_pack_end_multiple_widgets(GtkBox *destination, gboolean expand, gboolean fill, int padding, ...)
|
|
|
* [EN]
|
|
|
*
|
|
|
* [RU]
|
|
|
* Добвляет в [destination] все виджеты, прописанные после [padding]. Добавление происходит с конца контейнера.
|
|
|
* [expand] - расширяемость выделенного для виджетов места
|
|
|
* [fill] - заполнять ли виджетом всё ему выделенное место
|
|
|
* [padding] - отступ од других элементов
|
|
|
*/
|
|
|
int yon_dictionary_gtk_pack_end_multiple_widgets(GtkBox *destination, gboolean expand, gboolean fill, int padding, ...){
|
|
|
va_list args;
|
|
|
va_start(args,padding);
|
|
|
GtkWidget *widget = va_arg(args,GtkWidget*);
|
|
|
while (widget){
|
|
|
gtk_box_pack_end(GTK_BOX(destination), widget, expand, fill, padding);
|
|
|
}
|
|
|
va_end(args);
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
|
|
|
void _yon_ubl_header_setup(GtkWidget *Overlay, GtkWidget *Head, GtkWidget *Image, char *image_path)
|
|
|
{
|
|
|
gtk_overlay_add_overlay(GTK_OVERLAY(Overlay), Head);
|
|
|
gtk_image_set_from_file(GTK_IMAGE(Image), image_path);
|
|
|
}
|
|
|
|
|
|
void _yon_ubl_header_setup_resource(GtkWidget *Overlay, GtkWidget *Head, GtkWidget *Image, char *image_path)
|
|
|
{
|
|
|
gtk_overlay_add_overlay(GTK_OVERLAY(Overlay), Head);
|
|
|
gtk_image_set_from_resource(GTK_IMAGE(Image), image_path);
|
|
|
}
|
|
|
|
|
|
int yon_ubl_status_box_setup(GtkWidget *icon, GtkWidget *box, GtkWidget *label)
|
|
|
{
|
|
|
if(icon&&box&&label){
|
|
|
render.icon=icon;
|
|
|
render.box=box;
|
|
|
render.label=label;
|
|
|
return 1;
|
|
|
} else return 0;
|
|
|
}
|
|
|
|
|
|
void _yon_ubl_status_box_render(char *text, BACKGROUND_IMAGE_TYPE type)
|
|
|
{
|
|
|
render_data data = render;
|
|
|
GtkIconTheme *ictheme = gtk_icon_theme_get_default();
|
|
|
GError *err = NULL;
|
|
|
if (err)
|
|
|
{
|
|
|
printf("%s\n", err->message);
|
|
|
g_error_free(err);
|
|
|
}
|
|
|
if (type == BACKGROUND_IMAGE_SUCCESS_TYPE||! type)
|
|
|
{
|
|
|
gtk_style_context_remove_class(gtk_widget_get_style_context(data.box), "boxInfoMessError");
|
|
|
gtk_style_context_add_class(gtk_widget_get_style_context(data.box), "boxInfoMessOK");
|
|
|
gtk_image_set_from_pixbuf(GTK_IMAGE(data.icon), gtk_icon_theme_load_icon_for_scale(ictheme, "com.ublinux.ubl-settings-video.checked", 25, 1, GTK_ICON_LOOKUP_FORCE_SIZE, &err));
|
|
|
}
|
|
|
else if (type == BACKGROUND_IMAGE_FAIL_TYPE)
|
|
|
{
|
|
|
gtk_style_context_remove_class(gtk_widget_get_style_context(data.box), "boxInfoMessOK");
|
|
|
gtk_style_context_add_class(gtk_widget_get_style_context(data.box), "boxInfoMessError");
|
|
|
gtk_image_set_from_pixbuf(GTK_IMAGE(data.icon), gtk_icon_theme_load_icon_for_scale(ictheme, "com.ublinux.ubl-settings-video.warning", 25, 1, GTK_ICON_LOOKUP_FORCE_SIZE, &err));
|
|
|
}
|
|
|
if (text)
|
|
|
gtk_label_set_text(GTK_LABEL(data.label), text);
|
|
|
}
|
|
|
|
|
|
void yon_ubl_status_box_render(char *text, BACKGROUND_IMAGE_TYPE type){
|
|
|
_yon_ubl_status_box_render(text,type);
|
|
|
}
|
|
|
|
|
|
/**yon_ubl_setup_sockets(GtkWidget *main_window, GtkWidget *left_window, GtkWidget *right_window, int socket_main_id, int socket_left_id, int socket_right_id)
|
|
|
* [EN]
|
|
|
* Set up plugs for using with GtkSockets insine ubl-settings-manager.
|
|
|
* [main_window] is container widget, which holds main application functionality.
|
|
|
* [left_window] is container widget, which holds widgets, have to be shown at left part of ubl-settings-manager header.
|
|
|
* [right_window] is container widget, which holds widgets, have to be shown at right part of ubl-settings-manager header.
|
|
|
* [socket_main_id] is id of socket for [main_window].
|
|
|
* [socket_left_id] is id of socket for [left_window].
|
|
|
* [socket_right_id] is id of socket for [right_window].
|
|
|
* [RU]
|
|
|
* Настраивает плаги для работы с сокетами в утилите ubl-settings-manager.
|
|
|
* [main_window] - контейнер основного интерфейса приложения.
|
|
|
* [left_window] - контейнер для виджетов которые должны отображаться в левой части шапки ubl-settings-manager.
|
|
|
* [right_window] - контейнер для виджетов которые должны отображаться в правой части шапки ubl-settings-manager.
|
|
|
* [socket_main_id] - id сокета для [main_window].
|
|
|
* [socket_left_id] - id сокета для [left_window].
|
|
|
* [socket_right_id] - id сокета для [right_window].
|
|
|
*/
|
|
|
void yon_ubl_setup_sockets(GtkWidget *main_window, GtkWidget *left_window, GtkWidget *right_window, int socket_main_id, int socket_left_id, int socket_right_id){
|
|
|
if (main_window&&socket_main_id>-1){
|
|
|
gtk_widget_hide(gtk_widget_get_toplevel(main_window));
|
|
|
GtkWidget *plug_main=gtk_plug_new(socket_main_id);
|
|
|
GtkWidget *plug_left=NULL;
|
|
|
GtkWidget *plug_right=NULL;
|
|
|
GtkWidget *box=NULL;
|
|
|
g_signal_connect(G_OBJECT(plug_main), "destroy", G_CALLBACK(gtk_main_quit),NULL);
|
|
|
if (socket_left_id>-1&&left_window){
|
|
|
plug_left=gtk_plug_new(socket_left_id);
|
|
|
g_object_ref(left_window);
|
|
|
gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(left_window)),left_window);
|
|
|
gtk_container_add(GTK_CONTAINER(plug_left),left_window);
|
|
|
gtk_style_context_add_class(gtk_widget_get_style_context(plug_left),"primary-toolbar");
|
|
|
gtk_style_context_add_class(gtk_widget_get_style_context(left_window),"button");
|
|
|
gtk_style_context_add_class(gtk_widget_get_style_context(left_window),"opacited");
|
|
|
gtk_style_context_add_class(gtk_widget_get_style_context(left_window),"color");
|
|
|
gtk_style_context_add_class(gtk_widget_get_style_context(plug_left),"noborder");
|
|
|
gtk_widget_show(plug_left);
|
|
|
}
|
|
|
else if (left_window){
|
|
|
if (box==NULL){
|
|
|
box=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,5);
|
|
|
gtk_box_pack_start(GTK_BOX(main_window),box,0,0,5);
|
|
|
gtk_box_reorder_child(GTK_BOX(main_window),box,0);
|
|
|
gtk_widget_show(box);
|
|
|
}
|
|
|
gtk_style_context_add_class(gtk_widget_get_style_context(left_window),"inherited");
|
|
|
gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(left_window)),left_window);
|
|
|
gtk_box_pack_end(GTK_BOX(box),left_window,0,0,5);
|
|
|
}
|
|
|
if (socket_right_id>-1&&right_window){
|
|
|
plug_right=gtk_plug_new(socket_right_id);
|
|
|
g_object_ref(right_window);
|
|
|
gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(right_window)),right_window);
|
|
|
gtk_container_add(GTK_CONTAINER(plug_right),right_window);
|
|
|
gtk_style_context_add_class(gtk_widget_get_style_context(plug_right),"primary-toolbar");
|
|
|
gtk_style_context_add_class(gtk_widget_get_style_context(right_window),"button");
|
|
|
gtk_style_context_add_class(gtk_widget_get_style_context(right_window),"opacited");
|
|
|
gtk_style_context_add_class(gtk_widget_get_style_context(right_window),"color");
|
|
|
gtk_style_context_add_class(gtk_widget_get_style_context(plug_right),"noborder");
|
|
|
gtk_widget_show(plug_right);
|
|
|
}
|
|
|
else if (right_window){
|
|
|
if (box==NULL){
|
|
|
box=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,5);
|
|
|
gtk_box_pack_start(GTK_BOX(main_window),box,0,0,5);
|
|
|
gtk_box_reorder_child(GTK_BOX(main_window),box,0);
|
|
|
gtk_widget_show(box);
|
|
|
}
|
|
|
gtk_style_context_add_class(gtk_widget_get_style_context(right_window),"inherited");
|
|
|
gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(right_window)),right_window);
|
|
|
gtk_box_pack_start(GTK_BOX(box),right_window,0,0,5);
|
|
|
}
|
|
|
g_object_ref(main_window);
|
|
|
gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(main_window)),main_window);
|
|
|
gtk_container_add(GTK_CONTAINER(plug_main),main_window);
|
|
|
gtk_widget_show(plug_main);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#ifdef WEBKIT_FOUND
|
|
|
|
|
|
/**yon_ubl_browser_window_open(char *link, char *browser_window_name)
|
|
|
* [EN]
|
|
|
* Launches integrated browser window, named [browser_window_name] at header with [link].
|
|
|
* [RU]
|
|
|
* Открывает встроенный браузер с именем [browser_window_name] и показываемой страницей по ссылке [link]
|
|
|
*/
|
|
|
void yon_ubl_browser_window_open(char *link, char *browser_window_name){
|
|
|
GtkWidget *browser=gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
|
|
GtkWidget *web_place=gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
|
|
|
GtkWidget *header=gtk_header_bar_new();
|
|
|
GtkWidget *header_label=gtk_label_new(browser_window_name);
|
|
|
GtkWidget *WebView=webkit_web_view_new();
|
|
|
gtk_container_add(GTK_CONTAINER(browser),web_place);
|
|
|
gtk_window_set_titlebar(GTK_WINDOW(browser),header);
|
|
|
gtk_window_set_title(GTK_WINDOW(browser),browser_window_name);
|
|
|
gtk_widget_set_size_request(browser,800,600);
|
|
|
gtk_header_bar_set_custom_title(GTK_HEADER_BAR(header),header_label);
|
|
|
gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(header),1);
|
|
|
webkit_web_view_load_uri(WEBKIT_WEB_VIEW(WebView),link);
|
|
|
gtk_box_pack_start(GTK_BOX(web_place),WebView,1,1,0);
|
|
|
gtk_widget_show_all(browser);
|
|
|
}
|
|
|
#else
|
|
|
|
|
|
/**yon_ubl_browser_window_open(char *link, char *browser_window_name)
|
|
|
* [EN]
|
|
|
* Launches browser with [link].
|
|
|
* [browser_window_name] is't used. It's needed for compatibility with webkit version of that function.
|
|
|
* [RU]
|
|
|
* Открывает браузер со страницей по ссылке [link]
|
|
|
* [browser_window_name] не используется. Нужна для совместимости с webkit версией этой функции.
|
|
|
*/
|
|
|
void yon_ubl_browser_window_open(char *link, char *browser_window_name){
|
|
|
char *user=getenv("SUDO_USER");
|
|
|
if (!user)
|
|
|
user=getlogin();
|
|
|
char *command=yon_char_unite("sudo -u ",user," xdg-open ", link,NULL);
|
|
|
yon_launch_app(command);
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
#endif |