// $Id: formmain.ui.h,v 1.4 2003/06/15 10:18:36 calicant Exp $ /* * This file is part of Mapagi * Copyright (C) 2003 calicant * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * * The GNU General Public License is contained in the file COPYING. * * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "formcover.h" #include "mapagi.h" const QString WINDOWS_REGISTRY = "/QtMiaSoft"; const QString APP_KEY = "/mapagi/"; void FormMain::init() { menu = new QMenuBar(this); Q_CHECK_PTR(menu); m_menu_file = new QPopupMenu(this); Q_CHECK_PTR(m_menu_file); m_menu_file->insertItem("&Quit", this, SLOT(exitRequest()), CTRL+Key_Q); m_menu_help = new QPopupMenu(this); Q_CHECK_PTR(m_menu_help); m_menu_help->insertItem("About", this, SLOT(slotMenuHelpAbout())); m_menu_help->insertItem("About Qt", this, SLOT(slotMenuHelpAboutQt())); menu->insertItem("&File", m_menu_file ); menu->insertItem("&Help", m_menu_help ); statusBar->setText(""); layout17->insertWidget(0, menu); loadSettings(); } void FormMain::pbChooseDir_clicked() { QString lastVisitedDir; lastVisitedDir = leDirectory->text(); if (lastVisitedDir.isNull() || lastVisitedDir.isEmpty()) lastVisitedDir = QDir::currentDirPath(); else if (!QDir(lastVisitedDir).exists()) lastVisitedDir = QDir::currentDirPath(); QString s = QFileDialog::getExistingDirectory( lastVisitedDir, this, "choosedir", "Choose images dir", FALSE, TRUE ); if (s.isNull()) { statusBar->setText( "Dir opening abandoned."); return; } leDirectory->setText(s); } void FormMain::makePageDistribution( QMemArray distripage, uint nsheet, uint npages, uint startfrompage ) { unsigned int i; unsigned int currpage = startfrompage; unsigned int totpages = npages + currpage - 1; for (i = 0; i < nsheet; i++) { distripage[i].f1 = 0; distripage[i].f2 = 0; distripage[i].v1 = 0; distripage[i].v2 = 0; } if (rbWestern->isChecked()) { for (i = 0; i < nsheet; i++) { distripage[i].v2 = currpage++; if (currpage > totpages) break; distripage[i].f1 = currpage++; if (currpage > totpages) break; } if (currpage > totpages) ; else for (int j = nsheet - 1; j > -1; j--) { distripage[j].f2 = currpage++; if (currpage > totpages) break; distripage[j].v1 = currpage++; if (currpage > totpages) break; } } // Japanese page order? else { for (i = 0; i < nsheet; i++) { distripage[i].v1 = currpage++; if (currpage > totpages) break; distripage[i].f2 = currpage++; if (currpage > totpages) break; } if (currpage > totpages) ; else for (int j = nsheet - 1; j > -1; j--) { distripage[j].f1 = currpage++; if (currpage > totpages) break; distripage[j].v2 = currpage++; if (currpage > totpages) break; } } #ifdef DEBUG for (i = 0; i < nsheet; i++) qDebug( "sheet #%03d | front: [ %3d, %3d ] || verso [ %3d, %3d ] |", i + 1, distripage[i].f1, distripage[i].f2, distripage[i].v1, distripage[i].v2 ); qDebug("0' marks a blank page"); #endif } void FormMain::makeFascicleDistribution( QMemArray distripage, uint nsheet, uint npages, uint spf ) { uint nfascicles = nsheet / spf; uint currfolio = 0; QMemArray tempdistrib (spf); for (uint s = 0; s < nfascicles; s++) { makePageDistribution(tempdistrib, spf, 4 * spf, spf * 4 * s + 1); for (uint k = 0; k < spf; k++) { distripage[currfolio].f1 = tempdistrib[k].f1; distripage[currfolio].f2 = tempdistrib[k].f2; distripage[currfolio].v1 = tempdistrib[k].v1; distripage[currfolio++].v2 = tempdistrib[k].v2; } } uint rsheets = nsheet % spf; if (rsheets) { uint noutpages = nfascicles * spf * 4; makePageDistribution(tempdistrib, rsheets, npages - noutpages, noutpages + 1); for (uint k = 0; k < rsheets; k++) { distripage[currfolio].f1 = tempdistrib[k].f1; distripage[currfolio].f2 = tempdistrib[k].f2; distripage[currfolio].v1 = tempdistrib[k].v1; distripage[currfolio++].v2 = tempdistrib[k].v2; } } return; } bool FormMain::checkImportDir(QDir d) { // first a textual check if (leDirectory->text().isEmpty()) { QMessageBox::warning( this, "Images directory not set", "Please, set a working directory\n\n" ); return FALSE; } if (! d.exists()) { QMessageBox::warning( this, "Directory not found", "Could not find directory\n\n" + d.absPath() ); return FALSE; } if (! d.isReadable()) { QMessageBox::warning( this, "Access Denied", "Could not read directory\n\n" + d.absPath() ); return FALSE; } if (! d.count()) { QMessageBox::warning( this, "Images not found", "Could not find images (" + QString(IMAGE_EXT) + ") in\n\n" + d.absPath() ); return FALSE; } return TRUE; } // scan for images. generate preview and ps void FormMain::pbCreatePreview_clicked() { ivPreview->clear(); ivSheet->clear(); QString s(leDirectory->text()); QDir d; d.setSorting(QDir::Name); d.setNameFilter(IMAGE_EXT); d.setFilter(QDir::Files | QDir::NoSymLinks); d.setPath(s); if (!checkImportDir(d)) return; QProgressDialog progress( "Scanning for images...", "Cancel", d.count(), this, "progress", TRUE ); unsigned int i = 0; QString currimagename; QImage currimage; for (i = 0; i < d.count(); i++ ) { progress.setProgress(i); statusBar->setText(QString("Processing image '%1' (%2/%3)") .arg(d[i]).arg(i + 1).arg(d.count())); qApp->processEvents(); if (progress.wasCancelled()) { statusBar->setText("Page preview cancelled by user request"); break; } currimagename = s + d[i]; currimage.load(currimagename); ivPreview->ensureItemVisible( new QIconViewItem( ivPreview, d[i], currimage.smoothScale(SINGLE_PAGE_MINI, SINGLE_PAGE_MINI, QImage::ScaleMin) ) ); } progress.setProgress(d.count()); if (progress.wasCancelled()) return; statusBar->setText(QString("%1 page(s) scanned").arg(i)); unsigned int nsheet = d.count() / 4; if (d.count() % 4) nsheet++; QMemArray distripage(nsheet); uint spf = sbSheetsPerFascicle->value(); if (cbFascicles->isChecked() && nsheet > spf) makeFascicleDistribution(distripage, nsheet, d.count(), spf); else makePageDistribution(distripage, nsheet, d.count(), 1); QProgressDialog progressP( "Generating sheet previews", "Cancel", nsheet * 2, this, "progress", TRUE ); unsigned int totpages = 0; QString dida; int idxpage1, idxpage2; int lastw = 100, lasth = 50; uint nfascicles; bool statusfascicles = cbFascicles->isChecked(); QColor currminipagecolor(MINI_SHEET_BG_COLOR); for (i = 0; i < nsheet; i++) { if (!statusfascicles) nfascicles = 1; else { nfascicles = i / spf + 1; if (nfascicles %2) currminipagecolor.setNamedColor(MINI_SHEET_BG_COLOR); else currminipagecolor.setNamedColor(FASCICLES_ALT_COLOR); } for (uint k = 0; k < 2; k++) { if (!k) { dida = QString("#%1 - Front [%2, %3] - (%4)"). arg(i + 1). arg(distripage[i].f1). arg(distripage[i].f2). arg(nfascicles); idxpage1 = distripage[i].f1; idxpage2 = distripage[i].f2; } else { dida = QString("#%1 - Verso [%2, %3] - (%4)"). arg(i + 1). arg(distripage[i].v1). arg(distripage[i].v2). arg(nfascicles); idxpage1 = distripage[i].v1; idxpage2 = distripage[i].v2; } progressP.setProgress(totpages); statusBar->setText("Generating sheet " + dida + QString(" (%1/%2) ...").arg(totpages + 1).arg(nsheet * 2)); qApp->processEvents(); if (progressP.wasCancelled()) { k = 3; i = nsheet; statusBar->setText("Sheet preview cancelled by user request"); break; } QPixmap image1; QPixmap image2; if (idxpage1) { image1 = QPixmap(s + d[idxpage1 -1]); lastw = image1.width(); lasth = image1.height(); } else { image1 = QPixmap(lastw, lasth); image1.fill(QColor(BLANK_MINI_PAGE_COLOR)); } if (idxpage2) { image2 = QPixmap(s + d[idxpage2 - 1]); lastw = image2.width(); lasth = image2.height(); } else { image2 = QPixmap (lastw, lasth); image2.fill(QColor(BLANK_MINI_PAGE_COLOR)); } QPixmap target; if (idxpage1 + idxpage2) { QPainter p; int hmax, hmin; int wmax, wmin; if (image1.height() > image2.height()) { hmax = image1.height(); hmin = image2.height(); } else { hmax = image2.height(); hmin = image1.height(); } if (image1.width() > image2.width()) { wmax = image1.width(); wmin = image2.width(); } else { wmax = image2.width(); wmin = image1.width(); } target = QPixmap(wmax + ADD_H_SIZE + wmax, hmax + ADD_V_SIZE); target.fill(QColor(currminipagecolor)); p.begin(&target); if (idxpage1) p.drawPixmap(BORDER_H_SIZE, BORDER_V_SIZE, image1); if (idxpage2) p.drawPixmap( 0 + BORDER_H_SIZE + wmax + GAP_H_SIZE, BORDER_V_SIZE, image2); p.end(); } else { target = QPixmap(SHEET_PAGE_MINI * 2 + ADD_H_SIZE, SHEET_PAGE_MINI + ADD_V_SIZE); target.fill(QColor(currminipagecolor)); } // add mini target ivSheet->ensureItemVisible( new QIconViewItem( ivSheet, dida, (target.convertToImage()).smoothScale (SHEET_PAGE_MINI, SHEET_PAGE_MINI, QImage::ScaleMin) ) ); totpages++; } // for k } // for j progressP.setProgress(nsheet * 2); if (progressP.wasCancelled()) return; statusBar->setText(QString("%1 page(s) processed.").arg(totpages)); } void FormMain::pbPrint_clicked() { QString s(leDirectory->text()); QDir d; d.setSorting(QDir::Name); d.setNameFilter(IMAGE_EXT); d.setFilter(QDir::Files | QDir::NoSymLinks); d.setPath(s); unsigned int i = 0; if (!checkImportDir(d)) return; QPrinter *printer; unsigned int nsheet = d.count() / 4; if (d.count() % 4) nsheet++; QMemArray distripage(nsheet); uint spf = sbSheetsPerFascicle->value(); if (cbFascicles->isChecked() && nsheet > spf) makeFascicleDistribution(distripage, nsheet, d.count(), spf); else makePageDistribution(distripage, nsheet, d.count(), 1); printer = new QPrinter; printer->setOutputFileName("mapagi_output.ps"); printer->setOutputToFile(FALSE); printer->setOrientation(QPrinter::Landscape); printer->setMinMax(1, nsheet); printer->setMargins(5, 5, 5, 5); printer->setResolution(sbDPI->value()); unsigned int totpages = 0; int idxpage1, idxpage2; int lastw = 100, lasth = 50; if (printer->setup(this)) { QPainter pp; if (!pp.begin(printer)) { qDebug("Unexpected error: sorry unable to print"); statusBar->setText("Unexpected error: sorry unable to print"); return; } QPaintDeviceMetrics metrics (printer); QFontMetrics fm = pp.fontMetrics(); QFont pf ("times", PN_FONTSIZE); pp.setFont(pf); pp.setPen(Qt::black); qDebug(QString("Printing from page %1 to page %2") .arg(printer->fromPage()).arg(printer->toPage())); unsigned int npagetoprint; if (!printer->toPage() && !printer->fromPage()) npagetoprint = nsheet; else npagetoprint = printer->toPage() - printer->fromPage() + 1; int currentpage = 0; unsigned int currSheetIndex = cbSheetPart->currentItem(); int pageWidth = ((FORMAT_TANKOBON_W_MM - WGAP_MM - PAGE_DISTGAP_MM) * metrics.width()) / metrics.widthMM(); int pageHeight = ((FORMAT_TANKOBON_H_MM - HGAP_MM - HGAP_MM) * metrics.height()) / metrics.heightMM(); int pageWGap = (WGAP_MM * metrics.width()) / metrics.widthMM(); int pageHGap = (HGAP_MM * metrics.height()) / metrics.heightMM(); int pageDistGap = (PAGE_DISTGAP_MM * metrics.width()) / metrics.widthMM(); int marginPN_MM = (MARGIN_PN_MM * metrics.height()) / metrics.heightMM(); #ifdef DEBUG qDebug( "DPI = %d - sheet %dx%d [mm %dx%d] - page %dx%d [mm %dx%d]", printer->resolution(), metrics.width(), metrics.height(), metrics.widthMM(), metrics.heightMM(), pageWidth, pageHeight, FORMAT_TANKOBON_W_MM * 2, FORMAT_TANKOBON_H_MM ); #endif #ifdef DEBUG uint top, left, bottom, right; printer->margins(&top, &left, &bottom, &right); qDebug("margin: top = %d, left = %d, bottom = %d, right = %d", top, left, bottom, right); #endif QString pmessage; if (printer->outputToFile()) pmessage = "file " + printer->outputFileName(); else pmessage = printer->printerName(); // some check on unsupported options QString somewarning = ""; if (printer->pageSize() != QPrinter::A4) { printer->setPageSize(QPrinter::A4); somewarning = somewarning + "\n" + "A4 page size only."; } if (printer->orientation() != QPrinter::Landscape) { printer->setOrientation(QPrinter::Landscape); somewarning = somewarning + "\n" + "Landscape page orientation only."; } if (printer->pageOrder() != QPrinter::FirstPageFirst) { printer->setPageOrder(QPrinter::FirstPageFirst); somewarning = somewarning + "\n" + "'First Page First' order only."; } if (!somewarning.isEmpty()) QMessageBox::warning(this, "Unsupported options", somewarning, QMessageBox::Ok, QMessageBox::NoButton); QProgressDialog progressP( QString( "number of copies: %1 - number of sheets: %2

