コード例 #1
0
	void NotificationsManager::NotifyWithReason (QObject *entryObj, const QString& msg,
			const char *func, const QString& eventType,
			const QString& patternLite, const QString& patternFull)
	{
		const auto entry = qobject_cast<ICLEntry*> (entryObj);
		if (!entry)
		{
			qWarning () << func
					<< entryObj
					<< "doesn't implement ICLEntry";
			return;
		}

		const auto& str = msg.isEmpty () ?
				patternLite
					.arg (entry->GetEntryName ())
					.arg (entry->GetHumanReadableID ()) :
				patternFull
					.arg (entry->GetEntryName ())
					.arg (entry->GetHumanReadableID ())
					.arg (msg);

		auto e = Util::MakeNotification ("Azoth", str, PInfo_);
		BuildNotification (e, entry, "Event");
		e.Additional_ ["org.LC.AdvNotifications.EventType"] = eventType;
		e.Additional_ ["org.LC.AdvNotifications.FullText"] = str;
		e.Additional_ ["org.LC.AdvNotifications.Count"] = 1;
		e.Additional_ ["org.LC.Plugins.Azoth.Msg"] = msg;

		EntityMgr_->HandleEntity (e);
	}
コード例 #2
0
	MUCInviteDialog::MUCInviteDialog (IAccount *acc, ListType type, QWidget *parent)
	: QDialog (parent)
	, ManualMode_ (false)
	{
		Ui_.setupUi (this);
		Ui_.Invitee_->setInsertPolicy (QComboBox::NoInsert);

		ICLEntry::EntryType requestedType = ICLEntry::EntryType::Chat;
		switch (type)
		{
		case ListType::ListEntries:
			break;
		case ListType::ListMucs:
			requestedType = ICLEntry::EntryType::MUC;
			Ui_.InviteeLabel_->setText ("Conferences:");
			break;
		}

		for (auto entryObj : acc->GetCLEntries ())
		{
			const auto entry = qobject_cast<ICLEntry*> (entryObj);
			if (!entry ||
					entry->GetEntryType () != requestedType)
				continue;

			const QString& id = entry->GetHumanReadableID ();
			Ui_.Invitee_->addItem (QString ("%1 (%2)")
						.arg (entry->GetEntryName ())
						.arg (id),
					id);
		}
	}
コード例 #3
0
ファイル: util.cpp プロジェクト: MellonQ/leechcraft
	QStringList GetMucParticipants (const QString& entryId)
	{
		const auto entry = qobject_cast<IMUCEntry*> (Core::Instance ().GetEntry (entryId));
		if (!entry)
		{
			qWarning () << Q_FUNC_INFO
					<< entry
					<< "doesn't implement IMUCEntry";
			return {};
		}

		QStringList participantsList;
		for (const auto item : entry->GetParticipants ())
		{
			const auto part = qobject_cast<ICLEntry*> (item);
			if (!part)
			{
				qWarning () << Q_FUNC_INFO
						<< "unable to cast item to ICLEntry"
						<< item;
				continue;
			}
			participantsList << part->GetEntryName ();
		}
		return participantsList;
	}
コード例 #4
0
ファイル: metaentry.cpp プロジェクト: ForNeVeR/leechcraft
	QStringList MetaEntry::Variants () const
	{
		QStringList result;
		for (const auto entryObj : AvailableRealEntries_)
		{
			const auto entry = qobject_cast<ICLEntry*> (entryObj);

			const auto& name = entry->GetEntryName ();
			auto variants = entry->Variants ();
			if (!variants.contains (QString ()))
				variants.prepend (QString ());
			for (const auto& var : variants)
			{
				const auto& full = name + '/' + var;
				if (!Variant2RealVariant_.contains (full))
				{
					qWarning () << Q_FUNC_INFO
							<< "skipping out-of-sync with variant map:"
							<< name
							<< var
							<< Variant2RealVariant_;
					continue;
				}

				result << full;
			}
		}
		return result;
	}
コード例 #5
0
ファイル: core.cpp プロジェクト: MellonQ/leechcraft
	void Core::Process (QObject *msgObj)
	{
		IMessage *msg = qobject_cast<IMessage*> (msgObj);
		if (msg->GetMessageType () != IMessage::Type::ChatMessage &&
			msg->GetMessageType () != IMessage::Type::MUCMessage)
			return;

		if (msg->GetBody ().isEmpty ())
			return;

		if (msg->GetDirection () == IMessage::Direction::Out &&
				msg->GetMessageType () == IMessage::Type::MUCMessage)
			return;

		const double secsDiff = msg->GetDateTime ().secsTo (QDateTime::currentDateTime ());
		if (msg->GetMessageType () == IMessage::Type::MUCMessage &&
				std::abs (secsDiff) >= 2)
			return;

		ICLEntry *entry = qobject_cast<ICLEntry*> (msg->ParentCLEntry ());
		if (!entry)
		{
			qWarning () << Q_FUNC_INFO
					<< "message's other part doesn't implement ICLEntry"
					<< msg->GetQObject ()
					<< msg->OtherPart ();
			return;
		}
		if (DisabledIDs_.contains (entry->GetEntryID ()))
			return;

		const auto acc = entry->GetParentAccount ();

		QVariantMap data;
		data ["EntryID"] = entry->GetEntryID ();
		data ["AccountID"] = acc->GetAccountID ();
		data ["DateTime"] = msg->GetDateTime ();
		data ["Direction"] = msg->GetDirection () == IMessage::Direction::In ? "IN" : "OUT";
		data ["Body"] = msg->GetBody ();
		data ["OtherVariant"] = msg->GetOtherVariant ();
		data ["Type"] = static_cast<int> (msg->GetMessageType ());
		data ["EscapePolicy"] = msg->GetEscapePolicy () == IMessage::EscapePolicy::Escape ? "Esc" : "NEs";

		if (const auto irtm = qobject_cast<IRichTextMessage*> (msgObj))
			data ["RichBody"] = irtm->GetRichBody ();

		if (entry->GetEntryType () == ICLEntry::EntryType::PrivateChat)
		{
			const auto parent = entry->GetParentCLEntry ();
			data ["VisibleName"] = parent->GetEntryName () + "/" + entry->GetEntryName ();
		}
		else
			data ["VisibleName"] = entry->GetEntryName ();

		QMetaObject::invokeMethod (StorageThread_->GetStorage (),
				"addMessage",
				Qt::QueuedConnection,
				Q_ARG (QVariantMap, data));
	}
コード例 #6
0
ファイル: toxcontact.cpp プロジェクト: MellonQ/leechcraft
	void ToxContact::SetEntryName (const QString& name)
	{
		if (name == PublicName_)
			return;

		PublicName_ = name;
		emit nameChanged (GetEntryName ());
	}
