kchart

kchartDataEditor.cc

00001 #include <qcheckbox.h>
00002 #include <qlabel.h>
00003 #include <qspinbox.h>
00004 #include <qlayout.h>
00005 #include <qlineedit.h>
00006 #include <qregexp.h>
00007 #include <qwhatsthis.h>
00008 #include <qtooltip.h>
00009 #include <qvalidator.h>
00010 #include <qpushbutton.h>
00011 
00012 #include <kinputdialog.h>
00013 #include <klocale.h>
00014 #include <kdebug.h>
00015 #include <kmessagebox.h>
00016 #include <kiconloader.h>
00017 
00018 #include "kdchart/KDChartAxisParams.h"
00019 #include "kchart_params.h"
00020 #include "kchart_factory.h"
00021 
00022 #include "kchartDataEditor.h"
00023 #include "kchartDataEditor.moc"
00024 
00025 namespace KChart
00026 {
00027 
00028 
00029 // ================================================================
00030 //                    Class kchartDataSpinBox
00031 
00032 
00033 // We don't provide very much generality, since this spinbox is used
00034 // here and here only.
00035 //
00036 kchartDataSpinBox::kchartDataSpinBox(QWidget *parent)
00037     : QSpinBox(parent)
00038 {
00039     m_ignore = false;
00040 }
00041 
00042 
00043 kchartDataSpinBox::~kchartDataSpinBox()
00044 {
00045 }
00046 
00047 
00048 void kchartDataSpinBox::stepUp()
00049 {
00050     m_ignore = true;
00051     uint const new_value = value() + 1;
00052 
00053     QSpinBox::stepUp();
00054     setValue(new_value);
00055 
00056     emit valueChangedSpecial( value() );
00057     m_ignore = false;
00058 }
00059 
00060 
00061 void kchartDataSpinBox::stepDown()
00062 {
00063     m_ignore = true;
00064 
00065     uint const new_value = value() - 1;
00066     QSpinBox::stepDown();
00067     setValue(new_value);
00068 
00069     emit valueChangedSpecial( value() );
00070     m_ignore = false;
00071 }
00072 
00073 
00074 bool kchartDataSpinBox::eventFilter( QObject *obj, QEvent *ev )
00075 {
00076     if ( obj == editor() ) {
00077         if ( ev->type() == QEvent::FocusOut ) {
00078             //kdDebug() << "Focus out" << endl;
00079             setValue(editor()->text().toInt());
00080 
00081             // Don't emit valueChangedSpecial(int) twice when
00082             // stepUp/stepDown has been called
00083             if (!m_ignore)
00084                 emit valueChangedSpecial( value() );
00085         }
00086     }
00087  
00088     // Pass the event on to the parent class.
00089     return QSpinBox::eventFilter( obj, ev );
00090 }
00091 
00092 
00093 // ================================================================
00094 //                    Class kchartDataTable
00095 
00096 
00097 // Used for the keyboard navigation
00098 //
00099 kchartDataTable::kchartDataTable(QWidget *parent)
00100     : QTable(parent)
00101 {
00102 }
00103 
00104 
00105 kchartDataTable::~kchartDataTable()
00106 {
00107 }
00108 
00109 
00110 bool kchartDataTable::eventFilter( QObject *obj, QEvent *ev )
00111 {
00112     if (ev->type() == QEvent::KeyPress && strcmp(obj->name(), 
00113                          "qt_tableeditor")==0 ) {
00114         QKeyEvent *e = (QKeyEvent *)ev;
00115 
00116         switch ( e->key() ) {
00117             case Qt::Key_Up:
00118             {
00119                 if ( currentRow() > 0 ) {
00120                     setCurrentCell( currentRow()-1, currentColumn() );
00121                     editCell(currentRow(), currentColumn() );
00122                     return true;
00123                 }
00124                 break;
00125             }
00126             case Qt::Key_Down: 
00127         {
00128                 if ( currentRow() < numRows()-1 ) {
00129                     setCurrentCell( currentRow()+1, currentColumn() );
00130                     editCell(currentRow(), currentColumn() );
00131                     return true;
00132                 }
00133                 break;
00134             }
00135             case Qt::Key_Right: 
00136         {
00137                 if ( currentColumn() < numCols()-1 ) {
00138                     setCurrentCell( currentRow(), currentColumn()+1 );
00139                     editCell(currentRow(), currentColumn() );
00140                     return true;
00141                 }
00142                 break;
00143             }
00144             case Qt::Key_Left:
00145             {
00146                 if ( currentColumn() > 0 ) {
00147                     setCurrentCell( currentRow(), currentColumn()-1 );
00148                     editCell(currentRow(), currentColumn() );
00149                     return true;
00150                 }
00151                 break;
00152             }
00153         }
00154     }
00155 
00156     return QTable::eventFilter( obj, ev );
00157 }
00158 
00159 
00160 // ================================================================
00161 //                    Class kchartDataEditor
00162 
00163 
00164 #define COLUMNWIDTH  80
00165 
00166 kchartDataEditor::kchartDataEditor(QWidget* parent) :
00167     KDialogBase(parent, "dataeditor", true, i18n("KChart Data Editor"), 
00168         KDialogBase::Ok | KDialogBase::Cancel | KDialogBase::Apply,
00169         KDialogBase::Ok, true)
00170 {
00171     QWidget      *page = new QWidget( this );
00172     setMainWidget(page);
00173 
00174     // Create the main table.
00175     m_table = new kchartDataTable(page);
00176     m_table->setSelectionMode(QTable::NoSelection);
00177     m_table->setFocus();
00178     m_table->setRowMovingEnabled(true);
00179     m_table->setColumnMovingEnabled(true);
00180 
00181     connect( m_table, SIGNAL( currentChanged(int, int) ),
00182          this,    SLOT( currentChanged(int, int) ) );
00183   
00184     // Create the Rows setting
00185     m_rowsLA = new QLabel( i18n("# Rows:" ), page );
00186     m_rowsLA->resize( m_rowsLA->sizeHint() );
00187     m_rowsSB = new kchartDataSpinBox( page );
00188     m_rowsSB->resize( m_rowsSB->sizeHint() );
00189     m_rowsSB->setMinValue(1);
00190 
00191     // Create the columns setting
00192     m_colsLA = new QLabel( i18n("# Columns:" ), page );
00193     m_colsLA->resize( m_colsLA->sizeHint() );
00194     m_colsSB = new kchartDataSpinBox( page );
00195     m_colsSB->resize( m_colsSB->sizeHint() );
00196     m_colsSB->setMinValue(1);
00197     
00198 #if 0
00199     // The row/column as label checkboxes. 
00200     m_firstRowAsLabel = new QCheckBox( i18n( "First row as label" ), page);
00201     m_firstColAsLabel = new QCheckBox( i18n( "First column as label" ), page);
00202 #endif
00203 
00204     // Buttons for Inserting / Removing rows & columns 
00205     // The icon images are taken from the standard 
00206     m_insertRowButton = new QPushButton( page);
00207     // In 2.0; this is supposed to be just KIcon("name").pixmap(32).
00208     m_insertRowButton->setPixmap( BarIcon( QString("insert_table_row"),
00209                        KIcon::SizeMedium,
00210                        KIcon::DefaultState,
00211                        KChartFactory::global() ) );
00212     //m_insertRowButton = new QPushButton( i18n("Insert Row") , page);
00213     connect( m_insertRowButton, SIGNAL( clicked() ),
00214          this,              SLOT( insertRow() ) );
00215     
00216     m_removeRowButton = new QPushButton( page );
00217     m_removeRowButton->setPixmap( BarIcon( QString("delete_table_row"),
00218                        KIcon::SizeMedium,
00219                        KIcon::DefaultState,
00220                        KChartFactory::global() ) );
00221     //m_removeRowButton = new QPushButton( i18n("Remove Row") , page);
00222     connect( m_removeRowButton, SIGNAL( clicked() ),
00223          this,              SLOT( removeCurrentRow() ) );
00224     
00225     m_insertColButton = new QPushButton( page );
00226     m_insertColButton->setPixmap( BarIcon( QString("insert_table_col"),
00227                        KIcon::SizeMedium,
00228                        KIcon::DefaultState,
00229                        KChartFactory::global() ) );
00230     //m_insertColButton = new QPushButton( i18n("Insert Column") , page);
00231     connect( m_insertColButton, SIGNAL( clicked() ),
00232          this,              SLOT( insertColumn() ) );
00233     
00234     m_removeColButton = new QPushButton( page );
00235     m_removeColButton->setPixmap( BarIcon( QString("delete_table_col"),
00236                        KIcon::SizeMedium,
00237                        KIcon::DefaultState,
00238                        KChartFactory::global() ) );
00239     //m_removeColButton = new QPushButton( i18n("Remove Column") , page);
00240     connect( m_removeColButton, SIGNAL( clicked() ),
00241          this,              SLOT( removeCurrentColumn() ) );
00242 
00243     // Start the layout.  The buttons are at the top.
00244     QVBoxLayout  *topLayout = new QVBoxLayout( page );
00245     
00246     QHBoxLayout* insertRemoveLayout = new QHBoxLayout( );
00247    
00248     insertRemoveLayout->setSpacing(5);
00249     insertRemoveLayout->addWidget(m_insertRowButton);
00250     insertRemoveLayout->addWidget(m_removeRowButton);
00251     insertRemoveLayout->addWidget(m_insertColButton);
00252     insertRemoveLayout->addWidget(m_removeColButton);
00253     insertRemoveLayout->addStretch(1);
00254     
00255     topLayout->addLayout(insertRemoveLayout);
00256     topLayout->addSpacing(10);
00257     
00258     // The table is below the buttons.
00259     topLayout->addWidget(m_table);
00260 
00261     // Then, a horizontal layer with the rows and columns settings
00262     QHBoxLayout  *hbl1 = new QHBoxLayout(  );
00263     hbl1->addWidget(m_rowsLA);
00264     hbl1->addWidget(m_rowsSB);
00265     hbl1->addSpacing(20);
00266     hbl1->addWidget(m_colsLA);
00267     hbl1->addWidget(m_colsSB);
00268     hbl1->addStretch(1);
00269     hbl1->setMargin(10);
00270     topLayout->addLayout(hbl1);
00271 
00272 #if 0
00273     // Last, the checkboxes with "First row/column as label"
00274     QHBoxLayout  *hbl2 = new QHBoxLayout(  );
00275     hbl2->addWidget(m_firstRowAsLabel);
00276     hbl2->addWidget(m_firstColAsLabel);
00277     hbl2->addStretch(1);
00278     hbl2->setMargin(10);
00279     topLayout->addLayout(hbl2);
00280 #endif
00281 
00282     topLayout->setStretchFactor(m_table, 1);
00283     topLayout->setStretchFactor(insertRemoveLayout,1);
00284 
00285     // Connect signals from the spin boxes.
00286     connect(m_rowsSB, SIGNAL(valueChangedSpecial(int)), 
00287         this,     SLOT(setRows(int)));
00288     connect(m_colsSB, SIGNAL(valueChangedSpecial(int)), 
00289         this,     SLOT(setCols(int)));
00290 
00291     
00292 #if 0
00293     // -- Changed data editor to use top row and leftmost column for
00294     //    series names and labels so this is no longer necessary.
00295 
00296     connect(m_table->horizontalHeader(), SIGNAL(clicked(int)), 
00297         this,                        SLOT(column_clicked(int)) );
00298     connect(m_table->verticalHeader(),   SIGNAL(clicked(int)),
00299         this,                        SLOT(row_clicked(int)) );
00300 #endif
00301   
00302     connect(m_table, SIGNAL(valueChanged(int, int)),
00303         this,    SLOT(tableChanged(int, int)) );
00304 
00305     // At first, assume that any shrinking of the table is a mistake.
00306     // A confirmation dialog will make sure that the user knows what
00307     // (s)he is doing.
00308     m_userWantsToShrink = false;
00309 
00310     // The data is not modified at the start.
00311     m_modified          = false;
00312 
00313     // If the cursor starts at cell (0, 0), that is the header row and
00314     // col, and the user isn't allowed to remove those.
00315     m_removeRowButton->setEnabled( false );
00316     m_removeColButton->setEnabled( false );
00317 
00318     // Add tooltips and WhatsThis help.
00319     addDocs();
00320 }
00321 
00322 
00323 // Add Tooltips and WhatsThis help to various parts of the Data Editor.
00324 //
00325 void kchartDataEditor::addDocs()
00326 {
00327     // The rows settings.
00328     QString rowwhatsthis = i18n("<p><b>Sets the number of rows in the data table."
00329                 "</b><br><br>Each row represents one data set.</p>");
00330     QToolTip::add(m_rowsSB, i18n("Number of active data rows"));
00331     QWhatsThis::add(m_rowsLA, rowwhatsthis);
00332     QWhatsThis::add(m_rowsSB, rowwhatsthis);
00333 
00334     // The columns settings.
00335     QString colwhatsthis = i18n("<p><b>Sets the number of columns in the data table."
00336                 "</b><br><br>The number of columns defines the number of data values in each data set (row).</p>");
00337     QToolTip::add(m_colsSB, i18n("Number of active data columns"));
00338     QWhatsThis::add(m_colsLA, colwhatsthis);
00339     QWhatsThis::add(m_colsSB, colwhatsthis);
00340 
00341     // The table.
00342     QToolTip::add(m_table, i18n("Chart data table."));
00343     
00344     //GUI
00345     //The QWhatsThis information below is incorrect since the way that the contents of the table
00346     //are displayed in the chart depends upon the data format selected (which can be 
00347     //either "Data in columns" (default) or "Data in rows)
00348     //The names of the data sets / axes labels are no longer set by clicking on the table 
00349     //headers - since that was slow to work with and did not allow for keyboard input. 
00350     //Instead the names are taken from the topmost row and leftmost column.  
00351     //
00352     //eg:       Month | Sales 
00353     //          Jan   | 105
00354     //          Feb   | 117
00355     //          March | 120
00356     //
00357     //The captions of the header are automatically set to the names of the cells in the topmost row
00358     //and leftmost column.  This means that if you have more data than will fit in the visible area,
00359     //you can still see the column names or row names when the table has been scrolled.
00360     //KSpread could use some functionality like this as well.
00361     
00362     
00363 #if 0
00364     QWhatsThis::add(m_table, i18n("<p>This table contains the data"
00365     " for the chart.<br><br> Each row is one data set of values."
00366     " The name of such a data set can be changed in the column header (on the left)"
00367     " of the table. In a line diagram each row is one line. In a ring diagram each row"
00368     " is one slice. <br><br> Each column represents one value of each data set."
00369     " Just like rows you can also change the name of each value in the"
00370     " column headers (at the top) of the table.  In a bar diagram the number"
00371     " of columns defines the number of value sets.  In a ring diagram each"
00372     " column is one ring.</p>"));
00373 #endif
00374 
00375     QToolTip::add( m_insertRowButton, i18n("Insert row") );
00376     QToolTip::add( m_removeRowButton, i18n("Delete row") );
00377     QToolTip::add( m_insertColButton, i18n("Insert column") );
00378     QToolTip::add( m_removeColButton, i18n("Delete column") );
00379 }
00380 
00381 
00382 // Set the data in the data editor.
00383 //
00384 // The data is taken from the KDChart data.  This method is never
00385 // called when the chart is a part of a spreadsheet.
00386 //
00387 void kchartDataEditor::setData( KChartParams *params, KDChartTableData *dat )
00388 {
00389     unsigned int  rowsCount;
00390     unsigned int  colsCount;
00391 
00392     // Get the correct number of rows and columns.
00393     if ( dat->usedRows() == 0 && dat->usedCols() == 0) { // Data from KSpread
00394         rowsCount = dat->rows();
00395         colsCount = dat->cols();
00396     }
00397     else {
00398         rowsCount = dat->usedRows();
00399         colsCount = dat->usedCols();
00400     }
00401 
00402     // Empty table
00403     if ( rowsCount==0 && colsCount==0 ) {
00404     m_table->setNumRows(1);
00405     m_table->setNumCols(1);
00406     resize(600, 300);
00407     return;
00408     }
00409 
00410     rowsCount += headerRows();
00411     colsCount += headerCols();
00412 
00413     // Initiate widgets with the correct rows and columns.
00414     m_rowsSB->setValue(rowsCount);
00415     m_colsSB->setValue(colsCount);
00416 #if 0
00417     m_firstRowAsLabel->setChecked( params->firstRowAsLabel() );
00418     m_firstColAsLabel->setChecked( params->firstColAsLabel() );
00419 #endif
00420 
00421     // Fill the data from the chart into the editor.
00422     m_table->setNumRows(rowsCount);
00423     m_table->setNumCols(colsCount);
00424     for (unsigned int row = headerRows(); row < rowsCount; row++) {
00425         for (unsigned int col = headerCols(); col < colsCount; col++) {
00426             QVariant t = dat->cellVal(row-headerRows(), col-headerCols());
00427 
00428             // Fill it in from the part.
00429             if (t.isValid()) {
00430                 if ( t.type() == QVariant::Double ) {
00431             m_table->setText(row, col, 
00432                      QString("%1").arg(t.toDouble()));
00433         }
00434                 else if ( t.type() == QVariant::String )
00435                     kdDebug(35001) << "I cannot handle strings in the table yet"
00436                                    << endl;
00437                 else {
00438                     // nothing on purpose
00439                 }
00440             }
00441         }
00442     }
00443 
00444     // Set column widths.  The default is a little too wide.
00445     for (unsigned int col = 0; col < colsCount + 1; col++) 
00446     m_table->setColumnWidth(col, COLUMNWIDTH);
00447 
00448     // and resize the widget to a good size.
00449     resize(600, 300);
00450 }
00451 
00452 
00453 // Get the data from the data editor and put it back into the chart.
00454 //
00455 void kchartDataEditor::getData( KChartParams *params, KDChartTableData *dat )
00456 {   
00457     //Number of rows used as headers
00458     int labelRows = headerRows();
00459     //Number of columns used as headers 
00460     int labelCols = headerCols();
00461     
00462     int  numRows = m_table->numRows()-labelRows;
00463     int  numCols = m_table->numCols()-labelCols;
00464     
00465     // Make sure that the data table for the chart is not smaller than
00466     // the data in the editor.
00467     if ( static_cast<int>( dat->rows() ) < numRows
00468     || static_cast<int>( dat->cols() ) < numCols )
00469     dat->expand( numRows, numCols );
00470 
00471     dat->setUsedRows( numRows );
00472     dat->setUsedCols( numCols );
00473 
00474     // Empty table
00475 #if 0
00476     if ( numRows==1 && numCols==1 && m_table->horizontalHeader()->label(0).isEmpty()
00477             && m_table->verticalHeader()->label(0).isEmpty()
00478             && m_table->text(0, 0).isEmpty() ) {
00479         dat->expand(0,0);
00480         return;
00481     }
00482 #endif
00483 
00484     // Get all the data.
00485     for (int row = labelRows ; row < (numRows+labelRows); row++) {
00486         for (int col = labelCols ; col < (numCols+labelCols); col++) {
00487 
00488             // Get the text and convert to double.
00489             QString tmp = m_table->text(row, col);
00490             bool   bOk;
00491             double val = tmp.toDouble( &bOk );
00492             if (!bOk)
00493               val = 0.0;
00494             // and do the actual setting.
00495             //t = KoChart::Value( val );
00496             dat->setCell(row-labelRows,col-labelCols, val);
00497         }
00498     }
00499 
00500 #if 0
00501     params->setFirstRowAsLabel( m_firstRowAsLabel->isChecked() );
00502     params->setFirstColAsLabel( m_firstColAsLabel->isChecked() );
00503 #endif
00504 }
00505 
00506 
00507 // Set the row labels in the data editor.
00508 //
00509 void kchartDataEditor::setRowLabels(const QStringList &rowLabels)
00510 {
00511 #if 0
00512     QHeader  *rowHeader = m_table->verticalHeader();
00513     int       row;
00514     int       numRows = m_rowsSB->value();
00515 
00516     rowHeader->setLabel(0, "");
00517     if ( numRows==1 && m_colsSB->value()==1 && m_table->text(0, 0).isEmpty() )
00518         return;
00519     for (row = 0; row < numRows; row++) {
00520     rowHeader->setLabel(row, rowLabels[row]);
00521     }
00522 #endif
00523 
00524     for (unsigned int i=0; i < rowLabels.count(); i++) {
00525         m_table->setText(i + headerRows(), 0, rowLabels[i]);    
00526     }
00527     
00528     updateRowHeaders();
00529 }
00530 
00531 
00532 int kchartDataEditor::headerRows()
00533 {
00534     return 1;
00535 }
00536 
00537 int kchartDataEditor::headerCols()
00538 {
00539     return 1;
00540 }
00541 
00542 
00543 // Get the row labels from the data editor.
00544 //
00545 void kchartDataEditor::getRowLabels(QStringList &rowLabels)
00546 {
00547 #if 0
00548     QHeader  *rowHeader = m_table->verticalHeader();
00549     int  numRows = m_rowsSB->value();
00550     int  row;
00551 
00552     rowLabels.clear();
00553     for (row = 0; row < numRows; row++) {
00554       rowLabels << rowHeader->label(row);
00555     }
00556 #endif
00557     rowLabels.clear();
00558 
00559     for (int i=headerRows();i < m_table->numRows();i++)
00560     {
00561         rowLabels << m_table->text(i,0);
00562     }
00563 }
00564 
00565 
00566 // Set the column labels in the data editor.
00567 //
00568 void kchartDataEditor::setColLabels(const QStringList &colLabels)
00569 {
00570 #if 0
00571     QHeader  *colHeader = m_table->horizontalHeader();
00572     int       col;
00573 
00574     int  numCols = m_colsSB->value();
00575 
00576     colHeader->setLabel(0, "");
00577     if ( m_rowsSB->value()==1 && numCols==1 && m_table->text(0, 0).isEmpty() )
00578         return;
00579     for (col = 0; col < numCols; col++) {
00580     colHeader->setLabel(col, colLabels[col]);
00581     }
00582 #endif
00583 
00584     for (unsigned int i = 0; i < colLabels.count(); i++)
00585     {
00586         m_table->setText(0,i+headerCols(),colLabels[i]);
00587     }
00588     
00589     updateColHeaders();
00590 }
00591 
00592 
00593 // Get the column labels from the data editor.
00594 //
00595 void kchartDataEditor::getColLabels(QStringList &colLabels)
00596 {
00597 #if 0
00598     QHeader  *colHeader = m_table->horizontalHeader();
00599     int  numCols = m_colsSB->value();
00600     int  col;
00601 
00602     colLabels.clear();
00603     for (col = 0; col < numCols; col++) {
00604     colLabels << colHeader->label(col);
00605     }
00606 #endif
00607     
00608     colLabels.clear();
00609 
00610     for (int i = headerCols(); i < m_table->numCols(); i++) {
00611         colLabels << m_table->text(0, i); 
00612     }
00613 }
00614 
00615 
00616 // ================================================================
00617 //                              Slots
00618 
00619 
00620 // Slots for the buttons that insert/remove rows/columns.
00621 //
00622 
00623 void kchartDataEditor::removeCurrentRow()
00624 {
00625     int  row = m_table->currentRow();
00626     
00627     // Can't remove the header row.
00628     if ( row == 0 )
00629     return;
00630 
00631     // Need at least one data row.
00632     if ( m_table->numRows() == 2 )
00633     return;
00634 
00635     m_table->removeRow(row);
00636     m_rowsSB->setValue(m_table->numRows());
00637     
00638     m_modified = true;
00639 }
00640 
00641 void kchartDataEditor::removeCurrentColumn()
00642 {
00643     int  col = m_table->currentColumn();
00644     
00645     // Can't remove the header column.
00646     if ( col == 0 )
00647     return;
00648 
00649     // Need at least one data column.
00650     if ( m_table->numCols() == 2 )
00651     return;
00652 
00653     m_table->removeColumn(col);
00654     m_colsSB->setValue(m_table->numCols());
00655     
00656     m_modified = true;
00657 }
00658 
00659 void kchartDataEditor::insertColumn()
00660 {
00661     m_table->insertColumns(m_table->currentColumn() + 1, 1);
00662     m_colsSB->setValue(m_table->numCols());
00663     updateColHeaders();
00664 
00665     m_modified = true;
00666 }
00667 
00668 void kchartDataEditor::insertRow()
00669 {
00670     m_table->insertRows(m_table->currentRow() + 1, 1);
00671     m_rowsSB->setValue(m_table->numRows());
00672     updateRowHeaders();
00673 
00674     m_modified = true;
00675 }    
00676 
00677 
00678 // Ask user to make sure that (s)he really wants to remove a row or
00679 // column.
00680 //
00681 static int askUserForConfirmation(QWidget *parent)
00682 {
00683     return KMessageBox::warningContinueCancel(parent,
00684         i18n("You are about to shrink the data table and remove some values. "
00685          "This will lead to loss of existing data in the table "
00686          "and/or the headers.\n\n"
00687          "This message will not be shown again if you click Continue"));
00688 }
00689 
00690 
00691 // This slot is called when the spinbox for rows is changed.
00692 //
00693 void kchartDataEditor::setRows(int rows)
00694 {
00695     kdDebug(35001) << "setRows called: rows = " << rows << endl;;
00696 
00697     // Sanity check.  This should never happen since the spinbox has a
00698     // minvalue of 1, but just to be sure...
00699     if (rows < 1) {
00700     m_rowsSB->setValue(1);
00701     return;
00702     }
00703 
00704     int old_rows = m_table->numRows();
00705     if (rows > old_rows) {
00706     m_table->setNumRows(rows);
00707 
00708     // Default value for the new rows: empty string
00709     for (int i = old_rows; i < rows; i++)
00710         m_table->verticalHeader()->setLabel(i, "");
00711 
00712     m_modified = true;
00713     }
00714     else if (rows < m_table->numRows()) {
00715     bool ask_user = false;
00716 
00717     // Check if the last row is empty.
00718     for (int col=0; col<m_table->numCols(); col++) {
00719         if (!m_table->text(rows, col).isEmpty()) {
00720         ask_user = true;
00721         break;
00722         }
00723     }
00724 
00725     // If it is not, ask if the user really wants to shrink the table.
00726     if ( ask_user && !m_userWantsToShrink
00727         && askUserForConfirmation(this) == KMessageBox::Cancel) {
00728 
00729         // The user aborts.  Reset the number of rows and return.
00730         m_rowsSB->setValue(m_table->numRows());
00731         return;
00732     }
00733 
00734     // Record the fact that the user knows what (s)he is doing.
00735     if (ask_user)
00736         m_userWantsToShrink = true;
00737 
00738     // Do the actual shrinking.
00739     m_table->setNumRows(rows);
00740 
00741     m_modified = true;
00742     }
00743 }
00744 
00745 
00746 // This slot is called when the spinbox for columns is changed.
00747 //
00748 void kchartDataEditor::setCols(int cols)
00749 {
00750     kdDebug(35001) << "setCols called: cols = " << cols << endl;;
00751 
00752     // Sanity check.  This should never happen since the spinbox has a
00753     // minvalue of 1, but just to be sure...
00754     if (cols < 1) {
00755     m_colsSB->setValue(1);
00756     return;
00757     }
00758     
00759     int  old_cols = m_table->numCols();
00760     if (cols > old_cols) {
00761     m_table->setNumCols(cols);
00762 
00763     // Default value for the new columns: empty string.
00764     for (int i = old_cols; i < cols; i++) {
00765         m_table->horizontalHeader()->setLabel(i, "");
00766         m_table->setColumnWidth(i, COLUMNWIDTH);
00767     }
00768 
00769     m_modified = true;
00770     }
00771     else if (cols < m_table->numCols()) {
00772     bool ask_user = false;
00773 
00774     // Check if the last column is empty.
00775     for (int row=0; row<m_table->numRows(); row++) {
00776         if (!m_table->text(row, cols).isEmpty()) {
00777         ask_user = true;
00778         break;
00779         }
00780     }
00781 
00782     // If it is not, ask if the user really wants to shrink the table.
00783     if (ask_user && !m_userWantsToShrink
00784         && askUserForConfirmation(this) == KMessageBox::Cancel) {
00785 
00786         // The user aborts.  Reset the number of rows and return.
00787         m_colsSB->setValue(m_table->numCols());
00788         return;
00789     }
00790 
00791     // Record the fact that the user knows what (s)he is doing.
00792     if (ask_user)
00793         m_userWantsToShrink = true;
00794 
00795     // Do the actual shrinking.
00796     m_table->setNumCols(cols);
00797 
00798     m_modified = true;
00799     }
00800 }
00801 
00802 
00803 // Get the new name for a column header.
00804 //
00805 #if 0   // Disabled since the first row / column now contains the labels.
00806 void kchartDataEditor::column_clicked(int column)
00807 {
00808     bool ok;
00809     QString name = KInputDialog::getText(i18n("Column Name"), 
00810                      i18n("Type a new column name:"), 
00811                      m_table->horizontalHeader()->label(column),
00812                      &ok, this, 0, new QRegExpValidator(QRegExp(".*"), this) );
00813 
00814     // Rename the column.
00815     if ( ok ) {
00816     m_table->horizontalHeader()->setLabel(column, name);
00817     m_modified = true;
00818     }
00819 }
00820 
00821 
00822 // Get the new name for a row header.
00823 //
00824 void kchartDataEditor::row_clicked(int row)
00825 {
00826     bool ok;
00827     QString name = KInputDialog::getText(i18n("Row Name"),
00828                      i18n("Type a new row name:"), 
00829                      m_table->verticalHeader()->label(row),
00830                      &ok, this, 0, new QRegExpValidator(QRegExp(".*"), this) );
00831 
00832     // Rename the row.
00833     if ( ok ) {
00834     m_table->verticalHeader()->setLabel(row, name);
00835     m_modified = true;
00836     }
00837 }
00838 #endif
00839 
00840 
00841 void  kchartDataEditor::tableChanged(int row, int col)
00842 {
00843     if (row <= headerRows())
00844         updateColHeaders();
00845     if (col <= headerCols())
00846         updateRowHeaders();
00847 
00848     m_modified = true;
00849 }
00850 
00851 
00852 void  kchartDataEditor::currentChanged(int row, int col)
00853 {
00854     m_removeRowButton->setEnabled( row != 0 && m_table->numRows() > 2 );
00855     m_removeColButton->setEnabled( col != 0 && m_table->numCols() > 2 );
00856 }
00857 
00858 
00859 void kchartDataEditor::updateRowHeaders()
00860 {
00861     for (int i=0;i<m_table->numRows();i++)
00862     {
00863         QHeader* header=m_table->verticalHeader();
00864         
00865         QString tableCellText=m_table->text(i,0);
00866         
00867         if (tableCellText == QString::null)
00868             tableCellText=QString("");
00869         
00870         header->setLabel(header->mapToSection(i),tableCellText);
00871     }
00872 }
00873 
00874 void kchartDataEditor::updateColHeaders()
00875 {
00876     for (int i=0;i<m_table->numCols();i++)
00877     {
00878         QHeader* header=m_table->horizontalHeader();
00879         
00880         QString tableCellText=m_table->text(0,i);
00881         
00882         if (tableCellText == QString::null)
00883             tableCellText=QString("");
00884             
00885         header->setLabel(header->mapToSection(i),tableCellText);
00886     }
00887 }
00888 
00889 
00890 // This is a reimplementation of a slot defined in KDialogBase.  The
00891 // reason for the reimplementation is that we need to emit the signal
00892 // with a pointer to this so that we can get the data.
00893 //
00894 void kchartDataEditor::slotApply()
00895 {
00896     emit applyClicked(this);
00897 }
00898 
00899 
00900 }  //KChart namespace
KDE Home | KDE Accessibility Home | Description of Access Keys