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
////////////////////////////////////////////////////////////////////////////////
24
#include "rowcolumnlabel.h"
25
#include "linepiece.h"
26
#include "rectangle.h"
27
#include "inputfile.h"
28
#include "outputfile.h"
31
CellRow::CellRow(TableViewer *v, unsigned n, int h): CellVector(v,n) {
33
SetAlignment(v->GetDefaultRowAlignment());
37
void CellRow::CalcLabelPositions() {
38
// distance between row label and the cells.
39
const int LABEL_DIST = 4;
40
RowColumnLabel *l1 = GetLabel1();
41
RowColumnLabel *l2 = GetLabel2();
44
if (cells->count() == 0)
45
pt = GetViewer()->GetRowTopLeft(GetNumber());
47
pt = *(*cells)[0]->GetTopLeft();
49
pt.x -= (l1->GetWidth()/2 + LABEL_DIST);
50
if (GetViewer()->IsShowRowColumnLabels())
51
l1->UpdatePosition(&pt);
54
pt.x += GetViewer()->GetWidth() +
55
l1->GetWidth() + 2*LABEL_DIST;
56
if (GetViewer()->IsShowRowColumnLabels())
57
l2->UpdatePosition(&pt);
63
void CellRow::UpdateWidth(unsigned colnr) {
68
if (colnr == 0 && cells->count() > 0) { // shift first line.
71
p1 = *cell->GetTopLeft();
74
line->UpdatePoints(&p1, &p2);
77
for (unsigned i=colnr; i<cells->count(); i++) {
80
width = cell->GetWidth();
81
p1 = *cell->GetTopLeft();
83
p2 = *line->GetBegin();
87
line->UpdatePoints(&p2, &p3);
92
void CellRow::UpdatePosition(int delta) {
95
for (cells->first(); !cells->done(); cells->next()) {
96
Cell *cell = cells->cur();
97
Point pt = *cell->GetPosition();
99
cell->UpdatePosition(&pt);
101
for (lines->first(); !lines->done(); lines->next()) {
102
LinePiece *line = lines->cur();
103
Point pt1 = *line->GetBegin();
104
if (pt1.y + delta >= 0) {
106
Point pt2 = *line->GetEnd();
108
line->UpdatePoints(&pt1, &pt2);
111
CalcLabelPositions();
114
void CellRow::UpdateHeight(int h) {
117
for (lines->first(); !lines->done(); lines->next()) {
118
LinePiece *line = lines->cur();
119
Point pt = *line->GetEnd();
120
pt.y = pt.y - height + h;
121
line->UpdateEnd(&pt);
124
for (cells->first(); !cells->done(); cells->next()) {
125
Cell *cell = cells->cur();
126
int wd = cell->GetWidth();
127
Point pt = *cell->GetTopLeft();
128
pt.y = pt.y + height/2;
131
cell->SetSize(wd, height);
132
cell->SetPosition(&pt);
135
CalcLabelPositions();
138
Cell *CellRow::HitCell(int x, int y) {
141
Cell *cell = cells->cur();
142
Point pt = *(cell->GetTopLeft());
143
// look for this row.
144
if (y > pt.y && y < pt.y + height) {
145
// ok, look for right column.
148
int wd = cell->GetWidth();
149
pt = *(cell->GetTopLeft());
150
if (x > pt.x && x < pt.x + wd)
152
} while (cells->next());
154
return 0; // not in this row.
157
LinePiece *CellRow::HitLinePiece(int x, int y) {
160
LinePiece *line = lines->cur();
161
Point pt = *(line->GetBegin());
162
// look for this row.
163
if (y > pt.y && y < pt.y + height) {
166
pt = *line->GetBegin();
167
if (x > pt.x-3 && x < pt.x+3)
169
} while (lines->next());
171
return 0; // not in this row.
174
void CellRow::AddCell(Cell *c, bool redraw) {
175
LineStyle::Type lineStyle = GetViewer()->GetDefaultLineStyle();
176
int lineWidth = GetViewer()->GetDefaultLineWidth();
178
int w = c->GetWidth();
179
int h = c->GetHeight();
180
Point pos = *(c->GetTopLeft());
181
if (!cells->first()) {
182
// create first line.
187
LinePiece *l = new LinePiece(GetGrafport(), &from, &to,
188
lineStyle, lineWidth);
198
LinePiece *l2 = new LinePiece(GetGrafport(), &from, &to,
199
lineStyle, lineWidth);
205
void CellRow::DeleteCell(Cell *c, bool redraw) {
206
int pos = cells->find(c);
207
if (!check(pos != -1))
210
// delete first cell.
211
LinePiece *line = (*lines)[0];
216
if (cells->count() == 1) { // delete last cell
227
LinePiece *line = (*lines)[pos+1];
230
lines->removei(pos+1);
234
// move right cells of row left.
238
void CellRow::InsertCell(Cell *c, unsigned pos, bool redraw) {
239
if (!check(pos <= cells->count()))
241
if (pos == cells->count())
244
cells->insert(c, pos);
245
// create new line piece right to the cell.
246
LineStyle::Type lineStyle = GetViewer()->GetDefaultLineStyle();
247
unsigned lineWidth = GetViewer()->GetDefaultLineWidth();
248
Point pt1 = *c->GetTopLeft();
249
pt1.x += c->GetWidth();
251
pt2.y += c->GetHeight();
252
LinePiece *line = new LinePiece(GetGrafport(), &pt1, &pt2,
253
lineStyle, lineWidth);
254
lines->insert(line, pos+1);
257
// move line pieces of row down.
261
int CellRow::GetMinimalHeight() {
263
for (cells->first(); !cells->done(); cells->next()) {
264
int th = cells->cur()->GetTextHeight() +
265
2*GetViewer()->GetMarginHeight();
272
bool CellRow::ContainsPt(int x, int y) const {
275
if (cells->count() ==0)
277
Point pt = *(*cells)[0]->GetTopLeft();
278
pt.x = max(0, pt.x - SimpleLabel::MIN_TEXT_WIDTH);
279
int width = GetViewer()->GetWidth();
280
Rectangle rect(pt.x, pt.y, width, height);
281
return rect.Inside(x,y);
284
void CellRow::UpdateTextPositions() {
285
List<Cell *> cells2 = *cells;
286
for (cells2.first(); !cells2.done(); cells2.next()) {
287
Cell *cell = cells2.cur();
288
cell->UpdateTextPosition();
289
if (GetViewer()->IsAutoResize())
290
GetViewer()->RecomputeSizeCell(cell);
294
void CellRow::SetTextSizes() {
295
List<Cell *> cells2 = *cells;
296
for (cells2.first(); !cells2.done(); cells2.next()) {
297
Cell *cell = cells2.cur();
299
if (GetViewer()->IsAutoResize())
300
GetViewer()->RecomputeSizeCell(cell);
304
void CellRow::Write(OutputFile *ofile) {
305
(*ofile) << "Row " << GetNumber() << " {\n";
306
(*ofile) << "\t{ Height " << height << " }\n";
308
TextAlign::Type2String(GetAlignment(), &t);
309
(*ofile) << "\t{ Alignment " << t << " }\n";
310
(*ofile) << "\t{ NumberOfCells " << cells->count() << " }\n";
311
if (cells->first() && lines->first()) {
314
(*ofile) << "\t# cell " << GetNumber() << "," << i << '\n';
315
lines->cur()->Write(ofile);
316
cells->cur()->Write(ofile);
319
while (cells->next() && lines->next());
321
lines->cur()->Write(ofile);
326
void CellRow::WritePartial(OutputFile *ofile, int n, List<int> *columnNumbers) {
327
(*ofile) << "Row " << n << " {\n";
328
(*ofile) << "\t{ Height " << height << " }\n";
330
TextAlign::Type2String(GetAlignment(), &t);
331
(*ofile) << "\t{ Alignment " << t << " }\n";
332
(*ofile) << "\t{ NumberOfCells " << columnNumbers->count() << " }\n";
333
for (columnNumbers->first(); !columnNumbers->done();
334
columnNumbers->next()) {
335
int i = columnNumbers->cur();
336
(*lines)[i]->Write(ofile);
337
(*cells)[i]->Write(ofile);
339
if (columnNumbers->last())
340
(*lines)[columnNumbers->cur()+1]->Write(ofile);
344
bool CellRow::Read(InputFile *ifile, unsigned fromColumn, double format) {
346
if (!ifile->LookupWord("Row"))
350
if (!ifile->ReadWord(&val))
353
if (!ifile->LookupChar('{'))
355
// read and update row height (depending on whether the whole
356
// row is read in or just a part).
357
if (!ifile->ReadAttribute("Height", &val))
359
if (val.toint() != height) {
360
int ht = val.toint();
361
if (fromColumn == 0 || ht > height)
362
GetViewer()->ResizeRow(this, ht);
364
// read and update row alignment (if the whole row is read in).
365
if (!ifile->ReadAttribute("Alignment", &val))
367
if (fromColumn == 0) {
369
SetAlignment((TextAlign::Type) val.toint());
371
SetAlignment(TextAlign::String2Type(&val));
373
// read number of cells.
374
if (!ifile->ReadAttribute("NumberOfCells", &val))
376
// read and update cell texts and line types.
378
for (unsigned i=fromColumn;i<fromColumn+n; i++) {
379
(*lines)[i]->Read(ifile, format);
380
(*cells)[i]->Read(ifile, format);
383
(*lines)[fromColumn+n]->Read(ifile, format);
385
if (!ifile->LookupChar('}'))