~ubuntu-branches/ubuntu/breezy/koffice/breezy-security

« back to all changes in this revision

Viewing changes to kspread/kspread_dlg_formula.cc

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2005-10-11 14:49:50 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051011144950-lwpngbifzp8nk0ds
Tags: 1:1.4.1-0ubuntu7
* SECURITY UPDATE: fix heap based buffer overflow in the RTF importer of KWord
* Opening specially crafted RTF files in KWord can cause
  execution of abitrary code.
* Add kubuntu_01_rtfimport_heap_overflow.diff
* References:
  CAN-2005-2971
  CESA-2005-005
  http://www.koffice.org/security/advisory-20051011-1.txt

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* This file is part of the KDE project
2
 
   Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
3
 
   Copyright (C) 1999, 2000,2001  Montel Laurent <lmontel@mandrakesoft.com>
4
 
   This library is free software; you can redistribute it and/or
5
 
   modify it under the terms of the GNU Library General Public
6
 
   License as published by the Free Software Foundation; either
7
 
   version 2 of the License, or (at your option) any later version.
8
 
 
9
 
   This library is distributed in the hope that it will be useful,
10
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 
   Library General Public License for more details.
13
 
 
14
 
   You should have received a copy of the GNU Library General Public License
15
 
   along with this library; see the file COPYING.LIB.  If not, write to
16
 
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
 
   Boston, MA 02111-1307, USA.
18
 
*/
19
 
 
20
 
#include <qtextbrowser.h>
21
 
#include <qtabwidget.h>
22
 
 
23
 
#include "kspread_dlg_formula.h"
24
 
#include "kspread_canvas.h"
25
 
#include "kspread_util.h"
26
 
#include "kspread_editors.h"
27
 
#include "kspread_doc.h"
28
 
#include "kspread_map.h"
29
 
 
30
 
#include <kapplication.h>
31
 
#include <kdebug.h>
32
 
#include <kbuttonbox.h>
33
 
#include <knumvalidator.h>
34
 
#include <qcombobox.h>
35
 
#include <qevent.h>
36
 
#include <qlistbox.h>
37
 
#include <qlabel.h>
38
 
#include <qpushbutton.h>
39
 
#include <klineedit.h>
40
 
#include <qlayout.h>
41
 
 
42
 
KSpreadDlgFormula::KSpreadDlgFormula( KSpreadView* parent, const char* name,const QString& formulaName)
43
 
    : KDialogBase( parent, name,false,i18n("Function"), Ok|Cancel )
44
 
