~ubuntu-branches/ubuntu/maverick/datakiosk/maverick

« back to all changes in this revision

Viewing changes to src/datakiosk/src/datatable.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2005-06-27 22:48:06 UTC
  • Revision ID: james.westby@ubuntu.com-20050627224806-8farkci1dc2onhbs
Tags: upstream-0.7
ImportĀ upstreamĀ versionĀ 0.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
*   Copyright (C) 2005 by Adam Treat                                      *
 
3
*   treat@kde.org                                                         *
 
4
*                                                                         *
 
5
*   Copyright (C) 2004 by Scott Wheeler                                   *
 
6
*   wheeler@kde.org                                                       *
 
7
*                                                                         *
 
8
*   This program is free software; you can redistribute it and/or modify  *
 
9
*   it under the terms of the GNU General Public License as published by  *
 
10
*   the Free Software Foundation; either version 2 of the License, or     *
 
11
*   (at your option) any later version.                                   *
 
12
*                                                                         *
 
13
***************************************************************************/
 
14
 
 
15
#include <kconfig.h>
 
16
#include <kmessagebox.h>
 
17
#include <kurldrag.h>
 
18
#include <kiconloader.h>
 
19
#include <klineedit.h>
 
20
#include <kaction.h>
 
21
#include <kpopupmenu.h>
 
22
#include <klocale.h>
 
23
#include <kdebug.h>
 
24
#include <kinputdialog.h>
 
25
#include <kapplication.h>
 
26
 
 
27
#include <kdialog.h>
 
28
 
 
29
#include <qpainter.h>
 
30
#include <qheader.h>
 
31
#include <qcursor.h>
 
32
#include <qdir.h>
 
33
#include <qeventloop.h>
 
34
#include <qtooltip.h>
 
35
#include <qwidgetstack.h>
 
36
#include <qsqldatabase.h>
 
37
#include <qstyle.h>
 
38
#include <qsqlpropertymap.h>
 
39
 
 
40
#include <time.h>
 
41
#include <math.h>
 
42
#include <dirent.h>
 
43
 
 
44
#include "datatable.h"
 
45
#include "project.h"
 
46
#include "datatablesearch.h"
 
47
#include "actioncollection.h"
 
48
#include "datakiosk.h"
 
49
#include "databaseconnection.h"
 
50
#include "fieldeditordialogimpl.h"
 
51
#include "connectioneditordialogimpl.h"
 
52
#include "formlayout.h"
 
53
 
 
54
using namespace ActionCollection;
 
55
 
 
56
bool DataTable::m_visibleChanged = false;
 
57
 
 
58
DataTable::DataTable( Project *project ) :
 
59
        QTabWidget( project->dataTableStack() ),
 
60
        m_tableView( new DataTableView( this ) ),
 
61
        m_tableEdit( new DataTableEdit( this ) ),
 
62
        m_project( project ),
 
63
        m_factory( new DataTableEditorFactory( this ) ),
 
64
        m_propMap( new QSqlPropertyMap() ),
 
65
        m_updatesAllowed( false )
 
66
{
 
67
    setup();
 
68
    setIconName( "table" );
 
69
    m_project->setupDataTable( this, iconName() );
 
70
}
 
71
 
 
72
DataTable::DataTable( Project *project, DataTable* parent ) :
 
73
        QTabWidget( project->dataTableStack() ),
 
74
        m_tableView( new DataTableView( this ) ),
 
75
        m_tableEdit( new DataTableEdit( this ) ),
 
76
        m_project( project ),
 
77
        m_factory( new DataTableEditorFactory( this ) ),
 
78
        m_propMap( new QSqlPropertyMap() ),
 
79
        m_updatesAllowed( false )
 
80
{
 
81
    setup();
 
82
    setIconName( "child" );
 
83
    m_project->setupDataTable( this, iconName(), parent );
 
84
}
 
85
 
 
86
DataTable::~DataTable()
 
