#include "cmainwindow.h" #include "ui_cmainwindow.h" #include #include #include #include "cimage.h" #include "cexportdialog.h" #include "clogwindow.h" #include #include #include #include #include void addToExportLog(QString& exportLog, const QString& text) { QDateTime now = QDateTime::currentDateTime(); exportLog.append(" \n " + now.toString("yyyy-mm-dd hh:MM:ss") + "\n " + text + "\n \n"); } cMainWindow::cMainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::cMainWindow), m_progressBar(nullptr), m_listToolBar(nullptr), m_refreshAction(nullptr), m_actionToolBar(nullptr), m_exportAction(nullptr), m_stopAction(nullptr), m_albumRootsList(nullptr), m_albumsList(nullptr), m_folderViewModel(nullptr), m_folderSortFilterProxyModel(nullptr), m_thumbnailViewModel(nullptr), m_thumbnailSortFilterProxyModel(nullptr), m_rootItem(nullptr), m_loading(false), m_working(false), m_stopIt(false), m_exportLog("") { initUI(); createActions(); setImageFormats(); loadData(); initSignals(); } cMainWindow::~cMainWindow() { if(m_albumRootsList) delete m_albumRootsList; if(m_dbThumbnail.isOpen()) m_dbThumbnail.close(); if(m_dbDigikam.isOpen()) m_dbDigikam.close(); delete ui; } void cMainWindow::closeEvent(QCloseEvent *event) { QSettings settings; settings.setValue("main/width", QVariant::fromValue(size().width())); settings.setValue("main/height", QVariant::fromValue(size().height())); settings.setValue("main/x", QVariant::fromValue(x())); settings.setValue("main/y", QVariant::fromValue(y())); if(this->isMaximized()) settings.setValue("main/maximized", QVariant::fromValue(true)); else settings.setValue("main/maximized", QVariant::fromValue(false)); QList sizes = ui->m_splitter->sizes(); for(int x = 0;x < sizes.count();x++) settings.setValue(QString("main/splitter%1").arg(x+1), QVariant::fromValue(sizes[x])); // m_filterPanel->saveSettings(); event->accept(); } void cMainWindow::initUI() { ui->setupUi(this); QIcon::setThemeName("TangoMFK"); m_folderViewModel = new QStandardItemModel; m_folderSortFilterProxyModel = new cFolderSortFilterProxyModel(this); ui->m_folderView->setModel(m_folderSortFilterProxyModel); m_folderSortFilterProxyModel->setSourceModel(m_folderViewModel); m_thumbnailViewModel = new QStandardItemModel; m_thumbnailSortFilterProxyModel = new cThumbnailSortFilterProxyModel(this); ui->m_thumbnailView->setModel(m_thumbnailSortFilterProxyModel); m_thumbnailSortFilterProxyModel->setSourceModel(m_thumbnailViewModel); QSettings settings; if(!settings.value("main/maximized").toBool()) { qint32 iX = settings.value("main/x", QVariant::fromValue(-1)).toInt(); qint32 iY = settings.value("main/y", QVariant::fromValue(-1)).toInt(); qint32 iWidth = settings.value("main/width", QVariant::fromValue(-1)).toInt(); qint32 iHeight = settings.value("main/height", QVariant::fromValue(-1)).toInt(); if(iWidth != -1 && iHeight != -1) resize(iWidth, iHeight); if(iX != -1 && iY != -1) move(iX, iY); } qint32 iWidth1 = settings.value("main/splitter1", QVariant::fromValue(-1)).toInt(); qint32 iWidth2 = settings.value("main/splitter2", QVariant::fromValue(-1)).toInt(); qint32 iWidth3 = settings.value("main/splitter3", QVariant::fromValue(-1)).toInt(); ui->m_splitter->setSizes(QList() << iWidth1 << iWidth2 << iWidth3); m_progressBar = new QProgressBar(this); m_progressBar->setVisible(false); ui->m_statusBar->addPermanentWidget(m_progressBar); } void cMainWindow::createActions() { setToolButtonStyle(Qt::ToolButtonFollowStyle); createMenuActions(); createContextActions(); } void cMainWindow::createMenuActions() { m_listToolBar = addToolBar("list"); const QIcon refreshIcon = QIcon::fromTheme("view-refresh"); m_refreshAction = m_listToolBar->addAction(refreshIcon, tr("&Refresh"), this, &cMainWindow::onRefreshList); m_refreshAction->setShortcut(Qt::Key_F5); m_actionToolBar = addToolBar("action"); const QIcon startIcon = QIcon::fromTheme("media-playback-start"); m_exportAction = m_actionToolBar->addAction(startIcon, tr("&Export"), this, &cMainWindow::onExport); m_exportAction->setShortcut(Qt::CTRL | Qt::Key_R); const QIcon stopIcon = QIcon::fromTheme("process-stop"); m_stopAction = m_actionToolBar->addAction(stopIcon, tr("&Stop"), this, &cMainWindow::onStop); } void cMainWindow::createContextActions() { } void cMainWindow::setImageFormats() { QList readList = QImageReader::supportedImageFormats(); QList writeList = QImageWriter::supportedImageFormats(); QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "exportDigikam"); db.setHostName("localhost"); db.setDatabaseName("exportDigikam.db"); if(!db.open()) return; QSqlQuery query(db); query.prepare("SELECT shortname, description, extension FROM imageFormat;"); if(!query.exec()) { db.close(); return; } while(query.next()) addImageFormat(query.value("shortname").toString(), query.value("description").toString(), query.value("extension").toString(), readList, writeList); db.close(); } void cMainWindow::addImageFormat(const QString& shortName, const QString& description, const QString& extension, QList& readList, QList& writeList) { bool r = readList.contains(QByteArray(shortName.toUtf8())); bool w = writeList.contains(QByteArray(shortName.toUtf8())); if(QString(shortName).isEmpty()) r = true; IMAGEFORMAT i; i.shortName = shortName; i.description = description; i.extension = extension; i.read = r; i.write = w; m_imageFormats.append(i); } void cMainWindow::loadData() { m_thumbnailViewModel->clear(); m_folderViewModel->clear(); QElapsedTimer timer; timer.start(); if(m_albumRootsList) delete m_albumRootsList; if(m_albumsList) delete m_albumsList; if(!m_dbDigikam.isOpen()) { m_dbDigikam = QSqlDatabase::addDatabase("QSQLITE", "digikam4"); m_dbDigikam.setDatabaseName("C:\\Temp\\__DIGIKAM__\\digikam4.db"); if(!m_dbDigikam.open()) { qDebug() << "Digikam: DB Open failed. " << m_dbDigikam.lastError().text(); return; } } if(!m_dbThumbnail.isOpen()) { m_dbThumbnail = QSqlDatabase::addDatabase("QSQLITE", "thumbnails-digikam"); m_dbThumbnail.setDatabaseName("C:\\Temp\\__DIGIKAM__\\thumbnails-digikam.db"); if(!m_dbThumbnail.open()) { qDebug() << "Thumbnail: DB Open failed. " << m_dbDigikam.lastError().text(); return; } } m_albumRootsList = new cAlbumRootsList(&m_dbDigikam, &m_dbThumbnail, this); if(!m_albumRootsList) { qDebug() << "Album Root List: out of memory."; return; } if(!m_albumRootsList->load()) { qDebug() << "Album Root List: load failed."; return; } m_albumsList = new cAlbumsList(&m_dbDigikam, &m_dbThumbnail, m_albumRootsList, this); if(!m_albumsList) { qDebug() << "Album List: out of memory."; return; } if(!m_albumsList->load()) { qDebug() << "Album List: load failed."; return; } qDebug() << "Loading took " << timer.elapsed() << "ms"; displayData(); ui->m_folderView->expandAll(); } void cMainWindow::displayData() { m_loading = true; m_thumbnailViewModel->clear(); m_folderViewModel->clear(); m_rootItem = new QStandardItem("library"); m_folderViewModel->appendRow(m_rootItem); for(int x = 0;x < m_albumRootsList->count();x++) { QStandardItem* lpItem = new QStandardItem(m_albumRootsList->at(x)->label()); lpItem->setData(QVariant::fromValue(m_albumRootsList->at(x)), Qt::UserRole+1); lpItem->setCheckable(true); m_albumRootsList->at(x)->setItem(lpItem); m_rootItem->appendRow(lpItem); } for(int x = 0;x < m_albumsList->count();x++) { cAlbums* lpAlbums = m_albumsList->at(x); QStandardItem* lpItem = new QStandardItem(lpAlbums->path()); lpItem->setData(QVariant::fromValue(lpAlbums), Qt::UserRole+1); lpItem->setCheckable(true); QStandardItem* lpRootItem = findDBRootItem(m_folderViewModel, m_rootItem, lpAlbums->albumRoots()); if(lpAlbums->parentAlbums()) lpRootItem = lpAlbums->parentAlbums()->item(); lpAlbums->setItem(lpItem); lpRootItem->appendRow(lpItem); } m_loading = false; } QStandardItem* cMainWindow::findDBRootItem(QStandardItemModel* model, QStandardItem *rootItem, cAlbumRoots* albumRoots) { QModelIndex parent; if(rootItem) parent = rootItem->index(); for(int x = 0;x < model->rowCount(parent);x++) { QStandardItem* item = model->itemFromIndex(model->index(x, 0, parent)); if(item->data(Qt::UserRole+1).value() == albumRoots) return(item); } return(nullptr); } QStandardItem* cMainWindow::findParentItem(QStandardItemModel* model, QStandardItem *rootItem, cAlbums* albumRoots) { QModelIndex parent; if(rootItem) parent = rootItem->index(); for(int x = 0;x < model->rowCount(parent);x++) { QStandardItem* item = model->itemFromIndex(model->index(x, 0, parent)); if(item->data(Qt::UserRole+1).value() == albumRoots) return(item); if(item->hasChildren()) { item = findParentItem(model, item, albumRoots); if(item) return(item); } } return(nullptr); } void cMainWindow::initSignals() { connect(m_folderViewModel, &QStandardItemModel::itemChanged, this, &cMainWindow::onFolderViewItemChanged); connect(ui->m_folderView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &cMainWindow::onFolderSelected); connect(ui->m_thumbnailView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &cMainWindow::onThumbnailSelected); } void cMainWindow::onFolderViewItemChanged(QStandardItem* item) { Qt::CheckState state = item->checkState(); QModelIndex parent = item->index(); cAlbums* albums = item->data().value(); cImagesList* imagesList = nullptr; if(albums) imagesList = albums->imagesList(); if(imagesList) { for(int y = 0;y < imagesList->count();y++) { cImages* images = imagesList->at(y); QStandardItem* imagesItem = images->item(); if(imagesItem) imagesItem->setCheckState(state); } } for(int x = 0;x < m_folderViewModel->rowCount(parent);x++) { QStandardItem* curItem = m_folderViewModel->itemFromIndex(m_folderViewModel->index(x, 0, parent)); if(!curItem) continue; curItem->setCheckState(state); albums = curItem->data().value(); imagesList = albums->imagesList(); if(!imagesList) continue; if(!imagesList->count()) continue; for(int y = 0;y < imagesList->count();y++) { cImages* images = imagesList->at(y); QStandardItem* imagesItem = images->item(); if(imagesItem) imagesItem->setCheckState(state); } } } void cMainWindow::onFolderSelected(const QItemSelection& /*selection*/, const QItemSelection& /*previous*/) { if(m_loading) return; m_thumbnailViewModel->clear(); ui->m_information->clear(); if(!ui->m_folderView->selectionModel()->selectedIndexes().count()) return; QModelIndex index = ui->m_folderView->selectionModel()->selectedIndexes()[0]; if(!index.isValid()) return; cAlbums* albums = m_folderSortFilterProxyModel->data(index, Qt::UserRole+1).value(); Qt::CheckState state = albums->item()->checkState(); bool loaded = albums->loadImages(); cImagesList* imagesList = albums->imagesList(); if(!imagesList) return; for(int x = 0;x < imagesList->count();x++) { cImages* images = imagesList->at(x); if(!images) continue; QStandardItem* item = images->item(); if(loaded) item->setCheckState(state); m_thumbnailViewModel->appendRow(item); } } void cMainWindow::onThumbnailSelected(const QItemSelection& /*selection*/, const QItemSelection& /*previous*/) { QModelIndex index = ui->m_thumbnailView->selectionModel()->selectedIndexes()[0]; if(!index.isValid()) return; cImages* images = m_thumbnailSortFilterProxyModel->data(index, Qt::UserRole+1).value(); if(images) { QString information; information = "\n"; information.append("\n"); information.append(" \n"); information.append(" \n"); information.append(" \n"); information.append(" \n"); information.append(" \n"); information.append(" "); information.append(QString(" \n").arg(images->name())); information.append(QString(" \n").arg(images->albums()->path())); information.append(QString(" \n").arg(images->modificationDate().toString())); information.append(QString(" \n").arg(images->fileSize())); information.append(" \n"); information.append(QString(" \n").arg(images->imageInformation().format)); information.append(QString(" \n").arg(images->imageInformation().width).arg(images->imageInformation().height)); information.append(QString(" \n").arg(images->imageInformation().colorDepth)); information.append(" \n"); information.append(QString(" \n").arg(images->imageMetadata().model)); information.append(QString(" \n").arg(images->imageInformation().creationDate.toString())); information.append(QString(" \n").arg(images->imageMetadata().lens)); information.append(QString(" \n").arg(images->imageMetadata().aparture)); information.append(QString(" \n").arg(images->imageMetadata().focalLength)); information.append(QString(" \n").arg(images->imageMetadata().focalLength35)); information.append(QString(" \n").arg(1/images->imageMetadata().exposureTime)); information.append(QString(" \n").arg(images->imageMetadata().sensitivity)); information.append("
File properties
File:%1
Folder:%1
Date:%1
Size:%1
Image properties
Type:%1
Size:%1x%2
Color depth:%1 bpp
Shoot properties
Camera:%1
Taken:%1
Lens:%1
Aparture:F%1
Focal length:%1
Focal length (35mm):%1
Exposure time:1/%1
Sensitivity:ISO %1
\n"); information.append(" \n"); m_exportLog.append("\n"); ui->m_information->setText(information); } else ui->m_information->clear(); } void cMainWindow::onRefreshList() { loadData(); } void cMainWindow::onExport() { bool hasExport = false; for(int x = 0;x < m_albumsList->count();x++) { cAlbums* albums = m_albumsList->at(x); QStandardItem* item = albums->item(); if(item) { if(item->checkState() == Qt::Checked) { hasExport = true; goto done; } } if(albums) { cImagesList* imagesList = albums->imagesList(); if(imagesList) { for(int y = 0;y < imagesList->count();y++) { cImages* images = albums->imagesList()->at(y); if(images) { QStandardItem* item = images->item(); if(item) { if(item->checkState() == Qt::Checked) { hasExport = true; goto done; } } } } } } } done: if(!hasExport) { QMessageBox::information(this, "Export", tr("No files selected for export.")); return; } cExportDialog exportDialog(m_imageFormats, this); if(exportDialog.exec() == QDialog::Rejected) return; m_working = true; m_stopIt = false; // setActionEnabled(false, false, false, false, false, true); doExport(); // setActionEnabled(true, true, true, true, true, false); m_working = false; } void cMainWindow::onStop() { } void cMainWindow::doExport() { EXPORTSETTINGS exportSettings; OVERWRITE overwrite = OVERWRITE_ASK; m_exportLog = "\n"; m_exportLog.append("\n"); m_exportLog.append("\n"); m_exportLog.append("\n"); m_exportLog.append("\n"); m_exportLog.append("\n"); addToExportLog(m_exportLog, "Start Export"); getExportSettings(exportSettings); qint32 fileCount = 0; for(int x = 0;x < m_albumsList->count();x++) { cAlbums* albums = m_albumsList->at(x); if(albums) { cImagesList* imagesList = albums->imagesList(); if(imagesList) { for(int y = 0;y < imagesList->count();y++) { cImages* images = albums->imagesList()->at(y); if(images) { QStandardItem* item = images->item(); if(item) { if(item->checkState() == Qt::Checked) fileCount++; } } } } } } addToExportLog(m_exportLog, QString("Files to export: %1").arg(fileCount)); m_progressBar->setRange(0, fileCount); m_progressBar->setValue(0); m_progressBar->setVisible(true); qint32 curFile = 0; for(int x = 0;x < m_albumsList->count();x++) { cAlbums* albums = m_albumsList->at(x); if(albums) { cImagesList* imagesList = albums->imagesList(); if(imagesList) { for(int y = 0;y < imagesList->count();y++) { cImages* images = albums->imagesList()->at(y); if(images) { QStandardItem* item = images->item(); if(item) { if(item->checkState() == Qt::Checked) { m_progressBar->setValue(curFile); ui->m_statusBar->showMessage(images->name()); qApp->processEvents(); // overwrite = exportFile(exportSettings, overwrite); curFile++; } } } } } } } // for(int i = 0;i < m_lpFileListModel->rowCount();i++) // { // QStandardItem* lpItem = m_lpFileListModel->item(i, 0); // if(!lpItem) // continue; // cEXIF* lpExif = lpItem->data(Qt::UserRole+1).value(); // if(!lpExif) // continue; // overwrite = exportFile(exportSettings, lpExif, overwrite); // m_lpProgressBar->setValue(i+1); // qApp->processEvents(); // if(m_stopIt) // { // addToExportLog(m_exportLog, "aborted."); // break; // } // } m_progressBar->setVisible(false); ui->m_statusBar->showMessage(tr("export done."), 3000); addToExportLog(m_exportLog, "done."); m_exportLog.append("\n"); m_exportLog.append("\n"); cLogWindow logWindow; logWindow.setText(m_exportLog); logWindow.exec(); } /* DIRECTORY_METHOD directoryMethod; QString directory; bool keepStructure; QString directoryTag; STRIP_LAST_FOLDER_METHOD stripLastFolderMethod; QStringList stripLastFolderIfList; FILE_METHOD fileMethod; FILE_ADD fileAdd; QString fileTag; OVERWRITE_METHOD overwriteMethod; bool copyEXIF; QString fileFormat; int quality; */ void cMainWindow::getExportSettings(EXPORTSETTINGS& exportSettings) { QSettings settings; QString tmp; tmp = settings.value("export/directoryMethod", QVariant::fromValue(QString("keepDirectory"))).toString(); addToExportLog(m_exportLog, "Settings:"); exportSettings.directory = settings.value("export/destinationPath", QVariant::fromValue(QString(""))).toString(); exportSettings.keepStructure = settings.value("export/keepStructure", QVariant::fromValue(false)).toBool(); exportSettings.directoryTag = settings.value("export/destinationPathTag", QVariant::fromValue(QString(""))).toString(); if(tmp == "newDirectoryTag") { exportSettings.directoryMethod = DIRECTORY_METHOD_TAG; addToExportLog(m_exportLog, "Directory Name Method: rename Directory by TAG"); addToExportLog(m_exportLog, " - used TAG: " + exportSettings.directoryTag + ""); } else if(tmp == "newDirectory") { exportSettings.directoryMethod = DIRECTORY_METHOD_NEW; addToExportLog(m_exportLog, "Directory Name Method: create new directory"); addToExportLog(m_exportLog, " - used Directory: " + exportSettings.directory + ""); } else { exportSettings.directoryMethod = DIRECTORY_METHOD_KEEP; addToExportLog(m_exportLog, "Directory Name Method: keep directory"); } addToExportLog(m_exportLog, QString("Keep old Structure: %1").arg(exportSettings.keepStructure ? "yes" : "no")); bool stripLastFolder = settings.value("export/stripLastDirectory", QVariant::fromValue(false)).toBool(); bool stripLastFolderIf = settings.value("export/stripLastDirectoryIf", QVariant::fromValue(false)).toBool(); if(stripLastFolder) { if(stripLastFolderIf) { exportSettings.stripLastFolderMethod = STRIP_LAST_FOLDER_METHOD::STRIP_LAST_FOLDER_IF; exportSettings.stripLastFolderIfList = settings.value("export/stripLastDirectoryIfList", QVariant::fromValue(QString(""))).toString().split("\n"); addToExportLog(m_exportLog, "Strip last folder: yes"); addToExportLog(m_exportLog, QString(" - folders to strip: %1").arg(exportSettings.stripLastFolderIfList.join(", "))); } else { exportSettings.stripLastFolderMethod = STRIP_LAST_FOLDER_METHOD::STRIP_LAST_FOLDER; addToExportLog(m_exportLog, "Strip last folder: yes"); } } else { exportSettings.stripLastFolderMethod = STRIP_LAST_FOLDER_METHOD::STRIP_LAST_FOLDER_NO; addToExportLog(m_exportLog, "Strip last folder: no"); } tmp = settings.value("export/filenamePlus", QVariant::fromValue(QString("converted"))).toString(); if(tmp == "TAG") exportSettings.fileAdd = FILE_ADD_TAG; else exportSettings.fileAdd = FILE_ADD_CONVERTED; exportSettings.fileTag = settings.value("export/fileTag", QVariant::fromValue(QString(""))).toString(); tmp = settings.value("export/fileMethod", QVariant::fromValue(QString("keepFilename"))).toString(); if(tmp == "newFilename") { exportSettings.fileMethod = FILE_METHOD_RENAME; addToExportLog(m_exportLog, "File Name Method: FILE_METHOD_RENAME"); if(exportSettings.fileAdd == FILE_ADD_TAG) addToExportLog(m_exportLog, " - used TAG: " + exportSettings.fileTag + ""); else addToExportLog(m_exportLog, " - add '_converted'"); } else { exportSettings.fileMethod = FILE_METHOD_KEEP; addToExportLog(m_exportLog, "File Name Method: FILE_METHOD_KEEP"); } tmp = settings.value("export/overwrite", QVariant::fromValue(QString("ask"))).toString(); if(tmp == "no") { exportSettings.overwriteMethod = OVERWRITE_METHOD_NOEXPORT; addToExportLog(m_exportLog, "Existing File Overwrite Mode: do not export existing file"); } else if(tmp == "overwrite") { exportSettings.overwriteMethod = OVERWRITE_METHOD_OVERWRITE; addToExportLog(m_exportLog, "Existing File Overwrite Mode: overwrite existing file"); } else if(tmp == "rename") { exportSettings.overwriteMethod = OVERWRITE_METHOD_RENAME; addToExportLog(m_exportLog, "Existing File Overwrite Mode: rename existing file"); } else { exportSettings.overwriteMethod = OVERWRITE_METHOD_ASK; addToExportLog(m_exportLog, "Existing File Overwrite Mode: ask for overwrite"); } exportSettings.copyEXIF = settings.value("export/copyEXIF", QVariant::fromValue(true)).toBool(); exportSettings.fileFormat = settings.value("export/fileFormat").toString(); exportSettings.quality = settings.value("export/quality", QVariant::fromValue(50)).toInt(); addToExportLog(m_exportLog, "File Format: " + exportSettings.fileFormat + ""); addToExportLog(m_exportLog, "Default Output Quality: " + QString::number(exportSettings.quality) + ""); }