~ubuntu-branches/ubuntu/utopic/tcm/utopic

« back to all changes in this revision

Viewing changes to src/tb/cellcolumn.c

  • Committer: Bazaar Package Importer
  • Author(s): Otavio Salvador
  • Date: 2003-07-03 20:08:21 UTC
  • Revision ID: james.westby@ubuntu.com-20030703200821-se4xtqx25e5miczi
Tags: upstream-2.20
ImportĀ upstreamĀ versionĀ 2.20

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
////////////////////////////////////////////////////////////////////////////////
 
2
//
 
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).
 
6
//
 
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.
 
11
//
 
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.
 
16
//
 
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
 
20
// 02111-1307, USA.
 
21
////////////////////////////////////////////////////////////////////////////////
 
22
#include "cellcolumn.h"
 
23
#include "rowcolumnlabel.h"
 
24
#include "cell.h"
 
25
#include "linepiece.h"
 
26
#include "rectangle.h"
 
27
#include "inputfile.h"
 
28
#include "outputfile.h"
 
29
#include <stdlib.h>
 
30
 
 
31
CellColumn::CellColumn(TableViewer *v, unsigned n, int w): CellVector(v,n) {
 
32
        width = w;
 
33
        SetAlignment(v->GetDefaultColumnAlignment());
 
34
        CalcLabelPositions();
 
35
}
 
36
 
 
37
void CellColumn::CalcLabelPositions() {
 
38
        Point pt;
 
39
        RowColumnLabel *l1 = GetLabel1();
 
40
        RowColumnLabel *l2 = GetLabel2();
 
41
        if (l1 && l2) {
 
42
                if (cells->count() == 0)
 
43
                        pt = GetViewer()->GetColumnTopLeft(GetNumber());
 
44
                else
 
45
                        pt = *(*cells)[0]->GetTopLeft();
 
46
                pt.x += width/2;
 
47
                pt.y -= (l1->GetHeight()/2);
 
48
                if (GetViewer()->IsShowRowColumnLabels())
 
49
                        l1->UpdatePosition(&pt);
 
50
                else
 
51
                        l1->SetPosition(&pt);
 
52
                pt.y += GetViewer()->GetHeight() + l1->GetHeight();
 
53
                if (GetViewer()->IsShowRowColumnLabels())
 
54
                        l2->UpdatePosition(&pt);
 
55
                else
 
56
                        l2->SetPosition(&pt);
 
57
        }
 
58
}
 
59
 
 
60
void CellColumn::UpdateWidth(int w) {
 
61
        if (w == width)
 
62
                return;
 
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;
 
67
                line->UpdateEnd(&pt);
 
68
        } 
 
69
        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;
 
76
                cell->Undraw();
 
77
                cell->SetSize(width, height);
 
78
                cell->SetPosition(&pt);
 
79
                cell->Draw();
 
80
        }
 
81
        CalcLabelPositions();
 
82
}
 
83
 
 
84
void CellColumn::UpdatePosition(int delta) {
 
85
        if (delta == 0)
 
86
                return;
 
87
        for (cells->first(); !cells->done(); cells->next()) {
 
88
                Cell *cell = cells->cur();
 
89
                Point pt = *cell->GetPosition();
 
90
                pt.x += delta;
 
91
                cell->UpdatePosition(&pt);
 
92
        } 
 
93
        for (lines->first(); !lines->done(); lines->next()) {
 
94
                LinePiece *line = lines->cur();
 
95
                Point pt1 = *line->GetBegin();
 
96
                if (pt1.x + delta >= 0) {
 
97
                        pt1.x += delta;
 
98
                        Point pt2 = *line->GetEnd();
 
99
                        pt2.x += delta;
 
100
                        line->UpdatePoints(&pt1, &pt2);
 
101
                }
 
102
        }
 
103
        CalcLabelPositions();
 
104
}
 