{
45
 
  setWFlags( Qt::WDestructiveClose );
46
 
 
47
 
    m_pView = parent;
48
 
    m_focus = 0;
49
 
    m_desc = 0;
50
 
 
51
 
    KSpreadCell* cell = m_pView->activeTable()->cellAt( m_pView->canvasWidget()->markerColumn(),
52
 
                                                        m_pView->canvasWidget()->markerRow() );
53
 
     m_oldText=cell->text();
54
 
    // Make sure that there is a cell editor running.
55
 
    if ( !m_pView->canvasWidget()->editor() )
56
 
    {
57
 
        m_pView->canvasWidget()->createEditor( KSpreadCanvas::CellEditor );
58
 
        if(cell->text().isEmpty())
59
 
          m_pView->canvasWidget()->editor()->setText( "=" );
60
 
        else
61
 
          if(cell->text().at(0)!='=')
62
 
            m_pView->canvasWidget()->editor()->setText( "="+cell->text() );
63
 
          else
64
 
            m_pView->canvasWidget()->editor()->setText( cell->text() );
65
 
    }
66
 
 
67
 
    Q_ASSERT( m_pView->canvasWidget()->editor() );
68
 
 
69
 
    QWidget *page = new QWidget( this );
70
 
    setMainWidget(page);
71
 
 
72
 
    QGridLayout *grid1 = new QGridLayout(page,11,2,KDialog::marginHint(), KDialog::spacingHint());
73
 
 
74
 
    searchFunct = new KLineEdit(page);
75
 
    QSizePolicy sp3( QSizePolicy::Preferred, QSizePolicy::Fixed );
76
 
    searchFunct->setSizePolicy( sp3 );
77
 
 
78
 
    grid1->addWidget( searchFunct, 0, 0 );
79
 
 
80
 
    typeFunction = new QComboBox(page);
81
 
    QStringList cats = KSpreadFunctionRepository::self()->groups();
82
 
    cats.prepend( i18n("All") );
83
 
    typeFunction->insertStringList( cats  );
84
 
    grid1->addWidget( typeFunction, 1, 0 );
85
 
 
86
 
    functions = new QListBox(page);
87
 
    QSizePolicy sp1( QSizePolicy::Preferred, QSizePolicy::Expanding );
88
 
    functions->setSizePolicy( sp1 );
89
 
    grid1->addWidget( functions, 2, 0 );
90
 
 
91
 
    selectFunction = new QPushButton( page );
92
 
    QToolTip::add(selectFunction, i18n("Insert function") );
93
 
    selectFunction->setPixmap( BarIcon( "down", KIcon::SizeSmall ) );
94
 
    grid1->addWidget( selectFunction, 3, 0 );
95
 
 
96
 
    result = new QLineEdit( page );
97
 
    grid1->addMultiCellWidget( result, 4, 4, 0, 1 );
98
 
 
99
 
    m_tabwidget = new QTabWidget( page );
100
 
    QSizePolicy sp2( QSizePolicy::Expanding, QSizePolicy::Expanding );
101
 
    m_tabwidget->setSizePolicy( sp2 );
102
 
    grid1->addMultiCellWidget( m_tabwidget, 0, 2, 1, 1 );
103
 
 
104
 
    m_browser = new QTextBrowser( m_tabwidget );
105
 
    m_browser->setMinimumWidth( 300 );
106
 
 
107
 
    m_tabwidget->addTab( m_browser, i18n("&Help") );
108
 
    int index = m_tabwidget->currentPageIndex();
109
 
 
110
 
    m_input = new QWidget( m_tabwidget );
111
 
    QVBoxLayout *grid2 = new QVBoxLayout( m_input, KDialog::marginHint(), KDialog::spacingHint() );
112
 
 
113
 
    // grid2->setResizeMode (QLayout::Minimum);
114
 
 
115
 
    label1 = new QLabel(m_input);
116
 
    grid2->addWidget( label1 );
117
 
 
118
 
    firstElement=new QLineEdit(m_input);
119
 
    grid2->addWidget( firstElement );
120
 
 
121
 
    label2=new QLabel(m_input);
122
 
    grid2->addWidget( label2 );
123
 
 
124
 
    secondElement=new QLineEdit(m_input);
125
 
    grid2->addWidget( secondElement );
126
 
 
127
 
    label3=new QLabel(m_input);
128
 
    grid2->addWidget( label3 );
129
 
 
130
 
    thirdElement=new QLineEdit(m_input);
131
 
    grid2->addWidget( thirdElement );
132
 
 
133
 
    label4=new QLabel(m_input);
134
 
    grid2->addWidget( label4 );
135
 
 
136
 
    fourElement=new QLineEdit(m_input);
137
 
    grid2->addWidget( fourElement );
138
 
 
139
 
    label5=new QLabel(m_input);
140
 
    grid2->addWidget( label5 );
141
 
 
142
 
    fiveElement=new QLineEdit(m_input);
143
 
    grid2->addWidget( fiveElement );
144
 
 
145
 
    grid2->addStretch( 10 );
146
 
 
147
 
    m_tabwidget->addTab( m_input, i18n("&Parameters") );
148
 
    m_tabwidget->setTabEnabled( m_input, FALSE );
149
 
 
150
 
    m_tabwidget->setCurrentPage( index );
151
 
 
152
 
    refresh_result = true;
153
 
 
154
 
    connect( this, SIGNAL( cancelClicked() ), this, SLOT( slotClose() ) );
155
 
    connect( this, SIGNAL( okClicked() ), this, SLOT( slotOk() ) );
156
 
    connect( typeFunction, SIGNAL( activated(const QString &) ),
157
 
             this, SLOT( slotActivated(const QString &) ) );
158
 
    connect( functions, SIGNAL( highlighted(const QString &) ),
159
 
             this, SLOT( slotSelected(const QString &) ) );
160
 
    connect( functions, SIGNAL( selected(const QString &) ),
161
 
             this, SLOT( slotSelected(const QString &) ) );
162
 
    connect( functions, SIGNAL( doubleClicked(QListBoxItem * ) ),
163
 
             this ,SLOT( slotDoubleClicked(QListBoxItem *) ) );
164
 
 
165
 
    slotActivated(i18n("All"));
166
 
 
167
 
    connect( selectFunction, SIGNAL(clicked()),
168
 
             this,SLOT(slotSelectButton()));
169
 
 
170
 
    connect( firstElement,SIGNAL(textChanged ( const QString & )),
171
 
             this,SLOT(slotChangeText(const QString &)));
172
 
    connect( secondElement,SIGNAL(textChanged ( const QString & )),
173
 
             this,SLOT(slotChangeText(const QString &)));
174
 
    connect( thirdElement,SIGNAL(textChanged ( const QString & )),
175
 
             this,SLOT(slotChangeText(const QString &)));
176
 
    connect( fourElement,SIGNAL(textChanged ( const QString & )),
177
 
             this,SLOT(slotChangeText(const QString &)));
178
 
    connect( fiveElement,SIGNAL(textChanged ( const QString & )),
179
 
             this,SLOT(slotChangeText(const QString &)));
180
 
 
181
 
    connect( m_pView, SIGNAL( sig_chooseSelectionChanged( KSpreadSheet*, const QRect& ) ),
182
 
             this, SLOT( slotSelectionChanged( KSpreadSheet*, const QRect& ) ) );
183
 
 
184
 
    connect( m_browser, SIGNAL( linkClicked( const QString& ) ),
185
 
             this, SLOT( slotShowFunction( const QString& ) ) );
186
 
 
187
 
    // Save the name of the active table.
188
 
    m_tableName = m_pView->activeTable()->tableName();
189
 
    // Save the cells current text.
190
 
    QString tmp_oldText = m_pView->canvasWidget()->editor()->text();
191
 
    // Position of the cell.
192
 
    m_column = m_pView->canvasWidget()->markerColumn();
193
 
    m_row = m_pView->canvasWidget()->markerRow();
194
 
 
195
 
    if( tmp_oldText.isEmpty() )
196
 
        result->setText("=");
197
 
    else
198
 
    {
199
 
        if( tmp_oldText.at(0)!='=')
200
 
            result->setText( "=" + tmp_oldText );
201
 
        else
202
 
            result->setText( tmp_oldText );
203
 
    }
204
 
 
205
 
    // Allow the user to select cells on the spreadsheet.
206
 
    m_pView->canvasWidget()->startChoose();
207
 
 
208
 
    qApp->installEventFilter( this );
209
 
 
210
 
    // Was a function name passed along with the constructor ? Then activate it.
211
 
    if( !formulaName.isEmpty() )
212
 
    {
213
 
        functions->setCurrentItem( functions->index( functions->findItem( formulaName ) ) );
214
 
        slotDoubleClicked( functions->findItem( formulaName ) );
215
 
    }
216
 
    else
217
 
    {
218
 
        // Set keyboard focus to allow selection of a formula.
219
 
        searchFunct->setFocus();
220
 
    }
221
 
 
222
 
    // Add auto completion.
223
 
    searchFunct->setCompletionMode( KGlobalSettings::CompletionAuto );
224
 
    searchFunct->setCompletionObject( &listFunct, true );
225
 
 
226
 
    if( functions->currentItem() == -1 )
227
 
        selectFunction->setEnabled( false );
228
 
 
229
 
    connect( searchFunct, SIGNAL( textChanged( const QString & ) ),
230
 
             this, SLOT( slotSearchText(const QString &) ) );
231
 
    connect( searchFunct, SIGNAL( returnPressed() ),
232
 
             this, SLOT( slotPressReturn() ) );
233
 
}
234
 
 
235
 
