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
00029
00030
00031
00032
00033
00034 #include "sortdlg.h"
00035
00036
00037 #include <qlabel.h>
00038 #include <qradiobutton.h>
00039 #include <qmessagebox.h>
00040
00041 SortDialog::SortDialog(QWidget *parent)
00042 :QDialog(parent, 0, TRUE)
00043 {
00044
00045 tabs=new QTabWidget(this);
00046 widgetSort=new QWidget(tabs);
00047 widgetOptions=new QWidget(tabs);
00048 tabs->addTab(widgetSort, tr("&Sort"));
00049 tabs->addTab(widgetOptions, tr("&Options"));
00050
00051
00052 comboFieldA=createFieldCombo(tr("&Sort by"), 10);
00053 groupOrderA=createOrderButtons(10);
00054 comboFieldB=createFieldCombo(tr("&Then by"), 90);
00055 groupOrderB=createOrderButtons(90);
00056 comboFieldC=createFieldCombo(tr("Then &by"), 170);
00057 groupOrderC=createOrderButtons(170);
00058
00059
00060 checkCase=new QCheckBox(tr("&Case Sensitive"), widgetOptions);
00061 checkCase->setGeometry(10, 10, 215, 20);
00062 checkCase->setChecked(TRUE);
00063
00064 groupDirection=new QVButtonGroup(tr("&Direction"), widgetOptions);
00065 groupDirection->setGeometry(10, 40, 215, 70);
00066 QRadioButton *radio=new QRadioButton(tr("&Top to bottom (rows)"), groupDirection);
00067 radio=new QRadioButton(tr("&Left to right (columns)"), groupDirection);
00068 groupDirection->setButton(0);
00069 connect(groupDirection, SIGNAL(clicked(int)), this, SLOT(directionChanged(int)));
00070
00071
00072 box=new QVBoxLayout(this);
00073 box->addWidget(tabs);
00074
00075 setCaption(tr("Sort"));
00076 }
00077
00078 SortDialog::~SortDialog()
00079 {}
00080
00081 QComboBox *SortDialog::createFieldCombo(const QString &caption, int y)
00082 {
00083 QLabel *label=new QLabel(caption, widgetSort);
00084 label->setGeometry(10, y+5, 215, 20);
00085 QComboBox *combo=new QComboBox(FALSE, widgetSort);
00086 combo->setGeometry(10, y+35, 105, 20);
00087 label->setBuddy(combo);
00088 return combo;
00089 }
00090
00091 QVButtonGroup *SortDialog::createOrderButtons(int y)
00092 {
00093 QVButtonGroup *group=new QVButtonGroup(widgetSort);
00094 group->setGeometry(125, y, 100, 60);
00095 QRadioButton *radio=new QRadioButton(tr("&Ascending"), group);
00096 radio=new QRadioButton(tr("&Descending"), group);
00097 group->setButton(0);
00098 return group;
00099 }
00100
00101 void SortDialog::directionChanged(int id)
00102 {
00103 direction=id;
00104 fillFieldCombo(comboFieldA);
00105 fillFieldCombo(comboFieldB);
00106 fillFieldCombo(comboFieldC);
00107 }
00108
00109 void SortDialog::fillFieldCombo(QComboBox *combo)
00110 {
00111 combo->clear();
00112 if (direction)
00113 for (int row=row1; row<=row2; ++row)
00114 combo->insertItem("Row "+QString::number(row+1));
00115 else
00116 for (int col=col1; col<=col2; ++col)
00117 combo->insertItem("Column "+Sheet::getHeaderString(col+1));
00118 }
00119
00120 int SortDialog::exec(Sheet *s)
00121 {
00122 sheet=s;
00123 sheet->getSelection(&row1, &col1, &row2, &col2);
00124
00125 direction=0;
00126 fillFieldCombo(comboFieldA);
00127 fillFieldCombo(comboFieldB);
00128 fillFieldCombo(comboFieldC);
00129
00130 if (row1==row2 && col1==col2)
00131 {
00132 QMessageBox::warning(this, tr("Error"), tr("One cell cannot be sorted!"));
00133 return QDialog::Rejected;
00134 }
00135 if (QDialog::exec()==QDialog::Accepted)
00136 {
00137 QString field1S=comboFieldA->currentText(), field2S=comboFieldB->currentText(), field3S=comboFieldC->currentText();
00138 field1S=field1S.mid(field1S.find(' ')+1);
00139 field2S=field2S.mid(field2S.find(' ')+1);
00140 field3S=field3S.mid(field3S.find(' ')+1);
00141 int field1, field2, field3;
00142 if (direction)
00143 {
00144 field1=field1S.toInt()-1;
00145 field2=field2S.toInt()-1;
00146 field3=field3S.toInt()-1;
00147 int i, j;
00148 for (i=col2; i>=col1; --i)
00149 for (j=col1+1; j<=i; ++j)
00150 {
00151 bool swap=FALSE;
00152 int compareResult=compareItems(s->item(field1, j-1), s->item(field1, j), groupOrderA->id(groupOrderA->selected()), checkCase->isChecked());
00153 if (compareResult>0) swap=TRUE;
00154 else if (compareResult==0)
00155 {
00156 compareResult=compareItems(s->item(field2, j-1), s->item(field2, j), groupOrderB->id(groupOrderB->selected()), checkCase->isChecked());
00157 if (compareResult>0) swap=TRUE;
00158 else if (compareResult==0)
00159 {
00160 compareResult=compareItems(s->item(field3, j-1), s->item(field3, j), groupOrderC->id(groupOrderC->selected()), checkCase->isChecked());
00161 if (compareResult>0) swap=TRUE;
00162 }
00163 }
00164 if (swap)
00165 for (int row=row1; row<=row2; ++row)
00166 s->swapCells(row, j-1, row, j);
00167 }
00168 }
00169 else
00170 {
00171 field1=Sheet::getHeaderColumn(field1S)-1;
00172 field2=Sheet::getHeaderColumn(field2S)-1;
00173 field3=Sheet::getHeaderColumn(field3S)-1;
00174 int i, j;
00175 for (i=row2; i>=row1; --i)
00176 for (j=row1+1; j<=i; ++j)
00177 {
00178 bool swap=FALSE;
00179 int compareResult=compareItems(s->item(j-1, field1), s->item(j, field1), groupOrderA->id(groupOrderA->selected()), checkCase->isChecked());
00180 if (compareResult>0) swap=TRUE;
00181 else if (compareResult==0)
00182 {
00183 compareResult=compareItems(s->item(j-1, field2), s->item(j, field2), groupOrderB->id(groupOrderB->selected()), checkCase->isChecked());
00184 if (compareResult>0) swap=TRUE;
00185 else if (compareResult==0)
00186 {
00187 compareResult=compareItems(s->item(j-1, field3), s->item(j, field3), groupOrderC->id(groupOrderC->selected()), checkCase->isChecked());
00188 if (compareResult>0) swap=TRUE;
00189 }
00190 }
00191 if (swap)
00192 for (int col=col1; col<=col2; ++col)
00193 s->swapCells(j-1, col, j, col);
00194 }
00195 }
00196 return QDialog::Accepted;
00197 }
00198 return QDialog::Rejected;
00199 }
00200
00201 int SortDialog::compareItems(QTableItem *item1, QTableItem *item2,
00202 int descending, bool caseSensitive)
00203 {
00204 int result=0;
00205 if (item1)
00206 {
00207 if (item2) result=(caseSensitive ? item1->text().compare(item2->text()) : item1->text().upper().compare(item2->text().upper()));
00208 else result=-1;
00209 }
00210 else
00211 if (item2) result=1;
00212 return (descending ? -result : result);
00213 }