~ubuntu-branches/ubuntu/intrepid/tcm/intrepid

« back to all changes in this revision

Viewing changes to src/ed/document.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 1995, 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 "document.h"
 
23
#include "texteditdialog.h"
 
24
#include "fileselectiondialog.h"
 
25
#include "finddialog.h"
 
26
#include "replacedialog.h"
 
27
#include "questiondialog.h"
 
28
#include "inputfile.h"
 
29
#include "outputfile.h"
 
30
#include "menu.h"
 
31
#include "system.h"
 
32
#include "version.h"
 
33
#include "config.h"
 
34
#include "viewer.h"
 
35
#include "editstubs.h"
 
36
#include <stdlib.h>
 
37
#include <ctype.h>
 
38
#include <stdio.h>
 
39
 
 
40
Document::Document(Config *c, EditWindow *e, Viewer *v) {
 
41
        mainwindow = e;
 
42
        config = c;
 
43
        viewer = v;
 
44
        mwwidget = mainwindow->GetWidget();
 
45
        ifile = new InputFile();
 
46
        ofile = new OutputFile();
 
47
        (void)System::GetCwd(&dir);
 
48
        changes = 0;
 
49
        loaded = False;
 
50
        appending = False;
 
51
        saveSelection = False;
 
52
        annotation = "";
 
53
        chkbuf = "";
 
54
        tool = (Toolkit::ToolType)e->GetTool();
 
55
        suffix = Toolkit::DOCUMENT_SUFFIXES[tool];
 
56
        (void)System::GetLoginName(&login);
 
57
        toolName = Toolkit::TOOL_NAMES[tool]; 
 
58
        toolName += "-version-";
 
59
        toolName += Version::TOOLKIT_VERSION;
 
60
        fileFormat = Version::FILE_FORMAT;
 
61
        name = Toolkit::DOCUMENT_DEFAULT + suffix;
 
62
        docType = Toolkit::DOCUMENT_TYPES[tool];
 
63
        author = login;
 
64
        (void)System::GetTime(&createdOn);
 
65
        fileName = "";
 
66
        loadFormat = 0;
 
67
        generatedFrom = ""; 
 
68
        writtenOn = ""; 
 
69
        writtenBy = ""; 
 
70
        saveName = "";
 
71
        SetHierarchic(False);
 
72
        CreateDialogs();
 
73
}
 
74
 
 
75
void Document::CreateDialogs() {
 
76
        sourceEditDialog = new TextEditDialog(mwwidget);
 
77
        sourceEditDialog->Initialize();
 
78
        sourceEditDialog->SetTitle("Document Source Editor");
 
79
        sourceEditDialog->SetCancelCallback(0, 0);
 
80
        sourceEditDialog->SetOKButtonLabel("Save");
 
81
        sourceEditDialog->SetOKCallback(EditStubs::DocumentSourceOKCB, this);
 
82
        sourceEditDialog->SetTextSize(12, 60);
 
83
        docAnnotationDialog = new TextEditDialog(mwwidget);
 
84
        docAnnotationDialog->Initialize();
 
85
        docAnnotationDialog->SetTitle("Document Annotation Editor");
 
86
        docAnnotationDialog->SetCancelCallback(0, 0);
 
87
        docAnnotationDialog->SetOKCallback(EditStubs::AnnotationOKCB, this);
 
88
        docAnnotationDialog->SetTextSize(12, 60);
 
89
        eltAnnotationDialog = new TextEditDialog(GetMainWindow()->GetWidget());
 
90
        eltAnnotationDialog->Initialize();
 
91
        eltAnnotationDialog->SetTitle("Annotation Editor");
 
92
        eltAnnotationDialog->SetCancelCallback(0, 0);
 
93
        eltAnnotationDialog->SetTextSize(12, 60);
 
94
        fileSelectionDialog = new FileSelectionDialog(mwwidget);
 
95
        fileSelectionDialog->Initialize();
 
96
        fileSelectionDialog->SetTitle("Document File Selector");
 
97
        fileSelectionDialog->SetCancelCallback(EditStubs::CancelFSCB, this);
 
98
        infoDialog = new TextViewDialog(mwwidget);
 
99
        infoDialog->Initialize();
 
100
        infoDialog->SetTextSize(23, 60);
 
101
        infoDialog->SetTitle("Document Info");
 
102
        checkDialog = new TextViewDialog(mwwidget);
 
103
        checkDialog->Initialize();
 
104
        checkDialog->SetTextSize(12, 72);
 
105
        checkDialog->SetTitle("Check Document");
 
106
        findDialog = new FindDialog(mwwidget);
 
107
        findDialog->Initialize();
 
108
        findDialog->SetOKCallback(EditStubs::FindNextCB, this);
 
109
        findDialog->SetApplyCallback(EditStubs::FindAllCB, this);
 
110
        findDialog->ManageSubstringToggle(True);
 
111
        findDialog->SetTitle("Find text");
 
112
        replaceDialog = new ReplaceDialog(mwwidget);
 
113
        replaceDialog->Initialize();
 
114
        replaceDialog->SetTitle("Replace text");
 
115
        replaceDialog->SetOKCallback(EditStubs::ReplaceFindCB, this);
 
116
        replaceDialog->SetReplaceCallback(EditStubs::ReplaceNextCB, this);
 
117
        replaceDialog->SetApplyCallback(EditStubs::ReplaceAllCB, this);
 
118
        replaceDialog->ManageSubstringToggle(True);
 
119
}
 