KSpreadDlgFormula::~KSpreadDlgFormula()
236
 
{
237
 
    kdDebug(36001)<<"KSpreadDlgFormula::~KSpreadDlgFormula() \n";
238
 
}
239
 
 
240
 
 
241
 
void KSpreadDlgFormula::slotPressReturn()
242
 
{
243
 
    //laurent 2001-07-07 desactivate this code
244
 
    //because kspread crash.
245
 
    //TODO fix it
246
 
    /*
247
 
    if( !functions->currentText().isEmpty() )
248
 
        slotDoubleClicked( functions->findItem( functions->currentText() ) );
249
 
    */
250
 
}
251
 
 
252
 
void KSpreadDlgFormula::slotSearchText(const QString &_text)
253
 
{
254
 
    QString result = listFunct.makeCompletion( _text.upper() );
255
 
    if( !result.isNull() )
256
 
        functions->setCurrentItem( functions->index( functions->findItem( result ) ) );
257
 
}
258
 
 
259
 
bool KSpreadDlgFormula::eventFilter( QObject* obj, QEvent* ev )
260
 
{
261
 
    if ( obj == firstElement && ev->type() == QEvent::FocusIn )
262
 
        m_focus = firstElement;
263
 
    else if ( obj == secondElement && ev->type() == QEvent::FocusIn )
264
 
        m_focus = secondElement;
265
 
    else if ( obj == thirdElement && ev->type() == QEvent::FocusIn )
266
 
        m_focus = thirdElement;
267
 
    else if ( obj == fourElement && ev->type() == QEvent::FocusIn )
268
 
        m_focus = fourElement;
269
 
    else if ( obj == fiveElement && ev->type() == QEvent::FocusIn )
270
 
        m_focus = fiveElement;
271
 
    else
272
 
        return FALSE;
273
 
 
274
 
    if ( m_focus )
275
 
        m_pView->canvasWidget()->startChoose();
276
 
 
277
 
    return FALSE;
278
 
}
279
 
 
280
 
