1
////////////////////////////////////////////////////////////////////////////////
3
// This file is part of Toolkit for Conceptual Modeling (TCM).
4
// (c) copyright 1996, Vrije Universiteit Amsterdam.
5
// Author: Frank Dehne (frank@cs.vu.nl).
7
// TCM is free software; you can redistribute it and/or modify
8
// it under the terms of the GNU General Public License as published by
9
// the Free Software Foundation; either version 2 of the License, or
10
// (at your option) any later version.
12
// TCM is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
// GNU General Public License for more details.
17
// You should have received a copy of the GNU General Public License
18
// along with TCM; if not, write to the Free Software
19
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21
////////////////////////////////////////////////////////////////////////////////
22
#include "cellcolumn.h"
23
#include "rowcolumnlabel.h"
25
#include "linepiece.h"
26
#include "rectangle.h"
27
#include "inputfile.h"
28
#include "outputfile.h"
31
CellColumn::CellColumn(TableViewer *v, unsigned n, int w): CellVector(v,n) {
33
SetAlignment(v->GetDefaultColumnAlignment());
37
void CellColumn::CalcLabelPositions() {
39
RowColumnLabel *l1 = GetLabel1();
40
RowColumnLabel *l2 = GetLabel2();
42
if (cells->count() == 0)
43
pt = GetViewer()->GetColumnTopLeft(GetNumber());
45
pt = *(*cells)[0]->GetTopLeft();
47
pt.y -= (l1->GetHeight()/2);
48
if (GetViewer()->IsShowRowColumnLabels())
49
l1->UpdatePosition(&pt);
52
pt.y += GetViewer()->GetHeight() + l1->GetHeight();
53
if (GetViewer()->IsShowRowColumnLabels())
54
l2->UpdatePosition(&pt);
60
void CellColumn::UpdateWidth(int w) {
63
for (lines->first(); !lines->done(); lines->next()) {
64
LinePiece *line = lines->cur();
65
Point pt = *line->GetEnd();
66
pt.x = pt.x - width + w;
70
for (cells->first(); !cells->done(); cells->next()) {
71
Cell *cell = cells->cur();
72
int height = cell->GetHeight();
73
Point pt = *cell->GetTopLeft();
74
pt.x = pt.x + width/2;
75
pt.y = pt.y + height/2;
77
cell->SetSize(width, height);
78
cell->SetPosition(&pt);
84
void CellColumn::UpdatePosition(int delta) {
87
for (cells->first(); !cells->done(); cells->next()) {
88
Cell *cell = cells->cur();
89
Point pt = *cell->GetPosition();
91
cell->UpdatePosition(&pt);
93
for (lines->first(); !lines->done(); lines->next()) {
94
LinePiece *line = lines->cur();
95
Point pt1 = *line->GetBegin();
96
if (pt1.x + delta >= 0) {
98
Point pt2 = *line->GetEnd();
100
line->UpdatePoints(&pt1, &pt2);
103
CalcLabelPositions();
106
void CellColumn::UpdateHeight(unsigned rownr) {
111
if (rownr == 0 && cells->count() > 0) { // shift first line.
114
p1 = *cell->GetTopLeft();
117
line->UpdatePoints(&p1, &p2);
118
CalcLabelPositions();
120
for (unsigned i=rownr; i<cells->count(); i++) {
122
line = (*lines)[i+1];
123
height = cell->GetHeight();
124
p1 = *cell->GetTopLeft();
126
p2 = *line->GetBegin();
127
p2.y = p1.y + height;
128
p3 = *line->GetEnd();
129
p3.y = p1.y + height;
131
line->UpdatePoints(&p2, &p3);
136
void CellColumn::AddCell(Cell *c, bool redraw) {
137
LineStyle::Type lineStyle = GetViewer()->GetDefaultLineStyle();
138
unsigned lineWidth = GetViewer()->GetDefaultLineWidth();
140
int w = c->GetWidth();
141
int h = c->GetHeight();
142
Point pos = *(c->GetTopLeft());
143
if (!cells->first()) {
144
// create first line.
149
LinePiece *l = new LinePiece(GetGrafport(), &from, &to,
150
lineStyle, lineWidth);
160
LinePiece *l = new LinePiece(GetGrafport(), &from, &to,
161
lineStyle, lineWidth);
167
void CellColumn::DeleteCell(Cell *c, bool redraw) {
168
int pos = cells->find(c);
169
if (!check(pos != -1))
172
// delete first cell.
173
LinePiece *line = (*lines)[0];
178
if (cells->count() == 1) { // delete very last cell
189
LinePiece *line = (*lines)[pos+1];
192
lines->removei(pos+1);
196
// move lower cells of column up.
200
void CellColumn::InsertCell(Cell *c, unsigned pos, bool redraw) {
201
if (!check(pos <= cells->count()))
203
if (pos == cells->count())
206
cells->insert(c, pos);
207
// create new line piece below cell.
208
LineStyle::Type lineStyle = GetViewer()->GetDefaultLineStyle();
209
unsigned lineWidth = GetViewer()->GetDefaultLineWidth();
210
Point pt1 = *c->GetTopLeft();
211
pt1.y += c->GetHeight();
213
pt2.x += c->GetWidth();
214
LinePiece *line = new LinePiece(GetGrafport(), &pt1, &pt2,
215
lineStyle, lineWidth);
216
lines->insert(line, pos+1);
219
// move lower line pieces of column lright.
223
LinePiece *CellColumn::HitLinePiece(int x, int y) {
226
LinePiece *line = lines->cur();
227
Point pt = *(line->GetBegin());
228
// look for this column.
229
if (x > pt.x && x < pt.x + width) {
232
pt = *line->GetBegin();
233
if (y > pt.y-3 && y < pt.y+3)
235
} while (lines->next());
237
return 0; // not in this column.
240
int CellColumn::GetMinimalWidth() {
242
for (cells->first(); !cells->done(); cells->next()) {
243
int tw = cells->cur()->GetTextWidth() +
244
2*GetViewer()->GetMarginWidth();
251
void CellColumn::UpdateTextPositions() {
252
List<Cell *> cells2 = *cells;
253
for (cells2.first(); !cells2.done(); cells2.next()) {
254
Cell *cell = cells2.cur();
255
cell->UpdateTextPosition();
256
if (GetViewer()->IsAutoResize())
257
GetViewer()->RecomputeSizeCell(cell);
261
bool CellColumn::ContainsPt(int x, int y) const {
262
if (cells->count()==0)
264
Point pt = *(*cells)[0]->GetTopLeft();
265
pt.y = max(0, pt.y - SimpleLabel::MIN_TEXT_HEIGHT);
266
int height = GetViewer()->GetHeight();
267
Rectangle rect(pt.x, pt.y, width, height);
268
return rect.Inside(x,y);
271
void CellColumn::Write(OutputFile *ofile) {
272
(*ofile) << "Column " << GetNumber() << " {\n";
273
(*ofile) << "\t{ Width " << width << " }\n";
275
TextAlign::Type2String(GetAlignment(), &t);
276
(*ofile) << "\t{ Alignment " << t << " }\n";
277
(*ofile) << "\t{ NumberOfCells " << cells->count() << " }\n";
279
for (lines->first(); !lines->done(); lines->next()) {
280
(*ofile) << "\t# cell " << i << "," << GetNumber() << '\n';
281
lines->cur()->Write(ofile);
287
void CellColumn::WritePartial(OutputFile *ofile, int n, List<int> *rowNumbers) {
288
(*ofile) << "Column " << n << " {\n";
289
(*ofile) << "\t{ Width " << width << " }\n";
291
TextAlign::Type2String(GetAlignment(), &t);
292
(*ofile) << "\t{ Alignment " << t << " }\n";
293
(*ofile) << "\t{ NumberOfCells " << rowNumbers->count() << " }\n";
294
for (rowNumbers->first(); !rowNumbers->done(); rowNumbers->next())
295
(*lines)[rowNumbers->cur()]->Write(ofile);
296
if (rowNumbers->last())
297
(*lines)[rowNumbers->cur()]->Write(ofile);
301
bool CellColumn::Read(InputFile *ifile, unsigned fromRow, double format) {
303
if (!ifile->LookupWord("Column"))
305
// read column number.
307
if (!ifile->ReadWord(&val))
310
if (!ifile->LookupChar('{'))
312
// read and update column width (depending on whether the whole column
313
// is read in or just a part).
314
if (!ifile->ReadAttribute("Width", &val))
316
if (val.toint() != width) {
317
int wd = val.toint();
318
if (fromRow == 0 || wd > width)
319
GetViewer()->ResizeColumn(this, wd);
321
// read and update column alignment, if whole column is read in.
322
if (!ifile->ReadAttribute("Alignment", &val))
326
SetAlignment((TextAlign::Type) val.toint());
328
SetAlignment(TextAlign::String2Type(&val));
330
// read number of cells.
331
if (!ifile->ReadAttribute("NumberOfCells", &val))
333
// read and update line types.
335
for (unsigned i=fromRow; i<fromRow+n; i++)
336
(*lines)[i]->Read(ifile, format);
338
(*lines)[fromRow+n]->Read(ifile, format);
340
if (!ifile->LookupChar('}'))