120
 
 
121
Document::~Document() {
 
122
        delete viewer;
 
123
        delete ifile;
 
124
        delete ofile;
 
125
        delete sourceEditDialog;
 
126
        delete docAnnotationDialog;
 
127
        delete eltAnnotationDialog;
 
128
        delete fileSelectionDialog;
 
129
}
 
130
 
 
131
void Document::UpdateWindow() {
 
132
        UpdateDirectory(&dir);
 
133
        mainwindow->SetModified(changes != 0);
 
134
        mainwindow->SetDocumentName(&name);
 
135
        mainwindow->SetDocumentType(&docType);
 
136
}
 
137
 
 
138
void Document::UpdateDirectory(const string *s) {
 
139
        mainwindow->SetDirName(s);
 
140
        sourceEditDialog->SetDirectory(s);
 
141
        docAnnotationDialog->SetDirectory(s);
 
142
        eltAnnotationDialog->SetDirectory(s);
 
143
        fileSelectionDialog->SetDirectory(s);
 
144
}
 
145
 
 
146
void Document::New() {
 
147
        SetStatus("action: new");
 
148
        if (changes != 0) {
 
149
                if (AskSave() == False)
 
150
                        return;
 
151
        }
 
152
        string path = dir + Toolkit::DOCUMENT_DEFAULT + suffix;
 
153
        // delete document contents.
 
154
        RemoveAll();    
 
155
        NewFile(&path);
 
156
        Initialize();
 
157
        viewer->Refresh();
 
158
}
 
159
 
 
160
 
 
161
/* virtual */ void Document::Initialize() {
 
162
        SetHierarchic(False);
 
163
}
 
164
 
 
165
 
 
166
void Document::NewFile(const string *f) {
 
167
        string path = *f;
 
168
        if (!path.endsWith(suffix)) {
 
169
                string txt = "File name should have suffix '" + suffix + "'";
 
170
                if (mainwindow->IsDoMap()) {
 
171
                        (new MessageDialog(mwwidget, MessageDialog::WARNING))->
 
172
                                Show("Warning", &txt);
 
173
                        SetStatus("");
 
174
                }
 
175
                else 
 
176
                        std::cerr << txt << std::endl;
 
177
 
 
178
                // delete original suffix.
 
179
                path.setSuffix(suffix);
 
180
        }
 
181
        System::GiveFile(&path, &dir, &name); // get name from path.
 
182
        author = login;
 
183
        (void)System::GetTime(&createdOn);
 
184
        loaded = False;
 
185
        fileName = "";
 
186
        loadFormat = 0;
 
187
        generatedFrom = ""; 
 
188
        writtenOn = ""; 
 
189
        writtenBy = ""; 
 
190
        mainwindow->SetModified(False);
 
191
        mainwindow->SetDocumentName(&name);
 
192
        mainwindow->EnableDocumentSource(False);
 
193
        string txt = name + " [New Document]";
 
194
        SetStatus(&txt);
 
195
        annotation = "";
 
196
        changes = 0;
 
197
}
 
198
 
 
199
void Document::Load() {
 
200
        SetStatus("action: load");
 
201
        appending = False;
 
202
        string ext = "*" + suffix;
 
203
        fileSelectionDialog->SetTitle("Load document");
 
204
        fileSelectionDialog->ManageOptionMenu(False);
 
205
        fileSelectionDialog->SetExtension(&ext);
 
206
        fileSelectionDialog->SetOKCallback(EditStubs::LoadOKCB, this);
 
207
        fileSelectionDialog->SetDefaultFile("");
 
208
        fileSelectionDialog->Popup();
 
209
}
 
210
 
 
211
void Document::Append() {
 
212
        SetStatus("action: append");
 
213
        appending = True;
 
214
        string ext = "*" + suffix;
 
215
        fileSelectionDialog->SetTitle("Append document");
 
216
        fileSelectionDialog->SetExtension(&ext);
 
217
        fileSelectionDialog->SetOKCallback(EditStubs::LoadOKCB, this);
 
218
        fileSelectionDialog->SetDefaultFile("");
 
219
        fileSelectionDialog->Popup();
 
220
}
 
221
 
 
222
void Document::SetFSDir() {
 
223
        fileSelectionDialog->GetDirectory(&dir);
 
224
        UpdateDirectory(&dir);
 
225
}
 
226
 
 
227
void Document::LoadSave(const string *file) {
 
228
        if (changes != 0) {
 
229
                string tmp;    // make sure that the loaded
 
230
                System::GiveFile(file, &tmp); // file is not overwritten.
 
231
                if (tmp != name)
 
232
                        if (AskSave() == False)
 
233
                                return;
 
234
        }
 
235
        DoLoad(file);
 
236
}
 
