Example #1
0
bool	CFormula::Calculate(CContentTree * start , u64 & Ret)
{
	CFormulaNode * ptn = (CFormulaNode *)GetMyNode();
	switch(ptn->type)
	{
		case CFormulaNode::OPERATOR:
		{
			u64 Value1= 0, Value2 = 0;
			CFormula * pFml = (CFormula *)GetChildren();
			CFormulaOperatorNode * pFON  = (CFormulaOperatorNode *)ptn;

			if((!pFml)||(false == pFml->Calculate( start, Value1)))
					return false;

			pFml =  (CFormula *)(pFml->GetRightBrother());

			if((!pFml)||(false == pFml->Calculate( start, Value2)))
					return false;
					
			/*  formula is a two son tree. */
			switch(pFON->op)
			{
				case CFormulaOperatorNode::PLUS:
					Ret = Value1 + Value2;
					break;
				case CFormulaOperatorNode::MINUS:
					assert(Value1 >= Value2);
					Ret = Value1 - Value2;
					break;
				case CFormulaOperatorNode::MULTIPLY:
					Ret = Value1 * Value2;
					break;
				case CFormulaOperatorNode::DIVIDE:
					Ret = Value1 / Value2;
					break;
				case CFormulaOperatorNode::EQUAL:
					Ret = (Value1 == Value2);
					break;
				default:
					assert(0);
					break;
			}
		}
		break;
		case CFormulaNode::PARAMETER:
		{
			CFormulaParameterNode * pFPN = (CFormulaParameterNode *)ptn;
			if(false == (start->SearchBackFieldValue(&(pFPN->param) ,Ret)))
				return false;
		}
		break;
		case CFormulaNode::NUMERAL:
		{
			CFormulaNumeralNode * pFNN = (CFormulaNumeralNode *)ptn;	
			Ret = pFNN->num;
		}
		break;
	}
	return true;
}
//virtual
void  CDataDisplayPropertiesDialog::accept()
{
    if ( mVectorBox->isChecked() )
    {
        const CMapFormula &formulas = *mOperation->GetFormulas();
        for ( CMapFormula::const_iterator it = formulas.begin(); it != formulas.end(); it++ )
        {
            CFormula *f = dynamic_cast<CFormula*>( it->second );
            if ( f == nullptr || f == mFormula )
                continue;

            if ( ( f->IsNorthComponent() && mNorthComponent->isChecked() ) ||
                 ( f->IsEastComponent() && mEastComponent->isChecked() ) )
            {
                std::string s = mNorthComponent->isChecked() ? "north" : "east";
                SimpleErrorBox( "There is already a data field selected as " + s + " component." );
                return;
            }

            mFormula->SetNorthComponent( mNorthComponent->isChecked() );
            mFormula->SetEastComponent( mEastComponent->isChecked() );
        }
    }
    else
    {
        mFormula->SetNorthComponent( false );
        mFormula->SetEastComponent( false );
    }
    base_t::accept();
}
Example #3
0
bool	CFormula::IsValid(CFormatTree * start )
{
	CFormulaNode * ptn = (CFormulaNode *)GetMyNode();
	switch(ptn->type)
	{
		case CFormulaNode::OPERATOR:
		{
			CFormula * pFml = (CFormula *)GetChildren();								
			while(pFml)
			{
				if(false == pFml->IsValid( start))
					return false;

				pFml = (CFormula *)(pFml->GetRightBrother());
			}
		}
		break;
		case CFormulaNode::PARAMETER:
		{
			CFormulaParameterNode * pFPN = (CFormulaParameterNode *)ptn;
			if(false == (start->SearchBackField(&(pFPN->param))))
				return false;
		}
		break;
		case CFormulaNode::NUMERAL:
		{
			CFormulaNumeralNode * pFNN = (CFormulaNumeralNode *)ptn;
			if(pFNN->num == 0)
			{
				return false;/* number 0 is meanless .*/
			}
		}
		break;
	}
	return true;
}
Example #4
0
void CCellView::Read(BPositionIO& stream)
{
	CSwapStream str(stream);

	scChunk chunk;
	long offset;
	int *funcList, *styleList, *fontList, *formatList;
	int funcCount, styleCount, fontCount, formatCount, borderFont = fBorderFontID;
	bool warnForIncorrectFormula = true;
	scCell cl;

	styleCount = 0;
	styleList = (int *)MALLOC(0);
	fontCount = 0;
	fontList = (int *)MALLOC(0);
	formatCount = 0;
	formatList = (int *)MALLOC(0);
	funcList = NULL;
	
	scCSElement *colStyles = NULL;
	int colStyleCount = 0;

	offset = 0;

	StProgress progress(this, 1, pColorYellow, false);
	StWriteLock lock(fContainer);

	try
	{
		stream.Seek(offset, SEEK_SET);
		
		str >> chunk;

		if (chunk.type == kscVersion)
		{
			scVersion vers;
			str >> vers;
			if (vers.major != 3)
				THROW((errTooNewFileFormat));
		}
		else
			THROW((errUnknownFileFormat, ((CCellWindow *)Window())->EntryRef()->name));

		do
		{
			if (stream.Seek(offset, SEEK_SET) < offset)
			{
				MStopAlert("File is too short").Go();
				break;
			}
			
			str >> chunk;
			offset += 4 + chunk.size;
			
			switch (chunk.type)
			{
				case kscVersion:
					break;
				case kscHeader:
				{
					scHeader head;
					str >> head;
					
					funcList = (int *)CALLOC(head.functionCount, sizeof(int));
					FailNil(funcList);
					funcCount = head.functionCount;
					progress.NewMax(head.cellCount);
					break;
				}
				case kscView:
				{
					scView view;
					str >> view;
					
					if (view.windowRect.left > 0 && view.windowRect.top > 0)
					{
						BRect r;
						{
							r = BScreen().Frame();
						}

						r.InsetBy(4, 4);
						r = r & view.windowRect;
						
						if (r.IsValid() && r.Width() >= 300 && r.Height() >= 100)
						{
							Window()->MoveTo(r.left, r.top);
							Window()->ResizeTo(r.Width(), r.Height());
						}
					}
					if (view.position.h > 0 && view.position.v > 0)
						fPosition = view.position;
					fFrozen = view.frozen;
					if (view.selection.IsValid())
						fSelection = view.selection;
					if (fSelection.Contains(view.curCell))
						fCurCell = view.curCell;
					borderFont = view.headingFont;
					fShowGrid = (view.flags & kscShowGrid) != 0;
					fShowBorders = (view.flags & kscShowHeadings) != 0;
					if (!fShowBorders)
					{
						fCellBounds.left -= fBorderWidth;
						fCellBounds.top -= fBorderHeight;
					}

					Window()->Show();
					Window()->UpdateIfNeeded();
					break;
				}
				case kscPrint:
					break;
				case kscWidths:
				case kscHeights:
				{
					int count = chunk.size/(sizeof(short)*2);
					scWidthElement *elems = (scWidthElement *)MALLOC(chunk.size);
					FailNil(elems);
					
					int k = count * sizeof(scWidthElement);
					stream.Read(elems, k);
					
					if (chunk.type == kscWidths)
						fCellWidths.Read(count, elems);
					else
						fCellHeights.Read(count, elems);

					FREE(elems);
					break;
				}
				case kscColStyles:
				{
					colStyleCount = chunk.size/(sizeof(short)*2);
					colStyles = (scCSElement *)MALLOC(chunk.size);
					FailNil(colStyles);
					
					for (int i = 0; i < colStyleCount; i++)
						str >> colStyles[i];
					break;
				}
				case kscName:
				{
					char buf[50];
					scName *name = (scName *)buf;
					int l = std::min((int)chunk.size, 50);
					
					stream.Read(name, l);

					range r;
					
					memcpy(&r, name->reference+1, sizeof(cell));
					if (name->reference[0] == valRange)
						memcpy(&r.bottom, name->reference+5, sizeof(cell));
					else
						r.BotRight() = r.TopLeft();
					
					swap_order(r);
					
					if (fNames->count(name->name) == 0)
						(*fNames)[CName(name->name)] = r;
					break;
				}
				case kscFunc:
				{
					scFunc func;
					str >> func;
					
					if (!funcList) THROW((errCorruptedFile));
					if (func.funcNr >= funcCount)
						THROW((errCorruptedFile));
					
					funcList[func.funcNr] = GetFunctionNr(func.name);
					if (funcList[func.funcNr] == -1)
						WarnForMissingFunction(func.name);
					break;
				}
				case kscFont:
				{
					scFont font;
					str >> font;
					font_family fam;
					font_style sty;
					
					ReadCString(stream, sizeof(font_style), sty);
					ReadCString(stream, sizeof(font_family), fam);
				
					int *t = (int *)REALLOC(fontList, (fontCount+1)*sizeof(int));
					FailNil(t);
					fontList = t;
					fontList[fontCount] = gFontSizeTable.GetFontID(
						fam, sty, font.size, font.color);
					fontCount++;
					break;
				}
				case kscFormat:
				{
					scFormat format;
					str >> format;
					
					int *t = (int *)REALLOC(formatList, (formatCount+1)*sizeof(int));
					FailNil(t);
					formatList = t;
					
					if (format.nr < eFirstNewFormat)
						formatList[formatCount] = format.nr;
					else
					{
						char fs[256];
						ReadCString(stream, 255, fs);
						formatList[formatCount] = gFormatTable.GetFormatID(fs);
					}
						
					formatCount++;
					break;
				}
				case kscStyle:
				{
					scStyle style;
					str >> style;
					
					int *t = (int *)REALLOC(styleList, (styleCount+1)*sizeof(int));
					FailNil(t);
					styleList = t;
					
					CellStyle cs;

					if (style.font >= fontCount)
						THROW((errCorruptedFile));
					cs.fFont = fontList[style.font];

					if (style.format >= formatCount)
						THROW((errCorruptedFile));
					cs.fFormat = formatList[style.format];

					cs.fAlignment = style.align;
					cs.fLowColor = style.lowColor;
					cs.fLocked = (style.flags & kscLocked) != 0;
					cs.fHidden = (style.flags & kscHidden) != 0;
					
					styleList[styleCount] = gStyleTable.GetStyleID(cs);
					
					styleCount++;
					break;
				}
				case kscCellEmpty:
				case kscCellBool:
				case kscCellNumber:
				case kscCellDateTime:
				case kscCellText:
				{
					str >> cl;
					
					Value val;
					
					switch (chunk.type)
					{
						case kscCellBool:
						{
							bool b;
							str >> b;
							val = b;
							break;
						}
						case kscCellNumber:
						{
							double d;
							str >> d;
							val = d;
							break;
						}
						case kscCellDateTime:
						{
							time_t t;
							str >> t;
							val = t;
							break;
						}
						case kscCellText:
						{
							// do nothing yet...
						}
					}
	
					fContainer->NewCell(cl.loc, val, NULL);
					if (cl.style >= styleCount)
						/*THROW((errCorruptedFile))*/;
					else
						fContainer->SetCellStyleNr(cl.loc, styleList[cl.style]);
					
					progress.Step();
					break;
				}
				case kscString:
				{
					char s[256];
					Value val;
					stream.Read(s, std::min((int)chunk.size, 255));
					s[std::min((int)chunk.size, 255)] = 0;
					val = s;
					
					fContainer->SetValue(cl.loc, val);
					break;
				}
				case kscFormula:
				{
					CFormula form;
					try
					{
						if (!funcList) THROW((errCorruptedFile));
						form.Read(stream, funcList);
						Value v;
						form.Calculate(cl.loc, v, fContainer);
						fContainer->SetCellFormula(cl.loc, form.CopyString());
					}
					catch (CErr& e)
					{
						CATCHED;
						char s[32];
						cl.loc.GetName(s);
#if DEBUG
						printf("%s in formula of cell %s\n", (char *)e, s);
#endif
						if (warnForIncorrectFormula)
						{
							char m[256];
							sprintf(m, GetMessage(msgIncorrectFormula), s);
							MAlert *a = new MWarningAlert(m, GetMessage(msgOK),
								GetMessage(msgNoMoreWarnings));
							if (a->Go() == 2)
								warnForIncorrectFormula = false;
						}
					}
					form.Clear();
					break;
				}
				case kscChart:
					ReadChart(stream, chunk.size);
				case kscEnd:
					break;
				default:
					MStopAlert("File contains errors").Go();
					chunk.type = kscEnd;
					break;
			}
		}
		while (chunk.type != kscEnd);

// adjust the fields that couldn't be adjusted before
		if (fontCount && borderFont < fontCount)
			fBorderFontID = fontList[borderFont];
		
		if (colStyles && styleList)
		{
			for (int i = 0; i < colStyleCount; i++)
			{
				if (colStyles[i].style >= 0 && colStyles[i].style < styleCount)	
					colStyles[i].style = styleList[colStyles[i].style];
			}
			fContainer->GetColumnStyles().Read(colStyleCount, colStyles);
		}
	}
Example #5
0
void CCellView::Write(BPositionIO& stream)
{
// Collect the information needed to write the file, fonts first...
	int *fontList, usedFonts;
	fontList = (int *)MALLOC(gFontSizeTable.Count() * sizeof(int));
	FailNil(fontList);
	usedFonts = fContainer->CollectFontList(fontList);
	if (GetOffsetOf(fontList, fBorderFontID, usedFonts) == -1)
		fontList[usedFonts++] = fBorderFontID;

// ...then the styles
	int *styleList, usedStyles;
	styleList = (int *)CALLOC(gStyleTable.Count(), sizeof(int));
	FailNil(styleList);
	usedStyles = fContainer->CollectStyles(styleList);

// Write the version number
	scVersion vers;
	vers.major = 3;
	vers.minor = 0;
	WriteChunk(stream, kscVersion, sizeof(vers), &vers);

// Write some header info, global to the document
	scHeader head;
	head.defaultFormat = 0;
	head.flags = htonl(fAutoRecalc ? kscAutoRecalc : 0);
	head.functionCount = htons(gFuncCount);
	head.cellCount = htonl(fContainer->GetCellCount());
	WriteChunk(stream, kscHeader, sizeof(head), &head);

// Write a view 
	scView view;
	view.windowRect = Window()->Frame();			swap_order(view.windowRect);
	view.position = fPosition;								swap_order(view.position);
	view.frozen = fFrozen;								swap_order(view.frozen);
	view.curCell = fCurCell;								swap_order(view.curCell);
	view.selection = fSelection;							swap_order(view.selection);
	view.headingFont = htons(GetOffsetOf(fontList, fBorderFontID, usedFonts));
	if (fShowGrid) view.flags |= kscShowGrid;
	if (fShowBorders) view.flags |= kscShowHeadings;
	if (fDisplayZero) view.flags |= kscDisplayZero;	swap_order(view.flags);
	WriteChunk(stream, kscView, sizeof(view), &view);

	short size;

// Write the widths of the last view	
	size = fCellWidths.Count() * sizeof(short) * 2;
	void *p = MALLOC(size);
	FailNil(p);
	fCellWidths.Write(p);
	WriteChunk(stream, kscWidths, size, p);
	FREE(p);
	
// And the heights of course
	size = fCellHeights.Count() * sizeof(short) * 2;
	p = MALLOC(size);
	FailNil(p);
	fCellHeights.Write(p);
	WriteChunk(stream, kscHeights, size, p);
	FREE(p);

// Then write the styles for the columns
	size = fContainer->GetColumnStyles().Count() * sizeof(short) * 2;
	p = MALLOC(size);
	FailNil(p);
	scCSElement *sp = (scCSElement *)p;
	fContainer->GetColumnStyles().Write(p);
	for (int i = 0; i < fContainer->GetColumnStyles().Count(); i++)
	{
		swap_order(sp[i].index);
		sp[i].style = htons(GetOffsetOf(styleList, sp[i].style, usedStyles));
	}
	WriteChunk(stream, kscColStyles, size, p);
	FREE(p);

// Continue with the names
	namemap::iterator ni;
	for (ni = fNames->begin(); ni != fNames->end(); ni++)
	{
		scName name;
		char c;
		ushort k = htons(kscName);
		memset(name.name, 0, 32);
		
		CHECKWRITE(stream, &k, 2);
		
		strcpy(name.name, (*ni).first);
		
		if ((*ni).second.BotRight() == (*ni).second.TopLeft())
		{
			k = htons(32 + 6);
			CHECKWRITE(stream, &k, 2);
			CHECKWRITE(stream, name.name, 32);

			c = valCell;
			CHECKWRITE(stream, &c, sizeof(c));
			cell C = (*ni).second.BotRight();
			swap_order(C);
			CHECKWRITE(stream, &C, sizeof(cell));
		}
		else
		{
			k = htons(32 + 10);
			CHECKWRITE(stream, &k, 2);
			CHECKWRITE(stream, name.name, 32);

			c = valRange;
			CHECKWRITE(stream, &c, sizeof(c));
			range r = (*ni).second;
			swap_order(r);
			CHECKWRITE(stream, &r, sizeof(range));
		}
		c = opEnd;
		CHECKWRITE(stream, &c, sizeof(c));
	}

// Then there are the functions used in this document
	CSet funcs;
	fContainer->CollectFunctionNrs(funcs);
	for (int i = kFunctionCount; i < gFuncCount; i++)
		if (funcs[i])
		{
			scFunc func;
			memset(func.name, 0, 10);
			strcpy(func.name, gFuncArrayByNr[i].funcName);
			func.argCnt = htons(gFuncArrayByNr[i].argCnt);
			func.funcNr = htons(gFuncArrayByNr[i].funcNr);
			WriteChunk(stream, kscFunc, sizeof(func), &func);
		}

// Followed by the formatting information. Fonts first
	for (int i = 0; i < usedFonts; i++)
	{
		CFontMetrics fm = gFontSizeTable[fontList[i]];
		scFont *font;
		
		font_family fam;
		font_style sty;
		fm.Font().GetFamilyAndStyle(&fam, &sty);

		ulong size = sizeof(scFont) + strlen(fam) + strlen(sty) + 2;
		
		font = (scFont *)CALLOC(1, size);
		FailNil(font);
		
		font->size = B_HOST_TO_BENDIAN_FLOAT(fm.Font().Size());
		font->color = fm.FontColor();
		
		char *p = (char *)font + sizeof(scFont);
		strcpy(p, sty);
		p += strlen(sty) + 1;
		strcpy(p, fam);

		WriteChunk(stream, kscFont, size, font);
		FREE(font);
	}
	
// Then we get the number formats
	int *formatList, usedFormats;
	formatList = (int *)MALLOC(gFormatTable.Count() * sizeof(int));
	FailNil(formatList);
	usedFormats = fContainer->CollectFormats(formatList);
	for (int i = 0; i < usedFormats; i++)
	{
		CFormatter nf;
		if (formatList[i] < eFirstNewFormat)
			nf = CFormatter(formatList[i]);
		else
			nf = gFormatTable[formatList[i]];
		
		scFormat format;
		format.nr = htons(nf.FormatID());
		format.info[0] = 0;
		format.info[1] = 0;
		format.info[2] = 0;
		format.info[3] = 0;
		
		WriteChunk(stream, kscFormat, sizeof(format)-1, &format);
	}
	
// The style table
	for (int i = 0; i < usedStyles; i++)
	{
		CellStyle cs = gStyleTable[styleList[i]];

		scStyle style;
		memset(&style, 0, sizeof(style));
		style.font = htons(GetOffsetOf(fontList, cs.fFont, usedFonts));
		style.format = htons(GetOffsetOf(formatList, cs.fFormat, usedFormats));
		style.align = cs.fAlignment;
		style.lowColor = cs.fLowColor;
		
		WriteChunk(stream, kscStyle, sizeof(style), &style);
	}
	FREE(fontList);
	FREE(formatList);
	
	int *t = (int *)CALLOC(gStyleTable.Count(), sizeof(int));
	FailNil(t);
	for (int i = 0; i < usedStyles; i++)
		t[styleList[i]] = i;
	
	FREE(styleList);
	styleList = t;
	
// And now its time for some data
	StProgress progress(this, fContainer->GetCellCount(), pColorYellow, false);

	CCellIterator iter(fContainer);
	cell c;
	while (iter.NextExisting(c))
	{
		scCell cl;
		cl.loc = c;							swap_order(cl.loc);
		cl.style = htons(styleList[fContainer->GetCellStyleNr(c)]);
		Value val;
		fContainer->GetValue(c, val);
		
		switch (val.fType)
		{
			case eNoData:
				WriteChunk(stream, kscCellEmpty, kscCellSize, &cl);
				break;
			case eNumData:
			{
				double d = B_HOST_TO_BENDIAN_DOUBLE(val.fDouble);
				memcpy(cl.num, &d, sizeof(double));
				WriteChunk(stream, kscCellNumber, kscCellSize+sizeof(double), &cl);
				break;
			}
			case eBoolData:
				memcpy(cl.num, &val.fBool, sizeof(bool));
				WriteChunk(stream, kscCellBool, kscCellSize+sizeof(bool), &cl);
				break;
			case eTimeData:
			{
				time_t t = htonl(val.fTime);	
				memcpy(cl.num, &t, sizeof(time_t));
				WriteChunk(stream, kscCellDateTime, kscCellSize+sizeof(time_t), &cl);
				break;
			}
			case eTextData:
			{
				WriteChunk(stream, kscCellText, kscCellSize, &cl);
				const char *t = val;
				WriteChunk(stream, kscString, strlen(t) + 1, t);
				break;
			}
			default:
				// there was a warning about not all enum values handled in 
				// switch statement.
				break;
		}
		
		CFormula form = fContainer->GetCellFormula(c);
		if (form.IsFormula())
		{
			BMallocIO buf;
			form.Write(buf);
			
			WriteChunk(stream, kscFormula, buf.BufferLength(), buf.Buffer());
		}
		progress.Step();
	}
	
	WriteCharts(stream);
	
// cleanup the mess
	
	WriteChunk(stream, kscEnd, 0, NULL);

	FREE(styleList);
}
Example #6
0
bool CFormula::DumpToString(CString & TraceStr)
{
	CFormulaNode * ptn = (CFormulaNode *)GetMyNode();
	switch(ptn->type)
	{
		case CFormulaNode::OPERATOR:
			{
				CFormula * pFml = (CFormula *)GetChildren();
				CFormulaOperatorNode * pFON ;
				pFON = (CFormulaOperatorNode *)ptn;
					
				if(pFml)
				{
					pFml->DumpToString( TraceStr);
					while(pFml->GetRightBrother())
					{
						switch(pFON->op)
						{
							case CFormulaOperatorNode::PLUS:
								TraceStr.AppendFormat(" + ");
								break;
							case CFormulaOperatorNode::MINUS:
								TraceStr.AppendFormat(" - ");
								break;
							case CFormulaOperatorNode::MULTIPLY:
								TraceStr.AppendFormat(" * ");
								break;
							case CFormulaOperatorNode::DIVIDE:
								TraceStr.AppendFormat(" / ");
								break;
							case CFormulaOperatorNode::EQUAL:
								TraceStr.AppendFormat(" = ");
								break;
						}
						pFml = (CFormula *)(pFml->GetRightBrother());
						ptn = (CFormulaNode *)pFml->GetMyNode();
						if(ptn->type == CFormulaNode::OPERATOR)
						{/*second son is operator mean () is used for change priority */
							TraceStr.AppendFormat(" ( ");
							pFml->DumpToString( TraceStr);
							TraceStr.AppendFormat(" ) ");
						}
						else
						{
							pFml->DumpToString( TraceStr);
						}
					}
				}
				else
					assert(0);
			}
			break;
		case CFormulaNode::PARAMETER:
			{
				CFormulaParameterNode * pFPN = (CFormulaParameterNode *)ptn;
				TraceStr.AppendFormat("%s",pFPN->param);
			}
			break;
		case CFormulaNode::NUMERAL:
			{
				CFormulaNumeralNode * pFNN = (CFormulaNumeralNode *)ptn;
				TraceStr.AppendFormat("%d",pFNN->num);
			}
			break;
	}
	return true;
}