~ubuntu-branches/ubuntu/karmic/kguitar/karmic

« back to all changes in this revision

Viewing changes to kguitar/convertgtp.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Loic Pefferkorn
  • Date: 2005-08-19 15:22:41 UTC
  • Revision ID: james.westby@ubuntu.com-20050819152241-n24w9np4vblrm5as
Tags: upstream-0.5
ImportĀ upstreamĀ versionĀ 0.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "convertgtp.h"
 
2
 
 
3
#include <qfile.h>
 
4
#include <qdatastream.h>
 
5
 
 
6
ConvertGtp::ConvertGtp(TabSong *song): ConvertBase(song) {}
 
7
 
 
8
QString ConvertGtp::readDelphiString()
 
9
{
 
10
        QString str;
 
11
        Q_UINT8 l;
 
12
        char *c;
 
13
 
 
14
        int maxl = readDelphiInteger();
 
15
        (*stream) >> l;
 
16
 
 
17
        if (maxl != l + 1)  kdWarning() << "readDelphiString - first word doesn't match second byte\n";
 
18
 
 
19
        c = (char *) malloc(l + 5);
 
20
 
 
21
        if (c) {
 
22
                stream->readRawBytes(c, l);
 
23
                c[l] = 0;
 
24
                str = QString::fromLocal8Bit(c);
 
25
                free(c);
 
26
        }
 
27
 
 
28
        return str;
 
29
}
 
30
 
 
31
QString ConvertGtp::readPascalString()
 
32
{
 
33
        QString str;
 
34
        Q_UINT8 l;
 
35
        char *c;
 
36
 
 
37
        (*stream) >> l;
 
38
 
 
39
        c = (char *) malloc(l + 5);
 
40
 
 
41
        if (c) {
 
42
                stream->readRawBytes(c, l);
 
43
                c[l] = 0;
 
44
                str = QString::fromLocal8Bit(c);
 
45
                free(c);
 
46
        }
 
47
 
 
48
        return str;
 
49
}
 
50
 
 
51
QString ConvertGtp::readWordPascalString()
 
52
{
 
53
        QString str;
 
54
        char *c;
 
55
 
 
56
        int l = readDelphiInteger();
 
57
 
 
58
        c = (char *) malloc(l + 5);
 
59
 
 
60
        if (c) {
 
61
                stream->readRawBytes(c, l);
 
62
                c[l] = 0;
 
63
                str = QString::fromLocal8Bit(c);
 
64
                free(c);
 
65
        }
 
66
 
 
67
        return str;
 
68
}
 
69
 
 
70
int ConvertGtp::readDelphiInteger()
 
71
{
 
72
        Q_UINT8 x;
 
73
        int r;
 
74
        (*stream) >> x; r = x;
 
75
        (*stream) >> x; r += x << 8;
 
76
        (*stream) >> x; r += x << 16;
 
77
        (*stream) >> x; r += x << 24;
 
78
        return r;
 
79
}
 
80
 
 
81
void ConvertGtp::readChromaticGraph()
 
82
{
 
83
        Q_UINT8 num;
 
84
        int n;
 
85
 
 
86
        // GREYFIX: currently just skips over chromatic graph
 
87
        (*stream) >> num;                        // icon
 
88
        readDelphiInteger();                     // shown amplitude
 
89
        n = readDelphiInteger();                 // number of points
 
90
        for (int i = 0; i < n; i++) {
 
91
                readDelphiInteger();                 // time
 
92
                readDelphiInteger();                 // pitch
 
93
                (*stream) >> num;                    // vibrato
 
94
        }
 
95
}
 
96
 
 
97
void ConvertGtp::readChord()
 