void KSpreadDlgFormula::slotOk()
281
 
{
282
 
    m_pView->doc()->emitBeginOperation( false );
283
 
 
284
 
    m_pView->canvasWidget()->endChoose();
285
 
    // Switch back to the old table
286
 
    if( m_pView->activeTable()->tableName() !=  m_tableName )
287
 
    {
288
 
        KSpreadSheet *table=m_pView->doc()->map()->findTable(m_tableName);
289
 
        if( table)
290
 
            m_pView->setActiveTable(table);
291
 
    }
292
 
 
293
 
    // Revert the marker to its original position
294
 
    m_pView->selectionInfo()->setMarker( QPoint( m_column, m_row ),
295
 
                                         m_pView->activeTable());
296
 
 
297
 
    // If there is still an editor then set the text.
298
 
    // Usually the editor is always in place.
299
 
    if( m_pView->canvasWidget()->editor() != 0 )
300
 
    {
301
 
        Q_ASSERT( m_pView->canvasWidget()->editor() );
302
 
        QString tmp = result->text();
303
 
        if( tmp.at(0) != '=')
304
 
            tmp = "=" + tmp;
305
 
        int pos = m_pView->canvasWidget()->editor()->cursorPosition()+ tmp.length();
306
 
        m_pView->canvasWidget()->editor()->setText( tmp );
307
 
        m_pView->canvasWidget()->editor()->setFocus();
308
 
        m_pView->canvasWidget()->editor()->setCursorPosition( pos );
309
 
    }
310
 
 
311
 
    m_pView->slotUpdateView( m_pView->activeTable() );
312
 
    accept();
313
 
    //  delete this;
314
 
}
315
 
 
316
 
void KSpreadDlgFormula::slotClose()
317
 