コード例 #7
0
ファイル: LibrarySys.cpp プロジェクト: asceth/synapi
bool CDirectory::IsEntryDirectory()
{
#if defined PLATFORM_WINDOWS
	return ((m_fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
#elif defined PLATFORM_POSIX
	char temppath[PLATFORM_MAX_PATH];
	snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
	return g_LibSys.IsPathDirectory(temppath);
#endif
}
コード例 #8
0
ファイル: glooxclentry.cpp プロジェクト: Kalarel/leechcraft
	void GlooxCLEntry::RerequestAuth (const QString& reason)
	{
		if (ODS_)
			return;

		Account_->GetClientConnection ()->Subscribe (GetJID (),
				reason,
				GetEntryName (),
				Groups ());
	}
コード例 #9
0
bool CDirectory::IsEntryFile()
{
#if defined PLATFORM_WINDOWS
	return !(m_fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE));
#elif defined PLATFORM_POSIX
	char temppath[PLATFORM_MAX_PATH];
	snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
	return ke::file::IsFile(temppath);
#endif
}
コード例 #10
0
	void NotificationsManager::handleAttentionDrawn (const QString& text, const QString&)
	{
		if (XmlSettingsManager::Instance ()
				.property ("IgnoreDrawAttentions").toBool ())
			return;

		const auto entry = qobject_cast<ICLEntry*> (sender ());
		if (!entry)
		{
			qWarning () << Q_FUNC_INFO
					<< sender ()
					<< "doesn't implement ICLEntry";
			return;
		}

		const auto& str = text.isEmpty () ?
				tr ("%1 requests your attention")
					.arg (entry->GetEntryName ()) :
				tr ("%1 requests your attention: %2")
					.arg (entry->GetEntryName ())
					.arg (text);

		auto e = Util::MakeNotification ("Azoth", str, PInfo_);
		BuildNotification (e, entry, "AttentionDrawnBy");
		e.Additional_ ["org.LC.AdvNotifications.DeltaCount"] = 1;
		e.Additional_ ["org.LC.AdvNotifications.EventType"] = AN::TypeIMAttention;
		e.Additional_ ["org.LC.AdvNotifications.ExtendedText"] = tr ("Attention requested");
		e.Additional_ ["org.LC.AdvNotifications.FullText"] = tr ("Attention requested by %1")
				.arg (entry->GetEntryName ());
		e.Additional_ ["org.LC.Plugins.Azoth.Msg"] = text;

		const auto nh = new Util::NotificationActionHandler { e, this };
		nh->AddFunction (tr ("Open chat"),
				[entry, this] { Core::Instance ().GetChatTabsManager ()->OpenChat (entry, true); });
		nh->AddDependentObject (entry->GetQObject ());

		EntityMgr_->HandleEntity (e);
	}
コード例 #11
0
	void NotificationsManager::handleAuthorizationRequested (QObject *entryObj, const QString& msg)
	{
		const auto& proxy = std::make_shared<Util::DefaultHookProxy> ();
		emit hookGotAuthRequest (proxy, entryObj, msg);
		if (proxy->IsCancelled ())
			return;

		const auto entry = qobject_cast<ICLEntry*> (entryObj);
		if (!entry)
		{
			qWarning () << Q_FUNC_INFO
					<< entryObj
					<< "doesn't implement ICLEntry";
			return;
		}

		const auto& str = msg.isEmpty () ?
				tr ("Subscription requested by %1.")
					.arg (entry->GetEntryName ()) :
				tr ("Subscription requested by %1: %2.")
					.arg (entry->GetEntryName ())
					.arg (msg);
		auto e = Util::MakeNotification ("Azoth", str, PInfo_);

		BuildNotification (e, entry, "AuthRequestFrom");
		e.Additional_ ["org.LC.AdvNotifications.EventType"] = AN::TypeIMSubscrRequest;
		e.Additional_ ["org.LC.AdvNotifications.FullText"] = str;
		e.Additional_ ["org.LC.AdvNotifications.Count"] = 1;
		e.Additional_ ["org.LC.Plugins.Azoth.Msg"] = msg;

		const auto nh = new Util::NotificationActionHandler (e, this);
		nh->AddFunction (tr ("Authorize"), [this, entry] () { AuthorizeEntry (entry); });
		nh->AddFunction (tr ("Deny"), [this, entry] () { DenyAuthForEntry (entry); });
		nh->AddFunction (tr ("View info"), [entry] () { entry->ShowInfo (); });
		nh->AddDependentObject (entry->GetQObject ());
		EntityMgr_->HandleEntity (e);
	}
コード例 #12
0
	void Buddy::Update ()
	{
		if (Name_ != GetEntryName ())
		{
			Name_ = GetEntryName ();
			emit nameChanged (Name_);
		}

		auto purpleStatus = purple_presence_get_active_status (Buddy_->presence);
		const auto& status = FromPurpleStatus (Account_->GetPurpleAcc (), purpleStatus);
		if (status != Status_)
		{
			Status_ = status;
			emit statusChanged (Status_, QString ());
		}

		auto groupNode = purple_buddy_get_group (Buddy_);
		const auto& newGroup = groupNode ? QString::fromUtf8 (groupNode->name) : QString ();
		if (newGroup != Group_)
		{
			Group_ = newGroup;
			emit groupsChanged ({ Group_ });
		}
	}
コード例 #13
0
bool CDirectory::IsEntryFile()
{
#if defined PLATFORM_WINDOWS

	return !(m_fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE));

#elif defined PLATFORM_POSIX

	char temppath[PLATFORM_MAX_PATH];
	UTIL_Format(temppath, sizeof(temppath) - 1, "%s/%s", m_origpath, GetEntryName());

	return g_LibSys.IsPathFile(temppath);

#endif
}
コード例 #14
0
ファイル: mucjoinwidget.cpp プロジェクト: AlexWMF/leechcraft
	void MucJoinWidget::AccountSelected (QObject *accObj)
	{
		UsersModel_->clear ();

		auto acc = qobject_cast<VkAccount*> (accObj);
		for (auto entryObj : acc->GetCLEntries ())
		{
			auto entry = qobject_cast<VkEntry*> (entryObj);
			if (!entry)
				continue;

			auto item = new QStandardItem (entry->GetEntryName ());
			item->setEditable (false);
			item->setData (QVariant::fromValue (entryObj), Role::EntryObj);
			item->setCheckable (true);
			item->setCheckState (Qt::Unchecked);
			UsersModel_->appendRow (item);
		}
	}