87
{
 
88
    DataFieldList::iterator it = m_fieldList.begin();
 
89
    for ( ; it != m_fieldList.end(); ++it )
 
90
        delete ( *it );
 
91
 
 
92
    delete m_tableView->sqlCursor();
 
93
}
 
94
 
 
95
bool DataTable::initialize()
 
96
{
 
97
    if ( tableName().isEmpty() || connection().isEmpty() )
 
98
        return false;
 
99
 
 
100
    DatabaseConnection * database = m_project->databaseConnection( connection() );
 
101
 
 
102
    if ( !database )
 
103
        return false;
 
104
 
 
105
    if ( !database->isOpen() )
 
106
        if ( !database->open() )
 
107
        {
 
108
            ConnectionEditorDialog dialog( this );
 
109
            dialog.exec();
 
110
            database = m_project->databaseConnection( connection() );
 
111
        }
 
112
 
 
113
    m_tableView->setSqlCursor( new QSqlCursor( tableName(), true, database->connection() ), false );
 
114
    m_tableEdit->setSqlCursor( m_tableView->sqlCursor() );
 
115
 
 
116
    initializeFields( parentName().isEmpty() );
 
117
 
 
118
    m_updatesAllowed = true;
 
119
 
 
120
    if ( parentName().isEmpty() )
 
121
        slotSelectFirstRow();
 
122
    else
 
123
        emit requestParentSelect();
 
124
 
 
125
    initializeEditorFields();
 
126
 
 
127
    return true;
 
128
}
 
129
 
 
130
void DataTable::initializeFields( bool refresh )
 
131
{
 
132
    fieldSorter( m_fieldList.begin(), m_fieldList.end() );
 
133
    QStringList visible = visibleColumns();
 
134
    int diff = m_tableView->numCols() - visible.count();
 
135
 
 
136
    if ( diff > 0 )
 
137
    {
 
138
        for ( int i = 0; i < diff; ++i )
 
139
        {
 
140
            m_tableView->removeColumn( i );
 
141
        }
 
142
    }
 
143
    else if ( diff < 0 )
 
144
    {
 
145
        for ( int i = 0; i > diff; --i )
 
146
        {
 
147
            m_tableView->addColumn( "temp" );
 
148
        }
 
149
    }
 
150
 
 
151
    for ( DataFieldList::Iterator it = m_fieldList.begin(); it != m_fieldList.end(); ++it )
 
152
    {
 
153
        if ( ( *it ) ->isVirtual() )
 
154
            continue;
 
155
 
 
156
        QSqlField* field = m_tableView->sqlCursor() ->field( ( *it ) ->name().latin1() );
 
157
 
 
158
        if ( !field )
 
159
            continue;
 
160
 
 
161
        if ( ( *it ) ->hidden() )
 
162
            continue;
 
163
 
 
164
        QString labelName = ( *it ) ->label() != QString::null ? ( *it ) ->label() : field->name();
 
165
        m_tableView->setColumn( ( *it ) ->number(), field->name(), labelName, ( *it ) ->width() );
 
166
    }
 
167
 
 
168
    if ( refresh )
 
169
    {
 
170
        QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
 
171
        tableRefresh( QDataTable::RefreshAll );
 
172
        QApplication::restoreOverrideCursor();
 
173
    }
 
174
}
 
175
 
 
176
void DataTable::initializeEditorFields()
 
177
{
 
178
    DataEditorBase *base;
 
179
    m_tableEdit->removeEditors();
 
180
    for ( DataFieldList::Iterator it = m_fieldList.begin(); it != m_fieldList.end(); ++it )
 
181
    {
 
182
        QSqlField* field = 0;
 
183
        if ( !( *it ) ->isVirtual() )
 
184
        {
 
185
            field = m_tableView->sqlCursor() ->field( ( *it ) ->name().latin1() );
 
186
            if ( !field )
 
187
                continue;
 
188
        }
 
189
 
 
190
        if ( ( *it ) ->hidden() )
 
191
            continue;
 
192
 
 
193
        QString labelName = ( *it ) ->label() != QString::null ? ( *it ) ->label() : field->name();
 
194
 
 
195
        if (  ( *it ) ->isVirtual()  )
 
196
            base = new DataEditorBase( labelName, ( *it ) ->name(), m_factory, m_tableEdit->getFormBox() );
 
197
        else
 
198
            base = new DataEditorBase( labelName, field, m_factory, m_tableEdit->getFormBox() );
 
199
        m_tableEdit->addEditorBase( base, ( *it ) ->isVirtual() );
 
200
    }
 
201
    m_tableEdit->getFormLayout()->invalidate();
 
202
    m_tableEdit->getFormLayout()->activate();
 
203
    m_tableEdit->seek( m_tableView->currentRow() );
 
204
}
 