237
 
 
238
void Document::DoLoad(const string *path) {
 
239
        mainwindow->SetCursor(MouseCursor::WATCH);
 
240
        if ((*path)[0] != '/')
 
241
                // make absolute path name.
 
242
                fileName = dir + *path;
 
243
        else
 
244
                fileName = *path;
 
245
        string suf;
 
246
        if (!fileName.getSuffix(suf))
 
247
                fileName.setSuffix(suffix);
 
248
        string txt = "loading from " + fileName;
 
249
        SetStatus(&txt);
 
250
        // is it an non-existent file ?
 
251
        if (!System::FileExists(fileName.getstr())) {
 
252
                NewFile(&fileName);
 
253
                mainwindow->SetCursor(MouseCursor::LEFT_PTR);
 
254
                return;
 
255
        }
 
256
        if (Load(&fileName)) {
 
257
                changes = 0;
 
258
                mainwindow->SetDocumentName(&name);
 
259
                mainwindow->SetModified(False);
 
260
                if (appending)
 
261
                        txt = name + " appended";
 
262
                else {
 
263
                        loaded = True;
 
264
                        txt = name + " loaded";
 
265
                        mainwindow->EnableDocumentSource(True);
 
266
                }
 
267
                SetStatus(&txt);
 
268
        }
 
269
        else {
 
270
                loaded = False;
 
271
                if (appending)
 
272
                        SetStatus("append document failed");
 
273
                else
 
274
                        SetStatus("load document failed");
 
275
        }
 
276
        mainwindow->SetCursor(MouseCursor::LEFT_PTR);
 
277
}
 
278
 
 
279
bool Document::Load(const string *file) {
 
280
        // open file for reading.
 
281
        ifile->Open(file);
 
282
        if (!ifile->Good()) {
 
283
                string txt = "Can not open\n'" + *file + "'";
 
284
                ShowDialog(MessageDialog::ERROR, "Error", &txt);
 
285
                ifile->Close();
 
286
                return False;
 
287
        }
 
288
        // Check if it is not a directory etc.
 
289
        if (!System::FileRegular(file->getstr())) {
 
290
                string txt = "'" + *file + "'\nis not a regular file";
 
291
                ShowDialog(MessageDialog::ERROR, "Error", &txt);
 
292
                ifile->Close();
 
293
                return False;
 
294
        }
 
295
        if (!LoadHeader()) {
 
296
                ifile->Close();
 
297
                return False;
 
298
        }
 
299
        LoadEntries();
 
300
        ifile->Close();
 
301
        return True;
 
302
}
 
303
 
 
304
bool Document::LoadHeader() {
 
305
        // Check and load document info.
 
306
        if (appending) {
 
307
                if (!(CheckDocInfo() && 
 
308
                      viewer->Check(ifile, loadFormat) && 
 
309
                      CheckEditInfo()))
 
310
                        return False;
 
311
        }
 
312
        else {  // we are loading
 
313
                if (!(LoadDocInfo() && viewer->Load(ifile, loadFormat) 
 
314
                    && LoadEditInfo()))
 
315
                        return False;
 
316
        }
 
317
        return True;
 
318
}
 
319
 
 
320
bool Document::CheckDocInfo() {
 
321
        // Checks but does not actually read in the storage and document info;
 
322
        string val;
 
323
        // Check storage info and load file format (into loadFormat).
 
324
        if (!CheckFormat())
 
325
                ;    // try to continue.
 
326
                // return False;
 
327
        if (loadFormat < 1.08) {
 
328
                if ( !ifile->ReadAttribute("Generator", &val) || 
 
329
                        !ifile->ReadStringAttribute("Written", &val) || 
 
330
                        !ifile->LookupChar('}'))
 
331
                return False;
 
332
        }
 
333
        else {
 
334
                if ( !ifile->ReadAttribute("GeneratedFrom", &val) || 
 
335
                        !ifile->ReadAttribute("WrittenBy", &val) || 
 
336
                        !ifile->ReadStringAttribute("WrittenOn", &val) || 
 
337
                        !ifile->LookupChar('}'))
 
338
                return False;
 
339
        }
 
340
        // Check document info
 
341
        // dname = "Document" or "Diagram" (older versions).
 
342
        if (!ifile->ReadWord(&val) || 
 
343
            ((val != "Diagram") && (val != "Document")) ||
 
344
            !ifile->ReadWord(&val) || 
 
345
            !ifile->LookupChar('{') ||
 
346
            !CheckDocumentType())
 
347
                return False;
 
348
        if (!ifile->ReadAttribute("Name", &val))
 
349
                return False;
 
350
        if (!ifile->ReadAttribute("Author", &val))
 
351
                return False;
 
352
        if (loadFormat < 1.08) {
 
353
                if (!ifile->ReadStringAttribute("Created", &val))
 
354
                        return False;
 
355
        }
 
356
        else {
 
357
                if (!ifile->ReadStringAttribute("CreatedOn", &val))
 
358
                        return False;
 
359
        }
 
360
        if (loadFormat >= 1.09) {
 
361
                if (!ifile->ReadStringAttribute("Annotation", &val))
 
362
                        return False;
 
363
        }
 
364
        if ( loadFormat >= 1.32 && Toolkit::HierarchicEditor(
 
365
                                                GetMainWindow()->GetTool()) ) {
 
366
                if ( ! ifile->ReadAttribute("Hierarchy", &val) )
 
367
                        return False;
 
368
        }
 
369
        if (!ifile->LookupChar('}'))
 
370
                return False;
 
371
        return True;
 
372
}
 
