/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program is distributed in the hope that it will be 
	useful, but WITHOUT ANY WARRANTY; without even the 
	implied warranty of MERCHANTABILITY or FITNESS FOR A 
	PARTICULAR PURPOSE.

**********************************************************************/



extern "C" {
#include	"machine/include.h"
#include	"memory_debug.h"
#include	"gif_rgb.h"
#include	"utils.h"
#include	"task.h"
}

#include	"v/v.h"
#include 	"v/VgbQueryIndicate.h"


#define BACK_COLOR_G_R	0xc0
#define BACK_COLOR_G_G	0xc0
#define BACK_COLOR_G_B	0xc0
#define BACK_COLOR_G_A	0x40

QUERY_THREAD * copy_out_qind_thread(QIND_THREAD * qt,int);
void insert_qind_thread(VObjectStatus * s,VgbQueryIndicateWork *qw,QUERY_THREAD * qt,int focus);
QIND_THREAD * search_qind_thread(QIND_THREAD * qind,int id);
void delete_qind_thread(VgbQueryIndicateWork *,int id);
void new_q_thread_obj(VObjectStatus * s,VgbQueryIndicateWork *qw,QIND_THREAD * qind);
void set_q_thread_obj(VObjectStatus * s,VgbQueryIndicateWork *qw,QIND_THREAD * qind);
V_CALLBACK_D(qind_del_handler);
V_CALLBACK_D(qind_new_handler);
V_CALLBACK_D(qind_edit_handler);
int qth_check_focused(QIND_THREAD * qt);
int get_query_id(VgbQueryIndicateWork *);
void free_flame_ctl(FLAME_CTL *);
void insert_flame_ctl(VgbQueryIndicateWork *,int,int,QUERY_THREAD *);
void qind_event_handler(QUERY_THREAD * qt,void*);
void  set_q_thread_obj_indicate(VObjectStatus * s,QIND_THREAD * qind);
VexDraw * qind_VexDrawEye(VexDraw * obj,VObjectStatus * v_sts,VImage ** imgs,V_CALLBACK(cb),QIND_THREAD*);
V_CALLBACK_D(qind_eye_handler);
void  set_qind_eye(VgbQueryIndicateWork * qw);
V_CALLBACK_D(back_color_handler);
V_CALLBACK_D(qind_focus_command_status);
V_CALLBACK_D(qind_focus_obey_command);
V_CALLBACK_D(_qind_focus_obey_command);
V_CALLBACK_D(disable_focus_handler);

void qind_focus(VgbQueryIndicateWork * qw);

void
free_flame_ctl(FLAME_CTL * _fc)
{

FLAME_CTL * fc;
	for ( ; _fc ; ) {
		fc = _fc;
		_fc = fc->next;

		d_f_ree(fc);
	}
}

void
insert_flame_ctl(VgbQueryIndicateWork * q,int op,int id,QUERY_THREAD * qth)
{
FLAME_CTL * fc;
	fc = (FLAME_CTL*)d_alloc(sizeof(*fc));
	fc->op = op;
	fc->id = id;
	fc->qth = qth;
	fc->next = q->fctl;
	q->fctl = fc;
}

QUERY_THREAD *
copy_out_qind_thread(QIND_THREAD * qt,int focused)
{
QUERY_THREAD * ret;
QUERY_THREAD ** rp;
	ret = 0;
	rp = &ret;
	for ( ; qt ; qt = qt->next ) {
		if ( focused ) {
			if ( qth_check_focused(qt) == 0 )
				continue;
		}
		*rp = (QUERY_THREAD*)d_alloc(sizeof(**rp));
		(*rp)->next = 0;
		duplicate_q_thread(*rp,qt->qth);
		rp = &(*rp)->next;
	}
	return ret;
}


int
get_query_id(VgbQueryIndicateWork * qw)
{
int id;
QIND_THREAD * qt;

retry:
	id = qw->qth_id + 1;
	if ( id == 0 )
		id ++;
	qw->qth_id = id;
	for ( qt = qw->qind_th ; qt ; qt = qt->next )
		if ( qt->qth->id == id )
			goto retry;
	return id;
}

int 
qth_check_focused(QIND_THREAD * qt)
{
//VObjectStatus vsts;
//	qt->check_box->get_status(&vsts,VSF_VALUE);
	if ( qt->selected )
		return 1;
	return 0;
}

void 
set_q_thread_obj_indicate(VObjectStatus * s,QIND_THREAD * qind)
{
VObjectStatus sts;
VHAlignView * h;
	sts.parent = qind->indicate_obj;
	sts.alignv = VALIGN_TOP;
	sts.alignh = VALIGN_LEFT;
	sts.padding.w = sts.padding.h = 0;
	sts.spacing.w = sts.spacing.h = 0;
	sts.fsize = s->fsize;
	sts.ws = s->ws;
	if ( qind->qth->url ) {
		h = VHAlignView::create(&sts,VSF_PARENT|VSF_SPACING|VSF_PADDING|VSF_ALIGN);
		sts.parent = h;
		sts.descriptor = l_string(std_cm,"URL : ");
		VStaticText::create(&sts,
			VSF_DESC|VSF_PARENT|VSF_SPACING|VSF_PADDING|VSF_ALIGN|VSF_FSIZE|VSF_WS);
		if ( qind->qth->title )
			sts.descriptor = qind->qth->title;
		else	sts.descriptor = l_string(std_cm,"[UNTITLED]");
		VStaticText::create(&sts,
			VSF_DESC|VSF_PARENT|VSF_SPACING|VSF_PADDING|VSF_ALIGN|VSF_FSIZE|VSF_WS);
		sts.parent = qind->indicate_obj;
		sts.descriptor = qind->qth->url;
		VStaticText::create(&sts,
			VSF_DESC|VSF_PARENT|VSF_SPACING|VSF_PADDING|VSF_ALIGN|VSF_FSIZE|VSF_WS);
	}
	else {
		h = VHAlignView::create(&sts,VSF_PARENT|VSF_SPACING|VSF_PADDING|VSF_ALIGN);
		sts.parent = h;
		sts.descriptor = l_string(std_cm,"PROPERTY : ");
		VStaticText::create(&sts,
			VSF_DESC|VSF_PARENT|VSF_SPACING|VSF_PADDING|VSF_ALIGN|VSF_FSIZE|VSF_WS);
		if ( qind->qth->title )
			sts.descriptor = qind->qth->title;
		else	sts.descriptor = l_string(std_cm,"[UNTITLED]");
		VStaticText::create(&sts,
			VSF_DESC|VSF_PARENT|VSF_SPACING|VSF_PADDING|VSF_ALIGN|VSF_FSIZE|VSF_WS);
		sts.parent = qind->indicate_obj;
		sts.descriptor = qind->qth->property;
		VStaticText::create(&sts,
			VSF_DESC|VSF_PARENT|VSF_SPACING|VSF_PADDING|VSF_ALIGN|VSF_FSIZE|VSF_WS);
		sts.descriptor = get_q_thread_subtitle(qind->qth);
		VStaticText::create(&sts,
			VSF_DESC|VSF_PARENT|VSF_SPACING|VSF_PADDING|VSF_ALIGN|VSF_FSIZE|VSF_WS);
	}
}