98
{
 
99
        int x1, x2, x3, x4;
 
100
        Q_UINT8 num;
 
101
        QString text;
 
102
        char garbage[50];
 
103
        // GREYFIX: currently just skips over chord diagram
 
104
 
 
105
        // GREYFIX: chord diagram
 
106
        x1 = readDelphiInteger();
 
107
        if (x1 != 257)
 
108
                kdWarning() << "Chord INT1=" << x1 << ", not 257\n";
 
109
        x2 = readDelphiInteger();
 
110
        if (x2 != 0)
 
111
                kdWarning() << "Chord INT2=" << x2 << ", not 0\n";
 
112
        x3 = readDelphiInteger();
 
113
        kdDebug() << "Chord INT3: " << x3 << "\n"; // FF FF FF FF if there is diagram
 
114
        x4 = readDelphiInteger();
 
115
        if (x4 != 0)
 
116
                kdWarning() << "Chord INT4=" << x4 << ", not 0\n";
 
117
        (*stream) >> num;
 
118
        if (num != 0)
 
119
                kdWarning() << "Chord BYTE5=" << (int) num << ", not 0\n";
 
120
        text = readPascalString();
 
121
        kdDebug() << "Chord diagram: " << text << "\n";
 
122
        
 
123
        // Skip garbage after pascal string end
 
124
        stream->readRawBytes(garbage, 25 - text.length());
 
125
        
 
126
        // Chord diagram parameters - for every string
 
127
        for (int i = 0; i < STRING_MAX_NUMBER; i++) {
 
128
                x1 = readDelphiInteger();
 
129
                kdDebug() << x1 << "\n";
 
130
        }
 
131
        
 
132
        // Unknown bytes
 
133
        stream->readRawBytes(garbage, 36);
 
134
 
 
135
        kdDebug() << "after chord, position: " << stream->device()->at() << "\n";
 
136
}
 
137
 
 
138
bool ConvertGtp::readSignature()
 
139
{
 
140
        char garbage[10];
 
141
 
 
142
        QString s = readPascalString();          // Format string
 
143
        kdDebug() << "GTP format: " << s << "\n";
 
144
 
 
145
        stream->readRawBytes(garbage, 6);        // Mysterious bytes
 
146
 
 
147
        return TRUE;
 
148
}
 
149
 
 
150
void ConvertGtp::readSongAttributes()
 
151
{
 
152
        QString s;
 
153
        char garbage[10];
 
154
 
 
155
        Q_UINT8 num;
 
156
 
 
157
        song->comments = "";
 
158
 
 
159
        song->title = readDelphiString();        // Song title
 
160
        kdDebug() << "Title: " << song->title << "\n";
 
161
 
 
162
        s = readDelphiString();                  // Song subtitle
 
163
        if (!s.isEmpty())  song->title += " (" + s + ")";
 
164
        kdDebug() << "Title: " << song->title << "\n";
 
165
 
 
166
        song->author = readDelphiString();       // Artist
 
167
        kdDebug() << "Author: " << song->author << "\n";
 
168
 
 
169
        s = readDelphiString();                  // Album
 
170
        if (!s.isEmpty())  song->author += " (" + s + ")";
 
171
        kdDebug() << "Author: " << song->author << "\n";
 
172
 
 
173
        s = readDelphiString();                  // Author
 
174
        if (!s.isEmpty())  song->author += " / " + s;
 
175
        kdDebug() << "Author: " << song->author << "\n";
 
176
 
 
177
        s = readDelphiString();                  // Copyright
 
178
        if (!s.isEmpty())  song->comments += "(C) " + s + "\n\n";
 
179
 
 
180
        song->transcriber = readDelphiString();  // Tab
 
181
 
 
182
        s = readDelphiString();                  // Instructions
 
183
        if (!s.isEmpty())  song->comments += s + "\n\n";
 
184
 
 
185
        // Notice lines
 
186
        int n = readDelphiInteger();
 
187
        for (int i = 0; i < n; i++)
 
188
                song->comments += readDelphiString() + "\n";
 
189
 
 
190
        (*stream) >> num;                        // GREYFIX: Shuffle rhythm feel
 
191
 
 
192
        // Lyrics
 
193
        readDelphiInteger();                     // GREYFIX: Lyric track number start
 
194
        for (int i = 0; i < LYRIC_LINES_MAX_NUMBER; i++) {
 
195
                readDelphiInteger();                 // GREYFIX: Start from bar
 
196
                readWordPascalString();              // GREYFIX: Lyric line
 
197
        }
 
198
 
 
199
        song->tempo = readDelphiInteger();       // Tempo
 
200
        stream->readRawBytes(garbage, 5);        // Mysterious bytes
 
201
}
 
202
 
 
203
void ConvertGtp::readTrackDefaults()
 
