<commit_before>#include "expr.h"
#include "lit.h"
#include "asm.h"
#include "lex.h"
#include "token.h"
#include "parse.h"
#include "stdfunc.h"
#include "util.h"
#include "library.h"
#include "var.h"
#include "func.h"

int Parser::is_string_tok() { return tok.get().type == TOK_STRING; }
int Parser::is_number_tok() { return tok.get().type == TOK_NUMBER; }
int Parser::is_ident_tok()  { return tok.get().type == TOK_IDENT;  }
int Parser::is_char_tok() { return tok.get().type == TOK_CHAR; }

ExprType Parser::expr_entry() {
	ExprType et;
	expr_compare(et);
	return et;
}

int Parser::expr_compare(ExprType &et) {
	int andop=0, orop=0;
	expr_logic(et);
	while((andop=tok.skip("and") || tok.skip("&")) || (orop=tok.skip("or") ||
				tok.skip("|")) || tok.skip("xor") || tok.skip("^")) {
		ntv.genas("push eax");
		expr_logic(et);
		ntv.genas("mov ebx eax");
		ntv.genas("pop eax");
		ntv.gencode(andop ? 0x21 : orop ? 0x09 : 0x31); ntv.gencode(0xd8); // and eax ebx
	}

	return 0;
}

int Parser::expr_logic(ExprType &et) {
	int32_t lt=0, gt=0, ne=0, eql=0, fle=0;
	expr_add_sub(et);
	if((lt=tok.skip("<")) || (gt=tok.skip(">")) || (ne=tok.skip("!=")) ||
			(eql=tok.skip("==")) || (fle=tok.skip("<=")) || tok.skip(">=")) {
		ntv.genas("push eax");
		expr_add_sub(et);
		ntv.genas("mov ebx eax");
		ntv.genas("pop eax");
		ntv.gencode(0x39); ntv.gencode(0xd8); // cmp %eax, %ebx
		/*
		 * < setl 0x9c
		 * > setg 0x9f
		 * <= setle 0x9e
		 * >= setge 0x9d
		 * == sete 0x94
		 * != setne 0x95
		 */
		ntv.gencode(0x0f); ntv.gencode(lt ? 0x9c : gt ? 0x9f : ne ? 0x95 : eql ? 0x94 : fle ? 0x9e : 0x9d); ntv.gencode(0xc0); // setX al
		ntv.gencode(0x0f); ntv.gencode(0xb6); ntv.gencode(0xc0); // movzx eax al
	}

	return 0;
}

int Parser::expr_add_sub(ExprType &et) {
	int add = 0, concat = 0;
	expr_mul_div(et);
	while((add = tok.skip("+")) || (concat = tok.skip("~")) || tok.skip("-")) {
		ntv.genas("push eax");
		expr_mul_div(et);
		ntv.genas("mov ebx eax");  // mov %ebx %eax
		ntv.genas("pop eax");
		if(add) { ntv.genas("add eax ebx"); }// add %eax %ebx
		else if(concat) {
			// ntv.gencode(0x89); ntv.gencode(0x04); ntv.gencode(0x24);
			// ntv.gencode(0x89); ntv.gencode(0x5c); ntv.gencode(0x24); ntv.gencode(0xfc);
			ntv.genas("push ebx");
			ntv.genas("push eax");
			ntv.gencode(0xff); ntv.gencode(0x56); ntv.gencode(56); // call rea_concat
			ntv.genas("add esp 8");
		} else { ntv.genas("sub eax ebx"); } // sub %eax %ebx
	}
	return 0;
}

int Parser::expr_mul_div(ExprType &et) {
	int mul, div;
	expr_primary(et);
	while((mul = tok.skip("*")) || (div=tok.skip("/")) || tok.skip("%")) {
		ntv.genas("push eax");
		expr_primary(et);
		ntv.genas("mov ebx eax"); // mov %ebx %eax
		ntv.genas("pop eax");
		if(mul) {
			ntv.genas("mul ebx");
		} else if(div) {
			ntv.genas("mov edx 0");
			ntv.genas("div ebx");
		} else { //mod
			ntv.genas("mov edx 0");
			ntv.genas("div ebx");
			ntv.genas("mov eax edx");
		}
	}
	return 0;
}

int Parser::expr_primary(ExprType &et) {
	int is_get_addr = 0, ispare = 0;
	std::string name, mod_name = "";
	var_t *v;

	if(tok.skip("&")) is_get_addr = 1;

	if(is_number_tok()) {

		ntv.genas("mov eax %d", atoi(tok.next().val.c_str()));
		et.change(T_INT);

	} else if(is_char_tok()) {

		ntv.genas("mov eax %d", (int)tok.next().val[0]);
		et.change(T_INT);

	} else if(is_string_tok()) {

		ntv.gencode(0xb8);
		char *embed = (char *)malloc(tok.get().val.length() + 1);
		strcpy(embed, tok.next().val.c_str());
		replaceEscape(embed);
		ntv.gencode_int32((uint32_t)embed); // mov eax string_address

		et.change(T_STRING);

	} else if(is_ident_tok()) { // variable or inc or dec

		name = tok.get().val; mod_name = "";

		if(tok.is(":", 1)) { // module?
			mod_name = tok.next().val;
			tok.skip(":");
			name = tok.get().val;
		}

		if(is_asgmt()) {

			asgmt();

		} else {

			SKIP_TOK;

			if((ispare = tok.skip("(")) || is_stdfunc(name, mod_name) ||
					funcs.is(name, mod_name) || funcs.is(name, module) || lib_list.is(mod_name)) { // Function?

				if(lib_list.is(mod_name)) { // library function
					if(HAS_PARAMS_FUNC) {
						for(int i = 0; !tok.is(")") && !tok.skip(";"); i++) {
							expr_entry();
							ntv.gencode(0x89); ntv.gencode(0x44); ntv.gencode(0x24); ntv.gencode(i * ADDR_SIZE); // mov [esp+ADDR*i], eax
							tok.skip(",");
						}
					}
					ntv.gencode(0xe8); ntv.gencode_int32(lib_list.call(name, mod_name) - (uint32_t)&ntv.code[ntv.count] - ADDR_SIZE); // call func
				} else if(is_stdfunc(name, mod_name)) {

					make_stdfunc(name, mod_name);

				} else if(funcs.get(name, mod_name) || funcs.get(name, module) || ispare) {	// user function

					func_t *function = funcs.get(name, mod_name);
					if(function == NULL)
						function = funcs.get(name, module);
					if(function == NULL) { // undefined
						size_t params = 0;
						if(HAS_PARAMS_FUNC) { // has arg?
							for(params = 0; !tok.is(")") && !tok.skip(";"); params++) {
								expr_entry();
								ntv.genas("push eax");
								tok.skip(",");
							}
						}
						ntv.gencode(0xe8); undef_funcs.append_undef(name, module == "" ? mod_name : module, ntv.count);
						ntv.gencode_int32(0x00000000); // call func
						ntv.genas("add esp %d", params * ADDR_SIZE);

					} else { // defined
						if(HAS_PARAMS_FUNC) {
							for(size_t i = 0; i < function->params; i++) {
								expr_entry();
								ntv.genas("push eax");
								if(!tok.skip(",") && function->params - 1 != i)
									error("error: %d: expected ','", tok.get().nline);
							}
						}
						ntv.gencode(0xe8); ntv.gencode_int32(0xFFFFFFFF - (ntv.count - function->address) - 3); // call func
						ntv.genas("add esp %d", function->params * ADDR_SIZE);
					}
				}

				if(ispare)
					if(!tok.skip(")"))
						error("func: error: %d: expected expression ')'", tok.tok[tok.pos].nline);
				et.change(T_INT);
			} else { // single variable

				v = var.get(name, mod_name);
				if(v == NULL)
					v = var.get(name, module);
				if(v == NULL)
					error("var: error: %d: '%s' was not declare", tok.tok[tok.pos].nline, name.c_str());
				if(v->loctype == V_LOCAL) {
					ntv.gencode(0x8b); ntv.gencode(0x45);
					ntv.gencode(256 - ADDR_SIZE * v->id); // mov eax variable
				} else if(v->loctype == V_GLOBAL) {
					ntv.gencode(0xa1); ntv.gencode_int32(v->id); // mov eax GLOBAL_ADDR
				}
				et.change(v->type);
			}
		}
	} else if(tok.skip("(")) {
		if(is_asgmt()) asgmt(); else expr_entry();
		if(!tok.skip(")"))
			error("error: %d: expected expression ')'", tok.get().nline);
	} else if(!make_array(et)) error("error: %d: invalid expression", tok.get().nline);

	if(tok.skip(".")) {
		name = tok.next().val;
		func_t *function = funcs.get(name, mod_name);
		if(function == NULL)
			function = funcs.get(name, module);
		if(function == NULL) error("function not found");
		ntv.genas("push eax");
		if(HAS_PARAMS_FUNC) {
			for(size_t i = 0; i < function->params - 1; i++) {
				expr_entry();
				ntv.genas("push eax");
				tok.skip(",");
			}
		} tok.skip(")");
		ntv.gencode(0xe8); ntv.gencode_int32(0xFFFFFFFF - (ntv.count - function->address) - 3); // call func
		ntv.genas("add esp %d", function->params * ADDR_SIZE + ADDR_SIZE);
	}

	while(is_index()) make_index(et);
	return 0;
}

int Parser::is_index() {
	if(tok.is("[")) {
		return 1;
	}
	return 0;
}

int Parser::make_index(ExprType &et) {
	ntv.genas("mov edx eax");
	tok.skip("["); expr_entry(); tok.skip("]");
	ntv.genas("mov ecx eax");
	if(et.is_array()) { // TODO: create ExprType::is
		ntv.gencode(0x8b); ntv.gencode(0x04); ntv.gencode(0x8a);// mov eax, [edx + ecx * 4]
		if(et.is_type(T_INT)) et.change(T_INT);
		else if(et.is_type(T_STRING)) et.change(T_STRING);
	} else if(et.is_type(T_STRING)) {
		ntv.gencode(0x0f); ntv.gencode(0xb6); ntv.gencode(0x04); ntv.gencode(0x0a);// movzx eax, [edx + ecx]
		et.change(T_INT); // TODO: create type "char"
	}
	return 0;
}

int Parser::make_array(ExprType &et) {
	if(tok.skip("[")) {
		int elems = 0, pos = tok.pos;
		{ // count elements
			int pare = 1;
			while(pare) {
				if(tok.at(pos).val == "[") pare++;
				if(tok.at(pos).val == "]") pare--;
				if(tok.at(pos++).val == "," && pare == 1) elems++;
			} elems++;
		}
		{ // allocate memory
			ntv.genas("mov eax %d", elems * ADDR_SIZE + ADDR_SIZE);
			ntv.gencode(0x89); ntv.gencode(0x04); ntv.gencode(0x24); // mov [esp], eax
			ntv.gencode(0xff); ntv.gencode(0x56); ntv.gencode(12); // call malloc
			ntv.genas("push eax");
			ntv.gencode(0x89); ntv.gencode(0x04); ntv.gencode(0x24); // mov [esp], eax
			ntv.gencode(0xff); ntv.gencode(0x56); ntv.gencode(20); // call append_addr
		} // stack top is allocated address
		ExprType elem_type;
		for(int elem = 0; elem < elems; elem++)  {
			elem_type = expr_entry();
			ntv.genas("pop ecx"); // mem address
			ntv.genas("mov edx %d", elem);
			ntv.gencode(0x89); ntv.gencode(0x04); ntv.gencode(0x91); // mov [ecx+edx*4], eax
			ntv.genas("push ecx");
			if(elem < elems - 1) tok.skip(",");
		}
		et.change(elem_type.get().type | T_ARRAY); // TODO: refactoring
		ntv.genas("pop eax");
		tok.skip("]");
		return 1;
	} else return 0;
}