373
 
 
374
bool Document::LoadDocInfo() {
 
375
        string val;
 
376
        // Load and Check storage info.
 
377
        if (!CheckFormat())
 
378
                return False;
 
379
        if (loadFormat < 1.08) {
 
380
                if (!ifile->ReadAttribute("Generator", &generatedFrom))
 
381
                        return False;
 
382
                writtenBy = "?";
 
383
                if (!ifile->ReadStringAttribute("Written", &writtenOn))
 
384
                        return False;
 
385
        }
 
386
        else {
 
387
                if (!ifile->ReadAttribute("GeneratedFrom", &generatedFrom))
 
388
                        return False;
 
389
                if (!ifile->ReadAttribute("WrittenBy", &writtenBy))
 
390
                        return False;
 
391
                if (!ifile->ReadStringAttribute("WrittenOn", &writtenOn))
 
392
                        return False;
 
393
        }
 
394
        if (!ifile->LookupChar('}'))
 
395
                return False;
 
396
        // Load and Check document info.
 
397
        // dname = "Document" or "Diagram" (older versions).
 
398
        string dname;
 
399
        if (!ifile->ReadWord(&dname) || 
 
400
                ((dname != "Diagram") && (dname != "Document")))
 
401
                return False;
 
402
        if (loadFormat < 1.20) // in past documents had an extra id.
 
403
                if (!ifile->ReadWord(&val))
 
404
                        return False;
 
405
        if (!ifile->LookupChar('{') || !CheckDocumentType())
 
406
                return False;
 
407
        if (!ifile->ReadAttribute("Name", &name))
 
408
                return False;
 
409
        if (!ifile->ReadAttribute("Author", &author))
 
410
                return False;
 
411
        // file is copied or moved?
 
412
        string f;
 
413
        System::GiveFile(&fileName, &f);
 
414
        if (name != f && mainwindow->IsDoMap()) {
 
415
                string txt = "The file " + f + " contains the document named\n"
 
416
                        + name + " (apparently the file is moved or copied).\n"
 
417
                        "Do you wish to set the file name as new document " 
 
418
                        "name?";
 
419
                QuestionDialog q(mwwidget, False);
 
420
                q.Initialize();
 
421
                q.SetMessageString(&txt);
 
422
                q.SetTitle("file name as document name?");
 
423
                int answer = q.GetAnswer();
 
424
                if (answer == QuestionDialog::YES)
 
425
                        NewName(&f);
 
426
        }
 
427
        if (loadFormat < 1.08) {
 
428
                if (!ifile->ReadStringAttribute("Created", &createdOn))
 
429
                        return False;
 
430
        }
 
431
        else {
 
432
                if (!ifile->ReadStringAttribute("CreatedOn", &createdOn))
 
433
                        return False;
 
434
        }
 
435
        if (loadFormat >= 1.09) {
 
436
                if (!ifile->ReadStringAttribute("Annotation", &annotation))
 
437
                        return False;
 
438
        }
 
439
        if ( loadFormat >= 1.33 && Toolkit::HierarchicEditor(
 
440
                                                GetMainWindow()->GetTool()) ) {
 
441
                if ( ! ifile->ReadAttribute("Hierarchy", &val))
 
442
                        return False;
 
443
                SetHierarchic(val %= "True");
 
444
        } else
 
445
                SetHierarchic(False);
 
446
        if (!ifile->LookupChar('}'))
 
447
                return False;
 
448
        if (!name.endsWith(suffix)) {
 
449
                // string txt = "File name should have suffix '" + suffix + "'";
 
450
                // ShowDialog(MessageDialog::WARNING, "Warning", &txt);
 
451
                name.setSuffix(suffix);
 
452
        }
 
453
        return True;
 
454
}
 
455
 
 
456
bool Document::CheckFormat() {
 
457
        string val = "Storage";
 
458
        // look for storage clause.
 
459
        if (!(ifile->LookupWord(&val) && ifile->LookupChar('{'))) {
 
460
                string txt = "This file does not contain a loadable document";
 
461
                ShowDialog(MessageDialog::ERROR, "File error", &txt);
 
462
                return False;
 
463
        }
 
464
        // Load file format number.
 
465
        if (!(ifile->ReadAttribute("Format", &val)))
 
466
                return False;
 
467
        loadFormat = val.todouble();
 
468
        // Check file format number.
 
469
        if (loadFormat < 1.0) {
 
470
                string txt = "I found an obsolete file format";
 
471
                ShowDialog(MessageDialog::ERROR, "File format error", &txt);
 
472
                loadFormat = fileFormat;
 
473
                return False;
 
474
        }
 
475
        else if (loadFormat > fileFormat) {
 
476
                string txt = "This file format is newer than the current";
 
477
                txt += "\nthis could give problems reading this document";
 
478
                ShowDialog(MessageDialog::WARNING, "File format warning", &txt);
 
479
                loadFormat = fileFormat;
 
480
                return True;
 
481
        }
 
482
        return True;
 
483
}
 