204
{
 
205
        Q_UINT8 num;
 
206
 
 
207
        for (int i = 0; i < TRACK_MAX_NUMBER * 2; i++) {
 
208
                trackPatch[i] = readDelphiInteger(); // MIDI Patch
 
209
                (*stream) >> num;                    // GREYFIX: volume
 
210
                (*stream) >> num;                    // GREYFIX: pan
 
211
                (*stream) >> num;                    // GREYFIX: chorus
 
212
                (*stream) >> num;                    // GREYFIX: reverb
 
213
                (*stream) >> num;                    // GREYFIX: phase
 
214
                (*stream) >> num;                    // GREYFIX: tremolo
 
215
                (*stream) >> num;                    // 2 byte padding: must be 00 00
 
216
                (*stream) >> num;
 
217
        }
 
218
}
 
219
 
 
220
void ConvertGtp::readBarProperties()
 
221
{
 
222
        Q_UINT8 bar_bitmask, num;
 
223
 
 
224
        int time1 = 4;
 
225
        int time2 = 4;
 
226
 
 
227
        kdDebug() << "readBarProperties(): start\n";
 
228
        for (int i = 0; i < numBars; i++) {
 
229
                (*stream) >> bar_bitmask;                    // bar property bitmask
 
230
                if (bar_bitmask != 0)
 
231
                        kdDebug() << "BAR #" << i << " - flags " << (int) bar_bitmask << "\n";
 
232
                // GREYFIX: new_time_numerator
 
233
                if (bar_bitmask & 0x01) {
 
234
                        (*stream) >> num;
 
235
                        time1 = num;
 
236
                        kdDebug() << "new time1 signature: " << time1 << ":" << time2 << "\n";
 
237
                }
 
238
                // GREYFIX: new_time_denominator
 
239
                if (bar_bitmask & 0x02) {
 
240
                        (*stream) >> num;
 
241
                        time2 = num;
 
242
                        kdDebug() << "new time2 signature: " << time1 << ":" << time2 << "\n";
 
243
                }
 
244
                // GREYFIX: number_of_repeats
 
245
                if (bar_bitmask & 0x08) {
 
246
                        (*stream) >> num;
 
247
                        kdDebug() << "repeat " << (int) num << "x\n";
 
248
                }
 
249
                // GREYFIX: alternative_ending_to
 
250
                if (bar_bitmask & 0x10) {
 
251
                        (*stream) >> num;
 
252
                        kdDebug() << "alternative ending to " << (int) num << "\n";
 
253
                }
 
254
                // GREYFIX: new section
 
255
                if (bar_bitmask & 0x20) {
 
256
                        QString text = readDelphiString();
 
257
                        readDelphiInteger(); // color?
 
258
                        kdDebug() << "new section: " << text << "\n";
 
259
                }
 
260
                if (bar_bitmask & 0x40) {
 
261
                        kdDebug() << "new key signature\n";
 
262
                        (*stream) >> num;                // GREYFIX: alterations_number
 
263
                        (*stream) >> num;                // GREYFIX: minor
 
264
                }
 
265
                if (bar_bitmask & 0x80)
 
266
                        kdWarning() << "0x80 in bar properties!\n";
 
267
        }
 
268
        kdDebug() << "readBarProperties(): end\n";
 
269
}
 
270
 
 
271
void ConvertGtp::readTrackProperties()
 
272
{
 
273
        Q_UINT8 num;
 
274
        char garbage[100];
 
275
 
 
276
        kdDebug() << "readTrackProperties(): start\n";
 
277
 
 
278
        for (int i = 0; i < numTracks; i++) {
 
279
                song->t.append(new TabTrack(TabTrack::FretTab, 0, 0, 0, 0, 6, 24));
 
280
                TabTrack *trk = song->t.current();
 
281
 
 
282
                (*stream) >> num;                    // GREYFIX: simulations bitmask
 
283
                trk->name = readPascalString();      // Track name
 
284
                kdDebug() << "Track: " << trk->name << "\n";
 
285
 
 
286
                stream->readRawBytes(garbage, 40 - trk->name.length()); // Padding
 
287
 
 
288
                // Tuning information
 
289
 
 
290
                trk->string = readDelphiInteger();
 
291
 
 
292
                // Parse [0..string-1] with real string tune data in reverse order
 
293
                for (int j = trk->string - 1; j >= 0; j--)
 
294
                        trk->tune[j] = readDelphiInteger();
 
295
 
 
296
                // Throw out the other useless garbage in [string..MAX-1] range
 
297
                for (int j = trk->string; j < STRING_MAX_NUMBER; j++)
 
298
                        readDelphiInteger();
 
299
 
 
300
                // GREYFIX: auto flag here?
 
301
 
 
302
                readDelphiInteger();                 // GREYFIX: MIDI port
 
303
                trk->channel = readDelphiInteger();  // MIDI channel 1
 
304
                readDelphiInteger();                 // GREYFIX: MIDI channel 2
 
305
                trk->frets = readDelphiInteger();    // Frets
 
306
                readDelphiInteger();                 // GREYFIX: Capo
 
307
                readDelphiInteger();                 // GREYFIX: Color
 
308
 
 
309
                // Fill remembered values from defaults
 
310
                trk->patch = trackPatch[i];
 
311
        }
 
312
        kdDebug() << "readTrackProperties(): end\n";
 
313
}
 