<commit_msg>bug fix<commit_after>#include "expr.h"
#include "lit.h"
#include "asm.h"
#include "lex.h"
#include "token.h"
#include "parse.h"
#include "stdfunc.h"
#include "util.h"
#include "library.h"
#include "var.h"
#include "func.h"

int Parser::is_string_tok() { return tok.get().type == TOK_STRING; }
int Parser::is_number_tok() { return tok.get().type == TOK_NUMBER; }
int Parser::is_ident_tok()  { return tok.get().type == TOK_IDENT;  }
int Parser::is_char_tok() { return tok.get().type == TOK_CHAR; }

ExprType Parser::expr_entry() {
	ExprType et;
	expr_compare(et);
	return et;
}

int Parser::expr_compare(ExprType &et) {
	int andop=0, orop=0;
	expr_logic(et);
	while((andop=tok.skip("and") || tok.skip("&")) || (orop=tok.skip("or") ||
				tok.skip("|")) || tok.skip("xor") || tok.skip("^")) {
		ntv.genas("push eax");
		expr_logic(et);
		ntv.genas("mov ebx eax");
		ntv.genas("pop eax");
		ntv.gencode(andop ? 0x21 : orop ? 0x09 : 0x31); ntv.gencode(0xd8); // and eax ebx
	}

	return 0;
}

int Parser::expr_logic(ExprType &et) {
	int32_t lt=0, gt=0, ne=0, eql=0, fle=0;
	expr_add_sub(et);
	if((lt=tok.skip("<")) || (gt=tok.skip(">")) || (ne=tok.skip("!=")) ||
			(eql=tok.skip("==")) || (fle=tok.skip("<=")) || tok.skip(">=")) {
		ntv.genas("push eax");
		expr_add_sub(et);
		ntv.genas("mov ebx eax");
		ntv.genas("pop eax");
		ntv.gencode(0x39); ntv.gencode(0xd8); // cmp %eax, %ebx
		/*
		 * < setl 0x9c
		 * > setg 0x9f
		 * <= setle 0x9e
		 * >= setge 0x9d
		 * == sete 0x94
		 * != setne 0x95
		 */
		ntv.gencode(0x0f); ntv.gencode(lt ? 0x9c : gt ? 0x9f : ne ? 0x95 : eql ? 0x94 : fle ? 0x9e : 0x9d); ntv.gencode(0xc0); // setX al
		ntv.gencode(0x0f); ntv.gencode(0xb6); ntv.gencode(0xc0); // movzx eax al
	}

	return 0;
}

int Parser::expr_add_sub(ExprType &et) {
	int add = 0, concat = 0;
	expr_mul_div(et);
	while((add = tok.skip("+")) || (concat = tok.skip("~")) || tok.skip("-")) {
		ntv.genas("push eax");
		expr_mul_div(et);
		ntv.genas("mov ebx eax");  // mov %ebx %eax
		ntv.genas("pop eax");
		if(add) { ntv.genas("add eax ebx"); }// add %eax %ebx
		else if(concat) {
			// ntv.gencode(0x89); ntv.gencode(0x04); ntv.gencode(0x24);
			// ntv.gencode(0x89); ntv.gencode(0x5c); ntv.gencode(0x24); ntv.gencode(0xfc);
			ntv.genas("push ebx");
			ntv.genas("push eax");
			ntv.gencode(0xff); ntv.gencode(0x56); ntv.gencode(56); // call rea_concat
			ntv.genas("add esp 8");
		} else { ntv.genas("sub eax ebx"); } // sub %eax %ebx
	}
	return 0;
}

int Parser::expr_mul_div(ExprType &et) {
	int mul, div;
	expr_primary(et);
	while((mul = tok.skip("*")) || (div=tok.skip("/")) || tok.skip("%")) {
		ntv.genas("push eax");
		expr_primary(et);
		ntv.genas("mov ebx eax"); // mov %ebx %eax
		ntv.genas("pop eax");
		if(mul) {
			ntv.genas("mul ebx");
		} else if(div) {
			ntv.genas("mov edx 0");
			ntv.genas("div ebx");
		} else { //mod
			ntv.genas("mov edx 0");
			ntv.genas("div ebx");
			ntv.genas("mov eax edx");
		}
	}
	return 0;
}

int Parser::expr_primary(ExprType &et) {
	int is_get_addr = 0, ispare = 0;
	std::string name, mod_name = "";
	var_t *v;

	if(tok.skip("&")) is_get_addr = 1;

	if(is_number_tok()) {

		ntv.genas("mov eax %d", atoi(tok.next().val.c_str()));
		et.change(T_INT);

	} else if(is_char_tok()) {

		ntv.genas("mov eax %d", (int)tok.next().val[0]);
		et.change(T_INT);

	} else if(is_string_tok()) {

		ntv.gencode(0xb8);
		char *embed = (char *)malloc(tok.get().val.length() + 1);
		strcpy(embed, tok.next().val.c_str());
		replaceEscape(embed);
		ntv.gencode_int32((uint32_t)embed); // mov eax string_address

		et.change(T_STRING);

	} else if(is_ident_tok()) { // variable or inc or dec

		name = tok.get().val; mod_name = "";

		if(tok.is(":", 1)) { // module?
			mod_name = tok.next().val;
			tok.skip(":");
			name = tok.get().val;
		}

		if(is_asgmt()) {

			asgmt();

		} else {

			SKIP_TOK;

			if((ispare = tok.skip("(")) || is_stdfunc(name, mod_name) ||
					funcs.is(name, mod_name) || funcs.is(name, module) || lib_list.is(mod_name)) { // Function?

				if(lib_list.is(mod_name)) { // library function
					if(HAS_PARAMS_FUNC) {
						for(int i = 0; !tok.is(")") && !tok.skip(";"); i++) {
							expr_entry();
							ntv.gencode(0x89); ntv.gencode(0x44); ntv.gencode(0x24); ntv.gencode(i * ADDR_SIZE); // mov [esp+ADDR*i], eax
							tok.skip(",");
						}
					}
					ntv.gencode(0xe8); ntv.gencode_int32(lib_list.call(name, mod_name) - (uint32_t)&ntv.code[ntv.count] - ADDR_SIZE); // call func
				} else if(is_stdfunc(name, mod_name)) {

					make_stdfunc(name, mod_name);

				} else if(funcs.get(name, mod_name) || funcs.get(name, module) || ispare) {	// user function

					func_t *function = funcs.get(name, mod_name);
					if(function == NULL)
						function = funcs.get(name, module);
					if(function == NULL) { // undefined
						size_t params = 0;
						if(HAS_PARAMS_FUNC) { // has arg?
							for(params = 0; !tok.is(")") && !tok.skip(";"); params++) {
								expr_entry();
								ntv.genas("push eax");
								tok.skip(",");
							}
						}
						ntv.gencode(0xe8); undef_funcs.append_undef(name, module == "" ? mod_name : module, ntv.count);
						ntv.gencode_int32(0x00000000); // call func
						ntv.genas("add esp %d", params * ADDR_SIZE);

					} else { // defined
						if(HAS_PARAMS_FUNC) {
							for(size_t i = 0; i < function->params; i++) {
								expr_entry();
								ntv.genas("push eax");
								if(!tok.skip(",") && function->params - 1 != i)
									error("error: %d: expected ','", tok.get().nline);
							}
						}
						ntv.gencode(0xe8); ntv.gencode_int32(0xFFFFFFFF - (ntv.count - function->address) - 3); // call func
						ntv.genas("add esp %d", function->params * ADDR_SIZE);
					}
				}

				if(ispare)
					if(!tok.skip(")"))
						error("func: error: %d: expected expression ')'", tok.tok[tok.pos].nline);
				et.change(T_INT);
			} else { // single variable

				v = var.get(name, mod_name);
				if(v == NULL)
					v = var.get(name, module);
				if(v == NULL)
					error("var: error: %d: '%s' was not declare", tok.tok[tok.pos].nline, name.c_str());
				if(v->loctype == V_LOCAL) {
					ntv.gencode(0x8b); ntv.gencode(0x45);
					ntv.gencode(256 - ADDR_SIZE * v->id); // mov eax variable
				} else if(v->loctype == V_GLOBAL) {
					ntv.gencode(0xa1); ntv.gencode_int32(v->id); // mov eax GLOBAL_ADDR
				}
				et.change(v->type);
			}
		}
	} else if(tok.skip("(")) {
		if(is_asgmt()) asgmt(); else expr_entry();
		if(!tok.skip(")"))
			error("error: %d: expected expression ')'", tok.get().nline);
	} else if(!make_array(et)) error("error: %d: invalid expression", tok.get().nline);

	while(tok.skip(".")) {
		name = tok.next().val;
		func_t *function = funcs.get(name, mod_name);
		if(function == NULL)
			function = funcs.get(name, module);
		if(function == NULL) error("function not found");
		if(function->params > 0) ntv.genas("push eax");
		if(HAS_PARAMS_FUNC) {
			for(size_t i = 0; i < function->params - 1; i++) {
				expr_entry();
				ntv.genas("push eax");
				tok.skip(",");
			}
		} tok.skip(")");
		ntv.gencode(0xe8); ntv.gencode_int32(0xFFFFFFFF - (ntv.count - function->address) - 3); // call func
		ntv.genas("add esp %d", function->params * ADDR_SIZE);
	}

	while(is_index()) make_index(et);
	return 0;
}

int Parser::is_index() {
	if(tok.is("[")) {
		return 1;
	}
	return 0;
}

int Parser::make_index(ExprType &et) {
	ntv.genas("mov edx eax");
	tok.skip("["); expr_entry(); tok.skip("]");
	ntv.genas("mov ecx eax");
	if(et.is_array()) { // TODO: create ExprType::is
		ntv.gencode(0x8b); ntv.gencode(0x04); ntv.gencode(0x8a);// mov eax, [edx + ecx * 4]
		if(et.is_type(T_INT)) et.change(T_INT);
		else if(et.is_type(T_STRING)) et.change(T_STRING);
	} else if(et.is_type(T_STRING)) {
		ntv.gencode(0x0f); ntv.gencode(0xb6); ntv.gencode(0x04); ntv.gencode(0x0a);// movzx eax, [edx + ecx]
		et.change(T_INT); // TODO: create type "char"
	}
	return 0;
}