484
 
 
485
bool Document::CheckDocumentType() {
 
486
        string val;
 
487
        // Check document type.
 
488
        if (!(ifile->ReadStringAttribute("Type", &val)))
 
489
                return False;
 
490
        if (val != Toolkit::DOCUMENT_TYPES[tool])
 
491
                ; 
 
492
                // error("Warning: trying to read a \"%s\" with %s\n", 
 
493
                //      val.getstr(), Toolkit::TOOL_NAMES[tool]);
 
494
        return True;
 
495
}
 
496
 
 
497
void Document::Save() {
 
498
        SetStatus("action: save");
 
499
        if (IsDefault())
 
500
                SaveAs();
 
501
        else {
 
502
                saveName = dir + name;
 
503
                DoSaveAs(&saveName);
 
504
        }
 
505
}
 
506
 
 
507
void Document::PrepareSaveDialog() {
 
508
        saveName = dir;
 
509
        if (!IsDefault())
 
510
                saveName += name;
 
511
        string ext = "*" + suffix;
 
512
        fileSelectionDialog->ManageOptionMenu(False);
 
513
        fileSelectionDialog->SetExtension(&ext);
 
514
}
 
515
 
 
516
void Document::SaveAs() {
 
517
        SetStatus("action: save as");
 
518
        saveSelection = False;
 
519
        PrepareSaveDialog();
 
520
        fileSelectionDialog->SetTitle("Save document to file");
 
521
        fileSelectionDialog->SetOKCallback(EditStubs::SaveAsOKCB, this);
 
522
        fileSelectionDialog->SetDefaultFile(&saveName);
 
523
        fileSelectionDialog->Popup();
 
524
}
 
525
 
 
526
void Document::SaveSelectionAs() {
 
527
        SetStatus("action: save selection as");
 
528
        saveSelection = True;
 
529
        PrepareSaveDialog();
 
530
        fileSelectionDialog->SetTitle("Save selection to file");
 
531
        fileSelectionDialog->SetOKCallback(EditStubs::SaveAsOKCB, this);
 
532
        fileSelectionDialog->Popup();
 
533
}
 
534
 
 
535
void Document::DoSaveAs(const string *p) {
 
536
        string path = *p;
 
537
        mainwindow->SetCursor(MouseCursor::WATCH);
 
538
        if (System::FileExists(path.getstr()) &&
 
539
            !System::FileRegular(path.getstr())) {
 
540
                string txt = "'" + path + "'\n is not a regular file";
 
541
                ShowDialog(MessageDialog::ERROR, "Error", &txt);
 
542
                SetStatus("document is not saved");
 
543
                mainwindow->SetCursor(MouseCursor::LEFT_PTR);
 
544
                return;
 
545
        }
 
546
        // make extension always .suffix
 
547
        if (!path.endsWith(suffix)) {
 
548
                path.setSuffix(suffix);
 
549
        }
 
550
 
 
551
        string file, directory;
 
552
        System::GiveFile(&path, &directory, &file);
 
553
        // not empty files.
 
554
        if (file == suffix)
 
555
                path = directory + '/' + Toolkit::DOCUMENT_DEFAULT + suffix;
 
556
 
 
557
        string txt = "saving to " + path;
 
558
        SetStatus(&txt);
 
559
        // Check if file already exists and the user _wants_ to overwrite it.
 
560
        if (!MayWrite(&path)) {
 
561
                SetStatus("document is not saved");
 
562
                mainwindow->SetCursor(MouseCursor::LEFT_PTR);
 
563
                return;
 
564
        }
 
565
        // the chosen file name will be the document name.
 
566
        string oldName = name;
 
567
        if (file != name) {
 
568
                // check and give document new name.
 
569
                if (!NewName(&file)) {
 
570
                        SetStatus("illegal name so document is not saved");
 
571
                        mainwindow->SetCursor(MouseCursor::LEFT_PTR);
 
572
                        return;
 
573
                }
 
574
        }
 
575
        saveName = path;
 
576
        if (Save(&saveName)) {
 
577
                txt = name + " saved";
 
578
                SetStatus(&txt);
 
579
        }
 
580
        else
 
581
                SetStatus("save document failed");
 
582
 
 
583
        if (saveSelection) {
 
584
                // restore old document name.
 
585
                name = oldName; 
 
586
                mainwindow->SetDocumentName(&name);
 
587
        }
 
588
        mainwindow->SetCursor(MouseCursor::LEFT_PTR);
 
589
}
 