コード例 #15
0
ファイル: FileSystem.c プロジェクト: withmelody/SW_Project
int EnumerateDirStatus(const char* pDirName, DirEntry* pDirEntry, int dirEntries)
{
/*
 * precondition		: usage ) EnumerateDirStatus(pDirName, pDirEntry, dirEntries);
 * postcondition	: 디렉토리에 포함된 파일 또는 디렉토리 정보를 얻어낸다.
 * 					  이 함수는 해당 디렉토리를 구성하고 있는 디렉토리 엔트리들의
 * 					  묶음을 리턴한다.
 * 					  성공하면 읽어진 디렉토리 엔트리 개수를 리턴한다. 예로, 임의의 디렉토리의 전체
 * 					  디렉토리 엔트리 개수가 40이지만, dirEntries가 60으로 입력됬을때, 리턴되는 값은
 * 					  유효한 디렉토리 엔트리 개수인 40을 리턴해야 한다. 또한, 40개의 디렉토리 엔트리
 * 					  내용을 pDirEntry 배열로 전달해야 한다. 또한, 전체 디렉토리 엔트리 개수가 40이지만
 * 					  dirEntry가 20으로 입력되었을 때, 리턴되는 값은 20이며, 20개의 디렉토리 엔트리의
 * 					  내용이 pDirEntry로 리턴되어야 한다. 에러 발생시 -1을 리턴한다.
 */
	char dirname[NAME_LEN_MAX] = {NULL,};
	char* abspath = malloc(strlen(pDirName) + 1);
	char* ptr = abspath;
	DirEntry* dirEntry = pDirEntry;
	InodeInfo inodeInfo;
	DirBlock dirBlock;
	int i = 0, j = 0;
	int found = 0;
	int	cnt = 0;

	memcpy(abspath, pDirName, strlen(pDirName) + 1);

	GetEntryName(dirname, abspath);	// dirname 최종 디렉토리명
	ReadInode(&inodeInfo, fileSysInfo.rootInodeNum);

	ptr = strtok(abspath, "/");
	if (ptr == NULL && strcmp(dirname,"") == 0)		// root directory 일때
	{
		for ( i = 0 ; i < inodeInfo.blocks ; i++ )
		{
			ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
			for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++)
			{
				if ( strcmp(dirBlock.dirEntries[j].name, "") != 0)
				{
					memcpy(dirEntry, &dirBlock.dirEntries[j], sizeof(DirEntry));
					dirEntry++;
					cnt++;
				}
				if ( cnt == dirEntries )
				{
					free(abspath);
					return cnt;
				}
			}
		}
		free(abspath);
		return cnt;
	}
	while(ptr)
	{ // root 내부로 들어감
		for ( i = 0 ; i < inodeInfo.blocks ; i++ )
		{
			ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
			for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++ )
			{
				if( strcmp(ptr, dirBlock.dirEntries[j].name) == 0
						&& dirBlock.dirEntries[j].type == FILE_TYPE_DIR)
				{
					ReadInode(&inodeInfo, dirBlock.dirEntries[j].inodeNum);
					found++;
					break;
				}
			}
			if( found == 1 )
			{
				found = 0;
				break;
			}
		}
		ptr = strtok(NULL, "/");
	}
	// 찾는 디렉토리가 없음
	if ( j == MAX_INDEX_OF_DIRBLK )		return WRONG_VALUE;

	for ( i = 0 ; i < inodeInfo.blocks ; i++ )
	{
		ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
		for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++)
		{
//			if ( strcmp(dirBlock.dirEntries[j].name, "") != 0)
			if ( strcmp(dirBlock.dirEntries[j].name, "") != 0
					&& strcmp(dirBlock.dirEntries[j].name, ".") != 0
					&& strcmp(dirBlock.dirEntries[j].name, "..") != 0)
			{
				memcpy(dirEntry, &dirBlock.dirEntries[j], sizeof(DirEntry));
				dirEntry++;
				cnt++;
			}
			if ( cnt == dirEntries )
			{
				free(abspath);
				return cnt;
			}
		}
	}
	free(abspath);
	return cnt;
}
コード例 #16
0
ファイル: FileSystem.c プロジェクト: withmelody/SW_Project
int RemoveDir(const char* pDirName)
{
/*
 * precondition		: usage ) RemoveDir(pDirName);
 * postcondition	: 디렉토리를 제거한다. 단, 리눅스 파일 시스템처럼 빈 디렉토리만 제거가 가능하다.
 * 					  성공하면 0을 리턴한다. 실패 했을 때는 -1을 리턴한다.
 * 					  실패 원인은 다음과 같다.
 * 					  1) 디렉토리에 파일 또는 하위 디렉토리가 존재 할 경우
 * 					  2) 제거하고자 하는 디렉토리가 없을 경우
 */
	char dirname[NAME_LEN_MAX] = {NULL,};
	char* abspath = malloc(strlen(pDirName) + 1);
	char* ptr = abspath;
	InodeInfo inodeInfo;
	DirBlock dirBlock;
	int i = 0, j = 0;
	int found = 0;

	memcpy(abspath, pDirName, strlen(pDirName) + 1);

	GetEntryName(dirname, abspath);	// dirname 최종 디렉토리명
	GetEntryPath(abspath, dirname);	// abspath는 dirname을 제외한 path
	ReadInode(&inodeInfo, fileSysInfo.rootInodeNum);

	ptr = strtok(abspath, "/");
	if (ptr == NULL && strcmp(dirname, "") == 0)			// root directory block에서 지울때
	{
		if ( RemoveDirentry(&inodeInfo, dirname) == WRONG_VALUE )
		{
			fprintf(stderr, "* RemoveDirentry() error!\n");
			return WRONG_VALUE;
		}
		free(abspath);
		return 0;
	}
	while(ptr)
	{ // root 내부로 들어감
		for ( i = 0 ; i < inodeInfo.blocks ; i++ )
		{
			ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
			for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++ )
			{
				if( strcmp(ptr, dirBlock.dirEntries[j].name) == 0
						&& dirBlock.dirEntries[j].type == FILE_TYPE_DIR)
				{
					ReadInode(&inodeInfo, dirBlock.dirEntries[j].inodeNum);
					found++;
					break;
				}
			}
			if( found == 1 )
			{
				found = 0;
				break;
			}
		}
		ptr = strtok(NULL, "/");
	}
	// 찾는 디렉토리가 없음
	if ( j == MAX_INDEX_OF_DIRBLK )		return WRONG_VALUE;

	if ( RemoveDirentry(&inodeInfo, dirname) == WRONG_VALUE)
	{
		free(abspath);
		return WRONG_VALUE;
	}
	free(abspath);
	return 0;
}
コード例 #17
0
ファイル: FileSystem.c プロジェクト: withmelody/SW_Project
int MakeDir(const char* pDirName)
{
/*
 * precondition		: usage ) MakeFir(pDirName);
 * postcondition	: 디렉토리를 생성한다.
 * 					  성공하면 0을 리턴한다. 실패 했을 때는 -1을 리턴한다.
 * 					  실패 원인은 생성하고자 하는 디렉토리의 이름과
 * 					  동일한 디렉토리 또는 파일이 존재할 경우이다.
 */
	char dirname[NAME_LEN_MAX] = {NULL,};
	char* abspath = malloc(strlen(pDirName) + 1);
	char* ptr = abspath;
	InodeInfo inodeInfo;
	DirBlock dirBlock;
	int i = 0, j = 0;
	int found = 0;

	memcpy(abspath, pDirName, strlen(pDirName) + 1);

	GetEntryName(dirname, abspath);		// dirname 최종 디렉토리명
	GetEntryPath(abspath, dirname);	// abspath는 dirname을 제외한 path
	ReadInode(&inodeInfo, fileSysInfo.rootInodeNum);

	ptr = strtok(abspath, "/");
	if (!ptr)			// root directory block에 생성할때
	{
		if ( MakeDirentry(&inodeInfo, dirname) == WRONG_VALUE )
		{
			fprintf(stderr, "* MakeDirentry() error!\n");
			return WRONG_VALUE;
		}
		free(abspath);
		return 0;
	}
	while(ptr)
	{ // root directory block에 생성하지 않고 더 내부로 들어감
		for ( i = 0 ; i < inodeInfo.blocks ; i++ )
		{
			ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
			for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++ )
			{
				if( strcmp(ptr, dirBlock.dirEntries[j].name) == 0
					&& dirBlock.dirEntries[j].type == FILE_TYPE_DIR)
				{
					ReadInode(&inodeInfo, dirBlock.dirEntries[j].inodeNum);
					found++;
					break;
				}
			}
			if( found == 1 )
			{
				found = 0;
				break;
			}
		}
		ptr = strtok(NULL, "/");
	}
	if ( j == MAX_INDEX_OF_DIRBLK )		return WRONG_VALUE;

	if ( MakeDirentry(&inodeInfo, dirname) == WRONG_VALUE)
	{
		free(abspath);
		return WRONG_VALUE;
	}
	free(abspath);
	return 0;
}
コード例 #18
0
ファイル: FileSystem.c プロジェクト: withmelody/SW_Project
int RemoveFile(const char* pFileName)
{
/*
 * precondition		: usage ) RemoveFile(pFileName);
 * postcondition	: 파일을 제거한다. 단, open된 파일을 제거 할 수 없다.
 * 					  성공하면 0을 리턴한다. 실패 했을 때는 -1을 리턴한다.
 * 					  실패 원인은 다음과 같다.
 * 					  1) 제거할 파일 이름이 없을 경우
 * 					  2) 제거될 파일이 open 되어 있을 경우
 */
	char filename[NAME_LEN_MAX] = {NULL,};
	char* abspath = malloc(strlen(pFileName) + 1);
	char* ptr = abspath;
	InodeInfo inodeInfo;
	DirBlock dirBlock;
	int i = 0, j = 0;
	int found = 0;
	int parent_blockno = 0;
	memcpy(abspath, pFileName, strlen(pFileName) + 1);

	GetEntryName(filename, abspath);	// dirname 최종 디렉토리명
//	GetEntryPath(abspath, filename);	// abspath는 dirname을 제외한 path
	ReadInode(&inodeInfo, fileSysInfo.rootInodeNum);

	ptr = strtok(abspath, "/");
	while(ptr)
	{ // root 내부로 들어감
		for ( i = 0 ; i < inodeInfo.blocks ; i++ )
		{
			ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
			for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++ )
			{
				if( strcmp(ptr, dirBlock.dirEntries[j].name) == 0
						&& dirBlock.dirEntries[j].type == FILE_TYPE_DIR )
				{
					parent_blockno = inodeInfo.i_block[i];
					ReadInode(&inodeInfo, dirBlock.dirEntries[j].inodeNum);
					found++;
					break;
				}
				else if ( strcmp(filename, dirBlock.dirEntries[j].name) == 0
						&& dirBlock.dirEntries[j].type == FILE_TYPE_FILE)
				{
					parent_blockno = inodeInfo.i_block[i];
					ReadInode(&inodeInfo, dirBlock.dirEntries[j].inodeNum);
					found++;
					break;
				}
			}
			if( found == 1 )
			{
				found = 0;
				break;
			}
		}
		ptr = strtok(NULL, "/");
	}
	// 찾는 중간 디렉토리가 없음
	if ( j == MAX_INDEX_OF_DIRBLK )		return WRONG_VALUE;

///////////////////////////////////////////////////
// 여기부터 해당 파일 삭제
	// 사용중인 block 해제
	for ( i = 0 ; i < inodeInfo.blocks ; i++ )
	{
		if(SetBlockAllocToFree(inodeInfo.i_block[i]) == WRONG_VALUE)
		{
			fprintf(stderr, "* RemoveFile() Error!\n");
			return WRONG_VALUE;
		}
	}
	// 사용중인 inode 삭제
	for ( i = 0 ; i < MAX_INDEX_OF_DIRBLK ; i++ )
	{
		if ( strcmp(dirBlock.dirEntries[i].name, filename) == 0 )
		{
			if( SetInodeAllocToFree(dirBlock.dirEntries[i].inodeNum) == WRONG_VALUE)
			{
				fprintf(stderr, "* RemoveFile() Error!\n");
				return WRONG_VALUE;
			}
			strcpy(dirBlock.dirEntries[i].name, "");
			WriteDirBlock(&dirBlock, parent_blockno);
			break;
		}
	}
