initial import
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
# -------------------------------------------------
|
||||
# Project created by QtCreator 2009-08-15T12:08:20
|
||||
# -------------------------------------------------
|
||||
QT += sql
|
||||
TARGET = Importer
|
||||
TEMPLATE = app
|
||||
SOURCES += main.cpp \
|
||||
importerdialog.cpp \
|
||||
imageoutputformatdialog.cpp
|
||||
HEADERS += importerdialog.h \
|
||||
imageoutputformatdialog.h
|
||||
FORMS += importerdialog.ui \
|
||||
imageoutputformatdialog.ui
|
||||
@@ -0,0 +1,51 @@
|
||||
//! \file imageoutputformatdialog.cpp
|
||||
|
||||
#include "imageoutputformatdialog.h"
|
||||
#include "ui_imageoutputformatdialog.h"
|
||||
|
||||
ImageOutputFormatDialog::ImageOutputFormatDialog(QWidget *parent, QStringList list, bool keeppagenumber, int startpagenumber) :
|
||||
QDialog(parent),
|
||||
m_ui(new Ui::ImageOutputFormatDialog)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
//create the structure
|
||||
//we have 2 situations, either we want to keep the images names as they, or we would like to rename them sequentially
|
||||
// if we want to keep the names as they were!
|
||||
if( keeppagenumber )
|
||||
{
|
||||
//first show the user how everything will look like, and make sure its correct, and thats what he really want!
|
||||
for(int i=0; i< list.count(); i++)
|
||||
{
|
||||
QString name = list[i];
|
||||
//the newName value will be stripped down from all NON numeric character, and will output the name in the format dddd.jpg, where d is digit (0-9)
|
||||
QString destinationName = QString("%1.jpg").arg(name.remove(QRegExp("[^\\d]")), 4, QChar('0'));
|
||||
outputFileNames << destinationName;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i=0; i< list.count(); i++)
|
||||
{
|
||||
QString destinationName = QString("%1.jpg").arg(QString::number(i+startpagenumber), 4, QChar('0'));
|
||||
outputFileNames << destinationName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//create top level item and insert it to the treewidget
|
||||
QTreeWidgetItem *dirItem = new QTreeWidgetItem(QStringList(tr("Image names will look like this")));
|
||||
m_ui->treeWidget->insertTopLevelItem(0, dirItem);
|
||||
|
||||
for(int i=0; i < outputFileNames.count(); i++)
|
||||
{
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(QStringList( outputFileNames[i] ) );
|
||||
m_ui->treeWidget->itemAt(0,0)->addChild(item); //insert items from the list to treewidget
|
||||
}
|
||||
m_ui->treeWidget->expandAll();
|
||||
}
|
||||
|
||||
ImageOutputFormatDialog::~ImageOutputFormatDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
//! \file imageoutputformatdialog.h
|
||||
|
||||
#ifndef IMAGEOUTPUTFORMATDIALOG_H
|
||||
#define IMAGEOUTPUTFORMATDIALOG_H
|
||||
|
||||
#include <QtGui/QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class ImageOutputFormatDialog;
|
||||
}
|
||||
|
||||
//! \class ImageOutputFormatDialog
|
||||
//! \brief this class is used to show how the images will be named based on the users selection in the ImporterDialog class
|
||||
//! \author elzubeir
|
||||
class ImageOutputFormatDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
//! \fn ImageOutputFormatDialog(QWidget *parent, QStringList list)
|
||||
//! constructor that creates the object, and populate the tree widget with the list of
|
||||
//! names that are passed to it from the calling widget
|
||||
//! \param[in] parent QWidget pointer to parent class
|
||||
//! \param[in] list QStringList to hold list of image names to be displayed for the user
|
||||
//! \author elzubeir
|
||||
ImageOutputFormatDialog(QWidget *parent, QStringList lis, bool keeppagenumber, int startpagenumber);
|
||||
|
||||
//! \fn ~ImageOutputFormatDialog
|
||||
//! class destructor
|
||||
//! \author elzubeir
|
||||
~ImageOutputFormatDialog();
|
||||
|
||||
//! name of the output file
|
||||
QStringList outputFileNames;
|
||||
private:
|
||||
//! pointer to the Qt desginer UI class object
|
||||
Ui::ImageOutputFormatDialog *m_ui;
|
||||
};
|
||||
|
||||
#endif // IMAGEOUTPUTFORMATDIALOG_H
|
||||
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ImageOutputFormatDialog</class>
|
||||
<widget class="QDialog" name="ImageOutputFormatDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>280</width>
|
||||
<height>261</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QTreeWidget" name="treeWidget">
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Image output names</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Are you sure?</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>93</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>ImageOutputFormatDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>ImageOutputFormatDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +1,814 @@
|
||||
//! \file importerdialog.cpp
|
||||
//! \brief the implementation of the class
|
||||
#include <QtGui>
|
||||
#include <QtGlobal> //Q_WS_WIN
|
||||
|
||||
#include "importerdialog.h"
|
||||
#include "imageoutputformatdialog.h"
|
||||
#include "section.h"
|
||||
#include "importerthread.h"
|
||||
#include "constants.h"
|
||||
#include "globalfunctions.h"
|
||||
#include "publication.h"
|
||||
|
||||
#include "ui_importerdialog.h"
|
||||
|
||||
ImporterDialog::ImporterDialog(QWidget *parent, QSqlDatabase &masterDb, QSqlDatabase &slaveDb, User &user)
|
||||
: QDialog(parent), ui(new Ui::ImporterDialog), m_masterDatabase(masterDb), m_slaveDatabase(slaveDb), m_user(user)
|
||||
//, m_section(m_masterDatabase, m_slaveDatabase)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
//hid the progressbar
|
||||
ui->totalProgressBar->setVisible(false);
|
||||
ui->totalUploadLabel->setVisible(false);
|
||||
ui->totalUploadLabel_2->setVisible(false);
|
||||
|
||||
ui->fileUploadLabel->setVisible(false);
|
||||
ui->fileProgressBar->setVisible(false);
|
||||
ui->fileUploadLabel_1->setVisible(false);
|
||||
|
||||
|
||||
ui->publicationDate->setDate(QDate::currentDate()); //set the current date to today!
|
||||
ui->issueNumberLineEdit->setText(QDate::currentDate().toString(QString("yyyyMMdd"))); //set the form for the issue number to current date
|
||||
|
||||
QStringList list;
|
||||
QSqlQuery query("SELECT id_publication, name_publication_en, skip_ocr FROM publication", m_slaveDatabase);
|
||||
while( query.next() )
|
||||
{
|
||||
int id_publication = query.value(0).toInt();
|
||||
QString publicationName = query.value(1).toString();
|
||||
bool skipOcr = query.value(2).toBool();
|
||||
list << publicationName; //populate list with values from the database
|
||||
|
||||
m_publicationHash[publicationName] = id_publication; //also populate the hash table with name/id values
|
||||
m_publicationSkipOcrHash[publicationName] = skipOcr; //populate the hash table with name/skipocr values
|
||||
}
|
||||
|
||||
QCompleter* completer = new QCompleter(list, this); //createa completer with the list of publication names
|
||||
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
||||
ui->publicationNameLineEdit->setCompleter(completer); //use the complete with the publicationLineEdit
|
||||
|
||||
|
||||
//get section entries from database;
|
||||
//list = m_section.sections();
|
||||
list = Section::sectionNames(m_slaveDatabase);
|
||||
ui->sectionComboBox->addItems(list);
|
||||
|
||||
|
||||
//get issues path from database, and set the m_issuesPath with that value
|
||||
query.exec("SELECT issues_path, issues_windows_drive_letter FROM system_configuration");
|
||||
while (query.next())
|
||||
{
|
||||
m_issuesPath = query.value(0).toString();
|
||||
m_issuesWindowDriveLetter = query.value(1).toString();
|
||||
}
|
||||
|
||||
if( !m_issuesPath.startsWith("/") )
|
||||
m_issuesPath = "/" + m_imagesPath;
|
||||
|
||||
if( !m_issuesPath.endsWith("/") )
|
||||
m_issuesPath += "/";
|
||||
|
||||
//read ftp access
|
||||
m_thread = new ImporterThread(this);
|
||||
// connect(m_thread, SIGNAL(terminated()), this, SLOT(threadTerminated()) );
|
||||
|
||||
m_timer = new QTimer(); //create a timer and connect it's timeout signal to the update slot
|
||||
connect(m_timer, SIGNAL(timeout()), this, SLOT(update()));
|
||||
|
||||
connect(m_thread, SIGNAL(importerThreadCompleted()), this, SLOT(importerThreadCompleted()));
|
||||
}
|
||||
|
||||
ImporterDialog::~ImporterDialog()
|
||||
{
|
||||
m_masterDatabase.close();
|
||||
m_slaveDatabase.close();
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ImporterDialog::keyPressEvent(QKeyEvent *key)
|
||||
{
|
||||
if(key->key() == Qt::Key_Escape)//ignore the escape key pressed
|
||||
return;
|
||||
|
||||
QDialog::keyPressEvent(key);
|
||||
}
|
||||
|
||||
//private slots
|
||||
void ImporterDialog::import()
|
||||
{
|
||||
//make sure that the publication line edit is not empty
|
||||
QString publication_name = ui->publicationNameLineEdit->text().trimmed();
|
||||
if (publication_name.isEmpty() )
|
||||
{
|
||||
QMessageBox::warning(this, tr("Empty publication"), tr("Please select a publication\nEmpty publication names is not allowed"));
|
||||
ui->publicationNameLineEdit->setFocus();
|
||||
return;
|
||||
}
|
||||
|
||||
//get the id of the publicaiton to be used when creating the structure in the file server
|
||||
int id_publication = m_publicationHash[publication_name];
|
||||
bool skipOcr = m_publicationSkipOcrHash[publication_name];
|
||||
|
||||
if(id_publication == 0)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Error in publication ID"), tr("This publication has an id = 0, please check with your system administrator to fix this problem"));
|
||||
return;
|
||||
}
|
||||
|
||||
//get the id_section from the article_sections table
|
||||
int id_section = Section::sectionId(m_slaveDatabase, ui->sectionComboBox->currentText());
|
||||
if( id_section == 0)
|
||||
return;
|
||||
|
||||
//get date from publication date line edit, its in the ISODate format, i.e. yyy-MM-dd
|
||||
QString issue_date = ui->publicationDate->text();
|
||||
|
||||
int id_issue = ui->issueNumberLineEdit->text().toInt();
|
||||
if( id_issue == 0 )
|
||||
{
|
||||
ui->issueNumberLineEdit->setText(QDate::currentDate().toString("yyyMMdd"));
|
||||
id_issue = QDate::currentDate().toString("yyyMMdd").toInt(); //if empty, set it up to use the current date as issuenumber
|
||||
}
|
||||
|
||||
//get starting page number
|
||||
int startPagenumber = ui->startNumberlineEdit->text().toInt();
|
||||
if ( startPagenumber <= 0 )
|
||||
startPagenumber = 1; //if its empty set the default value to 1
|
||||
|
||||
bool keepPagenumber = ui->keepPageNumberCheckBox->isChecked();
|
||||
|
||||
//call the ImageOutputFormatDialog dialog to show the user how the naming will look like
|
||||
ImageOutputFormatDialog dlg(this, m_srcFileNames, keepPagenumber, startPagenumber);
|
||||
|
||||
if (dlg.exec() == QDialog::Rejected) //if the naming is not acceptable, exit the function without performing the import
|
||||
return;
|
||||
|
||||
setEnabled(false);
|
||||
|
||||
m_dstFileNames = dlg.outputFileNames;
|
||||
//disable import button
|
||||
ui->importButton->setEnabled(false);
|
||||
|
||||
if ( !m_imagesPath.endsWith("/") )
|
||||
m_imagesPath += "/";
|
||||
|
||||
|
||||
m_useFtp = false;
|
||||
readSettings();
|
||||
|
||||
//check if this is update operation or not
|
||||
int id_publication_issue = publicationIssueId(id_publication, id_issue, issue_date);
|
||||
int id_issue_sections;
|
||||
//bool publication_issue_exist = publicationIssueExist(id_publication, id_issue, issue_date, id_publication_issue);
|
||||
//bool issue_section_exist = false;
|
||||
|
||||
QStringList conflictList;
|
||||
|
||||
if( id_publication_issue > 0 )
|
||||
{
|
||||
//check if there are any conflicted files between src and dst
|
||||
id_issue_sections = issueSectionsId(id_publication_issue, id_section);
|
||||
if ( id_issue_sections > 0)
|
||||
{
|
||||
bool conflict = conflictedFiles(id_issue_sections, id_section, m_dstFileNames, conflictList);
|
||||
if(conflict)
|
||||
{
|
||||
/*
|
||||
if ( !canUserReplaceFiles() )
|
||||
{
|
||||
QMessageBox::critical(this, tr("Not sufficient permissions"), tr("You dont have necessary permission to replace files, pleaese contact your admin"));
|
||||
//ui->importButton->setEnabled(true);
|
||||
//return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//we should show the user a warning message!
|
||||
}
|
||||
*/
|
||||
|
||||
switch( QMessageBox::question(
|
||||
this,
|
||||
tr("conflicted files"),
|
||||
tr("Files with the same name already exist in the destination directory, this operation will overwrite them\nAre you sure?"),
|
||||
QMessageBox::Yes |
|
||||
QMessageBox::No,
|
||||
QMessageBox::No) )
|
||||
{
|
||||
case QMessageBox::Yes:
|
||||
break;
|
||||
case QMessageBox::No:
|
||||
setEnabled(true);
|
||||
return;
|
||||
default:
|
||||
setEnabled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
//delete files
|
||||
if(!m_useFtp)
|
||||
{
|
||||
QString dstPath = destinationPath(id_publication, id_section);
|
||||
deleteFiles(dstPath, conflictList);
|
||||
}
|
||||
//now we remove those values from database
|
||||
deleteFilesFromDatabase(id_issue_sections, conflictList );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString destPath = destinationPath(id_publication, id_section);
|
||||
|
||||
m_totalFilesCompleted = 0;
|
||||
|
||||
if ( m_useFtp )
|
||||
{
|
||||
//it may contains windows drive letter, so we remove it, also remove the beginning and the end /
|
||||
destPath = removeWindowsDriveLetter(destPath);
|
||||
|
||||
//ftp format will be: ftp://user:pass.ALLCONTENT.com/testdir/1-level/afile1
|
||||
destPath = QString("ftp://%1:%2@%3/").arg(m_username).arg(m_password).arg(m_address) + destPath;
|
||||
|
||||
ui->fileProgressBar->setRange(0, 100);
|
||||
ui->fileProgressBar->setVisible(true);
|
||||
ui->fileUploadLabel->setVisible(true);
|
||||
|
||||
}
|
||||
|
||||
ui->totalProgressBar->setRange(0, m_srcFileNames.count() );
|
||||
ui->totalProgressBar->setVisible(true);
|
||||
ui->totalUploadLabel->setVisible(true);
|
||||
|
||||
m_thread->set(m_imagesPath, m_srcFileNames, destPath, m_dstFileNames, skipOcr);
|
||||
m_thread->start();
|
||||
m_timer->start(1000);
|
||||
}
|
||||
|
||||
void ImporterDialog::addNewSection()
|
||||
{
|
||||
//get the name of the section from the lineEdit
|
||||
QString newSectionName = ui->newSectionNameLineEdit->text().trimmed();
|
||||
if (newSectionName.isEmpty()) //if its empty, do nothing
|
||||
return;
|
||||
|
||||
//check if the new name already exists in the drop-down list
|
||||
int i = ui->sectionComboBox->findText(newSectionName,Qt::MatchFixedString);
|
||||
if (i != -1)
|
||||
{
|
||||
QMessageBox::information(this, tr("Duplicate!"), tr("Section '%1' already exists in the list").arg(newSectionName));
|
||||
ui->newSectionNameLineEdit->setFocus();
|
||||
return;
|
||||
}
|
||||
|
||||
if( !Section::addNewSection(m_masterDatabase, newSectionName, m_user.id()) )
|
||||
return;
|
||||
|
||||
//add it to the end of the sectionComboBox
|
||||
ui->sectionComboBox->addItem(newSectionName);
|
||||
|
||||
QMessageBox::information(this, tr("Added!"), tr("Section '%1' was added successfully").arg(newSectionName));
|
||||
}
|
||||
|
||||
void ImporterDialog::browseScannedImages()
|
||||
{
|
||||
QString directory = QFileDialog::getExistingDirectory(this, tr("Select directory"), QDir::currentPath()); //get directory location from user
|
||||
|
||||
if( !directory.isEmpty() )
|
||||
{
|
||||
QDir::setCurrent(directory);
|
||||
readScannedImagesNames(directory); //read images from the directory, and populate the imagelist
|
||||
ui->scannedImagePathLineEdit->setText(directory); //set the path in the path lineEdit
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ImporterDialog::scannedImageLineEditTextChanged()
|
||||
{
|
||||
QString directory = ui->scannedImagePathLineEdit->text();
|
||||
QDir::setCurrent(directory);
|
||||
readScannedImagesNames(directory); //read images from the directory, and populate the imagelist
|
||||
}
|
||||
|
||||
void ImporterDialog::readScannedImagesNames(QString path)
|
||||
{
|
||||
QDir directory(path); //open the directory in path location
|
||||
QString fileName = "*.jpg"; //only filter jpg images
|
||||
QStringList filter = QStringList(fileName);
|
||||
|
||||
m_imagesPath = path;
|
||||
m_srcFileNames.clear();
|
||||
m_srcFileNames = directory.entryList(filter, QDir::Files | QDir::NoSymLinks, QDir::Name); //read files from directory, and save them in imagelist
|
||||
m_srcFileNames.sort();
|
||||
|
||||
ui->filesTreeWidget->clear();
|
||||
|
||||
QTreeWidgetItem *dirItem = new QTreeWidgetItem(QStringList(path));
|
||||
ui->filesTreeWidget->insertTopLevelItem(0, dirItem); //create a top level item in the tree widget
|
||||
|
||||
if(m_srcFileNames.count() > 0) //if there are images, insert them into the treelist
|
||||
{
|
||||
for(int i=0; i < m_srcFileNames.size(); i++)
|
||||
{
|
||||
QTreeWidgetItem *filenameItem = new QTreeWidgetItem(QStringList(m_srcFileNames[i]) );
|
||||
ui->filesTreeWidget->itemAt(0,0)->addChild(filenameItem);
|
||||
}
|
||||
|
||||
ui->importButton->setEnabled(true); //enable the import button
|
||||
}
|
||||
else //if the directory does not contain any .jpg files, then tell the user that, and disable import button!
|
||||
{
|
||||
QTreeWidgetItem *filenameItem = new QTreeWidgetItem(QStringList(tr("No jpg files in this directory!") ) );
|
||||
ui->filesTreeWidget->itemAt(0,0)->addChild(filenameItem);
|
||||
ui->importButton->setEnabled(false);
|
||||
}
|
||||
|
||||
ui->filesTreeWidget->expandAll();
|
||||
}
|
||||
|
||||
bool ImporterDialog::readSettings()
|
||||
{
|
||||
QString ftp_ini = QApplication::applicationDirPath()+ "/config.ini";
|
||||
QSettings settings(QString(ftp_ini), QSettings::IniFormat);
|
||||
|
||||
m_useFtp = settings.value("ftp access/useftp").toInt(); //if its set to 0, its false, otherwise it true
|
||||
if(m_useFtp)
|
||||
{
|
||||
m_address = settings.value("ftp access/server").toString();
|
||||
m_username = settings.value("ftp access/username").toString();
|
||||
m_password = settings.value("ftp access/password").toString();
|
||||
m_port = settings.value("ftp access/port").toInt();
|
||||
|
||||
if(m_address.isEmpty() || m_username.isEmpty() || m_password.isEmpty() || (m_port == 0))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int ImporterDialog::publicationIssueId(int id_publication, int id_issue, QString issue_date)
|
||||
{
|
||||
qDebug() << "publicationIssueId()";
|
||||
QSqlQuery query(m_slaveDatabase);
|
||||
query.prepare("SELECT id_publication_issue FROM publication_issue "
|
||||
"WHERE id_publication = :id_publication AND issue_date = :issue_date");
|
||||
query.bindValue(":id_publication", id_publication);
|
||||
query.bindValue(":issue_date", issue_date);
|
||||
|
||||
qDebug() << "id_publication_issue query: " << query.lastQuery();
|
||||
qDebug() << "id_publication: " << id_publication;
|
||||
qDebug() << "issue_date: " << issue_date;
|
||||
|
||||
if(!query.exec())
|
||||
{
|
||||
qDebug() << "select id_publication_issue query error: " << query.lastError().text();
|
||||
qDebug() << "returning 0";
|
||||
return 0;
|
||||
}
|
||||
|
||||
int id_publication_issue = 0;
|
||||
|
||||
if(!query.isValid())
|
||||
qDebug() << "The query is not valid";
|
||||
|
||||
if(query.next())
|
||||
{
|
||||
id_publication_issue = query.value(0).toInt();
|
||||
qDebug() << "id_publication_issue : " << id_publication_issue;
|
||||
return id_publication_issue;
|
||||
}
|
||||
|
||||
qDebug() << "return " << id_publication_issue;
|
||||
qDebug() << "end of publicationIssueId()";
|
||||
|
||||
return id_publication_issue;
|
||||
}
|
||||
|
||||
int ImporterDialog::issueSectionsId(int id_publication_issue, int id_section)
|
||||
{
|
||||
qDebug() << "issueSectionsId()";
|
||||
|
||||
QSqlQuery query(m_slaveDatabase);
|
||||
query.prepare("SELECT id_issue_sections FROM issue_sections WHERE "
|
||||
"id_publication_issue = :id_publication_issue AND id_section = :id_section");
|
||||
query.bindValue(":id_publication_issue", id_publication_issue);
|
||||
query.bindValue(":id_section", id_section);
|
||||
|
||||
QString str = QString("SELECT id_issue_sections FROM issue_sections WHERE "
|
||||
"id_publication_issue = %1 AND id_section = %2")
|
||||
.arg(id_publication_issue)
|
||||
.arg(id_section);
|
||||
|
||||
qDebug() << "id_issue_sections query: " << str;
|
||||
|
||||
if ( !query.exec() )
|
||||
{
|
||||
qDebug() << "select id_issue_sections query error: " << query.lastError().text();
|
||||
qDebug() << "returning 0";
|
||||
return 0;
|
||||
}
|
||||
|
||||
int id_issue_sections = 0;
|
||||
if( query.next() )
|
||||
id_issue_sections = query.value(0).toInt();
|
||||
|
||||
qDebug() << "return " << id_publication_issue;
|
||||
qDebug() << "end of issueSectionsId()";
|
||||
|
||||
return id_issue_sections;
|
||||
}
|
||||
|
||||
bool ImporterDialog::conflictedFiles(int id_issue_sections, int id_section, QStringList outputfiles, QStringList &conflictList)
|
||||
{
|
||||
QSqlQuery query(m_slaveDatabase);
|
||||
|
||||
query.exec("LOCK TABLE section_pages READ");
|
||||
|
||||
query.prepare("SELECT page_name FROM section_pages WHERE id_issue_sections = :id_issue_sections");
|
||||
query.bindValue(":id_issue_sections" , id_issue_sections);
|
||||
|
||||
if( !query.exec() )
|
||||
{
|
||||
query.exec("UNLOCK TABLES");
|
||||
return false;
|
||||
}
|
||||
|
||||
conflictList.clear();
|
||||
|
||||
QStringList dbfiles;
|
||||
while( query.next() )
|
||||
{
|
||||
dbfiles.append(query.value(0).toString());
|
||||
}
|
||||
|
||||
query.exec("UNLOCK TABLES");
|
||||
|
||||
//check if there are any conflicting files in the names, if so, check the permission
|
||||
bool conflict = false;
|
||||
foreach (QString str, dbfiles)
|
||||
{
|
||||
if(outputfiles.contains(str, Qt::CaseInsensitive))
|
||||
{
|
||||
conflictList.append(str);
|
||||
conflict = true;;
|
||||
}
|
||||
}
|
||||
|
||||
return conflict;
|
||||
}
|
||||
|
||||
bool ImporterDialog::canUserReplaceFiles()
|
||||
{
|
||||
return (m_user.userRole() == ADMIN_ROLE);
|
||||
}
|
||||
|
||||
QString ImporterDialog::destinationPath(int id_publication, int id_section)
|
||||
{
|
||||
QString day = QString::number( ui->publicationDate->date().day () );
|
||||
QString month = QString::number( ui->publicationDate->date().month() );
|
||||
QString year = QString::number( ui->publicationDate->date().year () );
|
||||
|
||||
QString dst = "";
|
||||
|
||||
//if we are under Windows, then we have a Windows drive letter, like C:/ or D: or I:\, so we add this to the issues path
|
||||
#ifdef Q_WS_WIN
|
||||
dst += m_issuesWindowDriveLetter;
|
||||
if ( dst.endsWith("/") || dst.endsWith("\\") )
|
||||
dst= dst.left(dst.length()-1);
|
||||
#endif
|
||||
|
||||
// fileserver/path/Issues/YYYY/MM/DD/ID_PUBLICATION/ID_SECTION/
|
||||
dst += m_issuesPath + QString("%1/%2/%3/%4/%5/").
|
||||
arg(year , 4, QChar('0')).
|
||||
arg(month, 2, QChar('0')).
|
||||
arg(day , 2, QChar('0')).
|
||||
arg(id_publication).
|
||||
arg(id_section);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
QString ImporterDialog::removeWindowsDriveLetter(QString destination)
|
||||
{
|
||||
QString dst = destination.mid(destination.indexOf(":")+1, destination.length());
|
||||
dst = dst.left( dst.length() -1 ); //to remove the last /
|
||||
|
||||
if ( !dst.endsWith("/") )
|
||||
dst += "/";
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
QString ImporterDialog::get96DPIImagePath(QString filename)
|
||||
{
|
||||
QImage originalImage(filename);
|
||||
QSize size(originalImage.width()/3, originalImage.height()/3);
|
||||
QImage image(size, QImage::Format_RGB888);
|
||||
|
||||
image = originalImage.scaledToWidth(originalImage.width()/3, Qt::SmoothTransformation);
|
||||
//return image;
|
||||
|
||||
QString filename96 = filename.replace(".jpg", "");
|
||||
filename96 += "_96dpi.jpg";
|
||||
|
||||
if( image.save(filename96, "jpg", JPG_SAVE_QUALITY) )
|
||||
return filename96;
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error!"), tr("Error creating 96 dpi image %1").arg(filename96));
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
void ImporterDialog::importerThreadCompleted()
|
||||
{
|
||||
m_timer->stop(); //stop the time,
|
||||
update(); //and call the update one last time to reflect the last changes
|
||||
|
||||
if(m_totalFilesCompleted < m_srcFileNames.count())
|
||||
{
|
||||
QString str;
|
||||
if(m_useFtp)
|
||||
str = tr("Error happened while importing images to FTP server, only %1/%2 files were imported successfully, Do you want to CANCEL the import process?").arg(m_totalFilesCompleted).arg(m_srcFileNames.count());
|
||||
else
|
||||
str = tr("Error happened while importing images to File server, only %1/%2 files were imported successfully, Do you want to CANCEL the import process?").arg(m_totalFilesCompleted).arg(m_srcFileNames.count());
|
||||
|
||||
switch( QMessageBox::question(
|
||||
this,
|
||||
tr("Error in importing files"),
|
||||
str,
|
||||
QMessageBox::Yes |
|
||||
QMessageBox::No,
|
||||
QMessageBox::Yes) )
|
||||
{
|
||||
case QMessageBox::Yes:
|
||||
{
|
||||
setEnabled(true);
|
||||
ui->importButton->setEnabled(true);
|
||||
return;
|
||||
}
|
||||
case QMessageBox::No:
|
||||
break;
|
||||
default:
|
||||
{
|
||||
setEnabled(true);
|
||||
ui->importButton->setEnabled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateDatabase();
|
||||
}
|
||||
|
||||
void ImporterDialog::updateDatabase()
|
||||
{
|
||||
qDebug() << "updateDatabase()";
|
||||
|
||||
QString publication_name = ui->publicationNameLineEdit->text().trimmed();
|
||||
int id_publication = m_publicationHash[publication_name];
|
||||
bool skipOcr = m_publicationSkipOcrHash[publication_name];
|
||||
int id_section = Section::sectionId(m_slaveDatabase, ui->sectionComboBox->currentText());
|
||||
QString issue_date = ui->publicationDate->text();
|
||||
int id_issue = ui->issueNumberLineEdit->text().toInt();
|
||||
|
||||
|
||||
QSqlQuery queryMaster(m_masterDatabase);
|
||||
|
||||
int id_publication_issue = publicationIssueId(id_publication, id_issue, issue_date);
|
||||
qDebug() << "publication issue id: " << id_publication_issue;
|
||||
|
||||
if( id_publication_issue == 0 )
|
||||
{
|
||||
//if not an update process, add the entry to publication_issue table, set the publication_status to 1
|
||||
queryMaster.prepare("INSERT INTO publication_issue (id_publication, id_issue, publication_status, issue_date, pages_number, created_by) "
|
||||
"VALUES( :id_publication, :id_issue, '1', :issue_date, :pagesNumber, :created_by)" );
|
||||
|
||||
queryMaster.bindValue(":id_publication" , id_publication);
|
||||
queryMaster.bindValue(":id_issue" , id_issue);
|
||||
queryMaster.bindValue(":issue_date" , issue_date);
|
||||
queryMaster.bindValue(":pagesNumber" , m_srcFileNames.count() );
|
||||
queryMaster.bindValue(":created_by" , m_user.id());
|
||||
|
||||
qDebug() << "insert publication_issue entry by user: " << m_user.username() << ", id = : " << m_user.id();
|
||||
|
||||
QString str = QString("INSERT INTO publication_issue (id_publication, id_issue, publication_status, issue_date, pages_number, created_by) "
|
||||
"VALUES( %1, %2, '1', %3, %4, %5)")
|
||||
.arg(id_publication)
|
||||
.arg(id_issue)
|
||||
.arg(issue_date)
|
||||
.arg(m_srcFileNames.count())
|
||||
.arg(m_user.id());
|
||||
qDebug() << "publication_issue insert statement: " << str;
|
||||
|
||||
if( !queryMaster.exec())
|
||||
{
|
||||
QMessageBox::critical(this, tr("SQL Error"), queryMaster.lastError().databaseText());
|
||||
ui->importButton->setEnabled(true);
|
||||
setEnabled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
id_publication_issue = queryMaster.lastInsertId().toInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
queryMaster.prepare("Update publication_issue set created_by = :created_by where id_publication_issue = :id");
|
||||
queryMaster.bindValue(":created_by", m_user.id());
|
||||
queryMaster.bindValue(":id", id_publication_issue);
|
||||
if( !queryMaster.exec() )
|
||||
{
|
||||
qDebug() << "update publication issue: " << queryMaster.lastQuery().toAscii();
|
||||
qDebug() << "user id: " << m_user.id();
|
||||
}
|
||||
|
||||
qDebug() << "update publication_issue entry by user: " << m_user.username() << ", id = : " << m_user.id();
|
||||
QString str = QString("Update publication_issue set created_by = %1 where id_publication_issue = %2 ")
|
||||
.arg(m_user.id())
|
||||
.arg(id_publication_issue);
|
||||
qDebug() << "publication_issue update statement: " << str;
|
||||
}
|
||||
|
||||
int id_issue_sections = issueSectionsId(id_publication_issue, id_section);
|
||||
qDebug() << "issue sections id: " << id_issue_sections;
|
||||
if( id_issue_sections == 0 )
|
||||
{
|
||||
queryMaster.prepare("INSERT INTO issue_sections (id_publication_issue, id_section, pages_reset, page_start, page_end, pages_number) "
|
||||
"VALUES (:id_publication_issue, :id_section, :pagesRest, :pageStart, :pageEnd, :pages_number)");
|
||||
|
||||
queryMaster.bindValue(":id_publication_issue" , id_publication_issue);
|
||||
queryMaster.bindValue(":id_section" , id_section);
|
||||
queryMaster.bindValue(":pagesRest" , 1);
|
||||
queryMaster.bindValue(":pageStart" , m_dstFileNames[0]);
|
||||
queryMaster.bindValue(":pageEnd" , m_dstFileNames[m_dstFileNames.count()-1]);
|
||||
queryMaster.bindValue(":pages_number" , m_dstFileNames.count() );
|
||||
|
||||
|
||||
QString str = QString("INSERT INTO issue_sections (id_publication_issue, id_section, pages_reset, page_start, page_end, pages_number) "
|
||||
"VALUES (%1, %2, %3, %4, %5, %6)")
|
||||
.arg(id_publication_issue)
|
||||
.arg(id_section)
|
||||
.arg(1)
|
||||
.arg(m_dstFileNames[0])
|
||||
.arg(m_dstFileNames[m_dstFileNames.count()-1])
|
||||
.arg(m_dstFileNames.count());
|
||||
qDebug() << "issue_sections insert statement: " << str;
|
||||
|
||||
if( !queryMaster.exec())
|
||||
{
|
||||
QMessageBox::critical(this, tr("SQL Error"), queryMaster.lastError().databaseText());
|
||||
qDebug() << "issue_sections insert query error: " << queryMaster.lastQuery().toAscii();
|
||||
ui->importButton->setEnabled(true);
|
||||
setEnabled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
id_issue_sections = queryMaster.lastInsertId().toInt();
|
||||
}
|
||||
|
||||
//first lock the database to make sure no one is using it
|
||||
queryMaster.exec("LOCK TABLE section_pages WRITE");
|
||||
|
||||
int status = 1;
|
||||
if (skipOcr)
|
||||
status = 0;
|
||||
|
||||
//insert pages to database, and set its request for the ocr to start processing it now
|
||||
queryMaster.prepare("INSERT INTO section_pages (id_issue_sections, page_name, status) "
|
||||
"VALUES (:id_issue_sections, :page_name, :status)");
|
||||
|
||||
queryMaster.bindValue(":id_issue_sections", id_issue_sections);
|
||||
queryMaster.bindValue(":status", status);
|
||||
|
||||
foreach (QString page_name, m_dstFileNames)
|
||||
{
|
||||
queryMaster.bindValue(":page_name", page_name);
|
||||
if( !queryMaster.exec() )
|
||||
{
|
||||
qDebug() << "insert section_pages Error: " << queryMaster.lastError();
|
||||
}
|
||||
QString str = QString("INSERT INTO section_pages (id_issue_sections, page_name, status) "
|
||||
"VALUES (%1, %2, %3)")
|
||||
.arg(id_issue_sections)
|
||||
.arg(page_name)
|
||||
.arg(status);
|
||||
qDebug() << "section_pages insert statement: " << str;
|
||||
}
|
||||
|
||||
//unlock pages
|
||||
queryMaster.exec("UNLOCK TABLES");
|
||||
|
||||
//update the pages_number in publication_issue table
|
||||
queryMaster.prepare("UPDATE publication_issue SET pages_number = "
|
||||
"(SELECT count(*) FROM section_pages s, issue_sections iss where s.id_issue_sections = iss.id_issue_sections AND "
|
||||
" iss.id_publication_issue = :id1) WHERE id_publication_issue = :id2;");
|
||||
queryMaster.bindValue(":id1", id_publication_issue);
|
||||
queryMaster.bindValue(":id2", id_publication_issue);
|
||||
|
||||
if(!queryMaster.exec())
|
||||
{
|
||||
qDebug() << "Error: " << queryMaster.lastError();
|
||||
}
|
||||
|
||||
//*/
|
||||
QMessageBox::information(this, tr("Finished"), tr("Importing %1/%2 images was done successfully!").arg(m_totalFilesCompleted).arg(m_srcFileNames.count()));
|
||||
|
||||
ui->scannedImagePathLineEdit->clear();
|
||||
ui->filesTreeWidget->clear();
|
||||
|
||||
ui->totalProgressBar->setVisible(false);
|
||||
ui->totalUploadLabel->setVisible(false);
|
||||
ui->totalUploadLabel_2->setVisible(false);
|
||||
|
||||
ui->fileUploadLabel->setVisible(false);
|
||||
ui->fileProgressBar->setVisible(false);
|
||||
ui->fileUploadLabel_1->setVisible(false);
|
||||
|
||||
setEnabled(true);
|
||||
|
||||
qDebug() << "end of updateDatabase()";
|
||||
|
||||
}
|
||||
|
||||
void ImporterDialog::update()
|
||||
{
|
||||
ui->fileUploadLabel->setText(QString("%1/%2 KB").arg(g_currentUpload/1024).arg(m_currentFileSize/1024) ); //update the labels, and the
|
||||
ui->fileProgressBar->setValue(g_currentUpload*100/m_currentFileSize); //progress bars to represent
|
||||
ui->totalProgressBar->setValue(m_totalFilesCompleted); //values from the ftp thread
|
||||
ui->totalUploadLabel->setText(QString("%1/%2 File(s)").arg( m_totalFilesCompleted ).arg( m_srcFileNames.count() ) ); //operation
|
||||
//qDebug("ImporterDialog::update() Total files completed %d", m_totalFilesCompleted+1);
|
||||
}
|
||||
|
||||
void ImporterDialog::deleteFiles(QString path, QStringList filenames)
|
||||
{
|
||||
for(int i=0; i< filenames.count(); i++)
|
||||
{
|
||||
if(!QFile::remove(path + filenames[i]))
|
||||
qDebug() << "Could not remove image: " << path + filenames[i];
|
||||
|
||||
if(!QFile::remove(path + HIGH_RES_IMAGE_DIR + filenames[i]))
|
||||
qDebug() << "Could not remove image: " << path + HIGH_RES_IMAGE_DIR + filenames[i];
|
||||
}
|
||||
}
|
||||
|
||||
void ImporterDialog::setEnabled(bool enable)
|
||||
{
|
||||
ui->publicationNameLineEdit-> setEnabled(enable);
|
||||
ui->publicationDate-> setEnabled(enable);
|
||||
ui->issueNumberLineEdit-> setEnabled(enable);
|
||||
ui->sectionComboBox-> setEnabled(enable);
|
||||
ui->newSectionCheckBox-> setEnabled(enable);
|
||||
ui->scannedImagePathLineEdit-> setEnabled(enable);
|
||||
ui->browseButton-> setEnabled(enable);
|
||||
ui->startNumberlineEdit-> setEnabled(enable);
|
||||
ui->keepPageNumberCheckBox-> setEnabled(enable);
|
||||
}
|
||||
|
||||
|
||||
void ImporterDialog::deleteFilesFromDatabase(int idSection, QStringList filenames )
|
||||
{
|
||||
//qDebug() << "deleteFilesFromDatabase()";
|
||||
QSqlQuery query(m_slaveDatabase);
|
||||
|
||||
//query.exec("LOCK TABLES section_pages page_text page_word_coordinates page_tag_coordinates WRITE");
|
||||
query.exec("LOCK TABLES section_pages page_text page_tag_coordinates WRITE");
|
||||
|
||||
foreach (QString filename, filenames)
|
||||
{
|
||||
/*query.prepare("DELETE FROM section_pages, page_text, page_word_coordinates, page_tag_coordinates "
|
||||
"USING section_pages, page_text, page_word_coordinates, page_tag_coordinates "
|
||||
"WHERE "
|
||||
" section_pages.id_issue_sections = :id_issue_sections "
|
||||
" AND section_pages.page_name like :page_name "
|
||||
" AND section_pages.section_pages = page_text.id_section_pages "
|
||||
" AND section_pages.section_pages = page_word_coordinates.id_section_pages "
|
||||
" AND section_pages.section_pages = page_tag_coordinates.id_section_pages;");*/
|
||||
|
||||
/*query.prepare("DELETE FROM section_pages, page_text, page_tag_coordinates "
|
||||
"USING section_pages, page_text, page_tag_coordinates "
|
||||
"WHERE "
|
||||
" section_pages.id_issue_sections = :id_issue_sections "
|
||||
" AND section_pages.page_name like :page_name "
|
||||
" AND section_pages.section_pages = page_text.id_section_pages "
|
||||
" AND section_pages.section_pages = page_tag_coordinates.id_section_pages;");
|
||||
|
||||
query.bindValue(":id_issue_sections" , idSection);
|
||||
query.bindValue(":page_name", filename);
|
||||
bool ret = query.exec();*/
|
||||
|
||||
//now delete the pages if they dont have any entries in the ocr tables.
|
||||
query.prepare("DELETE FROM section_pages "
|
||||
"WHERE "
|
||||
" section_pages.id_issue_sections = :id_issue_sections "
|
||||
" AND section_pages.page_name like :page_name");
|
||||
|
||||
query.bindValue(":id_issue_sections" , idSection);
|
||||
query.bindValue(":page_name", filename);
|
||||
query.exec();
|
||||
}
|
||||
|
||||
query.exec("UNLOCK TABLES");
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
//! \file importerdialog.h
|
||||
|
||||
#ifndef IMPORTERDIALOG_H
|
||||
#define IMPORTERDIALOG_H
|
||||
|
||||
#include <QtGui/QDialog>
|
||||
#include <QtSql>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
class ImporterThread;
|
||||
|
||||
#include "section.h"
|
||||
#include "user.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ImporterDialog;
|
||||
}
|
||||
|
||||
//! \class ImporterDialog
|
||||
//! \brief the class for importing images to fileserver and database it may also updates the article sections in database
|
||||
//! \author elzubeir
|
||||
class ImporterDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class ImporterThread;
|
||||
|
||||
public:
|
||||
//! \fn ImporterDialog(QWidget *parent, QSqlDatabase masterDb, QSqlDatabase slaveDb, User &user)
|
||||
//! default contructor
|
||||
//! Few operations are perfromed:
|
||||
//! 1- publications names, and ids are retreived from database, and inserted to the publication combobox
|
||||
//! 2- articles are retrieved from the database, and populated
|
||||
//! 3- the fileservers issues path variable is retrieved from the database
|
||||
//! 4- the publication date, and issue number are populated with the current date value
|
||||
|
||||
//! \param[in] parent QWidget pointer to parent class
|
||||
//! \param[in] masterDb the opened master database instance from the calling widget, its used for INSERT and UPDATE operations
|
||||
//! \param[in] slaveDb the opened slave database instance from the calling widget, its used for all other queries
|
||||
//! \param[in] user the logged in user
|
||||
//! \author elzubeir
|
||||
ImporterDialog(QWidget *parent, QSqlDatabase &masterDb, QSqlDatabase &slaveDb, User &user);
|
||||
|
||||
//! \fn ~ImporterDialog
|
||||
//! class destructor
|
||||
//! \author elzubeir
|
||||
~ImporterDialog();
|
||||
|
||||
protected:
|
||||
//! \fn keyPressEvent(QKeyEvent *key)
|
||||
//! override function from QDialog base class to trap the escape key pressed to prevent it from closing the dialog
|
||||
//! \param[in] key QKeyEvent pointer that represents the pressed key
|
||||
//! \author elzubeir
|
||||
void keyPressEvent(QKeyEvent *key);
|
||||
|
||||
private slots:
|
||||
|
||||
//! \fn import()
|
||||
//! This function performs the acutal importing of images, and copies them to fileserver, and also
|
||||
//! performs the necessary insertion to the database
|
||||
//! \author elzubeir
|
||||
void import();
|
||||
|
||||
//! \fn addNewSection()
|
||||
//! This functions adds a new section into the article_section table in the database, the values include the createdby
|
||||
//! which is the userId passed by the calling parent, also this will add the new section to the sections drop-down list in the UI
|
||||
//! \author elzubeir
|
||||
void addNewSection();
|
||||
|
||||
//! \fn browseScannedImages()
|
||||
//! This function browses the current user directories to selet the location of the image files to be imported
|
||||
//! \see readScannedImagesNames(QString path)
|
||||
//! \author elzubeir
|
||||
void browseScannedImages();
|
||||
|
||||
//! \fn scannedImageLineEditTextChanged()
|
||||
//! This slot handles the keyPressed signal from the scanned image line edit
|
||||
//! \see readScannedImagesNames(QString path)
|
||||
//! \see browseScannedImages()
|
||||
//! \author elzubeir
|
||||
void scannedImageLineEditTextChanged();
|
||||
|
||||
//! \fn update()
|
||||
//! update the importer dialog upload labels
|
||||
//! \author elzubeir
|
||||
void update();
|
||||
|
||||
//! \fn updateDatabase();
|
||||
//! update the database after the importing operation is done
|
||||
//! \author elzubeir
|
||||
void updateDatabase();
|
||||
|
||||
//! \fn importerThreadCompleted()
|
||||
//! called after the thread has completed successfully
|
||||
//! \author elzubeir
|
||||
void importerThreadCompleted();
|
||||
|
||||
private: //member functions
|
||||
//! \fn readScannedImagesNames(QString &path)
|
||||
//! This functions reads the image (*.jpg) files from the directory pointed to by path variable, and
|
||||
//! populate the m_srcFileNames variable with them, it also populates the QTreeWidget object with items representing the images
|
||||
//! found on the directory
|
||||
//! \see browseScannedImages()
|
||||
//! \see scannedImageLineEditTextChanged()
|
||||
//! \param[in] path QString that holds the value of the current selected directory from the function \fn browseScannedImages()
|
||||
//! \author elzubeir
|
||||
void readScannedImagesNames(QString path);
|
||||
|
||||
//! \fn readSettings()
|
||||
//! This function reads the settings for the ftp server settings from a config.ini file
|
||||
//! and populate the member variables with the values read from the file
|
||||
//! \return bool
|
||||
//! - true if all the values are populated
|
||||
//! - false otherwise
|
||||
//! \author elzubeir
|
||||
bool readSettings();
|
||||
|
||||
//! \fn destinationPath()
|
||||
//! This function returns a destination path for the imported images
|
||||
//! \return QString
|
||||
//! \param[in] id_publication publication id
|
||||
//! \param[in] id_section section id
|
||||
//! \author elzubeir
|
||||
QString destinationPath(int id_publication, int id_section);
|
||||
|
||||
//! \fn removeWindowsDriveLetter()
|
||||
//! This function removes the windows drive letter from destination path for the imported images
|
||||
//! \return QString
|
||||
//! \param[in] destination QString destination path
|
||||
//! \author elzubeir
|
||||
QString removeWindowsDriveLetter(QString destination);
|
||||
|
||||
//! \fn publicationIssueId()
|
||||
//! returns specific issue id within a publication
|
||||
//! \return int publication issue id
|
||||
//! \param[in] id_publication int publication id
|
||||
//! \param[in] id_issue int issue id
|
||||
//! \param[in] issue_date QString issue date
|
||||
//! \author elzubeir
|
||||
int publicationIssueId(int id_publication, int id_issue, QString issue_date);
|
||||
|
||||
//! \fn issueSectionsId()
|
||||
//! returns a specific section id within an issue
|
||||
//! \return int id_issue_sections int publication issue
|
||||
//! \param[in] id_publication_issue int publication id
|
||||
//! \param[in] id_section int issue id
|
||||
//! \author elzubeir
|
||||
int issueSectionsId(int id_publication_issue, int id_section);
|
||||
|
||||
//! \fn conflictedFiles()
|
||||
//! Checks the filenames stored in the database for a specific section again the imported filenames
|
||||
//! \return bool
|
||||
//! - true if conflict exists
|
||||
//! - false if no conflicts exist
|
||||
//! \param[in] id_issue_sections int issue sections
|
||||
//! \param[in] id_section int section id
|
||||
//! \param[in] outputfiles QStringList name of imported files
|
||||
//! \param[out] conflictList QStringList list of conflicted files
|
||||
//! \author elzubeir
|
||||
bool conflictedFiles(int id_issue_sections, int id_section, QStringList outputfiles, QStringList &conflictList);
|
||||
|
||||
//! \fn canUserReplaceFiles()
|
||||
//! Checks if the current user has the permission to replace files while importing
|
||||
//! \return bool
|
||||
//! - true if has permission
|
||||
//! - false if does not have permission
|
||||
//! \author elzubeir
|
||||
bool canUserReplaceFiles();
|
||||
|
||||
//! \fn get96DPIImage()
|
||||
//! returns a 96 dpi image from the 300 dpi image
|
||||
//! \return QImage image scaled to fit 96 dip image sizes
|
||||
//! \param[in] filenam QString name of image
|
||||
//! \author elzubeir
|
||||
QString get96DPIImagePath(QString filename);
|
||||
|
||||
//! \fn deleteFiles()
|
||||
//! delete image files that are in conflict with the current files being imported
|
||||
//! \param[in] path QString path of the images to be deleted
|
||||
//! \param[in] filenams list of image names
|
||||
//! \see conflictedFiles()
|
||||
//! \author elzubeir
|
||||
void deleteFiles(QString path, QStringList filenames);
|
||||
|
||||
void deleteFilesFromDatabase(int idSection, QStringList filenames );
|
||||
|
||||
//! \fn setEnabled()
|
||||
//! enable of disable the importers ui components
|
||||
//! \param[in] enable boolean
|
||||
//! - true enables the components
|
||||
//! - false disables them
|
||||
//! \author elzubeir
|
||||
void setEnabled(bool enable);
|
||||
|
||||
private: //member data
|
||||
//! pointer to the Qt desginer UI class object
|
||||
Ui::ImporterDialog *ui;
|
||||
|
||||
//! master database is used ONLY for UPDATE, and INSERT operations
|
||||
QSqlDatabase m_masterDatabase;
|
||||
//! slave database is used for ALL other quieries
|
||||
QSqlDatabase m_slaveDatabase;
|
||||
|
||||
//! hash object to hold name/id values for publications
|
||||
QHash<QString, int> m_publicationHash;
|
||||
|
||||
//! hash object to hold name/skipocr values for publications
|
||||
QHash<QString, bool> m_publicationSkipOcrHash;
|
||||
|
||||
//! to hold the path of the fileserver's issues
|
||||
QString m_issuesPath;
|
||||
|
||||
//! to hold the drive letter for the windows machine
|
||||
QString m_issuesWindowDriveLetter;
|
||||
|
||||
//! to hold the path of the scanned images location
|
||||
QString m_imagesPath;
|
||||
|
||||
//! list of images to be copied
|
||||
QStringList m_srcFileNames;
|
||||
|
||||
QStringList m_dstFileNames;
|
||||
//! the user object of the logged in user
|
||||
User m_user;
|
||||
|
||||
//! use ftp for uploading or not
|
||||
bool m_useFtp;
|
||||
//! ftp server address
|
||||
QString m_address;
|
||||
//! ftp username
|
||||
QString m_username;
|
||||
//! ftp password
|
||||
QString m_password;
|
||||
//! ftp port
|
||||
int m_port;
|
||||
|
||||
//! importer threads object
|
||||
ImporterThread *m_thread;
|
||||
|
||||
//! timer used to update the status of the importing process
|
||||
QTimer * m_timer;
|
||||
|
||||
//! current file size thats being uploaded
|
||||
int m_currentFileSize;
|
||||
|
||||
//! total number of files imported
|
||||
int m_totalFilesCompleted;
|
||||
|
||||
//! has the importing operation completed successfully
|
||||
bool m_completedSuccessfully;
|
||||
};
|
||||
|
||||
#endif // IMPORTERDIALOG_H
|
||||
@@ -0,0 +1,475 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ImporterDialog</class>
|
||||
<widget class="QDialog" name="ImporterDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::NonModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>463</width>
|
||||
<height>544</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::NoContextMenu</enum>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Importer</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="pubNameLabel">
|
||||
<property name="text">
|
||||
<string>Publication Name </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="publicationNameLineEdit"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="pubDateLabel">
|
||||
<property name="text">
|
||||
<string>Publication Date </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDateEdit" name="publicationDate">
|
||||
<property name="locale">
|
||||
<locale language="English" country="UnitedStates"/>
|
||||
</property>
|
||||
<property name="displayFormat">
|
||||
<string>yyyy-MM-dd</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="issueNumberLabel">
|
||||
<property name="text">
|
||||
<string>Issue number</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="issueNumberLineEdit">
|
||||
<property name="inputMask">
|
||||
<string extracomment="Only accept numbers">9999999999; </string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="sectionLabel">
|
||||
<property name="text">
|
||||
<string>Section</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="sectionComboBox">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="newSectionCheckBox">
|
||||
<property name="text">
|
||||
<string>Add new section</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="newSectionNameLineEdit">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="newSectionButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Scanned image path</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="scannedImagePathLineEdit">
|
||||
<property name="readOnly">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="browseButton">
|
||||
<property name="toolTip">
|
||||
<string>Browse scanned image location</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="startNumberlabel">
|
||||
<property name="text">
|
||||
<string>Start page number</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="startNumberlineEdit">
|
||||
<property name="inputMask">
|
||||
<string>9999; </string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>OR</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="keepPageNumberCheckBox">
|
||||
<property name="text">
|
||||
<string>Keep page number</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="filesTreeWidget">
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Image Files</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>218</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="fileUploadLabel_1">
|
||||
<property name="text">
|
||||
<string>Single File </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QProgressBar" name="fileProgressBar">
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="fileUploadLabel">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Uploading</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="totalUploadLabel_2">
|
||||
<property name="text">
|
||||
<string>Total imported</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QProgressBar" name="totalProgressBar">
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="totalUploadLabel">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Uploading</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="importButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Import</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<tabstops>
|
||||
<tabstop>browseButton</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>newSectionCheckBox</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>newSectionNameLineEdit</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>81</x>
|
||||
<y>130</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>242</x>
|
||||
<y>135</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>newSectionCheckBox</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>newSectionButton</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>42</x>
|
||||
<y>130</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>466</x>
|
||||
<y>139</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>newSectionButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>ImporterDialog</receiver>
|
||||
<slot>addNewSection()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>466</x>
|
||||
<y>139</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>345</x>
|
||||
<y>118</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>newSectionButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>newSectionNameLineEdit</receiver>
|
||||
<slot>clear()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>466</x>
|
||||
<y>139</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>252</x>
|
||||
<y>135</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>browseButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>ImporterDialog</receiver>
|
||||
<slot>browseScannedImages()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>466</x>
|
||||
<y>167</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>345</x>
|
||||
<y>142</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>importButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>ImporterDialog</receiver>
|
||||
<slot>import()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>467</x>
|
||||
<y>511</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>44</x>
|
||||
<y>456</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>keepPageNumberCheckBox</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>startNumberlineEdit</receiver>
|
||||
<slot>setDisabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>466</x>
|
||||
<y>194</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>149</x>
|
||||
<y>188</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>scannedImagePathLineEdit</sender>
|
||||
<signal>returnPressed()</signal>
|
||||
<receiver>ImporterDialog</receiver>
|
||||
<slot>scannedImageLineEditTextChanged()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>136</x>
|
||||
<y>158</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>152</x>
|
||||
<y>244</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>addNewSection()</slot>
|
||||
<slot>browseScannedImages()</slot>
|
||||
<slot>import()</slot>
|
||||
<slot>scannedImageLineEditTextChanged()</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
@@ -0,0 +1,10 @@
|
||||
#include <QtGui/QApplication>
|
||||
#include "importerdialog.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
ImporterDialog w;
|
||||
w.show();
|
||||
return a.exec();
|
||||
}
|
||||
Reference in New Issue
Block a user