{
318
 
    m_pView->doc()->emitBeginOperation( false );
319
 
 
320
 
    m_pView->canvasWidget()->endChoose();
321
 
 
322
 
    // Switch back to the old table
323
 
    if(m_pView->activeTable()->tableName() !=  m_tableName )
324
 
    {
325
 
        KSpreadSheet *table=m_pView->doc()->map()->findTable(m_tableName);
326
 
        if( !table )
327
 
            return;
328
 
        m_pView->setActiveTable(table);
329
 
    }
330
 
 
331
 
 
332
 
    // Revert the marker to its original position
333
 
    m_pView->selectionInfo()->setMarker( QPoint( m_column, m_row ),
334
 
                                         m_pView->activeTable() );
335
 
 
336
 
    // If there is still an editor then reset the text.
337
 
    // Usually the editor is always in place.
338
 
    if( m_pView->canvasWidget()->editor() != 0 )
339
 
    {
340
 
        Q_ASSERT( m_pView->canvasWidget()->editor() );
341
 
        m_pView->canvasWidget()->editor()->setText( m_oldText );
342
 
        m_pView->canvasWidget()->editor()->setFocus();
343
 
    }
344
 
 
345
 
    m_pView->slotUpdateView( m_pView->activeTable() );
346
 
    reject();
347
 
    //laurent 2002-01-03 comment this line otherwise kspread crash
348
 
    //but dialog box is not deleted => not good
349
 
    //delete this;
350
 
}
351
 
 
352
 
void KSpreadDlgFormula::slotSelectButton()
353
 
{
354
 
    if( functions->currentItem() != -1 )
355
 
    {
356
 
        slotDoubleClicked(functions->findItem(functions->text(functions->currentItem())));
357
 
    }
358
 
}
359
 
 
360
 
void KSpreadDlgFormula::slotChangeText( const QString& )
361
 
{
362
 
    // Test the lock
363
 
    if( !refresh_result )
364
 
        return;
365
 
 
366
 
    if ( m_focus == 0 )
367
 
        return;
368
 
 
369
 
    QString tmp = m_leftText+m_funcName+"(";
370
 
    tmp += createFormula();
371
 
    tmp = tmp+ ")" + m_rightText;
372
 
 
373
 
    result->setText( tmp );
374
 
}
375
 
 
376
 
QString KSpreadDlgFormula::createFormula()
377
 
{
378
 
    QString tmp( "" );
379
 
 
380
 
    if ( !m_desc )
381
 
        return QString::null;
382
 
 
383
 
    bool first = TRUE;
384
 
 
385
 
    int count = m_desc->params();
386
 
 
387
 
    if(!firstElement->text().isEmpty() && count >= 1 )
388
 
    {
389
 
        tmp=tmp+createParameter(firstElement->text(), 0 );
390
 
        first = FALSE;
391
 
    }
392
 
 
393
 
    if(!secondElement->text().isEmpty() && count >= 2 )
394
 
    {
395
 
        first = FALSE;
396
 
        if ( !first )
397
 
            tmp=tmp+";"+createParameter(secondElement->text(), 1 );
398
 
        else
399
 
            tmp=tmp+createParameter(secondElement->text(), 1 );
400
 
    }
401
 
    if(!thirdElement->text().isEmpty() && count >= 3 )
402
 
    {
403
 
        first = FALSE;
404
 
        if ( !first )
405
 
            tmp=tmp+";"+createParameter(thirdElement->text(), 2 );
406
 
        else
407
 
            tmp=tmp+createParameter(thirdElement->text(), 2 );
408
 
    }
409
 
    if(!fourElement->text().isEmpty() && count >= 4 )
410
 
    {
411
 
        first = FALSE;
412
 
        if ( !first )
413
 
            tmp=tmp+";"+createParameter(fourElement->text(), 3 );
414
 
        else
415
 
            tmp=tmp+createParameter(fourElement->text(), 3 );
416
 
    }
417
 
    if(!fiveElement->text().isEmpty() && count >= 5 )
418
 
    {
419
 
        first = FALSE;
420
 
        if ( !first )
421
 
            tmp=tmp+";"+createParameter(fiveElement->text(), 4 );
422
 
        else
423
 
            tmp=tmp+createParameter(fiveElement->text(), 4 );
424
 
    }
425
 
 
426
 
    return(tmp);
427
 
}
428
 
 
429
 