//
///////////////////////////////////////////////////
}
コード例 #19
0
ファイル: FileSystem.c プロジェクト: withmelody/SW_Project
int	OpenFile(const char* pFileName, OpenFlag flag)
{
/*
 * precondition		: usage) OpenFile(absfilepath, flag);
 * 					  pFileName은 오픈할 파일의 이름. 단, 파일 이름은 절대경로이다.
 * 					  flag는 OPEN_FLAG_READWRITE, OPEN_FLAG_CREATE가 있다.
 * postcondition	: 파일을 open한다.
 *					  성공하면, file descriptor를 리턴한다.
 * 					  이 file descriptor는 file descriptor table의 entry의 index값으로 정의된다.
 * 					  실패했을때는 -1을 리턴한다.
 */
	InodeInfo	inodeInfo, newInode;
	DirBlock	dirBlock;
	char* 	abspath = malloc(strlen(pFileName) + 1);
	char* 	ptr = malloc(strlen(pFileName) + 1);
	char	filename[NAME_LEN_MAX];
	int 	i = 0, j = 0;
	int		found = 0;
	int		fd = 0;
	int		parent_inodeno = 0;
	int		current_inodeno = 0;

	strcpy(abspath, pFileName);
	strcpy(ptr, pFileName);

	memset(&newInode, 0, sizeof(InodeInfo));

	if (*ptr != '/')		// 절대경로의 시작이 '/'가 아닐때
	{
		free(abspath);
		free(ptr);
		return -1;
	}
	// root inode와 block을 읽음
	// filename에 파일 경로를 얻어냄
	if ( GetEntryName(filename, abspath) == WRONG_VALUE)
	{
		fprintf(stderr, "* GetEntryName error!\n");
		fprintf(stderr, "* filename is too long!\n");
	}
	GetEntryPath(abspath, filename);

	ReadInode(&inodeInfo, fileSysInfo.rootInodeNum);
	abspath = strtok(abspath, "/");
	while(abspath)
	{
		for ( i = 0 ; i < inodeInfo.blocks ; i++ )
		{
			if( inodeInfo.type == FILE_TYPE_DIR ) {
				ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
				for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++ )
				{
					if ( strcmp(dirBlock.dirEntries[j].name, abspath) == 0
							&& dirBlock.dirEntries[j].type == FILE_TYPE_DIR)
					{// 마지막 상위 디렉토리(찾는 파일 또는 디렉토리의 ..)를 찾으면
						ReadInode(&inodeInfo, dirBlock.dirEntries[j].inodeNum);
						parent_inodeno = dirBlock.dirEntries[j].inodeNum;
						found++;
						break;
					}
				}
				if ( found == 1 )
				{
					found = 0;
					break;
				}
			}
		}
		abspath = strtok(NULL, "/");
	}
	if ( strcmp(filename, "") == 0)	// 파일명이 없으면 실패리턴
	{
		if( i == inodeInfo.blocks )
		{
			free(abspath);
			free(ptr);
			return WRONG_VALUE;	// 블록 전부를 검색했지만 일치하는 결과가 없으므로 실패
		}
		if( found == 0)
		{
			free(abspath);
			free(ptr);
			return WRONG_VALUE; // dir을 못찾았을
		}
	}
	// 여기까지 왔으면 해당 디렉토리 찾은 것
	switch(flag)
	{
	case OPEN_FLAG_READWRITE:
		// 파일명 찾고 permission readwrite로
		for ( i = 0 ; i < inodeInfo.blocks ; i++ )
		{
			if( inodeInfo.type == FILE_TYPE_DIR )
				ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
			for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++ )
			{
				if ( strcmp(dirBlock.dirEntries[j].name, filename) == 0
						&& dirBlock.dirEntries[j].type == FILE_TYPE_FILE)
				{// 파일명 찾으면
					// permission read로
					ReadInode(&inodeInfo, dirBlock.dirEntries[j].inodeNum);
					inodeInfo.mode = FILE_MODE_READWRITE;
					for ( fd = 0 ; fd < FS_INODE_COUNT ; fd++ )
					{// 이미 open 했던 경우
						if ( fileDescTable.file[fd].inodeNo == dirBlock.dirEntries[j].inodeNum )
						{
							fileDescTable.file[fd].offset = 0;
							free(abspath);
							free(ptr);
							return fd;
						}
					}
					for ( fd = 0 ; fd < FS_INODE_COUNT ; fd++ )
					{// 처음 open 하는 경우
						if ( fileDescTable.file[fd].valid_bit == 0 )
						{
							fileDescTable.file[fd].inodeNo = dirBlock.dirEntries[j].inodeNum;
							fileDescTable.file[fd].offset = 0;
							fileDescTable.file[fd].valid_bit = 1;
							free(abspath);
							free(ptr);
							return fd;
						}
					}
				}
			}
		}

		break;
	case OPEN_FLAG_CREATE:
		// 파일명 찾고 있으면 덮어쓰고 없으면 생성
		// 파일명 찾고 permission readonly로
		// 파일이 존재할 경우
		for ( i = 0 ; i < inodeInfo.blocks ; i++ )
		{
			if( inodeInfo.type == FILE_TYPE_DIR )
				ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
			for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++ )
			{
				if ( strcmp(dirBlock.dirEntries[j].name, filename) == 0
						&& dirBlock.dirEntries[j].type == FILE_TYPE_FILE)
				{// 파일명 찾으면
					// permission readwrite로
					ReadInode(&inodeInfo, dirBlock.dirEntries[j].inodeNum);
					inodeInfo.mode = FILE_MODE_READWRITE;
					for ( fd = 0 ; fd < FS_INODE_COUNT ; fd++ )
					{// 이미 open 했던 경우
						if ( fileDescTable.file[fd].inodeNo == dirBlock.dirEntries[j].inodeNum )
						{
							fileDescTable.file[fd].offset = 0;
							free(abspath);
							free(ptr);
							return fd;
						}
					}
					for ( fd = 0 ; fd < FS_INODE_COUNT ; fd++ )
					{// 처음 open 하는 경우
						if ( fileDescTable.file[fd].valid_bit == 0 )
						{
							fileDescTable.file[fd].inodeNo = dirBlock.dirEntries[j].inodeNum;
							fileDescTable.file[fd].offset = 0;
							fileDescTable.file[fd].valid_bit = 1;
							free(abspath);
							free(ptr);
							return fd;
						}
					}
				}
			}
		}
		// 파일이 없어서 생성해야 하는 경우
		for ( i = 0 ; i < inodeInfo.blocks ; i++ )
		{
			if( inodeInfo.type == FILE_TYPE_DIR )
				ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
			for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++ )
			{
				if ( strcmp(dirBlock.dirEntries[j].name,"") == 0 )
				{// 엔트리가 비어있으면
					strcpy(dirBlock.dirEntries[j].name, filename);
					dirBlock.dirEntries[j].type = FILE_TYPE_FILE;
					dirBlock.dirEntries[j].inodeNum = GetFreeInode();
					WriteDirBlock(&dirBlock, inodeInfo.i_block[i]); // 변경된 상위디렉토리의 dirBlock 갱신

					newInode.size = 0;
					newInode.type = FILE_TYPE_FILE;
					newInode.mode = FILE_MODE_READWRITE;
					newInode.blocks = 1;
					newInode.i_block[0] = GetFreeBlock();

					WriteInode(&newInode, dirBlock.dirEntries[j].inodeNum);
					SetInodeFreeToAlloc();
					SetBlockFreeToAlloc();
					for ( fd = 0 ; fd < FS_INODE_COUNT ; fd++ )
					{// 파일 디스크립터 생성
						if ( fileDescTable.file[fd].valid_bit == 0 )
						{
							fileDescTable.file[fd].inodeNo = dirBlock.dirEntries[j].inodeNum;
							fileDescTable.file[fd].valid_bit = 1;
							free(abspath);
							free(ptr);
							return fd;
						}
					}
				}
			}
		}
		// 사용 가능한 다이렉트블락이 없다 -> 실패리턴
		if ( inodeInfo.blocks != NUM_OF_INDIRECT_BLOCK )
		{
			// 사용 가능한 다이렉트블락이 있다 -> 진행
			inodeInfo.blocks++;
			inodeInfo.i_block[inodeInfo.blocks-1] = GetFreeBlock();
			SetBlockFreeToAlloc();
			WriteInode(&inodeInfo, parent_inodeno);
		//////////////////////////////////////////////////////////////
		//	생성한 directory block 초기화
			ReadDirBlock(&dirBlock, inodeInfo.i_block[inodeInfo.blocks-1]);
			strcpy(dirBlock.dirEntries[0].name, filename);
			dirBlock.dirEntries[0].inodeNum = GetFreeInode();
			SetInodeFreeToAlloc();
			dirBlock.dirEntries[0].type = FILE_TYPE_FILE;
			WriteDirBlock(&dirBlock, inodeInfo.i_block[inodeInfo.blocks-1]);
			return 0;
		//
		//////////////////////////////////////////////////////////////
		}
		break;
	}
	// 여기까지 왔으면 못찾은것임
	free(abspath);
	free(ptr);
	return WRONG_VALUE;
}
コード例 #20
0
ファイル: metaentry.cpp プロジェクト: ForNeVeR/leechcraft
	QString MetaEntry::GetHumanReadableID () const
	{
		return GetEntryName () + "@metacontact";
	}
コード例 #21
0
	void ContactDropFilter::HandleContactsDropped (const QMimeData *data)
	{
		const auto thisEntry = GetEntry<ICLEntry> (EntryId_);
		const bool isMuc = thisEntry->GetEntryType () == ICLEntry::EntryType::MUC;

		auto entries = DndUtil::DecodeEntryObjs (data);
		entries.erase (std::remove_if (entries.begin (), entries.end (),
					[thisEntry] (QObject *entryObj)
					{
						return !CanEntryBeInvited (thisEntry,
								qobject_cast<ICLEntry*> (entryObj));
					}),
				entries.end ());

		if (entries.isEmpty ())
			return;

		QString text;
		if (entries.size () > 1)
			text = isMuc ?
					tr ("Enter reason to invite %n contact(s) to %1:", 0, entries.size ())
						.arg (thisEntry->GetEntryName ()) :
					tr ("Enter reason to invite %1 to %n conference(s):", 0, entries.size ())
						.arg (thisEntry->GetEntryName ());
		else
		{
			const auto muc = isMuc ?
					thisEntry :
					qobject_cast<ICLEntry*> (entries.first ());
			const auto entry = isMuc ?
					qobject_cast<ICLEntry*> (entries.first ()) :
					thisEntry;
			text = tr ("Enter reason to invite %1 to %2:")
					.arg (entry->GetEntryName ())
					.arg (muc->GetEntryName ());
		}

		bool ok = false;
		auto reason = QInputDialog::getText (nullptr,
				tr ("Invite to a MUC"),
				text,
				QLineEdit::Normal,
				{},
				&ok);
		if (!ok)
			return;

		if (isMuc)
		{
			const auto muc = qobject_cast<IMUCEntry*> (thisEntry->GetQObject ());

			for (const auto& entry : entries)
				muc->InviteToMUC (qobject_cast<ICLEntry*> (entry)->GetHumanReadableID (), reason);
		}
		else
		{
			const auto thisId = thisEntry->GetHumanReadableID ();

			for (const auto& mucEntryObj : entries)
			{
				const auto muc = qobject_cast<IMUCEntry*> (mucEntryObj);
				muc->InviteToMUC (thisId, reason);
			}
		}
	}