205
 
 
206
QStringList DataTable::visibleColumns()
 
207
{
 
208
    QStringList lst;
 
209
    for ( DataFieldList::Iterator it = m_fieldList.begin(); it != m_fieldList.end(); ++it )
 
210
    {
 
211
        if ( ( *it ) ->isVirtual() )
 
212
            continue;
 
213
 
 
214
        QSqlField* field = dataTableView() ->sqlCursor() ->field( ( *it ) ->name().latin1() );
 
215
        if ( !field )
 
216
            continue;
 
217
 
 
218
        if ( ( *it ) ->hidden() )
 
219
            continue;
 
220
 
 
221
        lst.append( ( *it ) ->name() );
 
222
    }
 
223
    return lst;
 
224
}
 
225
 
 
226
QString DataTable::name() const
 
227
{
 
228
    if ( !m_dataTableName.isEmpty() )
 
229
        return m_dataTableName;
 
230
    else
 
231
        return m_tableName;
 
232
}
 
233
 
 
234
void DataTable::setName( const QString &n )
 
235
{
 
236
    m_project->addName( n );
 
237
    m_project->removeName( m_dataTableName );
 
238
 
 
239
    m_dataTableName = n;
 
240
    emit signalNameChanged( m_dataTableName );
 
241
}
 
242
 
 
243
QString DataTable::alias() const
 
244
{
 
245
    return DataTable::sanitize( name() );
 
246
}
 
247
 
 
248
QString DataTable::sanitize( const QString &str )
 
249
{
 
250
    QRegExp rx( "(?:[a-z]|[A-Z]|[0-9]|\\.|_|-)+" );
 
251
    QStringList list;
 
252
    int pos = 0;
 
253
    while ( pos >= 0 ) {
 
254
        pos = rx.search( str, pos );
 
255
        if ( pos > -1 ) {
 
256
            list += rx.cap();
 
257
            pos  += rx.matchedLength();
 
258
        }
 
259
    }
 
260
    return list.join("");
 
261
}
 
262
 
 
263
QString DataTable::iconName() const
 
264
{
 
265
    return m_dataTableIconName;
 
266
}
 
267
 
 
268
void DataTable::setIconName( const QString &n )
 
269
{
 
270
    m_dataTableIconName = n;
 
271
    setTabIconSet( m_tableView, SmallIconSet( n ) );
 
272
    m_project->setIconName( this, n );
 
273
}
 
274
 
 
275
QString DataTable::connection() const
 
276
{
 
277
    return m_connection;
 
278
}
 
279
 
 
280
void DataTable::setConnection( const QString &name )
 
281
{
 
282
    m_connection = name;
 
283
}
 
284
 
 
285
QString DataTable::tableName() const
 
286
{
 
287
    return m_tableName;
 
288
}
 
289
 
 
290
void DataTable::setTableName( const QString &name )
 
291
{
 
292
    m_tableName = name;
 
293
}
 
294
 
 
295
int DataTable::number() const
 
296
{
 
297
    return m_number;
 
298
}
 
299
 
 
300
void DataTable::setNumber( int number )
 
301
{
 
302
    m_number = number;
 
303
}
 
304
 
 
305
QString DataTable::parentName() const
 
306
{
 
307
    return m_parentName;
 
308
}
 
309
 
 
310
void DataTable::setParentName( const QString &name )
 
311
{
 
312
    m_parentName = name;
 
313
}
 
