Exemple #1
0
void CTabStack::ReleaseTabs(BOOL abInvalidOnly /*= TRUE*/)
{
	if (!this || !mpp_Stack || !mn_Used || !mn_MaxCount)
		return;

	MSectionLockSimple SC; SC.Lock(mpc_Section); // Сразу Exclusive lock

	// Идем сзади, т.к. нужно будет сдвигать элементы
	for (int i = (mn_Used - 1); i >= 0; i--)
	{
		if (!mpp_Stack[i])
			continue;
		if (abInvalidOnly)
		{
			if (mpp_Stack[i]->Info.Status == tisValid || mpp_Stack[i]->Info.Status == tisPassive)
				continue;
		}
		CTabID *p = mpp_Stack[i];
		mpp_Stack[i] = NULL;
		#ifdef TAB_REF_PLACE
		p->DelPlace(m_rp);
		#endif
		// Именно Release, т.к. ИД может быть использован в других стеках
		p->Release();

		mn_Used--;

		// Сдвинуть хвост, если есть
		if (abInvalidOnly && (mn_Used > 1) && (i < (mn_Used-1)))
		{
			memmove(mpp_Stack+i, mpp_Stack+i+1, sizeof(CTabID**) * (mn_Used - i));
		}
	}
}
Exemple #2
0
void CTabStack::RecheckPassive()
{
	if (mn_UpdatePos < mn_Used)
	{

		// Освободить все элементы за mn_UpdatePos
		int i = mn_UpdatePos;
		DEBUGTEST(int iPrev = mn_Used);
		while (i < mn_Used)
		{
			CTabID *pTab = mpp_Stack[i];

			if (pTab)
			{
				_ASSERTE(pTab->Info.pVCon!=NULL);
				if (abRConTabs && pTab->Info.pVCon)
				{
					bool bVConValid = false, bPidValid = false, bPassive = false;
					// Only for RCon->tabs.m_Tabs we must to check, if tab is:
					// 'Still Alive'
					// 'Hidden' (Another started Far hides editor/viewer of parent Far)
					// 'Terminated' (Editor/viewer was closed or Far instance terminated)
					CVConGroup::CheckTabValid(pTab, bVConValid, bPidValid, bPassive);

					if (bPidValid)
					{
						if (bPassive)
						{
							// Пока оставить этот таб
							i++;
							continue;
						}
					}
				}

				// If we get here - tab was terminated

				if (abRConTabs)
					pTab->Info.Status = tisInvalid;

				#ifdef TAB_REF_PLACE
				pTab->DelPlace(m_rp);
				#endif

				// Kill this tab
				pTab->Release();
				mpp_Stack[i] = NULL;
			}

			DEBUGTEST(iPrev = mn_Used);
			PRAGMA_ERROR("FAIL. Нужно убрать из стека все NULL-ячейки");
			TabDeleted(pUpdateLock, i);
			_ASSERTE(mn_Used < iPrev);
		}

		mn_Used = mn_UpdatePos;
	}
}
Exemple #3
0
// Возвращает "true" если были изменения в КОЛИЧЕСТВЕ табов (ЗДЕСЬ больше ничего не проверяется)
bool CTabStack::UpdateEnd(HANDLE hUpdate, DWORD anActiveFarPID)
{
	MSectionLockSimple* pUpdateLock = (MSectionLockSimple*)hUpdate;

	// Функция должна вызваться ТОЛЬКО между UpdateBegin & UpdateEnd
	if (mn_UpdatePos < 0)
	{
		_ASSERTE(mn_UpdatePos>=0);
		return false;
	}

	bool bVConClosed = false;

	if (!mb_FarUpdateMode && (mn_UpdatePos == 0))
	{
		if (!CVConGroup::isVConExists(0))
		{
			bVConClosed = true;
		}
		else
		{
			// Фукнция UpdateFarWindow должна была быть вызвана хотя бы раз!
			//UpdateFarWindow(CVirtualConsole* apVCon, LPCWSTR asName, int anType, int anPID, int anFarWindowID, int anViewEditID, CEFarWindowType anFlags)
			_ASSERTE(mn_UpdatePos>0 || CVConGroup::GetConCount()==0);
			pUpdateLock->Unlock();
			delete pUpdateLock;
			mn_UpdatePos = -1;
			return false;
		}
	}

	bool bChanged = (mn_Used != mn_UpdatePos);

	#if 1
	_ASSERTE(pUpdateLock->isLocked());
	#else
	pUpdateLock->RelockExclusive();
	#endif

	if (mb_FarUpdateMode)
	{
		_ASSERTE(mn_UpdatePos > 0);

		// Все табы ПОСЛЕ последнего добавленного/обновленного - помечаем неактивными
		for (int i = mn_UpdatePos; i < mn_Used; i++)
		{
			CTabID *pTab = mpp_Stack[i];
			if (pTab && (pTab->Info.Status != tisInvalid))
			{
				pTab->Info.Status = tisPassive;
			}
		}

		// Активен Far? ВСЕ tisPassive табы этого Far-а - разрушаем
		if (anActiveFarPID)
		{
			for (int i = 0; i < mn_Used; i++)
			{
				CTabID *pTab = mpp_Stack[i];

				// Проверяем только табы активного фара (пассивные [Far -> Far -> Far] не трогаем)
				if (!pTab || (pTab->Info.nPID != anActiveFarPID))
					continue;
				// Панели и табы с не пассивным статусом - не трогаем
				if ((pTab->Type() == fwt_Panels) || (pTab->Info.Status != tisPassive))
					continue;

				// Таб (редактор/вьювер) был закрыт, разрушаем
				_ASSERTE(pTab->Type()==fwt_Editor || pTab->Type()==fwt_Viewer);

				// Kill this tab
				pTab->Info.Status = tisInvalid;
			}
		}
	}
	else
	{
		// Для самого таббара - весь хвост просто выкинуть из списка, но сами CTabID не разрушать (tisInvalid не ставить)
		for (int i = mn_UpdatePos; i < mn_Used; i++)
		{
			CTabID *pTab = mpp_Stack[i];
			if (pTab)
			{
				if (!CVConGroup::isValid((CVirtualConsole*)pTab->Info.pVCon))
					pTab->Info.Status = tisInvalid;
				#ifdef TAB_REF_PLACE
				pTab->DelPlace(m_rp);
				#endif
				pTab->Release();
				// Remove from list
				mpp_Stack[i] = NULL;

				bChanged = true;
			}
		}
	}

	for (int i = 0; i < mn_Used; i++)
	{
		CTabID *pTab = mpp_Stack[i];

		// Kill all invalid tabs
		if (!pTab || (pTab->Info.Status != tisInvalid))
			continue;

		#ifdef TAB_REF_PLACE
		pTab->DelPlace(m_rp);
		#endif
		pTab->Release();
		// Remove from list
		mpp_Stack[i] = NULL;

		bChanged = true;
	}

	CleanNulls();

	pUpdateLock->Unlock();
	delete pUpdateLock;

	return bChanged;
}