コード例 #22
0
ファイル: LootMgr.cpp プロジェクト: 090809/TrinityCore
void LootStore::ReportUnusedIds(LootIdSet const& lootIdSet) const
{
    // all still listed ids isn't referenced
    for (LootIdSet::const_iterator itr = lootIdSet.begin(); itr != lootIdSet.end(); ++itr)
        TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d isn't %s and not referenced from loot, and thus useless.", GetName(), *itr, GetEntryName());
}
コード例 #23
0
ファイル: hlslLinker.cpp プロジェクト: asmboom/hlsl2glslfork
bool HlslLinker::link(HlslCrossCompiler* compiler, const char* entryFunc, bool usePrecision)
{
	std::vector<GlslFunction*> globalList;
	std::vector<GlslFunction*> functionList;
	std::string entryPoint;
	GlslFunction* funcMain = NULL;
	FunctionSet calledFunctions;
	std::set<TOperator> libFunctions;
	std::map<std::string,GlslSymbol*> globalSymMap;
	std::map<std::string,GlslStruct*> structMap;

	if (!compiler)
	{
		infoSink.info << "No shader compiler provided\n";
		return false;
	}

	EShLanguage lang = compiler->getLanguage();

	if (!entryFunc)
	{
		infoSink.info << "No shader entry function provided\n";
		return false;
	}

	entryPoint = GetEntryName (entryFunc);

	//build the list of functions
	HlslCrossCompiler *comp = static_cast<HlslCrossCompiler*>(compiler);

	std::vector<GlslFunction*> &fl = comp->functionList;

	for ( std::vector<GlslFunction*>::iterator fit = fl.begin(); fit < fl.end(); fit++)
	{
		if ( (*fit)->getName() == "__global__")
			globalList.push_back( *fit);
		else
			functionList.push_back( *fit);

		if ((*fit)->getName() == entryPoint)
		{
			if (funcMain)
			{
				infoSink.info << kShaderTypeNames[lang] << " entry function cannot be overloaded\n";
				return false;
			}
			funcMain = *fit;
		}
	}

	// check to ensure that we found the entry function
	if (!funcMain)
	{
		infoSink.info << "Failed to find entry function: '" << entryPoint <<"'\n";
		return false;
	}

	//add all the called functions to the list
	calledFunctions.push_back (funcMain);
	if (!addCalledFunctions (funcMain, calledFunctions, functionList))
	{
		infoSink.info << "Failed to resolve all called functions in the " << kShaderTypeNames[lang] << " shader\n";
	}

	//iterate over the functions, building a global list of structure declaractions and symbols
	// assume a single compilation unit for expediency (eliminates name clashes, as type checking
	// withing a single compilation unit has been performed)
	for (FunctionSet::iterator it=calledFunctions.begin(); it != calledFunctions.end(); it++)
	{
		//get each symbol and each structure, and add them to the map
		// checking that any previous entries are equivalent
		const std::vector<GlslSymbol*> &symList = (*it)->getSymbols();

		for (std::vector<GlslSymbol*>::const_iterator cit = symList.begin(); cit < symList.end(); cit++)
		{
			if ( (*cit)->getIsGlobal())
			{
				//should check for already added ones here
				globalSymMap[(*cit)->getName()] = *cit;
			}
		}

		//take each referenced library function, and add it to the set
		const std::set<TOperator> &libSet = (*it)->getLibFunctions();

		libFunctions.insert( libSet.begin(), libSet.end());
	}


	// The following code is what is used to generate the actual shader and "main"
	// function. The process is to take all the components collected above, and
	// write them to the appropriate code stream. Finally, a main function is
	// generated that calls the specified entrypoint. That main function uses
	// semantics on the arguments and return values to connect items appropriately.

	//
	// Write Library Functions & required extensions
	std::string shaderExtensions, shaderLibFunctions;
	if (!libFunctions.empty())
	{
		for (std::set<TOperator>::iterator it = libFunctions.begin(); it != libFunctions.end(); it++)
		{
			const std::string &func = getHLSLSupportCode(*it, shaderExtensions, lang==EShLangVertex);
			if (!func.empty())
			{
				shaderLibFunctions += func;
				shaderLibFunctions += '\n';
			}
		}
	}
	shader << shaderExtensions;
	shader << shaderLibFunctions;

	//
	//Structure addition hack
	// Presently, structures are not tracked per function, just dump them all
	// This could be improved by building a complete list of structures for the
	// shaders based on the variables in each function
	//
	{
		HlslCrossCompiler *comp = static_cast<HlslCrossCompiler*>(compiler);
		std::vector<GlslStruct*> &sList = comp->structList;

		if (!sList.empty())
		{
			for (std::vector<GlslStruct*>::iterator it = sList.begin(); it < sList.end(); it++)
			{
				shader << (*it)->getDecl() << "\n";
			}
		}
	}

	//
	// Write global variables
	//

	if (!globalSymMap.empty())
	{
		for (std::map<std::string,GlslSymbol*>::iterator sit = globalSymMap.begin(); sit != globalSymMap.end(); sit++)
		{
			sit->second->writeDecl(shader,false,false);
			shader << ";\n";

			if ( sit->second->getIsMutable() )
			{
				sit->second->writeDecl(shader, true, false);
				shader << ";\n";
			}         
		}
	}

	//
	// Write function declarations and definitions
	//
	EmitCalledFunctions (shader, calledFunctions);

	// 
	// Gather the uniforms into the uniform list
	//
	for (std::map<std::string, GlslSymbol*>::iterator it = globalSymMap.begin(); it != globalSymMap.end(); it++)
	{
		if (it->second->getQualifier() != EqtUniform)
			continue;

		ShUniformInfo infoStruct;
		infoStruct.name = new char[it->first.size()+1];
		strcpy( infoStruct.name, it->first.c_str());
		if (it->second->getSemantic() != "")
		{
			infoStruct.semantic = new char[it->second->getSemantic().size()+1];
			strcpy( infoStruct.semantic, it->second->getSemantic().c_str());
		}
		else
			infoStruct.semantic = 0;

		//gigantic hack, the enumerations are kept in alignment
		infoStruct.type = (EShType)it->second->getType();
		infoStruct.arraySize = it->second->getArraySize();

		if ( it->second->hasInitializer() )
		{
			int initSize = it->second->initializerSize();
			infoStruct.init = new float[initSize];
			memcpy( infoStruct.init, it->second->getInitializer(), sizeof(float) * initSize);
		}
		else
			infoStruct.init = 0;

		//TODO: need to add annotation

		uniforms.push_back( infoStruct);
	}

	//
	// Generate the main function
	//

		std::stringstream attrib;
		std::stringstream uniform;
		std::stringstream preamble;
		std::stringstream postamble;
		std::stringstream varying;
		std::stringstream call;
		const int pCount = funcMain->getParameterCount();

		preamble << "void main() {\n";
		const EGlslSymbolType retType = funcMain->getReturnType();
		GlslStruct *retStruct = funcMain->getStruct();
		if (  retType == EgstStruct)
		{
			assert(retStruct);
			preamble << "    " << retStruct->getName() << " xl_retval;\n";
		}
		else
		{
			if ( retType != EgstVoid)
			{
				preamble << "    ";
				writeType (preamble, retType, NULL, usePrecision?funcMain->getPrecision():EbpUndefined);
				preamble << " xl_retval;\n";
			}
		}

		// Write all mutable initializations
		if ( calledFunctions.size() > 0 )
		{
			for (FunctionSet::iterator fit = calledFunctions.begin(); fit != calledFunctions.end(); fit++)
			{
				std::string mutableDecls = (*fit)->getMutableDecls(1, calledFunctions.begin(), fit);

				if ( mutableDecls.size() > 0 )
				{
					preamble << mutableDecls;
				}
			}
		}

		call << "    ";
		if (retType != EgstVoid)
			call << "xl_retval = " << funcMain->getName() << "( ";
		else
			call << funcMain->getName() << "( ";

		// pass main function parameters
		for (int ii=0; ii<pCount; ii++)
		{
			GlslSymbol *sym = funcMain->getParameter(ii);
			EAttribSemantic attrSem = parseAttributeSemantic( sym->getSemantic());

			switch (sym->getQualifier())
			{

			// -------- IN & OUT parameters
			case EqtIn:
			case EqtInOut:
				if ( sym->getType() != EgstStruct)
				{
					std::string name, ctor;
					int pad;

					if ( getArgumentData( sym, lang==EShLangVertex ? EClassAttrib : EClassVarIn, name, ctor, pad) )
					{
						// In fragment shader, pass zero for POSITION inputs
						bool ignoredPositionInFragment = false;
						if (lang == EShLangFragment && attrSem == EAttrSemPosition)
						{
							call << ctor << "(0.0)";
							ignoredPositionInFragment = true;
						}
						// For "in" parameters, just call directly to the main
						else if ( sym->getQualifier() != EqtInOut )
						{
							call << ctor << "(" << name;
							for (int ii = 0; ii<pad; ii++)
								call << ", 0.0";
							call << ")";
						}
						// For "inout" parameters, declare a temp and initialize the temp
						else
						{
							preamble << "    ";
							writeType (preamble, sym->getType(), NULL, usePrecision?sym->getPrecision():EbpUndefined);
							preamble << " xlt_" << sym->getName() << " = ";
							preamble << ctor << "(" << name;
							for (int ii = 0; ii<pad; ii++)
								preamble << ", 0.0";
							preamble << ");\n";
						}

						if (lang == EShLangVertex) // vertex shader: deal with gl_ attributes
						{
							if ( strncmp( name.c_str(), "gl_", 3))
							{
								int typeOffset = 0;

								// If the type is integer or bool based, we must convert to a float based
								// type.  This is because GLSL does not allow int or bool based vertex attributes.
								if ( sym->getType() >= EgstInt && sym->getType() <= EgstInt4)
								{
									typeOffset += 4;
								}

								if ( sym->getType() >= EgstBool && sym->getType() <= EgstBool4)
								{
									typeOffset += 8;
								}

								// This is an undefined attribute
								attrib << "attribute " << getTypeString((EGlslSymbolType)(sym->getType() + typeOffset)) << " " << name << ";\n";
							}
						}

						if (lang == EShLangFragment) // deal with varyings
						{
							if (!ignoredPositionInFragment)
								AddToVaryings (varying, sym->getPrecision(), ctor, name);
						}
					}
					else
					{
						//should deal with fall through cases here
						assert(0);
						infoSink.info << "Unsupported type for shader entry parameter (";
						infoSink.info << getTypeString(sym->getType()) << ")\n";
					}
				}
				else
				{
					//structs must pass the struct, then process per element
					GlslStruct *Struct = sym->getStruct();
					assert(Struct);

					//first create the temp
					std::string tempVar = "xlt_" + sym->getName();
					preamble << "    " << Struct->getName() << " ";
					preamble << tempVar <<";\n";
					call << tempVar;

					const int elem = Struct->memberCount();
					for (int jj=0; jj<elem; jj++)
					{
						const GlslStruct::member &current = Struct->getMember(jj);
						EAttribSemantic memberSem = parseAttributeSemantic (current.semantic);
						std::string name, ctor;
						int pad;
						int numArrayElements = 1;
						bool bIsArray = false;

						// If it is an array, loop over each member
						if ( current.arraySize > 0 )
						{
							numArrayElements = current.arraySize;
							bIsArray = true;
						}

						for ( int arrayIndex = 0; arrayIndex <  numArrayElements; arrayIndex++ )
						{
							if ( getArgumentData2( current.name, current.semantic, current.type,
								lang==EShLangVertex ? EClassAttrib : EClassVarIn, name, ctor, pad, arrayIndex ) )
							{

								preamble << "    ";
								preamble << tempVar << "." << current.name;

								if ( bIsArray )
									preamble << "[" << arrayIndex << "]";

								// In fragment shader, pass zero for POSITION inputs
								bool ignoredPositionInFragment = false;
								if (lang == EShLangFragment && memberSem == EAttrSemPosition)
								{
									preamble << " = " << ctor << "(0.0);\n";
									ignoredPositionInFragment = true;
								}
								else
								{
									preamble << " = " << ctor << "( " << name;
									for (int ii = 0; ii<pad; ii++)
										preamble << ", 0.0";
									preamble << ");\n";
								}

								if (lang == EShLangVertex) // vertex shader: gl_ attributes
								{
									if ( strncmp( name.c_str(), "gl_", 3))
									{

										int typeOffset = 0;

										// If the type is integer or bool based, we must convert to a float based
										// type.  This is because GLSL does not allow int or bool based vertex attributes.
										if ( current.type >= EgstInt && current.type <= EgstInt4)
										{
											typeOffset += 4;
										}

										if ( current.type >= EgstBool && current.type <= EgstBool4)
										{
											typeOffset += 8;
										}

										// This is an undefined attribute
										attrib << "attribute " << getTypeString((EGlslSymbolType)(current.type + typeOffset)) << " " << name << ";\n";

									}
								}
								
								if (lang == EShLangFragment) // deal with varyings
								{
									if (!ignoredPositionInFragment)
										AddToVaryings (varying, current.precision, ctor, name);
								}
							}
							else
							{
								//should deal with fall through cases here
								assert(0);
								infoSink.info << "Unsupported type for struct element in shader entry parameter (";
								infoSink.info << getTypeString(current.type) << ")\n";
							}
						}
					}
				}

				//
				// NOTE: This check only breaks out of the case if we have an "in" parameter, for
				//       "inout" it will fallthrough to the next case
				//
				if ( sym->getQualifier() != EqtInOut )
				{
					break;
				}


			// -------- OUT parameters; also fall-through for INOUT (see the check above)
			case EqtOut:

				if ( sym->getType() != EgstStruct)
				{
					std::string name, ctor;
					int pad;

					if ( getArgumentData( sym, lang==EShLangVertex ? EClassVarOut : EClassRes, name, ctor, pad) )
					{
						// For "inout" parameters, the preamble was already written so no need to do it here.
						if ( sym->getQualifier() != EqtInOut )
						{
							preamble << "    ";
							writeType (preamble, sym->getType(), NULL, usePrecision?sym->getPrecision():EbpUndefined);
							preamble << " xlt_" << sym->getName() << ";\n";                     
						}
						
						if (lang == EShLangVertex) // deal with varyings
						{
							AddToVaryings (varying, sym->getPrecision(), ctor, name);
						}

						call << "xlt_" << sym->getName();

						postamble << "    ";
						postamble << name << " = " << ctor << "( xlt_" <<sym->getName();
						for (int ii = 0; ii<pad; ii++)
							postamble << ", 0.0";

						postamble << ");\n";
					}
					else
					{
						//should deal with fall through cases here
						assert(0);
						infoSink.info << "Unsupported type for shader entry parameter (";
						infoSink.info << getTypeString(sym->getType()) << ")\n";
					}
				}
				else
				{
					//structs must pass the struct, then process per element
					GlslStruct *Struct = sym->getStruct();
					assert(Struct);

					//first create the temp
					std::string tempVar = "xlt_" + sym->getName();

					// For "inout" parmaeters the preamble and call were already written, no need to do it here
					if ( sym->getQualifier() != EqtInOut )
					{
						preamble << "    " << Struct->getName() << " ";
						preamble << tempVar <<";\n";
						call << tempVar;
					}

					const int elem = Struct->memberCount();
					for (int ii=0; ii<elem; ii++)
					{
						const GlslStruct::member &current = Struct->getMember(ii);
						std::string name, ctor;
						int pad;

						if ( getArgumentData2( current.name, current.semantic, current.type, lang==EShLangVertex ? EClassVarOut : EClassRes, name, ctor, pad, 0) )
						{
							postamble << "    ";
							postamble << name << " = " << ctor;
							postamble << "( " << tempVar << "." << current.name;
							for (int ii = 0; ii<pad; ii++)
								postamble << ", 0.0";

							postamble << ");\n";

							if (lang == EShLangVertex) // deal with varyings
							{
								AddToVaryings (varying, current.precision, ctor, name);
							}
						}
						else
						{
							//should deal with fall through cases here
							assert(0);
							infoSink.info << "Unsupported type in struct element for shader entry parameter (";
							infoSink.info << getTypeString(current.type) << ")\n";
						}
					}
				}
				break;

			case EqtUniform:
				uniform << "uniform ";
				writeType (uniform, sym->getType(), NULL, usePrecision?sym->getPrecision():EbpUndefined);
				uniform << " xlu_" << sym->getName() << ";\n";
				call << "xlu_" << sym->getName();
				break;

			default:
				assert(0);
			};
			if (ii != pCount -1)
				call << ", ";
		}

		call << ");\n";


		// -------- return value of main entry point
		if (retType != EgstVoid)
		{

			if (retType != EgstStruct)
			{
				std::string name, ctor;
				int pad;

				if ( getArgumentData2( "", funcMain->getSemantic(), retType, lang==EShLangVertex ? EClassVarOut : EClassRes,
					name, ctor, pad, 0) )
				{

					postamble << "    ";
					postamble << name << " = " << ctor << "( xl_retval";
					for (int ii = 0; ii<pad; ii++)
						postamble << ", 0.0";

					postamble << ");\n";

					if (lang == EShLangVertex) // deal with varyings
					{
						AddToVaryings (varying, funcMain->getPrecision(), ctor, name);
					}
				}
				else
				{
					//should deal with fall through cases here
					assert(0);
					infoSink.info << (lang==EShLangVertex ? "Unsupported type for shader return value (" : "Unsupported return type for shader entry function (");
					infoSink.info << getTypeString(retType) << ")\n";
				}
			}
			else
			{
				const int elem = retStruct->memberCount();
				for (int ii=0; ii<elem; ii++)
				{
					const GlslStruct::member &current = retStruct->getMember(ii);
					std::string name, ctor;
					int pad;
					int numArrayElements = 1;
					bool bIsArray = false;

					if (lang == EShLangVertex) // vertex shader
					{
						// If it is an array, loop over each member
						if ( current.arraySize > 0 )
						{
							numArrayElements = current.arraySize;
							bIsArray = true;
						}
					}

					for ( int arrayIndex = 0; arrayIndex < numArrayElements; arrayIndex++ )
					{

						if ( getArgumentData2( current.name, current.semantic, current.type, lang==EShLangVertex ? EClassVarOut : EClassRes, name, ctor, pad, arrayIndex) )
						{
							postamble << "    ";
							postamble << name;                                                            
							postamble << " = " << ctor;
							postamble << "( xl_retval." << current.name;
							if ( bIsArray )
							{
								postamble << "[" << arrayIndex << "]";
							}
							for (int ii = 0; ii<pad; ii++)
								postamble << ", 0.0";

							postamble << ");\n";

							if (lang == EShLangVertex) // deal with varyings
							{
								AddToVaryings (varying, current.precision, ctor, name);
							}
						}
						else
						{
							//should deal with fall through cases here
							//assert(0);
							infoSink.info << (lang==EShLangVertex ? "Unsupported element type in struct for shader return value (" : "Unsupported struct element type in return type for shader entry function (");
							infoSink.info << getTypeString(current.type) << ")\n";
							return false;
						}
					}
				}
			}
		}
		else
		{
			if (lang == EShLangFragment) // fragment shader
			{
				// If no return type, close off the output
				postamble << ";\n";
			}
		}

		postamble << "}\n\n";

		EmitIfNotEmpty (shader, uniform);
		EmitIfNotEmpty (shader, attrib);
		EmitIfNotEmpty (shader, varying);

		shader << preamble.str() << "\n";
		shader << call.str() << "\n";
		shader << postamble.str() << "\n";

	return true;
}
コード例 #24
0
	void ServerHistoryManager::handleGotMessagesList ()
	{
		auto reply = qobject_cast<QNetworkReply*> (sender ());
		reply->deleteLater ();

		IsRefreshing_ = false;

		const auto& data = reply->readAll ();
		bool ok = true;
		const auto& varmap = QJson::Parser {}.parse (data).toMap ();
		if (!ok)
		{
			qWarning () << Q_FUNC_INFO
					<< "cannot parse reply"
					<< data;
			return;
		}

		auto varlist = varmap ["response"].toList ();
		if (varlist.isEmpty ())
			return;

		if (MsgCount_ == -1)
		{
			bool ok = false;
			const auto count = varlist.first ().toInt (&ok);
			if (ok)
			{
				MsgCount_ = count;
				qDebug () << Q_FUNC_INFO
						<< "detected"
						<< count
						<< "dialogs";
			}
		}

		for (const auto& var : varlist)
		{
			const auto& varmap = var.toMap ();
			if (varmap.isEmpty ())
				continue;

			// TODO handle MUCs
			if (varmap.contains ("admin_id"))
				continue;

			const auto uid = varmap ["uid"].toULongLong ();
			const auto ts = varmap ["date"].toULongLong ();

			const auto entry = Acc_->GetEntry (uid);
			if (!entry)
			{
				qWarning () << Q_FUNC_INFO
						<< "no entry for"
						<< uid;
				continue;
			}

			auto item = new QStandardItem (entry->GetEntryName ());
			item->setEditable (false);
			item->setData (QDateTime::fromTime_t (ts), ServerHistoryRole::LastMessageDate);
			item->setData (QVariant::fromValue<QObject*> (Acc_->GetEntry (uid)),
					ServerHistoryRole::CLEntry);
			item->setData (uid, CustomHistRole::UserUid);
			item->setData (entry->GetEntryName (), CustomHistRole::UserName);
			ContactsModel_->appendRow (item);
		}


		if (LastOffset_ + DlgChunkCount < MsgCount_)
		{
			IsRefreshing_ = true;
			Request (LastOffset_ + DlgChunkCount);
		}
	}
