#include "mainwindow.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int MainWindow::socketPair[2] = {0, 0}; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), loading(false), queued(0) { m_image = new ImageScrollArea(this); setCentralWidget(m_image); resize(800, 600); setWindowTitle(tr("Image Selector")); m_ringList = new ImageRingList(this); connect(m_ringList, SIGNAL(pixmapLoaded(QPixmap)), this, SLOT(pixmapLoaded(QPixmap))); connect(m_ringList, SIGNAL(currentImageChanged()), this, SLOT(updateWindowTitle())); QMenu *fileMenu = new QMenu(tr("File"), this); fileMenu->addAction(tr("Open"), this, SLOT(openFile()), QKeySequence("Ctrl+O")); fileMenu->addAction(tr("Copy marked files"), this, SLOT(copyMarked())); QAction *liveModeAction = fileMenu->addAction(tr("Live mode"), this, SLOT(liveMode(bool))); liveModeAction->setCheckable(true); fileMenu->addAction(tr("Exit"), this, SLOT(close())); menuBar()->addMenu(fileMenu); QMenu *viewMenu = new QMenu(tr("View"), this); viewMenu->addAction(tr("Zoom In"), m_image, SLOT(zoomIn()), QKeySequence::ZoomIn); viewMenu->addAction(tr("Zoom Out"), m_image, SLOT(zoomOut()), QKeySequence::ZoomOut); viewMenu->addAction(tr("Best Fit"), m_image, SLOT(bestFit()), QKeySequence("Ctrl+1")); viewMenu->addAction(tr("100%"), m_image, SLOT(oneToOne())); menuBar()->addMenu(viewMenu); QMenu *selectMenu = new QMenu(tr("Select"), this); selectMenu->addAction(tr("Mark"), this, SLOT(markImage()), Qt::Key_F5); selectMenu->addAction(tr("Unmark"), this, SLOT(unmarkImage()), Qt::Key_F8); selectMenu->addSeparator(); selectMenu->addAction(tr("Mark and next"), this, SLOT(markAndNext()), Qt::Key_M); selectMenu->addAction(tr("Unmark and next"), this, SLOT(unmarkAndNext()), Qt::Key_X); menuBar()->addMenu(selectMenu); m_database = new Database(this); if(!m_database->init()) QMessageBox::critical(this, tr("Can't open DB"), tr("Can't open SQLITE database")); setupSigterm(); } MainWindow::~MainWindow() { } void MainWindow::keyPressEvent(QKeyEvent *event) { if(!loading) { switch (event->key()) { case Qt::Key_Left: m_ringList->decrement(); break; case Qt::Key_Right: m_ringList->increment(); break; default: event->ignore(); break; } } else { event->ignore(); } if(event->isAccepted()) updateWindowTitle(); } void MainWindow::keyReleaseEvent(QKeyEvent *event) { event->ignore(); } void MainWindow::setupSigterm() { struct sigaction signal; signal.sa_handler = MainWindow::signalHandler; sigemptyset(&signal.sa_mask); signal.sa_flags = 0; signal.sa_flags |= SA_RESTART; sigaction(SIGHUP, &signal, 0); sigaction(SIGTERM, &signal, 0); sigaction(SIGINT, &signal, 0); ::socketpair(AF_UNIX, SOCK_STREAM, 0, socketPair); socketNotifier = new QSocketNotifier(socketPair[1], QSocketNotifier::Read, this); connect(socketNotifier, SIGNAL(activated(int)), this, SLOT(socketNotify())); } void MainWindow::signalHandler(int) { char a = 1; ::write(socketPair[0], &a, sizeof(a)); } void MainWindow::socketNotify() { socketNotifier->setEnabled(false); char tmp; read(socketPair[1], &tmp, sizeof(tmp)); close(); socketNotifier->setEnabled(true); } void MainWindow::pixmapLoaded(QPixmap pix) { m_image->setImage(pix); } void MainWindow::openFile() { QStringList standardLocations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation); QString path; if(standardLocations.size()) path = standardLocations.first(); QString file = QFileDialog::getOpenFileName(this, tr("Open file"), path, tr("Images (*.jpg *.png *.cr2 *.JPG *.PNG *.CR2)")); if(!file.isEmpty()) { QFileInfo info(file); m_ringList->setFile(info.canonicalFilePath()); updateWindowTitle(); } } void MainWindow::markImage() { ImagePtr ptr = m_ringList->currentImage(); if(ptr) { QString file = ptr->name(); if(!file.isEmpty()) m_database->mark(file); updateWindowTitle(); } } void MainWindow::unmarkImage() { ImagePtr ptr = m_ringList->currentImage(); if(ptr) { QString file = ptr->name(); if(!file.isEmpty()) m_database->unmark(file); updateWindowTitle(); } } void MainWindow::markAndNext() { markImage(); m_ringList->increment(); updateWindowTitle(); } void MainWindow::unmarkAndNext() { unmarkImage(); m_ringList->increment(); updateWindowTitle(); } void MainWindow::copyMarked() { QString dest = QFileDialog::getExistingDirectory(this, tr("Select destination")); QDir dir(dest); if(!dest.isEmpty() && dir.exists()) { int i = 0; QStringList files = m_database->getMarkedFiles(); QProgressDialog progress(tr("Copying"), tr("Cancel"), 0, files.size(), this); progress.setWindowModality(Qt::WindowModal); progress.show(); foreach(const QString &file, files) { QFileInfo info(file); QFile srcFile(file); QFile dstFile(dir.absoluteFilePath(info.fileName())); if(dstFile.exists()) continue; if(progress.wasCanceled()) break; srcFile.open(QIODevice::ReadOnly); dstFile.open(QIODevice::WriteOnly); if(ioctl(dstFile.handle(), BTRFS_IOC_CLONE, srcFile.handle()) < 0) { dstFile.remove(); dstFile.close(); qDebug() << dstFile.fileName(); srcFile.copy(dstFile.fileName()); } progress.setValue(i++); } } } void MainWindow::liveMode(bool active) { m_ringList->setLiveMode(active); } void MainWindow::updateWindowTitle() { ImagePtr ptr = m_ringList->currentImage(); if(ptr) { QFileInfo info(ptr->name()); QString title = info.fileName(); if(m_database->isMarked(ptr->name())) title += " *"; setWindowTitle(title); } }