VexDraw *
qind_VexDrawEye(VexDraw * target_obj,VObjectStatus * v_sts,VImage ** imgs,V_CALLBACK(cb),QIND_THREAD*obj)
{
VexDraw * ret;
int vsf_value_eh;
	if ( imgs[0] == 0 )
		return 0;
/*
	v_sts->padding.w = v_sts->padding.h = 0;
	v_sts->spacing.w = v_sts->spacing.h = 0;
*/
	v_sts->size = v_sts->min_size = imgs[0]->size;
	v_sts->attr = VexDraw::click_rotate_zero;
	v_sts->value_event_handler = cb;
	v_sts->value_eh_arg = (void*)obj;
	v_sts->visible = 1;
	if ( cb == 0 )
		vsf_value_eh = 0;
	else	vsf_value_eh = VSF_VALUE_EH;
	if ( target_obj ) {
		ret = target_obj;
		target_obj->set_status(v_sts,
				VSF_PARENT|VSF_ALIGN|VSF_SPACING|
				VSF_PADDING|VSF_MIN_SIZE|VSF_SIZE|
				VSF_VALUE|VSF_VISIBLE|
				VSF_ATTR|vsf_value_eh);
	}
	else	ret = VexDraw::create(v_sts,
				VSF_PARENT|VSF_ALIGN|VSF_SPACING|
				VSF_PADDING|VSF_MIN_SIZE|VSF_SIZE|
				VSF_VALUE|VSF_VISIBLE|
				VSF_ATTR|vsf_value_eh);
	ret->set_images(2,imgs,imgs[0]->size);
	ret->set_status(v_sts,VSF_VALUE);
	return ret;
}


void
VgbQueryIndicate::_qind_focus_command_status()
{
QIND_THREAD * qt1;
int fflags;
	_VM_OP_START_VOID
	fflags = 0;
	for ( qt1 = qw.qind_th ; qt1 ; qt1 = qt1->next ) {
		if ( qt1->selected ) {
			fflags |= VMF_CUT|VMF_CLEAR|VMF_COPY;
			break;
		}
	}
	if ( VdataQThread::clipboard_available() )
		fflags |= VMF_PASTE;
	qw.focus->set_editable_flags(fflags);
	VM_OP_END
}

V_CALLBACK_D(qind_focus_command_status)
{
	static_cast<VgbQueryIndicate*>(user_arg)->_qind_focus_command_status();
}

V_CALLBACK_D(qind_focus_obey_command)
{
VgbQueryIndicate * obj;
int type;
VgbQueryIndicateStatus sts;
VdataQThread * vq;
int err;
QUERY_THREAD * qt;

	type = *(int*)sys_arg;
	obj = static_cast<VgbQueryIndicate*>(user_arg);
	switch ( type ) {
	case VMT_PASTE:
		vq = VdataQThread::new_from_clipboard();
		if ( vq ) {
			sts.qth_set = vq->get_VdataQThread(&err);
			for ( qt = sts.qth_set ; qt ; qt = qt->next )
				qt->id = 0;
			if ( err < 0 ) {
				delete vq;
				break;
			}
			sts.qth_focused = 1;
			obj->set_queryindicate_status(&sts,VSF_QINDICATE_QTH_SET);
			free_query_thread(sts.qth_set);
		}
		break;
	case VMT_CUT:
		sts.qth_focused = 1;
		obj->get_queryindicate_status(&sts,VSF_QINDICATE_QTH_GET);
		vq = new VdataQThread(sts.qth_get,&err);
		free_query_thread(sts.qth_get);
		if ( err < 0 )
			er_panic("_qind_focus_obey_command");
		vq->store_into_clipboard();
		sts.qth_focused = 1;
		obj->set_queryindicate_status(&sts,VSF_QINDICATE_QTH_DELETE);
		break;
	case VMT_COPY:
		sts.qth_focused = 1;
		obj->get_queryindicate_status(&sts,VSF_QINDICATE_QTH_GET);
		vq = new VdataQThread(sts.qth_get,&err);
		free_query_thread(sts.qth_get);
		if ( err < 0 )
			er_panic("_qind_focus_obey_command");
		vq->store_into_clipboard();
		break;
	case VMT_CLEAR:
		sts.qth_focused = 1;
		obj->set_queryindicate_status(&sts,VSF_QINDICATE_QTH_DELETE);
		break;
	case VMT_SEL_ALL:
		break;
	default:
		ss_printf("OBEY_COMMAND %i\n",type);
	}
	obj->_qind_focus_command_status();
}

void
qind_focus(VgbQueryIndicateWork * qw)
{
	qw->focus->focus();
}

void
VgbQueryIndicate::_disable_focus_handler(bool when)
{
VObjectStatus sts;
QIND_THREAD * qt1;

	_VM_OP_START_VOID
	if ( when == true ) {
		for ( qt1 = qw.qind_th ; qt1 ; qt1 = qt1->next )
			if ( qt1->selected ) {
				sts.attr = vobject_get_hilite_color();
				qt1->obj->set_status(&sts,VSF_ATTR);
			}
		qind_focus(&qw);
		this->_qind_focus_command_status();
	}
	else {
		for ( qt1 = qw.qind_th ; qt1 ; qt1 = qt1->next )
			if ( qt1->selected ) {
				SET_RGB8_32(sts.attr,
					BACK_COLOR_G_R,BACK_COLOR_G_G,
					BACK_COLOR_G_B,BACK_COLOR_G_A);
				qt1->obj->set_status(&sts,VSF_ATTR);
			}
	}
	VM_OP_END
}

