596 lines
18 KiB
C++
596 lines
18 KiB
C++
/* qlscribe - Qt based application to print lightScribe discs
|
|
|
|
Copyright (C) 2009 Vyacheslav Kononenko <vyacheslav@kononenko.net>
|
|
|
|
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
$Id$ */
|
|
|
|
#include "mainwindow.h"
|
|
#include "qlightroundtextitem.h"
|
|
#include "qcdview.h"
|
|
#include "qcdscene.h"
|
|
#include "qshapefactory.h"
|
|
#include "qlightscribe.h"
|
|
#include "qdialogprint.h"
|
|
#include "qdialogprogress.h"
|
|
#include "qdialogcdproperties.h"
|
|
#include "qdialogsettings.h"
|
|
#include "previewinjector.h"
|
|
|
|
#include <QMenuBar>
|
|
#include <QStatusBar>
|
|
#include <QMdiArea>
|
|
#include <QMdiSubWindow>
|
|
#include <QMessageBox>
|
|
#include <QSignalMapper>
|
|
#include <QFileDialog>
|
|
#include <QLabel>
|
|
#include <QCloseEvent>
|
|
#include <QApplication>
|
|
#include <QClipboard>
|
|
#include <QMimeData>
|
|
#include <QSettings>
|
|
#include <QImageReader>
|
|
#include <QPicture>
|
|
|
|
|
|
MainWindow::MainWindow( bool enablePrint )
|
|
: QMainWindow( 0 ),
|
|
m_mdiArea( new QMdiArea( this ) ),
|
|
m_menuFile( 0 ), m_menuInsert( 0 ),
|
|
m_insertMapper( new QSignalMapper( this ) ),
|
|
m_newLabelMapper( new QSignalMapper( this ) )
|
|
{
|
|
setWindowTitle( tr( "Qt lightScribe", "Main window title \"Qt lightScribe\"" ) );
|
|
setCentralWidget( m_mdiArea );
|
|
|
|
m_menuFile = menuBar()->addMenu( tr( "File", "Menu item \"File\"" ) );
|
|
|
|
{
|
|
QMenu *newSubMenu = m_menuFile->addMenu( tr( "New label", "Menu item \"New lable\"" ) );
|
|
QAction *action = newSubMenu->addAction( tr( "Full", "Menu item \"Full\"" ),
|
|
m_newLabelMapper,
|
|
SLOT(map()) );
|
|
m_newLabelMapper->setMapping( action, modeFull );
|
|
|
|
action = newSubMenu->addAction( tr( "Content", "Menu item \"Content\"" ),
|
|
m_newLabelMapper,
|
|
SLOT(map()) );
|
|
m_newLabelMapper->setMapping( action, modeContent );
|
|
|
|
action = newSubMenu->addAction( tr( "Title", "Menu item \"Title\"" ),
|
|
m_newLabelMapper,
|
|
SLOT(map()) );
|
|
m_newLabelMapper->setMapping( action, modeTitle );
|
|
}
|
|
connect(m_newLabelMapper, &QSignalMapper::mappedInt,
|
|
this, &MainWindow::onMenuNewLabel);
|
|
|
|
m_menuFile->addAction( tr( "Open...", "Menu item \"Open\"" ),
|
|
this,
|
|
SLOT(onMenuOpen()),
|
|
QKeySequence( Qt::CTRL + Qt::Key_O ) );
|
|
|
|
m_actionSave = m_menuFile->addAction( tr( "Save", "Menu item \"Save\"" ),
|
|
this,
|
|
SLOT(onMenuSave()),
|
|
QKeySequence( Qt::CTRL + Qt::Key_S ) );
|
|
|
|
m_actionSaveAs = m_menuFile->addAction( tr( "Save as...", "Menu item \"Save as\"" ),
|
|
this,
|
|
SLOT(onMenuSaveAs()) );
|
|
|
|
m_menuFile->addSeparator();
|
|
|
|
m_actionLabelProperties =
|
|
m_menuFile->addAction( tr( "Label properties...", "Menu item \"Label propeties...\"" ),
|
|
this,
|
|
SLOT(onMenuProperties()) );
|
|
|
|
m_menuFile->addSeparator();
|
|
|
|
m_actionPrintPreview =
|
|
m_menuFile->addAction( tr( "Print preview...", "Menu item \"Print preview\"" ),
|
|
this,
|
|
SLOT(onMenuPrintPreview()) );
|
|
|
|
m_actionPrint =
|
|
m_menuFile->addAction( tr( "Print...", "Menu item \"Print\"" ),
|
|
this,
|
|
SLOT(onMenuPrint()) );
|
|
|
|
m_menuFile->addAction( tr( "Exit", "Menu item \"Exit\"" ),
|
|
this,
|
|
SLOT(close()),
|
|
QKeySequence( Qt::CTRL + Qt::Key_Q ) );
|
|
|
|
|
|
m_menuEdit = menuBar()->addMenu( tr( "Edit", "Menu item \"Edit\"" ) );
|
|
|
|
m_actionUndo = m_menuEdit->addAction( tr( "Undo", "Menu item \"Undo\"" ),
|
|
this,
|
|
SLOT(onMenuUndo()),
|
|
QKeySequence( Qt::CTRL + Qt::Key_Z ) );
|
|
|
|
m_actionRedo = m_menuEdit->addAction( tr( "Redo", "Menu item \"Redo\"" ),
|
|
this,
|
|
SLOT(onMenuRedo()),
|
|
QKeySequence( Qt::CTRL + Qt::Key_R ) );
|
|
|
|
m_actionCopy = m_menuEdit->addAction( tr( "Copy", "Menu item \"Copy\"" ),
|
|
this,
|
|
SLOT(onMenuCopy()),
|
|
QKeySequence( Qt::CTRL + Qt::Key_C ) );
|
|
|
|
m_actionCut = m_menuEdit->addAction( tr( "Cut", "Menu item \"Cut\"" ),
|
|
this,
|
|
SLOT(onMenuCut()),
|
|
QKeySequence( Qt::CTRL + Qt::Key_X ) );
|
|
|
|
m_actionPaste = m_menuEdit->addAction( tr( "Paste", "Menu item \"Paste\"" ),
|
|
this,
|
|
SLOT(onMenuPaste()),
|
|
QKeySequence( Qt::CTRL + Qt::Key_V ) );
|
|
|
|
m_menuInsert = m_menuEdit->addMenu( tr( "Insert", "Menu item \"Insert\"" ) );
|
|
|
|
m_menuEdit->addSeparator();
|
|
|
|
m_actionSettings = m_menuEdit->addAction( tr( "Settings...", "Menu item \"Settings\"" ),
|
|
this,
|
|
SLOT(onMenuSettings()) );
|
|
|
|
m_menuHelp = menuBar()->addMenu( tr( "Help", "Menu item \"Help\"" ) );
|
|
|
|
m_menuHelp->addAction( tr( "About...", "Menu item \"About\"" ),
|
|
this,
|
|
SLOT(onMenuAbout()) );
|
|
|
|
m_menuHelp->addAction( tr( "About Qt...", "Menu item \"About Qt\"" ),
|
|
this,
|
|
SLOT(onMenuQtAbout()) );
|
|
|
|
QShapeFactory &sfactory = QShapeFactory::instance();
|
|
|
|
for( QShapeFactory::iterator i = sfactory.begin(); i != sfactory.end(); ++i ) {
|
|
QAction *action = new QAction( i->second->menuName(), this );
|
|
m_menuInsert->addAction( action );
|
|
m_insertMapper->setMapping( action, i->first );
|
|
connect( action, SIGNAL(triggered()), m_insertMapper, SLOT(map()) );
|
|
}
|
|
connect(m_insertMapper, &QSignalMapper::mappedInt,
|
|
this, &MainWindow::onMenuInsert);
|
|
|
|
connect( QApplication::clipboard(), SIGNAL(changed(QClipboard::Mode)),
|
|
this, SLOT(updateMenu()) );
|
|
connect( m_mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)),
|
|
this, SLOT(updateMenu()) );
|
|
|
|
updateMenu();
|
|
|
|
QSettings settings;
|
|
|
|
settings.beginGroup( "MainWindow");
|
|
resize( settings.value( "size", QSize(800, 400) ).toSize() );
|
|
move( settings.value( "pos", QPoint(200, 200) ).toPoint() );
|
|
settings.endGroup();
|
|
}
|
|
|
|
MainWindow::~MainWindow()
|
|
{
|
|
}
|
|
|
|
void MainWindow::open( const QStringList &files )
|
|
{
|
|
foreach( QString fileName, files ) {
|
|
QCDView *newView = new QCDView;
|
|
QCDScene *scene = new QCDScene( newView );
|
|
newView->setScene( scene );
|
|
|
|
if( !scene->load( fileName ) ) {
|
|
delete newView;
|
|
continue;
|
|
}
|
|
connect( scene, SIGNAL(selectionChanged()), this, SLOT(updateMenu()) );
|
|
connect( scene, SIGNAL(changed()), this, SLOT(updateMenu()) );
|
|
|
|
QMdiSubWindow *subWindow = m_mdiArea->addSubWindow( newView );
|
|
subWindow->show();
|
|
}
|
|
}
|
|
|
|
bool MainWindow::saveSceneAs( QCDScene *scene )
|
|
{
|
|
QString fileName =
|
|
QFileDialog::getSaveFileName( this,
|
|
scene->name() + tr( ": save as" ),
|
|
QString(),
|
|
tr("qlscribe document (*.qlx)") );
|
|
if( fileName.isNull() )
|
|
return false;
|
|
|
|
if( !fileName.contains( '.' ) )
|
|
fileName += ".qlx";
|
|
|
|
return scene->saveAs( fileName );
|
|
}
|
|
|
|
bool MainWindow::saveScene( QCDScene *scene )
|
|
{
|
|
return scene->isUnnamed() ? saveSceneAs( scene ) : scene->save();
|
|
}
|
|
|
|
|
|
void MainWindow::closeEvent(QCloseEvent *event)
|
|
{
|
|
bool saveAll = false;
|
|
QList< QMdiSubWindow * > subs = m_mdiArea->subWindowList();
|
|
foreach( QMdiSubWindow *sub, subs ) {
|
|
QCDView *cdview = dynamic_cast< QCDView * >( sub->widget() );
|
|
if( !cdview )
|
|
continue;
|
|
|
|
QCDScene *scene = cdview->scene();
|
|
if( !scene || scene->isSaved() )
|
|
continue;
|
|
|
|
bool save = saveAll;
|
|
if( !save ) {
|
|
QMessageBox::StandardButton button =
|
|
QMessageBox::question( this,
|
|
tr( "Confirmation" ),
|
|
scene->name() + tr( " is unsaved, do you want to save?" ),
|
|
QMessageBox::Save | QMessageBox::SaveAll | QMessageBox::Discard | QMessageBox::Cancel );
|
|
if( button == QMessageBox::Cancel ) {
|
|
event->ignore();
|
|
return;
|
|
}
|
|
if( button == QMessageBox::SaveAll ) {
|
|
saveAll = true;
|
|
save = true;
|
|
}
|
|
if( button == QMessageBox::Save )
|
|
save = true;
|
|
}
|
|
if( save )
|
|
if( !saveScene( scene ) ) {
|
|
event->ignore();
|
|
return;
|
|
}
|
|
}
|
|
QSettings settings;
|
|
|
|
settings.beginGroup( "MainWindow" );
|
|
settings.setValue( "size", size());
|
|
settings.setValue( "pos", pos());
|
|
settings.endGroup();
|
|
|
|
event->accept();
|
|
}
|
|
|
|
void MainWindow::onMenuNewLabel( int mode )
|
|
{
|
|
QCDView *newView = new QCDView;
|
|
QCDScene *scene = new QCDScene( newView );
|
|
scene->start( LabelMode( mode ) );
|
|
newView->setScene( scene );
|
|
scene->setName();
|
|
connect( scene, SIGNAL(selectionChanged()), this, SLOT(updateMenu()) );
|
|
connect( scene, SIGNAL(changed()), this, SLOT(updateMenu()) );
|
|
|
|
QMdiSubWindow *subWindow = m_mdiArea->addSubWindow( newView );
|
|
subWindow->show();
|
|
}
|
|
|
|
inline
|
|
QCDScene *getScene( QMdiArea *area )
|
|
{
|
|
QMdiSubWindow *subWindow = area->activeSubWindow();
|
|
if( !subWindow )
|
|
return 0;
|
|
|
|
QCDView *cdview = dynamic_cast< QCDView * >( subWindow->widget() );
|
|
if( !cdview )
|
|
return 0;
|
|
|
|
return cdview->scene();
|
|
}
|
|
|
|
void MainWindow::onMenuInsert( int id )
|
|
{
|
|
QCDScene *cdscene = getScene( m_mdiArea );
|
|
if( !cdscene )
|
|
return;
|
|
|
|
QShapeFactory &sfactory = QShapeFactory::instance();
|
|
QGraphicsItem *item = sfactory.create( id );
|
|
if( !item ) {
|
|
QMessageBox::warning( this,
|
|
"Warning",
|
|
tr( "Creator for type id %n returned zero pointer", 0, id ) );
|
|
return;
|
|
}
|
|
if( !sfactory.edit( item, this ) ) {
|
|
delete item;
|
|
return;
|
|
}
|
|
|
|
cdscene->addItem( item, true );
|
|
cdscene->setChanged();
|
|
}
|
|
|
|
void MainWindow::onMenuOpen()
|
|
{
|
|
QString filter( tr("qlscribe document (*.qlx);;Images ( ") );
|
|
QList<QByteArray> list = QImageReader::supportedImageFormats();
|
|
foreach( QByteArray arr, list ) {
|
|
filter += QString( "*." ) + arr.data() + " ";
|
|
}
|
|
filter += tr( ");;All Files (*)" );
|
|
|
|
QFileDialog fd( this, "Open:", QString(), filter );
|
|
|
|
bool injectPreview = QSettings().value( cfgInjectPreview, true ).toBool();
|
|
PreviewInjector pj( injectPreview ? &fd : 0 );
|
|
fd.setFileMode( QFileDialog::ExistingFile );
|
|
|
|
if( fd.exec() != QDialog::Accepted )
|
|
return;
|
|
|
|
QString fileName = fd.selectedFiles().value(0);
|
|
if( fileName.isNull() )
|
|
return;
|
|
|
|
QCDView *newView = new QCDView;
|
|
QCDScene *scene = new QCDScene( newView );
|
|
newView->setScene( scene );
|
|
|
|
if( !scene->load( fileName ) ) {
|
|
delete newView;
|
|
return;
|
|
}
|
|
connect( scene, SIGNAL(selectionChanged()), this, SLOT(updateMenu()) );
|
|
connect( scene, SIGNAL(changed()), this, SLOT(updateMenu()) );
|
|
|
|
QMdiSubWindow *subWindow = m_mdiArea->addSubWindow( newView );
|
|
subWindow->show();
|
|
}
|
|
|
|
void MainWindow::onMenuSave()
|
|
{
|
|
QCDScene *scene = getScene( m_mdiArea );
|
|
if( scene )
|
|
saveScene( scene );
|
|
}
|
|
|
|
void MainWindow::onMenuSaveAs()
|
|
{
|
|
QCDScene *scene = getScene( m_mdiArea );
|
|
if( scene )
|
|
saveSceneAs( scene );
|
|
}
|
|
|
|
void MainWindow::onMenuProperties()
|
|
{
|
|
QCDScene *scene = getScene( m_mdiArea );
|
|
if( scene )
|
|
QDialogCDProperties::exec( this, scene );
|
|
}
|
|
|
|
namespace {
|
|
const int bigImageSize = 1600;
|
|
}
|
|
|
|
inline
|
|
void drawCircle( QPainter &painter, double radi )
|
|
{
|
|
const int half = bigImageSize / 2;
|
|
painter.drawEllipse( QRectF( half - radi, half - radi, radi * 2, radi * 2 ) );
|
|
}
|
|
|
|
inline
|
|
void drawCircle( QPainterPath &path, double radi )
|
|
{
|
|
const int half = bigImageSize / 2;
|
|
path.addEllipse( QRectF( half - radi, half - radi, radi * 2, radi * 2 ) );
|
|
}
|
|
|
|
void MainWindow::onMenuPrintPreview()
|
|
{
|
|
QCDScene *cdscene = getScene( m_mdiArea );
|
|
if( !cdscene )
|
|
return;
|
|
|
|
PrintParameters params;
|
|
params.m_labelMode = cdscene->labelMode();
|
|
QPair< bool, QLightDrive * > bd = QDialogPrint::exec( this, params, true );
|
|
if( !bd.first )
|
|
return;
|
|
|
|
if( !bd.second ) {
|
|
// software "rendering"
|
|
QPixmap image( bigImageSize, bigImageSize );
|
|
image.fill( 0xFFFFFFFF );
|
|
|
|
cdscene->clearSelection();
|
|
{
|
|
QPainter painter( &image );
|
|
QColor circleColor( 0xd8, 0xd8, 0xd8 );
|
|
painter.setPen( circleColor );
|
|
painter.setBrush( circleColor );
|
|
drawCircle( painter, bigImageSize / 2 );
|
|
|
|
cdscene->render( &painter, image.rect() );
|
|
|
|
QPainterPath p1;
|
|
p1.addRect( image.rect() );
|
|
{
|
|
QPainterPath p2;
|
|
drawCircle( p2, bigImageSize / 2 );
|
|
painter.setClipPath( p1.subtracted( p2 ) );
|
|
painter.fillRect( image.rect(), Qt::white );
|
|
painter.setClipPath( p1 );
|
|
}
|
|
|
|
painter.setBrush( circleColor );
|
|
|
|
if( params.m_labelMode == modeTitle ) {
|
|
// 3.22
|
|
QPainterPath p2;
|
|
drawCircle( p2, bigImageSize / 3.20 );
|
|
painter.setClipPath( p1.subtracted( p2 ) );
|
|
drawCircle( painter, bigImageSize / 2 );
|
|
// 3.74
|
|
painter.setClipPath( p1 );
|
|
drawCircle( painter, bigImageSize / 3.74 );
|
|
} else
|
|
if( params.m_labelMode == modeContent ) {
|
|
// 3.22
|
|
QPainterPath p2;
|
|
drawCircle( p2, bigImageSize / 3.20 );
|
|
painter.setClipPath( p1.subtracted( p2 ) );
|
|
drawCircle( painter, bigImageSize / 2 );
|
|
|
|
// 4.69
|
|
painter.setClipPath( p1 );
|
|
drawCircle( painter, bigImageSize / 4.69 );
|
|
}
|
|
|
|
painter.setBrush( Qt::white );
|
|
drawCircle( painter, bigImageSize / 4.93 );
|
|
}
|
|
QLabel *label = new QLabel;
|
|
label->setPixmap( image.scaled( QSize( 400, 400 ) ) );
|
|
|
|
QMdiSubWindow *subWindow = m_mdiArea->addSubWindow( label );
|
|
subWindow->setWindowTitle( "Software preview: " + cdscene->name() );
|
|
subWindow->show();
|
|
|
|
} else {
|
|
try {
|
|
QPixmap pixmap = bd.second->preview( params, cdscene, QSize( 400, 400 ) );
|
|
QLabel *label = new QLabel;
|
|
label->setPixmap( pixmap );
|
|
QMdiSubWindow *subWindow = m_mdiArea->addSubWindow( label );
|
|
subWindow->setWindowTitle( "Preview: " + cdscene->name() );
|
|
subWindow->show();
|
|
}
|
|
catch( const QString &err ) {
|
|
QMessageBox::critical( this, tr( "Error on print preview" ), err );
|
|
}
|
|
}
|
|
}
|
|
|
|
void MainWindow::onMenuPrint()
|
|
{
|
|
QCDScene *cdscene = getScene( m_mdiArea );
|
|
if( !cdscene )
|
|
return;
|
|
|
|
try {
|
|
QDialogProgress::exec( this, cdscene );
|
|
}
|
|
catch( const QString &err ) {
|
|
QMessageBox::critical( this, tr( "Error on print" ), err );
|
|
}
|
|
}
|
|
|
|
void MainWindow::onMenuUndo()
|
|
{
|
|
QCDScene *scene = getScene( m_mdiArea );
|
|
if( scene )
|
|
scene->undo();
|
|
}
|
|
|
|
void MainWindow::onMenuRedo()
|
|
{
|
|
QCDScene *scene = getScene( m_mdiArea );
|
|
if( scene )
|
|
scene->redo();
|
|
}
|
|
|
|
void MainWindow::onMenuCopy()
|
|
{
|
|
QCDScene *scene = getScene( m_mdiArea );
|
|
if( scene )
|
|
scene->putItemToClipboard( false );
|
|
}
|
|
|
|
void MainWindow::onMenuCut()
|
|
{
|
|
QCDScene *scene = getScene( m_mdiArea );
|
|
if( scene )
|
|
scene->putItemToClipboard( true );
|
|
}
|
|
|
|
void MainWindow::onMenuPaste()
|
|
{
|
|
QCDScene *scene = getScene( m_mdiArea );
|
|
if( scene )
|
|
scene->getItemFromClipboard();
|
|
}
|
|
|
|
void MainWindow::onMenuAbout()
|
|
{
|
|
QMessageBox::about( this,
|
|
tr( "About" ),
|
|
tr( "<h3>qlscribe - Qt LightScribe</h3>"
|
|
"<p>release 0.20</p>"
|
|
"<p>visit project at home page "
|
|
"<a href=\"https://gitea.disconnected-by-peer.at/geos_one/qlscribe\">"
|
|
"gitea.disconnected-by-peer.at/geos_one/qlscribe</a></p>" ) );
|
|
}
|
|
|
|
void MainWindow::onMenuQtAbout()
|
|
{
|
|
QMessageBox::aboutQt( this );
|
|
}
|
|
|
|
void MainWindow::onMenuSettings()
|
|
{
|
|
QDialogSettings::exec( this );
|
|
}
|
|
|
|
void MainWindow::updateMenu()
|
|
{
|
|
QCDScene *scene = getScene( m_mdiArea );
|
|
|
|
m_actionSave->setEnabled( scene );
|
|
m_actionSaveAs->setEnabled( scene );
|
|
m_actionLabelProperties->setEnabled( scene );
|
|
m_actionPrint->setEnabled( scene );
|
|
m_actionPrintPreview->setEnabled( scene );
|
|
m_menuInsert->setEnabled( scene );
|
|
|
|
if( !scene ) {
|
|
m_actionUndo->setEnabled( false );
|
|
m_actionRedo->setEnabled( false );
|
|
m_actionCopy->setEnabled( false );
|
|
m_actionCut->setEnabled( false );
|
|
m_actionPaste->setEnabled( false );
|
|
} else {
|
|
m_actionUndo->setEnabled( scene->canUndo() );
|
|
m_actionRedo->setEnabled( scene->canRedo() );
|
|
|
|
const QMimeData *mdata = QApplication::clipboard()->mimeData();
|
|
m_actionPaste->setEnabled( mdata && mdata->hasFormat( itemMimeType ) );
|
|
|
|
bool selected = scene->selectedItems().count();
|
|
m_actionCopy->setEnabled( selected );
|
|
m_actionCut->setEnabled( selected );
|
|
}
|
|
}
|