示例#1
0
/*----------------------------------------------------------------------------------------------
	Set the startup information this window to the promoted entry.
	@param hvo The id of the entry or subentry that has been promoted.
----------------------------------------------------------------------------------------------*/
void CleDeSplitChild::PromoteSetup(HVO hvo)
{
	Assert(hvo);
	// At the moment we are assuming hvo is a CmPossibility (or subclass). At some point this
	// will probably change, which will require additional code.
	Vector<HVO> vhvo;
	Vector<int> vflid;
	// Set up the path to hvo.
	vhvo.Push(hvo);
	// Add owning records, if there are any, until we reach the main record.
	CustViewDaPtr qcvd;
	m_qlpi->GetDataAccess(&qcvd);
	AssertPtr(qcvd);
	RecMainWnd * prmw = dynamic_cast<RecMainWnd *>(MainWindow());
	AssertPtr(prmw);
	HVO hvoRoot = prmw->GetRootObj();
	HVO hvoOwn;
	while (hvo)
	{
		CheckHr(qcvd->get_ObjOwner(hvo, &hvoOwn));
		hvo = hvoOwn;
		if (hvo == hvoRoot || !hvo)
			break;
		vhvo.Insert(0, hvo);
		vflid.Insert(0, kflidCmPossibility_SubPossibilities);
	}
	prmw->SetStartupInfo(vhvo.Begin(), vhvo.Size(), vflid.Begin(), vflid.Size(), 0, 0);
}
示例#2
0
/*----------------------------------------------------------------------------------------------
	Check to see if we are editing a new record, if so, update the date modified on the old
	record if changes were made.
----------------------------------------------------------------------------------------------*/
void CleDeSplitChild::BeginEdit(AfDeFieldEditor * pdfe)
{
	HVO hvoNew = pdfe->GetObj();
	if (m_hvoLastObj && m_hvoLastObj != hvoNew)
	{
		// We've opened an editor on a new object.
		CustViewDaPtr qcvd;
		m_qlpi->GetDataAccess(&qcvd);
		AssertPtr(qcvd);
		int clid;
		// Find out if this is a kind of CmPossibility.
		CheckHr(qcvd->get_ObjClid(m_hvoLastObj, &clid));
		IFwMetaDataCachePtr qmdc;
		m_qlpi->GetDbInfo()->GetFwMetaDataCache(&qmdc);
		AssertPtr(qmdc);
		do
		{
			if (clid == kclidCmPossibility)
			{
				// The object has a DateModified property, so see that it is current.
				RecMainWnd * prmw = dynamic_cast<RecMainWnd *>(MainWindow());
				Assert(prmw);
				prmw->UpdateDateModified(m_hvoLastObj, kflidCmPossibility_DateModified);
				break;
			}
			ulong uclid;
			qmdc->GetBaseClsId(clid, &uclid);
			clid = (int)uclid;
		} while (clid != 0);
	}
}
示例#3
0
/*----------------------------------------------------------------------------------------------
	Set things up for editing with a temporary data cache by marking the point to return to
	in the undo stack. Also returns the action handler which should be installed in the
	temporary cache. This can be called multiple times. If the mark is already set, it does
	nothing.
	@return
----------------------------------------------------------------------------------------------*/
IActionHandler * AfDeFeEdBoxBut::BeginTempEdit()
{
	// Get your action handler.
	CustViewDaPtr qcvd;
	GetDataAccess(&qcvd);
	IActionHandlerPtr qacth;
	CheckHr(qcvd->GetActionHandler(&qacth));
	if (!m_hMark)
		CheckHr(qacth->Mark(&m_hMark));
	return qacth;
}
示例#4
0
/*----------------------------------------------------------------------------------------------
	@return true if any changes have been made.
----------------------------------------------------------------------------------------------*/
bool AfDeFeCliRef::IsDirty()
{
	if (!m_hwnd)
		return false; // Editor not active.
	HVO hvoOrig;
	CustViewDaPtr qcvd;
	GetDataAccess(&qcvd);
	AssertPtr(qcvd);
	CheckHr(qcvd->get_ObjectProp(m_hvoObj, m_flid, &hvoOrig));
	return hvoOrig != m_pss;
}
示例#5
0
/*----------------------------------------------------------------------------------------------
	Refresh the field from the data cache.
----------------------------------------------------------------------------------------------*/
void AfDeFeCliRef::UpdateField()
{
	// Get the item info from the cache.
	CustViewDaPtr qcvd;
	GetDataAccess(&qcvd);
	AssertPtr(qcvd);
	HVO hvoPss;
	CheckHr(qcvd->get_ObjectProp(m_hvoObj, m_flid, &hvoPss));
	m_pss = hvoPss;

	// Get the string from the poss cache.
	ITsStringPtr qtss;
	ITsStrFactoryPtr qtsf;
	StrUni stu;
	PossListInfoPtr qpli;
	PossItemInfo * ppii;
	int ipss;

	qtsf.CreateInstance(CLSID_TsStrFactory);
	int ws = m_ws;
	if (m_pss)
	{
		GetLpInfo()->LoadPossList(m_hvoPssl, m_wsMagic, &qpli);
		AssertPtr(qpli);
		ipss = qpli->GetIndexFromId(m_pss);
		if (ipss >= 0)
		{
			ppii = qpli->GetPssFromIndex(ipss);
			AssertPtr(ppii);
			if (m_fHier)
				ppii->GetHierName(qpli, stu, m_pnt);
			else
				ppii->GetName(stu, m_pnt);
			ws = ppii->GetWs();
		}
	}
	qtsf->MakeStringRgch(stu.Chars(), stu.Length(), ws, &qtss);
	m_qtss = qtss;

	// If we have an edit box, update the contents.
	if (m_hwnd)
	{
		// Setting the property causes a recursive call to OnChange, so we want to block it
		// from making a further change. (e.g., when you backspace to set the string to null
		// then tab to the next field, we want it to stay null, not go to the first item in
		// the list.)
		m_fRecurse = true;
		::SendMessage(m_hwnd, FW_EM_SETTEXT, 0, (LPARAM)m_qtss.Ptr());
	}
}
示例#6
0
/*----------------------------------------------------------------------------------------------
	Check the requirments of the FldSpec, and verify that data in the field meets the
	requirement. It returns:
		kFTReqNotReq if the all requirements are met.
		kFTReqWs if data is missing, but it is encouraged.
		kFTReqReq if data is missing, but it is required.
----------------------------------------------------------------------------------------------*/
FldReq AfDeFeSt::HasRequiredData()
{
	if (m_qfsp->m_fRequired == kFTReqNotReq)
		return kFTReqNotReq;
	CustViewDaPtr qcvd;
	GetDataAccess(&qcvd);
	AssertPtr(qcvd);
	bool fEmpty = true;
	ITsStringPtr qtss;
	int cch = 0;
	HVO hvoPara;
	int iPara;

	if (!m_hvoText)
		goto LExit;

	int cPara;
	CheckHr(qcvd->get_VecSize(m_hvoText, kflidStText_Paragraphs, &cPara));
	if (!cPara)
		goto LExit;

	// Make sure at least some paragraph has data.
	for (iPara = 0; iPara < cPara; ++iPara)
	{
		CheckHr(qcvd->get_VecItem(m_hvoText, kflidStText_Paragraphs, iPara, &hvoPara));
		// At some point we may need to handle something other than StTxtPara.
		CheckHr(qcvd->get_StringProp(hvoPara, kflidStTxtPara_Contents, &qtss));
		if (qtss)
			CheckHr(qtss->get_Length(&cch));
		if (cch)
			break; // Have a valid string
	}

	fEmpty = iPara == cPara;

LExit:
	if (fEmpty)
		return m_qfsp->m_fRequired;
	else
		return kFTReqNotReq;
}
示例#7
0
/*----------------------------------------------------------------------------------------------
	Check to see if the edit box has valid data.  if so return true.  If not then put up a
	message to the user, then return false.
----------------------------------------------------------------------------------------------*/
bool CleDeFeString::BeginEdit(HWND hwnd, Rect & rc, int dxpCursor, bool fTopCursor)
{
	SuperClass::BeginEdit(hwnd, rc, dxpCursor, fTopCursor);

	CleMainWnd * pcmw = dynamic_cast<CleMainWnd *>(m_qadsc->MainWindow());
	Assert(pcmw);
	PossListInfoPtr qpli = pcmw->GetPossListInfoPtr();
	int ipss = qpli->GetIndexFromId(m_hvoObj);
	PossItemInfo * ppii = qpli->GetPssFromIndex(ipss);
	AssertPtr(ppii);

	// Save the primary string for comparison.
	AfLpInfo * plpi = pcmw->GetLpInfo();
	AssertPtr(plpi);
	CustViewDaPtr qcvd = pcmw->MainDa();
	AssertPtr(qcvd);
	CheckHr(qcvd->get_MultiStringAlt(m_hvoObj, m_flid, plpi->ActualWs(qpli->GetWs()), &m_qtssOld));

	switch(m_flid)
	{
		case kflidCmPossibility_Name:
		{
			StrUni stu;
			ppii->GetName(stu, kpntName);
			StrUni stuNewItem(kstidNewItem);
			if (stu.Left(stuNewItem.Length()) == stuNewItem)
				m_qrootb->MakeSimpleSel(true, true, true, true, NULL);
			break;
		}
		case kflidCmPossibility_Abbreviation:
		{
			StrUni stu;
			ppii->GetName(stu, kpntAbbreviation);
			StrUni stuNew(kstidNew);
			if (stu.Left(stuNew.Length()) == stuNew)
				m_qrootb->MakeSimpleSel(true, true, true, true, NULL);
			break;
		}
	}
	return true;
}
示例#8
0
/*----------------------------------------------------------------------------------------------
	End editing with a temporary data cache by clearing stuff out down to the mark created by
	BeginTempEdit. This can be called any number of times. If a mark is not in progress, it
	does nothing.
	@return
----------------------------------------------------------------------------------------------*/
IActionHandler * AfDeFeEdBoxBut::EndTempEdit()
{
	// Get your action handler.
	CustViewDaPtr qcvd;
	GetDataAccess(&qcvd);
	IActionHandlerPtr qacth;
	CheckHr(qcvd->GetActionHandler(&qacth));
	// Clear out any temporary Undo items relating to this window.
	if (m_hMark)
	{
		// Calling DiscardToMark() when the depth is greater than zero crashes.  (See DN-786.)
		int nDepth;
		CheckHr(qacth->get_CurrentDepth(&nDepth));
		if (nDepth == 0)
		{
			CheckHr(qacth->DiscardToMark(0));
			m_hMark = 0;
		}
	}
	return qacth;
}
示例#9
0
/*----------------------------------------------------------------------------------------------
	Save changes that have been made to the current editor.
	@return true if edit saved successfully
----------------------------------------------------------------------------------------------*/
bool AfDeFeCliRef::SaveEdit()
{
	if (m_fDelFromDialog)
	{
		m_fDelFromDialog = false;
		return true;
	}
	EndTempEdit();
	if (IsDirty())
	{
		CustViewDaPtr qcvd;
		GetDataAccess(&qcvd);
		AssertPtr(qcvd);
		// Check if the record has been edited by someone else since we first loaded the data.
		HRESULT hr;
		CheckHr(hr = qcvd->CheckTimeStamp(m_hvoObj));
		if (hr != S_OK)
		{
			// If it was changed and the user does not want to overwrite it, perform a refresh
			// so the displayed field will revert to it's original value.
			m_qadsc->UpdateAllDEWindows(m_hvoObj, m_flid);
			qcvd->PropChanged(NULL, kpctNotifyAll, m_hvoObj, m_flid, 0, 1, 1);
		}
		else
		{
			// Update the value in the cache and refresh views.
			BeginChangesToLabel();
			qcvd->SetObjProp(m_hvoObj, m_flid, m_pss);
			m_qadsc->UpdateAllDEWindows(m_hvoObj, m_flid);
			qcvd->PropChanged(NULL, kpctNotifyAll, m_hvoObj, m_flid, 0, 1, 1);
			CheckHr(qcvd->EndUndoTask());
		}
	}
	// We need to leave in a state that cancels undo actions since this may be called
	// without actually closing the edit box.
	BeginTempEdit();
	return true;
}
示例#10
0
/*----------------------------------------------------------------------------------------------
	This attempts to place the cursor as defined in RecMainWnd m_vhvoPath, m_vflidPath,
	and m_ichCur.
	@param vhvo Vector of ids inside the field.
	@param vflid Vector of flids inside the field.
	@param ichCur Character offset in the final field for the cursor.
----------------------------------------------------------------------------------------------*/
void AfDeFeSt::RestoreCursor(Vector<HVO> & vhvo, Vector<int> & vflid, int ichCur)
{
	// Store the current record/subrecord and field info.
	RecMainWnd * prmw = dynamic_cast<RecMainWnd *>(m_qadsc->MainWindow());
	if (!prmw)
		return;
	CustViewDaPtr qcvd = prmw->MainDa();
	AssertPtr(qcvd);
	IVwSelectionPtr qsel;
	if (m_qrootb)
	{
		// Get the index for the paragraph.
		// We are assuming at this point that we have something like
		// vhvo = 2007 (RnGenericRec), 2014 (StText), 2017 (StTxtPara)
		// vflid = 4006001, 14001 (StText_Paragraphs), 16002 (kflidStTxtPara_Contents)
		bool fFullSpec = vflid.Size() > 1 && vhvo.Size() > 2 && vflid[1] == kflidStText_Paragraphs;
		if (fFullSpec)
		{
			int ihvo;
			VwSelLevInfo rgvsli[1];
			CheckHr(qcvd->GetObjIndex(vhvo[1], vflid[1], vhvo[2], &ihvo));
			rgvsli[0].tag = kflidStText_Paragraphs; // Set up the index for the ids.
			rgvsli[0].cpropPrevious = 0;
			rgvsli[0].ihvo = ihvo;
			m_qrootb->MakeTextSelection(
				0, // int ihvoRoot
				1, // int cvlsi,
				rgvsli, // VwSelLevInfo * prgvsli
				kflidStTxtPara_Contents, // int tagTextProp,
				0, // int cpropPrevious,
				ichCur, // int ichAnchor,
				ichCur, // int ichEnd,
				0, // int ws,
				true, // ComBool fAssocPrev,
				-1, // int ihvoEnd,
				NULL, // ITsTextProps * pttpIns,
				true, // ComBool fInstall,
				&qsel); // IVwSelection ** ppsel
		}
		// If we didn't get a text selection, try getting a selection somewhere close.
		if (!qsel)
		{
			m_qrootb->MakeTextSelInObj(
				0,  // index of the one and only root object in this view
				0, // the object we want is one level down
				NULL, // and here's how to find it there
				0,
				NULL, // don't worry about the endpoint
				true, // select at the start of it
				true, // Find an editable field
				false, // and don't select a range.
				// Making this true, allows the whole record to scroll into view when we launch
				// a new window by clicking on a reference to an entry, but we don't get an insertion
				// point. Using false gives an insertion point, but the top of the record is typically
				// at the bottom of the screen, which isn't good.
				false, // don't select the whole object
				true, // but do install it as the current selection
				NULL); // and don't bother returning it to here.
		}
	}
}
示例#11
0
/*----------------------------------------------------------------------------------------------
	Fill in the string with the given "Date Created" or "Date Modified" value.

	@param flid Field id for either "DateCreated" or "DateModified".
	@param strb Reference to the output string.
----------------------------------------------------------------------------------------------*/
void GeneralPropDlgTab::GetDateString(int flid, StrAppBuf & strb)
{
	strb.Clear();
	try
	{
		AfLpInfo * plpi = m_ppropd->GetLangProjInfo();
		AssertPtr(plpi);
		CustViewDaPtr qcvd;
		plpi->GetDataAccess(&qcvd);
		AssertPtr(qcvd);
		int64 ntim = 0;
		SilTime tim;
		SYSTEMTIME stim;
		achar rgchDate[50]; // Tuesday, August 15, 2000		mardi 15 août 2000
		achar rgchTime[50]; // 10:17:09 PM					22:20:08
		int cch;
		HVO hvo = m_ppropd->GetObjId();
		HRESULT hr;
		CheckHr(hr = qcvd->get_TimeProp(hvo, flid, &ntim));
		if (hr == S_FALSE && !ntim)
		{
			int clid = MAKECLIDFROMFLID(flid);
			AfDbInfo * pdbi = plpi->GetDbInfo();
			AssertPtr(pdbi);
			IOleDbEncapPtr qode;
			pdbi->GetDbAccess(&qode);
			AssertPtr(qode);
			IFwMetaDataCachePtr qmdc;
			pdbi->GetFwMetaDataCache(&qmdc);
			AssertPtr(qmdc);
			SmartBstr sbstrField;
			CheckHr(qmdc->GetFieldName(flid, &sbstrField));
			IOleDbCommandPtr qodc;
			CheckHr(qode->CreateCommand(&qodc));
			StrUni stu;
			ComBool fIsNull;
			ComBool fMoreRows;
			ULONG cbSpaceTaken;

			SmartBstr sbstrClass;
			CheckHr(qmdc->GetClassName(clid, &sbstrClass));
			// Note that we need the view, not just the class table proper, in case the
			// attribute is defined on a superclass (such as CmMajorObject).
			stu.Format(L"select [%b] from [%b_] where [Id] = %d",
				sbstrField.Bstr(), sbstrClass.Bstr(), hvo);
			CheckHr(qodc->ExecCommand(stu.Bstr(), knSqlStmtSelectWithOneRowset));
			CheckHr(qodc->GetRowset(0));
			CheckHr(qodc->NextRow(&fMoreRows));
			if (fMoreRows)
			{
				DBTIMESTAMP dbtim;
				CheckHr(qodc->GetColValue(1, reinterpret_cast <BYTE *>(&dbtim),
					sizeof(DBTIMESTAMP), &cbSpaceTaken, &fIsNull, 0));
				if (!fIsNull)
				{
					stim.wYear = (unsigned short)dbtim.year;
					stim.wMonth = (unsigned short)dbtim.month;
					stim.wDayOfWeek = 0;
					stim.wDay = (unsigned short)dbtim.day;
					stim.wHour = (unsigned short)dbtim.hour;
					stim.wMinute = (unsigned short)dbtim.minute;
					stim.wSecond = (unsigned short)dbtim.second;
					stim.wMilliseconds = (unsigned short)(dbtim.fraction/1000000);
					cch = ::GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &stim, NULL,
						rgchDate, 50);
					rgchDate[cch] = 0;
					cch = ::GetTimeFormat(LOCALE_USER_DEFAULT, NULL, &stim, NULL,
						rgchTime, 50);
					rgchTime[cch] = 0;
					strb.Format(_T("%s %s"), rgchDate, rgchTime);
				}
			}

		}
		else if (ntim)
		{
			tim = ntim;
			// Convert the date to a system date.
			// Then format it to a time based on the current user locale.
			stim.wYear = (unsigned short)tim.Year();
			stim.wMonth = (unsigned short)tim.Month();
			stim.wDayOfWeek = (unsigned short)tim.WeekDay();
			stim.wDay = (unsigned short)tim.Date();
			stim.wHour = (unsigned short)tim.Hour();
			stim.wMinute = (unsigned short)tim.Minute();
			stim.wSecond = (unsigned short)tim.Second();
			stim.wMilliseconds = (unsigned short)tim.MilliSecond();
			cch = ::GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &stim, NULL, rgchDate,
				50);
			rgchDate[cch] = 0;
			cch = ::GetTimeFormat(LOCALE_USER_DEFAULT, NULL, &stim, NULL, rgchTime, 50);
			rgchTime[cch] = 0;
			strb.Format(_T("%s %s"), rgchDate, rgchTime);
		}
	}
	catch (...)	// Was empty.
	{
		throw;	// For now we have nothing to add, so pass it on up.
	}
}
示例#12
0
/*----------------------------------------------------------------------------------------------
	Return the text string that gets shown to the user when this object needs to be displayed.
	This is the method for displaying the name of a single reference. This view shows the
	name for an RnGenericRec consisting of the type of record, hyphen, title, hyphen,
	creation date. "Subevent - Fishing for pirana - 3/22/2001"

	@param pguid Pointer to a database object's assigned GUID.
	@param pptss Address of a pointer to an ITsString COM object used for returning the text
					string.

	@return S_OK, E_POINTER, or E_FAIL.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP CleRecVc::GetStrForGuid(BSTR bstrGuid, ITsString ** pptss)
{
	Assert(false);  // rework

	BEGIN_COM_METHOD;
	ChkComBstrArg(bstrGuid);
	ChkComOutPtr(pptss);

	if (BstrLen(bstrGuid) != 8)
		ReturnHr(E_INVALIDARG);

	CleMainWnd * pcmw = dynamic_cast<CleMainWnd *>(AfApp::Papp()->GetCurMainWnd());
	AssertPtr(pcmw);
	CleLpInfo * plpi = dynamic_cast<CleLpInfo *>(pcmw->GetLpInfo());
	AssertPtr(plpi);

	HVO hvo = plpi->GetDbInfo()->GetIdFromGuid((GUID *)bstrGuid);

	CustViewDaPtr qcvd;
	plpi->GetDataAccess(&qcvd);
	AssertPtr(qcvd);
	int clid;
	HVO hvoOwn;
	int64 ntim;
	ITsStringPtr qtssTitle;
	CheckHr(qcvd->get_IntProp(hvo, kflidCmObject_Class, &clid));
	CheckHr(qcvd->get_ObjectProp(hvo, kflidCmObject_Owner, &hvoOwn));
			// REVIEW KenZ(RandyR) Whey are DN flids in this app?
	CheckHr(qcvd->get_TimeProp(hvo, kflidRnGenericRec_DateCreated, &ntim));
	CheckHr(qcvd->get_StringProp(hvo, kflidRnGenericRec_Title, &qtssTitle));

	int stid;
			// REVIEW KenZ(RandyR) Whey are DN flids in this app?
	if (clid == kclidRnEvent)
	{
		if (pcmw->GetRootObj() == hvoOwn)
			stid = kstidEvent;
		else
			stid = kstidSubevent;
	}
	else if (clid == kclidRnAnalysis)
	{
		if (pcmw->GetRootObj() == hvoOwn)
			stid = kstidAnalysis;
		else
			stid = kstidSubanalysis;
	}
	StrUni stu(stid);
	StrUni stuSep(kstidSpHyphenSp);

	ITsStrFactoryPtr qtsf;
	ITsIncStrBldrPtr qtisb;
	qtsf.CreateInstance(CLSID_TsStrFactory);
	CheckHr(qtsf->GetIncBldr(&qtisb));
	CheckHr(qtisb->Append(stu.Bstr()));

	CheckHr(qtisb->Append(stuSep.Bstr()));
	CheckHr(qtisb->AppendTsString(qtssTitle)); // The title.
	CheckHr(qtisb->Append(stuSep.Bstr()));
	// Leave the date blank if a date doesn't exist.
	if (ntim)
	{
		// Convert the date to a system date.
		SilTime tim = ntim;
		SYSTEMTIME stim;
		stim.wYear = (unsigned short) tim.Year();
		stim.wMonth = (unsigned short) tim.Month();
		stim.wDay = (unsigned short) tim.Date();

		// Then format it to a time based on the current user locale.
		achar rgchDate[50]; // Tuesday, August 15, 2000		mardi 15 août 2000
		::GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &stim, NULL, rgchDate, 50);
		stu = rgchDate;
		CheckHr(qtisb->Append(stu.Bstr()));
	}
	CheckHr(qtisb->GetString(pptss));

	return S_OK;

	END_COM_METHOD(g_fact2, IID_IVwViewConstructor)
}
示例#13
0
/*----------------------------------------------------------------------------------------------
	Saves changes but keeps the editing window open. In this method we need to convert dummy
	items into real items if there are any people present. We also need to delete
	RnRoledPartic and convert the field into a dummy if all of the people have been
	deleted. Otherwise, there is no way for the user to get rid of RnRoledPartic.
	@return True if successful.
----------------------------------------------------------------------------------------------*/
bool RnDeFeRoleParts::SaveEdit()
{
	// See if any items are present.
	int cpss;
	HVO hvopssl = m_vpssl[0];
	ISilDataAccessPtr qsdaTemp;
	HRESULT hr = m_qvcd->QueryInterface(IID_ISilDataAccess, (void **)&qsdaTemp);
	if (FAILED(hr))
		ThrowInternalError(E_INVALIDARG);
	CheckHr(qsdaTemp->get_VecSize(hvopssl, kflidPssIds, &cpss));
	CustViewDaPtr qcvd;
	GetDataAccess(&qcvd);
	AssertPtr(qcvd);

	if (cpss > 1) // Don't count the dummy at the end.
	{
		if (m_hvoObj == khvoDummyRnRoledPartic)
		{
			// We have a dummy RnRoledParticipant with at least one item, so we need to
			// turn the dummy into a real object.
			HVO hvo;
			BeginChangesToLabel();
			CheckHr(qcvd->MakeNewObject(kclidRnRoledPartic, m_hvoOwner, kflidRnEvent_Participants,
				-1, &hvo));
			Assert(hvo);
			m_hvoObj = hvo;

			// If someone deleted the role we are interested in while we are displaying
			// this field, we can't set the object prop or we'll get an error from the
			// database. So before doing a save, make sure our role hasn't been deleted.
			if (m_pssRole)
				CheckHr(qcvd->SetObjProp(hvo, kflidRnRoledPartic_Role, m_pssRole));

			SuperClass::SaveEdit();
			CheckHr(qcvd->EndUndoTask());
			// Need to notify this property after the participants were added in the superclass
			// for this to properly update document views.
			CheckHr(qcvd->PropChanged(m_qrootb, kpctNotifyAllButMe, m_hvoOwner,
				kflidRnEvent_Participants, 1, 1, 0));
			return true;
		}
		else
		{
			// We have a real RnRoledParticipant with at least one item, so handle it as usual.
			bool fDirty = m_fDirty;
			if (!SuperClass::SaveEdit())
				return false;
			if (fDirty)
			{
				// Database triggers/procs do not update the entry, so we must do it here.
				qcvd->SetTimeStamp(m_hvoOwner);
				qcvd->CacheCurrTimeStamp(m_hvoOwner);
			}
			return true;
		}
	}
	else
	{
		if (m_hvoObj == khvoDummyRnRoledPartic)
		{
			// We have a dummy RnRoledParticipant without any people. Do nothing so the
			// field will go away when we move to the next record.
			return true;
		}
		else
		{
			// We have a real RnRoledParticipant with no items, so we need to change this
			// into a dummy RnRoledParticipant and remove it from the database.
			CustViewDaPtr qcvd;
			GetDataAccess(&qcvd);
			AssertPtr(qcvd);
			int ihvo;
			BeginChangesToLabel();
			CheckHr(qcvd->GetObjIndex(m_hvoOwner, kflidRnEvent_Participants, m_hvoObj, &ihvo));
			CheckHr(qcvd->DeleteObjOwner(m_hvoOwner, m_hvoObj, kflidRnEvent_Participants, ihvo));
			CheckHr(qcvd->EndUndoTask());
			m_hvoObj = khvoDummyRnRoledPartic;
			CheckHr(qcvd->PropChanged(m_qrootb, kpctNotifyAllButMe, m_hvoOwner,
				kflidRnEvent_Participants, 1, 0, 1));
			return true;
		}
	}
}
示例#14
0
/*----------------------------------------------------------------------------------------------
	Close the current editor, saving changes that were made.  This also updates the the cache
	if the name or abbr fields were edited, this then causing the treebar to be updated.
	@param fForce True if we want to force the editor closed without making any
		validity checks or saving any changes.
----------------------------------------------------------------------------------------------*/
void CleDeFeString::EndEdit(bool fForce)
{
	if (fForce)
	{
		SuperClass::EndEdit(fForce);
		return;
	}

	CleMainWnd * pcmw = dynamic_cast<CleMainWnd *>(MainWindow());
	Assert(pcmw);

	PossListInfoPtr qpli = pcmw->GetPossListInfoPtr();
	int ipss = qpli->GetIndexFromId(m_hvoObj);
	if (ipss < 0)
	{
		SuperClass::EndEdit(fForce); // Closing an old editor after an item was removed.
		return;
	}
	PossItemInfo * ppii = qpli->GetPssFromIndex(ipss);
	AssertPtr(ppii);
	StrUni stu;

	const OLECHAR * prgwch;
	int cch;
	ITsStringPtr qtss;
	AssertPtr(m_qadsc->MainWindow());
	AfLpInfo * plpi = m_qadsc->MainWindow()->GetLpInfo();
	AssertPtr(plpi);
	AfDbInfo * pdbi;
	pdbi = plpi->GetDbInfo();
	AssertPtr(pdbi);
	int wsMagic = qpli->GetWs();
	int ws = plpi->ActualWs(wsMagic);

	// At this point, all strings in a PossList cache are assumed to have the same writing system.
	// However, if that writing system is missing, a non-null string from a different writing system is
	// loaded. Thus if FRN is the writing system for the PossList cache, we can't tell from the
	// cache whether the string we are getting is FRN or ENG, or some other writing system. When
	// we display strings in this editor, we show actual strings for each writing system shown.
	// Suppose we are showing FRN and ENG, but FRN is missing. If a person edits the ENG
	// string that is showing, the user would expect the tree to reflect this change, since
	// FRN is still missing. However we can't do this at this point because we don't know
	// which writing system is actually being substituted in the tree. It could actually be a GER
	// string because there also wasn't an ENG string. So until we cache encodings with each
	// string, the best we can do is only modify the PossList cache if the string for the
	// primary writing system changed. In that case, we now have a FRN string, so it should show
	// in the tree as well.
	CustViewDaPtr qcvd = pcmw->MainDa();
	AssertPtr(qcvd);

	// Get the current primary string.
	CheckHr(qcvd->get_MultiStringAlt(m_hvoObj, m_flid, ws, &qtss));
	if (qtss)
	{
		qtss->LockText(&prgwch, &cch);
		qtss->UnlockText(prgwch);
	}

	// Trim leading and trailing space characters.
	UnicodeString ust(prgwch, cch);
	ust.trim();
	stu.Assign(ust.getBuffer(), ust.length());

	// We don't expect to use this for anything except name or abbr.
	Assert(m_flid == kflidCmPossibility_Name || m_flid == kflidCmPossibility_Abbreviation);
	// We don't allow long strings.
	if (stu.Length() > kcchPossNameAbbrMax) // Need constant here and the line below.
	{
		::MessageBeep(MB_ICONEXCLAMATION); // Beep if we truncated the length.
		stu.Replace(kcchPossNameAbbrMax, stu.Length(), L"");
	}

	ITsStrFactoryPtr qtsf;
	qtsf.CreateInstance(CLSID_TsStrFactory);
	qtsf->MakeStringRgch(stu.Chars(), stu.Length(), ws, &qtss);

	// If we changed the length, store the trimmed string.
	if (cch != stu.Length())
	{
		// Check if the record has been edited by someone else since we first loaded the data.
		HRESULT hrTemp;
		if ((hrTemp = qcvd->CheckTimeStamp(m_hvoObj)) != S_OK)
		{
			// If it was changed and the user does not want to overwrite it, perform a refresh
			// so the displayed field will revert to its original value.
			CheckHr(qcvd->PropChanged(NULL, kpctNotifyAll, m_hvoObj, m_flid, 0, 1, 1));
			return;
		}

		// Update the value in the cache and refresh views.
		CheckHr(qcvd->SetMultiStringAlt(m_hvoObj, m_flid, ws, qtss));
		CheckHr(qcvd->PropChanged(NULL, kpctNotifyAll, m_hvoObj, m_flid, 0, 1, 1));
	}

	SuperClass::EndEdit(fForce);

	// See if the primary string has changed.
	ComBool fEqual;
	CheckHr(qtss->Equals(m_qtssOld, &fEqual));
	if (fEqual)
		return; // No change was made, so we don't need to do anything else.

	// A change was made.
	if (m_flid != kflidCmPossibility_Name && m_flid != kflidCmPossibility_Abbreviation)
		return; // Nothing more to do if it isn't a name or abbreviation.

	// We've changed the primary name or abbreviation, so update the PossList cache.
	ppii->SetName(stu, m_flid == kflidCmPossibility_Name ? kpntName : kpntAbbreviation);

	if (qpli->GetIsSorted())
	{
		// The list is sorted, so we need to move the item to its new location.
		if (qpli->PutInSortedPosition(m_hvoObj, false))
		{
			int ihvo;
			pcmw->LoadData();
			HvoClsidVec & vhc = pcmw->Records();
			for (ihvo = vhc.Size(); --ihvo >= 0; )
			{
				if (vhc[ihvo].hvo == m_hvoObj)
					break;
			}
			Assert(ihvo >= 0); // Should have found item.
			pcmw->SetCurRecIndex(ihvo);
		}
	}
	// We can't do a sync in this method that opens new editors, so just flag
	// that it needs to be done.
	// We need to sync if either name or abbreviation has changed. Even though we may only
	// be showing one or the other in our lists, there may be overlays or something else
	// showing the other, so to be safe, we need to do a sync if either changed.
	dynamic_cast<CleDeSplitChild *>(m_qadsc.Ptr())->SetNeedSync(true);
}
示例#15
0
/*----------------------------------------------------------------------------------------------
	Check to see if the edit box has valid data.  if so return true.  If not then put up a
	message to the user, then return false.
----------------------------------------------------------------------------------------------*/
bool CleDeFeString::IsOkToClose(bool fWarn)
{
	CleMainWnd * pcmw = dynamic_cast<CleMainWnd *>(m_qadsc->MainWindow());
	Assert(pcmw);

	IVwSelectionPtr qvwsel;
	CheckHr(m_qrootb->get_Selection(&qvwsel));
	if (qvwsel)
	{
		ComBool fOk;
		CheckHr(qvwsel->Commit(&fOk));
	}

	PossListInfoPtr qpli = pcmw->GetPossListInfoPtr();
	int ipss = qpli->GetIndexFromId(m_hvoObj);
	StrUni stuNew;

	const OLECHAR * prgwch;
	int cch;
	ITsStringPtr qtss;
	CustViewDaPtr qcvd;

	GetDataAccess(&qcvd);
	AssertPtr(qcvd);
	int ws = m_qsvc->WritingSystems()[0];

	CheckHr(qcvd->get_MultiStringAlt(m_hvoObj, m_flid, ws, &qtss));
	Assert(qtss);
	qtss->LockText(&prgwch, &cch);
	qtss->UnlockText(prgwch);

	// Trim leading and trailing space characters.
	UnicodeString ust(prgwch, cch);
	ust.trim();
	stuNew.Assign(ust.getBuffer(), ust.length());

	//  Obtain pointer to IOleDbEncap interface.
	IOleDbEncapPtr qode;
	IOleDbCommandPtr qodc;
	StrUni stuSql;
	ComBool fIsNull;
	ComBool fMoreRows;
	AssertPtr(m_qadsc->MainWindow());
	AfLpInfo * plpi = m_qadsc->MainWindow()->GetLpInfo();
	AssertPtr(plpi);
	AfDbInfo * pdbi = plpi->GetDbInfo();
	AssertPtr(pdbi);
	pdbi->GetDbAccess(&qode);
	AssertPtr(qode);
	CheckHr(qode->CreateCommand(&qodc));
	int cpii = qpli->GetCount();

	if ((m_flid == kflidCmPossibility_Name) || (m_flid == kflidCmPossibility_Abbreviation))
	{
		// Make sure it does not have a ":" or a " - " in the string
		int ich = stuNew.FindStr(L":");
		StrUni stuTmp;
		bool fFixed = false;
		while (ich > 0)
		{
			stuNew.Replace(ich,ich + 1,"-");
			fFixed = true;
			ich = stuNew.FindStr(L":");
		}
		ich = stuNew.FindStr(L" - ");
		while (ich > 0)
		{
			stuNew.Replace(ich,ich + 3,"-");
			fFixed = true;
			ich = stuNew.FindStr(L" - ");
		}
		if (fFixed)
		{
			if (fWarn)
			{
				ITsStrFactoryPtr qtsf;
				qtsf.CreateInstance(CLSID_TsStrFactory);
				qtsf->MakeStringRgch(stuNew.Chars(), stuNew.Length(), pcmw->UserWs(), &qtss);
				CheckHr(qcvd->SetMultiStringAlt(m_hvoObj, m_flid, ws, qtss));
				CheckHr(qcvd->PropChanged(NULL, kpctNotifyAll, m_hvoObj, m_flid, 0, 1, 1));
				StrApp strMsg(kstidFixedStr);
				StrApp strTitle(kstidFixedStrTitle);
				::MessageBox(m_hwnd, strMsg.Chars(), strTitle.Chars(),
					MB_OK | MB_ICONINFORMATION);
			}
			return false;
		}
	}

	if (qpli->GetAllowDup())
		return true;

	ILgWritingSystemFactoryPtr qwsf;
	pdbi->GetLgWritingSystemFactory(&qwsf);
	AssertPtr(qwsf);
	switch (m_flid)
	{
		case kflidCmPossibility_Name:
		{
			for (int ipii = 0; ipii < cpii; ipii++)
			{
				if (ipii == ipss)
					continue;
				PossItemInfo * ppii = qpli->GetPssFromIndex(ipii);
				AssertPtr(ppii);
				StrUni stu;
				ppii->GetName(stu, kpntName);
				if (stu == stuNew)
				{
					stuSql.Format(L"select ws from CmPossibility_Name "
						L"where obj = %d and ws = %d",
						ppii->GetPssId(), ws);
					CheckHr(qode->CreateCommand(&qodc));
					CheckHr(qodc->ExecCommand(stuSql.Bstr(), knSqlStmtSelectWithOneRowset));
					CheckHr(qodc->GetRowset(0));
					CheckHr(qodc->NextRow(&fMoreRows));

					if (fMoreRows)
					{
						if (fWarn)
						{
							// this name already exists
							IWritingSystemPtr qws;
							CheckHr(qwsf->get_EngineOrNull(ws, &qws));
							AssertPtr(qws);
							SmartBstr sbstr;
							qws->get_Name(ws, &sbstr);

							StrUni stu(kstidDupItemName);
							StrUni stuMsg;
							stuMsg.Format(stu,sbstr.Chars());
							StrApp str(stuMsg);
							StrApp strTitle(kstidDupItemTitle);
							::MessageBox(m_hwnd, str.Chars(), strTitle.Chars(),
								MB_OK | MB_ICONINFORMATION);
						}
						return false;
					}
				}
			}
			break;
		}
		case kflidCmPossibility_Abbreviation:
		{
			for (int ipii = 0; ipii < cpii; ipii++)
			{
				if (ipii == ipss)
					continue;
				PossItemInfo * ppii = qpli->GetPssFromIndex(ipii);
				AssertPtr(ppii);
				StrUni stu;
				ppii->GetName(stu, kpntAbbreviation);
				if (stu == stuNew)
				{
					stuSql.Format(L"select ws from CmPossibility_Abbreviation "
						L"where obj = %d and ws = %d",
						ppii->GetPssId(), ws);
					CheckHr(qode->CreateCommand(&qodc));
					CheckHr(qodc->ExecCommand(stuSql.Bstr(), knSqlStmtSelectWithOneRowset));
					CheckHr(qodc->GetRowset(0));
					CheckHr(qodc->NextRow(&fMoreRows));

					if (fMoreRows)
					{
						if (fWarn)
						{
							// this abbreviation already exists
							IWritingSystemPtr qws;
							CheckHr(qwsf->get_EngineOrNull(ws, &qws));
							AssertPtr(qws);
							SmartBstr sbstr;
							qws->get_Name(ws, &sbstr);

							StrUni stu(kstidDupItemAbbr);
							StrUni stuMsg;
							stuMsg.Format(stu,sbstr.Chars());
							StrApp str(stuMsg);
							StrApp strTitle(kstidDupItemTitle);
							::MessageBox(m_hwnd, str.Chars(), strTitle.Chars(),
								MB_OK | MB_ICONINFORMATION);
						}
						return false;
					}
				}
			}
			break;
		}
	}
	return true;
}