コード例 #25
0
ファイル: entrybase.cpp プロジェクト: trett/leechcraft
	void EntryBase::SetStatus (const EntryStatus& status, const QString& variant, const QXmppPresence& presence)
	{
		const bool existed = CurrentStatus_.contains (variant);
		const bool wasOffline = existed ?
				CurrentStatus_ [variant].State_ == SOffline :
				false;

		if (existed &&
				status == CurrentStatus_ [variant] &&
				presence.priority () == Variant2ClientInfo_.value (variant).value ("priority"))
			return;

		CurrentStatus_ [variant] = status;

		const QStringList& vars = Variants ();
		if ((!existed || wasOffline) && !vars.isEmpty ())
		{
			const QString& highest = vars.first ();
			if (Location_.contains (QString ()))
				Location_ [highest] = Location_.take (QString ());
			if (Variant2ClientInfo_.contains (QString ()))
			{
				const auto& info = Variant2ClientInfo_ [QString ()];
				QStringList toCopy;
				toCopy << "user_tune" << "user_mood" << "user_activity";
				Q_FOREACH (const QString& key, toCopy)
					if (info.contains (key))
						Variant2ClientInfo_ [highest] [key] = info [key];
			}
		}

		if ((!existed || wasOffline) &&
				status.State_ != SOffline)
		{
			auto conn = Account_->GetClientConnection ();
			if (conn->GetInfoReqPolicyManager ()->IsRequestAllowed (InfoRequest::Version, this) &&
					!variant.isEmpty ())
				conn->FetchVersion (GetJID () + '/' + variant);
		}

		if (status.State_ != SOffline)
		{
			if (const int p = presence.priority ())
				Variant2ClientInfo_ [variant] ["priority"] = p;
		}
		else
		{
			Variant2Version_.remove (variant);
			Variant2ClientInfo_.remove (variant);
		}

		emit statusChanged (status, variant);

		if (!existed ||
				(existed && status.State_ == SOffline) ||
				wasOffline)
			emit availableVariantsChanged (vars);

		GlooxMessage *message = 0;
		if (GetEntryType () == ETPrivateChat)
			message = new GlooxMessage (IMessage::MTStatusMessage,
					IMessage::DIn,
					qobject_cast<RoomCLEntry*> (GetParentCLEntry ())->
							GetRoomHandler ()->GetRoomJID (),
					GetEntryName (),
					Account_->GetClientConnection ().get ());
		else
			message = new GlooxMessage (IMessage::MTStatusMessage,
				IMessage::DIn,
				GetJID (),
				variant,
				Account_->GetClientConnection ().get ());
		message->SetMessageSubType (IMessage::MSTParticipantStatusChange);

		GlooxProtocol *proto = qobject_cast<GlooxProtocol*> (Account_->GetParentProtocol ());
		IProxyObject *proxy = qobject_cast<IProxyObject*> (proto->GetProxyObject ());
		const QString& state = proxy->StateToString (status.State_);

		const QString& nick = GetEntryName () + '/' + variant;
		message->setProperty ("Azoth/Nick", nick);
		message->setProperty ("Azoth/TargetState", state);
		message->setProperty ("Azoth/StatusText", status.StatusString_);

		QString msg = tr ("%1 is now %2 (%3)")
				.arg (nick)
				.arg (state)
				.arg (status.StatusString_);
		message->SetBody (msg);
		HandleMessage (message);
	}