314
 
 
315
void ConvertGtp::readTabs()
 
316
{
 
317
        Q_UINT8 beat_bitmask, stroke_bitmask1, stroke_bitmask2, strings, num;
 
318
        Q_INT8 length, volume, pan, chorus, reverb, phase, tremolo;
 
319
        int x;
 
320
 
 
321
        TabTrack *trk = song->t.first();
 
322
        for (int tr = 0; tr < numTracks; tr++) {
 
323
                trk->b.resize(numBars);
 
324
                trk->c.resize(0);
 
325
                trk = song->t.next();
 
326
        }
 
327
 
 
328
        for (int j = 0; j < numBars; j++) {
 
329
                TabTrack *trk = song->t.first();
 
330
                for (int tr = 0; tr < numTracks; tr++) {
 
331
                        int numBeats = readDelphiInteger();
 
332
                        kdDebug() << "TRACK " << tr << ", BAR " << j << " (position: " << stream->device()->at() << ")\n";
 
333
 
 
334
                        x = trk->c.size();
 
335
                        trk->c.resize(trk->c.size() + numBeats);
 
336
                        trk->b[j].time1 = trk->b[j].time2 = 4; // GREYFIX: fixed 4:4 time signature
 
337
                        trk->b[j].start = x;
 
338
 
 
339
                        for (int k = 0; k < numBeats; k++) {
 
340
                                trk->c[x].flags = 0;
 
341
 
 
342
                                (*stream) >> beat_bitmask;   // beat bitmask
 
343
                                
 
344
                                if (beat_bitmask & 0x01)     // dotted column
 
345
                                        trk->c[x].flags |= FLAG_DOT;
 
346
 
 
347
                                if (beat_bitmask & 0x40) {
 
348
                                        (*stream) >> num;        // GREYFIX: pause_kind
 
349
                                }
 
350
                                
 
351
                                // Guitar Pro 4 beat lengths are as following:
 
352
                                // -2 = 1    => 480     3-l = 5  2^(3-l)*15
 
353
                                // -1 = 1/2  => 240           4
 
354
                                //  0 = 1/4  => 120           3
 
355
                                //  1 = 1/8  => 60            2
 
356
                                //  2 = 1/16 => 30 ... etc    1
 
357
                                //  3 = 1/32 => 15            0
 
358
 
 
359
                                (*stream) >> length;            // length
 
360
                                kdDebug() << "beat_bitmask: " << (int) beat_bitmask << "; length: " << length << "\n";
 
361
 
 
362
                                trk->c[x].l = (1 << (3 - length)) * 15;
 
363
 
 
364
                                if (beat_bitmask & 0x20) {
 
365
                                        readDelphiInteger();     // GREYFIX: t for tuples
 
366
                                }
 
367
                                
 
368
                                if (beat_bitmask & 0x02)     // Chord diagram
 
369
                                        readChord();
 
370
 
 
371
                                if (beat_bitmask & 0x04) {
 
372
                                        kdDebug() << "Text: " << readDelphiString() << "\n"; // GREYFIX: text with a beat
 
373
                                }
 
374
                                
 
375
                                // GREYFIX: stroke bitmasks
 
376
                                if (beat_bitmask & 0x08) {
 
377
                                        (*stream) >> stroke_bitmask1;
 
378
                                        (*stream) >> stroke_bitmask2;
 
379
                                        if (stroke_bitmask1 & 0x20)
 
380
                                                (*stream) >> num;      // GREYFIX: string torture
 
381
                                        if (stroke_bitmask2 & 0x04)
 
382
                                                readChromaticGraph();  // GREYFIX: tremolo graph
 
383
                                        if (stroke_bitmask1 & 0x40) {
 
384
                                                (*stream) >> num;      // GREYFIX: down stroke length
 
385
                                                (*stream) >> num;      // GREYFIX: up stroke length
 
386
                                        }
 
387
                                        if (stroke_bitmask2 & 0x02) {
 
388
                                                (*stream) >> num;      // GREYFIX: stroke pick direction
 
389
                                        }
 
390
                                }
 
391
                                
 
392
                                if (beat_bitmask & 0x10) {     // mixer variations
 
393
                                        (*stream) >> num;          // GREYFIX: new MIDI patch
 
394
                                        (*stream) >> volume;       // GREYFIX: new
 
395
                                        (*stream) >> pan;          // GREYFIX: new
 
396
                                        (*stream) >> chorus;       // GREYFIX: new
 
397
                                        (*stream) >> reverb;       // GREYFIX: new
 
398
                                        (*stream) >> phase;        // GREYFIX: new
 
399
                                        (*stream) >> tremolo;      // GREYFIX: new
 
400
                                        int tempo = readDelphiInteger(); // GREYFIX: new tempo
 
401
 
 
402
                                        // GREYFIX: transitions
 
403
                                        if (volume != -1)   (*stream) >> num;
 
404
                                        if (pan != -1)      (*stream) >> num;
 
405
                                        if (chorus != -1)   (*stream) >> num;
 
406
                                        if (reverb != -1)   (*stream) >> num;
 
407
                                        if (tremolo != -1)  (*stream) >> num;
 
408
                                        if (tempo != -1)    (*stream) >> num;
 
409
 
 
410
                                        (*stream) >> num;          // padding
 
411
                                }
 
412
                                
 
413
                                (*stream) >> strings;          // used strings mask
 
414
                                
 
415
                                for (int y = STRING_MAX_NUMBER - 1; y >= 0; y--) {
 
416
                                        trk->c[x].e[y] = 0;
 
417
                                        trk->c[x].a[y] = NULL_NOTE;
 
418
                                        if (strings & (1 << (y + STRING_MAX_NUMBER - trk->string)))
 
419
                                                readNote(trk, x, y);
 
420
                                }
 
421
                                
 
422
                                // Dump column
 
423
                                QString tmp = "";
 
424
                                for (int y = 0; y <= trk->string; y++) {
 
425
                                        if (trk->c[x].a[y] == NULL_NOTE) {
 
426
                                                tmp += ".";
 
427
                                        } else {
 
428
                                                tmp += '0' + trk->c[x].a[y];
 
429
                                        }
 
430
                                }
 
431
                                kdDebug() << "[" << tmp << "]\n";
 
432
                                
 
433
                                x++;
 
434
                        }
 
435
                        trk = song->t.next();
 
436
                }
 
437
        }
 
438
}
 