QString KSpreadDlgFormula::createParameter( const QString& _text, int param )
430
 
{
431
 
    if ( _text.isEmpty() )
432
 
        return QString( "" );
433
 
 
434
 
    if ( !m_desc )
435
 
        return QString( "" );
436
 
 
437
 
    QString text;
438
 
 
439
 
    KSpreadParameterType elementType = m_desc->param( param ).type();
440
 
 
441
 
    switch( elementType )
442
 
    {
443
 
    case KSpread_Any:
444
 
        {
445
 
                bool isNumber;
446
 
                double tmp = m_pView->doc()->locale()->readNumber( _text, &isNumber );
447
 
                Q_UNUSED( tmp );
448
 
 
449
 
                //In case of number or boolean return _text, else return value as KSpread_String
450
 
                if ( isNumber || _text.upper() =="FALSE" || _text.upper() == "TRUE" )
451
 
                        return _text;
452
 
        }
453
 
    case KSpread_String:
454
 
        {
455
 
            // Does the text start with quotes?
456
 
            if ( _text[0] == '"' )
457
 
            {
458
 
                text = "\\"; // changed: was "\""
459
 
 
460
 
                // Escape quotes
461
 
                QString tmp = _text;
462
 
                int pos;
463
 
                int start = 1;
464
 
                while( ( pos = tmp.find( '"', start ) ) != -1 )
465
 
                {
466
 
                  if (tmp[pos - 1] != '\\')
467
 
                    tmp.replace( pos, 1, "\\\"" );
468
 
                  else
469
 
                    start = pos + 1;
470
 
                }
471
 
 
472
 
                text += tmp;
473
 
                text += "\"";
474
 
            }
475
 
            else
476
 
            {
477
 
                KSpreadPoint p = KSpreadPoint( _text, m_pView->doc()->map() );
478
 
                KSpreadRange r = KSpreadRange( _text, m_pView->doc()->map() );
479
 
 
480
 
                if( !p.isValid() && !r.isValid() )
481
 
                {
482
 
                    text = "\"";
483
 
 
484
 
                    // Escape quotes
485
 
                    QString tmp = _text;
486
 
                    int pos;
487
 
                    int start = 1;
488
 
                    while( ( pos = tmp.find( '"', start ) ) != -1 )
489
 
                    {
490
 
                        if (tmp[pos - 1] != '\\')
491
 
                          tmp.replace( pos, 1, "\\\"" );
492
 
                        else
493
 
                          start = pos + 1;
494
 
                    }
495
 
 
496
 
                    text += tmp;
497
 
                    text += "\"";
498
 
                }
499
 
                else
500
 
                    text = _text;
501
 
            }
502
 
        }
503
 
        return text;
504
 
    case KSpread_Float:
505
 
        return _text;
506
 
    case KSpread_Boolean:
507
 
        return _text;
508
 
    case KSpread_Int:
509
 
        return _text;
510
 
    }
511
 
 
512
 
    // Never reached
513
 
    return text;
514
 
}
515
 
 
516
 
static void showEntry( QLineEdit* edit, QLabel* label, KSpreadFunctionDescription* desc, int param )
517
 
{
518
 
    edit->show();
519
 
 
520
 
    label->setText( desc->param( param ).helpText()+":" );
521
 
    label->show();
522
 
    KSpreadParameterType elementType = desc->param( param ).type();
523
 
    KFloatValidator *validate=0L;
524
 
    switch( elementType )
525
 
    {
526
 
    case KSpread_String:
527
 
    case KSpread_Boolean:
528
 
    case KSpread_Any:
529
 
      edit->clearValidator ();
530
 
      break;
531
 
    case KSpread_Float:
532
 
        validate=new KFloatValidator (edit);
533
 
        validate->setAcceptLocalizedNumbers(true);
534
 
        edit->setValidator(validate);
535
 
        edit->setText( "0" );
536
 
      break;
537
 
    case KSpread_Int:
538
 
      edit->setValidator(new QIntValidator (edit));
539
 
      edit->setText( "0" );
540
 
      break;
541
 
      }
542
 
 
543
 
}
544
 
 
545
 
