Changeset e0fcac5f2c in tspsg for src/mainwindow.cpp
- Timestamp:
- Oct 24, 2009, 3:37:48 PM (15 years ago)
- Branches:
- 0.1.3.145-beta1-symbian, 0.1.4.170-beta2-bb10, appveyor, imgbot, master, readme
- Children:
- 8af59c4aa3
- Parents:
- 85ad815b0b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/mainwindow.cpp
r85ad815b0b re0fcac5f2c 115 115 } 116 116 117 /*! 118 * \brief Handles Main Window close event. 119 * \param event Close event. 120 * 121 * Checks whether or not a current task was saved and asks for saving if not. 122 * Saves TSPSG settings. 123 */ 124 void MainWindow::closeEvent(QCloseEvent *event) 125 { 126 if (!maybeSave()) { 127 event->ignore(); 128 return; 129 } 130 settings->setValue("NumCities",spinCities->value()); 131 #ifndef Q_OS_WINCE 132 // Saving windows state 133 if (settings->value("SavePos",false).toBool()) { 134 settings->beginGroup("MainWindow"); 135 settings->setValue("Maximized",isMaximized()); 136 if (!isMaximized()) { 137 settings->setValue("Size",size()); 138 settings->setValue("Position",pos()); 139 } 140 settings->endGroup(); 141 } 142 #endif // Q_OS_WINCE 143 QMainWindow::closeEvent(event); 144 } 145 146 /* Privates **********************************************************/ 147 148 void MainWindow::actionFileNewTriggered() 149 { 150 if (!maybeSave()) 151 return; 152 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); 153 tspmodel->clear(); 154 setFileName(); 155 setWindowModified(false); 156 tabWidget->setCurrentIndex(0); 157 solutionText->clear(); 158 enableSolutionActions(false); 159 QApplication::restoreOverrideCursor(); 160 } 161 162 void MainWindow::actionFileOpenTriggered() 163 { 164 if (!maybeSave()) 165 return; 166 QFileDialog od(this); 167 od.setAcceptMode(QFileDialog::AcceptOpen); 168 od.setFileMode(QFileDialog::ExistingFile); 169 QStringList filters(trUtf8("All Supported Formats") + " (*.tspt *.zkt)"); 170 filters.append(trUtf8("%1 Task Files").arg("TSPSG") + " (*.tspt)"); 171 filters.append(trUtf8("%1 Task Files").arg("ZKomModRd") + " (*.zkt)"); 172 filters.append(trUtf8("All Files") + " (*)"); 173 od.setNameFilters(filters); 174 if (od.exec() != QDialog::Accepted) 175 return; 176 QStringList files = od.selectedFiles(); 177 if (files.empty()) 178 return; 179 if (!tspmodel->loadTask(files.first())) 180 return; 181 setFileName(files.first()); 182 tabWidget->setCurrentIndex(0); 183 setWindowModified(false); 184 solutionText->clear(); 185 enableSolutionActions(false); 186 } 187 188 void MainWindow::actionFileSaveTriggered() 189 { 190 if ((fileName == trUtf8("Untitled") + ".tspt") || (!fileName.endsWith(".tspt",Qt::CaseInsensitive))) 191 saveTask(); 192 else 193 if (tspmodel->saveTask(fileName)) 194 setWindowModified(false); 195 } 196 197 void MainWindow::actionFileSaveAsTaskTriggered() 198 { 199 saveTask(); 200 } 201 202 void MainWindow::actionFileSaveAsSolutionTriggered() 203 { 204 static QString selectedFile; 205 if (selectedFile.isEmpty()) 206 #ifndef QT_NO_PRINTER 207 selectedFile = "solution.pdf"; 208 #else 209 selectedFile = "solution.html"; 210 #endif // QT_NO_PRINTER 211 QFileDialog sd(this); 212 sd.setAcceptMode(QFileDialog::AcceptSave); 213 QStringList filters; 214 #ifndef QT_NO_PRINTER 215 filters.append(trUtf8("PDF Files") + "(*.pdf)"); 216 #endif 217 filters.append(trUtf8("HTML Files") + " (*.html *.htm)"); 218 #if QT_VERSION >= 0x040500 219 filters.append(trUtf8("OpenDocument Files") + " (*.odt)"); 220 #endif // QT_VERSION >= 0x040500 221 filters.append(trUtf8("All Files") + " (*)"); 222 sd.setNameFilters(filters); 223 sd.selectFile(selectedFile); 224 if (sd.exec() != QDialog::Accepted) 225 return; 226 QStringList files = sd.selectedFiles(); 227 if (files.empty()) 228 return; 229 selectedFile = files.first(); 230 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); 231 #ifndef QT_NO_PRINTER 232 if (selectedFile.endsWith(".pdf",Qt::CaseInsensitive)) { 233 QPrinter printer(QPrinter::HighResolution); 234 printer.setOutputFormat(QPrinter::PdfFormat); 235 printer.setOutputFileName(selectedFile); 236 solutionText->document()->print(&printer); 237 QApplication::restoreOverrideCursor(); 238 return; 239 } 240 #endif 241 #if QT_VERSION >= 0x040500 242 QTextDocumentWriter dw(selectedFile); 243 if (!(selectedFile.endsWith(".htm",Qt::CaseInsensitive) || selectedFile.endsWith(".html",Qt::CaseInsensitive) || selectedFile.endsWith(".odt",Qt::CaseInsensitive) || selectedFile.endsWith(".txt",Qt::CaseInsensitive))) 244 dw.setFormat("plaintext"); 245 dw.write(solutionText->document()); 246 #else 247 // Qt < 4.5 has no QTextDocumentWriter class 248 QFile file(selectedFile); 249 if (!file.open(QFile::WriteOnly)) { 250 QApplication::restoreOverrideCursor(); 251 return; 252 } 253 QTextStream ts(&file); 254 ts.setCodec(QTextCodec::codecForName("UTF-8")); 255 ts << solutionText->document()->toHtml("UTF-8"); 256 file.close(); 257 #endif // QT_VERSION >= 0x040500 258 QApplication::restoreOverrideCursor(); 259 } 260 261 #ifndef QT_NO_PRINTER 262 void MainWindow::actionFilePrintPreviewTriggered() 263 { 264 QPrintPreviewDialog ppd(printer, this); 265 connect(&ppd,SIGNAL(paintRequested(QPrinter *)),SLOT(printPreview(QPrinter *))); 266 ppd.exec(); 267 } 268 269 void MainWindow::actionFilePrintTriggered() 270 { 271 QPrintDialog pd(printer,this); 272 #if QT_VERSION >= 0x040500 273 // No such methods in Qt < 4.5 274 pd.setOption(QAbstractPrintDialog::PrintSelection,false); 275 pd.setOption(QAbstractPrintDialog::PrintPageRange,false); 276 #endif 277 if (pd.exec() != QDialog::Accepted) 278 return; 279 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); 280 solutionText->document()->print(printer); 281 QApplication::restoreOverrideCursor(); 282 } 283 #endif // QT_NO_PRINTER 284 285 void MainWindow::actionSettingsPreferencesTriggered() 286 { 287 SettingsDialog sd(this); 288 if (sd.exec() != QDialog::Accepted) 289 return; 290 if (sd.colorChanged() || sd.fontChanged()) { 291 initDocStyleSheet(); 292 if (!output.isEmpty() && sd.colorChanged() && (QMessageBox(QMessageBox::Question,trUtf8("Settings Changed"),trUtf8("You have changed color settings.\nDo you wish to apply them to current solution text?"),QMessageBox::Yes | QMessageBox::No,this).exec() == QMessageBox::Yes)) { 293 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); 294 solutionText->clear(); 295 solutionText->setHtml(output.join("")); 296 QApplication::restoreOverrideCursor(); 297 } 298 } 299 } 300 301 void MainWindow::actionSettingsLanguageAutodetectTriggered(bool checked) 302 { 303 if (checked) { 304 settings->remove("Language"); 305 QMessageBox(QMessageBox::Information,trUtf8("Language change"),trUtf8("Language will be autodetected on next application start."),QMessageBox::Ok,this).exec(); 306 } else 307 settings->setValue("Language",groupSettingsLanguageList->checkedAction()->data().toString()); 308 } 309 310 void MainWindow::groupSettingsLanguageListTriggered(QAction *action) 311 { 312 if (actionSettingsLanguageAutodetect->isChecked()) { 313 // We have language autodetection. It needs to be disabled to change language. 314 if (QMessageBox(QMessageBox::Question,trUtf8("Language change"),trUtf8("You have language autodetection turned on.\nIt needs to be off.\nDo you wish to turn it off?"),QMessageBox::Yes | QMessageBox::No,this).exec() == QMessageBox::Yes) { 315 actionSettingsLanguageAutodetect->trigger(); 316 } else 317 return; 318 } 319 bool untitled = (fileName == trUtf8("Untitled") + ".tspt"); 320 if (loadLanguage(action->data().toString())) { 321 settings->setValue("Language",action->data().toString()); 322 retranslateUi(this); 323 if (untitled) 324 setFileName(); 325 } 326 } 327 328 void MainWindow::actionHelpAboutTriggered() 329 { 330 //! \todo TODO: Normal about window :-) 331 QString about = QString::fromUtf8("TSPSG: TSP Solver and Generator\n"); 332 about += QString::fromUtf8(" Version: "BUILD_VERSION"\n"); 333 about += QString::fromUtf8(" Copyright (C) 2007-%1 Lёppa <contacts[at]oleksii[dot]name>\n").arg(QDate::currentDate().toString("yyyy")); 334 about += QString::fromUtf8("Target OS: %1\n").arg(OS); 335 about += "Qt library:\n"; 336 about += QString::fromUtf8(" Compile time: %1\n").arg(QT_VERSION_STR); 337 about += QString::fromUtf8(" Runtime: %1\n").arg(qVersion()); 338 about += QString::fromUtf8("Built on %1 at %2\n").arg(__DATE__).arg(__TIME__); 339 about += QString::fromUtf8(VERSIONID"\n\n"); 340 about += QString::fromUtf8("Algorithm: %1\n").arg(CTSPSolver::getVersionId()); 341 about += "\n"; 342 about += "TSPSG is licensed under the terms of the GNU General Public License. You should have received a copy of the GNU General Public License along with TSPSG."; 343 QMessageBox(QMessageBox::Information,"About",about,QMessageBox::Ok,this).exec(); 344 } 345 346 void MainWindow::buttonBackToTaskClicked() 347 { 348 tabWidget->setCurrentIndex(0); 349 } 350 351 void MainWindow::buttonRandomClicked() 352 { 353 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); 354 tspmodel->randomize(); 355 QApplication::restoreOverrideCursor(); 356 } 357 358 void MainWindow::buttonSolveClicked() 359 { 360 tMatrix matrix; 361 QList<double> row; 362 int n = spinCities->value(); 363 bool ok; 364 for (int r = 0; r < n; r++) { 365 row.clear(); 366 for (int c = 0; c < n; c++) { 367 row.append(tspmodel->index(r,c).data(Qt::UserRole).toDouble(&ok)); 368 if (!ok) { 369 QMessageBox(QMessageBox::Critical,trUtf8("Data error"),trUtf8("Error in cell [Row %1; Column %2]: Invalid data format.").arg(r + 1).arg(c + 1),QMessageBox::Ok,this).exec(); 370 return; 371 } 372 } 373 matrix.append(row); 374 } 375 CTSPSolver solver; 376 sStep *root = solver.solve(n,matrix,this); 377 if (!root) 378 return; 379 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); 380 QColor color = settings->value("Output/Color",DEF_FONT_COLOR).value<QColor>(); 381 output.clear(); 382 output.append("<p>" + trUtf8("Variant #%1").arg(spinVariant->value()) + "</p>"); 383 output.append("<p>" + trUtf8("Task:") + "</p>"); 384 outputMatrix(matrix,output); 385 output.append("<hr>"); 386 output.append("<p>" + trUtf8("Solution of Variant #%1 task").arg(spinVariant->value()) + "</p>"); 387 sStep *step = root; 388 n = 1; 389 while (n <= spinCities->value()) { 390 if (step->prNode->prNode != NULL || (step->prNode->prNode == NULL && step->plNode->prNode == NULL)) { 391 if (n != spinCities->value()) { 392 output.append("<p>" + trUtf8("Step #%1").arg(n++) + "</p>"); 393 outputMatrix(step->matrix,output,step->candidate.nRow,step->candidate.nCol); 394 if (step->alts) 395 output.append("<p class=\"hasalts\">" + trUtf8("This step has alternate candidates for branching.") + "</p>"); 396 output.append("<p> </p>"); 397 } 398 } 399 if (step->prNode->prNode != NULL) 400 step = step->prNode; 401 else if (step->plNode->prNode != NULL) 402 step = step->plNode; 403 else 404 break; 405 } 406 if (solver.isOptimal()) 407 output.append("<p>" + trUtf8("Optimal path:") + "</p>"); 408 else 409 output.append("<p>" + trUtf8("Resulting path:") + "</p>"); 410 output.append("<p> " + solver.getSortedPath() + "</p>"); 411 output.append("<p>" + trUtf8("The price is <b>%1</b> units.").arg(step->price) + "</p>"); 412 if (!solver.isOptimal()) { 413 output.append("<p> </p>"); 414 output.append("<p>" + trUtf8("<b>WARNING!!!</b><br>This result is a record, but it may not be optimal.<br>Iterations need to be continued to check whether this result is optimal or get an optimal one.") + "</p>"); 415 } 416 output.append("<p></p>"); 417 solutionText->setHtml(output.join("")); 418 solutionText->setDocumentTitle(trUtf8("Solution of Variant #%1 task").arg(spinVariant->value())); 419 420 // Scrolling to the end of text. 421 QTextCursor cursor(solutionText->textCursor()); 422 cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); 423 solutionText->setTextCursor(cursor); 424 425 enableSolutionActions(); 426 tabWidget->setCurrentIndex(1); 427 QApplication::restoreOverrideCursor(); 428 } 429 430 void MainWindow::dataChanged() 431 { 432 setWindowModified(true); 433 } 434 435 void MainWindow::dataChanged(const QModelIndex &tl, const QModelIndex &br) 436 { 437 setWindowModified(true); 438 if (settings->value("Autosize",true).toBool()) { 439 for (int k = tl.row(); k <= br.row(); k++) 440 taskView->resizeRowToContents(k); 441 for (int k = tl.column(); k <= br.column(); k++) 442 taskView->resizeColumnToContents(k); 443 } 444 } 445 446 void MainWindow::numCitiesChanged(int nCities) 447 { 448 blockSignals(true); 449 spinCities->setValue(nCities); 450 blockSignals(false); 451 } 452 453 #ifndef QT_NO_PRINTER 454 void MainWindow::printPreview(QPrinter *printer) 455 { 456 solutionText->print(printer); 457 } 458 #endif // QT_NO_PRINTER 459 460 void MainWindow::spinCitiesValueChanged(int n) 461 { 462 int count = tspmodel->numCities(); 463 tspmodel->setNumCities(n); 464 if ((n > count) && settings->value("Autosize",true).toBool()) 465 for (int k = count; k < n; k++) { 466 taskView->resizeColumnToContents(k); 467 taskView->resizeRowToContents(k); 468 } 469 } 470 117 471 void MainWindow::enableSolutionActions(bool enable) 118 472 { … … 126 480 actionFilePrintPreview->setEnabled(enable); 127 481 #endif // QT_NO_PRINTER 482 } 483 484 void MainWindow::initDocStyleSheet() 485 { 486 QColor color = settings->value("Output/Color",DEF_FONT_COLOR).value<QColor>(); 487 QColor hilight; 488 if (color.value() < 192) 489 hilight.setHsv(color.hue(),color.saturation(),127 + qRound(color.value() / 2)); 490 else 491 hilight.setHsv(color.hue(),color.saturation(),color.value() / 2); 492 solutionText->document()->setDefaultStyleSheet("* {color: " + color.name() +";} p {margin: 0px 10px;} table {margin: 5px;} td {padding: 1px 5px;} .hasalts {color: " + hilight.name() + ";} .selected {color: #A00000; font-weight: bold;} .alternate {color: #008000; font-weight: bold;}"); 493 solutionText->document()->setDefaultFont(settings->value("Output/Font",QFont(DEF_FONT_FAMILY,DEF_FONT_SIZE)).value<QFont>()); 494 } 495 496 void MainWindow::loadLangList() 497 { 498 QSettings langinfo(PATH_I18N"/languages.ini",QSettings::IniFormat); 499 #if QT_VERSION >= 0x040500 500 // In Qt < 4.5 QSettings doesn't have method setIniCodec. 501 langinfo.setIniCodec("UTF-8"); 502 #endif 503 QDir dir(PATH_I18N,"*.qm",QDir::Name | QDir::IgnoreCase,QDir::Files); 504 if (!dir.exists()) 505 return; 506 QFileInfoList langs = dir.entryInfoList(); 507 if (langs.size() <= 0) 508 return; 509 QAction *a; 510 for (int k = 0; k < langs.size(); k++) { 511 QFileInfo lang = langs.at(k); 512 if (!lang.completeBaseName().startsWith("qt_") && lang.completeBaseName().compare("en")) { 513 #if QT_VERSION >= 0x040500 514 a = menuSettingsLanguage->addAction(langinfo.value(lang.completeBaseName() + "/NativeName",lang.completeBaseName()).toString()); 515 #else 516 // We use Name if Qt < 4.5 because NativeName is in UTF-8, QSettings 517 // reads .ini file as ASCII and there is no way to set file encoding. 518 a = menuSettingsLanguage->addAction(langinfo.value(lang.completeBaseName() + "/Name",lang.completeBaseName()).toString()); 519 #endif 520 a->setData(lang.completeBaseName()); 521 a->setCheckable(true); 522 a->setActionGroup(groupSettingsLanguageList); 523 if (settings->value("Language",QLocale::system().name()).toString().startsWith(lang.completeBaseName())) 524 a->setChecked(true); 525 } 526 } 128 527 } 129 528 … … 176 575 } 177 576 178 void MainWindow::initDocStyleSheet()179 {180 QColor color = settings->value("Output/Color",DEF_FONT_COLOR).value<QColor>();181 QColor hilight;182 if (color.value() < 192)183 hilight.setHsv(color.hue(),color.saturation(),127 + qRound(color.value() / 2));184 else185 hilight.setHsv(color.hue(),color.saturation(),color.value() / 2);186 solutionText->document()->setDefaultStyleSheet("* {color: " + color.name() +";} p {margin: 0px 10px;} table {margin: 5px;} td {padding: 1px 5px;} .hasalts {color: " + hilight.name() + ";} .selected {color: #A00000; font-weight: bold;} .alternate {color: #008000; font-weight: bold;}");187 solutionText->document()->setDefaultFont(settings->value("Output/Font",QFont(DEF_FONT_FAMILY,DEF_FONT_SIZE)).value<QFont>());188 }189 190 void MainWindow::setFileName(QString fileName)191 {192 this->fileName = fileName;193 setWindowTitle(QString("%1[*] - %2").arg(QFileInfo(fileName).completeBaseName()).arg(trUtf8("Travelling Salesman Problem")));194 }195 196 void MainWindow::spinCitiesValueChanged(int n)197 {198 int count = tspmodel->numCities();199 tspmodel->setNumCities(n);200 if ((n > count) && settings->value("Autosize",true).toBool())201 for (int k = count; k < n; k++) {202 taskView->resizeColumnToContents(k);203 taskView->resizeRowToContents(k);204 }205 }206 207 577 bool MainWindow::maybeSave() 208 578 { … … 218 588 } 219 589 220 void MainWindow::actionFileNewTriggered() 221 { 222 if (!maybeSave()) 223 return; 224 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); 225 tspmodel->clear(); 226 setFileName(); 227 setWindowModified(false); 228 tabWidget->setCurrentIndex(0); 229 solutionText->clear(); 230 enableSolutionActions(false); 231 QApplication::restoreOverrideCursor(); 232 } 233 234 void MainWindow::actionFileOpenTriggered() 235 { 236 if (!maybeSave()) 237 return; 238 QFileDialog od(this); 239 od.setAcceptMode(QFileDialog::AcceptOpen); 240 od.setFileMode(QFileDialog::ExistingFile); 241 QStringList filters(trUtf8("All Supported Formats") + " (*.tspt *.zkt)"); 242 filters.append(trUtf8("%1 Task Files").arg("TSPSG") + " (*.tspt)"); 243 filters.append(trUtf8("%1 Task Files").arg("ZKomModRd") + " (*.zkt)"); 244 filters.append(trUtf8("All Files") + " (*)"); 245 od.setNameFilters(filters); 246 if (od.exec() != QDialog::Accepted) 247 return; 248 QStringList files = od.selectedFiles(); 249 if (files.empty()) 250 return; 251 if (!tspmodel->loadTask(files.first())) 252 return; 253 setFileName(files.first()); 254 tabWidget->setCurrentIndex(0); 255 setWindowModified(false); 256 solutionText->clear(); 257 enableSolutionActions(false); 258 } 259 260 void MainWindow::actionFileSaveTriggered() 261 { 262 if ((fileName == trUtf8("Untitled") + ".tspt") || (!fileName.endsWith(".tspt",Qt::CaseInsensitive))) 263 saveTask(); 264 else 265 if (tspmodel->saveTask(fileName)) 266 setWindowModified(false); 267 } 268 269 void MainWindow::actionFileSaveAsTaskTriggered() 270 { 271 saveTask(); 272 } 273 274 void MainWindow::actionFileSaveAsSolutionTriggered() 275 { 276 static QString selectedFile; 277 if (selectedFile.isEmpty()) 278 #ifndef QT_NO_PRINTER 279 selectedFile = "solution.pdf"; 280 #else 281 selectedFile = "solution.html"; 282 #endif // QT_NO_PRINTER 283 QFileDialog sd(this); 284 sd.setAcceptMode(QFileDialog::AcceptSave); 285 QStringList filters; 286 #ifndef QT_NO_PRINTER 287 filters.append(trUtf8("PDF Files") + "(*.pdf)"); 288 #endif 289 filters.append(trUtf8("HTML Files") + " (*.html *.htm)"); 290 #if QT_VERSION >= 0x040500 291 filters.append(trUtf8("OpenDocument Files") + " (*.odt)"); 292 #endif // QT_VERSION >= 0x040500 293 filters.append(trUtf8("All Files") + " (*)"); 294 sd.setNameFilters(filters); 295 sd.selectFile(selectedFile); 296 if (sd.exec() != QDialog::Accepted) 297 return; 298 QStringList files = sd.selectedFiles(); 299 if (files.empty()) 300 return; 301 selectedFile = files.first(); 302 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); 303 #ifndef QT_NO_PRINTER 304 if (selectedFile.endsWith(".pdf",Qt::CaseInsensitive)) { 305 QPrinter printer(QPrinter::HighResolution); 306 printer.setOutputFormat(QPrinter::PdfFormat); 307 printer.setOutputFileName(selectedFile); 308 solutionText->document()->print(&printer); 309 QApplication::restoreOverrideCursor(); 310 return; 311 } 312 #endif 313 #if QT_VERSION >= 0x040500 314 QTextDocumentWriter dw(selectedFile); 315 if (!(selectedFile.endsWith(".htm",Qt::CaseInsensitive) || selectedFile.endsWith(".html",Qt::CaseInsensitive) || selectedFile.endsWith(".odt",Qt::CaseInsensitive) || selectedFile.endsWith(".txt",Qt::CaseInsensitive))) 316 dw.setFormat("plaintext"); 317 dw.write(solutionText->document()); 318 #else 319 // Qt < 4.5 has no QTextDocumentWriter class 320 QFile file(selectedFile); 321 if (!file.open(QFile::WriteOnly)) { 322 QApplication::restoreOverrideCursor(); 323 return; 324 } 325 QTextStream ts(&file); 326 ts.setCodec(QTextCodec::codecForName("UTF-8")); 327 ts << solutionText->document()->toHtml("UTF-8"); 328 file.close(); 329 #endif // QT_VERSION >= 0x040500 330 QApplication::restoreOverrideCursor(); 590 void MainWindow::outputMatrix(tMatrix matrix, QStringList &output, int nRow, int nCol) 591 { 592 int n = spinCities->value(); 593 QString line=""; 594 output.append("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"); 595 for (int r = 0; r < n; r++) { 596 line = "<tr>"; 597 for (int c = 0; c < n; c++) { 598 if (matrix[r][c] == INFINITY) 599 line += "<td align=\"center\">"INFSTR"</td>"; 600 else if ((r == nRow) && (c == nCol)) 601 line += "<td align=\"center\" class=\"selected\">" + QVariant(matrix[r][c]).toString() + "</td>"; 602 else 603 line += "<td align=\"center\">" + QVariant(matrix[r][c]).toString() + "</td>"; 604 } 605 line += "</tr>"; 606 output.append(line); 607 } 608 output.append("</table>"); 331 609 } 332 610 … … 355 633 } 356 634 357 void MainWindow::actionSettingsPreferencesTriggered() 358 { 359 SettingsDialog sd(this); 360 if (sd.exec() != QDialog::Accepted) 361 return; 362 if (sd.colorChanged() || sd.fontChanged()) { 363 initDocStyleSheet(); 364 if (!output.isEmpty() && sd.colorChanged() && (QMessageBox(QMessageBox::Question,trUtf8("Settings Changed"),trUtf8("You have changed color settings.\nDo you wish to apply them to current solution text?"),QMessageBox::Yes | QMessageBox::No,this).exec() == QMessageBox::Yes)) { 365 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); 366 solutionText->clear(); 367 solutionText->setHtml(output.join("")); 368 QApplication::restoreOverrideCursor(); 369 } 370 } 371 } 372 373 #ifndef QT_NO_PRINTER 374 void MainWindow::printPreview(QPrinter *printer) 375 { 376 solutionText->print(printer); 377 } 378 379 void MainWindow::actionFilePrintPreviewTriggered() 380 { 381 QPrintPreviewDialog ppd(printer, this); 382 connect(&ppd,SIGNAL(paintRequested(QPrinter *)),SLOT(printPreview(QPrinter *))); 383 ppd.exec(); 384 } 385 386 void MainWindow::actionFilePrintTriggered() 387 { 388 QPrintDialog pd(printer,this); 389 #if QT_VERSION >= 0x040500 390 // No such methods in Qt < 4.5 391 pd.setOption(QAbstractPrintDialog::PrintSelection,false); 392 pd.setOption(QAbstractPrintDialog::PrintPageRange,false); 393 #endif 394 if (pd.exec() != QDialog::Accepted) 395 return; 396 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); 397 solutionText->document()->print(printer); 398 QApplication::restoreOverrideCursor(); 399 } 400 #endif // QT_NO_PRINTER 401 402 void MainWindow::buttonRandomClicked() 403 { 404 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); 405 tspmodel->randomize(); 406 QApplication::restoreOverrideCursor(); 407 } 408 409 void MainWindow::buttonBackToTaskClicked() 410 { 411 tabWidget->setCurrentIndex(0); 412 } 413 414 void MainWindow::outputMatrix(tMatrix matrix, QStringList &output, int nRow, int nCol) 415 { 416 int n = spinCities->value(); 417 QString line=""; 418 output.append("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"); 419 for (int r = 0; r < n; r++) { 420 line = "<tr>"; 421 for (int c = 0; c < n; c++) { 422 if (matrix[r][c] == INFINITY) 423 line += "<td align=\"center\">"INFSTR"</td>"; 424 else if ((r == nRow) && (c == nCol)) 425 line += "<td align=\"center\" class=\"selected\">" + QVariant(matrix[r][c]).toString() + "</td>"; 426 else 427 line += "<td align=\"center\">" + QVariant(matrix[r][c]).toString() + "</td>"; 428 } 429 line += "</tr>"; 430 output.append(line); 431 } 432 output.append("</table>"); 433 } 434 435 void MainWindow::buttonSolveClicked() 436 { 437 tMatrix matrix; 438 QList<double> row; 439 int n = spinCities->value(); 440 bool ok; 441 for (int r = 0; r < n; r++) { 442 row.clear(); 443 for (int c = 0; c < n; c++) { 444 row.append(tspmodel->index(r,c).data(Qt::UserRole).toDouble(&ok)); 445 if (!ok) { 446 QMessageBox(QMessageBox::Critical,trUtf8("Data error"),trUtf8("Error in cell [Row %1; Column %2]: Invalid data format.").arg(r + 1).arg(c + 1),QMessageBox::Ok,this).exec(); 447 return; 448 } 449 } 450 matrix.append(row); 451 } 452 CTSPSolver solver; 453 sStep *root = solver.solve(n,matrix,this); 454 if (!root) 455 return; 456 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); 457 QColor color = settings->value("Output/Color",DEF_FONT_COLOR).value<QColor>(); 458 output.clear(); 459 output.append("<p>" + trUtf8("Variant #%1").arg(spinVariant->value()) + "</p>"); 460 output.append("<p>" + trUtf8("Task:") + "</p>"); 461 outputMatrix(matrix,output); 462 output.append("<hr>"); 463 output.append("<p>" + trUtf8("Solution of Variant #%1 task").arg(spinVariant->value()) + "</p>"); 464 sStep *step = root; 465 n = 1; 466 while (n <= spinCities->value()) { 467 if (step->prNode->prNode != NULL || (step->prNode->prNode == NULL && step->plNode->prNode == NULL)) { 468 if (n != spinCities->value()) { 469 output.append("<p>" + trUtf8("Step #%1").arg(n++) + "</p>"); 470 outputMatrix(step->matrix,output,step->candidate.nRow,step->candidate.nCol); 471 if (step->alts) 472 output.append("<p class=\"hasalts\">" + trUtf8("This step has alternate candidates for branching.") + "</p>"); 473 output.append("<p> </p>"); 474 } 475 } 476 if (step->prNode->prNode != NULL) 477 step = step->prNode; 478 else if (step->plNode->prNode != NULL) 479 step = step->plNode; 480 else 481 break; 482 } 483 if (solver.isOptimal()) 484 output.append("<p>" + trUtf8("Optimal path:") + "</p>"); 485 else 486 output.append("<p>" + trUtf8("Resulting path:") + "</p>"); 487 output.append("<p> " + solver.getSortedPath() + "</p>"); 488 output.append("<p>" + trUtf8("The price is <b>%1</b> units.").arg(step->price) + "</p>"); 489 if (!solver.isOptimal()) { 490 output.append("<p> </p>"); 491 output.append("<p>" + trUtf8("<b>WARNING!!!</b><br>This result is a record, but it may not be optimal.<br>Iterations need to be continued to check whether this result is optimal or get an optimal one.") + "</p>"); 492 } 493 output.append("<p></p>"); 494 solutionText->setHtml(output.join("")); 495 solutionText->setDocumentTitle(trUtf8("Solution of Variant #%1 task").arg(spinVariant->value())); 496 497 // Scrolling to the end of text. 498 QTextCursor cursor(solutionText->textCursor()); 499 cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); 500 solutionText->setTextCursor(cursor); 501 502 enableSolutionActions(); 503 tabWidget->setCurrentIndex(1); 504 QApplication::restoreOverrideCursor(); 505 } 506 507 void MainWindow::actionHelpAboutTriggered() 508 { 509 //! \todo TODO: Normal about window :-) 510 QString about = QString::fromUtf8("TSPSG: TSP Solver and Generator\n"); 511 about += QString::fromUtf8(" Version: "BUILD_VERSION"\n"); 512 about += QString::fromUtf8(" Copyright (C) 2007-%1 Lёppa <contacts[at]oleksii[dot]name>\n").arg(QDate::currentDate().toString("yyyy")); 513 about += QString::fromUtf8("Target OS: %1\n").arg(OS); 514 about += "Qt library:\n"; 515 about += QString::fromUtf8(" Compile time: %1\n").arg(QT_VERSION_STR); 516 about += QString::fromUtf8(" Runtime: %1\n").arg(qVersion()); 517 about += QString::fromUtf8("Built on %1 at %2\n").arg(__DATE__).arg(__TIME__); 518 about += QString::fromUtf8(VERSIONID"\n\n"); 519 about += QString::fromUtf8("Algorithm: %1\n").arg(CTSPSolver::getVersionId()); 520 about += "\n"; 521 about += "TSPSG is licensed under the terms of the GNU General Public License. You should have received a copy of the GNU General Public License along with TSPSG."; 522 QMessageBox(QMessageBox::Information,"About",about,QMessageBox::Ok,this).exec(); 523 } 524 525 void MainWindow::loadLangList() 526 { 527 QSettings langinfo(PATH_I18N"/languages.ini",QSettings::IniFormat); 528 #if QT_VERSION >= 0x040500 529 // In Qt < 4.5 QSettings doesn't have method setIniCodec. 530 langinfo.setIniCodec("UTF-8"); 531 #endif 532 QDir dir(PATH_I18N,"*.qm",QDir::Name | QDir::IgnoreCase,QDir::Files); 533 if (!dir.exists()) 534 return; 535 QFileInfoList langs = dir.entryInfoList(); 536 if (langs.size() <= 0) 537 return; 538 QAction *a; 539 for (int k = 0; k < langs.size(); k++) { 540 QFileInfo lang = langs.at(k); 541 if (!lang.completeBaseName().startsWith("qt_") && lang.completeBaseName().compare("en")) { 542 #if QT_VERSION >= 0x040500 543 a = menuSettingsLanguage->addAction(langinfo.value(lang.completeBaseName() + "/NativeName",lang.completeBaseName()).toString()); 544 #else 545 // We use Name if Qt < 4.5 because NativeName is in UTF-8, QSettings 546 // reads .ini file as ASCII and there is no way to set file encoding. 547 a = menuSettingsLanguage->addAction(langinfo.value(lang.completeBaseName() + "/Name",lang.completeBaseName()).toString()); 548 #endif 549 a->setData(lang.completeBaseName()); 550 a->setCheckable(true); 551 a->setActionGroup(groupSettingsLanguageList); 552 if (settings->value("Language",QLocale::system().name()).toString().startsWith(lang.completeBaseName())) 553 a->setChecked(true); 554 } 555 } 556 } 557 558 void MainWindow::actionSettingsLanguageAutodetectTriggered(bool checked) 559 { 560 if (checked) { 561 settings->remove("Language"); 562 QMessageBox(QMessageBox::Information,trUtf8("Language change"),trUtf8("Language will be autodetected on next application start."),QMessageBox::Ok,this).exec(); 563 } else 564 settings->setValue("Language",groupSettingsLanguageList->checkedAction()->data().toString()); 565 } 566 567 void MainWindow::groupSettingsLanguageListTriggered(QAction *action) 568 { 569 if (actionSettingsLanguageAutodetect->isChecked()) { 570 // We have language autodetection. It needs to be disabled to change language. 571 if (QMessageBox(QMessageBox::Question,trUtf8("Language change"),trUtf8("You have language autodetection turned on.\nIt needs to be off.\nDo you wish to turn it off?"),QMessageBox::Yes | QMessageBox::No,this).exec() == QMessageBox::Yes) { 572 actionSettingsLanguageAutodetect->trigger(); 573 } else 574 return; 575 } 576 bool untitled = (fileName == trUtf8("Untitled") + ".tspt"); 577 if (loadLanguage(action->data().toString())) { 578 settings->setValue("Language",action->data().toString()); 579 retranslateUi(this); 580 if (untitled) 581 setFileName(); 582 } 583 } 584 585 /*! 586 * \brief Handles Main Window close event. 587 * \param event Close event. 588 * 589 * Checks whether or not a current task was saved and asks for saving if not. 590 * Saves TSPSG settings. 591 */ 592 void MainWindow::closeEvent(QCloseEvent *event) 593 { 594 if (!maybeSave()) { 595 event->ignore(); 596 return; 597 } 598 settings->setValue("NumCities",spinCities->value()); 599 #ifndef Q_OS_WINCE 600 // Saving windows state 601 if (settings->value("SavePos",false).toBool()) { 602 settings->beginGroup("MainWindow"); 603 settings->setValue("Maximized",isMaximized()); 604 if (!isMaximized()) { 605 settings->setValue("Size",size()); 606 settings->setValue("Position",pos()); 607 } 608 settings->endGroup(); 609 } 610 #endif // Q_OS_WINCE 611 QMainWindow::closeEvent(event); 612 } 613 614 void MainWindow::dataChanged() 615 { 616 setWindowModified(true); 617 } 618 619 void MainWindow::dataChanged(const QModelIndex &tl, const QModelIndex &br) 620 { 621 setWindowModified(true); 622 if (settings->value("Autosize",true).toBool()) { 623 for (int k = tl.row(); k <= br.row(); k++) 624 taskView->resizeRowToContents(k); 625 for (int k = tl.column(); k <= br.column(); k++) 626 taskView->resizeColumnToContents(k); 627 } 628 } 629 630 void MainWindow::numCitiesChanged(int nCities) 631 { 632 blockSignals(true); 633 spinCities->setValue(nCities); 634 blockSignals(false); 635 } 635 void MainWindow::setFileName(QString fileName) 636 { 637 this->fileName = fileName; 638 setWindowTitle(QString("%1[*] - %2").arg(QFileInfo(fileName).completeBaseName()).arg(trUtf8("Travelling Salesman Problem"))); 639 }
Note: See TracChangeset
for help on using the changeset viewer.