Exemple #1
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 #2
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;
}
Exemple #3
0
// Должен вызываться только из CRealConsole!
// Возвращает "true" если были изменения
bool CTabStack::UpdateFarWindow(HANDLE hUpdate, CVirtualConsole* apVCon, LPCWSTR asName, CEFarWindowType anType, int anPID, int anFarWindowID, int anViewEditID, CTab& rActiveTab)
{
	MSectionLockSimple* pUpdateLock = (MSectionLockSimple*)hUpdate;

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

	bool bChanged = false;
	CTabID* pTab = NULL;

	mb_FarUpdateMode = true;

	// Теперь - поехали обновлять. Правила такие:
	// 1. Новая вкладка в ФАР может появиться ТОЛЬКО в конце
	// 2. Закрыта может быть любая вкладка
	// 3. панели НЕ должны перебиваться на редактор при запуске "far /e"
	// 4. и вообще, первый таб мог быть добавлен изначально как редактор!

	int i = mn_UpdatePos;
	while (i < mn_Used)
	{
		if (!mpp_Stack[i])
		{
			i++;
			continue;
		}

		if (mpp_Stack[i]->IsEqual(apVCon, asName, anType, anPID, anViewEditID, fwt_TypeMask))
		{
			// OK, таб совпадает
			pTab = mpp_Stack[i];

			// Refresh status and title
			if (pTab->Set(asName, anType, anPID, anFarWindowID, anViewEditID, fwt_UpdateFlags))
				bChanged = true;

			_ASSERTE(pTab->Info.Status == tisValid);

			if (anType & fwt_CurrentFarWnd)
				rActiveTab.Init(pTab);

			mn_UpdatePos = i+1;

			// Закончили
			break;
		}

		// Tab was closed or gone to background
		bChanged = true;
		mpp_Stack[i]->Info.Status = tisPassive;
		i++;
	}

	// Если таб новый
	if (pTab == NULL)
	{
		// это новая вкладка, добавляемая в конец
		pTab = new CTabID(apVCon, asName, anType, anPID, anFarWindowID, anViewEditID);
		_ASSERTE(pTab->RefCount()==1);
		_ASSERTE(mn_Used == i);

		i = AppendInt(pTab, FALSE/*abMoveFirst*/, pUpdateLock);
		_ASSERTE(pTab->RefCount()==2);
		if (anType & fwt_CurrentFarWnd)
			rActiveTab.Init(pTab);
		pTab->Release();

		bChanged = true;
		mn_UpdatePos = i+1;
	}

	_ASSERTE(mn_UpdatePos>=1 && mn_UpdatePos<=mn_Used);

	return bChanged;
}