590
 
 
591
bool Document::Save(const string *file) {
 
592
        // create or overwrite file
 
593
        ofile->Open(file);
 
594
        if (!ofile->Good()) {
 
595
                string txt = "'" + *file + 
 
596
                             "'\n can not be created or overwritten";
 
597
                ShowDialog(MessageDialog::ERROR, "Error", &txt);
 
598
                ofile->Close();
 
599
                return False;
 
600
        }
 
601
        SaveDocInfo();  // write document info.
 
602
        viewer->Save(ofile); // write view options.
 
603
        SaveEditInfo(); // write editor defaults.
 
604
        SaveEntries();
 
605
        ofile->Close();// close file
 
606
        // reset changes counter of document when it is entirely saved.
 
607
        if (!saveSelection) {
 
608
                changes = 0;
 
609
                mainwindow->SetModified(False);
 
610
        }
 
611
        return True;
 
612
}
 
613
 
 
614
void Document::SaveDocInfo() {
 
615
        string val;
 
616
        // begin storage info
 
617
        (*ofile) << "Storage " << '\n';
 
618
        (*ofile) << "{\n";
 
619
        // write current format.
 
620
        // I do not trust operator<<(double).
 
621
        string x = fileFormat;
 
622
        (*ofile) << "\t{ " << "Format " << x << " }\n";
 
623
        // write name of tool.
 
624
        (*ofile) << "\t{ " << "GeneratedFrom " << toolName << " }\n";
 
625
        // write login name.
 
626
        (void)System::GetTime(&val);
 
627
        (*ofile) << "\t{ " << "WrittenBy " << login << " }\n";
 
628
        // write current time.
 
629
        (void)System::GetTime(&val);
 
630
        (*ofile) << "\t{ " << "WrittenOn " << '"' << val << '"' << " }\n";
 
631
        // end storage info
 
632
        (*ofile) << "}\n\n";
 
633
        // begin document info
 
634
        (*ofile) << "Document \n{\n"
 
635
        // write document type.
 
636
                    "\t{ Type \"" << docType << "\" }\n"
 
637
        // write document name.
 
638
                    "\t{ Name " << name << " }\n"
 
639
        // write document author.
 
640
                    "\t{ Author " << author << " }\n"
 
641
        // write document creation date.
 
642
                    "\t{ CreatedOn \"" << createdOn << "\" }\n"
 
643
        // write document annotation.
 
644
                    "\t{ Annotation \"" 
 
645
                        << annotation << "\" }\n";
 
646
        if ( Toolkit::HierarchicEditor(GetMainWindow()->GetTool()) ) {
 
647
                // write hierarchic document flag
 
648
                (*ofile) << "\t{ Hierarchy " <<
 
649
                                (isHierarchic ? "True" : "False") << " }\n";
 
650
        }
 
651
        // end document info.
 
652
        (*ofile) << "}\n\n";
 
653
}
 
654
 
 
655
void Document::SaveEditInfo() { }
 
656
 
 
657
void Document::ShowSource() {
 
658
        SetStatus("action: show document source");
 
659
        sourceEditDialog->SetTitle(&fileName);
 
660
        sourceEditDialog->LoadFile(&fileName);
 
661
        sourceEditDialog->Popup();
 
662
        sourceEditDialog->SetStatus(&fileName);
 
663
}
 
664
 
 
665
void Document::SaveSource() {
 
666
        if (sourceEditDialog->SaveFile(&fileName))
 
667
                SetStatus("action: document source saved");
 
668
        else
 
669
                SetStatus("ok, did not save");
 
670
}
 
671
 
 
672
void Document::ShowDocInfo() {
 
673
        SetStatus("action: document info");
 
674
        string val;
 
675
        string temp = "Current tool info\n";
 
676
        temp += "---------------------\n";
 
677
        temp += "Tool: ";
 
678
        temp += toolName;
 
679
        temp += "\n";
 
680
        temp += "File format: ";
 
681
        temp += fileFormat;
 
682
        temp += "\n";
 
683
        temp += "Login: ";
 
684
        temp += login;
 
685
        temp += "\n";
 
686
        System::GetTime(&val);
 
687
        temp += "Current date: ";
 
688
        temp += val;
 
689
        temp += "\n";
 
690
        temp += "Directory: ";
 
691
        temp += dir;
 
692
        temp += "\n";
 
693
        temp += "Number of changes: ";
 
694
        temp += changes;
 
695
        temp += "\n";
 
696
        temp += "\n";
 
697
        temp += "Current document info\n";
 
698
        temp += "---------------------\n";
 
699
        temp += "Type: ";
 
700
        temp += docType;
 
701
        temp += "\n";
 
702
        temp += "Name: ";
 
703
        temp += name;
 
704
        temp += "\n";
 
705
        temp += "Author: ";
 
706
        temp += author;
 
707
        temp += "\n";
 
708
        temp += "Created on: ";
 
709
        temp += createdOn;
 
710
        temp += "\n";
 
711
        temp += "\n";
 
712
        temp += "Loaded file info\n";
 
713
        temp += "---------------------\n";
 
714
        if (loaded) {
 
715
                temp += "File name:";
 
716
                temp += fileName;
 
717
                temp += "\n";
 
718
                temp += "Loaded format: ";
 
719
                temp += loadFormat;
 
720
                temp += "\n";
 
721
                temp += "Generated from: ";
 
722
                temp += generatedFrom;
 
723
                temp += "\n";
 
724
                temp += "Written by: ";
 
725
                temp += writtenBy;
 
726
                temp += "\n";
 
727
                temp += "Written on: ";
 
728
                temp += writtenOn;
 
729
                temp += "\n";
 
730
        }
 
731
        else
 
732
                temp += "None: document is created by current tool\n";
 
733
        infoDialog->SetTextString(&temp);
 
734
        infoDialog->Popup();
 
735
}
 