314
 
 
315
DataTable::RelationToParent DataTable::relationToParent() const
 
316
{
 
317
    return m_relationToParent;
 
318
}
 
319
 
 
320
void DataTable::setRelationToParent( DataTable::RelationToParent relation )
 
321
{
 
322
    m_relationToParent = relation;
 
323
}
 
324
 
 
325
QString DataTable::parentKey() const
 
326
{
 
327
    return m_parentKey;
 
328
}
 
329
 
 
330
void DataTable::setParentKey( const QString &name )
 
331
{
 
332
    m_parentKey = name;
 
333
}
 
334
 
 
335
QString DataTable::foreignKey() const
 
336
{
 
337
    return m_foreignKey;
 
338
}
 
339
 
 
340
void DataTable::setForeignKey( const QString &name )
 
341
{
 
342
    m_foreignKey = name;
 
343
}
 
344
 
 
345
QString DataTable::foreignValue() const
 
346
{
 
347
    return m_foreignValue;
 
348
}
 
349
 
 
350
void DataTable::setForeignValue( const QString &name )
 
351
{
 
352
    m_foreignValue = name;
 
353
}
 
354
 
 
355
QString DataTable::defaultFilter() const
 
356
{
 
357
    return m_defaultFilter;
 
358
}
 
359
 
 
360
void DataTable::setDefaultFilter( const QString &filter )
 
361
{
 
362
    m_defaultFilter = filter;
 
363
}
 
364
 
 
365
QString DataTable::searchFilter() const
 
366
{
 
367
    return m_searchFilter;
 
368
}
 
369
 
 
370
void DataTable::setSearchFilter( const QString &filter )
 
371
{
 
372
    m_searchFilter = filter;
 
373
}
 
374
 
 
375
QStringList DataTable::sort() const
 
376
{
 
377
    return m_sort;
 
378
}
 
379
 
 
380
void DataTable::setSort( const QStringList &sort )
 
381
{
 
382
    //Hold our own value to always reflect the default sort
 
383
    //not the current sort.
 
384
    m_sort = sort;
 
385
    m_tableView->setSort( m_sort );
 
386
    m_tableEdit->setSort( m_sort );
 
387
}
 
388
 
 
389
bool DataTable::updatesAllowed() const
 
390
{
 
391
    return m_updatesAllowed;
 
392
}
 
393
 
 
394
void DataTable::setUpdatesAllowed( bool allowed )
 
395
{
 
396
    m_updatesAllowed = allowed;
 
397
}
 
398
 
 
399
QStringList DataTable::inheritanceTree() const
 
400
{
 
401
    return m_inheritanceTree;
 
402
}
 
403
 
 
404
void DataTable::setInheritanceTree( const QStringList &inheritanceTree )
 
405
{
 
406
    m_inheritanceTree = inheritanceTree;
 
407
}
 
408
 
 
409
DataRelation* DataTable::dataRelation( const QString &key )
 
410
{
 
411
    DataFieldList::iterator it;
 
412
    for ( it = m_fieldList.begin(); it != m_fieldList.end(); ++it )
 
413
        if ( ( *it ) ->name() == key )
 
414
            return ( *it ) ->relation();
 
415
 
 
416
    return 0;
 
417
}
 
418
 
 
419
void DataTable::addDataRelation( const QString &name, const QString &targetTable,
 
420
                                 const QString &targetKey, const QString &targetField,
 
421
                                 const QString &targetConstraint,
 
422
                                 const QVariant::Type targetType, int number,
 
423
                                 int editorWidth )
 
424
{
 
425
    DataField * f = dataField( name );
 
426
    DataRelation *r = new DataRelation();
 
427
    r->setTable( targetTable );
 
428
    r->setKey( targetKey );
 
429
    r->setConstraint( targetConstraint );
 
430
    r->addDataField( targetField, targetType, number, editorWidth, false, true, false, false );
 
431
 
 
432
    f->setRelation( r );
 
433
}
 
434
 
 
435
DataFieldList DataTable::fieldList()
 