105
 
 
106
void CellColumn::UpdateHeight(unsigned rownr) {
 
107
        Point p1, p2, p3;
 
108
        Cell *cell;
 
109
        LinePiece *line;
 
110
        int height;
 
111
        if (rownr == 0 && cells->count() > 0) { // shift first line.
 
112
                cell = (*cells)[0];
 
113
                line = (*lines)[0];
 
114
                p1 = *cell->GetTopLeft();
 
115
                p2.y = p1.y;
 
116
                p2.x = p1.x + width;
 
117
                line->UpdatePoints(&p1, &p2);
 
118
                CalcLabelPositions();
 
119
        }
 
120
        for (unsigned i=rownr; i<cells->count(); i++) {
 
121
                cell = (*cells)[i];
 
122
                line = (*lines)[i+1];
 
123
                height = cell->GetHeight();
 
124
                p1 = *cell->GetTopLeft();
 
125
                if (line) {
 
126
                        p2 = *line->GetBegin();
 
127
                        p2.y = p1.y + height;
 
128
                        p3 = *line->GetEnd();
 
129
                        p3.y = p1.y + height;
 
130
                        p3.x = p1.x + width;
 
131
                        line->UpdatePoints(&p2, &p3);
 
132
                }
 
133
        }
 
134
}
 
135
 
 
136
void CellColumn::AddCell(Cell *c, bool redraw) {
 
137
        LineStyle::Type lineStyle = GetViewer()->GetDefaultLineStyle();
 
138
        unsigned lineWidth = GetViewer()->GetDefaultLineWidth();
 
139
        Point from, to;
 
140
        int w = c->GetWidth();
 
141
        int h = c->GetHeight();
 
142
        Point pos = *(c->GetTopLeft());
 
143
        if (!cells->first()) {
 
144
                // create first line.
 
145
                from.x = pos.x;
 
146
                from.y = pos.y;
 
147
                to.x = pos.x + w;
 
148
                to.y = pos.y;
 
149
                LinePiece *l = new LinePiece(GetGrafport(), &from, &to, 
 
150
                        lineStyle, lineWidth);
 
151
                if (redraw)
 
152
                        l->Draw();
 
153
                lines->add(l);
 
154
        }
 
155
        cells->add(c);
 
156
        from.x = pos.x;
 
157
        from.y = pos.y + h;
 
158
        to.x = pos.x + w;
 
159
        to.y = pos.y + h;
 
160
        LinePiece *l = new LinePiece(GetGrafport(), &from, &to,
 
161
                        lineStyle, lineWidth);
 
162
        if (redraw)
 
163
                l->Draw();
 
164
        lines->add(l);
 
165
}
 
166
 
 
167
void CellColumn::DeleteCell(Cell *c, bool redraw) {
 
168
        int pos = cells->find(c);
 
169
        if (!check(pos != -1))
 
170
                return;
 
171
        if (pos == 0) {
 
172
                // delete first cell.
 
173
                LinePiece *line = (*lines)[0];
 
174
                if (redraw)
 
175
                        line->Undraw();
 
176
                lines->removei(0);
 
177
                delete line;
 
178
                if (cells->count() == 1) { // delete very last cell
 
179
                        line = (*lines)[0];
 
180
                        if (redraw)
 
181
                                line->Undraw();
 
182
                        lines->removei(0);
 
183
                        if (redraw)
 
184
                                UndrawLabels();
 
185
                        delete line;
 
186
                }
 
187
        }
 
188
        else {
 
189
                LinePiece *line = (*lines)[pos+1];
 
190
                if (redraw)
 
191
                        line->Undraw();
 
192
                lines->removei(pos+1);
 
193
                delete line;
 
194
        }
 
195
        cells->removei(pos);
 
196
        // move lower cells of column up.
 
197
        UpdateHeight(pos); 
 
198
}
 
199
 
 
200
void CellColumn::InsertCell(Cell *c, unsigned pos, bool redraw) {
 
201
        if (!check(pos <= cells->count()))
 
202
                return;
 
203
        if (pos == cells->count())
 
204
                AddCell(c);
 
205
        // insert cell.
 
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();
 
212
        Point pt2 = pt1;
 
213
        pt2.x += c->GetWidth();
 
214
        LinePiece *line = new LinePiece(GetGrafport(), &pt1, &pt2, 
 
215
                lineStyle, lineWidth);
 
216
        lines->insert(line, pos+1);
 
217
        if (redraw)
 
218
                line->Draw();
 
219
        // move lower line pieces of column lright.
 
220
        UpdateHeight(pos); 
 
221
}
 
