diff --git a/qt/eliot.qrc b/qt/eliot.qrc
index 56bf4f6..a375dae 100644
--- a/qt/eliot.qrc
+++ b/qt/eliot.qrc
@@ -7,6 +7,7 @@
images/go-next.png
images/go-last.png
images/go-jump.png
+ images/print-preview.png
images/printer.png
images/preferences.png
images/playlist_16px.png
diff --git a/qt/images/print-preview.png b/qt/images/print-preview.png
new file mode 100644
index 0000000..741c318
Binary files /dev/null and b/qt/images/print-preview.png differ
diff --git a/qt/main_window.cpp b/qt/main_window.cpp
index 36e8f99..9b80b77 100644
--- a/qt/main_window.cpp
+++ b/qt/main_window.cpp
@@ -26,6 +26,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -376,6 +377,7 @@ void MainWindow::updateForGame(PublicGame *iGame)
if (iGame == NULL)
{
m_actionGameSaveAs->setEnabled(false);
+ m_actionGamePrintPreview->setEnabled(false);
m_actionGamePrint->setEnabled(false);
m_actionHistoryFirstTurn->setEnabled(false);
m_actionHistoryPrevTurn->setEnabled(false);
@@ -412,6 +414,7 @@ void MainWindow::updateForGame(PublicGame *iGame)
}
else
{
+ m_actionGamePrintPreview->setEnabled(true);
m_actionGamePrint->setEnabled(true);
m_actionGameSaveAs->setEnabled(true);
m_actionSettingsDefineTables->setEnabled(iGame->getMode() == PublicGame::kARBITRATION);
@@ -801,6 +804,9 @@ void MainWindow::createMenu()
m_actionGameSaveAs = addMenuAction(menuFile, _q("&Save as..."), _q("Ctrl+S"),
_q("Save the current game"), SLOT(onGameSaveAs()));
menuFile->addSeparator();
+ m_actionGamePrintPreview = addMenuAction(menuFile, _q("&Print preview..."), QString(""),
+ _q("Print preview"), SLOT(onGamePrintPreview()),
+ false, QIcon(":/images/print-preview.png"));
m_actionGamePrint = addMenuAction(menuFile, _q("&Print..."), _q("Ctrl+P"),
_q("Print the current game"), SLOT(onGamePrint()),
false, QIcon(":/images/printer.png"));
@@ -1014,152 +1020,169 @@ void MainWindow::onGamePrint()
QPrinter printer(QPrinter::HighResolution);
QPrintDialog printDialog(&printer, this);
- if (printDialog.exec() == QDialog::Accepted)
+ if (printDialog.exec() != QDialog::Accepted)
+ return;
+
+ LOG_INFO("Printing game");
+ print(&printer);
+}
+
+
+void MainWindow::onGamePrintPreview()
+{
+ LOG_INFO("Print preview");
+ QPrintPreviewDialog previewDialog;
+ QObject::connect(&previewDialog, SIGNAL(paintRequested(QPrinter *)),
+ this, SLOT(print(QPrinter*)));
+ previewDialog.exec();
+}
+
+
+void MainWindow::print(QPrinter *printer)
+{
+ ASSERT(m_game != NULL, "No game in progress");
+
+ QPainter painter(printer);
+ const History &history = m_game->getHistory();
+
+ // Printing parameters (XXX: these could be configurable by the users)
+ // Number of pixels virtually present on the page width. The bigger
+ // this number, the smaller the print result
+ static const int TOTAL_WIDTH = 700;
+ // Distance between 2 horizontal lines
+ static const int LINE_HEIGHT = 16;
+ // Font size, in pixels
+ static const int FONT_SIZE = 10;
+ // Width of the pen used to draw the grid lines
+ static const int PEN_WIDTH = 1;
+ // Offset of the text from the previous vertical line, in pixels
+ static const int TEXT_OFFSET = 10;
+ // Indicate whether the rack and the solution should be aligned
+ static const bool SHOULD_ALIGN = false;
+ // Columns widths
+ static const int colWidths[] = { 30, 120, 120, 35, 35 };
+ // Columns titles
+ static const char *colTitles[] = { _("N."), _("RACK"), _("SOLUTION"), _("REF"), _("PTS") };
+
+ static const unsigned int nbCols = sizeof(colWidths) / sizeof(int);
+ const unsigned int nbRows = history.getSize() + (SHOULD_ALIGN ? 1 : 2);
+
+ double scale = printer->pageRect().width() / double(TOTAL_WIDTH);
+ painter.scale(scale, scale);
+
+ QPen pen(painter.pen());
+ pen.setWidth(PEN_WIDTH);
+ painter.setPen(pen);
+
+ QFont font;
+ font.setPixelSize(FONT_SIZE);
+ painter.setFont(font);
+
+ int maxRight = 0;
+ for (unsigned int i = 0; i < nbCols; ++i)
+ maxRight += colWidths[i];
+ int maxBottom = LINE_HEIGHT * (nbRows + 1);
+
+ // Draw the horizontal lines
+ for (unsigned int i = 0; i <= nbRows + 1; ++i)
+ painter.drawLine(0, LINE_HEIGHT * i, maxRight, LINE_HEIGHT * i);
+
+ // Draw the vertical lines
+ painter.drawLine(0, 0, 0, maxBottom);
+ int curWidth = 0;
+ for (unsigned int i = 0; i < nbCols; ++i)
{
- LOG_INFO("Printing game");
-
- QPainter painter(&printer);
- const History &history = m_game->getHistory();
-
- // Printing parameters (XXX: these could be configurable by the users)
- // Number of pixels virtually present on the page width. The bigger
- // this number, the smaller the print result
- static const int TOTAL_WIDTH = 700;
- // Distance between 2 horizontal lines
- static const int LINE_HEIGHT = 16;
- // Font size, in pixels
- static const int FONT_SIZE = 10;
- // Width of the pen used to draw the grid lines
- static const int PEN_WIDTH = 1;
- // Offset of the text from the previous vertical line, in pixels
- static const int TEXT_OFFSET = 10;
- // Indicate whether the rack and the solution should be aligned
- static const bool SHOULD_ALIGN = false;
- // Columns widths
- static const int colWidths[] = { 30, 120, 120, 35, 35 };
- // Columns titles
- static const char *colTitles[] = { _("N."), _("RACK"), _("SOLUTION"), _("REF"), _("PTS") };
-
- static const unsigned int nbCols = sizeof(colWidths) / sizeof(int);
- const unsigned int nbRows = history.getSize() + (SHOULD_ALIGN ? 1 : 2);
-
- double scale = printer.pageRect().width() / double(TOTAL_WIDTH);
- painter.scale(scale, scale);
-
- QPen pen(painter.pen());
- pen.setWidth(PEN_WIDTH);
- painter.setPen(pen);
-
- QFont font;
- font.setPixelSize(FONT_SIZE);
- painter.setFont(font);
-
- int maxRight = 0;
- for (unsigned int i = 0; i < nbCols; ++i)
- maxRight += colWidths[i];
- int maxBottom = LINE_HEIGHT * (nbRows + 1);
-
- // Draw the horizontal lines
- for (unsigned int i = 0; i <= nbRows + 1; ++i)
- painter.drawLine(0, LINE_HEIGHT * i, maxRight, LINE_HEIGHT * i);
-
- // Draw the vertical lines
- painter.drawLine(0, 0, 0, maxBottom);
- int curWidth = 0;
- for (unsigned int i = 0; i < nbCols; ++i)
- {
- curWidth += colWidths[i];
- painter.drawLine(curWidth, 0, curWidth, maxBottom);
- }
-
- // Draw the titles
- QFontMetrics fm = painter.fontMetrics();
- int textHeight = fm.boundingRect('A').height();
- curWidth = 0;
- int curHeight = (LINE_HEIGHT + textHeight + 1) / 2;
- for (unsigned int i = 0; i < nbCols; ++i)
- {
- int textWidth = fm.width(colTitles[i]);
- painter.drawText(curWidth + (colWidths[i] - textWidth) / 2,
- curHeight, colTitles[i]);
- curWidth += colWidths[i];
- }
-
- // Draw the history of the game
- int score = 0;
- int nextHeight;
- if (SHOULD_ALIGN)
- nextHeight = curHeight;
- else
- nextHeight = curHeight + LINE_HEIGHT;
- for (unsigned int i = 0; i < history.getSize(); ++i)
- {
- const TurnData &t = history.getTurn(i);
- const Move &m = t.getMove();
-
- curWidth = TEXT_OFFSET;
- curHeight += LINE_HEIGHT;
- nextHeight += LINE_HEIGHT;
-
- // Turn number
- painter.drawText(curWidth, curHeight, QString("%1").arg(i + 1));
- curWidth += colWidths[0];
-
- // Rack
- painter.drawText(curWidth, curHeight,
- qfw(t.getPlayedRack().toString()));
- curWidth += colWidths[1];
-
- // Word and coordinates
- if (m.isValid())
- {
- const Round &r = m.getRound();
- painter.drawText(curWidth, nextHeight, qfw(r.getWord()));
- curWidth += colWidths[2];
- painter.drawText(curWidth, nextHeight,
- qfw(r.getCoord().toString()));
- curWidth += colWidths[3];
- }
- else if (m.isInvalid())
- {
- painter.drawText(curWidth, nextHeight,
- "<" + qfw(m.getBadWord()) + ">");
- curWidth += colWidths[2];
- painter.drawText(curWidth, nextHeight, qfw(m.getBadCoord()));
- curWidth += colWidths[3];
- }
- else if (m.isNull())
- {
- painter.drawText(curWidth, nextHeight, _q("(NO MOVE)"));
- curWidth += colWidths[2];
- curWidth += colWidths[3];
- }
- else if (m.isPass())
- {
- painter.drawText(curWidth, nextHeight, _q("(PASS)"));
- curWidth += colWidths[2];
- curWidth += colWidths[3];
- }
- else
- {
- painter.drawText(curWidth, nextHeight,
- "[-" + qfw(m.getChangedLetters()) + "]");
- curWidth += colWidths[2];
- curWidth += colWidths[3];
- }
-
- // Score
- painter.drawText(curWidth, nextHeight,
- QString("%1").arg(m.getScore()));
- score += m.getScore();
- }
-
- // Total score
- nextHeight += LINE_HEIGHT;
- painter.drawText(curWidth, nextHeight, QString("%1").arg(score));
-
- LOG_INFO("Game printed");
+ curWidth += colWidths[i];
+ painter.drawLine(curWidth, 0, curWidth, maxBottom);
}
+
+ // Draw the titles
+ QFontMetrics fm = painter.fontMetrics();
+ int textHeight = fm.boundingRect('A').height();
+ curWidth = 0;
+ int curHeight = (LINE_HEIGHT + textHeight + 1) / 2;
+ for (unsigned int i = 0; i < nbCols; ++i)
+ {
+ int textWidth = fm.width(colTitles[i]);
+ painter.drawText(curWidth + (colWidths[i] - textWidth) / 2,
+ curHeight, colTitles[i]);
+ curWidth += colWidths[i];
+ }
+
+ // Draw the history of the game
+ int score = 0;
+ int nextHeight;
+ if (SHOULD_ALIGN)
+ nextHeight = curHeight;
+ else
+ nextHeight = curHeight + LINE_HEIGHT;
+ for (unsigned int i = 0; i < history.getSize(); ++i)
+ {
+ const TurnData &t = history.getTurn(i);
+ const Move &m = t.getMove();
+
+ curWidth = TEXT_OFFSET;
+ curHeight += LINE_HEIGHT;
+ nextHeight += LINE_HEIGHT;
+
+ // Turn number
+ painter.drawText(curWidth, curHeight, QString("%1").arg(i + 1));
+ curWidth += colWidths[0];
+
+ // Rack
+ painter.drawText(curWidth, curHeight,
+ qfw(t.getPlayedRack().toString()));
+ curWidth += colWidths[1];
+
+ // Word and coordinates
+ if (m.isValid())
+ {
+ const Round &r = m.getRound();
+ painter.drawText(curWidth, nextHeight, qfw(r.getWord()));
+ curWidth += colWidths[2];
+ painter.drawText(curWidth, nextHeight,
+ qfw(r.getCoord().toString()));
+ curWidth += colWidths[3];
+ }
+ else if (m.isInvalid())
+ {
+ painter.drawText(curWidth, nextHeight,
+ "<" + qfw(m.getBadWord()) + ">");
+ curWidth += colWidths[2];
+ painter.drawText(curWidth, nextHeight, qfw(m.getBadCoord()));
+ curWidth += colWidths[3];
+ }
+ else if (m.isNull())
+ {
+ painter.drawText(curWidth, nextHeight, _q("(NO MOVE)"));
+ curWidth += colWidths[2];
+ curWidth += colWidths[3];
+ }
+ else if (m.isPass())
+ {
+ painter.drawText(curWidth, nextHeight, _q("(PASS)"));
+ curWidth += colWidths[2];
+ curWidth += colWidths[3];
+ }
+ else
+ {
+ painter.drawText(curWidth, nextHeight,
+ "[-" + qfw(m.getChangedLetters()) + "]");
+ curWidth += colWidths[2];
+ curWidth += colWidths[3];
+ }
+
+ // Score
+ painter.drawText(curWidth, nextHeight,
+ QString("%1").arg(m.getScore()));
+ score += m.getScore();
+ }
+
+ // Total score
+ nextHeight += LINE_HEIGHT;
+ painter.drawText(curWidth, nextHeight, QString("%1").arg(score));
+
+ LOG_INFO("Game printed");
}
diff --git a/qt/main_window.h b/qt/main_window.h
index a8190dc..7c4a39b 100644
--- a/qt/main_window.h
+++ b/qt/main_window.h
@@ -48,6 +48,7 @@ class AuxWindow;
class TimerModel;
class QLabel;
class QAction;
+class QPrinter;
class MainWindow: public QMainWindow
{
@@ -75,6 +76,7 @@ private slots:
void onGameLoad();
void onGameLoadAutoSave();
void onGameSaveAs();
+ void onGamePrintPreview();
void onGamePrint();
void onGameQuit();
void onSettingsChooseDic();
@@ -97,6 +99,9 @@ private slots:
void onHistoryLastTurn();
void onHistoryReplayTurn();
+ /// Print the game using the given printer
+ void print(QPrinter *printer);
+
/// Simply emit a beep with the system speakers
void beep();
@@ -158,6 +163,7 @@ private:
ScoreWidget *m_scoresWidget;
/// Actions enabled or disabled depending on the game state
+ QAction *m_actionGamePrintPreview;
QAction *m_actionGamePrint;
QAction *m_actionGameSaveAs;
QAction *m_actionHistoryPrevTurn;