436
{
 
437
    return m_fieldList;
 
438
}
 
439
 
 
440
DataField* DataTable::dataField( const QString &key )
 
441
{
 
442
    DataFieldList::iterator it;
 
443
    for ( it = m_fieldList.begin(); it != m_fieldList.end(); ++it )
 
444
        if ( ( *it ) ->name() == key )
 
445
            return ( *it );
 
446
 
 
447
    return 0;
 
448
}
 
449
 
 
450
DataField* DataTable::dataField( int col )
 
451
{
 
452
    DataFieldList::iterator it;
 
453
    for ( it = m_fieldList.begin(); it != m_fieldList.end(); ++it )
 
454
        if ( ( *it ) ->number() == col )
 
455
            return ( *it );
 
456
 
 
457
    return 0;
 
458
}
 
459
 
 
460
void DataTable::addDataField( const QString &name, const QVariant::Type type,
 
461
                              int isRequired, bool calculated, bool isVirtual,
 
462
                              const QString &equation, const QString &label,
 
463
                              int number, int width,
 
464
                              bool foreign, bool primary, bool hidden,
 
465
                              bool resizable, bool sortable )
 
466
{
 
467
    DataField * f = new DataField();
 
468
    f->setName( name );
 
469
    f->setTable( m_tableName );
 
470
    f->setType( type );
 
471
    f->setRequired( isRequired );
 
472
    f->setCalculated( calculated );
 
473
    f->setVirtual( isVirtual );
 
474
    f->setEquation( equation );
 
475
    f->setLabel( label );
 
476
    f->setNumber( number == -1 ? m_fieldList.count() : number );
 
477
    f->setWidth( width == 0 ? -1 : width );
 
478
    f->setForeign( foreign );
 
479
    f->setPrimary( primary );
 
480
    f->setHidden( hidden );
 
481
    f->setResizable( resizable );
 
482
    f->setSortable( sortable );
 
483
    m_fieldList.append( f );
 
484
}
 
485
 
 
486
void DataTable::removeDataField( DataField *field )
 
487
{
 
488
    bool isVirtual = field->isVirtual();
 
489
 
 
490
    m_fieldList.remove( field );
 
491
    delete field;
 
492
 
 
493
    if ( !isVirtual )
 
494
        initializeFields();
 
495
    initializeEditorFields();
 
496
}
 
497
 
 
498
KActionMenu *DataTable::columnVisibleAction() const
 
499
{
 
500
    return m_columnVisibleAction;
 
501
}
 
502
 
 
503
DataTableSearch DataTable::search() const
 
504
{
 
505
    return m_search;
 
506
}
 
507
 
 
508
void DataTable::setSearch( const DataTableSearch &search )
 
509
{
 
510
    m_search = search;
 
511
}
 
512
 
 
513
void DataTable::tableRefresh( QDataTable::Refresh mode )
 
514
{
 
515
    if ( !m_tableView->sqlCursor() )
 
516
        return;
 
517
    m_tableView->setSort( sort() );
 
518
    m_tableView->horizontalHeader()->setSortIndicator( -1, Qt::Ascending );
 
519
    m_tableView->refresh( mode );
 
520
    emit tableRefreshed();
 
521
}
 
522
 
 
523
bool DataTable::isRootTable()
 
524
{
 
525
    return parentName().isEmpty();
 
526
}
 
527
 
 
528
void DataTable::slotUpdate()
 
529
{
 
530
    if ( !m_updatesAllowed )
 
531
        return;
 
532
 
 
533
    if ( m_tableView->currentSelection() == -1 && m_tableView->numRows() < 1 )
 
534
    {
 
535
        m_tableEdit->setCurrentRow( -1 );
 
536
        emit myCurrentChanged( 0L );
 
537
    }
 
538
    else if ( m_tableView->currentSelection() != -1 )
 
539
    {
 
540
        m_tableEdit->setCurrentRow( m_tableView->currentRow() );
 
541
        if ( m_tableView->sqlCursor()->isValid() )
 
542
            emit myCurrentChanged( m_tableView->sqlCursor() );
 
543
        else
 
544
            emit myCurrentChanged( 0L );
 
545
        calculateFieldsInTree();
 
546
    }
 
547
}
 