int Parser::make_array(ExprType &et) {
	if(tok.skip("[")) {
		int elems = 0, pos = tok.pos;
		{ // count elements
			int pare = 1;
			while(pare) {
				if(tok.at(pos).val == "[") pare++;
				if(tok.at(pos).val == "]") pare--;
				if(tok.at(pos++).val == "," && pare == 1) elems++;
			} elems++;
		}
		{ // allocate memory
			ntv.genas("mov eax %d", elems * ADDR_SIZE + ADDR_SIZE);
			ntv.gencode(0x89); ntv.gencode(0x04); ntv.gencode(0x24); // mov [esp], eax
			ntv.gencode(0xff); ntv.gencode(0x56); ntv.gencode(12); // call malloc
			ntv.genas("push eax");
			ntv.gencode(0x89); ntv.gencode(0x04); ntv.gencode(0x24); // mov [esp], eax
			ntv.gencode(0xff); ntv.gencode(0x56); ntv.gencode(20); // call append_addr
		} // stack top is allocated address
		ExprType elem_type;
		for(int elem = 0; elem < elems; elem++)  {
			elem_type = expr_entry();
			ntv.genas("pop ecx"); // mem address
			ntv.genas("mov edx %d", elem);
			ntv.gencode(0x89); ntv.gencode(0x04); ntv.gencode(0x91); // mov [ecx+edx*4], eax
			ntv.genas("push ecx");
			if(elem < elems - 1) tok.skip(",");
		}
		et.change(elem_type.get().type | T_ARRAY); // TODO: refactoring
		ntv.genas("pop eax");
		tok.skip("]");
		return 1;
	} else return 0;
}

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "oglplayer.hxx"
#include "oglframegrabber.hxx"
#include "oglwindow.hxx"

#include <cppuhelper/supportsservice.hxx>
#include <tools/stream.hxx>
#include <vcl/graph.hxx>
#include <vcl/graphicfilter.hxx>
#include <tools/urlobj.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>

using namespace com::sun::star;

namespace avmedia { namespace ogl {

OGLPlayer::OGLPlayer()
    : Player_BASE(m_aMutex)
    , m_pHandle(NULL)
{
}

OGLPlayer::~OGLPlayer()
{
    // Comment out while it causes segmentation fault
    // gltf_renderer_release(m_pHandle);
}

static bool lcl_LoadFile( glTFFile* io_pFile, const OUString& rURL)
{
    SvFileStream aStream( rURL, STREAM_READ );
    if( !aStream.IsOpen() )
        return false;

    const sal_Int64 nBytes = aStream.remainingSize();
    char* pBuffer = new char[nBytes];
    aStream.Read( pBuffer, nBytes );
    aStream.Close();

    io_pFile->buffer = pBuffer;
    io_pFile->size = nBytes;

    return true;
}

bool OGLPlayer::create( const OUString& rURL )
{
    m_sURL = rURL;

    // Load *.json file and init renderer
    glTFFile aJsonFile;
    aJsonFile.type = GLTF_JSON;
    OString sFileName = OUStringToOString(INetURLObject(m_sURL).GetLastName(),RTL_TEXTENCODING_UTF8);
    aJsonFile.filename = (char*)sFileName.getStr();
    if( !lcl_LoadFile(&aJsonFile, m_sURL) )
    {
        SAL_WARN("avmedia.opengl", "Can't load *.json file: " + sFileName);
        return false;
    }

    m_pHandle = gltf_renderer_init(&aJsonFile);

    if( !m_pHandle || !m_pHandle->files )
    {
        SAL_WARN("avmedia.opengl", "gltf_renderer_init returned an invalid glTFHandle");
        return false;
    }

    // Load external resources
    for( size_t i = 0; i < m_pHandle->size; ++i )
    {
        glTFFile* pFile = m_pHandle->files[i];
        if( pFile && pFile->filename )
        {
            const OUString sFilesURL =
                INetURLObject::GetAbsURL(m_sURL,OStringToOUString(OString(pFile->filename),RTL_TEXTENCODING_UTF8));
            if( pFile->type == GLTF_IMAGE )
            {
                // Load images as bitmaps
                GraphicFilter aFilter;
                Graphic aGraphic;
                aFilter.ImportGraphic(aGraphic, INetURLObject(sFilesURL));
                const BitmapEx aBitmapEx = aGraphic.GetBitmapEx();
                pFile->buffer = (char*)OpenGLHelper::ConvertBitmapExToRGBABuffer(aBitmapEx);
                pFile->imagewidth = aBitmapEx.GetSizePixel().Width();
                pFile->imageheight = aBitmapEx.GetSizePixel().Height();
            }
            else if( pFile->type == GLTF_BINARY || pFile->type == GLTF_GLSL )
            {
                if( !lcl_LoadFile(pFile, sFilesURL) )
                {
                    SAL_WARN("avmedia.opengl", "Can't load glTF file: " + sFilesURL);
                    return false;
                }
            }
        }
    }

    // Set timer
    m_aTimer.SetTimeout(10);
    m_aTimer.SetTimeoutHdl(LINK(this,OGLPlayer,TimerHandler));
    return true;
}

void SAL_CALL OGLPlayer::start() throw ( uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard(m_aMutex);
    gltf_animation_start(m_pHandle);
    m_aTimer.Start();
}

void SAL_CALL OGLPlayer::stop() throw ( uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard(m_aMutex);
    gltf_animation_stop(m_pHandle);
    m_aTimer.Stop();
}

sal_Bool SAL_CALL OGLPlayer::isPlaying() throw ( uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard(m_aMutex);
    return (sal_Bool)gltf_animation_is_playing(m_pHandle);
}

double SAL_CALL OGLPlayer::getDuration() throw ( uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard(m_aMutex);
    return gltf_animation_get_duration(m_pHandle);
}

void SAL_CALL OGLPlayer::setMediaTime( double fTime ) throw ( uno::RuntimeException, std::exception )
{
    // TODO: doesn't work, but cause problem in playing
    osl::MutexGuard aGuard(m_aMutex);
    //gltf_animation_set_time(m_pHandle, fTime);
}

double SAL_CALL OGLPlayer::getMediaTime() throw ( ::com::sun::star::uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard(m_aMutex);
    return gltf_animation_get_time(m_pHandle);
}

double SAL_CALL OGLPlayer::getRate() throw ( uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard(m_aMutex);
    // Seems unused
    return 1.0;
}

void SAL_CALL OGLPlayer::setPlaybackLoop( sal_Bool bSet ) throw ( uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard(m_aMutex);
    gltf_animation_set_looping(m_pHandle, (int)bSet);
}

sal_Bool SAL_CALL OGLPlayer::isPlaybackLoop() throw ( uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard(m_aMutex);
    return (sal_Bool)gltf_animation_get_looping(m_pHandle);
}

void SAL_CALL OGLPlayer::setVolumeDB( sal_Int16 /*nVolumDB*/ ) throw ( uno::RuntimeException, std::exception )
{
    // OpenGL models have no sound.
}

sal_Int16 SAL_CALL OGLPlayer::getVolumeDB() throw ( uno::RuntimeException, std::exception )
{
    // OpenGL models have no sound.
    return 0;
}

void SAL_CALL OGLPlayer::setMute( sal_Bool /*bSet*/ ) throw ( uno::RuntimeException, std::exception )
{
    // OpenGL models have no sound.
}

sal_Bool SAL_CALL OGLPlayer::isMute() throw ( uno::RuntimeException, std::exception )
{
    // OpenGL models have no sound.
    return false;
}

awt::Size SAL_CALL OGLPlayer::getPreferredPlayerWindowSize() throw ( uno::RuntimeException, std::exception )
{
    return awt::Size( 480, 360 );
}

uno::Reference< media::XPlayerWindow > SAL_CALL OGLPlayer::createPlayerWindow( const uno::Sequence< uno::Any >& rArguments )
     throw ( uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard( m_aMutex );

    assert( rArguments.getLength() >= 3 );

    sal_IntPtr pIntPtr = 0;
    rArguments[ 2 ] >>= pIntPtr;
    SystemChildWindow *pChildWindow = reinterpret_cast< SystemChildWindow* >( pIntPtr );

    if( !m_aContext.init(pChildWindow) )
    {
        SAL_WARN("avmedia.opengl", "Context initialization failed");
        return uno::Reference< media::XPlayerWindow >();
    }

    Size aSize = pChildWindow->GetSizePixel();
    m_aContext.setWinSize(aSize);
    m_pHandle->viewport.x = 0;
    m_pHandle->viewport.y = 0;
    m_pHandle->viewport.width = aSize.Width();
    m_pHandle->viewport.height = aSize.Height();
    gltf_renderer_set_content(m_pHandle);
    m_pOGLWindow = new OGLWindow(m_pHandle, &m_aContext, pChildWindow);
    return uno::Reference< media::XPlayerWindow >( m_pOGLWindow );
}

uno::Reference< media::XFrameGrabber > SAL_CALL OGLPlayer::createFrameGrabber()
     throw ( uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard(m_aMutex);

    if( !m_aContext.init() )
    {
        SAL_WARN("avmedia.opengl", "Offscreen context initialization failed");
        return uno::Reference< media::XFrameGrabber >();
    }

    m_pHandle->viewport.x = 0;
    m_pHandle->viewport.y = 0;
    m_pHandle->viewport.width = getPreferredPlayerWindowSize().Width;
    m_pHandle->viewport.height = getPreferredPlayerWindowSize().Height;
    gltf_renderer_set_content(m_pHandle);
    OGLFrameGrabber *pFrameGrabber = new OGLFrameGrabber( m_pHandle );
    return uno::Reference< media::XFrameGrabber >( pFrameGrabber );
}

OUString SAL_CALL OGLPlayer::getImplementationName()
     throw ( ::com::sun::star::uno::RuntimeException, std::exception )
{
    return OUString("com.sun.star.comp.avmedia.Player_OpenGL");
}

sal_Bool SAL_CALL OGLPlayer::supportsService( const OUString& rServiceName )
     throw ( uno::RuntimeException, std::exception )
{
    return cppu::supportsService(this, rServiceName);
}

uno::Sequence< OUString > SAL_CALL OGLPlayer::getSupportedServiceNames()
     throw ( uno::RuntimeException, std::exception )
{
    uno::Sequence< OUString > aRet(1);
    aRet[0] = OUString("com.sun.star.media.Player_OpenGL");
    return aRet;
}

IMPL_LINK(OGLPlayer,TimerHandler,Timer*,pTimer)
{
    if (pTimer == &m_aTimer)
    {
        m_pOGLWindow->update();
        m_aTimer.Start();
    }

    return 0;
}

} // namespace ogl
} // namespace avmedia

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>WaE: unused parameter 'fTime'<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "oglplayer.hxx"
#include "oglframegrabber.hxx"
#include "oglwindow.hxx"

#include <cppuhelper/supportsservice.hxx>
#include <tools/stream.hxx>
#include <vcl/graph.hxx>
#include <vcl/graphicfilter.hxx>
#include <tools/urlobj.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>

using namespace com::sun::star;