コード例 #26
0
bool HlslLinker::link(HlslCrossCompiler* compiler, const char* entryFunc, ETargetVersion targetVersion, unsigned options)
{
	m_Target = targetVersion;
	m_Options = options;
	m_Extensions.clear();
	if (!linkerSanityCheck(compiler, entryFunc))
		return false;
	
	const bool usePrecision = Hlsl2Glsl_VersionUsesPrecision(targetVersion);
	
	EShLanguage lang = compiler->getLanguage();
	std::string entryPoint = GetEntryName (entryFunc);
	
	
	// figure out all relevant functions
	GlslFunction* globalFunction = NULL;
	std::vector<GlslFunction*> functionList;
	FunctionSet calledFunctions;
	GlslFunction* funcMain = NULL;
	if (!buildFunctionLists(compiler, lang, entryPoint, globalFunction, functionList, calledFunctions, funcMain))
		return false;
	assert(globalFunction);
	assert(funcMain);
	
	// uniforms and used built-in functions
	std::vector<GlslSymbol*> constants;
	std::set<TOperator> libFunctions;
	buildUniformsAndLibFunctions(calledFunctions, constants, libFunctions);
	// add built-in functions possibly used by uniform initializers
	const std::set<TOperator>& referencedGlobalFunctions = globalFunction->getLibFunctions();
	libFunctions.insert (referencedGlobalFunctions.begin(), referencedGlobalFunctions.end());
	
	buildUniformReflection (constants);


	// print all the components collected above.

	emitLibraryFunctions (libFunctions, lang, usePrecision);
	emitStructs(compiler);
	emitGlobals (globalFunction, constants);
	EmitCalledFunctions (shader, calledFunctions);

	
	// Generate a main function that calls the specified entrypoint.
	// That main function uses semantics on the arguments and return values to
	// connect items appropriately.	
	
	std::stringstream attrib;
	std::stringstream uniform;
	std::stringstream preamble;
	std::stringstream postamble;
	std::stringstream varying;
	std::stringstream call;

	markDuplicatedInSemantics(funcMain);

	// Declare return value
	const EGlslSymbolType retType = funcMain->getReturnType();
	emitMainStart(compiler, retType, funcMain, m_Options, usePrecision, preamble, constants);
	

	// Call the entry point
	call << "    ";
	if (retType != EgstVoid)
		call << "xl_retval = ";
	call << funcMain->getName() << "( ";
	

	// Entry point parameters
	const int pCount = funcMain->getParameterCount();
	for (int ii=0; ii<pCount; ii++)
	{
		GlslSymbol *sym = funcMain->getParameter(ii);
		EAttribSemantic attrSem = parseAttributeSemantic( sym->getSemantic());
		
		add_extension_from_semantic(attrSem, m_Target, m_Extensions);

		switch (sym->getQualifier())
		{

		// -------- IN & OUT parameters
		case EqtIn:
		case EqtInOut:
		case EqtConst:
			if (sym->getType() != EgstStruct)
			{
				emitInputNonStructParam(sym, lang, usePrecision, attrSem, attrib, varying, preamble, call);
			}
			else
			{
				emitInputStructParam(sym, lang, attrib, varying, preamble, call);
			}

			// NOTE: for "inout" parameters need to fallthrough to the next case
			if (sym->getQualifier() != EqtInOut)
			{
				break;
			}


		// -------- OUT parameters; also fall-through for INOUT (see the check above)
		case EqtOut:

			if ( sym->getType() != EgstStruct)
			{
				emitOutputNonStructParam(sym, lang, usePrecision, attrSem, varying, preamble, postamble, call);
			}
			else
			{
				emitOutputStructParam(sym, lang, usePrecision, attrSem, varying, preamble, postamble, call);
			}
			break;

		case EqtUniform:
			uniform << "uniform ";
			writeType (uniform, sym->getType(), NULL, usePrecision?sym->getPrecision():EbpUndefined);
			uniform << " xlu_" << sym->getName();
			if(sym->getArraySize())
				uniform << "[" << sym->getArraySize() << "]";
			uniform << ";\n";
			call << "xlu_" << sym->getName();
			break;

		default:
			assert(0);
		};
		if (ii != pCount -1)
			call << ", ";
	}

	call << ");\n";


	// Entry point return value
	if (!emitReturnValue(retType, funcMain, lang, varying, postamble))
		return false;

	postamble << "}\n\n";
	
	
	// Generate final code of the pieces above.
	{
		shaderPrefix << kTargetVersionStrings[targetVersion];
		ExtensionSet::const_iterator it = m_Extensions.begin(), end = m_Extensions.end();
		for (; it != end; ++it)
			shaderPrefix << "#extension " << *it << " : require" << std::endl;
	}

	EmitIfNotEmpty (shader, uniform);
	EmitIfNotEmpty (shader, attrib);
	EmitIfNotEmpty (shader, varying);

	shader << preamble.str() << "\n";
	shader << call.str() << "\n";
	shader << postamble.str() << "\n";

	return true;
}
コード例 #27
0
ファイル: entrybase.cpp プロジェクト: ForNeVeR/leechcraft
	void EntryBase::SetStatus (const EntryStatus& status, const QString& variant, const QXmppPresence& presence)
	{
		const bool existed = CurrentStatus_.contains (variant);
		const bool wasOffline = existed ?
				CurrentStatus_ [variant].State_ == SOffline :
				false;

		if (existed &&
				status == CurrentStatus_ [variant] &&
				presence.priority () == Variant2ClientInfo_.value (variant).value ("priority"))
			return;

		CurrentStatus_ [variant] = status;

		const QStringList& vars = Variants ();
		if ((!existed || wasOffline) && !vars.isEmpty ())
		{
			const QString& highest = vars.first ();
			if (Location_.contains ({}))
				Location_ [highest] = Location_.take ({});
			if (Variant2Audio_.contains ({}))
				Variant2Audio_ [highest] = Variant2Audio_.take ({});
			if (Variant2Mood_.contains ({}))
				Variant2Mood_ [highest] = Variant2Mood_.take ({});
			if (Variant2Activity_.contains ({}))
				Variant2Activity_ [highest] = Variant2Activity_.take ({});
		}

		if ((!existed || wasOffline) &&
				status.State_ != SOffline)
		{
			auto conn = Account_->GetClientConnection ();
			if (conn->GetInfoReqPolicyManager ()->IsRequestAllowed (InfoRequest::Version, this))
			{
				if (!variant.isEmpty ())
					conn->FetchVersion (GetJID () + '/' + variant);
				else
					conn->FetchVersion (GetJID ());
			}
		}

		if (status.State_ != SOffline)
		{
			if (const int p = presence.priority ())
				Variant2ClientInfo_ [variant] ["priority"] = p;
		}
		else
		{
			Variant2Version_.remove (variant);
			Variant2ClientInfo_.remove (variant);
			Variant2VerString_.remove (variant);
			Variant2Identities_.remove (variant);

			Variant2Audio_.remove (variant);
			Variant2Mood_.remove (variant);
			Variant2Activity_.remove (variant);

			Variant2SecsDiff_.remove (variant);
		}

		emit statusChanged (status, variant);

		if (!existed ||
				status.State_ == SOffline ||
				wasOffline)
			emit availableVariantsChanged (vars);

		GlooxMessage *message = 0;
		if (GetEntryType () == EntryType::PrivateChat)
			message = new GlooxMessage (IMessage::Type::StatusMessage,
					IMessage::Direction::In,
					qobject_cast<RoomCLEntry*> (GetParentCLEntryObject ())->
							GetRoomHandler ()->GetRoomJID (),
					GetEntryName (),
					Account_->GetClientConnection ().get ());
		else
			message = new GlooxMessage (IMessage::Type::StatusMessage,
				IMessage::Direction::In,
				GetJID (),
				variant,
				Account_->GetClientConnection ().get ());
		message->SetMessageSubType (IMessage::SubType::ParticipantStatusChange);

		const auto proxy = Account_->GetParentProtocol ()->GetProxyObject ();
		const auto& state = proxy->StateToString (status.State_);

		const auto& nick = GetEntryName () + '/' + variant;
		message->setProperty ("Azoth/Nick", nick);
		message->setProperty ("Azoth/TargetState", state);
		message->setProperty ("Azoth/StatusText", status.StatusString_);

		const auto& msg = tr ("%1 is now %2 (%3)")
				.arg (nick)
				.arg (state)
				.arg (status.StatusString_);
		message->SetBody (msg);
		HandleMessage (message);
	}