548
 
 
549
void DataTable::slotSelectFirstRow()
 
550
{
 
551
    m_tableView->slotSelectFirstRow();
 
552
}
 
553
 
 
554
void DataTable::slotDetailFromMaster( QSqlRecord * record )
 
555
{
 
556
    m_updatesAllowed = false;
 
557
 
 
558
    QString fk = foreignKey();
 
559
    if ( !record )
 
560
        setForeignValue( "-1" );
 
561
    else
 
562
        setForeignValue( record->value( parentKey() ).toString() );
 
563
    setDefaultFilter( foreignKey().append( "='" ).append( foreignValue() ).append( "'" ) );
 
564
    m_tableView->setFilter( defaultFilter().append( searchFilter() ) );
 
565
    m_tableEdit->setFilter( m_tableView->filter() );
 
566
 
 
567
    tableRefresh();
 
568
 
 
569
    m_updatesAllowed = true;
 
570
 
 
571
    slotSelectFirstRow();
 
572
}
 
573
 
 
574
void DataTable::slotFilterToBuffer( QSqlRecord * record )
 
575
{
 
576
    if ( parentName().isEmpty() )
 
577
        return;
 
578
 
 
579
    record->field( foreignKey() )->setValue( foreignValue() );
 
580
}
 
581
 
 
582
int DataTable::scrollTabLeft( int i )
 
583
{
 
584
    //hehe, easy since we only have two pages ;)
 
585
    if ( i == -1 )
 
586
        setCurrentPage( !currentPageIndex() );
 
587
    else
 
588
        setCurrentPage( i );
 
589
    return currentPageIndex();
 
590
}
 
591
 
 
592
int DataTable::scrollTabRight( int i )
 
593
{
 
594
    if ( i == -1 )
 
595
        setCurrentPage( !currentPageIndex() );
 
596
    else
 
597
        setCurrentPage( i );
 
598
    return currentPageIndex();
 
599
}
 
600
 
 
601
void DataTable::firstRecord()
 
602
{
 
603
    if ( relationToParent() == DataTable::ManyToOne ||
 
604
         relationToParent() == DataTable::OneToOne )
 
605
        m_project->dataTableByName( parentName() )->firstRecord();
 
606
    else
 
607
        m_tableEdit->first();
 
608
}
 
609
 
 
610
void DataTable::previousRecord()
 
611
{
 
612
    if ( relationToParent() == DataTable::ManyToOne ||
 
613
         relationToParent() == DataTable::OneToOne )
 
614
        m_project->dataTableByName( parentName() )->previousRecord();
 
615
    else
 
616
        m_tableEdit->prev();
 
617
}
 
618
 
 
619
void DataTable::nextRecord()
 
620
{
 
621
    if ( relationToParent() == DataTable::ManyToOne ||
 
622
         relationToParent() == DataTable::OneToOne )
 
623
        m_project->dataTableByName( parentName() )->nextRecord();
 
624
    else
 
625
        m_tableEdit->next();
 
626
}
 
627
 
 
628
void DataTable::lastRecord()
 
629
{
 
630
    if ( relationToParent() == DataTable::ManyToOne ||
 
631
         relationToParent() == DataTable::OneToOne )
 
632
        m_project->dataTableByName( parentName() )->lastRecord();
 
633
    else
 
634
        m_tableEdit->last();
 
635
}
 
636
 
 
637
void DataTable::commit()
 
638
{
 
639
    m_tableEdit->update();
 
640
}
 
641
 
 
642
void DataTable::insertRecord()
 
643
{
 
644
    if ( !m_tableEdit->insertRecord() )
 
645
        return;
 
646
 
 
647
    m_tableView->insertRows( m_tableView->numRows() );
 
648
    m_tableView->slotSelectRow( m_tableView->numRows() - 1, false );
 
649
    scrollTabRight();
 
650
    emit tableRefreshed(); //Perhaps a new signal eventually
 
651
}
 