void KSpreadDlgFormula::slotDoubleClicked( QListBoxItem* item )
546
 
{
547
 
    if ( !item )
548
 
        return;
549
 
    refresh_result = false;
550
 
    if ( !m_desc )
551
 
    {
552
 
        m_browser->setText( "" );
553
 
        return;
554
 
    }
555
 
 
556
 
    m_focus = 0;
557
 
    int old_length = result->text().length();
558
 
 
559
 
    // Dont change order of these function calls due to a bug in Qt 2.2
560
 
    m_browser->setText( m_desc->toQML() );
561
 
    m_tabwidget->setTabEnabled( m_input, TRUE );
562
 
    m_tabwidget->setCurrentPage( 1 );
563
 
 
564
 
    //
565
 
    // Show as many QLineEdits as needed.
566
 
    //
567
 
    if( m_desc->params() > 0 )
568
 
    {
569
 
        m_focus = firstElement;
570
 
        firstElement->setFocus();
571
 
 
572
 
        showEntry( firstElement, label1, m_desc, 0 );
573
 
    }
574
 
    else
575
 
    {
576
 
        label1->hide();
577
 
        firstElement->hide();
578
 
    }
579
 
 
580
 
    if( m_desc->params() > 1 )
581
 
    {
582
 
        showEntry( secondElement, label2, m_desc, 1 );
583
 
    }
584
 
    else
585
 
    {
586
 
        label2->hide();
587
 
        secondElement->hide();
588
 
    }
589
 
 
590
 
    if( m_desc->params() > 2 )
591
 
    {
592
 
        showEntry( thirdElement, label3, m_desc, 2 );
593
 
    }
594
 
    else
595
 
    {
596
 
        label3->hide();
597
 
        thirdElement->hide();
598
 
    }
599
 
 
600
 
    if( m_desc->params() > 3 )
601
 
    {
602
 
        showEntry( fourElement, label4, m_desc, 3 );
603
 
    }
604
 
    else
605
 
    {
606
 
        label4->hide();
607
 
        fourElement->hide();
608
 
    }
609
 
 
610
 
    if( m_desc->params() > 4 )
611
 
    {
612
 
        showEntry( fiveElement, label5, m_desc, 4 );
613
 
    }
614
 
    else
615
 
    {
616
 
        label5->hide();
617
 
        fiveElement->hide();
618
 
    }
619
 
 
620
 
    if( m_desc->params() > 5 )
621
 
    {
622
 
        kdDebug(36001) << "Error in param->nb_param" << endl;
623
 
    }
624
 
    refresh_result = true;
625
 
    //
626
 
    // Put the new function call in the result.
627
 
    //
628
 
    if( result->cursorPosition() < old_length )
629
 
    {
630
 
        m_rightText=result->text().right(old_length-result->cursorPosition());
631
 
        m_leftText=result->text().left(result->cursorPosition());
632
 
    }
633
 
    else
634
 
    {
635
 
        m_rightText="";
636
 
        m_leftText=result->text();
637
 
    }
638
 
    int pos = result->cursorPosition();
639
 
    result->setText( m_leftText+functions->text( functions->currentItem() ) + "()" + m_rightText);
640
 
 
641
 
    if (result->text()[0] != '=')
642
 
      result->setText("=" + result->text());
643
 
 
644
 
    //
645
 
    // Put focus somewhere is there are no QLineEdits visible
646
 
    //
647
 
    if( m_desc->params() == 0 )
648
 
    {
649
 
        label1->show();
650
 
        label1->setText( i18n("This function has no parameters.") );
651
 
 
652
 
        result->setFocus();
653
 
        result->setCursorPosition(pos+functions->text(functions->currentItem()).length()+2);
654
 
    }
655
 
    slotChangeText( "" );
656
 
}
657
 
 
658
 
