00001 #include "qsedataexport.h"
00002 #include <QDirModel>
00003 #include <QString>
00004 #include "qsesettings.h"
00005 #include <QMessageBox>
00006
00007 QseDataExport::QseDataExport(const QString &id, QseDataSet *data, QList<int> selections, QWidget *parent)
00008 : QDialog(parent),
00009 m_Identifier(id),
00010 m_Selections(selections),
00011 m_DataSet(data)
00012 {
00013 ui.setupUi(this);
00014
00015 readSettings();
00016
00017 int i;
00018 int nscans = data->scanCount();
00019
00020 for (i = 0; i<nscans; i++) {
00021 QString scanname = data->scan(i)->name();
00022
00023 ui.m_ScanList->addItem(scanname);
00024 }
00025
00026 scanRevert();
00027
00028 ui.m_DirectoryView->setModel(&m_DirModel);
00029 ui.m_DirectoryView->hideColumn(1);
00030 ui.m_DirectoryView->hideColumn(2);
00031 ui.m_DirectoryView->hideColumn(3);
00032
00033 updateNewDirectory();
00034
00035 ui.m_OutputPatternEdit -> setText(m_OutputPattern);
00036
00037 ui.m_SaveHeaderOption -> setChecked(m_Options & SaveHeader);
00038 ui.m_BriefHeaderOption -> setChecked(m_Options & BriefHeader);
00039 ui.m_SingleFileOption -> setChecked(m_Options & SingleFile);
00040 ui.m_FileHeaderInEachOption -> setChecked(m_Options & FileHeaderInEach);
00041 ui.m_ColumnHeaderLineOption -> setChecked(m_Options & ColumnHeaderLine);
00042 ui.m_AutoRenameOption -> setChecked(m_Options & AutoRename);
00043
00044 setWindowTitle(QString("Export Data from %1").arg(data->fileName()));
00045 setupConnections();
00046 }
00047
00048 void QseDataExport::setupConnections()
00049 {
00050 connect(ui.m_DirectoryCombo, SIGNAL(currentIndexChanged(const QString&)),
00051 this, SLOT(directoryChanged(const QString&)));
00052
00053 connect(ui.m_DirectoryUpButton, SIGNAL(clicked()), this, SLOT(upDirectory()));
00054 connect(ui.m_DirectoryHomeButton, SIGNAL(clicked()), this, SLOT(homeDirectory()));
00055 connect(ui.m_DirectoryView, SIGNAL(doubleClicked(const QModelIndex&)),
00056 this, SLOT(directoryChanged(const QModelIndex&)));
00057
00058 connect(ui.m_ScanSelectAllButton, SIGNAL(clicked()), this, SLOT(scanSelectAll()));
00059 connect(ui.m_ScanSelectNoneButton, SIGNAL(clicked()), this, SLOT(scanSelectNone()));
00060 connect(ui.m_ScanRevertButton, SIGNAL(clicked()), this, SLOT(scanRevert()));
00061
00062 connect(ui.m_OutputPatternEdit, SIGNAL(textChanged(const QString&)), this, SLOT(newOutputPattern(const QString&)));
00063 connect(ui.m_SaveHeaderOption, SIGNAL(clicked(bool)), this, SLOT(saveHeaderOptionChanged(bool)));
00064 connect(ui.m_BriefHeaderOption, SIGNAL(clicked(bool)), this, SLOT(briefHeaderOptionChanged(bool)));
00065 connect(ui.m_SingleFileOption, SIGNAL(clicked(bool)), this, SLOT(singleFileOptionChanged(bool)));
00066 connect(ui.m_FileHeaderInEachOption, SIGNAL(clicked(bool)), this, SLOT(fileHeaderInEachOptionChanged(bool)));
00067 connect(ui.m_ColumnHeaderLineOption, SIGNAL(clicked(bool)), this, SLOT(columnHeaderLineOptionChanged(bool)));
00068 connect(ui.m_AutoRenameOption, SIGNAL(clicked(bool)), this, SLOT(autoRenameOptionChanged(bool)));
00069
00070 connect(ui.m_ButtonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(okPressed()));
00071 connect(ui.m_ButtonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(applyPressed()));
00072 }
00073
00074 void QseDataExport::newOutputPattern(const QString &patt)
00075 {
00076 m_OutputPattern = patt;
00077 }
00078
00079 void QseDataExport::saveHeaderOptionChanged(bool opt)
00080 {
00081 if (opt) {
00082 m_Options |= SaveHeader;
00083 } else {
00084 m_Options &= ~SaveHeader;
00085 }
00086 }
00087
00088 void QseDataExport::briefHeaderOptionChanged(bool opt)
00089 {
00090 if (opt) {
00091 m_Options |= BriefHeader;
00092 } else {
00093 m_Options &= ~BriefHeader;
00094 }
00095 }
00096
00097 void QseDataExport::singleFileOptionChanged(bool opt)
00098 {
00099 if (opt) {
00100 m_Options |= SingleFile;
00101 } else {
00102 m_Options &= ~SingleFile;
00103 }
00104 }
00105
00106 void QseDataExport::fileHeaderInEachOptionChanged(bool opt)
00107 {
00108 if (opt) {
00109 m_Options |= FileHeaderInEach;
00110 } else {
00111 m_Options &= ~FileHeaderInEach;
00112 }
00113 }
00114
00115 void QseDataExport::columnHeaderLineOptionChanged(bool opt)
00116 {
00117 if (opt) {
00118 m_Options |= ColumnHeaderLine;
00119 } else {
00120 m_Options &= ~ColumnHeaderLine;
00121 }
00122 }
00123
00124 void QseDataExport::autoRenameOptionChanged(bool opt)
00125 {
00126 if (opt) {
00127 m_Options |= AutoRename;
00128 } else {
00129 m_Options &= ~AutoRename;
00130 }
00131 }
00132
00133 void QseDataExport::exportSelectedData(const QString &id, QseDataSet *data, QList<int> selections)
00134 {
00135 QseDataExport dialog(id, data, selections);
00136
00137 dialog.exec();
00138 }
00139
00140 void QseDataExport::updateNewDirectory()
00141 {
00142 ui.m_DirectoryView->setRootIndex(m_DirModel.index(m_OutputDir.path()));
00143
00144 ui.m_DirectoryCombo->blockSignals(true);
00145
00146 ui.m_DirectoryCombo->clear();
00147
00148 QDir qd = m_OutputDir;
00149
00150 do {
00151 if (qd.exists()) ui.m_DirectoryCombo->addItem(qd.absolutePath());
00152 } while(qd.cdUp());
00153
00154 ui.m_DirectoryCombo->blockSignals(false);
00155 }
00156
00157 void QseDataExport::upDirectory()
00158 {
00159 m_OutputDir.cdUp();
00160
00161 updateNewDirectory();
00162 }
00163
00164 void QseDataExport::homeDirectory()
00165 {
00166 m_OutputDir.cd(QDir::currentPath());
00167
00168 updateNewDirectory();
00169 }
00170
00171 void QseDataExport::directoryChanged(const QModelIndex& index)
00172 {
00173 QString fp = m_DirModel.filePath(index);
00174
00175 directoryChanged(fp);
00176 }
00177
00178 void QseDataExport::directoryChanged(const QString& newdir)
00179 {
00180 QDir qd(newdir);
00181
00182 if (qd.exists()) {
00183 m_OutputDir.cd(newdir);
00184
00185 updateNewDirectory();
00186 }
00187 }
00188
00189 void QseDataExport::scanSelectAll()
00190 {
00191 ui.m_ScanList->selectAll();
00192 }
00193
00194 void QseDataExport::scanSelectNone()
00195 {
00196 ui.m_ScanList->clearSelection();
00197 }
00198
00199 void QseDataExport::scanRevert()
00200 {
00201 int i;
00202 ui.m_ScanList->clearSelection();
00203
00204 foreach(i, m_Selections) {
00205 QModelIndex sel = ui.m_ScanList->model()->index(i,0);
00206
00207 ui.m_ScanList->selectionModel()->select(sel, QItemSelectionModel::Select);
00208 }
00209 }
00210
00211 QList<int> QseDataExport::selectedScans() const
00212 {
00213 QList<int> res;
00214 QList<QListWidgetItem*> selected = ui.m_ScanList->selectedItems();
00215 QListWidgetItem* w;
00216
00217 foreach(w, selected) {
00218 res.append(ui.m_ScanList->row(w));
00219 }
00220
00221 return res;
00222 }
00223
00224 bool QseDataExport::checkForOverwriting()
00225 {
00226 QString patt = ui.m_OutputPatternEdit -> text();
00227 QList<int> items = selectedScans();
00228 QList<QString> dups;
00229 QList<QString> files;
00230 int i, nd=0, nid=0;
00231
00232 foreach(i, items) {
00233 QString fnam = substituteFilenamePatterns(patt, i, m_DataSet);
00234
00235 if (QFile::exists(m_OutputDir.filePath(fnam))) {
00236 dups.append(fnam);
00237 }
00238
00239 if (files.contains(fnam)) {
00240 nid++;
00241 }
00242 }
00243
00244 nd = dups.count();
00245 QString msg;
00246
00247 if (nd) {
00248 msg.append(QString("%1 files will be overwritten by this operation").arg(nd));
00249 for (i = 0; i < qMin(5, nd); i++) {
00250 msg.append("\n");
00251 msg.append(dups[i]);
00252 }
00253
00254 if (nd > 5) {
00255 msg.append("\n...");
00256 }
00257 }
00258
00259 if (nid) {
00260 msg.append(QString("%1 of the output file names are duplicated").arg(nd));
00261 }
00262
00263 if (nd || nid) {
00264 msg.append("\nHow do you want to proceed?");
00265 QMessageBox msgBox;
00266 QPushButton *goAheadButton = msgBox.addButton("Overwrite", QMessageBox::ActionRole);
00267 QPushButton *renameButton = msgBox.addButton("Rename", QMessageBox::ActionRole);
00268 QPushButton *cancelButton = msgBox.addButton("Cancel", QMessageBox::ActionRole);
00269
00270 msgBox.setWindowTitle("Overwrite...");
00271 msgBox.setText("Some of the filenames to be used for output are either duplicated or already exist. What do you want to do?");
00272 msgBox.setDetailedText(msg);
00273 msgBox.setIcon(QMessageBox::Question);
00274
00275 msgBox.exec();
00276
00277 if (msgBox.clickedButton() == goAheadButton) {
00278 return true;
00279 } else if (msgBox.clickedButton() == renameButton) {
00280 if (! ui.m_AutoRenameOption->isChecked()) {
00281 ui.m_AutoRenameOption -> click();
00282 }
00283 return true;
00284 } else {
00285 return false;
00286 }
00287 }
00288
00289 return true;
00290 }
00291
00292 void QseDataExport::okPressed()
00293 {
00294 if (checkForOverwriting()) {
00295 }
00296
00297 writeSettings();
00298 }
00299
00300 void QseDataExport::applyPressed()
00301 {
00302 if (checkForOverwriting()) {
00303 QString patt = ui.m_OutputPatternEdit -> text();
00304 int i;
00305 QList<int> selected = selectedScans();
00306 FILE *f = NULL;
00307 bool headerdone = false;
00308
00309 foreach(i, selected) {
00310 QseScan *scan = m_DataSet -> scan(i);
00311 int nrows = scan -> maxRowCount();
00312 int ncols = scan -> columnCount();
00313
00314 if (f == NULL) {
00315 QString fnam;
00316
00317 if (m_Options & SingleFile) {
00318 fnam = substituteFilenamePatterns(patt, 0, m_DataSet);
00319 } else {
00320 fnam = substituteFilenamePatterns(patt, i, m_DataSet);
00321 }
00322
00323 if (QFile::exists(m_OutputDir.filePath(fnam))) {
00324 if (m_Options & AutoRename) {
00325 int n=1;
00326
00327 while (QFile::exists(m_OutputDir.filePath(fnam+QString("_%1").arg(n,5,10,QLatin1Char('0'))))) {
00328 n += 1;
00329 }
00330
00331 fnam = fnam+QString("_%1").arg(n,5,10,QLatin1Char('0'));
00332 } else {
00333 printf("Duplicate file name %s\n", qPrintable(fnam));
00334 }
00335 }
00336
00337 printf("Scan %d : %s\n", i, qPrintable(fnam));
00338 f = fopen(qPrintable(m_OutputDir.filePath(fnam)), "w");
00339 headerdone = false;
00340 }
00341
00342 if (f) {
00343 if (!headerdone) {
00344 if (m_Options & FileHeaderInEach) {
00345 QString s;
00346 QStringList hdr = m_DataSet->header();
00347
00348 foreach(s,hdr) {
00349 fputs(qPrintable(s), f);
00350 fputs("\n", f);
00351 }
00352 }
00353
00354 if (m_Options & SaveHeader) {
00355 QString s;
00356 QStringList hdr = scan->header();
00357
00358 foreach(s,hdr) {
00359 fputs(qPrintable(s), f);
00360 fputs("\n", f);
00361 }
00362 } else if (m_Options & BriefHeader) {
00363 fputs(qPrintable(scan->scanCommand()),f);
00364 fputs("\n", f);
00365
00366 fprintf(f, "#N %d\n", ncols);
00367 fprintf(f, "#L");
00368
00369 for (int i=0; i<ncols; i++) {
00370 QseColumn *col = scan->column(i);
00371 fprintf(f, " %s", qPrintable(col->name()));
00372 }
00373
00374 fprintf(f,"\n");
00375 }
00376
00377 if (m_Options & ColumnHeaderLine) {
00378 for (int i=0; i<ncols; i++) {
00379 QseColumn *col = scan->column(i);
00380 if (i == 0) {
00381 fputs(qPrintable(col->name()),f);
00382 } else{
00383 fprintf(f, "\t%s", qPrintable(col->name()));
00384 }
00385 }
00386
00387 fprintf(f,"\n");
00388 }
00389
00390 headerdone = true;
00391 }
00392
00393 for (int r=0; r<nrows; r++) {
00394 for (int c=0; c<ncols; c++) {
00395 if (c == 0) {
00396 fprintf(f, "%g",scan->column(c)->data(r));
00397 } else {
00398 fprintf(f, "\t%g",scan->column(c)->data(r));
00399 }
00400 }
00401 fprintf(f, "\n");
00402 }
00403
00404 if (!(m_Options & SingleFile)) {
00405 fclose(f);
00406 f = NULL;
00407 }
00408 }
00409 }
00410
00411 writeSettings();
00412 }
00413 }
00414
00415 QString QseDataExport::substituteFilenamePatterns(const QString &patt, int index, const QseDataSet *ds)
00416 {
00417 QseScan *scan = ds->scan(index);
00418 QString fnam = ds->fileName();
00419 int scannum = scan -> scanNumber();
00420 QDateTime dt = scan -> scanDateTime();
00421
00422 QString res = patt;
00423
00424 res.replace("%i", QString("%1").arg(index+1));
00425 res.replace("%n", QString("%1").arg(scannum));
00426 res.replace("%f", QFileInfo(fnam).completeBaseName());
00427 res.replace("%x", QFileInfo(fnam).suffix());
00428 res.replace("%d", dt.toString("yyyyMMdd_hhmmss"));
00429 res.replace("%t", dt.toString("yyyyMMdd"));
00430
00431 return res;
00432 }
00433
00434 void QseDataExport::readSettings()
00435 {
00436 QseSettings settings;
00437
00438 m_Options = settings.value(QString("%1/options").arg(m_Identifier),0).toInt();
00439 m_OutputDir.cd(settings.value(QString("%1/outputdir").arg(m_Identifier),QDir::currentPath()).toString());
00440 m_OutputPattern = settings.value(QString("%1/outputpattern").arg(m_Identifier),"%f_%d_%n").toString();
00441 }
00442
00443 void QseDataExport::writeSettings()
00444 {
00445 QSettings settings;
00446
00447 settings.setValue(QString("%1/options").arg(m_Identifier), int(m_Options));
00448 settings.setValue(QString("%1/outputdir").arg(m_Identifier), m_OutputDir.absolutePath());
00449 settings.setValue(QString("%1/outputpattern").arg(m_Identifier), m_OutputPattern);
00450 }