1
/* This file is part of the KDE project
2
Copyright (C) 2002-2003 Norbert Andres <nandres@web.de>
3
(C) 2002 Ariya Hidayat <ariya@kde.org>
4
(C) 2002 John Dailey <dailey@vt.edu>
5
(C) 2002 Werner Trobin <trobin@kde.org>
6
(C) 2001-2002 Philipp Mueller <philipp.mueller@gmx.de>
7
(C) 1999-2002 Laurent Montel <montel@kde.org>
8
(C) 2000 David Faure <faure@kde.org>
9
(C) 1998-2000 Torben Weis <weis@kde.org>
11
This library is free software; you can redistribute it and/or
12
modify it under the terms of the GNU Library General Public
13
License as published by the Free Software Foundation; either
14
version 2 of the License, or (at your option) any later version.
16
This library is distributed in the hope that it will be useful,
17
but WITHOUT ANY WARRANTY; without even the implied warranty of
18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
Library General Public License for more details.
21
You should have received a copy of the GNU Library General Public License
22
along with this library; see the file COPYING.LIB. If not, write to
23
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24
Boston, MA 02111-1307, USA.
28
#include "kspread_dlg_sort.h"
29
#include "kspread_doc.h"
30
#include "kspread_map.h"
31
#include "kspread_sheet.h"
32
#include "kspread_view.h"
33
#include "kspread_util.h"
38
#include <kmessagebox.h>
40
#include <qbuttongroup.h>
41
#include <qcheckbox.h>
42
#include <qcombobox.h>
43
#include <qgroupbox.h>
46
#include <qlineedit.h>
47
#include <qpushbutton.h>
48
#include <qradiobutton.h>
50
#include <qtabwidget.h>
54
KSpreadSortDlg::KSpreadSortDlg( KSpreadView * parent, const char * name,
56
: KDialogBase( parent, name, modal,"Sort",Ok|Cancel ),
60
setName( "KSpreadSortDlg" );
63
setCaption( i18n( "Sorting" ) );
64
//setSizeGripEnabled( true );
66
QVBox *page = makeVBoxMainWidget();
68
m_tabWidget = new QTabWidget( page, "m_tabWidget" );
70
m_page1 = new QWidget( m_tabWidget, "m_page1" );
71
QGridLayout * page1Layout
72
= new QGridLayout( m_page1, 1, 1, 11, 6, "page1Layout");
74
QGroupBox * sort1Box = new QGroupBox( m_page1, "sort1Box" );
75
sort1Box->setTitle( i18n( "Sort By" ) );
76
sort1Box->setColumnLayout(0, Qt::Vertical );
77
sort1Box->layout()->setSpacing( KDialog::spacingHint() );
78
sort1Box->layout()->setMargin( KDialog::marginHint() );
79
QHBoxLayout * sort1BoxLayout = new QHBoxLayout( sort1Box->layout() );
80
sort1BoxLayout->setAlignment( Qt::AlignTop );
82
m_sortKey1 = new QComboBox( false, sort1Box, "m_sortKey1" );
83
sort1BoxLayout->addWidget( m_sortKey1 );
85
m_sortOrder1 = new QComboBox( false, sort1Box, "m_sortOrder1" );
86
m_sortOrder1->insertItem( i18n( "Ascending" ) );
87
m_sortOrder1->insertItem( i18n( "Descending" ) );
88
sort1BoxLayout->addWidget( m_sortOrder1 );
90
page1Layout->addWidget( sort1Box, 0, 0 );
92
QGroupBox * sort2Box = new QGroupBox( m_page1, "sort2Box" );
93
sort2Box->setTitle( i18n( "Then By" ) );
94
sort2Box->setColumnLayout(0, Qt::Vertical );
95
sort2Box->layout()->setSpacing( KDialog::spacingHint() );
96
sort2Box->layout()->setMargin( KDialog::marginHint() );
97
QHBoxLayout * sort2BoxLayout = new QHBoxLayout( sort2Box->layout() );
98
sort2BoxLayout->setAlignment( Qt::AlignTop );
100
m_sortKey2 = new QComboBox( false, sort2Box, "m_sortKey2" );
101
m_sortKey2->insertItem( i18n( "None" ) );
102
sort2BoxLayout->addWidget( m_sortKey2 );
104
m_sortOrder2 = new QComboBox( false, sort2Box, "m_sortOrder2" );
105
m_sortOrder2->insertItem( i18n( "Ascending" ) );
106
m_sortOrder2->insertItem( i18n( "Descending" ) );
107
sort2BoxLayout->addWidget( m_sortOrder2 );
109
page1Layout->addWidget( sort2Box, 1, 0 );
111
QGroupBox * sort3Box = new QGroupBox( m_page1, "sort3Box" );
112
sort3Box->setTitle( i18n( "Then By" ) );
113
sort3Box->setColumnLayout(0, Qt::Vertical );
114
sort3Box->layout()->setSpacing( KDialog::spacingHint() );
115
sort3Box->layout()->setMargin( KDialog::marginHint() );
116
QHBoxLayout * sort3BoxLayout = new QHBoxLayout( sort3Box->layout() );
117
sort3BoxLayout->setAlignment( Qt::AlignTop );
119
m_sortKey3 = new QComboBox( false, sort3Box, "m_sortKey3" );
120
m_sortKey3->insertItem( i18n( "None" ) );
121
m_sortKey3->setEnabled( false );
122
sort3BoxLayout->addWidget( m_sortKey3 );
124
m_sortOrder3 = new QComboBox( false, sort3Box, "m_sortOrder3" );
125
m_sortOrder3->insertItem( i18n( "Ascending" ) );
126
m_sortOrder3->insertItem( i18n( "Descending" ) );
127
m_sortOrder3->setEnabled( false );
128
sort3BoxLayout->addWidget( m_sortOrder3 );
130
page1Layout->addWidget( sort3Box, 2, 0 );
131
m_tabWidget->insertTab( m_page1, i18n( "Sort Criteria" ) );
136
m_page2 = new QWidget( m_tabWidget, "m_page2" );
137
QGridLayout * page2Layout = new QGridLayout( m_page2, 1, 1, 11, 6, "page2Layout");
139
QGroupBox * firstKeyBox = new QGroupBox( m_page2, "firstKeyBox" );
140
firstKeyBox->setTitle( i18n( "First Key" ) );
141
firstKeyBox->setColumnLayout(0, Qt::Vertical );
142
firstKeyBox->layout()->setSpacing( KDialog::spacingHint() );
143
firstKeyBox->layout()->setMargin( KDialog::marginHint() );
144
QVBoxLayout * firstKeyBoxLayout = new QVBoxLayout( firstKeyBox->layout() );
145
firstKeyBoxLayout->setAlignment( Qt::AlignTop );
147
m_useCustomLists = new QCheckBox( firstKeyBox, "m_useCustomLists_2" );
148
m_useCustomLists->setText( i18n( "&Use custom list" ) );
149
firstKeyBoxLayout->addWidget( m_useCustomLists );
151
m_customList = new QComboBox( false, firstKeyBox, "m_customList" );
152
m_customList->setEnabled( false );
153
m_customList->setMaximumSize( 230, 30 );
154
firstKeyBoxLayout->addWidget( m_customList );
156
page2Layout->addWidget( firstKeyBox, 0, 1 );
158
QButtonGroup * orientationGroup = new QButtonGroup( m_page2, "orientationGroup" );
159
orientationGroup->setTitle( i18n( "Orientation" ) );
160
orientationGroup->setColumnLayout(0, Qt::Vertical );
161
orientationGroup->layout()->setSpacing( KDialog::spacingHint() );
162
orientationGroup->layout()->setMargin( KDialog::marginHint() );
163
QGridLayout * orientationGroupLayout = new QGridLayout( orientationGroup->layout() );
164
orientationGroupLayout->setAlignment( Qt::AlignTop );
166
m_sortColumn = new QRadioButton( orientationGroup, "m_sortColumn" );
167
m_sortColumn->setText( i18n( "&Column" ) );
168
m_sortColumn->setChecked( true );
170
orientationGroupLayout->addWidget( m_sortColumn, 0, 0 );
172
m_sortRow = new QRadioButton( orientationGroup, "m_sortRow" );
173
m_sortRow->setText( i18n( "&Row" ) );
175
orientationGroupLayout->addWidget( m_sortRow, 1, 0 );
177
page2Layout->addWidget( orientationGroup, 0, 0 );
179
m_copyLayout = new QCheckBox( m_page2, "m_copyLayout" );
180
m_copyLayout->setText( i18n( "Copy &layout" ) );
182
page2Layout->addMultiCellWidget( m_copyLayout, 2, 2, 0, 1 );
184
m_firstRowHeader = new QCheckBox( m_page2, "m_copyLayout" );
185
m_firstRowHeader->setText( i18n( "&First row contains header" ) );
187
page2Layout->addMultiCellWidget( m_firstRowHeader, 3, 3, 0, 1 );
189
m_respectCase = new QCheckBox( m_page2, "m_copyLayout" );
190
m_respectCase->setText( i18n( "Respect case" ) );
191
m_respectCase->setChecked( true );
193
page2Layout->addMultiCellWidget( m_respectCase, 4, 4, 0, 1 );
196
QGroupBox * resultToBox = new QGroupBox( m_page2, "resultToBox" );
197
resultToBox->setTitle( i18n( "Put Results To" ) );
198
resultToBox->setColumnLayout(0, Qt::Vertical );
199
resultToBox->layout()->setSpacing( KDialog::spacingHint() );
200
resultToBox->layout()->setMargin( KDialog::marginHint() );
201
QHBoxLayout * resultToBoxLayout = new QHBoxLayout( resultToBox->layout() );
202
resultToBoxLayout->setAlignment( Qt::AlignTop );
204
m_outputSheet = new QComboBox( false, resultToBox, "m_outputSheet" );
205
resultToBoxLayout->addWidget( m_outputSheet );
206
QSpacerItem * spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
207
resultToBoxLayout->addItem( spacer );
209
QLabel * startingCellLabel = new QLabel( resultToBox, "startingCellLabel" );
210
startingCellLabel->setText( i18n( "Starting cell:" ) );
211
resultToBoxLayout->addWidget( startingCellLabel );
213
m_outputCell = new QLineEdit( resultToBox, "m_outputCell" );
214
m_outputCell->setMaximumSize( QSize( 60, 32767 ) );
215
resultToBoxLayout->addWidget( m_outputCell );
217
page2Layout->addMultiCellWidget( resultToBox, 1, 1, 0, 1 );
218
m_tabWidget->insertTab( m_page2, i18n( "Options" ) );
220
QHBoxLayout * Layout1 = new QHBoxLayout( 0, 0, 6, "Layout1");
221
QSpacerItem * spacer_2 = new QSpacerItem( 20, 20, QSizePolicy::Expanding,
222
QSizePolicy::Minimum );
223
Layout1->addItem( spacer_2 );
225
connect( m_sortKey2, SIGNAL( activated( int ) ), this,
226
SLOT( sortKey2textChanged( int ) ) );
227
connect( m_useCustomLists, SIGNAL( stateChanged(int) ), this,
228
SLOT( useCustomListsStateChanged(int) ) );
229
connect( m_firstRowHeader, SIGNAL( stateChanged(int) ), this,
230
SLOT( firstRowHeaderChanged(int) ) );
231
connect( orientationGroup, SIGNAL( pressed(int) ), this,
232
SLOT( slotOrientationChanged(int) ) );
237
KSpreadSortDlg::~KSpreadSortDlg()
239
// no need to delete child widgets, Qt does it all for us
242
void KSpreadSortDlg::init()
245
lst<<i18n("January");
246
lst<<i18n("February");
253
lst<<i18n("September");
254
lst<<i18n("October");
255
lst<<i18n("November");
256
lst<<i18n("December");
259
lst<<i18n("Tuesday");
260
lst<<i18n("Wednesday");
261
lst<<i18n("Thursday");
263
lst<<i18n("Saturday");
266
KConfig * config = KSpreadFactory::global()->config();
267
config->setGroup( "Parameters" );
268
QStringList other = config->readListEntry("Other list");
270
for ( QStringList::Iterator it = other.begin(); it != other.end(); ++it )
274
else if( it != other.begin())
276
tmp = tmp.left(tmp.length() - 2);
281
m_customList->insertStringList(lst);
283
QPtrList<KSpreadSheet> sheetList = m_pView->doc()->map()->sheetList();
284
for (unsigned int c = 0; c < sheetList.count(); ++c)
286
KSpreadSheet * t = sheetList.at(c);
289
m_outputSheet->insertItem( t->sheetName() );
291
m_outputSheet->setCurrentText( m_pView->activeSheet()->sheetName() );
293
QRect r = m_pView->selection();
295
cellArea += KSpreadCell::columnName(r.left());
296
cellArea += QString::number( r.top() );
297
m_outputCell->setText( cellArea );
299
// Entire columns selected ?
300
if ( util_isColumnSelected(r) )
302
m_sortRow->setEnabled(false);
303
m_sortColumn->setChecked(true);
305
int right = r.right();
306
for (int i = r.left(); i <= right; ++i)
307
m_listColumn += i18n("Column %1").arg(KSpreadCell::columnName(i));
309
// Entire rows selected ?
310
else if ( util_isRowSelected(r) )
312
m_sortColumn->setEnabled(false);
313
m_sortRow->setChecked(true);
315
int bottom = r.bottom();
316
for (int i = r.top(); i <= bottom; ++i)
317
m_listRow += i18n("Row %1").arg(i);
321
// Selection is only one row
322
if ( r.top() == r.bottom() )
324
m_sortColumn->setEnabled(false);
325
m_sortRow->setChecked(true);
328
else if (r.left() == r.right())
330
m_sortRow->setEnabled(false);
331
m_sortColumn->setChecked(true);
335
m_sortColumn->setChecked(true);
338
int right = r.right();
339
int bottom = r.bottom();
340
for (int i = r.left(); i <= right; ++i)
341
m_listColumn += i18n("Column %1").arg(KSpreadCell::columnName(i));
343
for (int i = r.top(); i <= bottom; ++i)
344
m_listRow += i18n("Row %1").arg(i);
347
// Initialize the combo box
348
if ( m_sortRow->isChecked() )
349
slotOrientationChanged(1);
351
slotOrientationChanged(0);
354
void KSpreadSortDlg::slotOrientationChanged(int id)
362
m_sortKey1->insertStringList(m_listColumn);
363
m_sortKey2->insertItem( i18n("None") );
364
m_sortKey2->insertStringList(m_listColumn);
365
m_sortKey3->insertItem( i18n("None") );
366
m_sortKey3->insertStringList(m_listColumn);
373
m_sortKey1->insertStringList(m_listRow);
374
m_sortKey2->insertItem( i18n("None") );
375
m_sortKey2->insertStringList(m_listRow);
376
m_sortKey3->insertItem( i18n("None") );
377
m_sortKey3->insertStringList(m_listRow);
379
if (m_firstRowHeader->isChecked())
381
int k1 = m_sortKey1->currentItem();
382
int k2 = m_sortKey2->currentItem();
383
int k3 = m_sortKey3->currentItem();
384
m_sortKey1->removeItem( 0 );
385
m_sortKey2->removeItem( 1 ); // because there is "None" in there
386
m_sortKey3->removeItem( 1 );
388
m_sortKey1->setCurrentItem(--k1);
390
m_sortKey1->setCurrentItem( 0 );
392
m_sortKey2->setCurrentItem(--k2);
394
m_sortKey3->setCurrentItem(--k3);
400
kdDebug(36001) << "Error in signal : pressed(int id)" << endl;
405
void KSpreadSortDlg::slotOk()
407
m_pView->doc()->emitBeginOperation( false );
409
KSpreadSheet * sheet = m_pView->doc()->map()->findSheet( m_outputSheet->currentText() );
412
KMessageBox::error( this, i18n("The selected output table does not exist.") );
413
m_outputSheet->setFocus();
414
m_tabWidget->setTabEnabled(m_page2, true);
415
m_pView->slotUpdateView( m_pView->activeSheet() );
419
KSpreadPoint outputPoint( m_outputCell->text() );
420
if ( !outputPoint.isValid() || outputPoint.isSheetKnown() )
422
KMessageBox::error( this, i18n("The output cell is invalid.") );
423
m_outputCell->setFocus();
424
m_tabWidget->setTabEnabled(m_page2, true);
425
m_pView->slotUpdateView( m_pView->activeSheet() );
428
outputPoint.sheet = sheet;
430
QRect r = m_pView->selection();
431
if ( r.topLeft() != outputPoint.pos )
433
int h = outputPoint.pos.y() + r.height();
434
int w = outputPoint.pos.x() + r.width();
436
if ( r.contains(outputPoint.pos)
437
|| ( w >= r.left() && w <= r.right() )
438
|| ( h >= r.top() && h <= r.bottom() ) )
440
KMessageBox::error( this, i18n("The output region must not overlap with the source region.") );
441
m_outputCell->setFocus();
442
m_pView->slotUpdateView( m_pView->activeSheet() );
443
// TODO: set right tab
451
QStringList * firstKey = 0L;
452
KSpreadSheet::SortingOrder order1;
453
KSpreadSheet::SortingOrder order2;
454
KSpreadSheet::SortingOrder order3;
456
order1 = ( m_sortOrder1->currentItem() == 0 ? KSpreadSheet::Increase
457
: KSpreadSheet::Decrease );
458
order2 = ( m_sortOrder2->currentItem() == 0 ? KSpreadSheet::Increase
459
: KSpreadSheet::Decrease );
460
order3 = ( m_sortOrder3->currentItem() == 0 ? KSpreadSheet::Increase
461
: KSpreadSheet::Decrease );
463
if ( m_sortRow->isChecked() )
465
key1 = m_sortKey1->currentItem() + r.top();
466
if (m_sortKey2->currentItem() > 0)
467
key2 = m_sortKey2->currentItem() + r.top() - 1; // cause there is "None"
468
if (m_sortKey3->currentItem() > 0)
469
key3 = m_sortKey3->currentItem() + r.top() - 1; // cause there is "None"
471
if (m_firstRowHeader->isChecked())
483
key1 = m_sortKey1->currentItem() + r.left();
484
if (m_sortKey2->currentItem() > 0)
485
key2 = m_sortKey2->currentItem() + r.left() - 1; // cause there is "None"
486
if (m_sortKey3->currentItem() > 0)
487
key3 = m_sortKey3->currentItem() + r.left() - 1; // cause there is "None"
490
if ( m_useCustomLists->isChecked() )
492
firstKey = new QStringList();
493
QString list = m_customList->currentText();
495
int l = list.length();
496
for ( int i = 0; i < l; ++i )
498
if ( list[i] == ',' )
500
firstKey->append( tmp.stripWhiteSpace() );
514
if (key2 == 0 && key3 > 0)
520
if ( m_sortRow->isChecked() )
522
m_pView->activeSheet()->sortByRow( m_pView->selection(), key1, key2, key3,
523
order1, order2, order3,
524
firstKey, m_copyLayout->isChecked(),
525
m_firstRowHeader->isChecked(),
526
outputPoint, m_respectCase->isChecked() );
528
else if (m_sortColumn->isChecked())
530
m_pView->activeSheet()->sortByColumn( m_pView->selection(), key1, key2, key3,
531
order1, order2, order3,
532
firstKey, m_copyLayout->isChecked(),
533
m_firstRowHeader->isChecked(),
534
outputPoint, m_respectCase->isChecked() );
538
kdDebug(36001) << "Err in radiobutton" << endl;
544
m_pView->slotUpdateView( m_pView->activeSheet() );
548
void KSpreadSortDlg::sortKey2textChanged( int i )
550
m_sortKey3->setEnabled( ( i!=0 ) );
551
m_sortOrder3->setEnabled( ( i!=0 ) );
554
void KSpreadSortDlg::useCustomListsStateChanged( int state )
557
m_customList->setEnabled(false);
559
m_customList->setEnabled(true);
562
void KSpreadSortDlg::firstRowHeaderChanged( int state )
564
if (m_sortColumn->isChecked())
567
if (state == 0) // off
569
int k1 = m_sortKey1->currentItem();
570
int k2 = m_sortKey2->currentItem();
571
int k3 = m_sortKey3->currentItem();
575
m_sortKey1->insertStringList(m_listRow);
576
m_sortKey2->insertItem( i18n("None") );
577
m_sortKey2->insertStringList(m_listRow);
578
m_sortKey3->insertItem( i18n("None") );
579
m_sortKey3->insertStringList(m_listRow);
581
m_sortKey1->setCurrentItem(++k1);
582
m_sortKey2->setCurrentItem(++k2);
583
m_sortKey3->setCurrentItem(++k3);
585
else if (state == 2) // on
587
int k1 = m_sortKey1->currentItem();
588
int k2 = m_sortKey2->currentItem();
589
int k3 = m_sortKey3->currentItem();
590
m_sortKey1->removeItem( 0 );
591
m_sortKey2->removeItem( 1 ); // because there is "None" in there
592
m_sortKey3->removeItem( 1 );
594
m_sortKey1->setCurrentItem(--k1);
596
m_sortKey2->setCurrentItem(--k2);
598
m_sortKey3->setCurrentItem(--k3);
602
#include "kspread_dlg_sort.moc"