V_CALLBACK_D(disable_focus_handler)
{
VgbQueryIndicate * ind;
	ind = (VgbQueryIndicate*)user_arg;
	ind->_disable_focus_handler(*(bool*)sys_arg);
}


void
VgbQueryIndicate::_back_color_handler(QIND_THREAD * qt)
{
VObjectStatus sts;
QIND_THREAD * qt1;
VEditable * fo;
int new_focus;

	_VM_OP_START_VOID
	fo = VEditable::get_focused_object();
	if ( fo != qt->qw->focus )
		new_focus = 1;
	else	new_focus = 0;

	if ( new_focus == 0 )
		qt->selected = 1 - qt->selected;
	if ( qt->selected ) {
		sts.attr = vobject_get_hilite_color();
	}
	else {
		SET_RGB8_32(sts.attr,0,0,0,0);
	}
	qt->obj->set_status(&sts,VSF_ATTR);
	if ( qt->selected ) {
		SET_RGB8_32(sts.attr,0,0,0,0);
		for ( qt1 = qt->qw->qind_th ; qt1 ; qt1 = qt1->next ) {
			if ( qt == qt1 )
				continue;
			if ( qt1->selected ) {
				qt1->selected = 0;
				qt1->obj->set_status(&sts,VSF_ATTR);
			}
		}
	}
	qind_focus(qt->qw);
	this->_qind_focus_command_status();
	VM_OP_END
}

V_CALLBACK_D(back_color_handler)
{
QIND_THREAD * qt;
VgbQueryIndicate * obj;
	qt = (QIND_THREAD*)user_arg;
	obj = static_cast<VgbQueryIndicate*>(qt->qw->target_obj);
	obj->_back_color_handler(qt);
}

void 
new_q_thread_obj(VObjectStatus * s,VgbQueryIndicateWork *qw,QIND_THREAD * qind)
{
int order;
QIND_THREAD * qt;
VObjectStatus sts;
VAlignView * a;
VBackColorView * obj;
VVAlignView * vv0;
VVAlignView * vv;
VHAlignView * hh;
	a = qw->align_v;
	for ( order = 0 , qt = qw->qind_th ; qt && qt != qind ; qt = qt->next , order ++ );
	if ( qt == 0 )
		return;
	if ( a == 0 )
		return;
	sts.parent = a;
	sts.visible = 1;
	sts.alignv = VALIGN_TOP;
	sts.alignh = VALIGN_FILL;
	sts.padding.w = sts.padding.h = 0;
	sts.spacing.w = sts.spacing.h = 0;
	if ( qt->selected ) {
		sts.attr=vobject_get_hilite_color();
	}
	else {
		SET_RGB8_32(sts.attr,0,0,0,0);
	}
	sts.value_event_handler = back_color_handler;
	sts.value_eh_arg = (void*)qt;
	qt->obj = obj = VBackColorView::create(&sts,
		VSF_PARENT|VSF_SPACING|VSF_PADDING|VSF_ALIGN|VSF_VISIBLE|VSF_ATTR|VSF_VALUE_EH);
	if ( qt->next )
		a->reorder_child(qt->obj,order);

	sts.alignh = VALIGN_LEFT;
	sts.parent = obj;
	vv0 = VVAlignView::create(&sts,VSF_PARENT|VSF_SPACING|VSF_PADDING|VSF_ALIGN|VSF_VISIBLE);
	sts.parent = vv0;
	hh = VHAlignView::create(&sts,VSF_PARENT|VSF_SPACING|VSF_PADDING|VSF_ALIGN);
	qt->base_obj = hh;
	sts.parent = hh;
	sts.value = 0;

	sts.padding.w = sts.padding.h = 5;
	sts.spacing.w = sts.spacing.h = 0;

	qt->check_box = VCheckBox::create(&sts,VSF_PARENT|VSF_SPACING|VSF_PADDING|VSF_ALIGN|VSF_VALUE);
	if ( qind->qth->flags & QTF_ACTIVE )
		sts.value = 0;
	else	sts.value = 1;
	qt->qw = qw;
	sts.alignv = VALIGN_FILL;
	sts.alignh = VALIGN_LEFT;
	sts.parent = qt->eye_obj_base = VVAlignView::create(&sts,VSF_PARENT|VSF_SPACING|VSF_PADDING|VSF_ALIGN);
	sts.alignv = VALIGN_EXPAND;
	qt->eye_obj = qind_VexDrawEye(0,&sts,qw->eye_imgs,qind_eye_handler,qt);

	sts.parent = hh;
	vv = VVAlignView::create(&sts,VSF_PARENT|VSF_SPACING|VSF_PADDING|VSF_ALIGN);
	qt->indicate_obj = vv;

	set_q_thread_obj_indicate(s,qt);

	sts.parent = obj;
	sts.alignh= VALIGN_FILL;
	sts.padding.h = 10;
	VHSeparator::create(&sts,
		VSF_PARENT|VSF_SPACING|VSF_PADDING|VSF_ALIGN);
}

void 
set_q_thread_obj(VObjectStatus * s,VgbQueryIndicateWork *qw,QIND_THREAD * qind)
{
VObjectStatus sts;
	qind->indicate_obj->destroy();
	sts.parent = qind->base_obj;
	sts.alignv = VALIGN_TOP;
	sts.alignh = VALIGN_LEFT;
	sts.padding.w = sts.padding.h = 0;
	sts.spacing.w = sts.spacing.h = 0;
	qind->indicate_obj = VVAlignView::create(&sts,VSF_PARENT|VSF_SPACING|VSF_PADDING|VSF_ALIGN);
	set_q_thread_obj_indicate(s,qind);
}


QIND_THREAD *
search_qind_thread(QIND_THREAD * qind,int id)
{
QIND_THREAD * ret;
	for ( ret = qind ; ret ; ret = ret->next )
		if ( ret->qth->id == id )
			return ret;
	return ret;
}

void 
set_qind_eye(VgbQueryIndicateWork * qw)
{
QIND_THREAD * qt;
VObjectStatus v_sts;
	v_sts.visible = 1;
	v_sts.value = 0;
	v_sts.padding.w = v_sts.padding.h = 5;
	v_sts.spacing.w = v_sts.spacing.h = 0;
	v_sts.alignh = VALIGN_LEFT;
	v_sts.alignv = VALIGN_EXPAND;
	for ( qt = qw->qind_th ; qt ; qt = qt->next ) {
		v_sts.parent = qt->eye_obj_base;
		if ( qt->qth->flags & QTF_ACTIVE )
			v_sts.value = 0;
		else	v_sts.value = 1;
		qt->eye_obj = qind_VexDrawEye(qt->eye_obj,&v_sts,qw->eye_imgs,qind_eye_handler,qt);
	}
}