736
 
 
737
void Document::ShowSummary() {
 
738
        SetStatus("action: document summary");
 
739
        ShowDialog(MessageDialog::INFORMATION, "Document summary", 
 
740
                "Nothing to summarize\n");
 
741
}
 
742
 
 
743
void Document::CheckDocument() {
 
744
        SetStatus("action: check document syntax");
 
745
        ShowDialog(MessageDialog::INFORMATION, "Check document syntax", 
 
746
                "There are no checks for this document type\n");
 
747
}
 
748
 
 
749
void Document::ModelCheckProperty() {
 
750
        SetStatus("action: model check property");           
 
751
        ShowDialog(MessageDialog::INFORMATION,
 
752
                "Model check property", 
 
753
                "There are no checks for this document type\n");
 
754
}
 
755
 
 
756
void Document::ClearTrace() {
 
757
        SetStatus("action: clear trace");
 
758
        ShowDialog(MessageDialog::INFORMATION,
 
759
                "Clear trace",
 
760
                "Not needed for this document type\n");
 
761
}
 
762
 
 
763
void Document::Annotate() {
 
764
        SetStatus("action: annotate document");
 
765
        string txt = "Annotation of " + name;
 
766
        docAnnotationDialog->SetTitle(&txt);
 
767
        docAnnotationDialog->SetTextString(&annotation);
 
768
        docAnnotationDialog->Popup();
 
769
        docAnnotationDialog->SetStatus(&txt);
 
770
}
 
771
 
 
772
void Document::Find() {
 
773
        SetStatus("action: find");
 
774
        findDialog->Popup();
 
775
}
 
776
 
 
777
void Document::Replace() {
 
778
        SetStatus("action: replace");
 
779
        replaceDialog->Popup();
 
780
}
 
781
 
 
782
void Document::SetAnnotation(const string *a) {
 
783
        annotation = *a;
 
784
        SetStatus("document annotation updated");
 
785
        IncChanges();
 
786
}
 
787
 
 
788
void Document::Quit() {
 
789
        SetStatus("action: quit");
 
790
        viewer->TextModeOff();
 
791
        int answer;
 
792
        if (changes > 0) {
 
793
                answer = AskSave();
 
794
                if (answer == False)
 
795
                        return;
 
796
        }
 
797
        if (config->GetAskBeforeQuit()) {
 
798
                string txt = "Are you sure you want to quit ";
 
799
                txt += Toolkit::TOOL_NAMES[tool];
 
800
                txt += "?";
 
801
                QuestionDialog q(mwwidget, False);
 
802
                q.Initialize();
 
803
                q.SetTitle("Quit confirmation");
 
804
                q.SetMessageString(&txt);
 
805
                answer = q.GetAnswer();
 
806
                if (answer == QuestionDialog::NO)
 
807
                        return;
 
808
        }
 
809
        // delete mainwindow and consequently the rest of the gang.
 
810
        mainwindow->Close();
 
811
}
 
812
 
 
813
bool Document::AskSave() {
 
814
        string txt = "Document '" + name + "' has been modified "
 
815
                "\nDo you want to save it first?";
 
816
        QuestionDialog q(mwwidget, True);
 
817
        q.Initialize();
 
818
        q.SetTitle("Document modified");
 
819
        q.SetMessageString(&txt);
 
820
        int answer = q.GetAnswer();
 
821
        if (answer == QuestionDialog::YES) {
 
822
                saveSelection = False;
 
823
                saveName = dir + name;
 
824
                if (!Save(&saveName))
 
825
                        return False;
 
826
        }
 
827
        else if (answer == QuestionDialog::CANCEL)
 
828
                return False;
 
829
        return True;
 
830
}
 
