1 //////////////////////////////////////////////////////////////////////////
2 //
3 // pgAdmin III - PostgreSQL Tools
4 //
5 // Copyright (C) 2002 - 2016, The pgAdmin Development Team
6 // This software is released under the PostgreSQL Licence
7 //
8 // ddTextTableItemFigure.cpp - Draw a column inside a table
9 //
10 ////////////////////////////////////////////////////////////////////////////
11 
12 #include "pgAdmin3.h"
13 
14 // wxWindows headers
15 #include <wx/wx.h>
16 #include <wx/dcbuffer.h>
17 #include <wx/numdlg.h>
18 
19 // App headers
20 #include "dd/dditems/figures/ddTextTableItemFigure.h"
21 #include "dd/dditems/figures/ddRelationshipItem.h"
22 #include "dd/dditems/tools/ddColumnTextTool.h"
23 #include "dd/dditems/utilities/ddDataType.h"
24 #include "hotdraw/figures/hdSimpleTextFigure.h"
25 #include "hotdraw/main/hdDrawingView.h"
26 #include "dd/ddmodel/ddDrawingEditor.h"
27 #include "dd/ddmodel/ddDatabaseDesign.h"
28 #include "dd/dditems/figures/ddTableFigure.h"
29 #include "dd/dditems/utilities/ddPrecisionScaleDialog.h"
30 #include "hotdraw/utilities/hdRemoveDeleteDialog.h"
31 
ddTextTableItemFigure(wxString & columnName,ddDataType dataType,ddColumnFigure * owner)32 ddTextTableItemFigure::ddTextTableItemFigure(wxString &columnName, ddDataType dataType, ddColumnFigure *owner):
33 	hdSimpleTextFigure(columnName)
34 {
35 	setKindId(DDTEXTTABLEITEMFIGURE);
36 	ownerTable = NULL; //table name item is the only one case of use of this variable
37 	oneTimeNoAlias = false;
38 	columnType = dataType;
39 	this->setEditable(true);
40 	enablePopUp();
41 	ownerColumn = owner;
42 	showDataType = true;
43 	showAlias = false;
44 	recalculateDisplayBox();
45 	precision = -1;
46 	scale = -1;
47 
48 	if(owner)  //is Column Object
49 	{
50 		fontColorAttribute->fontColor = owner->getOwnerTable()->fontColorAttribute->fontColor;
51 		fontSelColorAttribute->fontColor = owner->getOwnerTable()->fontSelColorAttribute->fontColor;
52 	}
53 }
54 
~ddTextTableItemFigure()55 ddTextTableItemFigure::~ddTextTableItemFigure()
56 {
57 }
58 
recalculateDisplayBox()59 void ddTextTableItemFigure::recalculateDisplayBox()
60 {
61 	if (ownerColumn && ownerColumn->getOwnerTable())
62 	{
63 		hdSimpleTextFigure::recalculateDisplayBox();
64 		displayBox().width = ownerColumn->getOwnerTable()->getFiguresMaxWidth();
65 	}
66 }
67 
displayBoxUpdate()68 void ddTextTableItemFigure::displayBoxUpdate()
69 {
70 	recalculateDisplayBox();
71 }
72 
setOwnerTable(ddTableFigure * table)73 void ddTextTableItemFigure::setOwnerTable(ddTableFigure *table)
74 {
75 	ownerTable = table;
76 	if(table)//is Table Name object
77 	{
78 		fontColorAttribute->fontColor = ownerTable->fontColorAttribute->fontColor;
79 		fontSelColorAttribute->fontColor = ownerTable->fontSelColorAttribute->fontColor;
80 	}
81 }
82 
getText(bool extended)83 wxString &ddTextTableItemFigure::getText(bool extended)
84 {
85 	if(showDataType && extended && getOwnerColumn())
86 	{
87 		wxString ddType = dataTypes()[getDataType()];   //Should use getDataType() & getPrecision(), because when column is fk, type is not taken from this column, instead from original column (source of fk)
88 		bool havePrecision = columnType == dt_numeric || columnType == dt_bit || columnType == dt_char || columnType == dt_interval || columnType == dt_varbit || columnType == dt_varchar;
89 		if( havePrecision && getPrecision() >= 0)
90 		{
91 			ddType.Truncate(ddType.Find(wxT("(")));
92 			if(getScale() == -1)
93 				ddType += wxString::Format(wxT("(%d)"), getPrecision());
94 			else
95 				ddType += wxString::Format(wxT("(%d,%d)"), getPrecision(), getScale());
96 		}
97 		//Fix to serial is integer at automatically generated foreign key
98 		if(getDataType() == dt_serial && getOwnerColumn()->isGeneratedForeignKey())
99 			ddType = dataTypes()[dt_integer];
100 
101 		out = wxString( hdSimpleTextFigure::getText() + wxString(wxT(" : ")) + ddType );
102 		return  out;
103 	}
104 	else if( showAlias && getOwnerColumn() == NULL )
105 	{
106 		if(!oneTimeNoAlias)
107 			out = wxString( hdSimpleTextFigure::getText() + wxString(wxT(" ( ")) + colAlias + wxString(wxT(" ) ")) );
108 		else
109 		{
110 			out = wxString( hdSimpleTextFigure::getText() );
111 			oneTimeNoAlias = false;
112 		}
113 		return out;
114 	}
115 	else
116 	{
117 		return hdSimpleTextFigure::getText();
118 	}
119 }
120 
getType(bool raw)121 wxString ddTextTableItemFigure::getType(bool raw)
122 {
123 	wxString ddType = dataTypes()[columnType];
124 	if(raw)
125 		return ddType;
126 
127 	bool havePrecision = columnType == dt_numeric || columnType == dt_bit || columnType == dt_char || columnType == dt_interval || columnType == dt_varbit || columnType == dt_varchar;
128 	if( havePrecision && getPrecision() >= 0)
129 	{
130 		ddType.Truncate(ddType.Find(wxT("(")));
131 		if(getScale() == -1)
132 			ddType += wxString::Format(wxT("(%d)"), getPrecision());
133 		else
134 			ddType += wxString::Format(wxT("(%d,%d)"), getPrecision(), getScale());
135 	}
136 
137 	//Fix to serial is integer at automatically generated foreign key
138 	if(columnType == dt_serial && getOwnerColumn()->isGeneratedForeignKey())
139 		ddType = dataTypes()[dt_integer];
140 
141 	return ddType;
142 }
143 
144 //WARNING: event ID must match enum ddDataType!!! this event was created on view
OnGenericPopupClick(wxCommandEvent & event,hdDrawingView * view)145 void ddTextTableItemFigure::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view)
146 {
147 	wxTextEntryDialog *nameDialog = NULL;
148 	ddPrecisionScaleDialog *numericDialog = NULL;
149 	wxString tmpString;
150 	int answer;
151 	int tmpprecision;
152 	long tmpvalue;
153 	hdRemoveDeleteDialog *delremDialog = NULL;
154 
155 	switch(event.GetId())
156 	{
157 		case MNU_DDADDCOLUMN:
158 			nameDialog = new wxTextEntryDialog(view, wxT("New column name"), wxT("Add a column"));
159 			answer = nameDialog->ShowModal();
160 			if (answer == wxID_OK)
161 			{
162 				tmpString = nameDialog->GetValue();
163 				getOwnerColumn()->getOwnerTable()->addColumn(view->getIdx(), new ddColumnFigure(tmpString, getOwnerColumn()->getOwnerTable()));
164 				view->notifyChanged();
165 			}
166 			delete nameDialog;
167 			break;
168 		case MNU_DELCOLUMN:
169 			answer = wxMessageBox(wxT("Are you sure you wish to delete column ") + getText(true) + wxT("?"), wxT("Delete column?"), wxYES_NO | wxNO_DEFAULT, view);
170 			if (answer == wxYES)
171 			{
172 				getOwnerColumn()->getOwnerTable()->removeColumn(view->getIdx(), getOwnerColumn());
173 				view->notifyChanged();
174 			}
175 			break;
176 		case MNU_AUTONAMCOLUMN:
177 			getOwnerColumn()->activateGenFkName();
178 			getOwnerColumn()->getFkSource()->syncAutoFkName();
179 			view->notifyChanged();
180 			break;
181 		case MNU_RENAMECOLUMN:
182 			nameDialog = new wxTextEntryDialog(view, wxT("New column name"), wxT("Rename Column"), getText());
183 			nameDialog->ShowModal();
184 			if(getOwnerColumn()->isGeneratedForeignKey()) //after a manual user column rename, deactivated automatic generation of fk name.
185 				getOwnerColumn()->deactivateGenFkName();
186 			setText(nameDialog->GetValue());
187 			delete nameDialog;
188 			view->notifyChanged();
189 			break;
190 		case MNU_NOTNULL:
191 			if(getOwnerColumn()->isNotNull())
192 				getOwnerColumn()->setColumnOption(null);
193 			else
194 				getOwnerColumn()->setColumnOption(notnull);
195 			view->notifyChanged();
196 			break;
197 		case MNU_PKEY:
198 			if(getOwnerColumn()->isPrimaryKey())
199 			{
200 				getOwnerColumn()->disablePrimaryKey();
201 			}
202 			else
203 			{
204 				getOwnerColumn()->enablePrimaryKey();
205 				getOwnerColumn()->setColumnOption(notnull);
206 			}
207 			view->notifyChanged();
208 			break;
209 		case MNU_UKEY:
210 			getOwnerColumn()->toggleColumnKind(uk, view);
211 			view->notifyChanged();
212 			break;
213 		case MNU_TYPESERIAL:
214 			setDataType(dt_serial);  //Should use setDataType always to set this value to allow fk to work flawlessly
215 			recalculateDisplayBox();
216 			getOwnerColumn()->displayBoxUpdate();
217 			getOwnerColumn()->getOwnerTable()->updateTableSize();
218 			view->notifyChanged();
219 			break;
220 		case MNU_TYPEBOOLEAN:
221 			setDataType(dt_boolean);
222 			recalculateDisplayBox();
223 			getOwnerColumn()->displayBoxUpdate();
224 			getOwnerColumn()->getOwnerTable()->updateTableSize();
225 			view->notifyChanged();
226 			break;
227 		case MNU_TYPEINTEGER:
228 			setDataType(dt_integer);
229 			recalculateDisplayBox();
230 			getOwnerColumn()->displayBoxUpdate();
231 			getOwnerColumn()->getOwnerTable()->updateTableSize();
232 			view->notifyChanged();
233 			break;
234 		case MNU_TYPEMONEY:
235 			setDataType(dt_money);
236 			recalculateDisplayBox();
237 			getOwnerColumn()->displayBoxUpdate();
238 			getOwnerColumn()->getOwnerTable()->updateTableSize();
239 			view->notifyChanged();
240 			break;
241 		case MNU_TYPEVARCHAR:
242 			setDataType(dt_varchar);
243 			tmpprecision = wxGetNumberFromUser(_("Varchar size"),
244 			                                   _("Size for varchar datatype"),
245 			                                   _("Varchar size"),
246 			                                   getPrecision(), 0, 255, view);
247 			if (tmpprecision >= 0)
248 			{
249 				setPrecision(tmpprecision);
250 				setScale(-1);
251 			}
252 			recalculateDisplayBox();
253 			getOwnerColumn()->displayBoxUpdate();
254 			getOwnerColumn()->getOwnerTable()->updateTableSize();
255 			view->notifyChanged();
256 			break;
257 		case MNU_TYPEOTHER:
258 			answer = wxGetSingleChoiceIndex(wxT("New column datatype"), wxT("Column Datatypes"), dataTypes(), view);
259 			if(answer >= 0)
260 			{
261 				view->notifyChanged();
262 				if(answer == dt_varchar || answer == dt_bit || answer == dt_char || answer == dt_interval || answer == dt_varbit)
263 				{
264 					tmpprecision = wxGetNumberFromUser(_("datatype size"),
265 					                                   _("Size for datatype"),
266 					                                   _("size"),
267 					                                   getPrecision(), 0, 255, view);
268 					if (tmpprecision >= 0)
269 					{
270 						setPrecision(tmpprecision);
271 						setScale(-1);
272 					}
273 					recalculateDisplayBox();
274 					getOwnerColumn()->displayBoxUpdate();
275 					getOwnerColumn()->getOwnerTable()->updateTableSize();
276 				}
277 				if(answer == dt_numeric)
278 				{
279 					numericDialog = new ddPrecisionScaleDialog(	view,
280 					        NumToStr((long)getPrecision()),
281 					        NumToStr((long)getScale()));
282 					numericDialog->ShowModal();
283 					numericDialog->GetValue1().ToLong(&tmpvalue);
284 					setPrecision(tmpvalue);
285 					numericDialog->GetValue2().ToLong(&tmpvalue);
286 					setScale(tmpvalue);
287 					delete numericDialog;
288 					recalculateDisplayBox();
289 					getOwnerColumn()->displayBoxUpdate();
290 					getOwnerColumn()->getOwnerTable()->updateTableSize();
291 				}
292 
293 
294 				setDataType( (ddDataType) answer );
295 				recalculateDisplayBox();
296 				getOwnerColumn()->displayBoxUpdate();
297 				getOwnerColumn()->getOwnerTable()->updateTableSize();
298 			}
299 			break;
300 		case MNU_TYPEPKEY_CONSTRAINTNAME:
301 			tmpString = wxGetTextFromUser(wxT("New name of primary key:"), getOwnerColumn()->getOwnerTable()->getPkConstraintName(), getOwnerColumn()->getOwnerTable()->getPkConstraintName(), view);
302 			if(tmpString.length() > 0)
303 			{
304 				getOwnerColumn()->getOwnerTable()->setPkConstraintName(tmpString);
305 				view->notifyChanged();
306 			}
307 			break;
308 		case MNU_TYPEUKEY_CONSTRAINTNAME:
309 			answer = wxGetSingleChoiceIndex(wxT("Select Unique Key constraint to edit name"), wxT("Select Unique Constraint to edit name:"), getOwnerColumn()->getOwnerTable()->getUkConstraintsNames(), view);
310 			if(answer >= 0)
311 			{
312 				tmpString = wxGetTextFromUser(wxT("Change name of Unique Key constraint:"), getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Item(answer), getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Item(answer), view);
313 				if(tmpString.length() > 0)
314 				{
315 					getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Item(answer) = tmpString;
316 					view->notifyChanged();
317 				}
318 			}
319 			break;
320 		case MNU_DELTABLE:
321 
322 			delremDialog = new hdRemoveDeleteDialog(wxT("Are you sure you wish to delete table ") + getOwnerColumn()->getOwnerTable()->getTableName() + wxT("?"), wxT("Delete table?"), view);
323 			answer = delremDialog->ShowModal();
324 			ddTableFigure *table = getOwnerColumn()->getOwnerTable();
325 			if (answer == DD_DELETE)
326 			{
327 				ddDrawingEditor *editor = (ddDrawingEditor *) view->editor();
328 				//Unselect table at all diagrams
329 				editor->removeFromAllSelections(table);
330 				//Drop foreign keys with this table as origin or destination
331 				table->processDeleteAlert(view->getDrawing());
332 				//Drop table
333 				editor->deleteModelFigure(table);
334 				editor->getDesign()->refreshBrowser();
335 				view->notifyChanged();
336 			}
337 			else if(answer == DD_REMOVE)
338 			{
339 				ddDrawingEditor *editor = (ddDrawingEditor *) view->editor();
340 				editor->getExistingDiagram(view->getIdx())->removeFromSelection(table);
341 				editor->getExistingDiagram(view->getIdx())->remove(table);
342 				view->notifyChanged();
343 			}
344 			delete delremDialog;
345 			break;
346 	}
347 }
348 
createMenu(wxMenu & mnu)349 void ddTextTableItemFigure::createMenu(wxMenu &mnu)
350 {
351 	wxMenu *submenu;
352 	wxMenuItem *item;
353 
354 	mnu.Append(MNU_DDADDCOLUMN, _("Add a column..."));
355 	item = mnu.Append(MNU_DELCOLUMN, _("Delete the selected column..."));
356 	if(getOwnerColumn()->isGeneratedForeignKey())
357 		item->Enable(false);
358 	mnu.Append(MNU_RENAMECOLUMN, _("Rename the selected column..."));
359 	if(getOwnerColumn()->isGeneratedForeignKey() && !getOwnerColumn()->isFkNameGenerated())
360 		mnu.Append(MNU_AUTONAMCOLUMN, _("Activate fk auto-naming..."));
361 	mnu.AppendSeparator();
362 	item = mnu.AppendCheckItem(MNU_NOTNULL, _("Not NULL constraint"));
363 	if(getOwnerColumn()->isNotNull())
364 		item->Check(true);
365 	if(getOwnerColumn()->isGeneratedForeignKey())
366 		item->Enable(false);
367 	mnu.AppendSeparator();
368 	item = mnu.AppendCheckItem(MNU_PKEY, _("Primary Key"));
369 	if(getOwnerColumn()->isPrimaryKey())
370 		item->Check(true);
371 	if(getOwnerColumn()->isGeneratedForeignKey())
372 		item->Enable(false);
373 	item = mnu.AppendCheckItem(MNU_UKEY, _("Unique Key"));
374 	if(getOwnerColumn()->isUniqueKey())
375 		item->Check(true);
376 	mnu.AppendSeparator();
377 	submenu = new wxMenu();
378 	item = mnu.AppendSubMenu(submenu, _("Column datatype"));
379 	if(getOwnerColumn()->isGeneratedForeignKey())
380 		item->Enable(false);
381 	item = submenu->AppendCheckItem(MNU_TYPESERIAL, _("serial"));
382 	item->Check(columnType == dt_bigint);
383 	item = submenu->AppendCheckItem(MNU_TYPEBOOLEAN, _("boolean"));
384 	item->Check(columnType == dt_boolean);
385 	item = submenu->AppendCheckItem(MNU_TYPEINTEGER, _("integer"));
386 	item->Check(columnType == dt_integer);
387 	item = submenu->AppendCheckItem(MNU_TYPEMONEY, _("money"));
388 	item->Check(columnType == dt_money);
389 	item = submenu->AppendCheckItem(MNU_TYPEVARCHAR, _("varchar(n)"));
390 	item->Check(columnType == dt_varchar);
391 	item = submenu->Append(MNU_TYPEOTHER, _("Choose another datatype..."));
392 	mnu.AppendSeparator();
393 	mnu.Append(MNU_TYPEPKEY_CONSTRAINTNAME, _("Primary Key Constraint name..."));
394 	mnu.Append(MNU_TYPEUKEY_CONSTRAINTNAME, _("Unique Key Constraint name..."));
395 	mnu.AppendSeparator();
396 	mnu.Append(MNU_DELTABLE, _("Delete table..."));
397 };
398 
399 
dataTypes()400 const wxArrayString ddTextTableItemFigure::dataTypes()
401 {
402 	if(ddDatatypes.IsEmpty())
403 	{
404 		//Fast access ddDatatypes
405 		ddDatatypes.Add(wxT("ANY"));
406 		ddDatatypes.Add(wxT("serial"));
407 		ddDatatypes.Add(wxT("boolean"));
408 		ddDatatypes.Add(wxT("integer"));
409 		ddDatatypes.Add(wxT("money"));
410 		ddDatatypes.Add(wxT("varchar(n)"));
411 		//Normal access ddDatatypes
412 		ddDatatypes.Add(wxT("bigint"));
413 		ddDatatypes.Add(wxT("bit(n)"));
414 		ddDatatypes.Add(wxT("bytea"));
415 		ddDatatypes.Add(wxT("char(n)"));
416 		ddDatatypes.Add(wxT("cidr"));
417 		ddDatatypes.Add(wxT("circle"));
418 		ddDatatypes.Add(wxT("date"));
419 		ddDatatypes.Add(wxT("double precision"));
420 		ddDatatypes.Add(wxT("inet"));
421 		ddDatatypes.Add(wxT("interval(n)"));
422 		ddDatatypes.Add(wxT("line"));
423 		ddDatatypes.Add(wxT("lseg"));
424 		ddDatatypes.Add(wxT("macaddr"));
425 		ddDatatypes.Add(wxT("numeric(p,s)"));
426 		ddDatatypes.Add(wxT("path"));
427 		ddDatatypes.Add(wxT("point"));
428 		ddDatatypes.Add(wxT("polygon"));
429 		ddDatatypes.Add(wxT("real"));
430 		ddDatatypes.Add(wxT("smallint"));
431 		ddDatatypes.Add(wxT("text"));
432 		ddDatatypes.Add(wxT("time"));
433 		ddDatatypes.Add(wxT("timestamp"));
434 		ddDatatypes.Add(wxT("varbit(n)"));
435 	}
436 	return ddDatatypes;
437 }
438 
setText(wxString textString)439 void ddTextTableItemFigure::setText(wxString textString)
440 {
441 	hdSimpleTextFigure::setText(textString);
442 
443 	//Hack to allow column text to submit new size of text signal to tablefigure
444 	//and then recalculate displaybox. Helps with fk autorenaming too.
445 	if(ownerColumn)
446 	{
447 		ownerColumn->displayBoxUpdate();
448 		ownerColumn->getOwnerTable()->updateTableSize();
449 		ownerColumn->getOwnerTable()->updateFkObservers();
450 	}
451 }
452 
getAlias()453 wxString ddTextTableItemFigure::getAlias()
454 {
455 	return colAlias;
456 }
457 
458 //Activate use of alias or short names at ddtextTableItems like TableNames [Columns don' use it]
setAlias(wxString alias)459 void ddTextTableItemFigure::setAlias(wxString alias)
460 {
461 	if(alias.length() <= 0 || alias.length() > 3 )
462 	{
463 		showAlias = false;
464 		colAlias = wxEmptyString;
465 	}
466 	else
467 	{
468 		showAlias = true;
469 		colAlias = alias;
470 	}
471 	recalculateDisplayBox();
472 	ownerTable->updateFkObservers(); //Only triggered by a tableName item [Not a column]
473 	ownerTable->updateTableSize();
474 }
475 
setOneTimeNoAlias()476 void ddTextTableItemFigure::setOneTimeNoAlias()
477 {
478 	oneTimeNoAlias = true;
479 }
480 
getOwnerColumn()481 ddColumnFigure *ddTextTableItemFigure::getOwnerColumn()
482 {
483 	return ownerColumn;
484 }
485 
setOwnerColumn(ddColumnFigure * column)486 void ddTextTableItemFigure::setOwnerColumn(ddColumnFigure *column)
487 {
488 	ownerColumn = column;
489 }
490 
setShowDataType(bool value)491 void ddTextTableItemFigure::setShowDataType(bool value)
492 {
493 	showDataType = value;
494 }
495 
CreateFigureTool(hdDrawingView * view,hdITool * defaultTool)496 hdITool *ddTextTableItemFigure::CreateFigureTool(hdDrawingView *view, hdITool *defaultTool)
497 {
498 	if(getOwnerColumn())
499 	{
500 		return textEditable ? new ddColumnTextTool(view, this, defaultTool, false, wxT("New Column Name"), wxT("Rename Column")) : defaultTool;
501 	}
502 	else
503 	{
504 		setOneTimeNoAlias();
505 		return textEditable ? new ddColumnTextTool(view, this, defaultTool, false, wxT("New Table Name"), wxT("Rename Table")) : defaultTool;
506 	}
507 }
508 
getTextWidth()509 int ddTextTableItemFigure::getTextWidth()
510 {
511 	int w, h;
512 	getFontMetrics(w, h);
513 	return w;
514 }
515 
getTextHeight()516 int ddTextTableItemFigure::getTextHeight()
517 {
518 	int w, h;
519 	getFontMetrics(w, h);
520 	return h;
521 }
522 
getDataType()523 ddDataType ddTextTableItemFigure::getDataType()
524 {
525 	if(!getOwnerColumn()->isGeneratedForeignKey())
526 		return columnType;
527 	else
528 	{
529 		columnType = getOwnerColumn()->getFkSource()->original->getDataType();
530 		return columnType;
531 	}
532 }
533 
setDataType(ddDataType type)534 void ddTextTableItemFigure::setDataType(ddDataType type)
535 {
536 	columnType = type;
537 	ownerColumn->getOwnerTable()->updateSizeOfObservers();
538 }
539 
getPrecision()540 int ddTextTableItemFigure::getPrecision()
541 {
542 	if(getOwnerColumn()->isGeneratedForeignKey())
543 	{
544 		precision = getOwnerColumn()->getFkSource()->original->getPrecision();
545 		return precision;
546 	}
547 	else
548 	{
549 		return precision;
550 	}
551 }
552 
setPrecision(int value)553 void ddTextTableItemFigure::setPrecision(int value)
554 {
555 	if(!getOwnerColumn()->isGeneratedForeignKey())
556 	{
557 		precision = value;
558 		ownerColumn->getOwnerTable()->updateSizeOfObservers();
559 	}
560 }
561 
setScale(int value)562 void ddTextTableItemFigure::setScale(int value)
563 {
564 	if(!getOwnerColumn()->isGeneratedForeignKey())
565 	{
566 		scale = value;
567 		ownerColumn->getOwnerTable()->updateSizeOfObservers();
568 	}
569 }
570 
getScale()571 int ddTextTableItemFigure::getScale()
572 {
573 	if(getOwnerColumn()->isGeneratedForeignKey())
574 	{
575 		scale = getOwnerColumn()->getFkSource()->original->getScale();
576 		return scale;
577 	}
578 	else
579 	{
580 		return scale;
581 	}
582 }
583