void 
insert_qind_thread(VObjectStatus * s,VgbQueryIndicateWork * qw,QUERY_THREAD * qt,int focus)
{
QIND_THREAD * target;
QIND_THREAD * prev;
VObjectStatus v_sts;
	prev = 0;
	for ( ; qt ; qt = qt->next ) {
		if ( qt->id == 0 ) {
			if ( qw->flame == 0 ) {
				qt->id = get_query_id(qw);
				target = 0;
			}
			else {
				insert_flame_ctl(qw,FC_INSERT,0,qt);
				continue;
			}
		}
		else {
			target = search_qind_thread(qw->qind_th,qt->id);
		}
		if ( target == 0 ) {
			target = (QIND_THREAD*)d_alloc(sizeof(*target));
			memset(target,0,sizeof(*target));
			target->qth = (QUERY_THREAD*)d_alloc(sizeof(*target->qth));
			memset(target->qth,0,sizeof(*target->qth));
			if ( prev ) {
				target->next = prev->next;
				prev->next = target;
			}
			else {
				target->next = qw->qind_th;
				qw->qind_th = target;
			}
			qt->mask = 0;
		}
		if ( qt->mask ) {
			target->qth->flags &= ~qt->mask;
			target->qth->flags |= qt->mask & qt->flags;
			target->qth->mask = qt->mask;

			if ( target->qth->flags & QTF_ACTIVE )
				v_sts.value = 0;
			else	v_sts.value = 1;
			if ( target->eye_obj ) 
				target->eye_obj->set_status(&v_sts,VSF_VALUE);
		}
		else {
			duplicate_q_thread(target->qth,qt);
			if ( target->obj )
				set_q_thread_obj(s,qw,target);
			else	new_q_thread_obj(s,qw,target);
		}
		if ( qw->from_flame == 0 )
			insert_flame_ctl(qw,FC_SET,0,target->qth);
		target->qth->mask = 0;
		prev = target;
	}
}

void 
delete_qind_thread(VgbQueryIndicateWork * qw,int id)
{
QIND_THREAD * qt;
QIND_THREAD  **qind;
	qind = &qw->qind_th;
	for ( ; (*qind) && (*qind)->qth->id != id ; qind = &(*qind)->next );
	if ( *qind == 0 )
		return;
	qt = *qind;
	*qind = (*qind)->next;
	free_query_thread(qt->qth);
	qt->obj->destroy();
	d_f_ree(qt);

	if ( qw->from_flame == 0 )
		insert_flame_ctl(qw,FC_DELETE,id,0);
}

V_CALLBACK_D(qind_del_handler)
{
VgbQueryIndicate * obj;
	obj = (VgbQueryIndicate*)user_arg;
	obj->_qind_del_handler();
}

void
VgbQueryIndicate::_qind_del_handler()
{
VgbQueryIndicateStatus qsts;
	qsts.qth_focused = 1;
	this->set_queryindicate_status(&qsts,VSF_QINDICATE_QTH_DELETE);
}

V_CALLBACK_D(qind_new_handler)
{
VgbQueryIndicate * obj;
	obj = (VgbQueryIndicate*)user_arg;
	obj->_qind_new_handler();
}

void
VgbQueryIndicate::_qind_new_handler()
{
XL_SEXP * func,* ret;
VSysArgTranslator * vsat;
QUERY_THREAD * qt_ret;
//VgbQueryIndicateStatus qsts;
//VgbFlameStandard * flame;
//VgbFlameRadarStatus r_sts;
VObjectStatus o_sts;

	this->get_status(&o_sts,VSF_ENABLED);
	if ( o_sts.enabled == 0 )
		return;
	qt_ret = 0;
	gc_push(0,0,"_qind_new_handler");
	vsat = qw.edit_event;
	if ( vsat ) {
		func = List(	get_symbol(vsat->func),
				get_integer(sts.id,0),
				0,
				-1);
		ret = eval(vsat->env,func);
		if ( get_type_sexp(ret) == XLT_ERROR ) {
			log_print_sexp(LOG_MESSAGE,LOG_LAYER_GB,0,"Qind_edit",ret,0);
			qt_ret = 0;
		}
/*
		else qt_ret = sexp_to_q_thread(ret);
		if ( qt_ret ) {
			qt_ret->id = 0;
			qt_ret->next = 0;
			flame = qw.flame;
			if ( flame ) {
				r_sts.query_insert = qt_ret;
				flame->set_radar_status(&r_sts,VSF_FLAME_R_QUERY_INSERT);
			}
			else {
				qt_ret->id = get_query_id(&qw);
			}
			qsts.qth_set = qt_ret;
			qsts.qth_focus = 0;
			this->set_queryindicate_status(&qsts,VSF_QINDICATE_QTH_SET);
		}
*/
		o_sts.enabled = 0;
		this->set_status(&o_sts,VSF_ENABLED);
	}
	gc_pop(0,0);
	if ( qt_ret )
		free_query_thread(qt_ret);
}


V_CALLBACK_D(qind_edit_handler)
{
VgbQueryIndicate * obj;
	obj = (VgbQueryIndicate*)user_arg;
	obj->_qind_edit_handler();
}