コード例 #28
0
	void NotificationsManager::HandleMessage (IMessage *msg)
	{
		const bool showMsg = XmlSettingsManager::Instance ()
				.property ("ShowMsgInNotifications").toBool ();

		const auto other = qobject_cast<ICLEntry*> (msg->OtherPart ());
		const auto parentCL = qobject_cast<ICLEntry*> (msg->ParentCLEntry ());

		QString msgString;
		bool isHighlightMsg = false;
		switch (msg->GetMessageType ())
		{
		case IMessage::Type::ChatMessage:
			if (XmlSettingsManager::Instance ()
					.property ("NotifyAboutIncomingMessages").toBool ())
			{
				if (!showMsg)
					msgString = tr ("Incoming chat message from <em>%1</em>.")
							.arg (other->GetEntryName ());
				else
				{
					const auto& body = msg->GetEscapedBody ();
					const auto& notifMsg = body.size () > 50 ?
							body.left (50) + "..." :
							body;
					msgString = tr ("Incoming chat message from <em>%1</em>: <em>%2</em>")
							.arg (other->GetEntryName ())
							.arg (notifMsg);
				}
			}
			break;
		case IMessage::Type::MUCMessage:
		{
			isHighlightMsg = Core::Instance ().IsHighlightMessage (msg);
			if (isHighlightMsg && XmlSettingsManager::Instance ()
					.property ("NotifyAboutConferenceHighlights").toBool ())
			{
				if (!showMsg)
					msgString = tr ("Highlighted in conference <em>%1</em> by <em>%2</em>.")
							.arg (parentCL->GetEntryName ())
							.arg (other->GetEntryName ());
				else
				{
					const auto& body = msg->GetEscapedBody ();
					const auto& notifMsg = body.size () > 50 ?
							body.left (50) + "..." :
							body;
					msgString = tr ("Highlighted in conference <em>%1</em> by <em>%2</em>: <em>%3</em>")
							.arg (parentCL->GetEntryName ())
							.arg (other->GetEntryName ())
							.arg (notifMsg);
				}
			}
			break;
		}
		default:
			return;
		}

		auto e = Util::MakeNotification ("Azoth",
				msgString,
				PInfo_);

		if (msgString.isEmpty ())
			e.Mime_ += "+advanced";

		auto entry = msg->GetMessageType () == IMessage::Type::MUCMessage ?
				parentCL :
				other;
		BuildNotification (e, entry);

		const auto count = ++UnreadCounts_ [entry];
		if (msg->GetMessageType () == IMessage::Type::MUCMessage)
		{
			e.Additional_ ["org.LC.Plugins.Azoth.SubSourceID"] = other->GetEntryID ();
			e.Additional_ ["org.LC.AdvNotifications.EventType"] = isHighlightMsg ?
					AN::TypeIMMUCHighlight :
					AN::TypeIMMUCMsg;
			e.Additional_ ["NotificationPixmap"] = QVariant::fromValue (other->GetAvatar ());

			if (isHighlightMsg)
				e.Additional_ ["org.LC.AdvNotifications.FullText"] =
					tr ("%n message(s) from", 0, count) + ' ' + other->GetEntryName () +
							" <em>(" + parentCL->GetEntryName () + ")</em>";
			else
				e.Additional_ ["org.LC.AdvNotifications.FullText"] =
					tr ("%n message(s) in", 0, count) + ' ' + parentCL->GetEntryName ();
		}
		else
		{
			e.Additional_ ["org.LC.AdvNotifications.EventType"] = AN::TypeIMIncMsg;
			e.Additional_ ["org.LC.AdvNotifications.FullText"] =
				tr ("%n message(s) from", 0, count) +
						' ' + other->GetEntryName ();
		}

		e.Additional_ ["org.LC.AdvNotifications.Count"] = count;

		e.Additional_ ["org.LC.AdvNotifications.ExtendedText"] = tr ("%n message(s)", 0, count);
		e.Additional_ ["org.LC.Plugins.Azoth.Msg"] = msg->GetEscapedBody ();

		const auto nh = new Util::NotificationActionHandler { e, this };
		nh->AddFunction (tr ("Open chat"),
				[parentCL] { Core::Instance ().GetChatTabsManager ()->OpenChat (parentCL, true); });
		nh->AddDependentObject (parentCL->GetQObject ());

		EntityMgr_->HandleEntity (e);
	}