831
 
 
832
bool Document::NewName(const string *n) {
 
833
        string newName = *n;
 
834
        bool error = False;
 
835
        string txt;
 
836
 
 
837
        // name has a suffix but not the required suffix then give error msg.
 
838
        string suf;
 
839
        if (newName.getSuffix(suf) && suf != suffix) {
 
840
                error = True;
 
841
                txt = "Document name should have suffix '" + suffix + "'";
 
842
        }
 
843
        // add suffix when necessary.
 
844
        if (!newName.endsWith(suffix))
 
845
                newName.setSuffix(suffix);
 
846
 
 
847
        // no empty names.
 
848
        if (newName == suffix)
 
849
                newName = Toolkit::DOCUMENT_DEFAULT + suffix;
 
850
        
 
851
        // Check for illegal chars.
 
852
        for (unsigned i=0; i<newName.length(); i++) {
 
853
                unsigned char c = (unsigned char) newName[i];
 
854
                if (c == '/' || c == '{' || c == '}' || c == '"') {
 
855
                        error = True;
 
856
                        string cs = (char) c;
 
857
                        txt = "Document name should not contain the"
 
858
                              " character '" + cs + "'";
 
859
                }
 
860
                else if (!isprint(c)) {
 
861
                        error = True;
 
862
                        txt = "Document name should not contain"
 
863
                              " unprintable characters";
 
864
                }
 
865
                else if (isspace(c)) {
 
866
                        error = True;
 
867
                        txt = "Document name should not contain"
 
868
                              " white space characters";
 
869
                }
 
870
        }
 
871
        if (error) {
 
872
                ShowDialog(MessageDialog::ERROR, "Error", &txt);
 
873
                mainwindow->SetDocumentName(&name);
 
874
                SetStatus("document could not be renamed");
 
875
                return False;
 
876
        }
 
877
        mainwindow->SetDocumentName(&newName);
 
878
        if (name == newName)
 
879
                return True;
 
880
        name = newName;
 
881
        viewer->Refresh();      // refresh document header/footer (if any)
 
882
        txt = "document renamed to " + name;
 
883
        SetStatus(&txt);
 
884
        IncChanges();
 
885
        return True;
 
886
}
 
887
 
 
888
void Document::NewDir(const string *newdir) {
 
889
        if (!System::DirExists(newdir->getstr())) {
 
890
                string txt = *newdir + "\nis a non-existent directory";
 
891
                ShowDialog(MessageDialog::ERROR, "Error", &txt);
 
892
                UpdateDirectory(&dir);
 
893
                SetStatus("change directory failed");
 
894
                return;
 
895
        }
 
896
        else {
 
897
                dir = *newdir;
 
898
                if (dir[dir.length()-1] != '/')
 
899
                        dir += "/";
 
900
                UpdateDirectory(&dir);
 
901
                string txt = "change dir to " + dir;
 
902
                viewer->GetPrintFileSelectionDialog()->SetDirectory(&dir);
 
903
                SetStatus(&txt);
 
904
        }
 
905
}
 
906
 
 
907
bool Document::IsDefault() {
 
908
        string t = Toolkit::DOCUMENT_DEFAULT;
 
909
        return (name.startsWith(t) != 0);
 
910
}
 
911
 
 
912
void Document::IncChanges() {
 
913
        mainwindow->SetModified(0 != ++changes);
 
914
}
 
915
 
 
916
void Document::DecChanges() {
 
917
        mainwindow->SetModified(0 != --changes);
 
918
}
 
919
 
 
920
bool Document::MayWrite(const string *path) {
 
921
        if (System::FileExists(path->getstr())) {
 
922
                string txt = "'" + *path + 
 
923
                        "'\nalready exists. Do you want to overwrite it ?";
 
924
                QuestionDialog q(mwwidget, False);
 
925
                q.Initialize();
 
926
                q.SetTitle("Question");
 
927
                q.SetMessageString(&txt);
 
928
                int answer = q.GetAnswer();
 
929
                if (answer == QuestionDialog::NO)
 
930
                        return False;
 
931
        }
 
932
        return True;
 
933
}
 
934
 
 
935
void Document::ReportCheck(int errors, const string *msg) {
 
936
        SetStatus("action: report check document results");
 
937
        if (errors != 0) {
 
938
                string text = *msg;
 
939
                // get rid of carr. returns in text labels.
 
940
                text.replace('\r', ' ');
 
941
                checkDialog->SetTextString(&text);
 
942
                checkDialog->Popup();
 
943
        }
 
944
        else
 
945
                ShowDialog(MessageDialog::INFORMATION, "Check document",
 
946
                        "No violations found\n");
 
947
}
 
948
 
 
949
 
 
950
void Document::ShowDialog(MessageDialog::DialogType t, const char *title, 
 
951
                          const char *text) const {
 
952
        if (!mainwindow->IsDoMap()) {
 
953
                // mainwindow is not mapped, print to stderr.
 
954
                std::cerr << title << ": " << text << std::endl;
 
955
                return;
 
956
        }
 
957
        MessageDialog *d = new MessageDialog(mwwidget, t);
 
958
        d->Initialize();
 
959
        d->SetTitle(title);
 
960
#ifdef LINUX
 
961
        // I dont know why but otherwise I got crashes.
 
962
        d->Manage();
 
963
#endif
 
964
        d->SetMessageString(text);
 
965
        d->Popup();
 
966
}
 
967
 
 
968
 
 
969
void Document::SetHierarchic(bool set) {
 
970
        isHierarchic = AllowHierarchic() ? set : False;
 
971
}