void
VgbQueryIndicate::_qind_edit_handler()
{
VgbQueryIndicateStatus qsts;
QUERY_THREAD * qt,* qt_ret;
XL_SEXP * func, * ret;
VSysArgTranslator * vsat;
//VgbFlameStandard * flame;
//VgbFlameRadarStatus r_sts;
VObjectStatus o_sts;
	this->get_status(&o_sts,VSF_ENABLED);
	if ( o_sts.enabled == 0 )
		return;
	qsts.qth_focused = 1;
	qt_ret = 0;
	this->get_queryindicate_status(&qsts,VSF_QINDICATE_QTH_GET);
	if ( qsts.qth_get == 0 )
		return;
	qt = qsts.qth_get;
	if ( qt->next ) {
		qsts.qth_reset_focus = qt->next;
		this->set_queryindicate_status(&qsts,VSF_QINDICATE_QTH_RESET_FOCUS);
	}
	qt->next = 0;

	gc_push(0,0,"_qind_new_handler");
	vsat = qw.edit_event;
	if ( vsat ) {
		func = List(	get_symbol(vsat->func),
				get_integer(sts.id,0),
				List(	n_get_symbol("quote"),
					q_thread_to_sexp_1(qt,QTH_MAXIMUM_INFO),
					-1),
				-1);
		ret = eval(vsat->env,func);
		if ( get_type_sexp(ret) == XLT_ERROR ) {
			log_print_sexp(LOG_MESSAGE,LOG_LAYER_GB,0,"Qind_edit",ret,0);
			qt_ret = 0;
		}
/*
		else qt_ret = sexp_to_q_thread(ret);
		if ( qt_ret ) {
			qt_ret->id = qt->id;
			flame = qw.flame;
			if ( flame ) {
				r_sts.query_set = qt_ret;
				flame->set_radar_status(&r_sts,VSF_FLAME_R_QUERY_SET);
			}
			qsts.qth_set = qt_ret;
			qsts.qth_focus = 0;
			this->set_queryindicate_status(&qsts,VSF_QINDICATE_QTH_SET);
		}
*/

		o_sts.enabled = 0;
		this->set_status(&o_sts,VSF_ENABLED);
	}
	gc_pop(0,0);
	if ( qt )
		free_query_thread(qt);
	if ( qt_ret )
		free_query_thread(qt_ret);
}


V_CALLBACK_D(qind_eye_handler)
{
QIND_THREAD * qt;
VObjectStatus v_sts;
QUERY_THREAD qth;
VgbFlameStandard * f;
VgbFlameRadarStatus r_sts;
	qt = (QIND_THREAD*)user_arg;
	if ( qt->eye_obj == 0 )
		return;
	qt->eye_obj->get_status(&v_sts,VSF_VALUE);
	if ( v_sts.value == 0 )
		qt->qth->flags |= QTF_ACTIVE;
	else	qt->qth->flags &= ~QTF_ACTIVE;

	f = qt->qw->flame;
	if ( f == 0 )
		return;

	memset(&qth,0,sizeof(qth));
	qth.id = qt->qth->id;
	qth.flags = qt->qth->flags;
	qth.mask = QTF_ACTIVE;

	r_sts.query_set = &qth;
	f->set_radar_status(&r_sts,VSF_FLAME_R_QUERY_SET);
}


void
VgbQueryIndicate::_qind_event_handler(QUERY_THREAD * qt)
{
VgbQueryIndicateStatus q_sts;
	_VM_OP_START_VOID
	qw.from_flame ++;
	memset(&q_sts,0,sizeof(q_sts));
	if ( qt->mask ) {
		q_sts.qth_set = qt;
		q_sts.qth_focused = 0;
		this->set_queryindicate_status(&q_sts,VSF_QINDICATE_QTH_SET);
	}
	else if ( qt->url == 0 && qt->property == 0 ) {
		q_sts.qth_delete = qt;
		this->set_queryindicate_status(&q_sts,VSF_QINDICATE_QTH_DELETE);
	}
	else {
		q_sts.qth_set = qt;
		q_sts.qth_focused = 0;
		this->set_queryindicate_status(&q_sts,VSF_QINDICATE_QTH_SET);
	}
	qw.from_flame --;
	VM_OP_END
}


void 
qind_event_handler(QUERY_THREAD * qt,void* arg)
{
VgbQueryIndicate * qind;
	qind = (VgbQueryIndicate*)arg;
	qind->_qind_event_handler(qt);
}


VExError
VgbQueryIndicate::create_do(const VObjectStatus* s, int flags,VObject * nmp, void * arg)
{
VExError err;
VObjectStatus _sts;

VgbQueryIndicateStatus * in_sts;
int in_flags;
VObjectAppStatusAry * app;
	if ( arg == 0 )
		return initial_VExError(V_ER_NO_ERR,0,0);
	app = (VObjectAppStatusAry*)arg;
	in_sts = (VgbQueryIndicateStatus*)app[0].sts;
	in_flags = app[0].flags;

	memset(&qw,0,sizeof(qw));

	err = initial_VExError(V_ER_NO_ERR,VSF_SPACING,0);

	info = 0;

	copy_vobject_status(&_sts,(VObjectStatus*)s,flags);
	_sts.parent = this;
	_sts.spacing.w = _sts.spacing.h = 0;
	qw.focus = VFocusView::create(&_sts,
			flags|VSF_PARENT|VSF_SPACING);
	qw.focus->set_obey_command_handler(qind_focus_obey_command, (void*)this);
	qw.focus->set_command_status_handler(qind_focus_command_status, (void*)this);
	qw.focus->set_focused_event_handler(disable_focus_handler, (void*)this);
	_sts.parent = qw.focus;
	_sts.alignv = VALIGN_FILL;
	_sts.alignh = VALIGN_FILL;
	_sts.padding.w = _sts.padding.h = 4;
	_sts.spacing.w = _sts.spacing.h = 0;
	if ( in_flags & VSF_QINDICATE_SCROLL ) {
		qw.scroll = VScrollView::create(&_sts,
				flags|VSF_PARENT|VSF_SPACING|VSF_PADDING);
		_sts.parent = qw.scroll;
		_sts.alignv = VALIGN_FILL;
		_sts.alignh = VALIGN_FILL;
		_sts.padding.w = _sts.padding.h = 0;
		_sts.spacing.w = _sts.spacing.h = 0;
	}

	_sts.alignv = VALIGN_TOP;
	_sts.alignh = VALIGN_FILL;
	_sts.padding.w = _sts.padding.h = 0;
	_sts.spacing.w = _sts.spacing.h = 0;
	qw.align_v = VVAlignView::create(&_sts,
			flags|VSF_PARENT|VSF_SPACING);
	_sts.parent = qw.align_v;
	_sts.alignv = VALIGN_TOP;
	_sts.alignh = VALIGN_FILL;
	_sts.padding.w = _sts.padding.h = 0;
	_sts.spacing.w = _sts.spacing.h = 0;

	qw.target_obj = this;

	if ( err.code )
		return err;
	return err;
}

