~ubuntu-branches/ubuntu/trusty/qgis/trusty

« back to all changes in this revision

Viewing changes to src/plugins/grass/qtermwidget/History.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Johan Van de Wauw
  • Date: 2010-07-11 20:23:24 UTC
  • mfrom: (3.1.4 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100711202324-5ktghxa7hracohmr
Tags: 1.4.0+12730-3ubuntu1
* Merge from Debian unstable (LP: #540941).
* Fix compilation issues with QT 4.7
* Add build-depends on libqt4-webkit-dev 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    This file is part of Konsole, an X terminal.
 
3
    Copyright (C) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
 
4
 
 
5
    Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
 
6
 
 
7
    This program 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
    This program 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 this program; if not, write to the Free Software
 
19
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
20
    02110-1301  USA.
 
21
*/
 
22
 
 
23
// Own
 
24
#include "History.h"
 
25
 
 
26
// System
 
27
#include <iostream>
 
28
#include <stdlib.h>
 
29
#include <assert.h>
 
30
#include <stdio.h>
 
31
#include <sys/types.h>
 
32
#include <sys/mman.h>
 
33
#include <unistd.h>
 
34
#include <errno.h>
 
35
 
 
36
 
 
37
// Reasonable line size
 
38
#define LINE_SIZE 1024
 
39
 
 
40
using namespace Konsole;
 
41
 
 
42
/*
 
43
   An arbitrary long scroll.
 
44
 
 
45
   One can modify the scroll only by adding either cells
 
46
   or newlines, but access it randomly.
 
47
 
 
48
   The model is that of an arbitrary wide typewriter scroll
 
49
   in that the scroll is a serie of lines and each line is
 
50
   a serie of cells with no overwriting permitted.
 
51
 
 
52
   The implementation provides arbitrary length and numbers
 
53
   of cells and line/column indexed read access to the scroll
 
54
   at constant costs.
 
55
 
 
56
KDE4: Can we use QTemporaryFile here, instead of KTempFile?
 
57
 
 
58
FIXME: some complain about the history buffer comsuming the
 
59
       memory of their machines. This problem is critical
 
60
       since the history does not behave gracefully in cases
 
61
       where the memory is used up completely.
 
62
 
 
63
       I put in a workaround that should handle it problem
 
64
       now gracefully. I'm not satisfied with the solution.
 
65
 
 
66
FIXME: Terminating the history is not properly indicated
 
67
       in the menu. We should throw a signal.
 
68
 
 
69
FIXME: There is noticeable decrease in speed, also. Perhaps,
 
70
       there whole feature needs to be revisited therefore.
 
71
       Disadvantage of a more elaborated, say block-oriented
 
72
       scheme with wrap around would be it's complexity.
 
73
*/
 
74
 
 
75
//FIXME: tempory replacement for tmpfile
 
76
//       this is here one for debugging purpose.
 
77
 
 
78
//#define tmpfile xTmpFile
 
79
 
 
80
// History File ///////////////////////////////////////////
 
81
 
 
82
/*
 
83
  A Row(X) data type which allows adding elements to the end.
 
84
*/
 
85
 
 
86
HistoryFile::HistoryFile()
 
87
    : ion( -1 ),
 
88
    length( 0 ),
 
89
    fileMap( 0 )
 
90
{
 
91
  if ( tmpFile.open() )
 
92
  {
 
93
    tmpFile.setAutoRemove( true );
 
94
    ion = tmpFile.handle();
 
95
  }
 
96
}
 
97
 
 
98
HistoryFile::~HistoryFile()
 
99
{
 
100
  if ( fileMap )
 
101
    unmap();
 
102
}
 
103
 
 
104
//TODO:  Mapping the entire file in will cause problems if the history file becomes exceedingly large,
 
105
//(ie. larger than available memory).  HistoryFile::map() should only map in sections of the file at a time,
 
106
//to avoid this.
 
107
void HistoryFile::map()
 
108
{
 
109
  assert( fileMap == 0 );
 
110
 
 
111
  fileMap = ( char* )mmap( 0 , length , PROT_READ , MAP_PRIVATE , ion , 0 );
 
112
 
 
113
  //if mmap'ing fails, fall back to the read-lseek combination
 
114
  if ( fileMap == MAP_FAILED )
 
115
  {
 
116
    readWriteBalance = 0;
 
117
    fileMap = 0;
 
118
    qDebug() << ": mmap'ing history failed.  errno = " << errno;
 
119
  }
 
120
}
 
121
 
 
122
void HistoryFile::unmap()
 
123
{
 
124
  int result = munmap( fileMap , length );
 
125
  assert( result == 0 );
 
126
 
 
127
  fileMap = 0;
 
128
}
 
129
 
 
130
bool HistoryFile::isMapped()
 
131
{
 
132
  return ( fileMap != 0 );
 
133
}
 
134
 
 
135
void HistoryFile::add( const unsigned char* bytes, int len )
 
136
{
 
137
  if ( fileMap )
 
138
    unmap();
 
139
 
 
140
  readWriteBalance++;
 
141
 
 
142
  int rc = 0;
 
143
 
 
144
  rc = lseek( ion, length, SEEK_SET ); if ( rc < 0 ) { perror( "HistoryFile::add.seek" ); return; }
 
145
  rc = write( ion, bytes, len );       if ( rc < 0 ) { perror( "HistoryFile::add.write" ); return; }
 
146
  length += rc;
 
147
}
 
148
 
 
149
void HistoryFile::get( unsigned char* bytes, int len, int loc )
 
150
{
 
151
  //count number of get() calls vs. number of add() calls.
 
152
  //If there are many more get() calls compared with add()
 
153
  //calls (decided by using MAP_THRESHOLD) then mmap the log
 
154
  //file to improve performance.
 
155
  readWriteBalance--;
 
156
  if ( !fileMap && readWriteBalance < MAP_THRESHOLD )
 
157
    map();
 
158
 
 
159
  if ( fileMap )
 
160
  {
 
161
    for ( int i = 0; i < len; i++ )
 
162
      bytes[i] = fileMap[loc+i];
 
163
  }
 
164
  else
 
165
  {
 
166
    int rc = 0;
 
167
 
 
168
    if ( loc < 0 || len < 0 || loc + len > length )
 
169
      fprintf( stderr, "getHist(...,%d,%d): invalid args.\n", len, loc );
 
170
    rc = lseek( ion, loc, SEEK_SET ); if ( rc < 0 ) { perror( "HistoryFile::get.seek" ); return; }
 
171
    rc = read( ion, bytes, len );     if ( rc < 0 ) { perror( "HistoryFile::get.read" ); return; }
 
172
  }
 
173
}
 
174
 
 
175
int HistoryFile::len()
 
176
{
 
177
  return length;
 
178
}
 
179
 
 
180
 
 
181
// History Scroll abstract base class //////////////////////////////////////
 
182
 
 
183
 
 
184
HistoryScroll::HistoryScroll( HistoryType* t )
 
185
    : m_histType( t )
 
186
{
 
187
}
 
188
 
 
189
HistoryScroll::~HistoryScroll()
 
190
{
 
191
  delete m_histType;
 
192
}
 
193
 
 
194
bool HistoryScroll::hasScroll()
 
195
{
 
196
  return true;
 
197
}
 
198
 
 
199
// History Scroll File //////////////////////////////////////
 
200
 
 
201
/*
 
202
   The history scroll makes a Row(Row(Cell)) from
 
203
   two history buffers. The index buffer contains
 
204
   start of line positions which refere to the cells
 
205
   buffer.
 
206
 
 
207
   Note that index[0] addresses the second line
 
208
   (line #1), while the first line (line #0) starts
 
209
   at 0 in cells.
 
210
*/
 
211
 
 
212
HistoryScrollFile::HistoryScrollFile( const QString &logFileName )
 
213
    : HistoryScroll( new HistoryTypeFile( logFileName ) ),
 
214
    m_logFileName( logFileName )
 
215
{
 
216
}
 
217
 
 
218
HistoryScrollFile::~HistoryScrollFile()
 
219
{
 
220
}
 
221
 
 
222
int HistoryScrollFile::getLines()
 
223
{
 
224
  return index.len() / sizeof( int );
 
225
}
 
226
 
 
227
int HistoryScrollFile::getLineLen( int lineno )
 
228
{
 
229
  return ( startOfLine( lineno + 1 ) - startOfLine( lineno ) ) / sizeof( Character );
 
230
}
 
231
 
 
232
bool HistoryScrollFile::isWrappedLine( int lineno )
 
233
{
 
234
  if ( lineno >= 0 && lineno <= getLines() )
 
235
  {
 
236
    unsigned char flag;
 
237
    lineflags.get(( unsigned char* )&flag, sizeof( unsigned char ), ( lineno )*sizeof( unsigned char ) );
 
238
    return flag;
 
239
  }
 
240
  return false;
 
241
}
 
242
 
 
243
int HistoryScrollFile::startOfLine( int lineno )
 
244
{
 
245
  if ( lineno <= 0 ) return 0;
 
246
  if ( lineno <= getLines() )
 
247
  {
 
248
 
 
249
    if ( !index.isMapped() )
 
250
      index.map();
 
251
 
 
252
    int res;
 
253
    index.get(( unsigned char* )&res, sizeof( int ), ( lineno - 1 )*sizeof( int ) );
 
254
    return res;
 
255
  }
 
256
  return cells.len();
 
257
}
 
258
 
 
259
void HistoryScrollFile::getCells( int lineno, int colno, int count, Character res[] )
 
260
{
 
261
  cells.get(( unsigned char* )res, count*sizeof( Character ), startOfLine( lineno ) + colno*sizeof( Character ) );
 
262
}
 
263
 
 
264
void HistoryScrollFile::addCells( const Character text[], int count )
 
265
{
 
266
  cells.add(( unsigned char* )text, count*sizeof( Character ) );
 
267
}
 
268
 
 
269
void HistoryScrollFile::addLine( bool previousWrapped )
 
270
{
 
271
  if ( index.isMapped() )
 
272
    index.unmap();
 
273
 
 
274
  int locn = cells.len();
 
275
  index.add(( unsigned char* )&locn, sizeof( int ) );
 
276
  unsigned char flags = previousWrapped ? 0x01 : 0x00;
 
277
  lineflags.add(( unsigned char* )&flags, sizeof( unsigned char ) );
 
278
}
 
279
 
 
280
 
 
281
// History Scroll Buffer //////////////////////////////////////
 
282
HistoryScrollBuffer::HistoryScrollBuffer( unsigned int maxLineCount )
 
283
    : HistoryScroll( new HistoryTypeBuffer( maxLineCount ) )
 
284
    , _historyBuffer()
 
285
    , _maxLineCount( 0 )
 
286
    , _usedLines( 0 )
 
287
    , _head( 0 )
 
288
{
 
289
  setMaxNbLines( maxLineCount );
 
290
}
 
291
 
 
292
HistoryScrollBuffer::~HistoryScrollBuffer()
 
293
{
 
294
  delete[] _historyBuffer;
 
295
}
 
296
 
 
297
void HistoryScrollBuffer::addCellsVector( const QVector<Character>& cells )
 
298
{
 
299
  _head++;
 
300
  if ( _usedLines < _maxLineCount )
 
301
    _usedLines++;
 
302
 
 
303
  if ( _head >= _maxLineCount )
 
304
  {
 
305
    _head = 0;
 
306
  }
 
307
 
 
308
  _historyBuffer[bufferIndex( _usedLines-1 )] = cells;
 
309
  _wrappedLine[bufferIndex( _usedLines-1 )] = false;
 
310
}
 
311
void HistoryScrollBuffer::addCells( const Character a[], int count )
 
312
{
 
313
  HistoryLine newLine( count );
 
314
  qCopy( a, a + count, newLine.begin() );
 
315
 
 
316
  addCellsVector( newLine );
 
317
}
 
318
 
 
319
void HistoryScrollBuffer::addLine( bool previousWrapped )
 
320
{
 
321
  _wrappedLine[bufferIndex( _usedLines-1 )] = previousWrapped;
 
322
}
 
323
 
 
324
int HistoryScrollBuffer::getLines()
 
325
{
 
326
  return _usedLines;
 
327
}
 
328
 
 
329
int HistoryScrollBuffer::getLineLen( int lineNumber )
 
330
{
 
331
  Q_ASSERT( lineNumber >= 0 && lineNumber < _maxLineCount );
 
332
 
 
333
  if ( lineNumber < _usedLines )
 
334
  {
 
335
    return _historyBuffer[bufferIndex( lineNumber )].size();
 
336
  }
 
337
  else
 
338
  {
 
339
    return 0;
 
340
  }
 
341
}
 
342
 
 
343
bool HistoryScrollBuffer::isWrappedLine( int lineNumber )
 
344
{
 
345
  Q_ASSERT( lineNumber >= 0 && lineNumber < _maxLineCount );
 
346
 
 
347
  if ( lineNumber < _usedLines )
 
348
  {
 
349
    //kDebug() << "Line" << lineNumber << "wrapped is" << _wrappedLine[bufferIndex(lineNumber)];
 
350
    return _wrappedLine[bufferIndex( lineNumber )];
 
351
  }
 
352
  else
 
353
    return false;
 
354
}
 
355
 
 
356
void HistoryScrollBuffer::getCells( int lineNumber, int startColumn, int count, Character* buffer )
 
357
{
 
358
  if ( count == 0 ) return;
 
359
 
 
360
  Q_ASSERT( lineNumber < _maxLineCount );
 
361
 
 
362
  if ( lineNumber >= _usedLines )
 
363
  {
 
364
    memset( buffer, 0, count * sizeof( Character ) );
 
365
    return;
 
366
  }
 
367
 
 
368
  const HistoryLine& line = _historyBuffer[bufferIndex( lineNumber )];
 
369
 
 
370
  //kDebug() << "startCol " << startColumn;
 
371
  //kDebug() << "line.size() " << line.size();
 
372
  //kDebug() << "count " << count;
 
373
 
 
374
  Q_ASSERT( startColumn <= line.size() - count );
 
375
 
 
376
  memcpy( buffer, line.constData() + startColumn , count * sizeof( Character ) );
 
377
}
 
378
 
 
379
void HistoryScrollBuffer::setMaxNbLines( unsigned int lineCount )
 
380
{
 
381
  HistoryLine* oldBuffer = _historyBuffer;
 
382
  HistoryLine* newBuffer = new HistoryLine[lineCount];
 
383
 
 
384
  for ( int i = 0 ; i < qMin( _usedLines, ( int )lineCount ) ; i++ )
 
385
  {
 
386
    newBuffer[i] = oldBuffer[bufferIndex( i )];
 
387
  }
 
388
 
 
389
  _usedLines = qMin( _usedLines, ( int )lineCount );
 
390
  _maxLineCount = lineCount;
 
391
  _head = ( _usedLines == _maxLineCount ) ? 0 : _usedLines - 1;
 
392
 
 
393
  _historyBuffer = newBuffer;
 
394
  delete[] oldBuffer;
 
395
 
 
396
  _wrappedLine.resize( lineCount );
 
397
}
 
398
 
 
399
int HistoryScrollBuffer::bufferIndex( int lineNumber )
 
400
{
 
401
  Q_ASSERT( lineNumber >= 0 );
 
402
  Q_ASSERT( lineNumber < _maxLineCount );
 
403
  Q_ASSERT(( _usedLines == _maxLineCount ) || lineNumber <= _head );
 
404
 
 
405
  if ( _usedLines == _maxLineCount )
 
406
  {
 
407
    return ( _head + lineNumber + 1 ) % _maxLineCount;
 
408
  }
 
409
  else
 
410
  {
 
411
    return lineNumber;
 
412
  }
 
413
}
 
414
 
 
415
 
 
416
// History Scroll None //////////////////////////////////////
 
417
 
 
418
HistoryScrollNone::HistoryScrollNone()
 
419
    : HistoryScroll( new HistoryTypeNone() )
 
420
{
 
421
}
 
422
 
 
423
HistoryScrollNone::~HistoryScrollNone()
 
424
{
 
425
}
 
426
 
 
427
bool HistoryScrollNone::hasScroll()
 
428
{
 
429
  return false;
 
430
}
 
431
 
 
432
int  HistoryScrollNone::getLines()
 
433
{
 
434
  return 0;
 
435
}
 
436
 
 
437
int  HistoryScrollNone::getLineLen( int )
 
438
{
 
439
  return 0;
 
440
}
 
441
 
 
442
bool HistoryScrollNone::isWrappedLine( int /*lineno*/ )
 
443
{
 
444
  return false;
 
445
}
 
446
 
 
447
void HistoryScrollNone::getCells( int, int, int, Character [] )
 
448
{
 
449
}
 
450
 
 
451
void HistoryScrollNone::addCells( const Character [], int )
 
452
{
 
453
}
 
454
 
 
455
void HistoryScrollNone::addLine( bool )
 
456
{
 
457
}
 
458
 
 
459
// History Scroll BlockArray //////////////////////////////////////
 
460
 
 
461
HistoryScrollBlockArray::HistoryScrollBlockArray( size_t size )
 
462
    : HistoryScroll( new HistoryTypeBlockArray( size ) )
 
463
{
 
464
  m_blockArray.setHistorySize( size ); // nb. of lines.
 
465
}
 
466
 
 
467
HistoryScrollBlockArray::~HistoryScrollBlockArray()
 
468
{
 
469
}
 
470
 
 
471
int  HistoryScrollBlockArray::getLines()
 
472
{
 
473
  return m_lineLengths.count();
 
474
}
 
475
 
 
476
int  HistoryScrollBlockArray::getLineLen( int lineno )
 
477
{
 
478
  if ( m_lineLengths.contains( lineno ) )
 
479
    return m_lineLengths[lineno];
 
480
  else
 
481
    return 0;
 
482
}
 
483
 
 
484
bool HistoryScrollBlockArray::isWrappedLine( int /*lineno*/ )
 
485
{
 
486
  return false;
 
487
}
 
488
 
 
489
void HistoryScrollBlockArray::getCells( int lineno, int colno,
 
490
                                        int count, Character res[] )
 
491
{
 
492
  if ( !count ) return;
 
493
 
 
494
  const Block *b = m_blockArray.at( lineno );
 
495
 
 
496
  if ( !b )
 
497
  {
 
498
    memset( res, 0, count * sizeof( Character ) ); // still better than random data
 
499
    return;
 
500
  }
 
501
 
 
502
  assert((( colno + count ) * sizeof( Character ) ) < ENTRIES );
 
503
  memcpy( res, b->data + ( colno * sizeof( Character ) ), count * sizeof( Character ) );
 
504
}
 
505
 
 
506
void HistoryScrollBlockArray::addCells( const Character a[], int count )
 
507
{
 
508
  Block *b = m_blockArray.lastBlock();
 
509
 
 
510
  if ( !b ) return;
 
511
 
 
512
  // put cells in block's data
 
513
  assert(( count * sizeof( Character ) ) < ENTRIES );
 
514
 
 
515
  memset( b->data, 0, ENTRIES );
 
516
 
 
517
  memcpy( b->data, a, count * sizeof( Character ) );
 
518
  b->size = count * sizeof( Character );
 
519
 
 
520
  size_t res = m_blockArray.newBlock();
 
521
  assert( res > 0 );
 
522
  Q_UNUSED( res );
 
523
 
 
524
  m_lineLengths.insert( m_blockArray.getCurrent(), count );
 
525
}
 
526
 
 
527
void HistoryScrollBlockArray::addLine( bool )
 
528
{
 
529
}
 
530
 
 
531
//////////////////////////////////////////////////////////////////////
 
532
// History Types
 
533
//////////////////////////////////////////////////////////////////////
 
534
 
 
535
HistoryType::HistoryType()
 
536
{
 
537
}
 
538
 
 
539
HistoryType::~HistoryType()
 
540
{
 
541
}
 
542
 
 
543
//////////////////////////////
 
544
 
 
545
HistoryTypeNone::HistoryTypeNone()
 
546
{
 
547
}
 
548
 
 
549
bool HistoryTypeNone::isEnabled() const
 
550
{
 
551
  return false;
 
552
}
 
553
 
 
554
HistoryScroll* HistoryTypeNone::scroll( HistoryScroll *old ) const
 
555
{
 
556
  delete old;
 
557
  return new HistoryScrollNone();
 
558
}
 
559
 
 
560
int HistoryTypeNone::maximumLineCount() const
 
561
{
 
562
  return 0;
 
563
}
 
564
 
 
565
//////////////////////////////
 
566
 
 
567
HistoryTypeBlockArray::HistoryTypeBlockArray( size_t size )
 
568
    : m_size( size )
 
569
{
 
570
}
 
571
 
 
572
bool HistoryTypeBlockArray::isEnabled() const
 
573
{
 
574
  return true;
 
575
}
 
576
 
 
577
int HistoryTypeBlockArray::maximumLineCount() const
 
578
{
 
579
  return m_size;
 
580
}
 
581
 
 
582
HistoryScroll* HistoryTypeBlockArray::scroll( HistoryScroll *old ) const
 
583
{
 
584
  delete old;
 
585
  return new HistoryScrollBlockArray( m_size );
 
586
}
 
587
 
 
588
 
 
589
//////////////////////////////
 
590
 
 
591
HistoryTypeBuffer::HistoryTypeBuffer( unsigned int nbLines )
 
592
    : m_nbLines( nbLines )
 
593
{
 
594
}
 
595
 
 
596
bool HistoryTypeBuffer::isEnabled() const
 
597
{
 
598
  return true;
 
599
}
 
600
 
 
601
int HistoryTypeBuffer::maximumLineCount() const
 
602
{
 
603
  return m_nbLines;
 
604
}
 
605
 
 
606
HistoryScroll* HistoryTypeBuffer::scroll( HistoryScroll *old ) const
 
607
{
 
608
  if ( old )
 
609
  {
 
610
    HistoryScrollBuffer *oldBuffer = dynamic_cast<HistoryScrollBuffer*>( old );
 
611
    if ( oldBuffer )
 
612
    {
 
613
      oldBuffer->setMaxNbLines( m_nbLines );
 
614
      return oldBuffer;
 
615
    }
 
616
 
 
617
    HistoryScroll *newScroll = new HistoryScrollBuffer( m_nbLines );
 
618
    int lines = old->getLines();
 
619
    int startLine = 0;
 
620
    if ( lines > ( int ) m_nbLines )
 
621
      startLine = lines - m_nbLines;
 
622
 
 
623
    Character line[LINE_SIZE];
 
624
    for ( int i = startLine; i < lines; i++ )
 
625
    {
 
626
      int size = old->getLineLen( i );
 
627
      if ( size > LINE_SIZE )
 
628
      {
 
629
        Character *tmp_line = new Character[size];
 
630
        old->getCells( i, 0, size, tmp_line );
 
631
        newScroll->addCells( tmp_line, size );
 
632
        newScroll->addLine( old->isWrappedLine( i ) );
 
633
        delete [] tmp_line;
 
634
      }
 
635
      else
 
636
      {
 
637
        old->getCells( i, 0, size, line );
 
638
        newScroll->addCells( line, size );
 
639
        newScroll->addLine( old->isWrappedLine( i ) );
 
640
      }
 
641
    }
 
642
    delete old;
 
643
    return newScroll;
 
644
  }
 
645
  return new HistoryScrollBuffer( m_nbLines );
 
646
}
 
647
 
 
648
//////////////////////////////
 
649
 
 
650
HistoryTypeFile::HistoryTypeFile( const QString& fileName )
 
651
    : m_fileName( fileName )
 
652
{
 
653
}
 
654
 
 
655
bool HistoryTypeFile::isEnabled() const
 
656
{
 
657
  return true;
 
658
}
 
659
 
 
660
const QString& HistoryTypeFile::getFileName() const
 
661
{
 
662
  return m_fileName;
 
663
}
 
664
 
 
665
HistoryScroll* HistoryTypeFile::scroll( HistoryScroll *old ) const
 
666
{
 
667
  if ( dynamic_cast<HistoryFile *>( old ) )
 
668
    return old; // Unchanged.
 
669
 
 
670
  HistoryScroll *newScroll = new HistoryScrollFile( m_fileName );
 
671
 
 
672
  Character line[LINE_SIZE];
 
673
  int lines = ( old != 0 ) ? old->getLines() : 0;
 
674
  for ( int i = 0; i < lines; i++ )
 
675
  {
 
676
    int size = old->getLineLen( i );
 
677
    if ( size > LINE_SIZE )
 
678
    {
 
679
      Character *tmp_line = new Character[size];
 
680
      old->getCells( i, 0, size, tmp_line );
 
681
      newScroll->addCells( tmp_line, size );
 
682
      newScroll->addLine( old->isWrappedLine( i ) );
 
683
      delete [] tmp_line;
 
684
    }
 
685
    else
 
686
    {
 
687
      old->getCells( i, 0, size, line );
 
688
      newScroll->addCells( line, size );
 
689
      newScroll->addLine( old->isWrappedLine( i ) );
 
690
    }
 
691
  }
 
692
 
 
693
  delete old;
 
694
  return newScroll;
 
695
}
 
696
 
 
697
int HistoryTypeFile::maximumLineCount() const
 
698
{
 
699
  return 0;
 
700
}