Printing to %3..."). arg(printer->numCopies()).arg(npagetoprint).arg(pmessage), "Cancel", npagetoprint * printer->numCopies(), this, "progress", TRUE ); for (int ncopies = 0; ncopies < printer->numCopies(); ncopies++) { for (i = 0; i < nsheet; i++) { for (uint k = 0; k < 2; k++) { if (k != currSheetIndex) { continue; } currentpage++; if (npagetoprint < nsheet) { if (currentpage < printer->fromPage() || currentpage > printer->toPage()) { statusBar->setText( QString("Skip sheet #%1").arg(currentpage)); qApp->processEvents(); continue; } } if (!k) { idxpage1 = distripage[i].f1; idxpage2 = distripage[i].f2; } else { idxpage1 = distripage[i].v1; idxpage2 = distripage[i].v2; } progressP.setProgress(totpages); statusBar->setText(QString("Generating sheet #%1/%2...") .arg(totpages + 1).arg(npagetoprint * printer->numCopies())); qApp->processEvents(); if (progressP.wasCancelled()) { k = 3; i = nsheet; ncopies = printer->numCopies(); printer->abort(); break; } QPixmap image1; QPixmap image2; if (idxpage1) { image1 = QPixmap(s + d[idxpage1 -1]); lastw = image1.width(); lasth = image1.height(); } else { image1 = QPixmap(lastw, lasth); image1.fill(QColor(BLANK_PRINT_PAGE_COLOR)); } if (idxpage2) { image2 = QPixmap(s + d[idxpage2 - 1]); lastw = image2.width(); lasth = image2.height(); } else { image2 = QPixmap (lastw, lasth); image2.fill(QColor(BLANK_PRINT_PAGE_COLOR)); } QPainter p; // target pixmap int hmax, hmin; int wmax, wmin; if (image1.height() > image2.height()) { hmax = image1.height(); hmin = image2.height(); } else { hmax = image2.height(); hmin = image1.height(); } if (image1.width() > image2.width()) { wmax = image1.width(); wmin = image2.width(); } else { wmax = image2.width(); wmin = image1.width(); } QPixmap target1 (wmax, hmax); QPixmap target2 (wmax, hmax); target1.fill(QColor(PRINT_SHEET_BG_COLOR)); target2.fill(QColor(PRINT_SHEET_BG_COLOR)); if (idxpage1) { p.begin(&target1); p.drawPixmap(0, 0, image1); p.end(); } if (idxpage2) { p.begin(&target2); p.drawPixmap(0, 0, image2); p.end(); } QImage imagePage1 = (target1.convertToImage()).smoothScale( pageWidth, pageHeight, QImage::ScaleMin); QImage imagePage2 = (target2.convertToImage()).smoothScale( pageWidth, pageHeight, QImage::ScaleMin); if (totpages) printer->newPage(); uint pwpos = ( metrics.width() - imagePage1.width() - imagePage2.width() - pageDistGap *2 ) / 2; uint phpos = ( metrics.height() - imagePage1.height()) / 2; pp.drawPixmap(pwpos, phpos, imagePage1); pp.drawPixmap(pwpos + imagePage1.width() + pageDistGap * 2, phpos, imagePage2); pp.drawRect ( pwpos - pageWGap, phpos - pageHGap, imagePage1.width() + pageDistGap * 2 + imagePage2.width() + 2 * pageWGap, imagePage1.height() + 2 * pageHGap ); if (cbPrintPageNumber->isChecked()) { if (idxpage1) pp.drawText (pwpos, phpos + imagePage1.height() + marginPN_MM, metrics.width(), fm.lineSpacing(), ExpandTabs | DontClip, QString("%1").arg(idxpage1)); if (idxpage2) pp.drawText (pwpos + imagePage1.width() + imagePage2.width() + pageDistGap * 2, phpos + imagePage1.height() + marginPN_MM, metrics.width(), fm.lineSpacing(), ExpandTabs | DontClip, QString("%1").arg(idxpage2)); } totpages++; } // for k } // for j } // for ncopies progressP.setProgress(npagetoprint); pp.end(); } // if (printer->setup(this)) if (printer->outputToFile()) statusBar->setText(QString("%1 sheets(s) saved in %2").arg(totpages).arg(printer->outputFileName())); else statusBar->setText(QString("%1 sheet(s) processed").arg(totpages)); delete printer; } void FormMain::slotMenuHelpAbout() { QMessageBox::about( this, "Mapagi -- About", "
Mapagi " PROG_VER "