VExError 
VgbQueryIndicate::create_do_out_of_lock(
	const VObjectStatus *,int flags,VObject * nmp,void * arg)
{
VgbQueryIndicateStatus * in_sts;
int in_flags;
VObjectAppStatusAry * app;
	if ( arg == 0 )
		return initial_VExError(V_ER_NO_ERR,0,0);
	app = (VObjectAppStatusAry*)arg;
	in_sts = (VgbQueryIndicateStatus*)app[0].sts;
	in_flags = app[0].flags;
	in_flags &= ~(VSF_QINDICATE_SCROLL);
	if ( in_sts == 0 )
		return initial_VExError(V_ER_NO_ERR,0,0);
	return this->set_queryindicate_status(in_sts,in_flags);
}


void
VgbQueryIndicate::destroy_do(VObject * nmp)
{
VSysArgTranslator * vsat;
	qw.align_v = 0;
	for ( ; qw.qind_th ; )
		delete_qind_thread(&qw,qw.qind_th->qth->id);
	vsat = qw.edit_event;
	qw.edit_event = 0;
	free_VSysArgTranslator(VFLT_DELETE,(void*)vsat);
	free_flame_ctl(qw.fctl);
	qw.fctl = 0;
}

void
VgbQueryIndicate::destroy_do_out_of_lock(VObject * nmp)
{
VgbFlameRadarStatus r_sts;
	if ( qw.flame ) {
		r_sts.event_handler = 0;
		r_sts.eh_user_arg = 0;
		qw.flame->set_radar_status(&r_sts,VSF_FLAME_R_EVENT_HANDLER);
		qw.flame = 0;
	}
}

void
VgbQueryIndicate::redraw(VRect * rect) const
{
}

VExError
VgbQueryIndicate::get_queryindicate_status(
		VgbQueryIndicateStatus * sts,
		int flags) const
{
	VM_OP_START_EX
	if ( flags & VSF_QINDICATE_QTH_GET ) {
		sts->qth_get = copy_out_qind_thread(qw.qind_th,(int)sts->qth_focused);
		flags &= ~VSF_QINDICATE_QTH_GET;
	}
	if ( flags & VSF_QINDICATE_NEW_BUTTON ) {
		sts->new_button = qw.new_button;
		flags &= ~VSF_QINDICATE_NEW_BUTTON;
	}
	if ( flags & VSF_QINDICATE_DEL_BUTTON ) {
		sts->del_button = qw.del_button;
		flags &= ~VSF_QINDICATE_DEL_BUTTON;
	}
	if ( flags & VSF_QINDICATE_EDIT_BUTTON ) {
		sts->edit_button = qw.edit_button;
		flags &= ~VSF_QINDICATE_EDIT_BUTTON;
	}
	if ( flags & VSF_QINDICATE_FLAME ) {
		sts->flame = qw.flame;
		flags &= ~VSF_QINDICATE_FLAME;
	}
	VM_OP_END
	return initial_VExError(V_ER_NO_ERR,flags,0);
}

void
VgbQueryIndicate::
_exec_flame_ctl(VgbFlameStandard * f,FLAME_CTL * fc)
{
FLAME_CTL * fc1;
VgbFlameRadarStatus r_sts;
QUERY_THREAD * qth;
int flags;
	if ( f == 0 )
		goto end;
	for ( fc1 = fc ; fc1 ; fc1 = fc1->next ) {
		if ( fc1->op != FC_DELETE )
			continue;
		r_sts.delete_byno = fc1->id;
		f->set_radar_status(&r_sts,VSF_FLAME_R_QUERY_DELETE_BYNO);
	}
	r_sts.query_set = 0;
	r_sts.query_insert = 0;
	flags = 0;

	_VM_OP_START_VOID
	for ( fc1 = fc ; fc1 ; fc1 = fc1->next ) {
		switch ( fc1->op ) {
		case FC_SET:
			qth = (QUERY_THREAD*)d_alloc(sizeof(*qth));
			duplicate_q_thread(qth,fc1->qth);
			qth->next = r_sts.query_set;
			r_sts.query_set = qth;
			flags |= VSF_FLAME_R_QUERY_SET;
			break;
		case FC_INSERT:
			qth = (QUERY_THREAD*)d_alloc(sizeof(*qth));
			duplicate_q_thread(qth,fc1->qth);
			qth->next = r_sts.query_insert;
			r_sts.query_insert = qth;
			flags |= VSF_FLAME_R_QUERY_INSERT;
			break;
		}
	}
	VM_OP_END

	if ( flags ) {
		f->set_radar_status(&r_sts,flags);
		free_query_thread(r_sts.query_set);
		free_query_thread(r_sts.query_insert);
	}

end:
	free_flame_ctl(fc);
}