652
 
 
653
void DataTable::changeRecord()
 
654
{
 
655
    m_tableView->setFilter( "" );
 
656
    m_tableEdit->setFilter( m_tableView->filter() );
 
657
    m_tableView->setSelectionColor( Qt::yellow );
 
658
    m_tableView->setSelectionMode( DataTableView::MouseOver );
 
659
    tableRefresh();
 
660
}
 
661
 
 
662
void DataTable::associateRecord()
 
663
{
 
664
    m_tableView->setSelectionColor( Qt::green );
 
665
    m_tableView->setSelectionMode( DataTableView::Default );
 
666
    emit childValueChanged( parentKey(), m_tableView->sqlCursor()->value( foreignKey() ) );
 
667
}
 
668
 
 
669
void DataTable::slotValueFromChild( const QString &key, const QVariant &value )
 
670
{
 
671
    m_tableEdit->sqlCursor()->editBuffer()->setValue( key, value );
 
672
    m_tableEdit->sqlCursor()->update();
 
673
    tableRefresh();
 
674
    m_tableView->slotSelectRow( m_tableView->currentRow() );
 
675
}
 
676
 
 
677
void DataTable::deleteRecord()
 
678
{
 
679
    if ( !m_tableEdit->deleteRecord() )
 
680
    {
 
681
        //The cursor is invalidated during the attempt to delete
 
682
        tableRefresh();
 
683
        return;
 
684
    }
 
685
 
 
686
    m_tableView->removeRow( m_tableView->currentRow() );
 
687
    m_tableView->slotSelectRow(  m_tableView->currentRow() );
 
688
    emit tableRefreshed(); //Perhaps a new signal eventually
 
689
}
 
690
 
 
691
void DataTable::deleteAbortedInsert()
 
692
{
 
693
    m_tableView->removeRow( m_tableView->numRows() - 1 );
 
694
    emit tableRefreshed(); //Perhaps a new signal eventually
 
695
}
 
696
 
 
697
void DataTable::configureDataField( DataField *field  )
 
698
{
 
699
    FieldEditorDialog dialog( field, this, true, this );
 
700
    dialog.exec();
 
701
}
 
702
 
 
703
QString DataTable::uniqueDataFieldName( const QString &suggest )
 
704
{
 
705
    if ( suggest.isEmpty() )
 
706
        return uniqueDataFieldName();
 
707
 
 
708
    if ( !dataField( suggest ) )
 
709
        return suggest;
 
710
 
 
711
    QString base = suggest;
 
712
    base.remove( QRegExp( "\\s\\([0-9]+\\)$" ) );
 
713
 
 
714
    int count = 1;
 
715
    QString s = QString( "%1 (%2)" ).arg( base ).arg( count );
 
716
 
 
717
    while ( dataField( s ) )
 
718
    {
 
719
        count++;
 
720
        s = QString( "%1 (%2)" ).arg( base ).arg( count );
 
721
    }
 
722
 
 
723
    return s;
 
724
}
 
725
 
 
726
DataFieldList DataTable::calculatedFields()
 
727
{
 
728
    DataFieldList list;
 
729
    DataFieldList::iterator it = m_fieldList.begin();
 
730
    for ( ; it != m_fieldList.end(); ++it )
 
731
        if ( ( *it )->isVirtual() )
 
732
            list.append( ( *it ) );
 
733
    return list;
 
734
}
 
735
 
 
736
DataRecordList DataTable::recordsInTree()
 
737
{
 
738
    DataRecordList records;
 
739
    DataTableList tables = m_project->dataTablesInDataTableTree( this );
 
740
    for ( DataTableList::Iterator it = tables.begin(); it != tables.end(); ++it )
 
741
        records[ ( *it )->alias() ] = ( *it )->dataTableEdit()->sqlCursor()->editBuffer();
 
742
    return records;
 
743
}
 
744
 
 
745
void DataTable::calculateFieldsInTree()
 