" "Copyright (C) 2003 calicant (calicant@ferrara.linux.it)
" "This program is distributed under the terms of the GNU General Public License v2." ); } void FormMain::slotMenuHelpAboutQt() { QMessageBox::aboutQt(this, "About Qt"); } void FormMain::exitRequest() { saveSettings(); QApplication::exit(0); } void FormMain::closeEvent (QCloseEvent) { exitRequest(); } void FormMain::pbQuit_clicked() { exitRequest(); } void FormMain::loadSettings() { QSettings settings; int defaultScreenResolution; bool wpo; QPrinter *tp = new QPrinter; defaultScreenResolution = tp->resolution(); delete tp; settings.insertSearchPath(QSettings::Windows, WINDOWS_REGISTRY); wpo = settings.readBoolEntry(APP_KEY + "WesternOrder", TRUE); rbWestern->setChecked(wpo); rbJapanese->setChecked(!wpo); cbPrintPageNumber->setChecked( settings.readBoolEntry(APP_KEY + "PrintPageNumber", TRUE) ); sbDPI->setValue( settings.readNumEntry(APP_KEY + "PrinterResolution", defaultScreenResolution) ); cbFascicles->setChecked( settings.readBoolEntry(APP_KEY + "Fascicles", FALSE) ); sbSheetsPerFascicle->setEnabled(cbFascicles->isChecked()); sbSheetsPerFascicle->setValue( settings.readNumEntry(APP_KEY + "SheetsPerFascicle", DEFAULT_SHEETS_PER_FASCICLE) ); } void FormMain::saveSettings() { QSettings settings; settings.insertSearchPath(QSettings::Windows, WINDOWS_REGISTRY); settings.writeEntry(APP_KEY + "WesternOrder", rbWestern->isChecked()); settings.writeEntry(APP_KEY + "PrintPageNumber", cbPrintPageNumber->isChecked()); settings.writeEntry(APP_KEY + "PrinterResolution", sbDPI->value()); settings.writeEntry(APP_KEY + "Fascicles", cbFascicles->isChecked()); settings.writeEntry(APP_KEY + "SheetsPerFascicle", sbSheetsPerFascicle->value()); } void FormMain::cbFascicles_clicked() { sbSheetsPerFascicle->setEnabled(cbFascicles->isChecked()); } void FormMain::pbSetCover_clicked() { FormCover *printingCover = new FormCover (this, "covertool", TRUE); printingCover->sbDPI->setValue(sbDPI->value()); printingCover->exec(); // delete printingCover; }