VExError
VgbQueryIndicate::set_queryindicate_status(
		const VgbQueryIndicateStatus * _sts,
		int flags)
{
QUERY_THREAD * qt;
VObjectStatus v_sts;
QIND_THREAD ** qtt;
VgbFlameRadarStatus r_sts;
VButton * n,* d,* e;
VgbFlameStandard * f,* d_f;
FLAME_CTL * fc;
	VM_OP_START_EX
	n = d = e = 0;
	f = 0;
	d_f = 0;
	if ( flags & VSF_QINDICATE_QTH_SET ) {
		insert_qind_thread(&sts,&qw,_sts->qth_set,_sts->qth_focused);
		flags &= ~VSF_QINDICATE_QTH_GET;
	}
	if ( flags & VSF_QINDICATE_QTH_DELETE ) {
		if ( _sts->qth_focused ) {
			for ( qtt = &qw.qind_th ; *qtt ; ) {
				if ( qth_check_focused(*qtt) ) {
					delete_qind_thread(&qw,(*qtt)->qth->id);
				}
				else {
					qtt = &(*qtt)->next;
				}
			}
		}
		else {
			for ( qt = _sts->qth_delete ; qt ; qt = qt->next ) {
				delete_qind_thread(&qw,qt->id);
			}
		}
		flags &= ~VSF_QINDICATE_QTH_GET;
	}
	if ( flags & VSF_QINDICATE_QTH_REPLACE ) {
		for (  ; qw.qind_th ; )
			delete_qind_thread(&qw,qw.qind_th->qth->id);
		insert_qind_thread(&sts,&qw,_sts->qth_replace,0);
		flags &= ~VSF_QINDICATE_QTH_GET;
	}
	if ( flags & VSF_QINDICATE_EYE ) {
		qw.eye_imgs[0] = v_get_image_element(_sts->eye,
							_sts->eye_elr[0]);
		qw.eye_imgs[1] = v_get_image_element(_sts->eye,
							_sts->eye_elr[1]);
		set_qind_eye(&qw);
	}
	if ( flags & VSF_QINDICATE_NEW_BUTTON ) {
		flags &= ~VSF_QINDICATE_NEW_BUTTON;
		n = qw.new_button = _sts->new_button;
	}
	if ( flags & VSF_QINDICATE_DEL_BUTTON ) {
		flags &= ~VSF_QINDICATE_DEL_BUTTON;
		d = qw.del_button = _sts->del_button;
	}
	if ( flags & VSF_QINDICATE_EDIT_BUTTON ) {
		flags &= ~VSF_QINDICATE_EDIT_BUTTON;
		e = qw.edit_button = _sts->edit_button;
	}
	if ( flags & VSF_QINDICATE_FLAME ) {
		if ( qw.flame ) {
			qw.from_flame ++;
			for (  ; qw.qind_th ; )
				delete_qind_thread(&qw,qw.qind_th->qth->id);
			qw.from_flame --;
			d_f = qw.flame;
		}
		f = qw.flame = _sts->flame;
		flags &= ~VSF_QINDICATE_FLAME;
	}
	if ( flags & VSF_QINDICATE_EDIT_EVENT ) {
		qw.edit_event = copy_vsat(_sts->edit_event);
		insert_vsat_list(qw.edit_event);
		flags &= ~VSF_QINDICATE_EDIT_EVENT;
	}
	fc = qw.fctl;
	qw.fctl = 0;
	VM_OP_END
	if ( n ) {
		v_sts.value_event_handler = qind_new_handler;
		v_sts.value_eh_arg = (void*)this;
		n->set_status(&v_sts,VSF_VALUE_EH);
	}
	if ( d ) {
		v_sts.value_event_handler = qind_del_handler;
		v_sts.value_eh_arg = (void*)this;
		d->set_status(&v_sts,VSF_VALUE_EH);
	}
	if ( e ) {
		v_sts.value_event_handler = qind_edit_handler;
		v_sts.value_eh_arg = (void*)this;
		e->set_status(&v_sts,VSF_VALUE_EH);
	}
	if ( d_f ) {
		r_sts.event_handler = 0;
		r_sts.eh_user_arg = 0;
		d_f->set_radar_status(&r_sts,VSF_FLAME_R_EVENT_HANDLER);
	}
	if ( f ) {
		f->get_radar_status(&r_sts,VSF_FLAME_R_QUERY_GET);
		VM_OP_START_EX
		qw.from_flame ++;
		insert_qind_thread(&sts,&qw,r_sts.result_query,0);
		free_query_thread(r_sts.result_query);
		qw.from_flame --;
		VM_OP_END
		r_sts.event_handler = qind_event_handler;
		r_sts.eh_user_arg = (void*)this;
		f->set_radar_status(&r_sts,VSF_FLAME_R_EVENT_HANDLER);
	}
	if ( fc )
		_exec_flame_ctl(qw.flame,fc);
	return initial_VExError(V_ER_NO_ERR,flags,0);
}


VgbQueryIndicate::~VgbQueryIndicate()
{
}


VExError
VgbQueryIndicate::set_status(const VObjectStatus * s,int flags)
{
VExError ret;
VButton * b;
	ret = VMacro::set_status(s, flags);
	if ( ret.code )
		goto end;
	if ( flags & VSF_ENABLED ) {
		b = qw.new_button;
		if ( b ) {
			ret = b->set_status(s,VSF_ENABLED);
			if ( ret.code )
				return ret;
		}
		b = qw.del_button;
		if ( b ) {
			ret = b->set_status(s,VSF_ENABLED);
			if ( ret.code )
				return ret;
		}
		b = qw.edit_button;
		if ( b ) {
			ret = b->set_status(s,VSF_ENABLED);
			if ( ret.code )
				return ret;
		}
	}
end:
	return ret;
}

VExError
VgbQueryIndicate::get_status(VObjectStatus * s,int flags) const
{
	return VMacro::get_status(s,flags);
}




void
free_VgbQueryIndicateStatus(VgbQueryIndicateStatus * q_sts)
{
	if ( q_sts->qth_get )
		free_query_thread(q_sts->qth_get);
	if ( q_sts->qth_set )
		free_query_thread(q_sts->qth_set);
	if ( q_sts->qth_delete )
		free_query_thread(q_sts->qth_delete);
	if ( q_sts->qth_replace )
		free_query_thread(q_sts->qth_replace);
	if ( q_sts->qth_reset_focus )
		free_query_thread(q_sts->qth_reset_focus);
	if ( q_sts->eye )
		v_image_unref(q_sts->eye);
	if ( q_sts->edit_event )
		free_VSysArgTranslator(VFLT_DELETE,(void*)q_sts->edit_event);
}





// ============= VdataQThread ==============


VIM VIM_VdataQThread = { &VIM_VdataXL , VDT_NONE };


XL_SEXP *
q_thread_regulation(XL_SEXP*);

XL_SEXP *
q_thread_regulation(XL_SEXP* s)
{
XL_SEXP * p;

	if ( get_type(s) != XLT_PAIR )
		return s;
	if ( get_type(cdr(s)) )
		return s;
	p = car(s);
	switch ( get_type(p) ) {
	case XLT_SYMBOL:
		return s;
	case XLT_PAIR:
		return q_thread_regulation(p);
	default:
		return s;
	}
}


VdataQThread::VdataQThread(const L_CHAR *lstr,int * erp,bool valid)
	: VdataXL((char*)0,0,0)
{
VdataXL * xl;
QUERY_THREAD * q;
	if ( !valid )
		return;
	vdata_type = &VIM_VdataQThread;
	xl = new VdataXL(lstr,&err);
	if ( err < 0 ) {
		if ( erp )
			*erp = err;
		return;
	}
	q = sexp_to_q_thread(q_thread_regulation(xl->get_VdataXL()));
	if ( q == 0 ) {
		err = -1;
		if ( erp )
			*erp = err;
		return;
	}
	mData = q;
	size = 0;
	err = 0;
	if ( erp )
		*erp = 0;
	return;
}