439
 
 
440
void ConvertGtp::readNote(TabTrack *trk, int x, int y)
 
441
{
 
442
        Q_UINT8 note_bitmask, variant, num, mod_mask1, mod_mask2;
 
443
 
 
444
        (*stream) >> note_bitmask;               // note bitmask
 
445
        (*stream) >> variant;                    // variant
 
446
 
 
447
        if (note_bitmask & 0x01) {               // GREYFIX: note != beat
 
448
                (*stream) >> num;                    // length
 
449
                (*stream) >> num;                    // t
 
450
        }
 
451
 
 
452
        if (note_bitmask & 0x02) {};             // GREYFIX: note is dotted
 
453
 
 
454
        if (note_bitmask & 0x10) {               // GREYFIX: dynamic
 
455
                (*stream) >> num;
 
456
        }
 
457
 
 
458
        (*stream) >> num;                        // fret number
 
459
        trk->c[x].a[y] = num;
 
460
 
 
461
        if (variant == 2) {                      // link with previous beat
 
462
                trk->c[x].flags |= FLAG_ARC;
 
463
                for (uint i = 0; i < MAX_STRINGS; i++) {
 
464
                        trk->c[x].a[i] = NULL_NOTE;
 
465
                        trk->c[x].e[i] = 0;
 
466
                }
 
467
        }
 
468
 
 
469
        if (variant == 3)                        // dead notes
 
470
                trk->c[x].a[y] = DEAD_NOTE;
 
471
 
 
472
        if (note_bitmask & 0x80) {               // GREYFIX: fingering
 
473
                (*stream) >> num;
 
474
                (*stream) >> num;
 
475
        }
 
476
 
 
477
        if (note_bitmask & 0x08) {
 
478
                (*stream) >> mod_mask1;
 
479
                (*stream) >> mod_mask2;
 
480
                if (mod_mask1 & 0x01) {
 
481
                        readChromaticGraph();            // GREYFIX: bend graph
 
482
                }
 
483
                if (mod_mask1 & 0x02)                // hammer on / pull off
 
484
                        trk->c[x].e[y] |= EFFECT_LEGATO;
 
485
                if (mod_mask1 & 0x08)                // let ring
 
486
                        trk->c[x].e[y] |= EFFECT_LETRING;
 
487
                if (mod_mask1 & 0x10) {              // GREYFIX: graces
 
488
                        (*stream) >> num;                // GREYFIX: grace fret
 
489
                        (*stream) >> num;                // GREYFIX: grace dynamic
 
490
                        (*stream) >> num;                // GREYFIX: grace transition
 
491
                        (*stream) >> num;                // GREYFIX: grace length
 
492
                }
 
493
                if (mod_mask2 & 0x01)                // staccato - we do palm mute
 
494
                        trk->c[x].flags |= FLAG_PM;
 
495
                if (mod_mask2 & 0x02)                // palm mute - we mute the whole column
 
496
                        trk->c[x].flags |= FLAG_PM;
 
497
                if (mod_mask2 & 0x04) {              // GREYFIX: tremolo
 
498
                        (*stream) >> num;                // GREYFIX: tremolo picking length
 
499
                }
 
500
                if (mod_mask2 & 0x08) {              // slide
 
501
                        trk->c[x].e[y] |= EFFECT_SLIDE;
 
502
                        (*stream) >> num;                // GREYFIX: slide kind
 
503
                }
 
504
                if (mod_mask2 & 0x10) {              // GREYFIX: harmonic
 
505
                        (*stream) >> num;                // GREYFIX: harmonic kind
 
506
                }
 
507
                if (mod_mask2 & 0x20) {              // GREYFIX: trill
 
508
                        (*stream) >> num;                // GREYFIX: trill fret
 
509
                        (*stream) >> num;                // GREYFIX: trill length
 
510
                }
 
511
        }
 
512
}
 