void KSpreadDlgFormula::slotSelected( const QString& function )
659
 
{
660
 
    KSpreadFunctionDescription* desc =
661
 
       KSpreadFunctionRepository::self()->functionInfo( function );
662
 
    if ( !desc )
663
 
    {
664
 
        m_browser->setText( "" );
665
 
        return;
666
 
    }
667
 
 
668
 
    if( functions->currentItem() !=- 1 )
669
 
        selectFunction->setEnabled( TRUE );
670
 
 
671
 
    // Lock
672
 
    refresh_result = false;
673
 
 
674
 
    m_funcName = function;
675
 
    m_desc = desc;
676
 
 
677
 
    // Set the help text
678
 
    m_browser->setText( m_desc->toQML() );
679
 
    m_browser->setContentsPos( 0, 0 );
680
 
 
681
 
    m_focus=0;
682
 
 
683
 
    m_tabwidget->setCurrentPage( 0 );
684
 
    m_tabwidget->setTabEnabled( m_input, FALSE );
685
 
 
686
 
    // Unlock
687
 
    refresh_result=true;
688
 
}
689
 
 
690
 
// from hyperlink in the "Related Function"
691
 
void KSpreadDlgFormula::slotShowFunction( const QString& function )
692
 
{
693
 
    KSpreadFunctionDescription* desc =
694
 
       KSpreadFunctionRepository::self()->functionInfo( function );
695
 
    if ( !desc ) return;
696
 
 
697
 
    // select the category
698
 
    QString category = desc->group();
699
 
    typeFunction->setCurrentText( category );
700
 
    slotActivated( category );
701
 
 
702
 
    // select the function
703
 
    QListBoxItem* item = functions->findItem( function,
704
 
      Qt::ExactMatch | Qt::CaseSensitive );
705
 
    if( item ) functions->setCurrentItem( item );
706
 
 
707
 
    slotSelected( function );
708
 
}
709
 
 
710
 
void KSpreadDlgFormula::slotSelectionChanged( KSpreadSheet* _table, const QRect& _selection )
711
 
{
712
 
    if ( !m_focus )
713
 
        return;
714
 
 
715
 
    if ( _selection.left() == 0 )
716
 
        return;
717
 
 
718
 
    if ( _selection.left() >= _selection.right() && _selection.top() >= _selection.bottom() )
719
 
    {
720
 
        int dx = _selection.right();
721
 
        int dy = _selection.bottom();
722
 
        QString tmp;
723
 
        tmp.setNum( dy );
724
 
        tmp = _table->tableName() + "!" + util_encodeColumnLabelText( dx ) + tmp;
725
 
        m_focus->setText( tmp );
726
 
    }
727
 
    else
728
 
    {
729
 
        QString area = util_rangeName( _table, _selection );
730
 
        m_focus->setText( area );
731
 
    }
732
 
}
733
 
 
734
 
void KSpreadDlgFormula::slotActivated( const QString& category )
735
 
{
736
 
    QStringList lst;
737
 
    if ( category == i18n("All") )
738
 
        lst = KSpreadFunctionRepository::self()->functionNames();
739
 
    else
740
 
        lst = KSpreadFunctionRepository::self()->functionNames( category );
741
 
 
742
 
    kdDebug(36001)<<"category: "<<category<<" ("<<lst.count()<<"functions)" << endl;
743
 
 
744
 
    functions->clear();
745
 
    functions->insertStringList( lst );
746
 
 
747
 
    QStringList upperList;
748
 
    for ( QStringList::Iterator it = lst.begin(); it != lst.end();++it )
749
 
      upperList.append((*it).upper());
750
 
 
751
 
    listFunct.setItems( upperList );
752
 
 
753
 
    // Go to the first function in the list.
754
 
    functions->setCurrentItem(0);
755
 
    slotSelected( functions->text(0) );
756
 
}
757
 
 
758
 
void KSpreadDlgFormula::closeEvent ( QCloseEvent * e )
759
 
{
760
 
  e->accept();
761
 
}
762
 
 
763
 
#include "kspread_dlg_formula.moc"