222
 
 
223
LinePiece *CellColumn::HitLinePiece(int x, int y) {
 
224
        if (!lines->first())
 
225
                return 0;
 
226
        LinePiece *line = lines->cur();
 
227
        Point pt = *(line->GetBegin());
 
228
        // look for this column.
 
229
        if (x > pt.x && x < pt.x + width) {
 
230
                do {
 
231
                        line = lines->cur();
 
232
                        pt = *line->GetBegin();
 
233
                        if (y > pt.y-3 && y < pt.y+3)
 
234
                                return line;
 
235
                } while (lines->next());
 
236
        }
 
237
        return 0; // not in this column.
 
238
}
 
239
 
 
240
int CellColumn::GetMinimalWidth() {
 
241
        int vw = 0;
 
242
        for (cells->first(); !cells->done(); cells->next()) {
 
243
                int tw = cells->cur()->GetTextWidth() + 
 
244
                         2*GetViewer()->GetMarginWidth(); 
 
245
                if (vw < tw) 
 
246
                        vw = tw;
 
247
        } 
 
248
        return vw;
 
249
}
 
250
 
 
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);
 
258
        } 
 
259
}
 
260
 
 
261
bool CellColumn::ContainsPt(int x, int y) const {
 
262
        if (cells->count()==0)
 
263
                return False;
 
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);
 
269
}
 
270
 
 
271
void CellColumn::Write(OutputFile *ofile) {
 
272
        (*ofile) << "Column " << GetNumber() << " {\n";
 
273
        (*ofile) << "\t{ Width " << width << " }\n";
 
274
        string t;
 
275
        TextAlign::Type2String(GetAlignment(), &t);
 
276
        (*ofile) << "\t{ Alignment " << t << " }\n";
 
277
        (*ofile) << "\t{ NumberOfCells " << cells->count() << " }\n";
 
278
        int i=0;
 
279
        for (lines->first(); !lines->done(); lines->next()) {
 
280
                (*ofile) << "\t# cell " << i << "," << GetNumber() << '\n';
 
281
                lines->cur()->Write(ofile);
 
282
                i++;
 
283
        }
 
284
        (*ofile) << "}\n\n";
 
285
}
 
286
 
 
287
void CellColumn::WritePartial(OutputFile *ofile, int n, List<int> *rowNumbers) {
 
288
        (*ofile) << "Column " << n << " {\n";
 
289
        (*ofile) << "\t{ Width " << width << " }\n";
 
290
        string t;
 
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);
 
298
        (*ofile) << "}\n\n";
 
299
}
 
300
 
 
301
bool CellColumn::Read(InputFile *ifile, unsigned fromRow, double format) {
 
302
        // read Column
 
303
        if (!ifile->LookupWord("Column"))
 
304
                return False;
 
305
        // read column number.
 
306
        string val;
 
307
        if (!ifile->ReadWord(&val))
 
308
                return False;
 
309
        // read {
 
310
        if (!ifile->LookupChar('{'))
 
311
                return False;
 
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))
 
315
                return False;
 
316
        if (val.toint() != width) {
 
317
                int wd = val.toint();
 
318
                if (fromRow == 0 || wd > width) 
 
319
                        GetViewer()->ResizeColumn(this, wd);
 
320
        }
 
321
        // read and update column alignment, if whole column is read in.
 
322
        if (!ifile->ReadAttribute("Alignment", &val))
 
323
                return False;
 
324
        if (fromRow == 0) {
 
325
                if (format <= 1.08)
 
326
                        SetAlignment((TextAlign::Type) val.toint());
 
327
                else
 
328
                        SetAlignment(TextAlign::String2Type(&val));
 
329
        }
 
330
        // read number of cells.
 
331
        if (!ifile->ReadAttribute("NumberOfCells", &val))
 
332
                return False;
 
333
        // read and update line types.
 
334
        int n = val.toint();
 
335
        for (unsigned i=fromRow; i<fromRow+n; i++)
 
336
                (*lines)[i]->Read(ifile, format);
 
337
        if (n > 0)
 
338
                (*lines)[fromRow+n]->Read(ifile, format);
 
339
        // read }
 
340
        if (!ifile->LookupChar('}'))
 
341
                return False;
 
342
        return True;
 
343
}