namespace avmedia { namespace ogl {

OGLPlayer::OGLPlayer()
    : Player_BASE(m_aMutex)
    , m_pHandle(NULL)
{
}

OGLPlayer::~OGLPlayer()
{
    // Comment out while it causes segmentation fault
    // gltf_renderer_release(m_pHandle);
}

static bool lcl_LoadFile( glTFFile* io_pFile, const OUString& rURL)
{
    SvFileStream aStream( rURL, STREAM_READ );
    if( !aStream.IsOpen() )
        return false;

    const sal_Int64 nBytes = aStream.remainingSize();
    char* pBuffer = new char[nBytes];
    aStream.Read( pBuffer, nBytes );
    aStream.Close();

    io_pFile->buffer = pBuffer;
    io_pFile->size = nBytes;

    return true;
}

bool OGLPlayer::create( const OUString& rURL )
{
    m_sURL = rURL;

    // Load *.json file and init renderer
    glTFFile aJsonFile;
    aJsonFile.type = GLTF_JSON;
    OString sFileName = OUStringToOString(INetURLObject(m_sURL).GetLastName(),RTL_TEXTENCODING_UTF8);
    aJsonFile.filename = (char*)sFileName.getStr();
    if( !lcl_LoadFile(&aJsonFile, m_sURL) )
    {
        SAL_WARN("avmedia.opengl", "Can't load *.json file: " + sFileName);
        return false;
    }

    m_pHandle = gltf_renderer_init(&aJsonFile);

    if( !m_pHandle || !m_pHandle->files )
    {
        SAL_WARN("avmedia.opengl", "gltf_renderer_init returned an invalid glTFHandle");
        return false;
    }

    // Load external resources
    for( size_t i = 0; i < m_pHandle->size; ++i )
    {
        glTFFile* pFile = m_pHandle->files[i];
        if( pFile && pFile->filename )
        {
            const OUString sFilesURL =
                INetURLObject::GetAbsURL(m_sURL,OStringToOUString(OString(pFile->filename),RTL_TEXTENCODING_UTF8));
            if( pFile->type == GLTF_IMAGE )
            {
                // Load images as bitmaps
                GraphicFilter aFilter;
                Graphic aGraphic;
                aFilter.ImportGraphic(aGraphic, INetURLObject(sFilesURL));
                const BitmapEx aBitmapEx = aGraphic.GetBitmapEx();
                pFile->buffer = (char*)OpenGLHelper::ConvertBitmapExToRGBABuffer(aBitmapEx);
                pFile->imagewidth = aBitmapEx.GetSizePixel().Width();
                pFile->imageheight = aBitmapEx.GetSizePixel().Height();
            }
            else if( pFile->type == GLTF_BINARY || pFile->type == GLTF_GLSL )
            {
                if( !lcl_LoadFile(pFile, sFilesURL) )
                {
                    SAL_WARN("avmedia.opengl", "Can't load glTF file: " + sFilesURL);
                    return false;
                }
            }
        }
    }

    // Set timer
    m_aTimer.SetTimeout(10);
    m_aTimer.SetTimeoutHdl(LINK(this,OGLPlayer,TimerHandler));
    return true;
}

void SAL_CALL OGLPlayer::start() throw ( uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard(m_aMutex);
    gltf_animation_start(m_pHandle);
    m_aTimer.Start();
}

void SAL_CALL OGLPlayer::stop() throw ( uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard(m_aMutex);
    gltf_animation_stop(m_pHandle);
    m_aTimer.Stop();
}

sal_Bool SAL_CALL OGLPlayer::isPlaying() throw ( uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard(m_aMutex);
    return (sal_Bool)gltf_animation_is_playing(m_pHandle);
}

double SAL_CALL OGLPlayer::getDuration() throw ( uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard(m_aMutex);
    return gltf_animation_get_duration(m_pHandle);
}

void SAL_CALL OGLPlayer::setMediaTime( double fTime ) throw ( uno::RuntimeException, std::exception )
{
    // TODO: doesn't work, but cause problem in playing
    osl::MutexGuard aGuard(m_aMutex);
    (void) fTime;
    //gltf_animation_set_time(m_pHandle, fTime);
}

double SAL_CALL OGLPlayer::getMediaTime() throw ( ::com::sun::star::uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard(m_aMutex);
    return gltf_animation_get_time(m_pHandle);
}

double SAL_CALL OGLPlayer::getRate() throw ( uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard(m_aMutex);
    // Seems unused
    return 1.0;
}

void SAL_CALL OGLPlayer::setPlaybackLoop( sal_Bool bSet ) throw ( uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard(m_aMutex);
    gltf_animation_set_looping(m_pHandle, (int)bSet);
}

sal_Bool SAL_CALL OGLPlayer::isPlaybackLoop() throw ( uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard(m_aMutex);
    return (sal_Bool)gltf_animation_get_looping(m_pHandle);
}

void SAL_CALL OGLPlayer::setVolumeDB( sal_Int16 /*nVolumDB*/ ) throw ( uno::RuntimeException, std::exception )
{
    // OpenGL models have no sound.
}

sal_Int16 SAL_CALL OGLPlayer::getVolumeDB() throw ( uno::RuntimeException, std::exception )
{
    // OpenGL models have no sound.
    return 0;
}

void SAL_CALL OGLPlayer::setMute( sal_Bool /*bSet*/ ) throw ( uno::RuntimeException, std::exception )
{
    // OpenGL models have no sound.
}

sal_Bool SAL_CALL OGLPlayer::isMute() throw ( uno::RuntimeException, std::exception )
{
    // OpenGL models have no sound.
    return false;
}

awt::Size SAL_CALL OGLPlayer::getPreferredPlayerWindowSize() throw ( uno::RuntimeException, std::exception )
{
    return awt::Size( 480, 360 );
}

uno::Reference< media::XPlayerWindow > SAL_CALL OGLPlayer::createPlayerWindow( const uno::Sequence< uno::Any >& rArguments )
     throw ( uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard( m_aMutex );

    assert( rArguments.getLength() >= 3 );

    sal_IntPtr pIntPtr = 0;
    rArguments[ 2 ] >>= pIntPtr;
    SystemChildWindow *pChildWindow = reinterpret_cast< SystemChildWindow* >( pIntPtr );

    if( !m_aContext.init(pChildWindow) )
    {
        SAL_WARN("avmedia.opengl", "Context initialization failed");
        return uno::Reference< media::XPlayerWindow >();
    }

    Size aSize = pChildWindow->GetSizePixel();
    m_aContext.setWinSize(aSize);
    m_pHandle->viewport.x = 0;
    m_pHandle->viewport.y = 0;
    m_pHandle->viewport.width = aSize.Width();
    m_pHandle->viewport.height = aSize.Height();
    gltf_renderer_set_content(m_pHandle);
    m_pOGLWindow = new OGLWindow(m_pHandle, &m_aContext, pChildWindow);
    return uno::Reference< media::XPlayerWindow >( m_pOGLWindow );
}

uno::Reference< media::XFrameGrabber > SAL_CALL OGLPlayer::createFrameGrabber()
     throw ( uno::RuntimeException, std::exception )
{
    osl::MutexGuard aGuard(m_aMutex);

    if( !m_aContext.init() )
    {
        SAL_WARN("avmedia.opengl", "Offscreen context initialization failed");
        return uno::Reference< media::XFrameGrabber >();
    }

    m_pHandle->viewport.x = 0;
    m_pHandle->viewport.y = 0;
    m_pHandle->viewport.width = getPreferredPlayerWindowSize().Width;
    m_pHandle->viewport.height = getPreferredPlayerWindowSize().Height;
    gltf_renderer_set_content(m_pHandle);
    OGLFrameGrabber *pFrameGrabber = new OGLFrameGrabber( m_pHandle );
    return uno::Reference< media::XFrameGrabber >( pFrameGrabber );
}

OUString SAL_CALL OGLPlayer::getImplementationName()
     throw ( ::com::sun::star::uno::RuntimeException, std::exception )
{
    return OUString("com.sun.star.comp.avmedia.Player_OpenGL");
}

sal_Bool SAL_CALL OGLPlayer::supportsService( const OUString& rServiceName )
     throw ( uno::RuntimeException, std::exception )
{
    return cppu::supportsService(this, rServiceName);
}

uno::Sequence< OUString > SAL_CALL OGLPlayer::getSupportedServiceNames()
     throw ( uno::RuntimeException, std::exception )
{
    uno::Sequence< OUString > aRet(1);
    aRet[0] = OUString("com.sun.star.media.Player_OpenGL");
    return aRet;
}

IMPL_LINK(OGLPlayer,TimerHandler,Timer*,pTimer)
{
    if (pTimer == &m_aTimer)
    {
        m_pOGLWindow->update();
        m_aTimer.Start();
    }

    return 0;
}

} // namespace ogl
} // namespace avmedia

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/******************************************************************************

  This source file is part of the Avogadro project.

  Copyright 2012 Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

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

#include "scenepluginmodel.h"

#include "sceneplugin.h"

namespace Avogadro {
namespace QtGui {

ScenePluginModel::ScenePluginModel(QObject *parent_)
  : QAbstractItemModel(parent_)
{
}

QModelIndex ScenePluginModel::parent(const QModelIndex &) const
{
  return QModelIndex();
}

int ScenePluginModel::rowCount(const QModelIndex &parent_) const
{
  if (parent_.isValid())
    return 0;
  else
    return m_scenePlugins.size();
}

int ScenePluginModel::columnCount(const QModelIndex &) const
{
  return 1;
}

Qt::ItemFlags ScenePluginModel::flags(const QModelIndex &index_) const
{
  if (index_.column() == 0)
    return Qt::ItemIsEditable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
  else
    return Qt::ItemIsEnabled;
}

bool ScenePluginModel::setData(const QModelIndex &index_, const QVariant &value,
                               int role)
{
  if (!index_.isValid() || index_.column() > 1)
    return false;

  ScenePlugin *item =
    qobject_cast<ScenePlugin *>(static_cast<QObject *>(index_.internalPointer()));
  if (!item)
    return false;

  switch (role) {
  case Qt::CheckStateRole:
    if (value == Qt::Checked && !item->isEnabled()) {
      item->setEnabled(true);
      emit pluginStateChanged(item);
    }
    else if (value == Qt::Unchecked && item->isEnabled()) {
      item->setEnabled(false);
      emit pluginStateChanged(item);
    }
    emit dataChanged(index_, index_);
    return true;
  }
  return false;
}

QVariant ScenePluginModel::data(const QModelIndex &index_, int role) const
{
  if (!index_.isValid() || index_.column() > 1)
    return QVariant();

  QObject *object = static_cast<QObject *>(index_.internalPointer());
  ScenePlugin *item = qobject_cast<ScenePlugin *>(object);
  if (!item)
    return QVariant();

  if (index_.column() == 0) {
    switch (role) {
    case Qt::DisplayRole:
    case Qt::EditRole:
      return item->name();
    case Qt::CheckStateRole:
      if (item->isEnabled())
        return Qt::Checked;
      else
        return Qt::Unchecked;
    case Qt::ToolTipRole:
    case Qt::WhatsThisRole:
      return item->description();
    default:
      return QVariant();
    }
  }
  return QVariant();
}

QModelIndex ScenePluginModel::index(int row, int column,
                                    const QModelIndex &parent_) const
{
  if (!parent_.isValid() && row >= 0 && row < m_scenePlugins.size())
    return createIndex(row, column, m_scenePlugins[row]);
  else
    return QModelIndex();
}

void ScenePluginModel::clear()
{
  m_scenePlugins.clear();
}

QList<ScenePlugin *> ScenePluginModel::activeScenePlugins() const
{
  QList<ScenePlugin *> result;
  foreach (ScenePlugin *plugin, m_scenePlugins) {
    if (plugin->isEnabled())
      result << plugin;
  }
  return result;
}

void ScenePluginModel::addItem(ScenePlugin *item)
{
  if (!m_scenePlugins.contains(item))
    m_scenePlugins.append(item);
}

void ScenePluginModel::removeItem(ScenePlugin *item)
{
  m_scenePlugins.removeAll(item);
}

void ScenePluginModel::itemChanged()
{
  ScenePlugin *item = qobject_cast<ScenePlugin *>(sender());
  if (item) {
    int row = m_scenePlugins.indexOf(item);
    if (row >= 0)
      emit dataChanged(createIndex(row, 0), createIndex(row, 0));
  }
}

} // End QtGui namespace
} // End Avogadro namespace
<commit_msg>Have the model take ownership of the ScenePlugin<commit_after>/******************************************************************************

  This source file is part of the Avogadro project.

  Copyright 2012 Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

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

#include "scenepluginmodel.h"

#include "sceneplugin.h"

namespace Avogadro {
namespace QtGui {

ScenePluginModel::ScenePluginModel(QObject *parent_)
  : QAbstractItemModel(parent_)
{
}

QModelIndex ScenePluginModel::parent(const QModelIndex &) const
{
  return QModelIndex();
}

int ScenePluginModel::rowCount(const QModelIndex &parent_) const
{
  if (parent_.isValid())
    return 0;
  else
    return m_scenePlugins.size();
}

int ScenePluginModel::columnCount(const QModelIndex &) const
{
  return 1;
}

Qt::ItemFlags ScenePluginModel::flags(const QModelIndex &index_) const
{
  if (index_.column() == 0)
    return Qt::ItemIsEditable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
  else
    return Qt::ItemIsEnabled;
}

bool ScenePluginModel::setData(const QModelIndex &index_, const QVariant &value,
                               int role)
{
  if (!index_.isValid() || index_.column() > 1)
    return false;

  ScenePlugin *item =
    qobject_cast<ScenePlugin *>(static_cast<QObject *>(index_.internalPointer()));
  if (!item)
    return false;

  switch (role) {
  case Qt::CheckStateRole:
    if (value == Qt::Checked && !item->isEnabled()) {
      item->setEnabled(true);
      emit pluginStateChanged(item);
    }
    else if (value == Qt::Unchecked && item->isEnabled()) {
      item->setEnabled(false);
      emit pluginStateChanged(item);
    }
    emit dataChanged(index_, index_);
    return true;
  }
  return false;
}

QVariant ScenePluginModel::data(const QModelIndex &index_, int role) const
{
  if (!index_.isValid() || index_.column() > 1)
    return QVariant();

  QObject *object = static_cast<QObject *>(index_.internalPointer());
  ScenePlugin *item = qobject_cast<ScenePlugin *>(object);
  if (!item)
    return QVariant();

  if (index_.column() == 0) {
    switch (role) {
    case Qt::DisplayRole:
    case Qt::EditRole:
      return item->name();
    case Qt::CheckStateRole:
      if (item->isEnabled())
        return Qt::Checked;
      else
        return Qt::Unchecked;
    case Qt::ToolTipRole:
    case Qt::WhatsThisRole:
      return item->description();
    default:
      return QVariant();
    }
  }
  return QVariant();
}

QModelIndex ScenePluginModel::index(int row, int column,
                                    const QModelIndex &parent_) const
{
  if (!parent_.isValid() && row >= 0 && row < m_scenePlugins.size())
    return createIndex(row, column, m_scenePlugins[row]);
  else
    return QModelIndex();
}

void ScenePluginModel::clear()
{
  m_scenePlugins.clear();
}

QList<ScenePlugin *> ScenePluginModel::activeScenePlugins() const
{
  QList<ScenePlugin *> result;
  foreach (ScenePlugin *plugin, m_scenePlugins) {
    if (plugin->isEnabled())
      result << plugin;
  }
  return result;
}

void ScenePluginModel::addItem(ScenePlugin *item)
{
  if (!m_scenePlugins.contains(item)) {
    m_scenePlugins.append(item);
    item->setParent(this);
  }
}

void ScenePluginModel::removeItem(ScenePlugin *item)
{
  m_scenePlugins.removeAll(item);
}

void ScenePluginModel::itemChanged()
{
  ScenePlugin *item = qobject_cast<ScenePlugin *>(sender());
  if (item) {
    int row = m_scenePlugins.indexOf(item);
    if (row >= 0)
      emit dataChanged(createIndex(row, 0), createIndex(row, 0));
  }
}

} // End QtGui namespace
} // End Avogadro namespace
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/renderer/autofill_helper.h"

#include "app/l10n_util.h"
#include "chrome/renderer/form_manager.h"
#include "chrome/renderer/render_view.h"
#include "grit/generated_resources.h"
#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFormControlElement.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
#include "webkit/glue/password_form.h"

using WebKit::WebFormControlElement;
using WebKit::WebFormElement;
using WebKit::WebFrame;
using WebKit::WebInputElement;
using WebKit::WebNode;
using WebKit::WebString;

namespace {

// The size above which we stop triggering autofill for an input text field
// (so to avoid sending long strings through IPC).
const size_t kMaximumTextSizeForAutoFill = 1000;

}  // namespace

AutoFillHelper::AutoFillHelper(RenderView* render_view)
    : render_view_(render_view),
      autofill_query_id_(0),
      autofill_action_(AUTOFILL_NONE),
      suggestions_clear_index_(-1),
      suggestions_options_index_(-1) {
}

void AutoFillHelper::QueryAutoFillSuggestions(const WebNode& node,
                                              const WebString& name,
                                              const WebString& value) {
  static int query_counter = 0;
  autofill_query_id_ = query_counter++;
  autofill_query_node_ = node;

  const WebFormControlElement& element = node.toConst<WebFormControlElement>();
  webkit_glue::FormField field;
  FormManager::WebFormControlElementToFormField(element, true, &field);

  // WebFormControlElementToFormField does not scrape the DOM for the field
  // label, so find the label here.
  // TODO(jhawkins): Add form and field identities so we can use the cached form
  // data in FormManager.
  field.set_label(FormManager::LabelForElement(element));

  bool form_autofilled = form_manager_.FormWithNodeIsAutoFilled(node);
  render_view_->Send(new ViewHostMsg_QueryFormFieldAutoFill(
      render_view_->routing_id(), autofill_query_id_, form_autofilled, field));
}

void AutoFillHelper::RemoveAutocompleteSuggestion(
    const WebKit::WebString& name, const WebKit::WebString& value) {
  // The index of clear & options will have shifted down.
  if (suggestions_clear_index_ != -1)
    suggestions_clear_index_--;
  if (suggestions_options_index_ != -1)
    suggestions_options_index_--;

  render_view_->Send(new ViewHostMsg_RemoveAutocompleteEntry(
      render_view_->routing_id(), name, value));
}

void AutoFillHelper::SuggestionsReceived(int query_id,
                                         const std::vector<string16>& values,
                                         const std::vector<string16>& labels,
                                         const std::vector<string16>& icons,
                                         const std::vector<int>& unique_ids) {
  WebKit::WebView* web_view = render_view_->webview();
  if (!web_view || query_id != autofill_query_id_)
    return;

  // Any popup currently showing is now obsolete.
  web_view->hidePopups();

  // No suggestions: nothing to do.
  if (values.empty())
    return;

  std::vector<string16> v(values);
  std::vector<string16> l(labels);
  std::vector<string16> i(icons);
  std::vector<int> ids(unique_ids);
  int separator_index = -1;

  // The form has been auto-filled, so give the user the chance to clear the
  // form.  Append the 'Clear form' menu item.
  if (form_manager_.FormWithNodeIsAutoFilled(autofill_query_node_)) {
    v.push_back(l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM));
    l.push_back(string16());
    i.push_back(string16());
    ids.push_back(0);
    suggestions_clear_index_ = v.size() - 1;
    separator_index = values.size();
  }

  // Only include "AutoFill Options" special menu item if we have AutoFill
  // items, identified by |unique_ids| having at least one valid value.
  bool show_options = false;
  for (size_t i = 0; i < ids.size(); ++i) {
    if (ids[i] != 0) {
      show_options = true;
      break;
    }
  }
  if (show_options) {
    // Append the 'AutoFill Options...' menu item.
    v.push_back(l10n_util::GetStringUTF16(IDS_AUTOFILL_OPTIONS));
    l.push_back(string16());
    i.push_back(string16());
    ids.push_back(0);
    suggestions_options_index_ = v.size() - 1;
    separator_index = values.size();
  }

  // Send to WebKit for display.
  if (!v.empty()) {
    web_view->applyAutoFillSuggestions(
        autofill_query_node_, v, l, i, ids, separator_index);
  }
}

void AutoFillHelper::FormDataFilled(int query_id,
                                    const webkit_glue::FormData& form) {
  if (!render_view_->webview() || query_id != autofill_query_id_)
    return;

  switch (autofill_action_) {
    case AUTOFILL_FILL:
      form_manager_.FillForm(form, autofill_query_node_);
      break;
    case AUTOFILL_PREVIEW:
      form_manager_.PreviewForm(form);
      break;
    default:
      NOTREACHED();
  }
  autofill_action_ = AUTOFILL_NONE;
}

void AutoFillHelper::DidSelectAutoFillSuggestion(const WebNode& node,
                                                 const WebString& value,
                                                 const WebString& label,
                                                 int unique_id) {
  DidClearAutoFillSelection(node);
  QueryAutoFillFormData(node, value, label, unique_id, AUTOFILL_PREVIEW);
}

void AutoFillHelper::DidAcceptAutoFillSuggestion(const WebNode& node,
                                                 const WebString& value,
                                                 const WebString& label,
                                                 int unique_id,
                                                 unsigned index) {
  if (suggestions_options_index_ != -1 &&
      index == static_cast<unsigned>(suggestions_options_index_)) {
    // User selected 'AutoFill Options'.
    render_view_->Send(new ViewHostMsg_ShowAutoFillDialog(
        render_view_->routing_id()));
  } else if (suggestions_clear_index_ != -1 &&
             index == static_cast<unsigned>(suggestions_clear_index_)) {
    // User selected 'Clear form'.
    // The form has been auto-filled, so give the user the chance to clear the
    // form.
    form_manager_.ClearFormWithNode(node);
  } else if (form_manager_.FormWithNodeIsAutoFilled(node) || !unique_id) {
    // User selected an Autocomplete entry, so we fill directly.
    WebInputElement element = node.toConst<WebInputElement>();

    // Set the suggested value to update input element value immediately in UI.
    // The |setValue| call has update delayed until element loses focus.
    string16 substring = value;
    substring = substring.substr(0, element.maxLength());
    element.setSuggestedValue(substring);
    element.setValue(substring);

    WebFrame* webframe = node.document().frame();
    if (webframe)
      webframe->notifiyPasswordListenerOfAutocomplete(element);
  } else {
    // Fill the values for the whole form.
    QueryAutoFillFormData(node, value, label, unique_id, AUTOFILL_FILL);
  }

  suggestions_clear_index_ = -1;
  suggestions_options_index_ = -1;
}

void AutoFillHelper::DidClearAutoFillSelection(const WebNode& node) {
  form_manager_.ClearPreviewedFormWithNode(node);
}

void AutoFillHelper::FrameContentsAvailable(WebFrame* frame) {
  form_manager_.ExtractForms(frame);
  SendForms(frame);
}

void AutoFillHelper::FrameWillClose(WebFrame* frame) {
  form_manager_.ResetFrame(frame);
}

void AutoFillHelper::FrameDetached(WebFrame* frame) {
  form_manager_.ResetFrame(frame);
}

void AutoFillHelper::TextDidChangeInTextField(const WebInputElement& element) {
  ShowSuggestions(element, false, true);
}

void AutoFillHelper::InputElementClicked(const WebInputElement& element,
                                         bool already_focused) {
  if (already_focused)
    ShowSuggestions(element, true, false);
}

void AutoFillHelper::ShowSuggestions(
    const WebInputElement& const_element,
    bool autofill_on_empty_values,
    bool requires_caret_at_end) {
  // We need to call non-const methods.
  WebInputElement element(const_element);
  if (!element.isEnabledFormControl() ||
      element.inputType() != WebInputElement::Text ||
      element.inputType() == WebInputElement::Password ||
      !element.autoComplete() || element.isReadOnly()) {
    return;
  }

  WebString name = element.nameForAutofill();
  if (name.isEmpty())  // If the field has no name, then we won't have values.
    return;

  // Don't attempt to autofill with values that are too large.
  WebString value = element.value();
  if (value.length() > kMaximumTextSizeForAutoFill)
    return;

  if (!autofill_on_empty_values && value.isEmpty())
    return;

  if (requires_caret_at_end &&
      (element.selectionStart() != element.selectionEnd() ||
       element.selectionEnd() != static_cast<int>(value.length()))) {
    return;
  }

  QueryAutoFillSuggestions(element, name, value);
}

void AutoFillHelper::QueryAutoFillFormData(const WebNode& node,
                                           const WebString& value,
                                           const WebString& label,
                                           int unique_id,
                                           AutoFillAction action) {
  static int query_counter = 0;
  autofill_query_id_ = query_counter++;

  webkit_glue::FormData form;
  const WebInputElement element = node.toConst<WebInputElement>();
  if (!form_manager_.FindFormWithFormControlElement(
          element, FormManager::REQUIRE_NONE, &form))
    return;

  autofill_action_ = action;
  render_view_->Send(new ViewHostMsg_FillAutoFillFormData(
      render_view_->routing_id(), autofill_query_id_, form, value, label,
      unique_id));
}

void AutoFillHelper::SendForms(WebFrame* frame) {
  // TODO(jhawkins): Use FormManager once we have strict ordering of form
  // control elements in the cache.
  WebKit::WebVector<WebFormElement> web_forms;
  frame->forms(web_forms);

  std::vector<webkit_glue::FormData> forms;
  for (size_t i = 0; i < web_forms.size(); ++i) {
    const WebFormElement& web_form = web_forms[i];

    webkit_glue::FormData form;
    if (FormManager::WebFormElementToFormData(
            web_form, FormManager::REQUIRE_NONE, false, &form)) {
      forms.push_back(form);
    }
  }

  if (!forms.empty()) {
    render_view_->Send(new ViewHostMsg_FormsSeen(render_view_->routing_id(),
                                                 forms));
  }
}
<commit_msg>Every time a new autofill suggestion was received we would hide the autofill popup before showing a new one. This causes it to flash every time the user type a new key (as we get new suggestions for each key stroke). It is safe to hide the autofill only when there are no suggestions. If there are suggestions, the WebKit side takes care of resizing and potentially hiding the popup if necessary.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/renderer/autofill_helper.h"

#include "app/l10n_util.h"
#include "chrome/renderer/form_manager.h"
#include "chrome/renderer/render_view.h"
#include "grit/generated_resources.h"
#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFormControlElement.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
#include "webkit/glue/password_form.h"

using WebKit::WebFormControlElement;
using WebKit::WebFormElement;
using WebKit::WebFrame;
using WebKit::WebInputElement;
using WebKit::WebNode;
using WebKit::WebString;

namespace {

// The size above which we stop triggering autofill for an input text field
// (so to avoid sending long strings through IPC).
const size_t kMaximumTextSizeForAutoFill = 1000;

}  // namespace

AutoFillHelper::AutoFillHelper(RenderView* render_view)
    : render_view_(render_view),
      autofill_query_id_(0),
      autofill_action_(AUTOFILL_NONE),
      suggestions_clear_index_(-1),
      suggestions_options_index_(-1) {
}

void AutoFillHelper::QueryAutoFillSuggestions(const WebNode& node,
                                              const WebString& name,
                                              const WebString& value) {
  static int query_counter = 0;
  autofill_query_id_ = query_counter++;
  autofill_query_node_ = node;

  const WebFormControlElement& element = node.toConst<WebFormControlElement>();
  webkit_glue::FormField field;
  FormManager::WebFormControlElementToFormField(element, true, &field);

  // WebFormControlElementToFormField does not scrape the DOM for the field
  // label, so find the label here.
  // TODO(jhawkins): Add form and field identities so we can use the cached form
  // data in FormManager.
  field.set_label(FormManager::LabelForElement(element));

  bool form_autofilled = form_manager_.FormWithNodeIsAutoFilled(node);
  render_view_->Send(new ViewHostMsg_QueryFormFieldAutoFill(
      render_view_->routing_id(), autofill_query_id_, form_autofilled, field));
}

void AutoFillHelper::RemoveAutocompleteSuggestion(
    const WebKit::WebString& name, const WebKit::WebString& value) {
  // The index of clear & options will have shifted down.
  if (suggestions_clear_index_ != -1)
    suggestions_clear_index_--;
  if (suggestions_options_index_ != -1)
    suggestions_options_index_--;

  render_view_->Send(new ViewHostMsg_RemoveAutocompleteEntry(
      render_view_->routing_id(), name, value));
}

void AutoFillHelper::SuggestionsReceived(int query_id,
                                         const std::vector<string16>& values,
                                         const std::vector<string16>& labels,
                                         const std::vector<string16>& icons,
                                         const std::vector<int>& unique_ids) {
  WebKit::WebView* web_view = render_view_->webview();
  if (!web_view || query_id != autofill_query_id_)
    return;

  if (values.empty()) {
    // No suggestions, any popup currently showing is obsolete.
    web_view->hidePopups();
    return;
  }

  std::vector<string16> v(values);
  std::vector<string16> l(labels);
  std::vector<string16> i(icons);
  std::vector<int> ids(unique_ids);
  int separator_index = -1;

  // The form has been auto-filled, so give the user the chance to clear the
  // form.  Append the 'Clear form' menu item.
  if (form_manager_.FormWithNodeIsAutoFilled(autofill_query_node_)) {
    v.push_back(l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM));
    l.push_back(string16());
    i.push_back(string16());
    ids.push_back(0);
    suggestions_clear_index_ = v.size() - 1;
    separator_index = values.size();
  }

  // Only include "AutoFill Options" special menu item if we have AutoFill
  // items, identified by |unique_ids| having at least one valid value.
  bool show_options = false;
  for (size_t i = 0; i < ids.size(); ++i) {
    if (ids[i] != 0) {
      show_options = true;
      break;
    }
  }
  if (show_options) {
    // Append the 'AutoFill Options...' menu item.
    v.push_back(l10n_util::GetStringUTF16(IDS_AUTOFILL_OPTIONS));
    l.push_back(string16());
    i.push_back(string16());
    ids.push_back(0);
    suggestions_options_index_ = v.size() - 1;
    separator_index = values.size();
  }

  // Send to WebKit for display.
  if (!v.empty()) {
    web_view->applyAutoFillSuggestions(
        autofill_query_node_, v, l, i, ids, separator_index);
  }
}

void AutoFillHelper::FormDataFilled(int query_id,
                                    const webkit_glue::FormData& form) {
  if (!render_view_->webview() || query_id != autofill_query_id_)
    return;

  switch (autofill_action_) {
    case AUTOFILL_FILL:
      form_manager_.FillForm(form, autofill_query_node_);
      break;
    case AUTOFILL_PREVIEW:
      form_manager_.PreviewForm(form);
      break;
    default:
      NOTREACHED();
  }
  autofill_action_ = AUTOFILL_NONE;
}

void AutoFillHelper::DidSelectAutoFillSuggestion(const WebNode& node,
                                                 const WebString& value,
                                                 const WebString& label,
                                                 int unique_id) {
  DidClearAutoFillSelection(node);
  QueryAutoFillFormData(node, value, label, unique_id, AUTOFILL_PREVIEW);
}

void AutoFillHelper::DidAcceptAutoFillSuggestion(const WebNode& node,
                                                 const WebString& value,
                                                 const WebString& label,
                                                 int unique_id,
                                                 unsigned index) {
  if (suggestions_options_index_ != -1 &&
      index == static_cast<unsigned>(suggestions_options_index_)) {
    // User selected 'AutoFill Options'.
    render_view_->Send(new ViewHostMsg_ShowAutoFillDialog(
        render_view_->routing_id()));
  } else if (suggestions_clear_index_ != -1 &&
             index == static_cast<unsigned>(suggestions_clear_index_)) {
    // User selected 'Clear form'.
    // The form has been auto-filled, so give the user the chance to clear the
    // form.
    form_manager_.ClearFormWithNode(node);
  } else if (form_manager_.FormWithNodeIsAutoFilled(node) || !unique_id) {
    // User selected an Autocomplete entry, so we fill directly.
    WebInputElement element = node.toConst<WebInputElement>();

    // Set the suggested value to update input element value immediately in UI.
    // The |setValue| call has update delayed until element loses focus.
    string16 substring = value;
    substring = substring.substr(0, element.maxLength());
    element.setSuggestedValue(substring);
    element.setValue(substring);

    WebFrame* webframe = node.document().frame();
    if (webframe)
      webframe->notifiyPasswordListenerOfAutocomplete(element);
  } else {
    // Fill the values for the whole form.
    QueryAutoFillFormData(node, value, label, unique_id, AUTOFILL_FILL);
  }

  suggestions_clear_index_ = -1;
  suggestions_options_index_ = -1;
}

void AutoFillHelper::DidClearAutoFillSelection(const WebNode& node) {
  form_manager_.ClearPreviewedFormWithNode(node);
}

void AutoFillHelper::FrameContentsAvailable(WebFrame* frame) {
  form_manager_.ExtractForms(frame);
  SendForms(frame);
}

void AutoFillHelper::FrameWillClose(WebFrame* frame) {
  form_manager_.ResetFrame(frame);
}

void AutoFillHelper::FrameDetached(WebFrame* frame) {
  form_manager_.ResetFrame(frame);
}

void AutoFillHelper::TextDidChangeInTextField(const WebInputElement& element) {
  ShowSuggestions(element, false, true);
}

void AutoFillHelper::InputElementClicked(const WebInputElement& element,
                                         bool already_focused) {
  if (already_focused)
    ShowSuggestions(element, true, false);
}

void AutoFillHelper::ShowSuggestions(
    const WebInputElement& const_element,
    bool autofill_on_empty_values,
    bool requires_caret_at_end) {
  // We need to call non-const methods.
  WebInputElement element(const_element);
  if (!element.isEnabledFormControl() ||
      element.inputType() != WebInputElement::Text ||
      element.inputType() == WebInputElement::Password ||
      !element.autoComplete() || element.isReadOnly()) {
    return;
  }

  WebString name = element.nameForAutofill();
  if (name.isEmpty())  // If the field has no name, then we won't have values.
    return;

  // Don't attempt to autofill with values that are too large.
  WebString value = element.value();
  if (value.length() > kMaximumTextSizeForAutoFill)
    return;

  if (!autofill_on_empty_values && value.isEmpty())
    return;

  if (requires_caret_at_end &&
      (element.selectionStart() != element.selectionEnd() ||
       element.selectionEnd() != static_cast<int>(value.length()))) {
    return;
  }

  QueryAutoFillSuggestions(element, name, value);
}

void AutoFillHelper::QueryAutoFillFormData(const WebNode& node,
                                           const WebString& value,
                                           const WebString& label,
                                           int unique_id,
                                           AutoFillAction action) {
  static int query_counter = 0;
  autofill_query_id_ = query_counter++;

  webkit_glue::FormData form;
  const WebInputElement element = node.toConst<WebInputElement>();
  if (!form_manager_.FindFormWithFormControlElement(
          element, FormManager::REQUIRE_NONE, &form))
    return;

  autofill_action_ = action;
  render_view_->Send(new ViewHostMsg_FillAutoFillFormData(
      render_view_->routing_id(), autofill_query_id_, form, value, label,
      unique_id));
}

void AutoFillHelper::SendForms(WebFrame* frame) {
  // TODO(jhawkins): Use FormManager once we have strict ordering of form
  // control elements in the cache.
  WebKit::WebVector<WebFormElement> web_forms;
  frame->forms(web_forms);

  std::vector<webkit_glue::FormData> forms;
  for (size_t i = 0; i < web_forms.size(); ++i) {
    const WebFormElement& web_form = web_forms[i];

    webkit_glue::FormData form;
    if (FormManager::WebFormElementToFormData(
            web_form, FormManager::REQUIRE_NONE, false, &form)) {
      forms.push_back(form);
    }
  }

  if (!forms.empty()) {
    render_view_->Send(new ViewHostMsg_FormsSeen(render_view_->routing_id(),
                                                 forms));
  }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: interactionhandler.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-13 15:09:16 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef UUI_INTERACTIONHANDLER_HXX
#define UUI_INTERACTIONHANDLER_HXX

#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_
#include "com/sun/star/lang/XInitialization.hpp"
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include "com/sun/star/lang/XServiceInfo.hpp"
#endif
#ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_
#include "com/sun/star/task/XInteractionHandler.hpp"
#endif

#ifndef _CPPUHELPER_IMPLBASE3_HXX_
#include "cppuhelper/implbase3.hxx"
#endif

class UUIInteractionHelper;

class UUIInteractionHandler:
    public cppu::WeakImplHelper3< com::sun::star::lang::XServiceInfo,
                                  com::sun::star::lang::XInitialization,
                                  com::sun::star::task::XInteractionHandler >
{
public:
    static char const m_aImplementationName[];

    static com::sun::star::uno::Sequence< rtl::OUString >
    getSupportedServiceNames_static();

    static com::sun::star::uno::Reference< com::sun::star::uno::XInterface >
    SAL_CALL
    createInstance(
        com::sun::star::uno::Reference<
                com::sun::star::lang::XMultiServiceFactory > const &
            rServiceFactory)
        SAL_THROW((com::sun::star::uno::Exception));

private:
    com::sun::star::uno::Reference<
        com::sun::star::lang::XMultiServiceFactory > m_xServiceFactory;
    UUIInteractionHelper * m_pImpl;

    UUIInteractionHandler(UUIInteractionHandler &); // not implemented
    void operator =(UUIInteractionHandler); // not implemented

    UUIInteractionHandler(com::sun::star::uno::Reference<
                  com::sun::star::lang::XMultiServiceFactory >
                  const & rServiceFactory)
        SAL_THROW(());

    virtual ~UUIInteractionHandler() SAL_THROW(());

    virtual rtl::OUString SAL_CALL getImplementationName()
        throw (com::sun::star::uno::RuntimeException);

    virtual sal_Bool SAL_CALL supportsService(rtl::OUString const &
                          rServiceName)
        throw (com::sun::star::uno::RuntimeException);

    virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
    getSupportedServiceNames()
        throw (com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL
    initialize(
        com::sun::star::uno::Sequence< com::sun::star::uno::Any > const &
            rArguments)
        throw (com::sun::star::uno::Exception);

    virtual void SAL_CALL
    handle(com::sun::star::uno::Reference<
           com::sun::star::task::XInteractionRequest > const &
       rRequest)
        throw (com::sun::star::uno::RuntimeException);

};

#endif // UUI_INTERACTIONHANDLER_HXX
<commit_msg>INTEGRATION: CWS changefileheader (1.2.78); FILE MERGED 2008/04/01 16:03:50 thb 1.2.78.3: #i85898# Stripping all external header guards 2008/04/01 13:00:08 thb 1.2.78.2: #i85898# Stripping all external header guards 2008/03/31 15:33:10 rt 1.2.78.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: interactionhandler.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef UUI_INTERACTIONHANDLER_HXX
#define UUI_INTERACTIONHANDLER_HXX

#include "com/sun/star/lang/XInitialization.hpp"
#include "com/sun/star/lang/XServiceInfo.hpp"
#include "com/sun/star/task/XInteractionHandler.hpp"
#include "cppuhelper/implbase3.hxx"

class UUIInteractionHelper;

class UUIInteractionHandler:
    public cppu::WeakImplHelper3< com::sun::star::lang::XServiceInfo,
                                  com::sun::star::lang::XInitialization,
                                  com::sun::star::task::XInteractionHandler >
{
public:
    static char const m_aImplementationName[];

    static com::sun::star::uno::Sequence< rtl::OUString >
    getSupportedServiceNames_static();

    static com::sun::star::uno::Reference< com::sun::star::uno::XInterface >
    SAL_CALL
    createInstance(
        com::sun::star::uno::Reference<
                com::sun::star::lang::XMultiServiceFactory > const &
            rServiceFactory)
        SAL_THROW((com::sun::star::uno::Exception));

private:
    com::sun::star::uno::Reference<
        com::sun::star::lang::XMultiServiceFactory > m_xServiceFactory;
    UUIInteractionHelper * m_pImpl;

    UUIInteractionHandler(UUIInteractionHandler &); // not implemented
    void operator =(UUIInteractionHandler); // not implemented

    UUIInteractionHandler(com::sun::star::uno::Reference<
                  com::sun::star::lang::XMultiServiceFactory >
                  const & rServiceFactory)
        SAL_THROW(());

    virtual ~UUIInteractionHandler() SAL_THROW(());

    virtual rtl::OUString SAL_CALL getImplementationName()
        throw (com::sun::star::uno::RuntimeException);

    virtual sal_Bool SAL_CALL supportsService(rtl::OUString const &
                          rServiceName)
        throw (com::sun::star::uno::RuntimeException);

    virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
    getSupportedServiceNames()
        throw (com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL
    initialize(
        com::sun::star::uno::Sequence< com::sun::star::uno::Any > const &
            rArguments)
        throw (com::sun::star::uno::Exception);

    virtual void SAL_CALL
    handle(com::sun::star::uno::Reference<
           com::sun::star::task::XInteractionRequest > const &
       rRequest)
        throw (com::sun::star::uno::RuntimeException);

};

#endif // UUI_INTERACTIONHANDLER_HXX
<|endoftext|>


<commit_before>// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Tests for the top plugins to catch regressions in our plugin host code, as
// well as in the out of process code.  Currently this tests:
//  Flash
//  Real
//  QuickTime
//  Windows Media Player
//    -this includes both WMP plugins.  npdsplay.dll is the older one that
//     comes with XP.  np-mswmp.dll can be downloaded from Microsoft and
//     needs SP2 or Vista.

#include <windows.h>
#include <shellapi.h>
#include <shlobj.h>
#include <atlbase.h>
#include <comutil.h>

#include <stdlib.h>
#include <string.h>
#include <memory.h>

#include "base/file_util.h"
#include "base/registry.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/base/net_util.h"
#include "webkit/glue/plugins/plugin_constants_win.h"
#include "webkit/glue/plugins/plugin_list.h"

const char kTestCompleteCookie[] = "status";
const char kTestCompleteSuccess[] = "OK";
const int kShortWaitTimeout = 10 * 1000;
const int kLongWaitTimeout  = 30 * 1000;

class PluginTest : public UITest {
 protected:
  virtual void SetUp() {
    const testing::TestInfo* const test_info =
        testing::UnitTest::GetInstance()->current_test_info();
    if (strcmp(test_info->name(), "MediaPlayerNew") == 0) {
      // The installer adds our process names to the registry key below.  Since
      // the installer might not have run on this machine, add it manually.
      RegKey regkey;
      if (regkey.Open(HKEY_LOCAL_MACHINE,
                      L"Software\\Microsoft\\MediaPlayer\\ShimInclusionList",
                      KEY_WRITE)) {
        regkey.CreateKey(L"CHROME.EXE", KEY_READ);
      }
      launch_arguments_.AppendSwitch(kNoNativeActiveXShimSwitch);

    } else if (strcmp(test_info->name(), "MediaPlayerOld") == 0) {
      // When testing the old WMP plugin, we need to force Chrome to not load
      // the new plugin.
      launch_arguments_.AppendSwitch(kUseOldWMPPluginSwitch);
      launch_arguments_.AppendSwitch(kNoNativeActiveXShimSwitch);
    } else if (strcmp(test_info->name(), "FlashSecurity") == 0) {
      launch_arguments_.AppendSwitchWithValue(switches::kTestSandbox,
                                              L"security_tests.dll");
    }

    UITest::SetUp();
  }

  void TestPlugin(const std::wstring& test_case, int timeout) {
    GURL url = GetTestUrl(test_case);
    NavigateToURL(url);
    WaitForFinish(timeout);
  }

  // Generate the URL for testing a particular test.
  // HTML for the tests is all located in test_directory\plugin\<testcase>
  GURL GetTestUrl(const std::wstring &test_case) {
    std::wstring path;
    PathService::Get(chrome::DIR_TEST_DATA, &path);
    file_util::AppendToPath(&path, L"plugin");
    file_util::AppendToPath(&path, test_case);
    return net::FilePathToFileURL(path);
  }

  // Waits for the test case to finish.
  void WaitForFinish(const int wait_time) {
    const int kSleepTime = 500;      // 2 times per second
    const int kMaxIntervals = wait_time / kSleepTime;

    GURL url = GetTestUrl(L"done");
    scoped_ptr<TabProxy> tab(GetActiveTab());

    std::string done_str;
    for (int i = 0; i < kMaxIntervals; ++i) {
      Sleep(kSleepTime);

      // The webpage being tested has javascript which sets a cookie
      // which signals completion of the test.
      std::string cookieName = kTestCompleteCookie;
      tab->GetCookieByName(url, cookieName, &done_str);
      if (!done_str.empty())
        break;
    }

    EXPECT_EQ(kTestCompleteSuccess, done_str);
  }
};

TEST_F(PluginTest, Quicktime) {
  TestPlugin(L"quicktime.html", kShortWaitTimeout);
}

TEST_F(PluginTest, MediaPlayerNew) {
  TestPlugin(L"wmp_new.html", kShortWaitTimeout);
}

// http://crbug.com/4809
TEST_F(PluginTest, DISABLED_MediaPlayerOld) {
  TestPlugin(L"wmp_old.html", kLongWaitTimeout);
}

TEST_F(PluginTest, Real) {
  TestPlugin(L"real.html", kShortWaitTimeout);
}

TEST_F(PluginTest, Flash) {
  TestPlugin(L"flash.html", kShortWaitTimeout);
}

TEST_F(PluginTest, FlashOctetStream) {
  TestPlugin(L"flash-octet-stream.html", kShortWaitTimeout);
}

TEST_F(PluginTest, FlashSecurity) {
  TestPlugin(L"flash.html", kShortWaitTimeout);
}

// http://crbug.com/8690
TEST_F(PluginTest, DISABLED_Java) {
  TestPlugin(L"Java.html", kShortWaitTimeout);
}

TEST_F(PluginTest, Silverlight) {
  TestPlugin(L"silverlight.html", kShortWaitTimeout);
}

typedef HRESULT (__stdcall* DllRegUnregServerFunc)();

class ActiveXTest : public PluginTest {
 public:
  ActiveXTest() {
    dll_registered = false;
  }
 protected:
  void TestActiveX(const std::wstring& test_case, int timeout, bool reg_dll) {
    if (reg_dll) {
      RegisterTestControl(true);
      dll_registered = true;
    }
    TestPlugin(test_case, timeout);
  }
  virtual void TearDown() {
    PluginTest::TearDown();
    if (dll_registered)
      RegisterTestControl(false);
  }
  void RegisterTestControl(bool register_server) {
    std::wstring test_control_path = browser_directory_ +
        L"\\activex_test_control.dll";
    HMODULE h = LoadLibrary(test_control_path.c_str());
    ASSERT_TRUE(h != NULL) << "Failed to load activex_test_control.dll";
    const char* func_name = register_server ?
                                "DllRegisterServer" : "DllUnregisterServer";
    DllRegUnregServerFunc func = reinterpret_cast<DllRegUnregServerFunc>(
        GetProcAddress(h, func_name));
    // This should never happen actually.
    ASSERT_TRUE(func != NULL) << "Failed to find reg/unreg function.";
    HRESULT hr = func();
    const char* error_message = register_server ? "Failed to register dll."
                                                : "Failed to unregister dll";
    ASSERT_TRUE(SUCCEEDED(hr)) << error_message;
    FreeLibrary(h);
  }
 private:
  bool dll_registered;
};

TEST_F(ActiveXTest, EmbeddedWMP) {
  TestActiveX(L"activex_embedded_wmp.html", kLongWaitTimeout, false);
}

TEST_F(ActiveXTest, WMP) {
  TestActiveX(L"activex_wmp.html", kLongWaitTimeout, false);
}

TEST_F(ActiveXTest, CustomScripting) {
  TestActiveX(L"activex_custom_scripting.html", kShortWaitTimeout, true);
}

<commit_msg>Re-enable java plugin test (reverting 11510)<commit_after>// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Tests for the top plugins to catch regressions in our plugin host code, as
// well as in the out of process code.  Currently this tests:
//  Flash
//  Real
//  QuickTime
//  Windows Media Player
//    -this includes both WMP plugins.  npdsplay.dll is the older one that
//     comes with XP.  np-mswmp.dll can be downloaded from Microsoft and
//     needs SP2 or Vista.

#include <windows.h>
#include <shellapi.h>
#include <shlobj.h>
#include <atlbase.h>
#include <comutil.h>

#include <stdlib.h>
#include <string.h>
#include <memory.h>

#include "base/file_util.h"
#include "base/registry.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/base/net_util.h"
#include "webkit/glue/plugins/plugin_constants_win.h"
#include "webkit/glue/plugins/plugin_list.h"

const char kTestCompleteCookie[] = "status";
const char kTestCompleteSuccess[] = "OK";
const int kShortWaitTimeout = 10 * 1000;
const int kLongWaitTimeout  = 30 * 1000;

class PluginTest : public UITest {
 protected:
  virtual void SetUp() {
    const testing::TestInfo* const test_info =
        testing::UnitTest::GetInstance()->current_test_info();
    if (strcmp(test_info->name(), "MediaPlayerNew") == 0) {
      // The installer adds our process names to the registry key below.  Since
      // the installer might not have run on this machine, add it manually.
      RegKey regkey;
      if (regkey.Open(HKEY_LOCAL_MACHINE,
                      L"Software\\Microsoft\\MediaPlayer\\ShimInclusionList",
                      KEY_WRITE)) {
        regkey.CreateKey(L"CHROME.EXE", KEY_READ);
      }
      launch_arguments_.AppendSwitch(kNoNativeActiveXShimSwitch);

    } else if (strcmp(test_info->name(), "MediaPlayerOld") == 0) {
      // When testing the old WMP plugin, we need to force Chrome to not load
      // the new plugin.
      launch_arguments_.AppendSwitch(kUseOldWMPPluginSwitch);
      launch_arguments_.AppendSwitch(kNoNativeActiveXShimSwitch);
    } else if (strcmp(test_info->name(), "FlashSecurity") == 0) {
      launch_arguments_.AppendSwitchWithValue(switches::kTestSandbox,
                                              L"security_tests.dll");
    }

    UITest::SetUp();
  }

  void TestPlugin(const std::wstring& test_case, int timeout) {
    GURL url = GetTestUrl(test_case);
    NavigateToURL(url);
    WaitForFinish(timeout);
  }

  // Generate the URL for testing a particular test.
  // HTML for the tests is all located in test_directory\plugin\<testcase>
  GURL GetTestUrl(const std::wstring &test_case) {
    std::wstring path;
    PathService::Get(chrome::DIR_TEST_DATA, &path);
    file_util::AppendToPath(&path, L"plugin");
    file_util::AppendToPath(&path, test_case);
    return net::FilePathToFileURL(path);
  }

  // Waits for the test case to finish.
  void WaitForFinish(const int wait_time) {
    const int kSleepTime = 500;      // 2 times per second
    const int kMaxIntervals = wait_time / kSleepTime;

    GURL url = GetTestUrl(L"done");
    scoped_ptr<TabProxy> tab(GetActiveTab());

    std::string done_str;
    for (int i = 0; i < kMaxIntervals; ++i) {
      Sleep(kSleepTime);

      // The webpage being tested has javascript which sets a cookie
      // which signals completion of the test.
      std::string cookieName = kTestCompleteCookie;
      tab->GetCookieByName(url, cookieName, &done_str);
      if (!done_str.empty())
        break;
    }

    EXPECT_EQ(kTestCompleteSuccess, done_str);
  }
};

TEST_F(PluginTest, Quicktime) {
  TestPlugin(L"quicktime.html", kShortWaitTimeout);
}

TEST_F(PluginTest, MediaPlayerNew) {
  TestPlugin(L"wmp_new.html", kShortWaitTimeout);
}

// http://crbug.com/4809
TEST_F(PluginTest, DISABLED_MediaPlayerOld) {
  TestPlugin(L"wmp_old.html", kLongWaitTimeout);
}

TEST_F(PluginTest, Real) {
  TestPlugin(L"real.html", kShortWaitTimeout);
}

TEST_F(PluginTest, Flash) {
  TestPlugin(L"flash.html", kShortWaitTimeout);
}

TEST_F(PluginTest, FlashOctetStream) {
  TestPlugin(L"flash-octet-stream.html", kShortWaitTimeout);
}

TEST_F(PluginTest, FlashSecurity) {
  TestPlugin(L"flash.html", kShortWaitTimeout);
}

TEST_F(PluginTest, Java) {
  TestPlugin(L"Java.html", kShortWaitTimeout);
}

TEST_F(PluginTest, Silverlight) {
  TestPlugin(L"silverlight.html", kShortWaitTimeout);
}

typedef HRESULT (__stdcall* DllRegUnregServerFunc)();

class ActiveXTest : public PluginTest {
 public:
  ActiveXTest() {
    dll_registered = false;
  }
 protected:
  void TestActiveX(const std::wstring& test_case, int timeout, bool reg_dll) {
    if (reg_dll) {
      RegisterTestControl(true);
      dll_registered = true;
    }
    TestPlugin(test_case, timeout);
  }
  virtual void TearDown() {
    PluginTest::TearDown();
    if (dll_registered)
      RegisterTestControl(false);
  }
  void RegisterTestControl(bool register_server) {
    std::wstring test_control_path = browser_directory_ +
        L"\\activex_test_control.dll";
    HMODULE h = LoadLibrary(test_control_path.c_str());
    ASSERT_TRUE(h != NULL) << "Failed to load activex_test_control.dll";
    const char* func_name = register_server ?
                                "DllRegisterServer" : "DllUnregisterServer";
    DllRegUnregServerFunc func = reinterpret_cast<DllRegUnregServerFunc>(
        GetProcAddress(h, func_name));
    // This should never happen actually.
    ASSERT_TRUE(func != NULL) << "Failed to find reg/unreg function.";
    HRESULT hr = func();
    const char* error_message = register_server ? "Failed to register dll."
                                                : "Failed to unregister dll";
    ASSERT_TRUE(SUCCEEDED(hr)) << error_message;
    FreeLibrary(h);
  }
 private:
  bool dll_registered;
};

TEST_F(ActiveXTest, EmbeddedWMP) {
  TestActiveX(L"activex_embedded_wmp.html", kLongWaitTimeout, false);
}

TEST_F(ActiveXTest, WMP) {
  TestActiveX(L"activex_wmp.html", kLongWaitTimeout, false);
}

TEST_F(ActiveXTest, CustomScripting) {
  TestActiveX(L"activex_custom_scripting.html", kShortWaitTimeout, true);
}

<|endoftext|>