示例#1
0
void RimeWithWeaselHandler::_UpdateUI(UINT session_id)
{
	weasel::Status weasel_status;
	weasel::Context weasel_context;

	bool is_tsf = _IsSessionTSF(session_id);

	if (session_id == 0)
		weasel_status.disabled = m_disabled;

	_GetStatus(weasel_status, session_id);

	if (!is_tsf) {
		_GetContext(weasel_context, session_id);
	}

	if (!m_ui) return;
	if (RimeGetOption(session_id, "inline_preedit"))
		m_ui->style().client_caps |= weasel::INLINE_PREEDIT_CAPABLE;
	else
		m_ui->style().client_caps &= ~weasel::INLINE_PREEDIT_CAPABLE;


	if (weasel_status.composing)
	{
		m_ui->Update(weasel_context, weasel_status);
		if (!is_tsf) m_ui->Show();
	}
	else if (!_ShowMessage(weasel_context, weasel_status))
	{
		m_ui->Hide();
		m_ui->Update(weasel_context, weasel_status);
	}
	
	// Dangerous, don't touch
	static char app_name[50];
	RimeGetProperty(session_id, "client_app", app_name, sizeof(app_name) - 1);
	if (utf8towcs(app_name) == std::wstring(L"explorer.exe") && m_vista_greater) {
		boost::thread th([=]() {
			::Sleep(100);
			if (_UpdateUICallback) _UpdateUICallback();
		});
	}
	else {
		if (_UpdateUICallback) _UpdateUICallback();
	}

	m_message_type.clear();
	m_message_value.clear();
}
示例#2
0
void RimeWithWeaselHandler::_UpdateUI(UINT session_id)
{
	weasel::Status weasel_status;
	weasel::Context weasel_context;
	if (session_id == 0)
		weasel_status.disabled = m_disabled;

	RimeStatus status = {0};
	RIME_STRUCT_INIT(RimeStatus, status);
	if (RimeGetStatus(session_id, &status))
	{
		weasel_status.schema_name = utf8towcs(status.schema_name);
		weasel_status.ascii_mode = status.is_ascii_mode;
		weasel_status.composing = status.is_composing;
		weasel_status.disabled = status.is_disabled;
		RimeFreeStatus(&status);
	}

	RimeContext ctx = {0};
	RIME_STRUCT_INIT(RimeContext, ctx);
	if (RimeGetContext(session_id, &ctx))
	{
		if (ctx.composition.length > 0)
		{
			weasel_context.preedit.str = utf8towcs(ctx.composition.preedit);
			if (ctx.composition.sel_start < ctx.composition.sel_end)
			{
				weasel::TextAttribute attr;
				attr.type = weasel::HIGHLIGHTED;
				attr.range.start = utf8towcslen(ctx.composition.preedit, ctx.composition.sel_start);
				attr.range.end = utf8towcslen(ctx.composition.preedit, ctx.composition.sel_end);
			
				weasel_context.preedit.attributes.push_back(attr);
			}
		}
		if (ctx.menu.num_candidates)
		{
			weasel::CandidateInfo &cinfo(weasel_context.cinfo);
			cinfo.candies.resize(ctx.menu.num_candidates);
			cinfo.comments.resize(ctx.menu.num_candidates);
			for (int i = 0; i < ctx.menu.num_candidates; ++i)
			{
				cinfo.candies[i].str = utf8towcs(ctx.menu.candidates[i].text);
				if (ctx.menu.candidates[i].comment)
				{
					cinfo.comments[i].str = utf8towcs(ctx.menu.candidates[i].comment);
				}
			}
			cinfo.highlighted = ctx.menu.highlighted_candidate_index;
			cinfo.currentPage = ctx.menu.page_no;
			cinfo.labels = ctx.menu.select_keys;
		}
		RimeFreeContext(&ctx);
	}

	if (!m_ui) return;
	if (RimeGetOption(session_id, "inline_preedit"))
		m_ui->style().client_caps |= weasel::INLINE_PREEDIT_CAPABLE;
	else
		m_ui->style().client_caps &= ~weasel::INLINE_PREEDIT_CAPABLE;
	if (weasel_status.composing)
	{
		m_ui->Update(weasel_context, weasel_status);
		m_ui->Show();
	}
	else if (!_ShowMessage(weasel_context, weasel_status))
	{
		m_ui->Hide();
		m_ui->Update(weasel_context, weasel_status);
	}

	m_message_type.clear();
	m_message_value.clear();
}
示例#3
0
bool RimeWithWeaselHandler::_Respond(UINT session_id, EatLine eat)
{
	std::set<std::string> actions;
	std::list<std::string> messages;

	// extract information

	RIME_STRUCT(RimeCommit, commit);
	if (RimeGetCommit(session_id, &commit))
	{
		actions.insert("commit");
		messages.push_back(std::string("commit=") + commit.text + '\n');
		RimeFreeCommit(&commit);
	}
	
	bool is_composing = false;
	RIME_STRUCT(RimeStatus, status);
	if (RimeGetStatus(session_id, &status))
	{
		is_composing = !!status.is_composing;
		actions.insert("status");
		messages.push_back(std::string("status.ascii_mode=") + std::to_string(status.is_ascii_mode) + '\n');
		messages.push_back(std::string("status.composing=") + std::to_string(status.is_composing) + '\n');
		messages.push_back(std::string("status.disabled=") + std::to_string(status.is_disabled) + '\n');
		RimeFreeStatus(&status);
	}
	
	RIME_STRUCT(RimeContext, ctx);
	if (RimeGetContext(session_id, &ctx))
	{
		if (is_composing)
		{
			actions.insert("ctx");
			switch (m_ui->style().preedit_type)
			{
			case weasel::UIStyle::PREVIEW:
				if (ctx.commit_text_preview != NULL)
				{
					std::string first = ctx.commit_text_preview;
					messages.push_back(std::string("ctx.preedit=") + first + '\n');
					messages.push_back(std::string("ctx.preedit.cursor=") +
						std::to_string(utf8towcslen(first.c_str(), 0)) + ',' +
						std::to_string(utf8towcslen(first.c_str(), first.size())) + '\n');
					break;
				}
				// no preview, fall back to composition
			case weasel::UIStyle::COMPOSITION:
				messages.push_back(std::string("ctx.preedit=") + ctx.composition.preedit + '\n');
				if (ctx.composition.sel_start <= ctx.composition.sel_end)
				{
					messages.push_back(std::string("ctx.preedit.cursor=") +
						std::to_string(utf8towcslen(ctx.composition.preedit, ctx.composition.sel_start)) + ',' +
						std::to_string(utf8towcslen(ctx.composition.preedit, ctx.composition.sel_end)) + '\n');
				}
				break;
			}
		}
		if (ctx.menu.num_candidates)
		{
			weasel::CandidateInfo cinfo;
			std::wstringstream ss;
			boost::archive::text_woarchive oa(ss);
			_GetCandidateInfo(cinfo, ctx);

			oa << cinfo;

			messages.push_back(std::string("ctx.cand=") + wcstoutf8(ss.str().c_str()) + '\n');
		}
		RimeFreeContext(&ctx);
	}

	// configuration information
	actions.insert("config");
	messages.push_back(std::string("config.inline_preedit=") + std::to_string((int)m_ui->style().inline_preedit) + '\n');

	// style
	bool has_synced = RimeGetOption(session_id, "__synced");
	if (!has_synced) {
		std::wstringstream ss;
		boost::archive::text_woarchive oa(ss);
		oa << m_ui->style();

		actions.insert("style");
		messages.push_back(std::string("style=") + wcstoutf8(ss.str().c_str()) + '\n');
		RimeSetOption(session_id, "__synced", true);
	}

	// summarize

	if (actions.empty())
	{
		messages.insert(messages.begin(), std::string("action=noop\n"));
	}
	else
	{
		std::string actionList(join(actions, ","));
		messages.insert(messages.begin(), std::string("action=") + actionList + '\n');
	}

	messages.push_back(std::string(".\n"));

	return std::all_of(messages.begin(), messages.end(), [&eat](std::string &msg)
	{
		return eat(std::wstring(utf8towcs(msg.c_str())));
	});
}