746
{
 
747
    DataTableList tables = m_project->childrenOfDataTable( this );
 
748
    for ( DataTableList::Iterator it = tables.begin(); it != tables.end(); ++it )
 
749
        ( *it )->dataTableEdit()->calculateFields();
 
750
}
 
751
 
 
752
void DataTable::addVirtualField()
 
753
{
 
754
    QString name = uniqueDataFieldName( i18n("Virtual Field") );
 
755
    addDataField(
 
756
        name,                           //name
 
757
        QVariant::Invalid,              //type
 
758
        false,                          //required
 
759
        true,                           //calculated
 
760
        true,                           //virtual
 
761
        QString::null,                  //equation
 
762
        name,                           //label
 
763
        -1,                             //number
 
764
        -1,                             //width
 
765
        false,                          //foreign
 
766
        false,                          //primary
 
767
        false,                          //hidden
 
768
        false,                          //resizable
 
769
        false                           //sortable
 
770
    );
 
771
 
 
772
    FieldEditorDialog dialog( dataField(name), this, false, this );
 
773
    dialog.exec();
 
774
}
 
775
 
 
776
void DataTable::setup()
 
777
{
 
778
    setFocusPolicy( QWidget::ClickFocus );
 
779
    addTab( m_tableView, i18n( "View Table" ) );
 
780
    addTab( m_tableEdit, SmallIconSet( "edit" ), i18n( "Edit Record" ) );
 
781
    QObject::connect( m_tableView, SIGNAL( selectionChanged() ),
 
782
                      this, SLOT( slotUpdate() ) );
 
783
    QObject::connect( m_tableEdit, SIGNAL( primeInsert( QSqlRecord * ) ),
 
784
                      this, SLOT( slotFilterToBuffer( QSqlRecord * ) ) );
 
785
    QObject::connect( m_tableEdit, SIGNAL( insertAborted() ),
 
786
                      this, SLOT( deleteAbortedInsert() ) );
 
787
    QObject::connect( m_tableEdit, SIGNAL( selectedFirst( bool ) ),
 
788
                      m_tableView, SLOT( slotSelectFirstRow( bool ) ) );
 
789
    QObject::connect( m_tableEdit, SIGNAL( selectedPrev( bool ) ),
 
790
                      m_tableView, SLOT( slotSelectPrevRow( bool ) ) );
 
791
    QObject::connect( m_tableEdit, SIGNAL( selectedNext( bool ) ),
 
792
                      m_tableView, SLOT( slotSelectNextRow( bool ) ) );
 
793
    QObject::connect( m_tableEdit, SIGNAL( selectedLast( bool ) ),
 
794
                      m_tableView, SLOT( slotSelectLastRow( bool ) ) );
 
795
    QObject::connect( m_tableEdit, SIGNAL( selectedRow( int, bool ) ),
 
796
                      m_tableView, SLOT( slotSelectRow( int, bool ) ) );
 
797
    QObject::connect( m_tableEdit, SIGNAL( colorBoxChanged( const QColor & ) ),
 
798
                      m_tableView, SLOT( setSelectionColor( const QColor & ) ) );
 
799
    m_propMap->insert( "DataLineEdit", "value" );
 
800
    m_propMap->insert( "RelationCombo", "relationid" );
 
801
    m_propMap->insert( "DateEdit", "date" );
 
802
    m_propMap->insert( "TimeEdit", "time" );
 
803
    m_propMap->insert( "DateTimeEdit", "datetime" );
 
804
    m_tableView->installPropertyMap( m_propMap );
 
805
    m_tableEdit->installPropertyMap( m_propMap );
 
806
    m_tableView->installEditorFactory( m_factory );
 
807
}
 
808
 
 
809
bool processEvents()
 
810
{
 
811
    static QTime time = QTime::currentTime();
 
812
 
 
813
    if ( time.elapsed() > 200 )
 
814
    {
 
815
        time.restart();
 
816
        kapp->processEvents();
 
817
        return true;
 
818
    }
 
819
    return false;
 
820
}
 
821
 
 
822
#include "datatable.moc"