00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "kspread_dlg_sort.h"
00029 #include "kspread_doc.h"
00030 #include "kspread_map.h"
00031 #include "kspread_sheet.h"
00032 #include "kspread_view.h"
00033 #include "kspread_util.h"
00034
00035 #include <kconfig.h>
00036 #include <kdebug.h>
00037 #include <klocale.h>
00038 #include <kmessagebox.h>
00039
00040 #include <qbuttongroup.h>
00041 #include <qcheckbox.h>
00042 #include <qcombobox.h>
00043 #include <qgroupbox.h>
00044 #include <qlabel.h>
00045 #include <qlayout.h>
00046 #include <qlineedit.h>
00047 #include <qpushbutton.h>
00048 #include <qradiobutton.h>
00049 #include <qrect.h>
00050 #include <qtabwidget.h>
00051 #include <qwidget.h>
00052 #include <qvbox.h>
00053
00054 KSpreadSortDlg::KSpreadSortDlg( KSpreadView * parent, const char * name,
00055 bool modal )
00056 : KDialogBase( parent, name, modal,"Sort",Ok|Cancel ),
00057 m_pView( parent )
00058 {
00059 if ( !name )
00060 setName( "KSpreadSortDlg" );
00061
00062 resize( 528, 316 );
00063 setCaption( i18n( "Sorting" ) );
00064
00065
00066 QVBox *page = makeVBoxMainWidget();
00067
00068 m_tabWidget = new QTabWidget( page, "m_tabWidget" );
00069
00070 m_page1 = new QWidget( m_tabWidget, "m_page1" );
00071 QGridLayout * page1Layout
00072 = new QGridLayout( m_page1, 1, 1, 11, 6, "page1Layout");
00073
00074 QGroupBox * sort1Box = new QGroupBox( m_page1, "sort1Box" );
00075 sort1Box->setTitle( i18n( "Sort By" ) );
00076 sort1Box->setColumnLayout(0, Qt::Vertical );
00077 sort1Box->layout()->setSpacing( KDialog::spacingHint() );
00078 sort1Box->layout()->setMargin( KDialog::marginHint() );
00079 QHBoxLayout * sort1BoxLayout = new QHBoxLayout( sort1Box->layout() );
00080 sort1BoxLayout->setAlignment( Qt::AlignTop );
00081
00082 m_sortKey1 = new QComboBox( false, sort1Box, "m_sortKey1" );
00083 sort1BoxLayout->addWidget( m_sortKey1 );
00084
00085 m_sortOrder1 = new QComboBox( false, sort1Box, "m_sortOrder1" );
00086 m_sortOrder1->insertItem( i18n( "Ascending" ) );
00087 m_sortOrder1->insertItem( i18n( "Descending" ) );
00088 sort1BoxLayout->addWidget( m_sortOrder1 );
00089
00090 page1Layout->addWidget( sort1Box, 0, 0 );
00091
00092 QGroupBox * sort2Box = new QGroupBox( m_page1, "sort2Box" );
00093 sort2Box->setTitle( i18n( "Then By" ) );
00094 sort2Box->setColumnLayout(0, Qt::Vertical );
00095 sort2Box->layout()->setSpacing( KDialog::spacingHint() );
00096 sort2Box->layout()->setMargin( KDialog::marginHint() );
00097 QHBoxLayout * sort2BoxLayout = new QHBoxLayout( sort2Box->layout() );
00098 sort2BoxLayout->setAlignment( Qt::AlignTop );
00099
00100 m_sortKey2 = new QComboBox( false, sort2Box, "m_sortKey2" );
00101 m_sortKey2->insertItem( i18n( "None" ) );
00102 sort2BoxLayout->addWidget( m_sortKey2 );
00103
00104 m_sortOrder2 = new QComboBox( false, sort2Box, "m_sortOrder2" );
00105 m_sortOrder2->insertItem( i18n( "Ascending" ) );
00106 m_sortOrder2->insertItem( i18n( "Descending" ) );
00107 sort2BoxLayout->addWidget( m_sortOrder2 );
00108
00109 page1Layout->addWidget( sort2Box, 1, 0 );
00110
00111 QGroupBox * sort3Box = new QGroupBox( m_page1, "sort3Box" );
00112 sort3Box->setTitle( i18n( "Then By" ) );
00113 sort3Box->setColumnLayout(0, Qt::Vertical );
00114 sort3Box->layout()->setSpacing( KDialog::spacingHint() );
00115 sort3Box->layout()->setMargin( KDialog::marginHint() );
00116 QHBoxLayout * sort3BoxLayout = new QHBoxLayout( sort3Box->layout() );
00117 sort3BoxLayout->setAlignment( Qt::AlignTop );
00118
00119 m_sortKey3 = new QComboBox( false, sort3Box, "m_sortKey3" );
00120 m_sortKey3->insertItem( i18n( "None" ) );
00121 m_sortKey3->setEnabled( false );
00122 sort3BoxLayout->addWidget( m_sortKey3 );
00123
00124 m_sortOrder3 = new QComboBox( false, sort3Box, "m_sortOrder3" );
00125 m_sortOrder3->insertItem( i18n( "Ascending" ) );
00126 m_sortOrder3->insertItem( i18n( "Descending" ) );
00127 m_sortOrder3->setEnabled( false );
00128 sort3BoxLayout->addWidget( m_sortOrder3 );
00129
00130 page1Layout->addWidget( sort3Box, 2, 0 );
00131 m_tabWidget->insertTab( m_page1, i18n( "Sort Criteria" ) );
00132
00133
00134
00135
00136 m_page2 = new QWidget( m_tabWidget, "m_page2" );
00137 QGridLayout * page2Layout = new QGridLayout( m_page2, 1, 1, 11, 6, "page2Layout");
00138
00139 QGroupBox * firstKeyBox = new QGroupBox( m_page2, "firstKeyBox" );
00140 firstKeyBox->setTitle( i18n( "First Key" ) );
00141 firstKeyBox->setColumnLayout(0, Qt::Vertical );
00142 firstKeyBox->layout()->setSpacing( KDialog::spacingHint() );
00143 firstKeyBox->layout()->setMargin( KDialog::marginHint() );
00144 QVBoxLayout * firstKeyBoxLayout = new QVBoxLayout( firstKeyBox->layout() );
00145 firstKeyBoxLayout->setAlignment( Qt::AlignTop );
00146
00147 m_useCustomLists = new QCheckBox( firstKeyBox, "m_useCustomLists_2" );
00148 m_useCustomLists->setText( i18n( "&Use custom list" ) );
00149 firstKeyBoxLayout->addWidget( m_useCustomLists );
00150
00151 m_customList = new QComboBox( false, firstKeyBox, "m_customList" );
00152 m_customList->setEnabled( false );
00153 m_customList->setMaximumSize( 230, 30 );
00154 firstKeyBoxLayout->addWidget( m_customList );
00155
00156 page2Layout->addWidget( firstKeyBox, 0, 1 );
00157
00158 QButtonGroup * orientationGroup = new QButtonGroup( m_page2, "orientationGroup" );
00159 orientationGroup->setTitle( i18n( "Orientation" ) );
00160 orientationGroup->setColumnLayout(0, Qt::Vertical );
00161 orientationGroup->layout()->setSpacing( KDialog::spacingHint() );
00162 orientationGroup->layout()->setMargin( KDialog::marginHint() );
00163 QGridLayout * orientationGroupLayout = new QGridLayout( orientationGroup->layout() );
00164 orientationGroupLayout->setAlignment( Qt::AlignTop );
00165
00166 m_sortColumn = new QRadioButton( orientationGroup, "m_sortColumn" );
00167 m_sortColumn->setText( i18n( "&Column" ) );
00168 m_sortColumn->setChecked( true );
00169
00170 orientationGroupLayout->addWidget( m_sortColumn, 0, 0 );
00171
00172 m_sortRow = new QRadioButton( orientationGroup, "m_sortRow" );
00173 m_sortRow->setText( i18n( "&Row" ) );
00174
00175 orientationGroupLayout->addWidget( m_sortRow, 1, 0 );
00176
00177 page2Layout->addWidget( orientationGroup, 0, 0 );
00178
00179 m_copyLayout = new QCheckBox( m_page2, "m_copyLayout" );
00180 m_copyLayout->setText( i18n( "Copy &layout" ) );
00181
00182 page2Layout->addMultiCellWidget( m_copyLayout, 2, 2, 0, 1 );
00183
00184 m_firstRowHeader = new QCheckBox( m_page2, "m_copyLayout" );
00185 m_firstRowHeader->setText( i18n( "&First row contains header" ) );
00186
00187 page2Layout->addMultiCellWidget( m_firstRowHeader, 3, 3, 0, 1 );
00188
00189 m_respectCase = new QCheckBox( m_page2, "m_copyLayout" );
00190 m_respectCase->setText( i18n( "Respect case" ) );
00191 m_respectCase->setChecked( true );
00192
00193 page2Layout->addMultiCellWidget( m_respectCase, 4, 4, 0, 1 );
00194
00195
00196 QGroupBox * resultToBox = new QGroupBox( m_page2, "resultToBox" );
00197 resultToBox->setTitle( i18n( "Put Results To" ) );
00198 resultToBox->setColumnLayout(0, Qt::Vertical );
00199 resultToBox->layout()->setSpacing( KDialog::spacingHint() );
00200 resultToBox->layout()->setMargin( KDialog::marginHint() );
00201 QHBoxLayout * resultToBoxLayout = new QHBoxLayout( resultToBox->layout() );
00202 resultToBoxLayout->setAlignment( Qt::AlignTop );
00203
00204 m_outputSheet = new QComboBox( false, resultToBox, "m_outputSheet" );
00205 resultToBoxLayout->addWidget( m_outputSheet );
00206 QSpacerItem * spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
00207 resultToBoxLayout->addItem( spacer );
00208
00209 QLabel * startingCellLabel = new QLabel( resultToBox, "startingCellLabel" );
00210 startingCellLabel->setText( i18n( "Starting cell:" ) );
00211 resultToBoxLayout->addWidget( startingCellLabel );
00212
00213 m_outputCell = new QLineEdit( resultToBox, "m_outputCell" );
00214 m_outputCell->setMaximumSize( QSize( 60, 32767 ) );
00215 resultToBoxLayout->addWidget( m_outputCell );
00216
00217 page2Layout->addMultiCellWidget( resultToBox, 1, 1, 0, 1 );
00218 m_tabWidget->insertTab( m_page2, i18n( "Options" ) );
00219
00220 QHBoxLayout * Layout1 = new QHBoxLayout( 0, 0, 6, "Layout1");
00221 QSpacerItem * spacer_2 = new QSpacerItem( 20, 20, QSizePolicy::Expanding,
00222 QSizePolicy::Minimum );
00223 Layout1->addItem( spacer_2 );
00224
00225 connect( m_sortKey2, SIGNAL( activated( int ) ), this,
00226 SLOT( sortKey2textChanged( int ) ) );
00227 connect( m_useCustomLists, SIGNAL( stateChanged(int) ), this,
00228 SLOT( useCustomListsStateChanged(int) ) );
00229 connect( m_firstRowHeader, SIGNAL( stateChanged(int) ), this,
00230 SLOT( firstRowHeaderChanged(int) ) );
00231 connect( orientationGroup, SIGNAL( pressed(int) ), this,
00232 SLOT( slotOrientationChanged(int) ) );
00233
00234 init();
00235 }
00236
00237 KSpreadSortDlg::~KSpreadSortDlg()
00238 {
00239
00240 }
00241
00242 void KSpreadSortDlg::init()
00243 {
00244 QStringList lst;
00245 lst<<i18n("January");
00246 lst<<i18n("February");
00247 lst<<i18n("March");
00248 lst<<i18n("April");
00249 lst<<i18n("May");
00250 lst<<i18n("June");
00251 lst<<i18n("July");
00252 lst<<i18n("August");
00253 lst<<i18n("September");
00254 lst<<i18n("October");
00255 lst<<i18n("November");
00256 lst<<i18n("December");
00257
00258 lst<<i18n("Monday");
00259 lst<<i18n("Tuesday");
00260 lst<<i18n("Wednesday");
00261 lst<<i18n("Thursday");
00262 lst<<i18n("Friday");
00263 lst<<i18n("Saturday");
00264 lst<<i18n("Sunday");
00265
00266 KConfig * config = KSpreadFactory::global()->config();
00267 config->setGroup( "Parameters" );
00268 QStringList other = config->readListEntry("Other list");
00269 QString tmp;
00270 for ( QStringList::Iterator it = other.begin(); it != other.end(); ++it )
00271 {
00272 if((*it) != "\\")
00273 tmp += (*it) + ", ";
00274 else if( it != other.begin())
00275 {
00276 tmp = tmp.left(tmp.length() - 2);
00277 lst.append(tmp);
00278 tmp = "";
00279 }
00280 }
00281 m_customList->insertStringList(lst);
00282
00283 QPtrList<KSpreadSheet> sheetList = m_pView->doc()->map()->sheetList();
00284 for (unsigned int c = 0; c < sheetList.count(); ++c)
00285 {
00286 KSpreadSheet * t = sheetList.at(c);
00287 if (!t)
00288 continue;
00289 m_outputSheet->insertItem( t->sheetName() );
00290 }
00291 m_outputSheet->setCurrentText( m_pView->activeSheet()->sheetName() );
00292
00293 QRect r = m_pView->selection();
00294 QString cellArea;
00295 cellArea += KSpreadCell::columnName(r.left());
00296 cellArea += QString::number( r.top() );
00297 m_outputCell->setText( cellArea );
00298
00299
00300 if ( util_isColumnSelected(r) )
00301 {
00302 m_sortRow->setEnabled(false);
00303 m_sortColumn->setChecked(true);
00304
00305 int right = r.right();
00306 for (int i = r.left(); i <= right; ++i)
00307 m_listColumn += i18n("Column %1").arg(KSpreadCell::columnName(i));
00308 }
00309
00310 else if ( util_isRowSelected(r) )
00311 {
00312 m_sortColumn->setEnabled(false);
00313 m_sortRow->setChecked(true);
00314
00315 int bottom = r.bottom();
00316 for (int i = r.top(); i <= bottom; ++i)
00317 m_listRow += i18n("Row %1").arg(i);
00318 }
00319 else
00320 {
00321
00322 if ( r.top() == r.bottom() )
00323 {
00324 m_sortColumn->setEnabled(false);
00325 m_sortRow->setChecked(true);
00326 }
00327
00328 else if (r.left() == r.right())
00329 {
00330 m_sortRow->setEnabled(false);
00331 m_sortColumn->setChecked(true);
00332 }
00333 else
00334 {
00335 m_sortColumn->setChecked(true);
00336 }
00337
00338 int right = r.right();
00339 int bottom = r.bottom();
00340 for (int i = r.left(); i <= right; ++i)
00341 m_listColumn += i18n("Column %1").arg(KSpreadCell::columnName(i));
00342
00343 for (int i = r.top(); i <= bottom; ++i)
00344 m_listRow += i18n("Row %1").arg(i);
00345 }
00346
00347
00348 if ( m_sortRow->isChecked() )
00349 slotOrientationChanged(1);
00350 else
00351 slotOrientationChanged(0);
00352 }
00353
00354 void KSpreadSortDlg::slotOrientationChanged(int id)
00355 {
00356 switch( id )
00357 {
00358 case 0 :
00359 m_sortKey1->clear();
00360 m_sortKey2->clear();
00361 m_sortKey3->clear();
00362 m_sortKey1->insertStringList(m_listColumn);
00363 m_sortKey2->insertItem( i18n("None") );
00364 m_sortKey2->insertStringList(m_listColumn);
00365 m_sortKey3->insertItem( i18n("None") );
00366 m_sortKey3->insertStringList(m_listColumn);
00367 break;
00368
00369 case 1 :
00370 m_sortKey1->clear();
00371 m_sortKey2->clear();
00372 m_sortKey3->clear();
00373 m_sortKey1->insertStringList(m_listRow);
00374 m_sortKey2->insertItem( i18n("None") );
00375 m_sortKey2->insertStringList(m_listRow);
00376 m_sortKey3->insertItem( i18n("None") );
00377 m_sortKey3->insertStringList(m_listRow);
00378
00379 if (m_firstRowHeader->isChecked())
00380 {
00381 int k1 = m_sortKey1->currentItem();
00382 int k2 = m_sortKey2->currentItem();
00383 int k3 = m_sortKey3->currentItem();
00384 m_sortKey1->removeItem( 0 );
00385 m_sortKey2->removeItem( 1 );
00386 m_sortKey3->removeItem( 1 );
00387 if (k1 > 0)
00388 m_sortKey1->setCurrentItem(--k1);
00389 else
00390 m_sortKey1->setCurrentItem( 0 );
00391 if (k2 > 0)
00392 m_sortKey2->setCurrentItem(--k2);
00393 if (k3 > 0)
00394 m_sortKey3->setCurrentItem(--k3);
00395 }
00396
00397 break;
00398
00399 default :
00400 kdDebug(36001) << "Error in signal : pressed(int id)" << endl;
00401 break;
00402 }
00403 }
00404
00405 void KSpreadSortDlg::slotOk()
00406 {
00407 m_pView->doc()->emitBeginOperation( false );
00408
00409 KSpreadSheet * sheet = m_pView->doc()->map()->findSheet( m_outputSheet->currentText() );
00410 if ( !sheet )
00411 {
00412 KMessageBox::error( this, i18n("The selected output table does not exist.") );
00413 m_outputSheet->setFocus();
00414 m_tabWidget->setTabEnabled(m_page2, true);
00415 m_pView->slotUpdateView( m_pView->activeSheet() );
00416 return;
00417 }
00418
00419 KSpreadPoint outputPoint( m_outputCell->text() );
00420 if ( !outputPoint.isValid() || outputPoint.isSheetKnown() )
00421 {
00422 KMessageBox::error( this, i18n("The output cell is invalid.") );
00423 m_outputCell->setFocus();
00424 m_tabWidget->setTabEnabled(m_page2, true);
00425 m_pView->slotUpdateView( m_pView->activeSheet() );
00426 return;
00427 }
00428 outputPoint.sheet = sheet;
00429
00430 QRect r = m_pView->selection();
00431 if ( r.topLeft() != outputPoint.pos )
00432 {
00433 int h = outputPoint.pos.y() + r.height();
00434 int w = outputPoint.pos.x() + r.width();
00435
00436 if ( r.contains(outputPoint.pos)
00437 || ( w >= r.left() && w <= r.right() )
00438 || ( h >= r.top() && h <= r.bottom() ) )
00439 {
00440 KMessageBox::error( this, i18n("The output region must not overlap with the source region.") );
00441 m_outputCell->setFocus();
00442 m_pView->slotUpdateView( m_pView->activeSheet() );
00443
00444 return;
00445 }
00446 }
00447
00448 int key1 = 1;
00449 int key2 = 0;
00450 int key3 = 0;
00451 QStringList * firstKey = 0L;
00452 KSpreadSheet::SortingOrder order1;
00453 KSpreadSheet::SortingOrder order2;
00454 KSpreadSheet::SortingOrder order3;
00455
00456 order1 = ( m_sortOrder1->currentItem() == 0 ? KSpreadSheet::Increase
00457 : KSpreadSheet::Decrease );
00458 order2 = ( m_sortOrder2->currentItem() == 0 ? KSpreadSheet::Increase
00459 : KSpreadSheet::Decrease );
00460 order3 = ( m_sortOrder3->currentItem() == 0 ? KSpreadSheet::Increase
00461 : KSpreadSheet::Decrease );
00462
00463 if ( m_sortRow->isChecked() )
00464 {
00465 key1 = m_sortKey1->currentItem() + r.top();
00466 if (m_sortKey2->currentItem() > 0)
00467 key2 = m_sortKey2->currentItem() + r.top() - 1;
00468 if (m_sortKey3->currentItem() > 0)
00469 key3 = m_sortKey3->currentItem() + r.top() - 1;
00470
00471 if (m_firstRowHeader->isChecked())
00472 {
00473 if (key1 >= 0)
00474 ++key1;
00475 if (key2 > 0)
00476 ++key2;
00477 if (key3 > 0)
00478 ++key3;
00479 }
00480 }
00481 else
00482 {
00483 key1 = m_sortKey1->currentItem() + r.left();
00484 if (m_sortKey2->currentItem() > 0)
00485 key2 = m_sortKey2->currentItem() + r.left() - 1;
00486 if (m_sortKey3->currentItem() > 0)
00487 key3 = m_sortKey3->currentItem() + r.left() - 1;
00488 }
00489
00490 if ( m_useCustomLists->isChecked() )
00491 {
00492 firstKey = new QStringList();
00493 QString list = m_customList->currentText();
00494 QString tmp;
00495 int l = list.length();
00496 for ( int i = 0; i < l; ++i )
00497 {
00498 if ( list[i] == ',' )
00499 {
00500 firstKey->append( tmp.stripWhiteSpace() );
00501 tmp = "";
00502 }
00503 else
00504 tmp += list[i];
00505 }
00506 }
00507
00508 if (key1 == key2)
00509 key2 = 0;
00510
00511 if (key1 == key3)
00512 key3 = 0;
00513
00514 if (key2 == 0 && key3 > 0)
00515 {
00516 key2 = key3;
00517 key3 = 0;
00518 }
00519
00520 if ( m_sortRow->isChecked() )
00521 {
00522 m_pView->activeSheet()->sortByRow( m_pView->selection(), key1, key2, key3,
00523 order1, order2, order3,
00524 firstKey, m_copyLayout->isChecked(),
00525 m_firstRowHeader->isChecked(),
00526 outputPoint, m_respectCase->isChecked() );
00527 }
00528 else if (m_sortColumn->isChecked())
00529 {
00530 m_pView->activeSheet()->sortByColumn( m_pView->selection(), key1, key2, key3,
00531 order1, order2, order3,
00532 firstKey, m_copyLayout->isChecked(),
00533 m_firstRowHeader->isChecked(),
00534 outputPoint, m_respectCase->isChecked() );
00535 }
00536 else
00537 {
00538 kdDebug(36001) << "Err in radiobutton" << endl;
00539 }
00540
00541 delete firstKey;
00542 firstKey = 0L;
00543
00544 m_pView->slotUpdateView( m_pView->activeSheet() );
00545 accept();
00546 }
00547
00548 void KSpreadSortDlg::sortKey2textChanged( int i )
00549 {
00550 m_sortKey3->setEnabled( ( i!=0 ) );
00551 m_sortOrder3->setEnabled( ( i!=0 ) );
00552 }
00553
00554 void KSpreadSortDlg::useCustomListsStateChanged( int state )
00555 {
00556 if (state == 0)
00557 m_customList->setEnabled(false);
00558 else if (state == 2)
00559 m_customList->setEnabled(true);
00560 }
00561
00562 void KSpreadSortDlg::firstRowHeaderChanged( int state )
00563 {
00564 if (m_sortColumn->isChecked())
00565 return;
00566
00567 if (state == 0)
00568 {
00569 int k1 = m_sortKey1->currentItem();
00570 int k2 = m_sortKey2->currentItem();
00571 int k3 = m_sortKey3->currentItem();
00572 m_sortKey1->clear();
00573 m_sortKey2->clear();
00574 m_sortKey3->clear();
00575 m_sortKey1->insertStringList(m_listRow);
00576 m_sortKey2->insertItem( i18n("None") );
00577 m_sortKey2->insertStringList(m_listRow);
00578 m_sortKey3->insertItem( i18n("None") );
00579 m_sortKey3->insertStringList(m_listRow);
00580
00581 m_sortKey1->setCurrentItem(++k1);
00582 m_sortKey2->setCurrentItem(++k2);
00583 m_sortKey3->setCurrentItem(++k3);
00584 }
00585 else if (state == 2)
00586 {
00587 int k1 = m_sortKey1->currentItem();
00588 int k2 = m_sortKey2->currentItem();
00589 int k3 = m_sortKey3->currentItem();
00590 m_sortKey1->removeItem( 0 );
00591 m_sortKey2->removeItem( 1 );
00592 m_sortKey3->removeItem( 1 );
00593 if (k1 > 0)
00594 m_sortKey1->setCurrentItem(--k1);
00595 if (k2 > 0)
00596 m_sortKey2->setCurrentItem(--k2);
00597 if (k3 > 0)
00598 m_sortKey3->setCurrentItem(--k3);
00599 }
00600 }
00601
00602 #include "kspread_dlg_sort.moc"