VdataQThread::VdataQThread(const char *str,int * erp,bool valid)
	: VdataXL((char*)0,0,0)
{
VdataXL * xl;
QUERY_THREAD * q;
	if ( !valid )
		return;
	vdata_type = &VIM_VdataQThread;
	xl = new VdataXL(str,&err);
	if ( err < 0 ) {
		if ( erp )
			*erp = err;
		return;
	}
	q = sexp_to_q_thread(q_thread_regulation(xl->get_VdataXL()));
	if ( q == 0 ) {
		err = -1;
		return;
	}
	mData = q;
	size = 0;
	err = 0;
	if ( erp )
		*erp = 0;
	return;
}

VdataQThread::VdataQThread(const XL_SEXP * s,int * erp,bool valid)
	: VdataXL((char*)0,0,0)
{
QUERY_THREAD * q;
	if ( !valid )
		return;
	vdata_type = &VIM_VdataQThread;
	q = sexp_to_q_thread(q_thread_regulation((XL_SEXP*)s));
	if ( q == 0 ) {
		err = -1;
		if ( erp )
			*erp = err;
		return;
	}
	mData = q;
	size = 0;
	err = 0;
	if ( erp )
		*erp = 0;
	return;
}

VdataQThread::VdataQThread(const QUERY_THREAD * qt,int * erp,bool valid)
	: VdataXL((char*)0,0,0)
{
QUERY_THREAD * ret, ** p;
QUERY_THREAD * q,* r;
	if ( !valid )
		return;
	vdata_type = &VIM_VdataQThread;
	if ( qt == 0 ) {
		err = -1;
		if ( erp )
			*erp = err;
		return;
	}
	ret = 0;
	p = &ret;
	for ( q = (QUERY_THREAD*)qt; q ; q = q->next ) {
		r = (QUERY_THREAD*)d_alloc(sizeof(*r));
		memset(r,0,sizeof(*r));
		_copy_q_thread(r,q);
		*p = r;
		p = &r->next;
	}
	mData = ret;
	size = 0;
	err = 0;
	if ( erp )
		*erp = 0;
	return;
}

VdataQThread::VdataQThread(Vdata * d,int * erp,bool valid)
	: VdataXL((char*)0,0)
{
VIM * v;
VdataXL * xl;
XL_SEXP * _xl;
VdataQThread * vqt;
	if ( !valid )
		return;
	err = 0;
	vdata_type = &VIM_VdataQThread;
	v = d->get_type();
	switch ( cmp_VIM(v,&VIM_VdataQThread) ) {
	case 0:
	case 1:
		mData = (void*)static_cast<VdataQThread*>(d)->get_VdataQThread(&err);
		break;
	case -1:
		xl = new VdataXL(d,&err);
		if ( err < 0 ) {
			if ( erp )
				*erp = err;
			delete xl;
			return;
		}
		_xl = xl->get_VdataXL();
		delete xl;
		vqt = new VdataQThread(_xl);
		mData = vqt->get_VdataQThread(&err);
		if ( err < 0 ) {
			if ( erp )
				*erp = err;
			return;
		}
		break;
	default:
		err = -1;
		break;
	}
	if ( erp )
		*erp = err;
	if ( err < 0 )
		return;
	err = 0;
}

VdataQThread::~VdataQThread()
{
	if ( this->get_type() != &VIM_VdataXL )
		return;
	if ( mData ) {
		free_query_thread((QUERY_THREAD*)mData);
	}
}

char*
VdataQThread::get_VdataString(int * erp)
{
XL_SEXP * xl;
VdataXL * _xl;
char * ret;
	if ( err < 0 ) {
		if ( erp )
			*erp = err;
		return 0;
	}
	xl = q_thread_to_sexp((QUERY_THREAD*)mData,QTH_MAXIMUM_INFO);
	_xl = new VdataXL(xl);
	ret = _xl->get_VdataString();
	delete _xl;
	if ( erp )
		*erp = 0;
	return ret;
}

L_CHAR*
VdataQThread::get_VdataLString(int * erp)
{
XL_SEXP * xl;
VdataXL * _xl;
L_CHAR * ret;
	if ( err < 0 ) {
		if ( erp )
			*erp = err;
		return 0;
	}
	xl = q_thread_to_sexp((QUERY_THREAD*)mData,QTH_MAXIMUM_INFO);
	_xl = new VdataXL(xl);
	ret = _xl->get_VdataLString();
	delete _xl;
	if ( erp )
		*erp = 0;
	return ret;
}

XL_SEXP*
VdataQThread::get_VdataXL(int * erp)
{
	if ( erp )
		*erp = 0;
	return q_thread_to_sexp((QUERY_THREAD*)mData,QTH_MAXIMUM_INFO);
}

QUERY_THREAD*
VdataQThread::get_VdataQThread(int * erp)
{
QUERY_THREAD * ret, ** p;
QUERY_THREAD * q,* r;
	if ( err < 0 ) {
		if ( erp )
			*erp = err;
		return 0;
	}
	ret = 0;
	p = &ret;
	for ( q = (QUERY_THREAD*)mData; q ; q = q->next ) {
		r = (QUERY_THREAD*)d_alloc(sizeof(*r));
		memset(r,0,sizeof(*r));
		_copy_q_thread(r,q);
		*p = r;
		p = &r->next;
	}
	if ( erp )
		*erp = 0;
	return ret;
}

bool
VdataQThread::clipboard_available(bool lock_flag)
{
Vdata * d;
VdataXL * d2;
int er;
bool ret;
ClipBoardList * c;
	if ( lock_flag )
		lock_task(cb_lock);
	ret = false;
	d2 = static_cast<VdataXL*>(check_clipboard_variation(&VIM_VdataQThread));
	if ( d2 ) {
		ret = true;
		goto end;
	}
	c = get_clipboard();
	if ( c == 0 )
		goto end;
	d = c->target;
	if ( d == 0 )
		goto end;
	d2 = new VdataQThread(d,&er);
	if ( er < 0 )
		goto end;
	insert_clipboard_variation(c,d2);
	ret = true;
end:
	if ( lock_flag )
		unlock_task(cb_lock,"new_from_clipboard");
	return ret;
}

VdataQThread * 
VdataQThread::new_from_clipboard()
{
VdataQThread * ret;
	lock_task(cb_lock);
	if ( VdataQThread::clipboard_available(false) )
		ret = static_cast<VdataQThread*>(delete_clipboard_variation(&VIM_VdataQThread));
	else	ret = 0;
	unlock_task(cb_lock,"new_from_clipboard");
	return ret;
}