513
 
 
514
bool ConvertGtp::load(QString fileName)
 
515
{
 
516
        QFile f(fileName);
 
517
        if (!f.open(IO_ReadOnly))
 
518
                return FALSE;
 
519
 
 
520
        QDataStream s(&f);
 
521
        stream = &s;
 
522
 
 
523
        if (!readSignature())
 
524
                return FALSE;
 
525
 
 
526
        // Cleanup
 
527
        song->t.clear();
 
528
 
 
529
        readSongAttributes();
 
530
        readTrackDefaults();
 
531
 
 
532
        numBars = readDelphiInteger();           // Number of bars
 
533
        numTracks = readDelphiInteger();         // Number of tracks
 
534
 
 
535
        kdDebug() << "Bars: " << numBars << "\n";
 
536
        kdDebug() << "Tracks: " << numTracks << "\n";
 
537
 
 
538
        // Mysterious padding: must be 43 04 04 00 (for 4.00 format)
 
539
        kdDebug() << "PAD: " << readDelphiInteger() << " (must be 263235)\n";
 
540
 
 
541
        readBarProperties();
 
542
        readTrackProperties();
 
543
        readTabs();
 
544
 
 
545
        int ex = readDelphiInteger();            // Exit code: 00 00 00 00
 
546
        if (ex != 0)
 
547
                kdWarning() << "File not ended with 00 00 00 00\n";
 
548
        if (!f.atEnd())
 
549
                kdWarning() << "File not ended - there's more data!\n";
 
550
 
 
551
        f.close();
 
552
 
 
553
    return TRUE;
 
554
}
 
555
 
 
556
bool ConvertGtp::save(QString)
 
557
{
 
558
    return FALSE;
 
559
}