initial import

This commit is contained in:
Mo Elzubeir
2022-12-13 09:18:00 -06:00
commit d2d561810c
322 changed files with 1147261 additions and 0 deletions
+101
View File
@@ -0,0 +1,101 @@
# -------------------------------------------------
# Project created by QtCreator 2009-08-20T00:31:05
# -------------------------------------------------
QT += sql
TARGET = "Clipping Station"
TEMPLATE = app
SOURCES += main.cpp \
clippingstation.cpp \
authenticationdialog.cpp \
globalfunctions.cpp \
Importer/importerdialog.cpp \
Importer/imageoutputformatdialog.cpp \
section.cpp \
user.cpp \
publication.cpp \
statusbar.cpp \
tag.cpp \
pushbuttondelegate.cpp \
tagswrapper.cpp \
imageitem.cpp \
fullpagescene.cpp \
imagecachingdialog.cpp \
imagecachingthread.cpp \
fullpageview.cpp \
issue.cpp \
drawerscene.cpp \
pageitem.cpp \
droppeditem.cpp \
drawerviewstackedwidget.cpp \
drawerview.cpp \
pagemargin.cpp \
droppeditemzoomdialog.cpp \
systemconfiguration.cpp \
thumbnail.cpp \
article.cpp \
importerthread.cpp \
imagecutout.cpp \
tagcoordinates.cpp \
coordinates.cpp \
prominencedialog.cpp \
prominence.cpp \
pagetextdialog.cpp \
wordcoordinates.cpp \
searchpublicationlistdialog.cpp \
digitalclock.cpp
HEADERS += clippingstation.h \
authenticationdialog.h \
Importer/importerdialog.h \
Importer/imageoutputformatdialog.h \
section.h \
user.h \
publication.h \
globalfunctions.h \
constants.h \
statusbar.h \
tag.h \
pushbuttondelegate.h \
tagswrapper.h \
fullpagescene.h \
fullpageview.h \
imagecachingthread.h \
imagecachingdialog.h \
imageitem.h \
issue.h \
drawerscene.h \
drawerviewstackedwidget.h \
drawerview.h \
pagemargin.h \
pageitem.h \
droppeditem.h \
droppeditemzoomdialog.h \
systemconfiguration.h \
thumbnail.h \
article.h \
importerthread.h \
imagecutout.h \
tagcoordinates.h \
coordinates.h \
prominencedialog.h \
prominence.h \
pagetextdialog.h \
wordcoordinates.h \
searchpublicationlistdialog.h \
digitalclock.h
FORMS += clippingstation.ui \
authenticationdialog.ui \
Importer/importerdialog.ui \
Importer/imageoutputformatdialog.ui \
imagecachingdialog.ui \
droppeditemzoomdialog.ui \
prominencedialog.ui \
pagetextdialog.ui \
searchpublicationlistdialog.ui
ICON = socialhose.icns
RC_FILE = ClippingStation.rc
win32 {
LIBS += -L"C:\curl-7.19.6\bin\"
INCLUDEPATH += "C:\curl-7.19.6\include\"
}
LIBS += -lcurl
RESOURCES += icons.qrc
+1
View File
@@ -0,0 +1 @@
IDI_ICON1 ICON DISCARDABLE "socialhose.ico"
+13
View File
@@ -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>
+814
View File
@@ -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");
}
+255
View File
@@ -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
+475
View File
@@ -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>
+10
View File
@@ -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();
}
+974
View File
@@ -0,0 +1,974 @@
/************************************************************************
* $Id: article.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/article.cpp $
*
************************************************************************/
#include "article.h"
#include "publication.h"
#include "section.h"
#include "imagecutout.h"
Article::Article(): m_status(1)
{
m_imagesNumber = 0;
}
Article::~Article()
{
//qDebug("~Article()");
//for(int i=0; i< m_imageCutoutsList.count(); i++)
//delete m_imageCutoutsList[i];
//m_imageCutoutsList.clear();
}
bool Article::operator == (const Article & pc)
{
return (this->m_id == pc.m_id);
}
void Article::setId(int articleId)
{
m_id = articleId;
}
void Article::setPagename(QString pagename)
{
m_pagename = pagename;
}
void Article::setImageCutouts(QList<ImageCutout *> cutoutsList)
{
m_imageCutoutsList = cutoutsList;
}
void Article::updateImageCutouts(QSqlDatabase &database, QList<ImageCutout *> cutoutsList)
{
//the easit way to do it is to delete all the old clipping coordinates, and insert new ones
QSqlQuery query(database);
query.prepare("DELETE FROM clipping_coordinates WHERE id_article = :id_article");
query.bindValue(":id_article", m_id);
if(!query.exec() )
{
qDebug() << query.lastError().text().toAscii();
qDebug() << "\t...." << query.lastError().databaseText();
}
//now just insert the new ones
setCippingCoordinates(database, m_id, cutoutsList);
m_imageCutoutsList = cutoutsList;
}
void Article::setTags(QList<Tag> &tags)
{
m_tags = tags;
}
void Article::updateTags(QSqlDatabase &database, QList<Tag> &tags, bool isArabic)
{
//if(tags == m_tags)
// return;
//here, we either have tags added, removed, or added and removed
QList<Tag> addedTags; //check for new added tags;
foreach (Tag tag, tags)
{
if( !m_tags.contains(tag) )
addedTags.append(tag);
}
QList<Tag> removedTags;
foreach(Tag tag, m_tags)
{
if(!tags.contains(tag))
{
m_tags.removeOne(tag);
removedTags.append(tag);
}
}
m_tags.append(addedTags);
if(removedTags.count() > 0)
{
//we will remov tags from database
QSqlQuery query(database);
query.prepare("DELETE FROM article_company WHERE id_article = :id_article AND id_company = :id_company");
query.bindValue(":id_article", m_id);
for(int i=0; i< removedTags.count(); i++)
{
query.bindValue(":id_company", removedTags[i].id());
if(!query.exec() )
{
qDebug() << query.lastError().text().toAscii();
qDebug() << "\t...." << query.lastError().databaseText();
}
}
//also remove all the accombining prominence values
query.prepare("DELETE FROM prominence WHERE id_article = :id_article AND id_company = :id_company");
query.bindValue(":id_article", m_id);
for(int i=0; i< removedTags.count(); i++)
{
query.bindValue(":id_company", removedTags[i].id());
if(!query.exec() )
{
qDebug() << query.lastError().text().toAscii();
qDebug() << "\t...." << query.lastError().databaseText();
}
}
}
if(addedTags.count() > 0)
{
//we will add tags from database
QSqlQuery query(database);
query.prepare("INSERT INTO article_company (id_article, id_company, coordinates) VALUES (:id_article, :id_company, :coordinates)");
query.bindValue(":id_article", m_id);
for(int i=0; i< addedTags.count(); i++)
{
query.bindValue("id_company", addedTags[i].id());
query.bindValue(":coordinates", addedTags[i].coordinates());
if(!query.exec() )
{
qDebug() << query.lastError().text().toAscii();
qDebug() << "\t...." << query.lastError().databaseText();
}
}
}
//we need to update the towrite flag as well
//get the max value from tags
int towrite = 0;
for(int i=0; i< m_tags.count(); i++)
{
if(towrite < m_tags[i].towrite())
towrite = m_tags[i].towrite();
}
for(int i=0; i< addedTags.count(); i++)
{
if(towrite < addedTags[i].towrite())
towrite = addedTags[i].towrite();
}
if(towrite > 0)
setArticleTowrite(database, m_id, towrite, isArabic);
m_tags = tags;
}
void Article::setImagesNumber(int imagesNumber)
{
m_imagesNumber = imagesNumber;
}
void Article::updateImagesNumber(QSqlDatabase &database, int images_number)
{
m_imagesNumber = images_number;
QSqlQuery query(database);
query.prepare("UPDATE article SET images_number = :images_number WHERE id_article = :id_article");
query.bindValue(":images_number", images_number);
query.bindValue(":id_article" , m_id);
if(!query.exec() )
{
qDebug() << query.lastError().text().toAscii();
qDebug() << "\t...." << query.lastError().databaseText();
}
}
void Article::updateImagesNumber(QSqlDatabase &database, int articleId, int images_number)
{
QSqlQuery query(database);
query.prepare("UPDATE article SET images_number = :images_number WHERE id_article = :id_article");
query.bindValue(":images_number", images_number);
query.bindValue(":id_article" , articleId);
if(!query.exec() )
{
qDebug() << query.lastError().text().toAscii();
qDebug() << "\t...." << query.lastError().databaseText();
}
}
void Article::setImagesLocalPath(QHash<QString, QString> path)
{
m_imagesLocalPath = path;
}
void Article::setImagesRemotePath(QHash<QString, QString> path)
{
m_imagesRemotePath = path;
}
void Article::setStatus(int status)
{
m_status = status;
}
void Article::updateStatus(QSqlDatabase &database, int status)
{
QSqlQuery query(database);
query.prepare("UPDATE article set clipping_status = :clipping_status WHERE id_article = :id_article");
query.bindValue(":clipping_status" , status);
query.bindValue(":id_article" , m_id);
if ( !query.exec() )
qDebug() << query.lastError().text().toAscii();
}
void Article::updateStatus(QSqlDatabase &database, int articleId, int status)
{
qDebug("updateStatus() for article %d", articleId);
QSqlQuery query(database);
query.prepare("UPDATE article set clipping_status = :clipping_status WHERE id_article = :id_article");
query.bindValue(":clipping_status" , status);
query.bindValue(":id_article" , articleId);
if ( !query.exec() )
qDebug() << query.lastError().text().toAscii();
qDebug("end of updateStatus() for article %d", articleId);
}
void Article::updateHeadline(QSqlDatabase &database, int id, QString headline, bool isArabic)
{
QSqlQuery query(database);
if(isArabic)
query.prepare("UPDATE article set headline_ar = :headline WHERE id_article = :id");
else
query.prepare("UPDATE article set headline_en = :headline WHERE id_article = :id");
query.bindValue(":headline", headline);
query.bindValue(":id_article", id);
if ( !query.exec() )
qDebug() << "updateHeadline() error: " << query.lastError().text().toAscii();
}
void Article::updateText(QSqlDatabase &database, int id, QString text)
{
QSqlQuery query(database);
query.prepare("UPDATE article set text_ocr = :text WHERE id_article = :id_article");
query.bindValue(":text" , text);
query.bindValue(":id_article", id);
if ( !query.exec() )
{
qDebug() << "updateText() error: " << query.lastError().text().toAscii();
qDebug() << "text is " << text;
}
}
void Article::deleteArticle(QSqlDatabase &database)
{
QSqlQuery query(database);
query.prepare("DELETE FROM article WHERE id_article = :id_article");
query.bindValue(":id_article" , m_id);
if ( !query.exec() )
{
qDebug() << query.lastError().text().toAscii();
qDebug() << "\t...." << query.lastError().databaseText();
}
query.prepare("DELETE FROM article_company WHERE id_article = :id_article");
query.bindValue(":id_article" , m_id);
if ( !query.exec() )
{
qDebug() << query.lastError().text().toAscii();
qDebug() << "\t...." << query.lastError().databaseText();
}
query.prepare("DELETE FROM clipping_coordinates WHERE id_article = :id_article");
query.bindValue(":id_article" , m_id);
if ( !query.exec() )
{
qDebug() << query.lastError().text().toAscii();
qDebug() << "\t...." << query.lastError().databaseText();
}
}
void Article::deleteArticle(QSqlDatabase &database, int articleId)
{
QSqlQuery query(database);
query.prepare("DELETE FROM article WHERE id_article = :id_article");
query.bindValue(":id_article" , articleId);
query.exec();
query.prepare("DELETE FROM article_company WHERE id_article = :id_article");
query.bindValue(":id_article" , articleId);
query.exec();
query.prepare("DELETE FROM clipping_coordinates WHERE id_article = :id_article");
query.bindValue(":id_article" , articleId);
query.exec();
}
int Article::id()
{
return m_id;
}
QList<ImageCutout *> Article::imageCutoutsList()
{
return m_imageCutoutsList;
}
QList<Tag> Article::tags()
{
return m_tags;
}
int Article::imagesNumber()
{
return m_imagesNumber;
}
int Article::status()
{
return m_status;
}
QStringList Article::pageNames()
{
QList<QString> keys = m_imagesLocalPath.keys();
QStringList list(keys);
list.sort();
return list;
}
void Article::getImagesLocalAndRemoateFiles(QStringList &localpaths, QStringList &remotepaths)
{
localpaths.clear(); //clear the list
remotepaths.clear();
foreach (QString key, m_imagesLocalPath.keys() )
{
localpaths.append(m_imagesLocalPath [key]);
remotepaths.append(m_imagesRemotePath[key]);
}
localpaths.sort();
remotepaths.sort();
}
bool Article::updateArticle(QSqlDatabase &database, Publication &publication, QList<Tag> &tags, QList<ImageCutout *> &cutoutsList, qreal imageSize)
{
QSqlQuery queryMaster(database);
queryMaster.prepare("UPDATE article SET headline_en = :headline_en, "
"page_number = :page_number, "
"size = :size, ave = :ave, real_size = :real_size, size_l = :size_l, size_w = :size_w WHERE id_article =:id_article ");
QString headline_en = Tag::headlineEnglish(tags);
QString page_number = ImageCutout::pages(cutoutsList);
qreal size_l;
qreal size_w;
qreal size;
qreal real_size;
getSize(publication, imageSize, size_l, size_w, size, real_size, cutoutsList);
qreal ave = calculateAVE(publication.isMagazine(), publication.adRate(), size, real_size, true);
queryMaster.bindValue(":id_article", m_id);
queryMaster.bindValue(":headline_en", headline_en);
queryMaster.bindValue(":page_number", page_number);
queryMaster.bindValue(":size", size);
queryMaster.bindValue(":ave", ave);
queryMaster.bindValue(":real_size", real_size);
queryMaster.bindValue(":size_l", size_l);
queryMaster.bindValue(":size_w", size_w);
if(!queryMaster.exec())
{
qDebug() << "Sql Error (updateArticle): " << queryMaster.lastError().text().toAscii();
return false;
}
bool isArabic = (publication.language() == "Arabic");
updateTags(database, tags, isArabic);
updateImageCutouts(database, cutoutsList);
return true;
}
QList<Article> Article::preclippedArticles(QSqlDatabase &database, int publicationId, int issueNumber,
QString &localIssuePath, QString &remoteIssuePath)
{
return articles(database, publicationId, issueNumber, localIssuePath, remoteIssuePath, 1);
}
QList<Article> Article::clippedArticles (QSqlDatabase &database, int publicationId, int issueNumber,
QString &localIssuePath, QString &remoteIssuePath)
{
return articles(database, publicationId, issueNumber, localIssuePath, remoteIssuePath, 2);
}
QList<Article> Article::articles(QSqlDatabase &database, int publicationId, int issueNumber,
QString &localIssuePath, QString &remoteIssuePath, int clipping_status)
{
QSqlQuery query(database);
query.prepare("SELECT pc.id_article, pc.id_article_section, pc.page_number, pc.type, pc.x, pc.y, pc.width, pc.height, ar.images_number, pc.id_clipping_table "
"FROM clipping_coordinates as pc, article as ar "
"WHERE pc.id_article = ar.id_article AND ar.id_publication = :id_publication AND ar.issue_number = :issue_number and clipping_status = :clipping_status "
" AND ar.reject != 1 "
" ORDER BY pc.id_article");
query.bindValue(":id_publication", publicationId);
query.bindValue(":issue_number", issueNumber);
query.bindValue(":clipping_status", clipping_status);
if( !query.exec() )
{
qDebug() << query.lastError().text();
return QList<Article> ();
}
QList<Article> list;
int tmpId = -1;
int articleId = 0;
int count = 0;
Article pc;
QList<ImageCutout *> cutoutsList;
QHash<QString, QString> localpath;
QHash<QString, QString> remotepath;
bool found = false;
while( query.next() )
{
//qDebug("Iterator %d", counter++);
tmpId = query.value(0).toInt();
int sectionId = query.value(1).toInt();
QString pagename = query.value(2).toString();
pagename = QString("%1").arg(pagename, 4, QChar('0'));
if (!pagename.endsWith(".jpg") )
pagename += ".jpg";
int type = query.value(3).toInt();
int x = query.value(4).toInt();
int y = query.value(5).toInt();
int w = query.value(6).toInt();
int h = query.value(7).toInt();
int imagesNumber = query.value(8).toInt();
int clippingId = query.value(9).toInt();
if( tmpId != articleId)
{
found = true;
if(count != 0)
{
pc.setImageCutouts(cutoutsList);
QList<Tag> tags = Tag::loadArticleTags(database, articleId);
pc.setTags(tags);
pc.setImagesLocalPath(localpath);
pc.setImagesRemotePath(remotepath);
list.append(pc);
cutoutsList.clear();
localpath.clear();
remotepath.clear();
}
articleId = tmpId;
pc.setId(articleId);
pc.setImagesNumber(imagesNumber);
//cutoutsList.clear();
//pc.setImageCutouts(cutoutsList);
count++;
}
QString localPagename = localIssuePath + QString("%1/%2").arg(sectionId).arg(pagename);
QString remotePagename = remoteIssuePath+ QString("%1/%2").arg(sectionId).arg(pagename);
QString sectionPagename = Section::sectionName(database, sectionId) + "/" + pagename;
localpath [sectionPagename] = localPagename;
remotepath[sectionPagename] = remotePagename;
SELECTION_AREA_TYPE stype = static_cast<SELECTION_AREA_TYPE> (type);
ImageCutout * rect = new ImageCutout(clippingId, QPolygonF(QRectF(x, y, w, h)), 0, localPagename, stype);
cutoutsList.append(rect);
}
if(found)
{
pc.setImageCutouts(cutoutsList);
QList<Tag> tags = Tag::loadArticleTags(database, articleId);
pc.setTags(tags);
pc.setImagesLocalPath(localpath);
pc.setImagesRemotePath(remotepath);
list.append(pc);
}
return list;
}
int Article::clip(QSqlDatabase &database, Publication &publication, int created_by, QList<Tag> &tags,
QList<ImageCutout *> &cutoutsList, QString section, qreal image_size, int images_number, int clipping_status, QString text_ocr)
{
QSqlQuery queryMaster(database);
queryMaster.prepare("INSERT INTO article ( headline_en, publication_date, issue_number, id_publication, "
"id_article_type, created_by, created, section, circulation, images_number, page_number, "
"size, id_article_section, ave, real_size, clipping_status, size_l, size_w, id_zissor) "
"VALUES"
" (:headline_en, :publication_date, :issue_number, :id_publication, "
":id_article_type, :created_by, NOW(), :section, :circulation, :images_number, :page_number, "
":size, :id_article_section, :ave, :real_size, :clipping_status, :size_l, :size_w, :id_zissor) ");
QString headline_en = Tag::headlineEnglish(tags);
QString publication_date = publication.currentIssue()->date();
int issue_number = publication.currentIssue()->id();
int id_publication = publication.id();
int id_article_type = publication.type();
int circulation = publication.circulation();
int id_article_section = publication.currentIssue()->section(section).id();
int id_zissor = 1;
QString page_number = ImageCutout::pages(cutoutsList);
qreal size_l;
qreal size_w;
qreal size;
qreal real_size;
getSize(publication, image_size, size_l, size_w, size, real_size, cutoutsList);
qreal ave = calculateAVE(publication.isMagazine(), publication.adRate(), size, real_size, true);
queryMaster.bindValue(":headline_en", headline_en);
queryMaster.bindValue(":publication_date", publication_date);
queryMaster.bindValue(":issue_number", issue_number);
queryMaster.bindValue(":images_number", images_number);
queryMaster.bindValue(":id_publication", id_publication);
queryMaster.bindValue(":id_article_type", id_article_type);
queryMaster.bindValue(":created_by", created_by);
queryMaster.bindValue(":section", section);
queryMaster.bindValue(":page_number", page_number);
queryMaster.bindValue(":circulation", circulation);
queryMaster.bindValue(":size", size);
queryMaster.bindValue(":id_article_section", id_article_section);
queryMaster.bindValue(":ave", ave);
queryMaster.bindValue(":real_size", real_size);
queryMaster.bindValue(":clipping_status", clipping_status);
queryMaster.bindValue(":size_l", size_l);
queryMaster.bindValue(":size_w", size_w);
queryMaster.bindValue(":id_zissor", id_zissor);
//queryMaster.bindValue(":text_ocr", text_ocr);
if(!queryMaster.exec())
{
qDebug() << queryMaster.lastQuery().toAscii();
//QMessageBox::critical(this, tr("SQL Error"), queryMaster.lastError().databaseText());
return -1;
}
int id_article = 0;
QVariant var = queryMaster.lastInsertId();
if(var.isValid())
id_article = var.toInt();
Tag::setArticleTags(database, id_article, tags);
insertPromience(database, publication, id_article, tags, created_by);
//insert into the clipping coordinates table
setCippingCoordinates(database, id_article, cutoutsList);
//insert towrite flag
//get highest to write value
int towrite = 0;
for(int i=0; i<tags.count(); i++)
{
if (towrite < tags[i].towrite())
towrite = tags[i].towrite();
}
if(towrite > 0)
{
bool isArabic = (publication.language() == "Arabic");
setArticleTowrite(database, id_article, towrite, isArabic);
}
return id_article;
}
void Article::getSize(Publication &publication, qreal image_size, qreal &size_l, qreal &size_w, qreal &size, qreal &real_size, QList<ImageCutout *> &cutoutsList)
{
size_l = size_w = size = real_size = 0.0;
qreal width, height;//, tmpsize = 0.0;
QHash<QString, qreal> sizes;
if(publication.isMagazine())
{
QStringList tmpCount;
for(int i=0; i< cutoutsList.count(); i++)
{
width = (cutoutsList[i]->boundingRect().width()/DPI) * 2.54;
height = (cutoutsList[i]->boundingRect().height()/DPI) * 2.54;
size_w += width;
size_l += height;
//tmpsize += (size_w * size_l);
qreal tmpsize = (width * height) / image_size;
//qDebug() << cutoutsList[i]->pageName().toAscii();
//qDebug("\t%.2f", tmpsize);
if(!tmpCount.contains(cutoutsList[i]->pageName()) )
{
tmpCount.append(cutoutsList[i]->pageName() );
sizes[cutoutsList[i]->pageName()] = tmpsize;
}
else
sizes[cutoutsList[i]->pageName()]+= tmpsize;
}
size = tmpCount.count();
foreach ( QString key, sizes.keys() )
real_size += sizes[key];
}
else
{
qreal columnWidth = publication.columnWidth();
if(!columnWidth)
columnWidth = NEWSPAPER_COLUMN_WIDTH;
for(int i=0; i< cutoutsList.count(); i++)
{
width = (cutoutsList[i]->boundingRect().width()/DPI) * 2.54;
height = (cutoutsList[i]->boundingRect().height()/DPI) * 2.54;
size_w += width;
size_l += height;
width /= columnWidth;
size += width * height;
}
}
}
qreal Article::calculateAVE(bool isMagazine, qreal adrate, qreal size, qreal real_size, bool round)
{
if (isMagazine)
{
if (adrate > 0 )
{
if(round)
{
float ss = roundf(real_size*100.0f)/100.0f;
return ss * adrate;
}
else
return real_size * adrate;
}
else
return 0.0;
}
else
{
if ( adrate > 0 )
return size * adrate;
else
return 0.0;
}
}
void Article::setCippingCoordinates(QSqlDatabase &database, int id_article, QList<ImageCutout*> &cutoutsList)
{
QSqlQuery query(database);
query.prepare("INSERT INTO clipping_coordinates (id_article, id_article_section, page_number, type, x, y, width, height) "
"VALUES (:id_article, :id_article_section, :page_number, :type, :x, :y, :w, :h)");
query.bindValue(":id_article", id_article);
//The name is in the format of
// /socialhose/app/ClippingStation/cach/2009/09/10/162/9/0001.jpg
for(int i=0; i< cutoutsList.count(); i++)
{
QString page = cutoutsList[i]->pageName();
int index = page.lastIndexOf("/");
int index2 = page.lastIndexOf("/", index-1);
int pagenumber = page.right(page.length()-index-1).replace(".jpg", "").toInt();
//int pagenumber2 = cutoutsList[i]->pageNumber().toInt();
QString page_number = QString("%1").arg(pagenumber);
int id_section = page.mid(index2+1, abs(index2-index)-1).toInt();
//int id_section2 = cutoutsList[i]->sectionNumber();
int x = static_cast<int> (cutoutsList[i]->boundingRect().topLeft().x());
int y = static_cast<int> (cutoutsList[i]->boundingRect().topLeft().y());
int w = static_cast<int> (cutoutsList[i]->boundingRect().width());
int h = static_cast<int> (cutoutsList[i]->boundingRect().height());
int type = cutoutsList[i]->areaType();
query.bindValue(":id_article_section", id_section);
query.bindValue(":page_number", page_number);
query.bindValue(":type", type);
query.bindValue(":x", x);
query.bindValue(":y", y);
query.bindValue(":w", w);
query.bindValue(":h", h);
if (!query.exec())
{
qDebug() << "Error (clipping coordinates): "<< query.lastError().databaseText().toAscii();
}
}
}
void Article::setArticleTowrite(QSqlDatabase &database, int idArticle, int toWrite, bool isArabic)
{
//advert_summary = 1
int idSummary = 1;
if(toWrite == 1)
{
QSqlQuery queryPublish(database);
queryPublish.prepare("UPDATE article SET published=1, published_by=1, published_date=NOW(), id_summary=:id_summary WHERE id_article=:id_article AND towrite=0");
queryPublish.bindValue(":id_summary", idSummary);
queryPublish.bindValue(":id_article", idArticle);
if (!queryPublish.exec())
{
}
qDebug("setArticleTowrite(): [tag:1] Set article %d as published", idArticle);
}
else if(toWrite == 2)
{
QSqlQuery queryToWrite(database), queryUnpublish(database);
queryToWrite.prepare("UPDATE article SET towrite=1 WHERE id_article=:id_article");
queryToWrite.bindValue(":id_article", idArticle);
queryUnpublish.prepare("UPDATE article SET published=0, published_by=0, published_date='0000-00-00', id_summary=0 WHERE id_article=:id_article AND published_by=1 AND towrite=1");
queryUnpublish.bindValue(":id_article", idArticle);
queryToWrite.exec();
queryUnpublish.exec();
qDebug("setArticleTowrite(): [tag:2] Set towrite and unpublished article %d", idArticle);
}
else if(toWrite == 3)
{
if(isArabic)
{
QSqlQuery queryToWrite(database), queryUnpublish(database);
queryToWrite.prepare("UPDATE article SET towrite=1 WHERE id_article=:id_article");
queryToWrite.bindValue(":id_article", idArticle);
queryUnpublish.prepare("UPDATE article SET published=0, published_by=0, published_date='0000-00-00', id_summary=0 WHERE id_article=:id_article AND published_by=1 AND towrite=1");
queryUnpublish.bindValue(":id_article", idArticle);
queryToWrite.exec();
queryUnpublish.exec();
qDebug("setArticleTowrite(): [tag:3] Set towrite and unpublished article %d", idArticle);
}
}
else
qDebug("setArticleTowrite(): This is not supposed to happen.");
}
Article Article::article(QSqlDatabase &database, int articleId, QString &localIssuePath, QString &remoteIssuePath)
{
QSqlQuery query(database);
query.prepare("SELECT pc.id_article, pc.id_article_section, pc.page_number, pc.type, pc.x, pc.y, pc.width, pc.height, ar.images_number, pc.id_clipping_table "
"FROM clipping_coordinates as pc, article as ar "
"WHERE pc.id_article = ar.id_article AND ar.id_article = :id_article");
query.bindValue(":id_article", articleId);
if( !query.exec() )
{
qDebug() << query.lastError().databaseText();
return Article();
}
int tmpId = -1, tmpId2 = 0;
Article pc;
QList<ImageCutout *> cutoutsList;
QHash<QString, QString> localpath;
QHash<QString, QString> remotepath;
bool found = false;
while( query.next() )
{
//qDebug("Iterator %d", counter++);
tmpId = query.value(0).toInt();
int sectionId = query.value(1).toInt();
QString pagename = query.value(2).toString();
pagename = QString("%1").arg(pagename, 4, QChar('0'));
if (!pagename.endsWith(".jpg") )
pagename += ".jpg";
int type = query.value(3).toInt();
int x = query.value(4).toInt();
int y = query.value(5).toInt();
int w = query.value(6).toInt();
int h = query.value(7).toInt();
int imagesNumber = query.value(8).toInt();
int clippinId = query.value(9).toInt();
if( tmpId != tmpId2)
{
found = true;
tmpId2 = tmpId;
articleId = tmpId;
pc.setId(articleId);
pc.setImagesNumber(imagesNumber);
}
QString localPagename = localIssuePath + QString("%1/%2").arg(sectionId).arg(pagename);
QString remotePagename = remoteIssuePath+ QString("%1/%2").arg(sectionId).arg(pagename);
QString sectionPagename = Section::sectionName(database, sectionId) + "/" + pagename;
localpath [sectionPagename] = localPagename;
remotepath[sectionPagename] = remotePagename;
SELECTION_AREA_TYPE stype = static_cast<SELECTION_AREA_TYPE> (type);
ImageCutout * rect = new ImageCutout(clippinId, QPolygonF(QRectF(x, y, w, h)), 0, localPagename, stype);
cutoutsList.append(rect);
}
if(found)
{
pc.setImageCutouts(cutoutsList);
QList<Tag> tags = Tag::loadArticleTags(database, articleId);
pc.setTags(tags);
pc.setImagesLocalPath(localpath);
pc.setImagesRemotePath(remotepath);
}
return pc;
}
void Article::insertPromience(QSqlDatabase &database, Publication &publication, int idArticle, QList<Tag> &tags, int createdBy)
{
qDebug("insertPromience()");
QSqlQuery query(database);
query.prepare("INSERT INTO prominence (id_company, id_article, mention_score, visual_score, "
"tone_score, created_by, created, size_cc, size_page, ave, note) "
" VALUES (:id_company, :id_article, :mention_score, :visual_score, "
":tone_score, :created_by, NOW(), :size_cc, :size_page, :ave, :note )");
query.bindValue(":id_article", idArticle);
for(int i=0; i < tags.count(); i++)
{
Tag t = tags[i];
if(t.prominence().m_size <= 0)
{
qDebug ("Prominance for Tag (%d) has a value of zero, wont be inserted to db.", t.id() );
continue;
}
double ave = calculateAVE(publication.isMagazine(), publication.adRate(), t.prominence().m_size, t.prominence().m_size, false);
query.bindValue(":id_company", t.id());
query.bindValue(":mention_score", t.prominence().m_mentionScore);
query.bindValue(":visual_score", t.prominence().m_visualScore);
query.bindValue(":tone_score", t.prominence().m_toneScore);
query.bindValue(":created_by", createdBy);
if(publication.isMagazine())
{
query.bindValue(":size_cc", QVariant(QVariant::Double) );
query.bindValue(":size_page", t.prominence().m_size);
}
else
{
query.bindValue(":size_cc", t.prominence().m_size);
query.bindValue(":size_page", QVariant(QVariant::Double) );
}
query.bindValue(":ave", ave);
query.bindValue(":note", t.prominence().m_note);
if(!query.exec() )
{
qDebug() << "insertPromience() Sql Error " << query.lastError().text();
qDebug() << "exe query:" << query.executedQuery();
}
}
qDebug("end of insertPromience()");
}
void Article::updateProminence(QSqlDatabase &database, Publication &publication, QList<Tag> &tags, int createdBy)
{
qDebug("updateProminence()");
//delete prominence for this aricle, and re-insert them.
QSqlQuery query(database);
query.prepare("DELETE FROM prominence WHERE id_article = :id_article");
query.bindValue(":id_article", m_id);
if(!query.exec())
{
//could delete all prominence to db.
qDebug() << "updateProminence() Sql Error " << query.lastError().text();
qDebug() << "exe query:" << query.executedQuery();
}
insertPromience(database, publication, m_id, tags, createdBy);
qDebug("end of updateProminence()");
}
+349
View File
@@ -0,0 +1,349 @@
/************************************************************************
* $Id: article.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/article.h $
*
************************************************************************/
#ifndef ARTICLE_H
#define ARTICLE_H
#include <QtCore>
#include <QtSql>
#include "imagecutout.h"
#include "tag.h"
class Publication;
class Article
{
public:
//! \fn Article()
//! default constructor
//! \author elzubeir
Article();
//! \fn ~Article()
//! default destructor
//! \author elzubeir
~Article();
//! \fn operator ==()
//! assignment operator
//! \author elzubeir
bool operator == (const Article & pc);
//! \fn setId()
//! sets the id for the article
//! \param[in] articleId integer holding the article id
//! \author elzubeir
void setId(int articleId);
//! \fn setPagename()
//! sets the pagename for the article
//! \param[in] pagename string holding the pagename
//! \author elzubeir
void setPagename(QString pagename);
//! \fn setImageCutouts()
//! sets the list of imagecutouts for the article
//! \param[in] cutoutsList list of cutouts belonging to the article
//! \author elzubeir
void setImageCutouts(QList<ImageCutout *> cutoutsList);
//! \fn updateImageCutouts()
//! updates the list of imagecutouts for the article
//! \param[in] database database object to update the query
//! \param[in] cutoutsList list of cutouts belonging to the article
//! \author elzubeir
void updateImageCutouts(QSqlDatabase &database, QList<ImageCutout *> cutoutsList);
//! \fn setTags()
//! sets the list of tages belongs to the article
//! \param[in] tags list of tags belonging to the article
//! \author elzubeir
void setTags(QList<Tag> &tags);
//! \fn setTags()
//! sets the list of tages belongs to the article
//! \param[in] database database object to update the query
//! \param[in] tags list of tags to be updated
//! \param[in] isArabic boolean to show if the tags are arabic or not
//! \author elzubeir
void updateTags(QSqlDatabase &database, QList<Tag> &tags, bool isArabic);
void updateProminence(QSqlDatabase &database, Publication &publication, QList<Tag> &tags, int createdBy);
//! \fn setImagesNumber()
//! sets the number of images contained in the article
//! \param[in] imagesNumber int holding the number of images in article
//! \author elzubeir
void setImagesNumber(int imagesNumber);
//! \fn updateImagesNumber()
//! updates the number of images contained in the article
//! \param[in] database database object to update the query
//! \param[in] imagesNumber int holding the new value for number of images
//! \author elzubeir
void updateImagesNumber(QSqlDatabase &database, int imagesNumber);
//! \fn updateImagesNumber()
//! updates the number of images contained in the article
//! \param[in] database database object to update the query
//! \param[in] articleId the id of the article
//! \param[in] imagesNumber int holding the new value for number of images
//! \author elzubeir
//! \author elzubeir
static void updateImagesNumber(QSqlDatabase &database, int articleId, int imagesNumber);
//! \fn setImagesLocalPath()
//! sets the path for the local images belonging to the article
//! \param[in] path string/string hash holding the value of section pagename, and its local location path
//! \author elzubeir
void setImagesLocalPath(QHash<QString, QString> path);
//! \fn setImagesRemotePath()
//! sets the path for the remote images belonging to the article
//! \param[in] path string/string hash holding the value of section pagename, and its remote location path (could be file server or ftp server)
//! \author elzubeir
void setImagesRemotePath(QHash<QString, QString> path);
//! \fn setStatus()
//! sets the article status
//! \param[in] status int holding the status of article
//! \author elzubeir
void setStatus(int status);
//! \fn updateStatus()
//! updates the status of the article
//! \param[in] database database object to update the query
//! \param[in] status int the new status value for the article
//! \author elzubeir
void updateStatus(QSqlDatabase &database, int status);
static void updateText(QSqlDatabase &database, int id, QString text);
static void updateHeadline(QSqlDatabase &database, int id, QString headline, bool isArabic);
//! \fn updateStatus()
//! static function to updates the status of the article passed by its id
//! \param[in] database database object to update the query
//! \param[in] articleId int the id of the article to update its status
//! \param[in] status int the new status value for the article
//! \author elzubeir
static void updateStatus(QSqlDatabase &database, int articleId, int status);
//! \fn deleteArticle()
//! delete the article from database
//! \param[in] database database object to update the query
//! \author elzubeir
void deleteArticle(QSqlDatabase &database);
//! \fn deleteArticle()
//! static version to delete an article from database
//! \param[in] database database object to update the query
//! \param[in] articleId int the id of the article to be deleted
//! \author elzubeir
static void deleteArticle(QSqlDatabase &database, int articleId);
//! \fn updateArticle()
//! update the article with different values
//! \param[in] database database object to update the query
//! \param[in] publication Publication object holds the publication this article belongs to
//! \param[in] tags list of new tags belonging to this article
//! \param[in] cutoutsList list of new image cutouts belonging to this article
//! \param[in] imageSize float the new size of the images for the article
//! \author elzubeir
bool updateArticle(QSqlDatabase &database, Publication &publication, QList<Tag> &tags, QList<ImageCutout *> &cutoutsList, qreal imageSize);
//! \fn getImagesLocalAndRemoateFiles()
//! returns the local and remoate list of images belonging to the article
//! \param[out] locafiles list of local image paths
//! \param[out] remoatefiles list of remoate image paths
//! \author elzubeir
void getImagesLocalAndRemoateFiles(QStringList &localfiles, QStringList &remotefiles);
//! \fn id()
//! returns the id of the article
//! \return int holding the article id
//! \author elzubeir
int id();
//! \fn pageNames()
//! returns list of page names contained in the article
//! \return string list holding the article page names
//! \author elzubeir
QStringList pageNames();
//! \fn imageCutoutsList()
//! returns list of cutouts of the article
//! \return image cutout list in the article
//! \author elzubeir
QList<ImageCutout *> imageCutoutsList();
//! \fn tags()
//! returns list of tags of the article
//! \return tags list in the article
//! \author elzubeir
QList<Tag> tags();
//! \fn status()
//! returns the status the article
//! \return int represents the status of article
//! \author elzubeir
int status();
//! \fn imagesNumber()
//! returns the number of images in the article
//! \return int represents the number of images in article
//! \author elzubeir
int imagesNumber();
//! \fn preclippedArticles()
//! returns a list of preclippedarticles based on passed parameters
//! \param[in] database database object to update the query
//! \param[in] publicationId Publication object holds the publication this article belongs to
//! \param[in] issueNumber int issueNumber of the required articles
//! \param[in] localIssuePath string holding the local path for the issue
//! \param[in] remoteIssuePath string holding the remote path for the issue
//! \return list of preclipped articles
//! \author elzubeir
static QList<Article> preclippedArticles (QSqlDatabase &database, int publicationId, int issueNumber,
QString &localIssuePath, QString &remoteIssuePath);
//! \fn clippedArticles()
//! returns a list of clipped articles based on passed parameters
//! \param[in] database database object to update the query
//! \param[in] publicationId Publication object holds the publication this article belongs to
//! \param[in] issueNumber int issueNumber of the required articles
//! \param[in] localIssuePath string holding the local path for the issue
//! \param[in] remoteIssuePath string holding the remote path for the issue
//! \return list of clipped articles
//! \author elzubeir
static QList<Article> clippedArticles (QSqlDatabase &database, int publicationId, int issueNumber,
QString &localIssuePath, QString &remoteIssuePath);
//! \fn article()
//! returns an article based on passed parameters
//! \param[in] database database object to update the query
//! \param[in] articleId int id of the article to return
//! \param[in] localIssuePath string holding the local path for the issue
//! \param[in] remoteIssuePath string holding the remote path for the issue
//! \return article object
//! \author elzubeir
static Article article (QSqlDatabase &database, int articleId, QString &localIssuePath, QString &remoteIssuePath);
//! \fn clip()
//! static function to insert a new article to the article's table
//! \param[in] database database object to insert the query
//! \param[in] publication Publication object that the article belongs to
//! \param[in] createdBy int the user id who created the article
//! \param[in] tags list of tags to insert to this article
//! \param[in] cutoutsList list of image cutouts to insert to this article
//! \param[in] section string the section name containing the article
//! \param[in] imageSize float the total size of the images for the article
//! \param[in] imagesNumber int holding the number of images in article
//! \param[in] clippingStatus int status of the article
//! \param[in] text_ocr int text of the article
//! \return int value holding the id for the newley created article
//! \author elzubeir
static int clip(QSqlDatabase &database, Publication &publication, int createdBy, QList<Tag> &tags,
QList<ImageCutout *> &cutoutsList, QString section, qreal imageSize, int imagesNumber, int clippingStatus, QString text_ocr = "");
private:
//! \fn setCippingCoordinates()
//! static function to set the image cutouts clipping corrdinates
//! \param[in] database database object to update the query
//! \param[in] articleId int id of the article to return
//! \param[in] cutoutsList list of cutouts of the article
//! \author elzubeir
static void setCippingCoordinates(QSqlDatabase &database, int articleId, QList<ImageCutout*> &cutoutsList);
//! \fn articles()
//! static function to calculate the total size of the article
//! \param[in] publication Publication object that the article belongs to
//! \param[in] imageSize the size of the total image
//! \param[out] sizeL float the total length of all the image cutouts of the article
//! \param[out] sizeW float the total width of all the image cutouts of the article
//! \param[out] size float the total size of all the cutouts in the article, if the article is newspaper
//! \param[out] realSize float the total size of all the cutouts in the article, if the article is magazine
//! \return float value represents the total AVE of the article
//! \author elzubeir
static void getSize(Publication &publication, qreal imageSize, qreal &sizeL, qreal &sizeW, qreal &size,
qreal &realSize, QList<ImageCutout *> &cutoutsList);
//! \fn articles()
//! static function to calculate the total AVE of the article
//! \param[in] isMagazine boolean if the article is magazine or newspaper
//! \param[in] adrate float the add rate value for the article
//! \param[in] size float the size of the article
//! \param[in] realSize float the real size of the article, needed when
//! \return float value represents the total AVE of the article
//! \author elzubeir
static qreal calculateAVE (bool isMagazine, qreal adrate, qreal size, qreal real_size, bool round);
//! \fn articles()
//! static function to return a list of articles based on passed parameters
//! \param[in] database database object to update the query
//! \param[in] publicationId Publication object holds the publication this article belongs to
//! \param[in] issueNumber int issueNumber of the required articles
//! \param[in] localIssuePath string holding the local path for the issue
//! \param[in] remoteIssuePath string holding the remote path for the issue
//! \param[in] clippingStatus int status of the clippings to search for
//! \return list of articles
//! \author elzubeir
static QList<Article> articles (QSqlDatabase &database, int publicationId, int issueNumber,
QString &localIssuePath, QString &remoteIssuePath, int clippingStatus);
//! \fn setArticleTowrite()
//! sets the article attribute to write
//! \param[in] database database object to update the query
//! \param[in] idArticle int article's id
//! \param[in] toWrite int to write value for the article
//! \param[in] isArabic boolean is this article an arabic one or not
//! \author elzubeir
static void setArticleTowrite(QSqlDatabase &database, int idArticle, int toWrite, bool isArabic);
static void insertPromience(QSqlDatabase &database, Publication &publication, int idArticle, QList<Tag> &tags, int createdBy);
private:
//! the article id
int m_id;
//! the pagename will be the section ID, and the pagename
QString m_pagename;
//! hash of the section name/local image paths for the article
QHash<QString, QString> m_imagesLocalPath;
//! hash of the section name/remote image paths for the article
QHash<QString, QString> m_imagesRemotePath;
//! list of image cutouts in the article
QList<ImageCutout *> m_imageCutoutsList;
//! list of tags in the article
QList<Tag> m_tags;
//! status of the article
int m_status;
//! number of images contained in the article
int m_imagesNumber;
};
#endif // ARTICLE_H
+44
View File
@@ -0,0 +1,44 @@
//! \file authenticationdialog.cpp
/************************************************************************
* $Id: authenticationdialog.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/authenticationdialog.cpp $
*
************************************************************************/
#include "authenticationdialog.h"
#include "ui_authenticationdialog.h"
AuthenticationDialog::AuthenticationDialog(QWidget *parent) :
QDialog(parent),
m_ui(new Ui::AuthenticationDialog)
{
m_ui->setupUi(this);
}
AuthenticationDialog::~AuthenticationDialog()
{
delete m_ui;
}
void AuthenticationDialog::accept()
{
//set m_username, m_password from user input
m_username = m_ui->usernameLineEdit->text();
m_password = m_ui->passwordLineEdit->text();
//call base class's accept method
QDialog::accept();
}
+67
View File
@@ -0,0 +1,67 @@
//! \file authenticationdialog.h
/************************************************************************
* $Id: authenticationdialog.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/authenticationdialog.h $
*
************************************************************************/
#ifndef AUTHENTICATIONDIALOG_H
#define AUTHENTICATIONDIALOG_H
#include <QtGui/QDialog>
namespace Ui {
class AuthenticationDialog;
}
//! \class AuthenticationDialog
//! \brief This class creates a username/password input dialog,
//! and passes the value obtained to the main application for verification
//! \author elzubeir
class AuthenticationDialog : public QDialog {
Q_OBJECT
public:
//! \fn AuthenticationDialog(QWidget *parent = 0)
//! default constructor
//! \param[in] parent QWidget pointer set to the calling widget
//! \author elzubeir
AuthenticationDialog(QWidget *parent = 0);
//! \fn ~AuthenticationDialog()
//! destructor
//! \author elzubeir
~AuthenticationDialog();
protected:
//! \fn accept()
//! Overrides the base function, and sets the m_username/m_password from the users input, and then calls
//! the base calss's accept method
//! \author elzubeir
void accept();
public:
//! saves the username obtained from the user
QString m_username;
//! saves the password obtained from the user
QString m_password;
private:
//! pointer to the Qt desginer UI class object
Ui::AuthenticationDialog *m_ui;
};
#endif // AUTHENTICATIONDIALOG_H
+98
View File
@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AuthenticationDialog</class>
<widget class="QDialog" name="AuthenticationDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>284</width>
<height>131</height>
</rect>
</property>
<property name="contextMenuPolicy">
<enum>Qt::NoContextMenu</enum>
</property>
<property name="windowTitle">
<string>Authentication</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Please enter your username and password</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Username</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="usernameLineEdit"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Password</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="passwordLineEdit">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<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>AuthenticationDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>222</x>
<y>95</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>114</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>AuthenticationDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>222</x>
<y>101</y>
</hint>
<hint type="destinationlabel">
<x>231</x>
<y>114</y>
</hint>
</hints>
</connection>
</connections>
</ui>
File diff suppressed because it is too large Load Diff
+948
View File
@@ -0,0 +1,948 @@
//! \file clippingstation.h
/************************************************************************
* $Id: clippingstation.h 667 2011-05-15 10:41:45Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-05-15 14:41:45 +0400 (Sun, 15 May 2011) $
* $Author: elzubeir $
* $Revision: 667 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/clippingstation.h $
*
************************************************************************/
#ifndef CLIPPINGSTATION_H
#define CLIPPINGSTATION_H
#include <QtGui>
#include <QtSql>
#include <QModelIndex>
#include "user.h"
#include "publication.h"
#include "imagecachingdialog.h"
#include "tagswrapper.h"
#include "imagecutout.h"
#include "globalfunctions.h"
#include "searchpublicationlistdialog.h"
#include "wordcoordinates.h"
#include "tagcoordinates.h"
namespace Ui
{
class ClippingStation;
}
//! \class ClippingStation
//! The ClippingStation class is the main class devierd from the QMainWindow base class
//! it incorporates all the functionality of the other modules, and preform the main operations, like
//! clipping, drawer, importer
class ClippingStation : public QMainWindow
{
Q_OBJECT
public:
//! \fn ClippingStation()
//! default constructor
//! \param[in] parent QWidget pointer, set to zero, because this is the main window
//! \author elzubeir
ClippingStation(QWidget *parent = 0);
//! \fn ~ClippingStation()
//! destructor
//! \author elzubeir
~ClippingStation();
//! \fn displayStatusMessage()
//! \brief Display a message in the status bar.
//! \param status the message.
//! \author elzubeir
void displayStatusMessage(const QString & status);
//! \fn clearStatusMessage()
//! \brief clear the status bar.
//! \author elzubeir
void clearStatusMessage();
//! \fn displayCoordinatesStatus()
//! \brief Display mouse coordinates in the status bar.
//! \param x x mouse coordinate.
//! \param y y mouse coordinate.
//! \author elzubeir
void displayCoordinatesStatus(qreal x, qreal y, qreal width = 0.0, qreal height = 0.0);
//! \fn displayRotationAngleStatus()
//! \brief Display angle in the status bar.
//! \param status the message.
//! \author elzubeir
void displayRotationAngleStatus(qreal angle);
//! \fn displayZoomStatus()
//! \brief Display zoom in the status bar.
//! \param status the message.
//! \author elzubeir
void displayZoomStatus(qreal zoom);
//! \fn updateDrawerPageInformation()
//! update the page information for the drawer
//! \author elzubeir
void updateDrawerPageInformation();
//! \fn thumbnail()
//! creates the thumbnail for the image containing the first cutout on the left pane
//! \author elzubeir
void thumbnail();
//! \fn A4Scale()
//! returns the current scale for the A4 pages
//! \return qreal holding the current scale for the A4 page
//! \author elzubeir
qreal A4Scale();
//! \fn calculatePosAndScale()
//! calculation the position for the drop image in drawer
//! \param[in] cellSize size of the cell.
//! \param[in] img dropped image.
//! \param[in] type type of image (image, title or body)
//! \param[in] resetarray to reset the array or not.
//! \param[in] pos the postion of the image
//! \param[in] scale the scale of that image.
//! \return bool
//! - true if all the values are populated
//! - false otherwise
//! \author elzubeir
bool calculatePosAndScale(QSizeF cellSize, QImage &img, int type, bool resetarray, QPointF &pos, qreal &scale);
//! \fn A4CellSize()
//! calculate the a4 cell size.
//! \param[in] isfirst: is the first page in drawer.
//! \return QSizeF the size of the cell
//! \author elzubeir
QSizeF A4CellSize(bool isfirst);
//! \fn addTagsToTagWrapper()
//! add tags to the tag wrapper
//! \param[in] tagIds: list of tags to be added
//! \param[in] tagCoord: list of coordinates to be added
//! \param[in] removeAndThenAdd: remove tags from wrapper and then add
//! \return void
//! \author elzubeir
void addTagsToTagWrapper(QList<int> &tagIds, QStringList tagCoord, bool removedAndThenAdd = false);
QStringList getRelatedKeywords(QString tag);
protected:
bool eventFilter(QObject *obj, QEvent *ev);
private:
//! \fn readSettings()
//! This function reads the settings for the application from a config.ini file
//! and populate the member variables with the values read from the ini file
//! \see connectToDatabase()
//! \return bool
//! - true if all the values are populated
//! - false otherwise
//! \author elzubeir
bool readSettings();
//! \fn connectToDatabase()
//! Connect to master and slave databases based on the valuess read from "config.ini" file for the connection strings
//! \see readSettings()
//! \return bool
//! - true if the two connections are established correctly
//! - false if error occurs
//! \author elzubeir
bool connectToDatabase();
//! \fn authenticate()
//! Authenticate the user who wants to login, it calls the authenticate function in the user class, if authentication is successful, the user object
//! is populated with the apropriate username, password, and userid
//! \return bool
//! - true if authenticate is true
//! - false otherwise
//! \author elzubeir
bool authenticate();
//! \fn createActions()
//! create actions for the main Window, and attach them to their correspoding slots
//! \author elzubeir
void createActions();
//! \fn loadImage()
//! loads image in the full page view based on the user's selection
//! \return bool
//! true if operation successful
//! false if not
//! \author elzubeir
bool loadImage();
//! \fn cache()
//! caches pages from the current selected issue, this is done in background
//! \see cacheOnePage()
//! \author elzubeir
void cache();
//! \fn cacheOnePage()
//! Caches one page from src to local cache directory
//! \param[in] srcPage QString path to the source page
//! \param[in] dstPage QString path to the destination page
//! \return bool
//! true if operation successful
//! false if not
//! \author elzubeir
bool cacheOnePage(QString srcPage, QString dstPage);
//! \fn recursiveDelete()
//! Deletes directory recursively
//! \param[in] dir QDir path to the parent directory to be deleted
//! \return bool
//! true if operation successful
//! false if not
//! \author elzubeir
bool recursiveDelete(const QDir &dir );
//! \fn gotoClipPage()
//! When an article from the article tree view is selected, this functions higlights the appropriate page on the issues tree view
//! \see articleTreeViewClicked()
//! \author elzubeir
void gotoClipPage();
//! \fn createClipImages()
//! Creats screenshots of the clipped images
//! \return QList List of screenshots images
//! \see saveClipImagesToFileServer(), saveClipImagesToFtpServer()
//! \author elzubeir
QList<QImage> createClipImages();
//! \fn saveClipImagesToFileServer()
//! Saves the clip images to fileserver
//! \param[in] id_article articles id
//! \param[in] list List of images to save
//! \return bool
//! true if operation successful
//! false if not
//! \see createClipImages(), saveClipImagesToFtpServer()
//! \author elzubeir
static int saveClipImagesToFileServer(QString currentIssue, int id_article, QList<QImage> &list);
//! \fn saveClipImagesToFileServer()
//! Static function that saves the clip images to FTP server
//! \param[in] currentIssue current issue date
//! \param[in] id_article article id
//! \param[in] list List of images to save
//! \param[in] fromPreclip boolean to show is this clip is from a preclip, or a fresh one
//! \param[in] database QSqlDatabase instante to update table
//! \return bool
//! true if operation successful
//! false if not
//! \see saveClipImagesToFileServer(), saveClipImagesToFtpServer()
//! \author elzubeir
static bool saveClipImagesToFtpServer (QString &currentIssue, int &id_article, QList<QImage> &list, bool fromPreclip, QSqlDatabase &database);
//! \fn addTextToClip()
//! add ocr text to the clip
//! \param[in] id of the article
//! \param[in] list of image cutouts.
//! \param[in] database instance
//! \returns true if operation successful, otherwise false
//! \author elzubeir
static bool addTextToClip(int id_article, QList<ImageCutout*> &list, QSqlDatabase &database, bool isArabic);
//! \fn getTextFromCutout()
//! gets a text from the cutout
//! \param[in] rec rectangle of the cutout
//! \param[in] list of WordCoordinates containing all the words in the cutout
//! \returns a concatenated string of the text in the cutout
//! \author elzubeir
static QString getTextFromCutout( QRect rect, QList<WordCoordinates> wc );
//! \fn enableDrawerButtons()
//! enable/disable drawer buttons
//! \param[in] enable boolean to enable/disable buttons
//! \author elzubeir
void enableDrawerButtons(bool enable = true);
//! \fn setModifyClipButton()
//! toggle clip buttons text between Modify and Clip
//! \param[in] modify boolean to toggle text
//! \author elzubeir
void setModifyClipButton(bool modify);
//! \fn setModifyPreclipButton()
//! toggle clip buttons text between Modify and Preclip
//! \param[in] modify boolean to toggle text
//! \author elzubeir
void setModifyPreclipButton(bool modify);
//! \fn totalNumberOfCutoutsInDrawer()
//! returns the total number of image cutouts in drawer's A4 pages
//! \return int total number of cutouts
//! \author elzubeir
int totalNumberOfCutoutsInDrawer();
//! \fn addMargintoPos()
//! add A4 margins offset to cutout postition in auto arrange of cutouts
//! \param[out] pos QPointF holding the value of the new position after adding the margins offset
//! \param[in] isfirst boolean, different margins for first page than other pages
//! \see onActionAutoArrange()
//! \author elzubeir
void addMargintoPos(QPointF &pos, bool isfirst);
//! \fn orderList()
//! order the cutouts list based on their order numbers
//! \param[out] cutouts QList<ImageCutout*> list of cutout images
//! \see onActionAutoArrange()
//! \author elzubeir
void orderList(QList<ImageCutout*> &cutouts);
//! \fn isImageLocked()
//! checks if the image is locked by other user
//! \param[in] image image name to check if locked
//! \param[out] lockedBy id of the user locking the page
//! \return bool
//! true if image is locked
//! false if not
//! \see lockImage(), unlockImages()
//! \author elzubeir
bool isImageLocked(QString image, int &lockedBy);
//! \fn isImageLocked()
//! lock the image by the current user
//! \param[in] image image name to try to lock
//! \return bool
//! true if image is locked successfully
//! false if not
//! \see isImageLocked(), unlockImages()
//! \author elzubeir
bool lockImage(QString image);
//! \fn isImageLocked()
//! unlock the image(s) locked by the current user
//! \return bool
//! true if image is unlocked successfully
//! false if not
//! \see isImageLocked(), lockImage()
//! \author elzubeir
bool unlockImages();
//! \fn loadImageHighlights()
//! load keyword coordinates and add them to image scene
//! \param[in] name namge of the image to load
//! \author elzubeir
void loadImageHighlights(int imageId);
//! \fn loadImageText()
//! load the full text for the current image
//! \param[in] name namge of the image to load
//! \param[in] database: instance of the database to load
//! \returns a list of WordCoordinates that contains all the words and their coordinates sorted.
//! \author elzubeir
static QList<WordCoordinates> loadImageText(QString name, QSqlDatabase &database);
//! \fn currentSectionPagesStatus()
//! loads the state of the pages in the current section.
//! \param[in] id of the section
//! \returns a hash contains the page name with an icon indicationg its states (ocr processed, not processed, or waiting to be processed)
//! \author elzubeir
QHash<QString, QIcon> currentSectionPagesStatus(int sectionId);
//! \fn emptyDrawerPages()
//! returns a list of the pages in drawers that contains no cutouts.
//! \returns a list of names
//! \author elzubeir
QStringList emptyDrawerPages();
//! \fn setShortcuts()
//! set the shortcuts from settings
//! \author elzubeir
void setShortcuts();
int getImageId(const QString name);
private slots:
//! \fn onActionImporter();
//! Shows the dockable widget that contains the importer module if its closed, and if its open, it does nothing
//! \author elzubeir
void onActionImporter();
//! \fn on_rejectButton_clicked();
//! reject the article
//! \author elzubeir
void on_rejectButton_clicked();
//! \fn onActionKeyword()
//! Shows/hides the dockable widget that contains the keywords module
//! \author elzubeir
void onActionKeyword();
//! \fn onActionPublications()
//! Shows/hides the dockable widget that contains the publication module
//! \author elzubeir
void onActionPublications();
//! \fn onActionClip()
//! creates a clip
//! \author elzubeir
void onActionClip();
//! \fn onActionPreclip()
//! creates a preclip
//! \author elzubeir
void onActionPreclip();
//! \fn onActionModifyePreclip()
//! modify a selected preclip from the preclipped article list
//! \author elzubeir
void onActionModifyePreclip();
//! \fn onActionDeletePreclip()
//! delete a selected preclip from the preclipped article list
//! \author elzubeir
void onActionDeletePreclip();
//! \fn onActionAutoArrange()
//! auto arranges the selected cutouts in the drawer
//! \author elzubeir
void onActionAutoArrange();
//! \fn onActionMarkIssueAsDone()
//! marks the current issue as done
//! \author elzubeir
void onActionMarkIssueAsDone();
//! \fn onActionMarkIssueAsUndone()
//! marks the current issue as not done
//! \author elzubeir
void onActionMarkIssueAsUndone();
//! \fn onActionSendPageToOCR()
//! send the page to OCR
//! \author elzubeir
void onActionSendPageToOCR();
//! \fn onActionSendIssueToOCR()
//! send issue back to OCR
//! \author elzubeir
void onActionSendIssueToOCR();
//! \fn onActionViewPageText()
//! view the pages OCR text
//! \author elzubeir
void onActionViewPageText();
//! \fn onActionViewClipText();
//! view the clips OCR text
//! \author elzubeir
void onActionViewClipText();
void onActionViewKeywordsSearchword();
void onActionGoToKeywordWikiPage();
//! \fn onActionAbout()
//! view about dialog box
//! \author elzubeir
void onActionAbout();
//! \fn loadIssues();
//! Show the issues for a particular publication selected
//! \author elzubeir
void loadIssues();
//! \fn issueTreeViewItemClicked()
//! selecting of issues
//! \param[in] index QModelIndex of the selected issue/section/page
//! \author elzubeir
void issueTreeViewItemClicked(QModelIndex);
//! \fn articleTreeViewClicked()
//! selecting of articles
//! \param[in] index QModelIndex of the selected article
//! \author elzubeir
void articleTreeViewClicked(QModelIndex);
//! \fn previousPage()
//! navigate to the previous page in the current issue
//! \author elzubeir
void previousPage();
//! \fn nextPage();
//! navigate to the next page in the current issue
//! \author elzubeir
void nextPage();
//! \fn firstPage();
//! navigate to the first page in the current issue
//! \author elzubeir
void firstPage();
//! \fn previousPage()
//! navigate to the last page in the current issue
//! \author elzubeir
void lastPage();
//! \fn gotoPage();
//! navigate to the page sent by the gotoPageLineEdit variable
//! \author elzubeir
void gotoPage();
//! \fn zoomOut()
//! rotate the current image but rotateAngle
//! \param[in] rotateAngle double, the rotation value
//! \author elzubeir
void rotate(double rotateAngle);
//! \fn saveImageRotation();
//! save the current image by the value rotated in the rotate dialog
//! \author elzubeir
void saveImageRotation();
//! \fn zoomOut()
//! zoom out the current image
//! \author elzubeir
qreal zoomOut();
//! \fn zoomIn()
//! zoom in the current image
//! \author elzubeir
qreal zoomIn();
//! \fn bestFit()
//! best fit the current image to the available screen
//! \author elzubeir
void bestFit();
//! \fn widthFit()
//! fit the current image to the available width
//! \author elzubeir
void widthFit();
//! \fn actualSize()
//! show the current image in its original size
//! \author elzubeir
qreal actualSize();
//! \fn drawerZoomOut()
//! zoom out the drawer
//! \author elzubeir
qreal drawerZoomOut();
//! \fn drawerZoomIn()
//! zoom in the drawer
//! \author elzubeir
qreal drawerZoomIn();
//! \fn bestFit()
//! best fit the current image to the available screen
//! \author elzubeir
void drawerBestFit();
//! \fn widthFit()
//! fit the current image to the available width
//! \author elzubeir
void drawerWidthFit();
//! \fn actualSize()
//! show the current image in its original size
//! \author elzubeir
qreal drawerActualSize();
//! \fn searchKeyword()
//! search for a keyword, and displays the results in table
//! \author elzubeir
void searchKeyword();
//! \fn checkAllKeywords()
//! check all keywords in the table
//! \author elzubeir
void checkAllKeywords();
//! \fn uncheckAllKeywords()
//! uncheck all keywords in the table
//! \author elzubeir
void uncheckAllKeywords();
//! \fn selectKeyword()
//! select checked keywords and add them to the OCR list
//! \author elzubeir
void selectKeyword();
//! \fn drawerResetPages()
//! reset drawer pages, and removes all the items from it
//! \author elzubeir
void drawerResetPages();
//! \fn drawerAddPage()
//! add a page to drawer, with the broders and margins
//! \param isfirst bool
//! - true : add page with top margin for first page
//! - fasle: add page with top margin for other pages
//! \author elzubeir
void drawerAddPage(bool isfirst = false);
//! \fn drawerRemovePage()
//! remove the current active page in drawer, the function does not remove the first page
//! \see drawerResetPages()
//! \author elzubeir
void drawerRemovePage();
//! \fn drawerPreviousPage()
//! navigate to previous page in drawer
//! \author elzubeir
void drawerPreviousPage();
//! \fn drawerNextPage()
//! navigate to next page in drawer
//! \author elzubeir
void drawerNextPage();
//! \fn clipsTreeContextMenu()
//! show context menu in the clips/preclips tree
//! \param[in] point QPoint position of the mouse when clicked
//! \author elzubeir
void clipsTreeContextMenu(QPoint point);
//! \fn issueTreeContextMenu()
//! show context menu in the issues tree
//! \param[in] point QPoint position of the mouse when clicked
//! \author elzubeir
void issueTreeContextMenu(QPoint point);
void keywordsTreeContextMenu(QPoint point);
//! \fn preclip()
//! create a preclip
//! \see clip()
//! \author elzubeir
void preclip();
//! \fn clip()
//! create a clip
//! \see preclip()
//! \author elzubeir
void clip();
//! \fn createThumbnail()
//! create a thumbnail picture for the first page in the full page view and add it to the first page in drawer
//! \see clip()
//! \author elzubeir
void createThumbnail();
//! \fn loadFilteredPublication()
//! load publication that has issues that contains preclips
//! \param[in] index int represents the current index value from publicationComboBox
//! \see loadIssuesWithPreclipsOnly()
//! \author elzubeir
void loadFilteredPublication(int index);
//! \fn loadIssuesWithPreclipsOnly()
//! load issues that has preclips
//! \see loadFilteredPublication()
//! \author elzubeir
void loadIssuesWithPreclipsOnly();
void loadUndoneIssuesOnly();
//! \fn loadFilteredIssues();
//! load issues that are filtered based on the filter criteria
//! \see loadIssuesWithPreclipsOnly()
//! \author elzubeir
void loadFilteredIssues();
//! \fn loadClippingImages()
//! loads clipping images for a particular image, it loads images from file server or ftp server
//! \param[in] clipid int article id
//! \see saveClipImagesToFileServer(), saveClipImagesToFtpServer()
//! \author elzubeir
void loadClippingImages(int clipid);
//! \fn cancelModifyPreclip()
//! cancel modification of preclip
//! \see setModifyPreclipButton()
//! \author elzubeir
void cancelModifyPreclip();
//! \fn orderCutoutsSelections()
//! starts the ordering of image cutouts
//! \author elzubeir
void orderCutoutsSelections();
//! \fn saveClipImagesToFtpServerWatcherFinished();
//! this is called when the saveClipImagesToFtpServer() function is finished
//! \author elzubeir
void saveClipImagesToFtpServerWatcherFinished();
//! \fn saveClipImagesToFileServerWatcherFinished();
//! this is called when the saveClipImagesToFileServer() function is finished
//! \author elzubeir
void saveClipImagesToFileServerWatcherFinished();
//! \fn addTextToClipWatcherFinished()
//! this is called when the addTextToClip() function is finished
//! \author elzubeir
void addTextToClipWatcherFinished();
//! \fn updateSectionPagesStatus()
//! updates the current section's pages status
//! \author elzubeir
void updateSectionPagesStatus();
//! \fn filterPublications()
//! filter the publications
//! \author elzubeir
void filterPublications();
//! \fn pauseTracking()
//! pause Tracking
//! \author elzubeir
void pauseTracking();
void updateTrackLabel();
int publicationIssueId(int id_publication, QString issue_date);
int issueSectionsId(int id_publication_issue, int id_section);
void addRelatedKeywordsToTag(QList<TagCoordinates> &tagH);
void onAppFocusChanged();
private:
//! pointer to the Qt desginer UI class object
Ui::ClippingStation *ui;
//! Databases object
QSqlDatabase m_masterDatabase;
QSqlDatabase m_slaveDatabase;
static QSqlDatabase m_ocrDatabase;
static QSqlDatabase m_clipDatabase;
//@{
//! master database connection string
//! master database host name
QString m_masterDatabaseHost;
//! master database name
QString m_masterDatabaseName;
//! master database username
QString m_masterDatabaseUser;
//! master database password
QString m_masterDatabasePassword;
//! master database port number
int m_masterDatabasePort;
//! slave database host name
QString m_slaveDatabaseHost;
//! slave database connection string
//! slave database name
QString m_slaveDatabaseName;
//! slave database username
QString m_slaveDatabaseUser;
//! slave database password
QString m_slaveDatabasePassword;
//! slave database port number
int m_slaveDatabasePort;
//! ocr database host name
QString m_ocrDatabaseHost;
//! ocr database name
QString m_ocrDatabaseName;
//! ocr database username
QString m_ocrDatabaseUser;
//! ocr database password
QString m_ocrDatabasePassword;
//! ocr database port number
int m_ocrDatabasePort;
//@}
//! use ftp for uploading or not
bool m_useFtp;
//! ftp server address
static QString m_address;
//! ftp username
static QString m_username;
//! ftp password
static QString m_password;
//! ftp port
static int m_port;
//! object of the User class, used for authentication, checking the roles, ..etc
User m_user;
//! hash object to hold name/id values for publications
QHash<QString, int> m_publicationHash;
//! hash object to hold name/id values for countries
QHash<QString, int> m_countriesHash;
//! publication object of the current opened publication
Publication m_publication;
//! tags wrapper object
TagsWrapper m_tagsWrapper;
//! current selected issue
QString m_currentIssueDate;
//! current selected section
QString m_currentSectionName;
//! list of images of current issue in local directory
QStringList m_localImagesList;
//! list of images of current issue in remote directory
QStringList m_remoteImagesList;
//! list of images of current preclipped article images in local directory
QStringList m_preclippedLocalImagesList;
//! list of images of current preclipped article images in remote directory
QStringList m_preclippedRemoteImagesList;
//! list of images of current clipped article images in local directory
QStringList m_clippedLocalImagesList;
//! list of images of current clipped article images in remote directory
QStringList m_clippedRemoteImagesList;
//! index of current selected image
int m_imageIndex;
//! index of current selected preclip image
int m_clippedImageIndex;
//! index of current selected clip image
int m_preclippedImageIndex;
//! index of current selected image model
QModelIndex m_imageModelIndex;
//! index of current selected preclip image model
QModelIndex m_clippedImageModelIndex;
//! index of current selected clip image model
QModelIndex m_preclippedImageModelIndex;
//! ImageCachingDialog object for caching images from file/ftp server
ImageCachingDialog m_imageCachingDialog;
//! hash object for holding image names and their caching status
QHash<QString, bool> m_cachedImages;
//! cache directory for the application
static QString m_cacheDir;
//! name of the first page in the clip, needed for the thumbnail creation
QString m_firstPageInClip;
//! current scale for the A4 page
qreal m_currentA4Scale;
//! running mode for the full page view
RUNNING_MODE m_runningMode;
//! filter mode for the publication view
FILTER_MODE m_filterMode;
//! current preclip id number
int m_currentPreclipId;
//! current clip id number
int m_currentClipId;
//! a context menu for the preclipped articles, to modify and delete
QMenu *m_preclipContextMenu;
//! a context menu for the clipped articles, to view text
QMenu *m_clipContextMenu;
//! a context menu for issue, to re-send to OCR engine
QMenu *m_issueContextMenu;
//! a context menu for the issue pages, to re-send to OCR engine
QMenu *m_issuePageContextMenu;
QMenu *m_keywordsContextMenu;
//! object to monitor the saveClipImagesToFtpServer future object
QFutureWatcher<bool> m_saveClipImagesToFtpServerWatcher;
//! object to monitor the saveClipImagesToFileServer future object
QFutureWatcher<int> m_saveClipImagesToFileServerWatcher;
QFutureWatcher<bool> m_addTextToClipWatcher;
//! string to hold the error message returned by the ftp server for uploading the clipped images
static QString saveClipImagesToFtpServerErrorMsg;
//! image to hold the thumbnail
static QImage m_thumbnail;
//! the search dialog list
SearchPublicationListDialog m_searchPublicationsDlg;
//! string for the clip shortcut
QString m_clipShortcut;
//! string for the preclip shortcut
QString m_preclipShortcut;
//! string for the add page shortcut
QString m_addPageShortcut;
//! string for the next page shortcut
QString m_nextPageShortcut;
//! string for the previous page shortcut
QString m_previousPageShortcut;
//! string for the debug mode (on/off)
QString m_debug;
QString m_preclip;
bool m_isPaused;
QTimer m_trackingTimer;
int m_trackingSeconds;
int m_currentPageId;
int m_maxTimeLimit;
};
#endif // CLIPPINGSTATION_H
File diff suppressed because it is too large Load Diff
+38
View File
@@ -0,0 +1,38 @@
[master database]
server=localhost ;url for the database
port=3306
database=socialhose
uid=root
pwd=aq19911
[slave database]
server=localhost ;url for the database
port=3306
database=socialhose
uid=root
pwd=aq19911
[ocr database]
server=localhost ;url for the database
port=3306
database=socialhose
uid=root
pwd=aq19911
[ftp access]
useftp=0 ;if set to 0, then no ftp will be used, otherwise, ftp upload is the default
server=localhost
port=21
username=aa
password=aq19911
[shortcuts]
Clip=Ctrl+S
Preclip=Ctrl+D
AddPage=Ctrl+A
NextPage=Ctrl+E
PreviousPage=Ctrl+W
[debug mode]
debug=on
+91
View File
@@ -0,0 +1,91 @@
/************************************************************************
* $Id: constants.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/constants.h $
*
************************************************************************/
#ifndef CONSTANTS_H
#define CONSTANTS_H
// version
#define VERSION_NUMBER 0.5
// zoom factor
#define ZOOM_FACTOR 0.25
// zoom limits
#define MIN_SCALE 0.0625
#define MAX_SCALE 16.0
// values are in inch
#define A4_WIDTH 8.27
#define A4_HEIGHT 11.69
#define DPI 96.0
#define FULLPAGE_MIN_WIDTH 8.27
#define FULLPAGE_MIN_HEIGHT 11.69
enum PAGE_LAYOUT
{
ACTUAL_SIZE = 0,
WIDTH_FIT,
BEST_FIT
};
enum SELECTION_AREA_TYPE
{
IMAGE = 0,
TITLE,
BODY
};
enum SELECTION_MODE
{
SELECT = 0,
VIEW,
ORDER
};
enum RUNNING_MODE
{
NORMAL_MODE = 0,
PRECLIPPING_MODE,
CLIPPING_MODE
};
enum FILTER_MODE
{
NO_FILTER =0,
PRECLIPSONLY_FILTER
};
#define AVEDIALOG_ROW_COUNT 4
#define AVEDIALOG_COLUMN_COUNT 4
#define NEWSPAPER 1
#define MAGAZINE 2
#define NEWSPAPER_COLUMN_WIDTH 5.0
#define THUMBNAIL_WIDTH 70
#define JPG_SAVE_QUALITY 85
#define HIGH_RES_IMAGE_DIR "300dpi/"
//update the page status every 7.5 seconds
#define PAGE_STATUS_TIMERS 7.5*1000
#endif // CONSTANTS_H
+48
View File
@@ -0,0 +1,48 @@
/************************************************************************
* $Id: coordinates.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/coordinates.cpp $
*
************************************************************************/
#include "coordinates.h"
Coordinates::Coordinates(int top, int left, int bottom, int right)
{
m_top = top;
m_left = left;
m_bottom= bottom;
m_right = right;
}
int Coordinates::top()
{
return m_top;
}
int Coordinates::left()
{
return m_left;
}
int Coordinates::bottom()
{
return m_bottom;
}
int Coordinates::right()
{
return m_right;
}
+72
View File
@@ -0,0 +1,72 @@
/************************************************************************
* $Id: coordinates.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/coordinates.h $
*
************************************************************************/
#ifndef COORDINATES_H
#define COORDINATES_H
//! \class Coordinates
//! a coordinates class to hold coordinates in format of (top/left) (bottom/right)
class Coordinates
{
public:
//! \fn Coordinates()
//! default constructor
//! \param[in] top: top value of coordinate
//! \param[in] left: left value of coordinate
//! \param[in] bottom: bottom value of coordinate
//! \param[in] right: right value of coordinate
//! \author elzubeir
Coordinates(int top, int left, int bottom, int right);
//! \fn top()
//! return the top of the coordinates
//! \author elzubeir
int top();
//! \fn left()
//! return the left of the coordinates
//! \author elzubeir
int left();
//! \fn bottom()
//! return the bottom of the coordinates
//! \author elzubeir
int bottom();
//! \fn right()
//! return the right of the coordinates
//! \author elzubeir
int right();
private:
//! int of top value of coordinate
int m_top;
//! int of left value of coordinate
int m_left;
//! int of bottom value of coordinate
int m_bottom;
//! int of right value of coordinate
int m_right;
};
#endif // COORDINATES_H
+44
View File
@@ -0,0 +1,44 @@
/************************************************************************
* $Id$
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date$
* $Author$
* $Revision$
* $HeadURL$
*
************************************************************************/
#include "digitalclock.h"
#include <cstdio>
using namespace std;
DigitalClock::DigitalClock(QWidget *parent) :
QLCDNumber(parent)
{
QPalette palette = this->palette();
palette.setColor(QPalette::WindowText, Qt::darkGreen);
setPalette(palette);
setSegmentStyle(Filled);
display("00:00");
}
void DigitalClock::showTime(int seconds)
{
int min = seconds/60;
int sec = seconds - (min*60);
char frmt[10];
sprintf(frmt, "%02i:%02i", min, sec);
QString text(frmt);
display(text);
}
+33
View File
@@ -0,0 +1,33 @@
/************************************************************************
* $Id$
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date$
* $Author$
* $Revision$
* $HeadURL$
*
************************************************************************/
#ifndef DIGITALCLOCK_H
#define DIGITALCLOCK_H
#include <QLCDNumber>
class DigitalClock : public QLCDNumber
{
Q_OBJECT
public:
explicit DigitalClock(QWidget *parent = 0);
void showTime(int seconds);
};
#endif // DIGITALCLOCK_H
+181
View File
@@ -0,0 +1,181 @@
/************************************************************************
* $Id: drawerscene.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/drawerscene.cpp $
*
************************************************************************/
#include "drawerscene.h"
#include <QGraphicsSceneDragDropEvent>
#include <QMimeData>
#include <QGraphicsPixmapItem>
#include <QPainter>
#include <QPrinter>
#include <QImage>
#include <QApplication>
#include <QDesktopWidget>
#include "constants.h"
DrawerScene::DrawerScene(bool isfirst, QObject * parent):
QGraphicsScene(parent)
{
setBackgroundBrush(Qt::gray);
// by now this is A4 format, so we set the scene Rect with a A4 geometry + margins borders (30 pix).
createPageItem("A4", isfirst);
if (m_pageItem)
setSceneRect(-10.0, -10.0, m_pageItem->boundingRect().width()+20.0, m_pageItem->boundingRect().height()+20.0);
m_timer = new QTimer(); //create a timer and connect it's timeout signal to the update slot
connect( m_timer, SIGNAL( timeout() ), this, SLOT( thumbnail() ) );
}
DrawerScene::~DrawerScene()
{
//qDebug("~DrawerScene()");
if(m_pageItem)
{
delete m_pageItem;
m_pageItem = 0;
}
if(m_timer)
{
if (m_timer->isActive())
m_timer->stop();
delete m_timer;
m_timer = 0;
}
}
void DrawerScene::dropEvent(QGraphicsSceneDragDropEvent * event)
{
//event->ignore();
QGraphicsScene::dropEvent(event);
//qDebug() << "emit signal";
//emit createThumbnail();
m_timer->start(100);
}
bool DrawerScene::createPageItem(const QString & paperFormat, bool isfirst)
{
// format is useless by now
m_pageItem = new PageItem(paperFormat, isfirst);
addItem(m_pageItem);
return true;
}
QImage DrawerScene::screenShot()
{
//first we hide the margins
m_pageItem->hideMargins();
m_pageItem->unselectItems();
int dpi = QApplication::desktop()->logicalDpiX();
int w = static_cast<int> (dpi * A4_WIDTH);
int h = static_cast<int> (dpi * A4_HEIGHT);
//int w = 827;
//int h = 1169;
QImage image(w, h, QImage::Format_RGB32);
QPainter painter(&image);
setBackgroundBrush(Qt::white);
painter.setBackgroundMode(Qt::TransparentMode);
painter.setBackground(Qt::white);
painter.setRenderHint(QPainter::HighQualityAntialiasing);
//QRect rec = m_pageItem->boundingRect().toRect();
//rec.setX(rec.x() - 20);
//rec.setY(rec.y() - 20);
//rec.setX(rec.x()-20);
//rec.setWidth(rec.width()-20);
QPoint bottomright = m_pageItem->boundingRect().toRect().bottomRight();
bottomright.setX(bottomright.x()+1);
bottomright.setY(bottomright.y()+1);
QRect rec(QPoint(-1, -1), bottomright);
//this->render(&painter, m_pageItem->boundingRect().toRect(), m_pageItem->boundingRect().toRect() );
this->render(&painter, rec, m_pageItem->boundingRect().toRect());
setBackgroundBrush(Qt::gray);
m_pageItem->hideMargins(false);
return image;
}
void DrawerScene::addThumbnail(QImage &img)
{
m_pageItem->addThumbnail(img);
}
void DrawerScene::addCutout(QImage &img, QPointF &pos, qreal scale)
{
m_pageItem->addCutout(img, pos, scale);
}
void DrawerScene::transform(qreal zoomFactor)
{
if (!m_pageItem)
return;
m_zoomfactor = zoomFactor;
// we compute image center.
qreal imageCenterX = m_pageItem->x()+ m_pageItem->boundingRect().width()/2;
qreal imageCenterY = m_pageItem->y()+ m_pageItem->boundingRect().height()/2;
qreal imageX, imageY;
imageX = m_pageItem->boundingRect().width()/2;
imageY = m_pageItem->boundingRect().height()/2;
//m_pageItem->setTransformationMode(Qt::SmoothTransformation);
m_pageItem->setTransform(QTransform().translate(imageCenterX, imageCenterY).scale(zoomFactor, zoomFactor).translate(-imageCenterX, -imageCenterY));
//qDebug("Zoom Factor %.2d", zoomFactor);
}
void DrawerScene::thumbnail()
{
emit createThumbnail();
m_timer->stop();
}
void DrawerScene::setPixmap(const QPixmap &pix) const
{
m_pageItem->setPixmap(pix);
}
int DrawerScene::cutoutsCount()
{
return m_pageItem->cutoutsCount();
}
QRectF DrawerScene::centerCutouts(bool isArabic)
{
return m_pageItem->centerCutouts(isArabic);
}
+140
View File
@@ -0,0 +1,140 @@
/************************************************************************
* $Id: drawerscene.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/drawerscene.h $
*
************************************************************************/
#ifndef DESTINATION_SCENE_H
#define DESTINATION_SCENE_H
#include <QGraphicsScene>
#include <QImage>
#include <QTimer>
#include "pageitem.h"
#include "globalfunctions.h"
//! \brief Destination scene.
//! Scene for the left panel part.
//! Each scene holds a page item.
class DrawerScene : public QGraphicsScene
{
Q_OBJECT
public:
//! \fn DrawerScene()
//! default constructor
//! \param[in] isfirst boolean showing if the page on the scen is the first page or not
//! \param[in] parent QObject pointer to the parent
//! \author elzubeir
DrawerScene(bool isfirst, QObject * parent);
//! \fn ~DrawerScene()
//! destructor
//! \author elzubeir
virtual ~DrawerScene();
//! \fn screenShot()
//! Take a screenshot of the A4 page on the scene
//! \return QImage represents the screenshot taken for the A4 page
//! \author elzubeir
QImage screenShot();
//! \fn addThumbnail()
//! Adds a thumbnail image to the A4 page, it adds the thumbnail on th top right corner of the page
//! \param[in] img QImage holding the thumbnail image to be added
//! \author elzubeir
void addThumbnail(QImage &img);
//! \fn addCutout()
//! Adds an image cutout to the A4 page, it adds based on the pos passed and scaled to scale, this function is used when auto-arrange is used
//! \param[in] img QImage holding the cutout image to be added
//! \param[in] pos position of A4 page where the cutout to be added
//! \param[in] scale qreal value to represent the scale of image
//! \author elzubeir
void addCutout(QImage &img, QPointF &pos, qreal scale);
//! \fn transform()
//! set the items transformation martix based on the zoomFactor
//! \param[in] zoomFactor qreal representing the zoom factor for the item
//! \author elzubeir
void transform(qreal zoomFactor);
//! \fn setPixmap()
//! Set a pixmap image to A4 page, this function is called when viewing clipped A4 images
//! \param[in] pix QPixmap representing the A4 clipped image to be shown
//! \author elzubeir
void setPixmap(const QPixmap &pix) const;
//! \fn cutoutsCount()
//! Returns the number of image cutouts on the A4 page, the count does not include the thumbnail item
//! nor the page margin items
//! \return int number of image cutouts
//! \author elzubeir
int cutoutsCount();
//! \fn centerCutouts()
//! center the cutouts in the drawer
//! \param[in] is this an arabic cutout of not
//! \returns a rectangle holding the centered cutouts
//! \author elzubeir
QRectF centerCutouts(bool isArabic);
protected:
//! \fn dropEvent()
//! Drag n' drop event for the view framework
//! \param[in] event the event for drag n' drop in grahpics view
//! \author elzubeir
virtual void dropEvent(QGraphicsSceneDragDropEvent * event);
signals:
//! \fn createThumbnail()
//! This signal is emitted to create the thumbnail of the page on the left pane view,
//! the signal is emitted ONLY if this scene contains the first A4 page.
//! \author elzubeir
void createThumbnail();
private slots:
//! \fn thumbnail()
//! The slot is called when timeout signal is emitted from the time, its used to signal
//! the main application to create the thumbnail of the left pane view
//! \author elzubeir
void thumbnail();
private:
//! \fn createPageItem()
//! Creates the A4 page item for the scene
//! \param[in] paperFormat string representing the image format, currently we only support A4 images
//! \param[in] isfirst boolean showing if this A4 page is the first page on the scene
//! \return bool
//! true if page is created successfully
//! false otherwise
//! \author elzubeir
bool createPageItem(const QString & paperFormat, bool isfirst);
private:
//! The A4 page item
PageItem * m_pageItem;
//! qreal value represents the zoom factor
qreal m_zoomfactor;
//! Timer object to do GUI updates, and check status of operations
QTimer * m_timer;
};
#endif // DESTINATION_SCENE_H
+218
View File
@@ -0,0 +1,218 @@
/************************************************************************
* $Id: drawerview.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/drawerview.cpp $
*
************************************************************************/
#include "drawerview.h"
#include <QWheelEvent>
#include "drawerscene.h"
#include "constants.h"
DrawerView::DrawerView(bool isfirst, QWidget * parent) :
QGraphicsView(parent),
m_pageLayout(ACTUAL_SIZE),
m_scale(1.0)
{
//qDebug("DrawerView()");
m_scene = new DrawerScene(isfirst, this);
setScene(m_scene);
connect(m_scene, SIGNAL(createThumbnail()), this, SIGNAL(createThumbnail()));
//setPageLayout(m_pageLayout);
setAcceptDrops(true);
}
DrawerView::~DrawerView()
{
//qDebug("~DrawerView()");
// if (m_scene)
// delete m_scene;
// m_scene = 0;
}
QImage DrawerView::screenShot()
{
qreal scale = actualSize();
return m_scene->screenShot();
setScale(scale);
}
void DrawerView::addThumbnail(QImage &img)
{
m_scene->addThumbnail(img);
}
void DrawerView::addCutout(QImage &img, QPointF &pos, qreal scale)
{
m_scene->addCutout(img, pos, scale);
}
qreal DrawerView::zoom(bool zoomin)
{
m_pageLayout = ACTUAL_SIZE; //
qreal oldscale = m_scale;
qreal sc = ::pow(2, zoomin? ZOOM_FACTOR : -ZOOM_FACTOR);
m_scale *= sc;
m_scale = qMin(m_scale, MAX_SCALE);
m_scale = qMax(m_scale, MIN_SCALE);
if (m_scale >= 1.0)
m_scale = 1.0;
if (m_scale >= MIN_SCALE && m_scale <= 1)
{
m_scene->transform(m_scale);
//m_clippingStation->displayZoomStatus(m_scale);
m_scene->setSceneRect(m_scene->itemsBoundingRect() );
this->setSceneRect(m_scene->itemsBoundingRect() );
}
if(oldscale >= 1.0)
return 1.0;
return oldscale;
}
qreal DrawerView::actualSize()
{
qreal oldscale = m_scale;
m_scale = 1.0;
m_scene->transform(m_scale);
m_scene->setSceneRect(m_scene->itemsBoundingRect() );
this->setSceneRect(m_scene->itemsBoundingRect() );
return oldscale;
}
void DrawerView::resizeEvent(QResizeEvent* event)
{
//*
if( m_pageLayout != ACTUAL_SIZE )
{
actualSize(); //just reset the page to default
qreal w = rect().width();
qreal h = rect().height();
qreal sceneWidth = m_scene->itemsBoundingRect().width();
qreal sceneHeight = m_scene->itemsBoundingRect().height();
//calculate the ratio
qreal precW = w/sceneWidth;
qreal precH = h/sceneHeight;
qreal prec = precW;
if (m_pageLayout == BEST_FIT)
prec = qMin(precW, precH);
//calculate the ratio
m_scale = prec;
if( m_scale > 1.0 )
m_scale = 1.0;
}
//to show the scroll bar as page changes
//qDebug("Scale from resizeEvent %.2f", m_scale);
m_scene->transform(m_scale);
m_scene->setSceneRect(m_scene->itemsBoundingRect() );
this->setSceneRect(m_scene->itemsBoundingRect() );
QGraphicsView::resizeEvent(event);
}
void DrawerView::setPageLayout(PAGE_LAYOUT layout)
{
m_pageLayout = layout;
if( m_pageLayout != ACTUAL_SIZE )
{
actualSize(); //just reset the page to default
//fitInView((QGraphicsItem*)m_scene->imageItem(), Qt::KeepAspectRatio);
qreal w = rect().width();
qreal h = rect().height();
qreal sceneWidth = m_scene->itemsBoundingRect().width();
qreal sceneHeight = m_scene->itemsBoundingRect().height();
//calculate the ratio
qreal precW = w/sceneWidth;
qreal precH = h/sceneHeight;
qreal prec = precW;
if (m_pageLayout == BEST_FIT)
prec = qMin(precW, precH);
//calculate the ratio
m_scale = prec;
if( m_scale > 1.0 )
m_scale = 1.0;
//qDebug("Scale from pageLayout %.2f", m_scale);
//this->setSceneRect(QRectF(QPoint(0, 0), QSize() ) );
}
m_scene->transform(m_scale);
m_scene->setSceneRect(m_scene->itemsBoundingRect() );
this->setSceneRect(m_scene->itemsBoundingRect() );
}
qreal DrawerView::currentScale()
{
return m_scale;
}
void DrawerView::setScale(qreal scale)
{
m_scale = scale;
//m_pageLayout = ACTUAL_SIZE;
m_scene->transform(m_scale);
m_scene->setSceneRect(m_scene->itemsBoundingRect() );
this->setSceneRect(m_scene->itemsBoundingRect() );
}
void DrawerView::setPixmap(const QPixmap &pix) const
{
m_scene->setPixmap(pix);
}
int DrawerView::cutoutsCount()
{
return m_scene->cutoutsCount();
}
QRectF DrawerView::centerCutouts(bool isArabic)
{
return m_scene->centerCutouts(isArabic);
}
+150
View File
@@ -0,0 +1,150 @@
/************************************************************************
* $Id: drawerview.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/drawerview.h $
*
************************************************************************/
#ifndef DRAWER_VIEW_H
#define DRAWER_VIEW_H
#include <QGraphicsView>
#include "globalfunctions.h"
#include "drawerscene.h"
#include "constants.h"
//! Destination View. Holds the scene.
class DrawerView : public QGraphicsView
{
Q_OBJECT
public:
//! \fn DrawerView()
//! default constructor
//! \param[in] isfirst boolean showing if the page on the scen is the first page or not
//! \param[in] parent QObject pointer to the parent
//! \author elzubeir
DrawerView(bool isfirst, QWidget * parent);
//! \fn ~DrawerView()
//! destructor
//! \author elzubeir
virtual ~DrawerView();
//! \fn screenShot()
//! Take a screenshot of the A4 page on the scene
//! \return QImage represents the screenshot taken for the A4 page
//! \author elzubeir
QImage screenShot();
//! \fn scene()
//! This function returns the DrawerScene object associated with this view
//! \return DrawerScene* pointer represents associated scene to this view
//! \author elzubeir
DrawerScene* scene() { return m_scene;}
//! \fn addThumbnail()
//! Adds a thumbnail image to the DrawerScene's A4 page, it adds the thumbnail on th top right corner of the page
//! \param[in] img QImage holding the thumbnail image to be added
//! \author elzubeir
void addThumbnail(QImage &img);
//! \fn addCutout()
//! Adds an image cutout to the DrawerScene's A4 page, it adds based on the
//! pos passed and scaled to scale, this function is used when auto-arrange is used
//! \param[in] img QImage holding the cutout image to be added
//! \param[in] pos position of A4 page where the cutout to be added
//! \param[in] scale qreal value to represent the scale of image
//! \author elzubeir
void addCutout(QImage &img, QPointF &pos, qreal scale);
//! \fn zoom()
//! zoom in/out the current view
//! \param[in] isIn boolean if true, it zooms in, false zooms out
//! \return qreal value holding the old scale value
//! \author elzubeir
qreal zoom(bool isIn);
//! \fn actualSize()
//! Retusn the actual size of the view, scalled to 100%
//! \return qreal value holding the old scale value
//! \author elzubeir
qreal actualSize();
//! \fn currentScale()
//! Retusn the current scale factor
//! \return qreal value holding the current scale value
//! \author elzubeir
qreal currentScale();
//! \fn setPageLayout(
//! Set the current layout for the page, we currently support 3 layouts ACTUAL_SIZE, WIDTH_FIT, BEST_FIT
//! \param[in] layout PAGE_LAYOUT value
//! \author elzubeir
void setPageLayout(PAGE_LAYOUT layout);
//! \fn setScale()
//! Sets the current scale factor
//! \param[in] qreal value holding the current scale value
//! \author elzubeir
void setScale(qreal scale);
//! \fn setPixmap()
//! Set a pixmap image to DrawerScene's A4 page, this function is called when viewing clipped A4 images
//! \param[in] pix QPixmap representing the A4 clipped image to be shown
//! \author elzubeir
void setPixmap(const QPixmap &pix) const;
//! \fn cutoutsCount()
//! Returns the number of image cutouts on the DrawerScene's A4 page, the count does not include the thumbnail item
//! nor the page margin items
//! \return int number of image cutouts
//! \author elzubeir
int cutoutsCount();
//! \fn centerCutouts()
//! center the cutouts in the drawer
//! \param[in] is this an arabic cutout of not
//! \returns a rectangle holding the centered cutouts
//! \author elzubeir
QRectF centerCutouts(bool isArabic);
protected:
//! \fn resizeEvent()
//! resize the view's viewport
//! \param[in] event QResizeEvent* event's paramter for resizing
//! \author elzubeir
void resizeEvent(QResizeEvent* event);
signals:
//! \fn createThumbnail()
//! This signal is emitted to create the thumbnail of the page on the left pane view,
//! the signal is emitted ONLY if this DrawerScene's scene contains the first A4 page. the signal is propogated to the main window
//! \author elzubeir
void createThumbnail();
private:
//! The view's scene
DrawerScene * m_scene;
//! The current page layout
PAGE_LAYOUT m_pageLayout;
//! the current scale
qreal m_scale;
};
#endif // DRAWER_VIEW_H
@@ -0,0 +1,31 @@
/************************************************************************
* $Id: drawerviewstackedwidget.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/drawerviewstackedwidget.cpp $
*
************************************************************************/
#include "drawerviewstackedwidget.h"
DrawerViewStackedWidget::DrawerViewStackedWidget(QWidget * parent) :
QStackedWidget(parent)
{
}
DrawerViewStackedWidget::~DrawerViewStackedWidget()
{
qDebug("~DrawerViewStackedWidget()");
}
+43
View File
@@ -0,0 +1,43 @@
/************************************************************************
* $Id: drawerviewstackedwidget.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/drawerviewstackedwidget.h $
*
************************************************************************/
#ifndef DRAWER_VIEW_STACKED_WIDGET_H
#define DRAWER_VIEW_STACKED_WIDGET_H
#include <QStackedWidget>
/**
\brief Stack widget that contains all Destination View.
Manages the display of each graphics view.
*/
class DrawerViewStackedWidget : public QStackedWidget
{
public:
//! \fn DrawerViewStackedWidget()
//! default const
//! \param[in] parent of the calling widget
//! \author elzubeir
DrawerViewStackedWidget(QWidget * parent = 0); //ctor
//! \fn ~DrawerViewStackedWidget()
//! destructor
//! \author elzubeir
virtual ~DrawerViewStackedWidget(); //dtor
};
#endif // DRAWER_VIEW_STACKED_WIDGET_H
+311
View File
@@ -0,0 +1,311 @@
/************************************************************************
* $Id: droppeditem.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/droppeditem.cpp $
*
************************************************************************/
#include "droppeditem.h"
#include "pageitem.h"
#include <QKeyEvent>
#include <QtDebug>
#include <QTime>
#include <QGraphicsScene>
#include <QMessageBox>
#include <QPainter>
DroppedItem::DroppedItem(const QPixmap & pixmap, const QPointF & scenePos, qreal perc, QGraphicsItem * parent /*=0*/) :
QGraphicsPixmapItem(pixmap, parent),
m_originalPixmap(pixmap),
m_imageWidth(m_originalPixmap.width())
{
// set position with scene position.
setPos(scenePos);
setZValue(0.9);
// make the item selectable, movable & focusable
setFlag(QGraphicsItem::ItemIsSelectable, true);
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemIsFocusable,true);
m_pageItem = static_cast<PageItem*> (parentItem());
//setPixmap(m_originalPixmap);
m_zoomDlg = new DroppedItemZoomDialog(this, 0);
m_zoomDlg->setValue(static_cast<int>(perc*100));
setPixmap(m_originalPixmap);
//qreal w = m_currentValue/100.0;
//setTransformationMode(Qt::SmoothTransformation);
//setTransform(QTransform().scale(w, w));
m_originalImage = m_originalPixmap.toImage();
}
DroppedItem::~DroppedItem()
{
qDebug("~DroppedItem()");
//if (m_pageItem)
//{
// delete m_pageItem;
// m_pageItem = 0;
//}
if(m_zoomDlg)
{
delete m_zoomDlg;
m_zoomDlg = 0;
}
}
int DroppedItem::type() const
{
return Type;
}
void DroppedItem::keyPressEvent(QKeyEvent * event)
{
if (event->key() == Qt::Key_Delete && isSelected())
{
// remove item when key press event is Suppr.
scene()->removeItem(this);
return;
}
else if(event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_Minus )
{
m_currentValue -= 5;
zoom(m_currentValue);
}
else if(event->modifiers() == Qt::AltModifier && event->key() == Qt::Key_Minus )
{
m_currentValue -= 1;
zoom(m_currentValue);
}
else if(event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_Equal )
{
m_currentValue += 5;
zoom(m_currentValue);
}
else if(event->modifiers() == Qt::AltModifier && event->key() == Qt::Key_Equal )
{
m_currentValue += 1;
zoom(m_currentValue);
}
else if(event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_0 )
{
zoom(100); //restore to 100%
}
else if(event->key() == Qt::Key_Left)
{
qreal x = this->pos().x();
this->setPos(x-5, pos().y());
//return;
}
else if(event->key() == Qt::Key_Right)
{
qreal x = this->pos().x();
this->setPos(x+5, pos().y());
//return;
}
else if(event->key() == Qt::Key_Up)
{
qreal y = this->pos().y();
this->setPos(pos().x(), y-5);
//return;
}
else if(event->key() == Qt::Key_Down)
{
qreal y = this->pos().y();
this->setPos(pos().x(), y+5);
//return;
}
else
{
//check if the new position is within the boundary of the page
QGraphicsPixmapItem::keyPressEvent(event);
}
checkBoundary( pos().x(), pos().y() );
}
void DroppedItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{
m_zoomDlg->setValue(m_currentValue);
m_zoomDlg->exec();
}
void DroppedItem::zoom(int value)
{
m_currentValue = value;
//update(this->boundingRect().toRect());
prepareGeometryChange();
}
void DroppedItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() != Qt::LeftButton)
{
event->ignore();
return;
}
checkBoundary(event->pos().toPoint(), true);
if(m_tweakingpart != "")
m_tweaking = true;
QGraphicsPixmapItem::mousePressEvent(event);
}
void DroppedItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if(m_tweaking)
{
QPoint pt = event->pos().toPoint();
m_rectangle = this->boundingRect().toRect();
qreal value = 1.0;
/*
if ( m_tweakingpart == "topLeft" ) m_rectangle . setTopLeft ( pt ) ;
else if ( m_tweakingpart == "topRight" ) m_rectangle . setTopRight ( pt ) ;
else if ( m_tweakingpart == "bottomLeft" ) m_rectangle . setBottomLeft ( pt ) ;
else if ( m_tweakingpart == "bottomRight" ) m_rectangle . setBottomRight ( pt ) ;
else if ( m_tweakingpart == "top" ) m_rectangle . setTop ( pt . y () ) ;
else
*/
/*else if ( m_tweakingpart == "left" ) m_rectangle . setLeft ( pt . x () ) ;*/
if ( m_tweakingpart == "bottomRight" ) { m_rectangle . setBottomRight ( pt ) ; value = static_cast<qreal> (m_rectangle.height() / (m_originalPixmap.height()*1.0) );}
else if ( m_tweakingpart == "bottom" ) { m_rectangle . setBottom ( pt . y () ) ; value = static_cast<qreal> (m_rectangle.height() / (m_originalPixmap.height()*1.0) );}
else if ( m_tweakingpart == "right" ) { m_rectangle . setRight ( pt . x () ) ; value = static_cast<qreal> (m_rectangle.width() / (m_originalPixmap.width() *1.0) );}
zoom(value*100);
}
else
{
QGraphicsPixmapItem::mouseMoveEvent(event);
}
}
void DroppedItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
m_tweaking = false ;
m_tweakingpart = "" ;
setCursor(QCursor(Qt::OpenHandCursor));
//QPointF pt = mapToScene(pos().x(), pos().y());
//pt = mapToItem(m_pageItem, pt);
QPointF pt = pos();
//pt.setX(pt.x() * m_currentValue/100.0);
//pt.setX(pt.y() * m_currentValue/100.0);
checkBoundary(pt.x(), pt.y());
QGraphicsPixmapItem::mouseReleaseEvent(event);
//setPixmap(m_originalPixmap);
}
void DroppedItem::checkBoundary(qreal x, qreal y)
{
//*
qreal w, h;
QPolygonF rec = mapToItem(m_pageItem, boundingRect());
w = rec.boundingRect().width();
h = rec.boundingRect().height();
if ( y < m_pageItem->margin().top())
y = m_pageItem->margin().top();
if ( x < m_pageItem->margin().left() )
x = m_pageItem->margin().left();
if ( x+w > (m_pageItem->width() - m_pageItem->margin().right()) )
x = m_pageItem->width() - m_pageItem->margin().right() - w;
if ( y+h > (m_pageItem->height() - m_pageItem->margin().bottom()) )
y = m_pageItem->height() - m_pageItem->margin().bottom() - h;
setPos(x, y);
}
void DroppedItem::checkBoundary(QPoint pt, bool t)
{
m_rectangle = this->boundingRect().toRect();
if ( m_rectangle.isValid() )
{
QPoint m_tl = m_rectangle.topLeft();
QPoint m_tr = m_rectangle.topRight();
QPoint m_bl = m_rectangle.bottomLeft();
QPoint m_br = m_rectangle.bottomRight();
const QPoint off(20, 20), offx(20, -20), offy(-20, 20);
if( QRect( m_br-off, m_br+off).contains(pt) )
{
if (t)
m_tweakingpart = "bottomRight" ;
this->setCursor( Qt::SizeFDiagCursor );
}
else if( QRect( m_bl+offx, m_br-offx ).contains(pt) )
{
if (t)
m_tweakingpart = "bottom";
this->setCursor( Qt::SizeVerCursor ) ;
}
else if( QRect( m_tr+offy, m_br-offy ).contains(pt) )
{
if (t)
m_tweakingpart = "right";
this->setCursor( Qt::SizeHorCursor );
}
}
}
void DroppedItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->drawImage(boundingRect().toRect(),getScaledImage());
}
QRectF DroppedItem::boundingRect() const
{
qreal w = (m_currentValue/100.0) * m_originalPixmap.width();
qreal h = (m_currentValue/100.0) * m_originalPixmap.height();
return QRectF(QPointF(0,0), QPointF(w, h));
}
QImage DroppedItem::getScaledImage()
{
//QImage originalImage = m_originalPixmap.toImage();
qreal w = (m_currentValue/100.0) * m_originalPixmap.width();
qreal h = (m_currentValue/100.0) * m_originalPixmap.height();
QSizeF size(w, h);
QImage image(size.toSize(), QImage::Format_RGB888);
image = m_originalImage.scaledToWidth(w, Qt::SmoothTransformation);
return image;
}
+157
View File
@@ -0,0 +1,157 @@
/************************************************************************
* $Id: droppeditem.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/droppeditem.h $
*
************************************************************************/
#ifndef DROPPED_ITEM_H
#define DROPPED_ITEM_H
#include <QGraphicsPixmapItem>
#include <QGraphicsSceneMouseEvent>
/**
\brief Purpose of this class is to display the pixmap dropped on the page item.
*/
#include "droppeditemzoomdialog.h"
class PageItem;
class DroppedItemZoomDialog;
class DroppedItem : public QGraphicsPixmapItem
{
public:
enum { Type = UserType + 1 };
//! \fn DroppedItem()
//! constructor
//! \param[in] pixmap: containing the dropped image
//! \param[in] scenePos position of the image in the scene
//! \param[in] prec: precentage to the scale
//! \author elzubeir
DroppedItem(const QPixmap & pixmap, const QPointF & scenePos, qreal prec, QGraphicsItem * parent = 0); ///< ctor
//! \fn ~DroppedItem()
//! desctuctor
//! \author elzubeir
~DroppedItem();
//! \fn paint()
//! override the paints function
//! \author elzubeir
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
//! \fn boundingRect()
//! the bounding rectangle of the item
//! \returns the bounding rectangle of the item
//! \author elzubeir
QRectF boundingRect() const;
//! \fn type()
//! the type of the item
//! \returns the type of the item
//! \author elzubeir
int type() const;
protected:
//! \fn keyPressEvent()
//! overrides the keyPressEvent() function
//! \author elzubeir
virtual void keyPressEvent(QKeyEvent * event);
//! \fn mouseDoubleClickEvent()
//! overrides the function
//! \author elzubeir
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
//! \fn mousePressEvent()
//! overrides the function
//! \author elzubeir
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
//! \fn mouseMoveEvent()
//! overrides the function
//! \author elzubeir
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event);
//! \fn mouseReleaseEvent()
//! overrides the function
//! \author elzubeir
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
public:
//! \fn zoom()
//! zoom the item to a value
//! \param[in] value to zoom the item to.
//! \author elzubeir
void zoom(int value);
private:
//! \fn checkBoundary()
//! check if the point is on the item's boundaries
//! \param[in] point of the current point to check
//! \param[in] bool for tweaking part.
//! \author elzubeir
void checkBoundary(QPoint pt, bool t);
//! \fn checkBoundary()
//! check if the point (x,y) are on the boundary
//! \param[in] x: x value of the point
//! \param[in] y: y value of the point
//! \author elzubeir
void checkBoundary(qreal x, qreal y);
//! \fn getScaledImage()
//! get the image scaled
//! \returns scaled image
//! \author elzubeir
QImage getScaledImage();
private:
//! original pixmap
QPixmap m_originalPixmap;
//! image width
qreal m_imageWidth;
//! current value
int m_currentValue;
//! original image
QImage m_originalImage;
//! zoom dialog
DroppedItemZoomDialog *m_zoomDlg;
//! a4 page item
PageItem* m_pageItem;
//! should we do twaking
bool m_tweaking;
//! on what part we do weaking
QString m_tweakingpart ;
//! points for top/let, top/right, bottom/left, bottom/right
QPoint m_tl, m_tr, m_bl, m_br ;
//! rectangle of the current item
QRect m_rectangle;
};
#endif // DROPPED_ITEM_H
+57
View File
@@ -0,0 +1,57 @@
/************************************************************************
* $Id: droppeditemzoomdialog.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/droppeditemzoomdialog.cpp $
*
************************************************************************/
#include "droppeditemzoomdialog.h"
#include "ui_droppeditemzoomdialog.h"
DroppedItemZoomDialog::DroppedItemZoomDialog(DroppedItem *droppedItem, QWidget *parent) :
QDialog(parent),
m_ui(new Ui::DroppedItemZoomDialog),
m_droppedItem(droppedItem)
{
m_ui->setupUi(this);
}
DroppedItemZoomDialog::~DroppedItemZoomDialog()
{
delete m_ui;
}
void DroppedItemZoomDialog::changeEvent(QEvent *e)
{
QDialog::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
m_ui->retranslateUi(this);
break;
default:
break;
}
}
void DroppedItemZoomDialog::setValue(int i)
{
m_ui->zoomSlider->setValue(i);
}
void DroppedItemZoomDialog::zoom(int value)
{
m_droppedItem->zoom(value);
}
+72
View File
@@ -0,0 +1,72 @@
/************************************************************************
* $Id: droppeditemzoomdialog.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/droppeditemzoomdialog.h $
*
************************************************************************/
#ifndef DROPPEDITEMZOOMDIALOG_H
#define DROPPEDITEMZOOMDIALOG_H
#include <QtGui/QDialog>
#include "droppeditem.h"
namespace Ui {
class DroppedItemZoomDialog;
}
class DroppedItem;
class DroppedItemZoomDialog : public QDialog {
Q_OBJECT
public:
//! \fn DroppedItemZoomDialog()
//! constructor to zoom the dropped it in the drawer page
//! \param[in] dropped item pointer to the item in the drawer to be zoomed in/out
//! \author elzubeir
DroppedItemZoomDialog(DroppedItem *droppedItem, QWidget *parent = 0);
//! \fn ~DroppedItemZoomDialog()
//! destructor
//! \author elzubeir
~DroppedItemZoomDialog();
//! \fn setValue()
//! set the zoom value of the dialog
//! \param[in] value of the zooming
//! \author elzubeir
void setValue(int i);
protected:
void changeEvent(QEvent *e);
private slots:
//! \fn zoom()
//! do the zoom operation
//! \param[in] the value of zooming
//! \author elzubeir
void zoom(int);
private:
Ui::DroppedItemZoomDialog *m_ui;
//! dropped item pointer
DroppedItem *m_droppedItem;
};
#endif // DROPPEDITEMZOOMDIALOG_H
+274
View File
@@ -0,0 +1,274 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DroppedItemZoomDialog</class>
<widget class="QDialog" name="DroppedItemZoomDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>407</width>
<height>208</height>
</rect>
</property>
<property name="windowTitle">
<string>Zoom &amp; Rotate</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Zoom</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSlider" name="zoomSlider">
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<property name="maximum">
<number>300</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>10</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="zoomSpinBox">
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<property name="maximum">
<number>300</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Rotate</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSlider" name="rotateSlider">
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<property name="minimum">
<number>-179</number>
</property>
<property name="maximum">
<number>180</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>25</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="rotateSpinBox">
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<property name="minimum">
<number>-179</number>
</property>
<property name="maximum">
<number>180</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="2" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="3" 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>
<tabstops>
<tabstop>zoomSlider</tabstop>
<tabstop>zoomSpinBox</tabstop>
<tabstop>buttonBox</tabstop>
<tabstop>rotateSlider</tabstop>
<tabstop>rotateSpinBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>DroppedItemZoomDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>397</x>
<y>198</y>
</hint>
<hint type="destinationlabel">
<x>273</x>
<y>129</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>DroppedItemZoomDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>397</x>
<y>198</y>
</hint>
<hint type="destinationlabel">
<x>367</x>
<y>99</y>
</hint>
</hints>
</connection>
<connection>
<sender>zoomSlider</sender>
<signal>valueChanged(int)</signal>
<receiver>zoomSpinBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>162</x>
<y>42</y>
</hint>
<hint type="destinationlabel">
<x>346</x>
<y>47</y>
</hint>
</hints>
</connection>
<connection>
<sender>zoomSpinBox</sender>
<signal>valueChanged(int)</signal>
<receiver>zoomSlider</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>349</x>
<y>38</y>
</hint>
<hint type="destinationlabel">
<x>143</x>
<y>38</y>
</hint>
</hints>
</connection>
<connection>
<sender>rotateSlider</sender>
<signal>valueChanged(int)</signal>
<receiver>rotateSpinBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>84</x>
<y>114</y>
</hint>
<hint type="destinationlabel">
<x>128</x>
<y>115</y>
</hint>
</hints>
</connection>
<connection>
<sender>rotateSpinBox</sender>
<signal>valueChanged(int)</signal>
<receiver>rotateSlider</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>112</x>
<y>120</y>
</hint>
<hint type="destinationlabel">
<x>95</x>
<y>120</y>
</hint>
</hints>
</connection>
<connection>
<sender>zoomSlider</sender>
<signal>valueChanged(int)</signal>
<receiver>DroppedItemZoomDialog</receiver>
<slot>zoom(int)</slot>
<hints>
<hint type="sourcelabel">
<x>124</x>
<y>46</y>
</hint>
<hint type="destinationlabel">
<x>164</x>
<y>6</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>zoom(int)</slot>
</slots>
</ui>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+638
View File
@@ -0,0 +1,638 @@
/************************************************************************
* $Id: fullpagescene.cpp 666 2011-05-08 22:48:10Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-05-09 02:48:10 +0400 (Mon, 09 May 2011) $
* $Author: elzubeir $
* $Revision: 666 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/fullpagescene.cpp $
*
************************************************************************/
#include <QMessageBox>
#include <QPainter>
#include "fullpagescene.h"
#include "fullpageview.h"
#include "imageitem.h"
#include "imagecutout.h"
#include "constants.h"
#include "clippingstation.h"
#include "coordinates.h"
FullPageScene::FullPageScene(QObject * parent) :
QGraphicsScene(parent),
m_imageItem(0),//,m_selectionRectItem(0)
m_currentImageCutout(0)
{
setBackgroundBrush(Qt::Dense7Pattern);
m_zoomfactor = 1.0;
m_rotateAngle = 1.0;
m_selectionMode = SELECT;
m_currentOrder = 1;
}
FullPageScene::~FullPageScene()
{
qDebug("~FullPageScene()");
}
bool FullPageScene::loadPixmap(const QPixmap & pixmap)
{
removePixmap();
hideImageCutouts();
if (m_imageItem) // image already exists so we erase the old one.
{
removeItem(m_imageItem);
delete m_imageItem;
}
QPixmap scaledPix = getScaledPixmap(pixmap);
m_imageItem = new ImageItem(scaledPix);
addItem(m_imageItem);
m_pageHeight = scaledPix.height();
m_pageWidth = scaledPix.width ();
showImageCutouts();
return true;
}
void FullPageScene::removePixmap()
{
// TO DO
if(m_imageItem)
m_imageItem->setPixmap(QPixmap(0,0) );
}
void FullPageScene::addWordCoordinates(QList<WordCoordinates> &tagW)
{
//removeWordCoordinates();
m_wordCoordinates = tagW;
}
QList<TagCoordinates>& FullPageScene::tagCoorindates()
{
return m_tagCoordinates;
}
void FullPageScene::addTagCoordinates(QList<TagCoordinates> &tagH)
{
//remove all the tags from the scene
removeTagCoordinates();
m_tagCoordinates = tagH;
QBrush brush;
//brush.setStyle(Qt::Dense4Pattern);
//brush.setColor(QColor(106,90,205));
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::red); // Qt::darkBlue);
for(int i=0; i<m_tagCoordinates.count(); i++)
{
for(int j=0; j < m_tagCoordinates[i].coordinates().count(); j++)
{
Coordinates crd = m_tagCoordinates[i].coordinates(j);
QPointF pt1(crd.left(), crd.top());
QPointF pt2(crd.right(), crd.bottom());
pt1 += m_imageItem->pos();
pt2 += m_imageItem->pos();
QRectF rec(pt1, pt2);
QGraphicsRectItem *rect = new QGraphicsRectItem(rec, 0, this);
rect->setZValue(1.1);
rect->setPen(QPen( Qt::NoPen ) );
rect->setBrush( brush );
rect->setOpacity(.3);
rect->setToolTip(m_tagCoordinates[i].relatedKeywords().join("\n") );
m_tagCoordinates[i].rectItems().append(rect);
addItem(rect);
}
}
transform(m_zoomfactor, m_rotateAngle);
}
void FullPageScene::removeTagCoordinates()
{
for(int i=0; i < m_tagCoordinates.count(); i++)
{
foreach (QGraphicsRectItem *rect, m_tagCoordinates[i].rectItems() )
{
removeItem(rect);
delete rect;
}
m_tagCoordinates[i].clearCoordinates();
m_tagCoordinates[i].clearRectItems();
}
}
bool FullPageScene::createImageCutout(const QPolygonF & selectionRect, qreal rotationAngle, QString pageName, SELECTION_AREA_TYPE selectionType)
{
ImageCutout* cutout = new ImageCutout(0, selectionRect, rotationAngle, pageName, selectionType, SELECT);
ImageCutout::incrementTotalCount();
cutout->setOrder( ImageCutout::getTotalCount() );
m_currentOrder++;
m_imageCutoutsList.append(cutout);
addItem(cutout);
transform(m_zoomfactor, m_rotateAngle);
//now add the keywors to the selected area
addTags( m_imageCutoutsList[m_imageCutoutsList.count()-1]->boundingRect().toRect() );
return true;
}
void FullPageScene::removeImageCutout(ImageCutout * rect)
{
int i = m_imageCutoutsList.indexOf(rect); //qDebug("Selection index %d", i);
if(i > -1)
{
//removeItem(rect); //its removed from selectionItemrect function
//m_imageCutoutsList.removeOne(rect);
removeItem(rect);
rect->setVisible(false);
//delete rect; //dont do this
m_currentImageCutout = 0;
m_currentOrder--;
m_imageCutoutsList.removeAt(i);
ImageCutout::decrementTotalCount();
addTags();
}
}
void FullPageScene::removeImageCutouts()
{
foreach (ImageCutout *rect, m_imageCutoutsList)
{
removeItem(rect);
//delete rect;
ImageCutout::decrementTotalCount();
}
m_imageCutoutsList.clear();
m_currentOrder = 1;
}
void FullPageScene::removePreselectedImageCutouts()
{
foreach (ImageCutout *rect, m_preselectedImageCutoutsList)
{
removeItem(rect);
}
m_preselectedImageCutoutsList.clear();
}
void FullPageScene::showImageCutouts()
{
foreach (ImageCutout *rect, m_imageCutoutsList)
{
if(rect->pageName() == m_fileName)
addItem(rect);
rect->setMode( m_selectionMode );
}
foreach (ImageCutout *rect, m_preselectedImageCutoutsList)
{
if(rect->pageName() == m_fileName)
addItem(rect);
rect->setMode(VIEW);
}
transform(m_zoomfactor, m_rotateAngle);
}
void FullPageScene::hideImageCutouts()
{
foreach (ImageCutout *rect, m_imageCutoutsList)
{
//if (rect->scene() != this)
removeItem(rect);
}
}
void FullPageScene::setImageCutouts(QList<ImageCutout *> cutouts)
{
m_imageCutoutsList = cutouts;
ImageCutout::setTotalCount(0);
for(int i=0; i< m_imageCutoutsList.count(); i++)
{
ImageCutout::incrementTotalCount();
m_imageCutoutsList[i]->setOrder( ImageCutout::getTotalCount() );
}
}
void FullPageScene::setPreselectedImageCutouts(QList<ImageCutout *> cutouts)
{
m_preselectedImageCutoutsList = cutouts;
}
int FullPageScene::preselectedImageCutoutsCount()
{
return m_preselectedImageCutoutsList.count();
}
bool FullPageScene::isSourceImageIsLoad() const
{
return m_imageItem ? true : false;
}
void FullPageScene::setSelectionMode(SELECTION_MODE selectionMode)
{
m_selectionMode = selectionMode;
}
bool FullPageScene::isPointIsOnImageCutoutItem(const QPointF & point)
{
if(m_imageCutoutsList.isEmpty())
return false;
foreach (ImageCutout* rec, m_imageCutoutsList)
{
if( itemAt(point) == rec)
{
m_currentImageCutout = rec;
return true;
}
}
m_currentImageCutout = 0;
return false;
}
bool FullPageScene::isPointIsOnImageItem(const QPointF & point) const
{
if (!m_imageItem)
return false;
// get items list under the point to iterate on the mand find the image item.
QListIterator<QGraphicsItem *> it(items(point));
while (it.hasNext())
{
if (it.next() == m_imageItem)
return true;
}
return false;
}
QPixmap FullPageScene::getImageCutoutPixmap(const QRectF & rect) const
{
if (m_imageCutoutsList.isEmpty() )
return QPixmap();
return m_imageItem->getImageCutoutPixmap(rect);
}
QPointF FullPageScene::mapToImageItem(const QPointF & scenePos) const
{
if (m_imageItem)
return m_imageItem->mapFromScene(scenePos);
return QPointF(0, 0);
}
void FullPageScene::transform(qreal zoomFactor, qreal angle)
{
if (!m_imageItem)
return;
m_zoomfactor = zoomFactor;
m_rotateAngle = angle;
// we compute image center.
qreal imageCenterX = m_imageItem->x()+ m_imageItem->boundingRect().width()/2;
qreal imageCenterY = m_imageItem->y()+ m_imageItem->boundingRect().height()/2;
qreal imageX, imageY;
imageX = m_imageItem->boundingRect().width()/2;
imageY = m_imageItem->boundingRect().height()/2;
m_imageItem->setTransformationMode(Qt::SmoothTransformation);
m_imageItem->setTransform(QTransform().translate(imageCenterX, imageCenterY).rotate(angle).scale(zoomFactor, zoomFactor).translate(-imageCenterX, -imageCenterY));
foreach(ImageCutout* sel, m_imageCutoutsList)
{
qreal selectionX = sel->x() + imageX;
qreal selectionY = sel->y() + imageY;
sel->setTransform(QTransform().translate(selectionX, selectionY).rotate(angle).scale(zoomFactor, zoomFactor).translate(-selectionX, -selectionY));
}
foreach(ImageCutout* sel, m_preselectedImageCutoutsList)
{
qreal selectionX = sel->x() + imageX;
qreal selectionY = sel->y() + imageY;
sel->setTransform(QTransform().translate(selectionX, selectionY).rotate(angle).scale(zoomFactor, zoomFactor).translate(-selectionX, -selectionY));
}
for(int i=0; i < m_tagCoordinates.count(); i++)
{
foreach (QGraphicsRectItem *sel, m_tagCoordinates[i].rectItems() )
{
qreal selectionX = sel->x() + imageX;
qreal selectionY = sel->y() + imageY;
sel->setTransform(QTransform().translate(selectionX, selectionY).rotate(angle).scale(zoomFactor, zoomFactor).translate(-selectionX, -selectionY));
}
}
}
ImageCutout* FullPageScene::currentImageCutout()
{
return m_currentImageCutout;
}
QList<ImageCutout *> FullPageScene::imageCutoutsList()
{
return m_imageCutoutsList;
}
qreal FullPageScene::pageSize()
{
qreal w = (m_pageWidth /DPI) * 2.54;
qreal h = (m_pageHeight/DPI) * 2.54;
return w*h;
}
void FullPageScene::setfileName(QString fileName)
{
m_fileName = fileName;
}
QImage FullPageScene::screenShot()
{
int w = imageItem()->boundingRect().toRect().width();
int h = imageItem()->boundingRect().toRect().height();
QImage image(w, h, QImage::Format_ARGB32 );
QPainter painter(&image);
painter.setRenderHint(QPainter::HighQualityAntialiasing);
foreach (ImageCutout *rect, m_imageCutoutsList)
rect->setScreenshot(true);
foreach (ImageCutout *rect, m_preselectedImageCutoutsList)
rect->hide();
for(int i=0; i < m_tagCoordinates.count(); i++)
{
foreach (QGraphicsRectItem *rect, m_tagCoordinates[i].rectItems() )
rect->hide();
}
this->render(&painter, imageItem()->boundingRect().toRect(), imageItem()->boundingRect().toRect() );
foreach (ImageCutout *rect, m_imageCutoutsList)
rect->setScreenshot(false);
foreach (ImageCutout *rect, m_preselectedImageCutoutsList)
rect->show();
for(int i=0; i < m_tagCoordinates.count(); i++)
{
foreach (QGraphicsRectItem *rect, m_tagCoordinates[i].rectItems() )
rect->show();
}
return image;
}
qreal FullPageScene::A4PageScale() const
{
FullPageView *view = static_cast<FullPageView*>(views()[0]);
return view->getClippingStation()->A4Scale();
}
QPixmap FullPageScene::getScaledPixmap(const QPixmap & pixmap)
{
qreal dpi = pixmap.toImage().dotsPerMeterX() / 100.0;
dpi *= 2.54;
//qDebug("setImageItemPixmap() DPI = %.1f", dpi);
if( dpi > 150 )
return pixmap.scaledToHeight(pixmap.height()/3, Qt::SmoothTransformation);
else
return pixmap;
}
void FullPageScene::setOrderMode(bool set)
{
if(set)
{
m_currentOrder = 1;
m_selectionMode = ORDER;
}
else
m_selectionMode = SELECT;
foreach (ImageCutout *rect, m_imageCutoutsList)
rect->setMode(m_selectionMode);
}
int FullPageScene::currentOrder()
{
return m_currentOrder;
}
void FullPageScene::increaseCurrentOrder()
{
m_currentOrder++;
if(m_currentOrder > ImageCutout::getTotalCount() )
m_currentOrder = 1;
}
void FullPageScene::resetCurrentOrder()
{
m_currentOrder = 1;
}
QRectF FullPageScene::imageBoundingRect()
{
return m_imageItem->boundingRect();
}
void FullPageScene::addTags( QRect rect)
{
QList<int> tagIds;
QStringList tagCoords;
int left = rect.topLeft().x();
int top = rect.topLeft().y();
for(int i=0; i<m_tagCoordinates.count(); i++)
{
QString coordString = "";
for(int j=0; j < m_tagCoordinates[i].coordinates().count(); j++)
{
Coordinates crd = m_tagCoordinates[i].coordinates(j);
QPointF pt1(crd.left(), crd.top());
QPointF pt2(crd.right(), crd.bottom());
pt1 += m_imageItem->pos();
pt2 += m_imageItem->pos();
QRectF rec(pt1, pt2);
if( rect.contains( rec.toRect() ) )
{
if( !tagIds.contains( m_tagCoordinates[i].id() ) )
{
tagIds.append( m_tagCoordinates[i].id() );
//break; //no need to add it again
//format it in a top left, bottom, right fashion
QString str = QString("%1,%2,%3,%4").arg(crd.top()-top)
.arg(crd.left()-left)
.arg(crd.bottom()-top)
.arg(crd.right()-left);
//coordString += str;
tagCoords.append(str);
}
else
{
int index = tagIds.indexOf(m_tagCoordinates[i].id() );
QString str = QString("%1,%2,%3,%4").arg(crd.top()-top)
.arg(crd.left()-left)
.arg(crd.bottom()-top)
.arg(crd.right()-left);
//before we add it, make sure its not already added
if ( !tagCoords[index].contains(str, Qt::CaseInsensitive) )
tagCoords[index] += ":" + str;
}
}
}
//if( !coordString.isEmpty() && !coordString.isNull() )
//tagCoords.append(coordString);
}
FullPageView *view = static_cast<FullPageView*>(views()[0]);
view->addTags(tagIds, tagCoords, false);
}
void FullPageScene::addTags()
{
QList<int> tagIds;
QStringList tagCoords;
for(int cut=0; cut < m_imageCutoutsList.count(); cut++)
{
QRect rect = m_imageCutoutsList[cut]->boundingRect().toRect();
int left = rect.topLeft().x();
int top = rect.topLeft().y();
for(int i=0; i<m_tagCoordinates.count(); i++)
{
for(int j=0; j < m_tagCoordinates[i].coordinates().count(); j++)
{
Coordinates crd = m_tagCoordinates[i].coordinates(j);
QPointF pt1(crd.left(), crd.top());
QPointF pt2(crd.right(), crd.bottom());
pt1 += m_imageItem->pos();
pt2 += m_imageItem->pos();
QRectF rectF(pt1, pt2);
if( rect.contains( rectF.toRect() ) )
{
if( !tagIds.contains( m_tagCoordinates[i].id() ) )
{
QString str = QString("%1,%2,%3,%4").arg(crd.top()-top)
.arg(crd.left()-left)
.arg(crd.bottom()-top)
.arg(crd.right()-left);
tagCoords.append(str);
}
else
{
int index = tagIds.indexOf(m_tagCoordinates[i].id() );
QString str = QString("%1,%2,%3,%4").arg(crd.top()-top)
.arg(crd.left()-left)
.arg(crd.bottom()-top)
.arg(crd.right()-left);
//before we add it, make sure its not already added
if ( !tagCoords[index].contains(str, Qt::CaseInsensitive) )
tagCoords[index] += ":" + str;
}
}
}
}
}
FullPageView *view = static_cast<FullPageView*>(views()[0]);
view->addTags(tagIds, tagCoords, true);
}
QString FullPageScene::text()
{
QString text;
//
for(int i=0; i< m_imageCutoutsList.count(); i++)
{
QStringList words = getWord( m_imageCutoutsList[i]->boundingRect().toRect() );
text += words.join(" ");
}
return text;
}
QStringList FullPageScene::getWord(QRect rect)
{
QStringList words;
for(int i=0; i<m_wordCoordinates.count(); i++)
{
Coordinates crd = m_wordCoordinates[i].coordinates();
QPointF pt1(crd.left(), crd.top());
QPointF pt2(crd.right(), crd.bottom());
pt1 += m_imageItem->pos();
pt2 += m_imageItem->pos();
QRectF rec(pt1, pt2);
if( rect.contains( rec.toRect() ) )
words.append(m_wordCoordinates[i].word());
}
return words;
}
void FullPageScene::setImageVisibility(bool show)
{
m_imageItem->setVisible(show);
}
+320
View File
@@ -0,0 +1,320 @@
/************************************************************************
* $Id: fullpagescene.h 666 2011-05-08 22:48:10Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-05-09 02:48:10 +0400 (Mon, 09 May 2011) $
* $Author: elzubeir $
* $Revision: 666 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/fullpagescene.h $
*
************************************************************************/
#ifndef SOURCE_SCENE_H
#define SOURCE_SCENE_H
#include <QGraphicsScene>
#include "constants.h"
#include "clippingstation.h"
#include "tagcoordinates.h"
#include "wordcoordinates.h"
class ImageItem;
class ImageCutout;
class FullPageScene : public QGraphicsScene
{
public:
//! \fn FullPageScene()
//! default constructor
//! \author elzubeir
FullPageScene(QObject * parent);
//! \fn ~FullPageScene()
//! destructor
//! \author elzubeir
~FullPageScene();
//! \fn loadPixmap()
//! loads the pixmap to the scene
//! \param[in] pixmap to be loaded to the scene
//! \returns true if successful, false if not
//! \author elzubeir
bool loadPixmap(const QPixmap & pixmap);
//! \fn removePixmap()
//! removes a pixmap from the scene
//! \author elzubeir
void removePixmap();
//! \fn createImageCutout()
//! create the image cutout
//! \param[in] polygon of the points of the cutout
//! \param[in] rotation angle of the cutout
//! \param[in] name of the page from the image cutout
//! \param[in] type of the created selection, image, title or body
//! \returns true if successful, false if not
//! \author elzubeir
bool createImageCutout(const QPolygonF & cutout, qreal rotationAngle, QString pageName, SELECTION_AREA_TYPE selectionType = IMAGE);
//! \fn removeImageCutout()
//! remove image cutout from the scene
//! \param[in] the cutout to remove
//! \author elzubeir
void removeImageCutout(ImageCutout * rect);
//! \fn addWordCoordinates()
//! add words of the page to the scene
//! \param[in] list of WordCoordinates to add to the scene
//! \author elzubeir
void addWordCoordinates(QList<WordCoordinates> &tagW);
//void removeWordCoordinates();
//! \fn addTagCoordinates()
//! add words of the page to the scene
//! \param[in] list of TagCoordinates to add to the scene
//! \author elzubeir
void addTagCoordinates(QList<TagCoordinates> &tagHighlight);
QList<TagCoordinates>& tagCoorindates();
//! \fn removeTagCoordinates();
//! remove the tag coordinates from the scene
//! \author elzubeir
void removeTagCoordinates();
//! \fn removeImageCutout()
//! remove all the image cutouts from the scene
//! \author elzubeir
void removeImageCutouts();
//! \fn removePreselectedImageCutouts()
//! remove the preselected image cutouts
//! \author elzubeir
void removePreselectedImageCutouts();
//! \fn hideImageCutouts()
//! hide image cutouts from the scene
//! \author elzubeir
void hideImageCutouts();
//! \fn showImageCutouts();
//! show image cutouts in the scene
//! \author elzubeir
void showImageCutouts();
//! \fn setImageCutouts()
//! add image cutouts to the scene
//! \param[in] image cutous list to be added
//! \author elzubeir
void setImageCutouts(QList<ImageCutout *> cutouts);
//! \fn setPreselectedImageCutouts()
//! add preselected image cutout to the scene
//! \param[in] list of the preselected image cutouts to be added
//! \author elzubeir
void setPreselectedImageCutouts(QList<ImageCutout *> cutouts);
//! \fn preselectedImageCutoutsCount()
//! count of preselected image cutout
//! \returns count of the preselected cutouts
//! \author elzubeir
int preselectedImageCutoutsCount();
//! \fn setSelectionMode()
//! set the current selection mode
//! \param[in] SELECTION_MODE type
//! \author elzubeir
void setSelectionMode(SELECTION_MODE selectionMode);
//! \fn isSourceImageIsLoad()
//! is image loaded
//! \returns true if image is loaded, false if not
//! \author elzubeir
bool isSourceImageIsLoad() const;
//! \fn isPointIsOnImageCutoutItem()
//! is point on image cutout
//! \param[in] point to test
//! \returns true if point on image cutout, false if not
//! \author elzubeir
bool isPointIsOnImageCutoutItem(const QPointF & point);
//! \fn isPointIsOnImageItem()
//! is point on the image
//! \param[in] point to test
//! \returns true if poing on image, false if not
//! \author elzubeir
bool isPointIsOnImageItem(const QPointF & point) const;
//! \fn getImageCutoutPixmap()
//! returns the cutouf of the image based on the passed rectangle
//! \param[in] rectangle holding the cutout's coordinates
//! \returns partial image from the page loaded
//! \author elzubeir
QPixmap getImageCutoutPixmap(const QRectF & rect) const;
//! \fn mapToImageItem()
//! map a scene position to the image item position.
//! \param[in] point to be mapped
//! \returns a mapped point
//! \author elzubeir
QPointF mapToImageItem(const QPointF & scenePos) const;
//! \fn transform()
//! transformation operations on the image item.
//! \param[in] zoomFactor the scale used in zoom operation.
//! \param[in] angle rotation angle.
//! \author elzubeir
void transform(qreal zoomFactor, qreal angle);
//! \fn currentImageCutout()
//! returns the current cutout from the image
//! \returns returns the image cutout
//! \author elzubeir
ImageCutout* currentImageCutout();
//! \fn imageCutoutsList()
//! list of image cutous of the scene
//! \returns the list of the image cutous
//! \author elzubeir
QList<ImageCutout *> imageCutoutsList();
//! \fn pageSize()
//! the size of the image page
//! \returns the size of the image
//! \author elzubeir
qreal pageSize();
//! \fn imageItem()
//! current image item
//! \returns current image item pointer
//! \author elzubeir
inline const ImageItem* imageItem() { return m_imageItem;}
//! \fn setfileName()
//! set file name of the current image
//! \param[in] fileName of the current image
//! \author elzubeir
void setfileName(QString fileName);
//! \fn screenShot()
//! create a screen shot of the image on the scene
//! \returns image of the screen shot
//! \author elzubeir
QImage screenShot();
//! \fn A4PageScale()
//! scale of the a4 page in drawer
//! \returns the scale of the a4 page in drawer
//! \author elzubeir
qreal A4PageScale() const;
//! \fn getScaledPixmap()
//! return a scaled image of the pixmap
//! \param[in] original pixmap
//! \returns the scaled image
//! \author elzubeir
QPixmap getScaledPixmap(const QPixmap & pixmap);
//! \fn setOrderMode()
//! set the order mode to set of select
//! \param[in] order mode
//! \author elzubeir
void setOrderMode(bool set);
//! \fn currentOrder()
//! returns the current odrder
//! \author elzubeir
int currentOrder();
//! \fn increaseCurrentOrder()
//! increase the current order of the cutouts
//! \author elzubeir
void increaseCurrentOrder();
//! \fn resetCurrentOrder();
//! set the current order to 1
//! \author elzubeir
void resetCurrentOrder();
//! \fn imageBoundingRect()
//! the bounding rectange of the scene
//! \returns rectangle of the scene
//! \author elzubeir
QRectF imageBoundingRect();
//! \fn addTags()
//! add tags from the current rect
//! \param[in] rectangle to check tags existance inside of them
//! \author elzubeir
void addTags(QRect rect);
//! \fn addTags()
//! add tags from all the cutouts
//! \author elzubeir
void addTags();
//! \fn getWord()
//! return a string list of the words in the rect
//! \param[in] rect of the cutout to get the words from
//! \returns string list of the words
//! \author elzubeir
QStringList getWord(QRect rect);
//! \fn text()
//! returns a text of the image
//! \author elzubeir
QString text();
void setImageVisibility(bool show);
private:
//! image item
ImageItem * m_imageItem; ///< the image.
//! selected cutouts
QList<ImageCutout *> m_imageCutoutsList; ///< the selected rect.
//! preselected cutouts
QList<ImageCutout *> m_preselectedImageCutoutsList;
//QList<QGraphicsRectItem *> m_tagItems;
//! words list
QList<WordCoordinates> m_wordCoordinates;
//! tags list
QList<TagCoordinates> m_tagCoordinates;
//! current cutout
ImageCutout* m_currentImageCutout;
//! zoom factor
qreal m_zoomfactor;
//! rotate angle
qreal m_rotateAngle;
//! filename
QString m_fileName;
//! page widht
qreal m_pageWidth;
//! page height
qreal m_pageHeight;
//! selection mode
SELECTION_MODE m_selectionMode;
//! current order
int m_currentOrder;
};
#endif // SOURCE_SCENE_H
+530
View File
@@ -0,0 +1,530 @@
/************************************************************************
* $Id: fullpageview.cpp 667 2011-05-15 10:41:45Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-05-15 14:41:45 +0400 (Sun, 15 May 2011) $
* $Author: elzubeir $
* $Revision: 667 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/fullpageview.cpp $
*
************************************************************************/
#include "fullpageview.h"
#include <QMouseEvent>
#include <math.h>
#include <QtDebug>
#include "clippingstation.h"
#include "constants.h"
#include "fullpagescene.h"
#include "imagecutout.h"
FullPageView::FullPageView(QWidget * parent) :
QGraphicsView(parent),
m_clippingStation(0),
m_rubberBand(0),
m_scale(1.0),
m_rotationAngle(0.0),
m_pageLayout(BEST_FIT),
m_selectionAreaType(IMAGE),
m_selectionMode(SELECT)
{
// construct the scene
m_scene = new FullPageScene(this);
setScene(m_scene);
setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
//m_pageLayout = ACTUAL_SIZE;
//m_selectionAreaType = IMAGE;
m_selectionMode = SELECT;
m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
tweaking = false ;
mousePressed = false;
}
FullPageView::~FullPageView()
{
qDebug("~FullPageView()");
if(m_rubberBand)
delete m_rubberBand;
m_rubberBand = 0;
if (m_scene)
delete m_scene;
m_scene = 0;
}
void FullPageView::setClippingStation(ClippingStation* clippingStation)
{
m_clippingStation = clippingStation;
}
ClippingStation * FullPageView::getClippingStation() const
{
return m_clippingStation;
}
bool FullPageView::load(const QString & fileName)
{
// call the scene to load pixmap.
setCursor(Qt::BusyCursor);
m_scene->setfileName(fileName);
bool loaded = m_scene->loadPixmap(QPixmap(fileName));
if(loaded && m_scale >= MIN_SCALE && m_scale <= MAX_SCALE)
{
setPageLayout(m_pageLayout);
m_scene->transform(m_scale, m_rotationAngle);
m_clippingStation->displayZoomStatus(m_scale);
m_scene->setSceneRect( m_scene->itemsBoundingRect() );
this->setSceneRect(m_scene->itemsBoundingRect() );
m_currentPageName = fileName;
//now load the highlighted keywords now
}
m_currentPageName = fileName;
unsetCursor();
return loaded;
}
void FullPageView::leaveEvent(QEvent * event)
{
// when mouse leave the view, we clear the status message.
if (m_clippingStation)
{
m_clippingStation->clearStatusMessage();
}
}
void FullPageView::mouseDoubleClickEvent(QMouseEvent *event)
{
qDebug() << "mouseDoubleClickEvent()";
if (!m_scene->isPointIsOnImageItem(mapToScene(event->pos())))
{
//m_scene->removeImageCutout();
return;
}
QPointF point = mapToScene(event->pos());
point = mapToImageItem(point);
qDebug() << "point clicked: " << point.toPoint();
//get the word under the mouse
QList<TagCoordinates> tc = m_scene->tagCoorindates();
qDebug() << "tag coordinates count: " <<tc.size();
for(int i=0; i < tc.count(); i++)
{
foreach (QGraphicsRectItem *rect, tc[i].rectItems() )
{
qDebug() << "rect: " << rect->boundingRect().toRect();
if(rect->contains(point))
{
qDebug() << "press is inside a keyword rect";
//found, we load the related keyword for this tag.
QString tag = tc[i].tag();
QStringList keywords = m_clippingStation->getRelatedKeywords(tag);
tc[i].setRelatedKeywords(keywords);
foreach (QGraphicsRectItem *rec2, tc[i].rectItems() )
rec2->setToolTip(keywords.join("\n"));
return;
}
}
}
qDebug() << "end of mouseDoubleClickEvent()";
}
void FullPageView::mousePressEvent(QMouseEvent *event)
{
//if selection not on image item, we return
if (!m_scene->isPointIsOnImageItem(mapToScene(event->pos())))
{
//m_scene->removeImageCutout();
return;
}
// if click not occurs in selection Rect, we don't do anything.
if (! m_scene->isPointIsOnImageCutoutItem(mapToScene(event->pos())) &&
m_selectionMode == SELECT)
{
m_selectionAreaType = IMAGE;
m_origin = event->pos(); // keep position
if (!m_rubberBand)
{
m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
}
m_rubberBand->setGeometry( QRect(m_origin, QSize()) );
m_rubberBand->show();
//m_isModified = false;
}
QGraphicsView::mousePressEvent(event);
}
void FullPageView::mouseMoveEvent(QMouseEvent *event)
{
if (m_rubberBand && (event->buttons() & Qt::LeftButton) )
{
m_rubberBand->setGeometry(QRect(m_origin, event->pos()).normalized()); // draw select rect
}
if (m_clippingStation)
{
QPointF scenePos = mapToScene(event->pos());
// if we draw the selection rect, we display coordinates in the staus bar + width and height values.
// if not, we only display mouse coordinates.
if (m_rubberBand && m_rubberBand->isVisible())
{
QPointF sceneOrigin = mapToScene(m_origin);
QPointF itemOrigin = mapToImageItem(sceneOrigin);
QPointF itemPos = mapToImageItem(scenePos);
m_clippingStation->displayCoordinatesStatus(itemOrigin.x(), itemOrigin.y(), qAbs(itemPos.x() - itemOrigin.x()), qAbs(itemPos.y() - itemOrigin.y()));
}
else
{
if (m_scene->isSourceImageIsLoad())
{
QPointF pointInItem = mapToImageItem(scenePos);
m_clippingStation->displayCoordinatesStatus(pointInItem.x(), pointInItem.y());
}
}
}
QPointF pt = mapToScene(event->pos());
pt = mapToImageItem(pt);
if(m_scene->isPointIsOnImageCutoutItem( pt ) )
{
//static int i=0;
//qDebug("%d\tIn item", i++);
m_scene->currentImageCutout()->checkBoundary(pt.toPoint(), false );
}
QGraphicsView::mouseMoveEvent(event);
}
QPointF FullPageView::mapToImageItem(const QPointF & scenePos) const
{
return m_scene->mapToImageItem(scenePos);
}
void FullPageView::mouseReleaseEvent(QMouseEvent *event)
{
if(m_selectionMode != SELECT)
{
QGraphicsView::mouseReleaseEvent(event);
return;
}
// after releasing the mouse, we create the selection rect.
if (m_rubberBand && m_rubberBand->isVisible())
{
if (m_scene->isSourceImageIsLoad()) // check if an image is loaded.
{
//m_scene->createImageCutout(mapToScene(m_rubberBand->geometry()), m_rotationAngle); //the old way
QPointF sceneOrigin = mapToScene(m_origin); //now we map the values to the image item directly, this helps us to make a selection...
QPointF itemOrigin = mapToImageItem(sceneOrigin); //regardless of zooming/rotating values
QPointF scenePos = mapToScene(event->pos());
QPointF itemPos = mapToImageItem(scenePos);
QRectF rec(itemOrigin.x(), itemOrigin.y(), (itemPos.x() - itemOrigin.x()), (itemPos.y() - itemOrigin.y()));
rec = rec.normalized();
if( rec.width() < 20.0 && rec.height() < 20 )
{
QGraphicsView::mouseReleaseEvent(event);
return;
}
QPolygonF ply(rec);
m_scene->createImageCutout(ply, m_rotationAngle, m_currentPageName, m_selectionAreaType);
}
//if(!m_isModified)
m_rubberBand->hide();
}
QGraphicsView::mouseReleaseEvent(event);
}
void FullPageView::rotate(double rotateAngle)
{
if (m_scene->isSourceImageIsLoad()) // check if an image is loaded.
{
m_rotationAngle = rotateAngle;
m_scene->transform(m_scale, m_rotationAngle);
m_clippingStation->displayRotationAngleStatus(m_rotationAngle);
m_scene->setSceneRect(m_scene->itemsBoundingRect() );
}
}
qreal FullPageView::zoom(bool zoomin)
{
if (m_scene->isSourceImageIsLoad()) // check if an image is loaded.
{
// compute scale
qreal oldscale = m_scale;
qreal sc = ::pow(2, zoomin? ZOOM_FACTOR : -ZOOM_FACTOR);
m_scale *= sc;
m_scale = qMin(m_scale, MAX_SCALE);
m_scale = qMax(m_scale, MIN_SCALE);
if (m_scale >= MIN_SCALE && m_scale <= MAX_SCALE)
{
m_scene->transform(m_scale, m_rotationAngle);
m_clippingStation->displayZoomStatus(m_scale);
m_scene->setSceneRect(m_scene->itemsBoundingRect() );
this->setSceneRect(m_scene->itemsBoundingRect() );
}
return oldscale;
}
return m_scale;
}
qreal FullPageView::actualSize()
{
qreal oldscale = m_scale;
if (m_scene->isSourceImageIsLoad()) // check if an image is loaded.
{
m_scale = 1.0;
m_scene->transform(m_scale, m_rotationAngle);
m_clippingStation->displayZoomStatus(m_scale);
m_scene->setSceneRect(m_scene->itemsBoundingRect() );
this->setSceneRect(m_scene->itemsBoundingRect() );
}
return oldscale;
}
void FullPageView::setScale(qreal scale)
{
m_scale = scale;
m_scene->transform(m_scale, m_rotationAngle);
m_clippingStation->displayZoomStatus(m_scale);
m_scene->setSceneRect(m_scene->itemsBoundingRect() );
this->setSceneRect(m_scene->itemsBoundingRect() );
}
void FullPageView::resizeEvent(QResizeEvent* event)
{
if( m_pageLayout != ACTUAL_SIZE )
{
actualSize(); //just reset the page to default
qreal w = rect().width();
qreal h = rect().height();
qreal sceneWidth = m_scene->itemsBoundingRect().width();
qreal sceneHeight = m_scene->itemsBoundingRect().height();
//calculate the ratio
qreal precW = w/sceneWidth;
qreal precH = h/sceneHeight;
qreal prec = precW;
if (m_pageLayout == BEST_FIT)
prec = qMin(precW, precH);
//calculate the ratio
m_scale = prec;
m_scene->transform(m_scale, m_rotationAngle);
m_clippingStation->displayZoomStatus(m_scale);
m_scene->setSceneRect(m_scene->itemsBoundingRect() );
this->setSceneRect(m_scene->itemsBoundingRect() );
}
//else
{
//to show the scroll bar as page changes
m_scene->setSceneRect(m_scene->itemsBoundingRect() );
this->setSceneRect(m_scene->itemsBoundingRect() );
}
int w = (int)this->rect().width();
int h = (int)this->rect().height();
int x = (int)this->rect().x();
int y = (int)this->rect().y();
//static int i = 0;
//qDebug("%d: (%d,%d) -> (%d,%d)", i++, x, y, w, h);
w = (int)m_scene->itemsBoundingRect().width();
h = (int)m_scene->itemsBoundingRect().height();
x = (int)m_scene->itemsBoundingRect().x();
y = (int)m_scene->itemsBoundingRect().y();
//qDebug("\t\t(%d,%d) -> (%d,%d)", x, y, w, h);
QGraphicsView::resizeEvent(event);
}
void FullPageView::setPageLayout(PAGE_LAYOUT layout)
{
m_pageLayout = layout;
if( m_pageLayout != ACTUAL_SIZE )
{
actualSize(); //just reset the page to default
//fitInView((QGraphicsItem*)m_scene->imageItem(), Qt::KeepAspectRatio);
qreal w = rect().width();
qreal h = rect().height();
qreal sceneWidth = m_scene->itemsBoundingRect().width();
qreal sceneHeight = m_scene->itemsBoundingRect().height();
//calculate the ratio
qreal precW = w/sceneWidth;
qreal precH = h/sceneHeight;
qreal prec = precW;
if (m_pageLayout == BEST_FIT)
prec = qMin(precW, precH);
//calculate the ratio
m_scale = prec;
this->setSceneRect(QRectF(QPoint(0, 0), QSize() ) );
m_scene->transform(m_scale, m_rotationAngle);
m_clippingStation->displayZoomStatus(m_scale);
m_scene->setSceneRect(m_scene->itemsBoundingRect() );
}
else
{
//to show the scroll bar as page changes
//this->setSceneRect(QRectF(QPoint(0, 0), QSize() ) );
//m_scene->setSceneRect(m_scene->itemsBoundingRect() );
}
}
void FullPageView::keyPressEvent(QKeyEvent *key)
{
if(key->key() == Qt::Key_I)
{
m_selectionAreaType = IMAGE;
}
else if(key->key() == Qt::Key_T)
m_selectionAreaType = TITLE;
else if(key->key() == Qt::Key_B)
m_selectionAreaType = BODY;
else if(key->modifiers() == Qt::ControlModifier && key->key() == Qt::Key_A)
{
QPolygonF ply(m_scene->imageBoundingRect());
m_scene->createImageCutout(ply, m_rotationAngle, m_currentPageName, m_selectionAreaType);
}
//else //to propogate the call to the items in the view
QGraphicsView::keyPressEvent(key);
}
void FullPageView::setSelectionMode(SELECTION_MODE selectionMode)
{
m_selectionMode = selectionMode;
}
const QList<ImageCutout *> FullPageView::imageCutoutsList() const
{
return m_scene->imageCutoutsList();
}
void FullPageView::removeImageCutouts()
{
m_scene->removeImageCutouts();
}
void FullPageView::removePreselectedImageCutouts()
{
m_scene->removePreselectedImageCutouts();
}
void FullPageView::hideImageCutouts()
{
m_scene->hideImageCutouts();
}
void FullPageView::setImageCutouts(QList<ImageCutout *> cutouts)
{
m_scene->setImageCutouts(cutouts);
}
void FullPageView::setPreselectedImageCutouts(QList<ImageCutout *> cutouts)
{
m_scene->setPreselectedImageCutouts(cutouts);
}
int FullPageView::preselectedImageCutoutsCount()
{
return m_scene->preselectedImageCutoutsCount();
}
qreal FullPageView::pageSize()
{
return m_scene->pageSize();
}
QImage FullPageView::screenShot()
{
return m_scene->screenShot();
}
void FullPageView::setOrderMode(bool set)
{
if(set)
m_selectionMode = ORDER;
else
m_selectionMode = SELECT;
m_scene->setOrderMode(set);
}
void FullPageView::addWordCoordinates(QList<WordCoordinates> &tagW)
{
m_scene->addWordCoordinates(tagW);
}
void FullPageView::addTagCoordinates(QList<TagCoordinates> &tagH)
{
m_scene->addTagCoordinates(tagH);
}
void FullPageView::addTags(QList<int> &tagIds, QStringList tagCoord, bool removedAndThenAdd)
{
m_clippingStation->addTagsToTagWrapper(tagIds, tagCoord, removedAndThenAdd);
}
QString FullPageView::text()
{
return m_scene->text();
}
void FullPageView::setImageVisibility(bool show)
{
m_scene->setImageVisibility(show);
}
+261
View File
@@ -0,0 +1,261 @@
/************************************************************************
* $Id: fullpageview.h 666 2011-05-08 22:48:10Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-05-09 02:48:10 +0400 (Mon, 09 May 2011) $
* $Author: elzubeir $
* $Revision: 666 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/fullpageview.h $
*
************************************************************************/
#ifndef SOURCE_VIEW_H
#define SOURCE_VIEW_H
#include <QGraphicsView>
#include "constants.h"
#include "imagecutout.h"
#include "clippingstation.h"
#include "tagcoordinates.h"
#include "wordcoordinates.h"
class FullPageScene;
class ClippingStation;
class QRubberBand;
/**
\brief FullPage View is the left view.
This is where the user can see the full image loaded.
As a view class, its role is to pass UI interaction to the scene.
It got also responsability to draw the selection cutouts.
*/
class FullPageView : public QGraphicsView
{
public:
FullPageView(QWidget * parent); ///< ctor
~FullPageView();
/**
\brief load image to the scene.
\param fileName file name image.
\return loading state.
*/
bool load(const QString & fileName);
/**
\brief accessors to main window
Used to acess to status bar, toolbar...
*/
void setClippingStation(ClippingStation* clippingStation);
ClippingStation * getClippingStation() const;
/**
\brief rotate action. Occurs only if an image is load in the scene.
\param isRotatingToRight. Rotate direction. Set to true means rotate right, false means left.
*/
void rotate(double rotateAngle);
/**
\brief zoom action. Occurs only if an image is load in the scene.
\param isZoomIn. Zoom direction. Set to true means zoom in, false means zoom out.
*/
qreal zoom(bool isIn);
qreal actualSize();
void setScale(qreal oldscale);
void setPageLayout(PAGE_LAYOUT layout);
void setSelectionMode(SELECTION_MODE selectionMode);
const QList<ImageCutout *> imageCutoutsList() const;
//! \fn setImageCutouts()
//! add image cutouts to the scene
//! \param[in] image cutous list to be added
//! \author elzubeir
void setImageCutouts(QList<ImageCutout *> cutouts);
//! \fn hideImageCutouts()
//! hide image cutouts from the scene
//! \author elzubeir
void hideImageCutouts();
//! \fn removeImageCutout()
//! remove all the image cutouts from the scene
//! \author elzubeir
void removeImageCutouts();
//! \fn setPreselectedImageCutouts()
//! add preselected image cutout to the scene
//! \param[in] list of the preselected image cutouts to be added
//! \author elzubeir
void setPreselectedImageCutouts(QList<ImageCutout *> cutouts);
//! \fn removePreselectedImageCutouts()
//! remove the preselected image cutouts
//! \author elzubeir
void removePreselectedImageCutouts();
//! \fn preselectedImageCutoutsCount()
//! count of preselected image cutout
//! \returns count of the preselected cutouts
//! \author elzubeir
int preselectedImageCutoutsCount();
//! \fn pageSize()
//! the size of the image page
//! \returns the size of the image
//! \author elzubeir
qreal pageSize();
//! \fn screenShot()
//! create a screen shot of the image on the scene
//! \returns image of the screen shot
//! \author elzubeir
QImage screenShot();
//! \fn addWordCoordinates()
//! add words of the page to the scene
//! \param[in] list of WordCoordinates to add to the scene
//! \author elzubeir
void addWordCoordinates(QList<WordCoordinates> &tagW);
//! \fn addTagCoordinates()
//! add words of the page to the scene
//! \param[in] list of TagCoordinates to add to the scene
//! \author elzubeir
void addTagCoordinates(QList<TagCoordinates> &tagH);
//! \fn setOrderMode()
//! set the order mode to set of select
//! \param[in] order mode
//! \author elzubeir
void setOrderMode(bool set);
//! \fn addTags()
//! add tags to the tagwrapper
//! \param[in] tagIds: list of tags to be added
//! \param[in] tagCoord: list of coordinates to be added
//! \param[in] removeAndThenAdd: remove tags from wrapper and then add
//! \return void
//! \author elzubeir
void addTags(QList<int> &tagIds, QStringList tagCoord, bool removedAndThenAdd);
//! \fn text()
//! returns a text of the image
//! \author elzubeir
QString text();
void setImageVisibility(bool show);
protected:
//! \fn leaveEvent()
//! called when mouse cursor leave the view.
//! \author elzubeir
virtual void leaveEvent(QEvent * event);
//! \fn mousePressEvent()
//! called when a mouse button is pressed.
//! \author elzubeir
virtual void mousePressEvent(QMouseEvent *event);
//! \fn mouseMoveEvent()
//! called when a mouse is moved
//! \author elzubeir
virtual void mouseMoveEvent(QMouseEvent *event);
//! \fn mouseReleaseEvent()
//! called when mouse button is released.
//! \author elzubeir
virtual void mouseReleaseEvent(QMouseEvent *event);
//! \fn resizeEvent()
//! resize the view's viewport
//! \param[in] event QResizeEvent* event's paramter for resizing
//! \author elzubeir
void resizeEvent(QResizeEvent* event);
//! \fn keyPressEvent()
//! overrides the keyPressEvent() function
//! \author elzubeir
virtual void keyPressEvent(QKeyEvent * event);
virtual void mouseDoubleClickEvent(QMouseEvent *event);
private:
//! \fn mapToImageItem()
//! map a scene position to the image item position.
//! \param[in] point to be mapped
//! \returns a mapped point
//! \author elzubeir
QPointF mapToImageItem(const QPointF & scenePos) const;
//! \fn checkBoundary()
//! check if the point is on the item's boundaries
//! \param[in] point of the current point to check
//! \param[in] bool for tweaking part.
//! \author elzubeir
void checkBoundary(QPoint pt, bool t);
private:
//! the scene
FullPageScene * m_scene;
//! main window.
ClippingStation * m_clippingStation;
//! scene origin point where click starts. Used to draw selection rect.
QPoint m_origin;
//! selection rect
QRubberBand * m_rubberBand;
//! scale
qreal m_scale;
//! rotation
qreal m_rotationAngle;
//! page layout
PAGE_LAYOUT m_pageLayout;
//! selection type
SELECTION_AREA_TYPE m_selectionAreaType;
//! selection mode
SELECTION_MODE m_selectionMode;
//! page name
QString m_currentPageName;
//! are we twaking
bool tweaking;
//! is moue pressed
bool mousePressed;
//! origina point
QPoint origin ;
//! tweaking part
QString tweakingpart ;
//! points for top/let, top/right, bottom/left, bottom/right
QPoint tl, tr, bl, br ;
};
#endif // SOURCE_VIEW_H
+190
View File
@@ -0,0 +1,190 @@
/************************************************************************
* $Id: globalfunctions.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/globalfunctions.cpp $
*
************************************************************************/
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include "globalfunctions.h"
int g_currentUpload = 0;
ofstream g_logfile;
bool g_debug = false;
/*
//parse headers for Content-Length
size_t getcontentlengthfunc(void *ptr, size_t size, size_t nmemb, void *stream) {
int r;
long len = 0;
r = sscanf((const char*)ptr, "Content-Length: %ld\n", &len);
if (r)
*((long *) stream) = len;
return size * nmemb;
}
// discard downloaded data
size_t discardfunc(void *ptr, size_t size, size_t nmemb, void *stream) {
return size * nmemb;
}
*/
// read data to upload
size_t readfunc(void *ptr, size_t size, size_t nmemb, void *stream)
{
FILE *f = (FILE*)stream; //convert the stream fo file
size_t n;
if (ferror(f))
return CURL_READFUNC_ABORT;
n = fread(ptr, size, nmemb, f) * size; //read bytes from the stream
g_currentUpload += n; //increase the uploaded data by n
return n;
}
int upload(CURL *curlhandle, const char * remotepath, const char * localpath,
long timeout, long tries, char * errorstr)
{
FILE *f;
CURLcode r = CURLE_GOT_NOTHING;
int c;
f = fopen(localpath, "rb");
if (f == NULL) {
perror(NULL);
return 0;
}
curl_easy_setopt(curlhandle, CURLOPT_UPLOAD, 1L); //set the operation to upload
curl_easy_setopt(curlhandle, CURLOPT_URL, remotepath); //set the file to remote path
if (timeout)
curl_easy_setopt(curlhandle, CURLOPT_FTP_RESPONSE_TIMEOUT, timeout); //set timeout if timeout flag is set
curl_easy_setopt(curlhandle, CURLOPT_READFUNCTION, readfunc); //this is the read functino that would read that data from f, as passed in the next line
curl_easy_setopt(curlhandle, CURLOPT_READDATA, f); //where to read the data to upload from
curl_easy_setopt(curlhandle, CURLOPT_FTPPORT, "-"); // disable passive mode
curl_easy_setopt(curlhandle, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L); //create any missing directories if they do not exist
//curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curlhandle, CURLOPT_NOPROGRESS, 0L); //no progress present
//curl_easy_setopt(curlhandle, CURLOPT_PROGRESSFUNCTION, my_progress_func);
for (c = 0; (r != CURLE_OK) && (c < tries); c++) //try to upload mutilple times if tries > 0
{
curl_easy_setopt(curlhandle, CURLOPT_APPEND, 0L); //this is the first time to uplaod the file
r = curl_easy_perform(curlhandle); //do the acutal upload
}
fclose(f); //close the file
if ( CURLE_OK == r ) //if operation is successfull, return 1
return 1;
else
{ //otherwise, set the error string, and reutrn 0
strcpy(errorstr, curl_easy_strerror(r));
return 0;
}
}
size_t writefunc(void *buffer, size_t size, size_t nmemb, void *stream)
{
struct FtpFile *out=(struct FtpFile *)stream;
if(out && !out->stream)
{
/* open file for writing */
out->stream=fopen(out->filename, "wb");
if(!out->stream)
return -1; /* failure, can't open file to write */
}
return fwrite(buffer, size, nmemb, out->stream);
}
int download(CURL* curlhandle, const char * remotepath, const char * localpath,
long timeout, long tries, char * strerror)
{
FtpFile ftpfile=
{
localpath, // name to store the file as if succesful
NULL
};
CURLcode res = CURLE_GOT_NOTHING;
curl_easy_setopt(curlhandle, CURLOPT_URL, remotepath);
curl_easy_setopt(curlhandle, CURLOPT_WRITEFUNCTION, writefunc); // Define our callback to get called when there's data to be written
curl_easy_setopt(curlhandle, CURLOPT_WRITEDATA, &ftpfile); // Set a pointer to our struct to pass to the callback
curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1L); // Switch on full protocol/debug output
res = curl_easy_perform(curlhandle);
if(CURLE_OK != res)
{
/* we failed */
strcpy(strerror, curl_easy_strerror(res));
return 0;
}
if(ftpfile.stream)
fclose(ftpfile.stream); /* close the local file */
return 1;
}
void MyOutputHandler(QtMsgType type, const char *msg) {
if(!g_debug)
return;
switch (type) {
case QtDebugMsg:
g_logfile << QTime::currentTime().toString().toAscii().data() << " Debug: \t" << msg << "\n";
break;
case QtCriticalMsg:
g_logfile << QTime::currentTime().toString().toAscii().data() << " Critical: \t" << msg << "\n";
break;
case QtWarningMsg:
//g_logfile << QTime::currentTime().toString().toAscii().data() << " Warning: \t" << msg << "\n";
break;
case QtFatalMsg:
g_logfile << QTime::currentTime().toString().toAscii().data() << " Fatal: \t" << msg << "\n";
abort();
}
g_logfile.flush();
}
+112
View File
@@ -0,0 +1,112 @@
/************************************************************************
* $Id: globalfunctions.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/globalfunctions.h $
*
************************************************************************/
#ifndef GLOBALFUNCTIONS_H
#define GLOBALFUNCTIONS_H
#include <curl/curl.h>
#include <iostream>
#include <fstream>
using namespace std;
#include <QtCore>
//! gloabl variable to hold the number of currently read bytes from the uploaded file
extern int g_currentUpload;
extern ofstream g_logfile;
extern bool g_debug;
//! \struct FtpFile
//! structu to holds the filename, and the stream used to write the local file when an ftp get operation is performed
struct FtpFile {
const char *filename;
FILE *stream;
};
struct MarginValues{
qreal top;
qreal bottom;
qreal left;
qreal right;
};
//! \fn readfunc(void *ptr, size_t size, size_t nmemb, void *stream)
//! Reads block of data from stream of element count of nmemb, and each elements of size size, and stores it in prt
//! \param[out] prt void* to hold the read data
//! \param[in] size size_t holds the size of individual element to read
//! \param[in] nmemb size_t holds the number of elements to read
//! \param[in] stream void* holds the stream to read from
//! \return size_t
//! value > 0 the total number of elements successfully read
//! value = 0 end of stream is reached
//! value < 0 error happened
size_t readfunc(void *ptr, size_t size, size_t nmemb, void *stream);
//! \fn upload(CURL *curlhandle, const char * remotepath, const char * localpath, long timeout, long tries, char * strerror)
//! Uploads the file to the ftp server
//! \param[in] curlhandle CURL handle to do the acutal ftp operation
//! \param[in] remotepath char* holds the remote files path
//! \param[in] localpath char* holds the local files path
//! \param[in] timeout whether to set a timeout for the ftp operation
//! \param[in] tries number of tries for the ftp operation, currently its set to 0
//! \param[out] strerror char* to hold the error string if error happened
//! \return integer
//! value > 0 operations is successfull
//! value <=0 error happend
int upload(CURL *curlhandle, const char * remotepath, const char * localpath,
long timeout, long tries, char * strerror);
//! \fn writefunc(void *buffer, size_t size, size_t nmemb, void *stream)
//! Write block of data from stream of element count of nmemb, and each elements of size size, and stores it in prt
//! \param[out] prt void* to hold the data to be written
//! \param[in] size size_t holds the size of each element to be written
//! \param[in] nmemb size_t holds the number of elements to be written
//! \param[in] stream void* holds the stream to write to
//! \return size_t
//! value > 0 the total number of elements successfully written
//! value = 0 end of stream is reached
//! value < 0 error happened
/*static */size_t writefunc(void *buffer, size_t size, size_t nmemb, void *stream);
//! \fn download(CURL* curlhandle, const char * remoepath, const char * localpath, long timeout, long tries, char * strerror)
//! downloads the file from the ftp server
//! \param[in] curlhandle CURL handle to do the acutal ftp operation
//! \param[in] remotepath char* holds the remote files path
//! \param[in] localpath char* holds the local files path
//! \param[in] timeout whether to set a timeout for the ftp operation
//! \param[in] tries number of tries for the ftp operation, currently its set to 0
//! \param[out] strerror char* to hold the error string if error happened
//! \return integer
//! value > 0 operations is successfull
//! value <=0 error happend
int download(CURL* curlhandle, const char * remoepath, const char * localpath,
long timeout, long tries, char * strerror);
void MyOutputHandler(QtMsgType type, const char *msg);
#endif // GLOBALFUNCTIONS_H
+28
View File
@@ -0,0 +1,28 @@
<RCC>
<qresource prefix="/" >
<file>icons/open.png</file>
<file>icons/rotate-left.png</file>
<file>icons/rotate-right.png</file>
<file>icons/version.png</file>
<file>icons/firstpage.png</file>
<file>icons/lastpage.png</file>
<file>icons/next.png</file>
<file>icons/previous.png</file>
<file>icons/zoomout.png</file>
<file>icons/zoomin.png</file>
<file>icons/find.png</file>
<file>icons/resetzoom.png</file>
<file>icons/ok.png</file>
<file>icons/select.png</file>
<file>icons/cancel.png</file>
<file>icons/pageremove.png</file>
<file>icons/pageadd.png</file>
<file>icons/red_circle.png</file>
<file>icons/green_circle.png</file>
<file>icons/green_selection.png</file>
<file>icons/red_selection.png</file>
<file>icons/yellow_circle.png</file>
<file>icons/no_icon.png</file>
<file>icons/gray_circle.png</file>
</qresource>
</RCC>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 901 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

+332
View File
@@ -0,0 +1,332 @@
/************************************************************************
* $Id: imagecachingdialog.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/imagecachingdialog.cpp $
*
************************************************************************/
#include "imagecachingdialog.h"
#include "ui_imagecachingdialog.h"
#include <QtCore>
#include <QMessageBox>
ImageCachingDialog::ImageCachingDialog(QWidget *parent, QHash<QString, bool> &cachedImages) :
QDialog(parent),
m_ui(new Ui::ImageCachingDialog), m_thread(this), m_cachedImages(cachedImages)
{
m_ui->setupUi(this);
//initalize the bool values
m_generalError = false;
m_terminated = false;
m_completedSuccessfully = false;
//connect the termianted signal
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()));
readSettings();
}
ImageCachingDialog::~ImageCachingDialog()
{
delete m_ui;
if(m_thread.isRunning())
m_thread.quit();
m_timer->stop();
delete m_timer;
m_timer = 0;
}
void ImageCachingDialog::setValues(QStringList srcFiles, QStringList dstFiles)
{
//m_srcPath = srcPath;
m_srcFiles = srcFiles;
//m_dstPath = dstPath;
m_dstFiles = dstFiles;
m_totalFiles = srcFiles.count();
}
bool ImageCachingDialog::createCacheDirectory(QString dstPath)
{
//QString
QDir dir(dstPath);
if( dir.exists() )
return true;
//make the directory if it does not exist
return dir.mkpath( dstPath );
}
/*
bool ImageCachingDialog::recursiveDelete(const QDir &dir)
{
QString abspath = dir.absolutePath();
qDebug() <<abspath.toAscii();
//QList<QFileInfo> infLst = dir.entryInfoList(QStringList("*.jpg"), QDir::NoSymLinks);
QStringList flist = dir.entryList(QStringList("*.jpg"), QDir::NoSymLinks | QDir::Files );
qDebug ("File list is %d", flist.count() );
//foreach(QFileInfo finfo, infLst )
foreach (QString fname, flist)
{
//
if(finfo.isDir() )
{
QDir subDir(finfo.absolutePath());
if (recursiveDelete(subDir) )
return dir.rmdir(subDir.absolutePath());
return false;
}
else
{ //file
QDir dir;
if( !dir.remove(abspath + "/" + fname))
return false;
}
}
return true;
}
*/
/*
void ImageCachingDialog::changeEvent(QEvent *e)
{
QDialog::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
m_ui->retranslateUi(this);
break;
default:
break;
}
}*/
void ImageCachingDialog::keyPressEvent(QKeyEvent *key)
{
if(key->key() == Qt::Key_Escape)//ignore the escape key pressed
return;
QDialog::keyPressEvent(key);
}
void ImageCachingDialog::startCaching()
{
//m_cachedImages.clear();
m_resume = true;
QDir dir;
//QString dstPath = dir.filePath(m_srcFiles[0]);
for(int i=0; i< m_dstFiles.count(); i++)
{
int index = m_dstFiles[i].lastIndexOf("/");
QString path = m_dstFiles[i].left(index);
if(!createCacheDirectory(path))
{
qDebug() << "error creating dst Directory";
return;
}
}
populateFilesFromCacheDirectory();
m_ui->progressBar->setRange(0, m_totalFiles);
//m_thread.setValues(m_srcPath, m_srcFiles, m_dstPath);
m_thread.setValues("", m_srcFiles, "", m_dstFiles);
m_thread.start(); //start the read,
if(m_timer->isActive() )
m_timer->stop();
m_timer->start(1000); //and the timer with 1 sec timeout
}
void ImageCachingDialog::stopCaching()
{
m_thread.terminate();
}
void ImageCachingDialog::pause()
{
m_resume = false;
}
void ImageCachingDialog::resume()
{
m_resume = true;
}
bool ImageCachingDialog::cacheOnePage(QString srcPage, QString dstPage)
{
//m_srcPath = srcpath;
QDir dir;
//QString path = dir.filePath(dstPage);
int index = dstPage.lastIndexOf("/");
QString path = dstPage.left(index);
if (!createCacheDirectory(path) )
return false;
//after we checked the cache directory
if( !m_cachedImages[ dstPage ] )
{
bool ret = false;
if(m_useFtp)
ret = m_thread.cacheFromFtpServer(srcPage, dstPage);
else
ret = m_thread.cacheFromFileServer(srcPage, dstPage);
m_cachedImages[ dstPage ] = ret;
m_totalFilesCompleted++;
}
return true;
}
void ImageCachingDialog::threadTerminated()
{
m_terminated = true; //the user has termianted the process
m_completedSuccessfully = false; //and it has not completed successfully
m_timer->stop();
done(QDialog::Accepted);
}
void ImageCachingDialog::update()
{
if(m_generalError) //if general error has occured, then close the dialog
{
done(QDialog::Accepted);
}
m_ui->progressBar->setValue(m_totalFilesCompleted); //values from the ftp thread
if(m_totalFilesCompleted == m_totalFiles) //if thread is finished with the ftp operation, then close the ImporterDialog box
{
m_timer->stop();
m_thread.wait();
m_completedSuccessfully = true; //set the flag to completed successfully
done(QDialog::Accepted);
//qDebug() << "Thread completed successfully";
}
if( !m_resume)
{
m_timer->stop();
//m_thread.wait();
m_completedSuccessfully = true; //set the flag to completed successfully
done(QDialog::Accepted);
qDebug() << "Thread exited pre-complition";
}
}
bool ImageCachingDialog::completedSuccessfully()
{
return m_completedSuccessfully;
}
bool ImageCachingDialog::terminated()
{
return m_terminated;
}
QString ImageCachingDialog::lastError()
{
return m_errorString;
}
int ImageCachingDialog::cachedFilesCount()
{
return m_totalFilesCompleted;
}
bool ImageCachingDialog::cachingThreadStarted()
{
return m_thread.isRunning();
}
void ImageCachingDialog::populateFilesFromCacheDirectory()
{
QDir dir;
foreach (QString fname, m_dstFiles)
{
if( dir.exists(fname) )
m_cachedImages[fname] = true;
else
m_cachedImages[fname] = false;
}
}
bool ImageCachingDialog::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;
}
bool ImageCachingDialog::useFtp()
{
return m_useFtp;
}
QString ImageCachingDialog::address()
{
return m_address;
}
QString ImageCachingDialog::username()
{
return m_username;
}
QString ImageCachingDialog::password()
{
return m_password;
}
int ImageCachingDialog::port()
{
return m_port;
}
+257
View File
@@ -0,0 +1,257 @@
/************************************************************************
* $Id: imagecachingdialog.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/imagecachingdialog.h $
*
************************************************************************/
#ifndef IMAGECACHINGDIALOG_H
#define IMAGECACHINGDIALOG_H
#include <QtGui/QDialog>
#include <QTimer>
#include <QKeyEvent>
#include "imagecachingthread.h"
namespace Ui {
class ImageCachingDialog;
}
class ImageCachingDialog : public QDialog {
Q_OBJECT
friend class ImageCachingThread;
public:
ImageCachingDialog(QWidget *parent, QHash<QString, bool> &cachedImages);
//! \fn ~ImageCachingDialog()
//! destructor
//! \author elzubeir
~ImageCachingDialog();
//! \fn completedSuccessfully()
//! This function returns whether the ftp operation completed successfully or not
//! \return bool
//! - true if operation completed successfully
//! - false otherwise
//! \author elzubeir
bool completedSuccessfully();
//! \fn terminated()
//! This function returns whether the ftp operation was terminated by user or not
//! \return bool
//! - true if operation terminated by user
//! - false otherwise
//! \author elzubeir
bool terminated();
//! \fn cachedFilesCount()
//! This function returns the number of successfully cached files
//! \return int
//! - the number of files cached successfully
//! \author elzubeir
int cachedFilesCount();
//! \fn lastError()
//! This function returns the last error that occured in the ftp operation
//! \return QString
//! - the last error that happened
//! \author elzubeir
QString lastError();
//! \fn cachingThreadStarted()
//! is the caching process started
//! \return boolean to represent if the caching thread has started or not
//! \author elzubeir
bool cachingThreadStarted();
//! \fn startCaching()
//! stats the caching process
//! \author elzubeir
void startCaching();
//! \fn stopCaching()
//! stops the caching process
//! \author elzubeir
void stopCaching();
//! \fn pause()
//! pause the caching process
//! \author elzubeir
void pause();
//! \fn resume()
//! resume the caching process
//! \author elzubeir
void resume();
//! \fn cacheOnePage()
//! Caches one page from src to local cache directory
//! \param[in] srcPage QString path to the source page
//! \param[in] dstPage QString path to the destination page
//! \return bool
//! true if operation successful
//! false if not
//! \author elzubeir
bool cacheOnePage(QString srcPage, QString dstPage);
//! \fn setValues()
//! set the values for the local and remote file names, this function is used before starting the caching process to map
//! the remote file paths to local file paths
//! \param[in] srcFiles QString list of the source (remote) file paths
//! \param[in] dstFiles QString list of the destination (local) file paths
//! \author elzubeir
void setValues(QStringList srcFiles, QStringList dstFiles );
//! \fn useFtp()
//! this functions returns if the operation to be done on ftp server ot not
//! \return bool
//! true if use ftp
//! false if not
//! \author elzubeir
bool useFtp();
//! \fn address()
//! this functions returns the ftp's address
//! \return QString the ftp's addrss
//! \author elzubeir
QString address();
//! \fn username()
//! this functions returns the ftp's username
//! \return QString the ftp's username
//! \author elzubeir
QString username();
//! \fn password()
//! this functions returns the ftp's password()
//! \return QString the ftp's password
//! \author elzubeir
QString password();
//! \fn port()
//! this functions returns the ftp's port
//! \return int the ftp's port
//! \author elzubeir
int port();
private:
//! \fn createCacheDirectory()
//! This function creates the cache directory on the local device
//! dstPath string holding the path of the cache directory
//! \return bool
//! - true if the cache directory is created successfully
//! - false otherwise
//! \author elzubeir
bool createCacheDirectory(QString dstPath);
//! \fn createCacheDirectory()
//! This function checks if the files for the publication already cached in the directory, if so,
//! it updates the hash object to reflect that case, this function is useful for not re-cache the files from the file/ftp server
//! \author elzubeir
void populateFilesFromCacheDirectory();
//! \fn readSettings()
//! This function reads the settings for the ftp usage from a config.ini file
//! and populate the member variables with the values read from the ini file
//! \return bool
//! - true if all the values are populated
//! - false otherwise
//! \author elzubeir
bool readSettings();
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);
//void changeEvent(QEvent *e);
private slots:
//! \fn update()
//! the update function that is called by the timer's timeout() signal,
//! it updates the GUI to reflect the latest changes from the ftp operation
//! \author elzubeir
void update();
//! \fn update()
//! this function is called in response to threads terminated() singal
//! \author elzubeir
void threadTerminated();
private:
//! pointer to the Qt desginer UI class object
Ui::ImageCachingDialog *m_ui;
//! object of the threading class
ImageCachingThread m_thread;
//! Timer object to do GUI updates, and check status of operations
QTimer * m_timer;
//! the size of the current file being processed by the ftp thread
int m_currentFileSize;
//! the number of completed files already processed by the ftp thread
int m_totalFilesCompleted;
//! the total number of files to be processed by the ftp thread
int m_totalFiles;
//! has the process been termianted by user
bool m_terminated;
//! has the process completed successfully
bool m_completedSuccessfully;
//! has a general error occured
bool m_generalError;
//! the errors string
QString m_errorString;
//! string list containing the source filenames
QStringList m_srcFiles;
//! string list containing the destination filenames
QStringList m_dstFiles;
//! hash object with name of the image, and has it been hashed or not
QHash<QString, bool> &m_cachedImages;
//! resume the thread of not
bool m_resume;
//! 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;
};
#endif // IMAGECACHINGDIALOG_H
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ImageCachingDialog</class>
<widget class="QDialog" name="ImageCachingDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>158</width>
<height>42</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Caching</string>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="toolTip">
<string>Image Caching</string>
</property>
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<property name="value">
<number>0</number>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="textVisible">
<bool>true</bool>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
<property name="textDirection">
<enum>QProgressBar::TopToBottom</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+112
View File
@@ -0,0 +1,112 @@
/************************************************************************
* $Id: imagecachingthread.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/imagecachingthread.cpp $
*
************************************************************************/
#include "imagecachingthread.h"
#include "imagecachingdialog.h"
#include "globalfunctions.h"
#include <QMessageBox>
#include <curl/curl.h>
ImageCachingThread::ImageCachingThread(ImageCachingDialog * dlg):
m_imageCacheDlg(*dlg)
{
}
void ImageCachingThread::setValues(QString srcPath, QStringList srcFiles, QString dstPath, QStringList dstFiles )
{
m_srcPath = srcPath; //src path
m_srcFiles = srcFiles; //src files
m_dstPath = dstPath; //dst path
m_dstFiles = dstFiles; //dst files
}
void ImageCachingThread::run()
{
m_imageCacheDlg.m_totalFilesCompleted = 0; //number of completed files it set to zero
m_dstPath = m_srcPath = "";
//char strerror[256]; //string to hold the error message, if any occurs
for( int i=0; i< m_srcFiles.count(); i++) //iterate thru the files to upload
{
while( !m_imageCacheDlg.m_resume )
return;
//qDebug() << "Copying " << m_srcFiles[i].toAscii();
if (m_imageCacheDlg.m_cachedImages[ m_dstPath+m_dstFiles[i] ] )
{
m_imageCacheDlg.m_totalFilesCompleted++;
}
else
{
bool ret = false;
if(m_imageCacheDlg.useFtp())
ret = cacheFromFtpServer(m_srcPath+m_srcFiles[i], m_dstPath+m_dstFiles[i]);
else
ret = cacheFromFileServer(m_srcPath+m_srcFiles[i], m_dstPath+m_dstFiles[i]);
m_imageCacheDlg.m_cachedImages[ m_dstPath+m_dstFiles[i] ] = ret;
m_imageCacheDlg.m_totalFilesCompleted++;
}
}
}
bool ImageCachingThread::cacheFromFtpServer(QString srcPage, QString dstPage)
{
//remove windows drive letter, if any
QString dst = srcPage.mid(srcPage.indexOf(":")+1, srcPage.length());
//dst = dst.left( dst.length() -1 ); //to remove the last /
//if ( !dst.endsWith("/") )
// dst += "/";
srcPage = dst;
srcPage = QString("ftp://%1:%2@%3/").arg( m_imageCacheDlg.username() ).arg( m_imageCacheDlg.password() ).arg( m_imageCacheDlg.address()) + srcPage;
CURL *curlhandle = NULL; //the libcurl easy handle
curl_global_init(CURL_GLOBAL_ALL); //initate it
curlhandle = curl_easy_init();
char strerror[256];
bool ret = download(curlhandle, srcPage.toAscii(), dstPage.toAscii(), 0, 1, strerror);
curl_easy_cleanup(curlhandle);
curl_global_cleanup();
return ret;
}
bool ImageCachingThread::cacheFromFileServer(QString srcPage, QString dstPage)
{
if (!QFile::exists(dstPage) && !QFile::copy(srcPage, dstPage) )
{
QMessageBox::critical(NULL, tr("Error!"), tr("Error copying image %1 to %2").arg(srcPage).arg(dstPage) );
return false;
}
return true;
}
+92
View File
@@ -0,0 +1,92 @@
/************************************************************************
* $Id: imagecachingthread.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/imagecachingthread.h $
*
************************************************************************/
#ifndef IMAGECACHINGTHREAD_H
#define IMAGECACHINGTHREAD_H
#include <QtCore>
#include <QThread>
class ImageCachingDialog;
class ImageCachingThread : public QThread
{
Q_OBJECT
public:
//! \fn ImageCachingThread()
//! The constructor
//! \param[in] dlg ImageCachingDialog pointer to the UI dialog that created this thread
//! \author elzubeir
ImageCachingThread(ImageCachingDialog * dlg);
//! \fn setValues()
//! \param[in] srcPath QString source path for the files to be cached
//! \param[in] srcFiles QStringList list of files to be copiled
//! \param[in] dstPath QString destination path for the files to be cached
//! \param[in] dstFiles QStringList list of destination names files
//! \author elzubeir
void setValues(QString srcPath, QStringList srcFiles, QString dstPath, QStringList dstFiles);
//! \fn cacheFromFileServer()
//! caches one page from file server to local directory
//! \param[in] srcPage QString source path for the file to be cached
//! \param[in] dstPage QString destination path for the file to be cached
//! \return bool
//! - true if the page chaching is successfull
//! - false otherwise
//! \author elzubeir
bool cacheFromFileServer(QString srcPage, QString dstPage);
//! \fn cacheFromFtpServer()
//! caches one page from ftp server to local directory
//! \param[in] srcPage QString source path for the file to be caeched
//! \param[in] dstPage QString destination path for the file to be cached
//! \return bool
//! - true if the page chaching is successfull
//! - false otherwise
//! \author elzubeir
bool cacheFromFtpServer(QString srcPage, QString dstPage);
protected:
//! \fn run()
//! The starting point for the thread. After calling start(), the thread calls this function
//! where it does the actual ftp process, like uploading of files
void run();
private:
//! a reference to the calling FtpDialog instance that created this thread
ImageCachingDialog& m_imageCacheDlg;
//! to hold the path of the source files
QString m_srcPath;
//! to hold a list of the source files
QStringList m_srcFiles;
//! to hold the path to the destination path, it will be of ftp address,
//! mainly in this format ftp://user:password@ftpaddress/location/to/desired/path
QString m_dstPath;
//! to hold a list of the destination files
QStringList m_dstFiles;
};
#endif // IMAGECACHINGTHREAD_H
+542
View File
@@ -0,0 +1,542 @@
/************************************************************************
* $Id: imagecutout.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/imagecutout.cpp $
*
************************************************************************/
#include "imagecutout.h"
#include <QPen>
#include <QCursor>
#include <QGraphicsSceneMouseEvent>
#include <QApplication>
#include <QDrag>
#include <QMimeData>
#include <QPainter>
#include <QBitmap>
#include <QtDebug>
#include <QByteArray>
#include <QBuffer>
#include "fullpagescene.h"
int ImageCutout::totalCount = 0;
ImageCutout::ImageCutout(int id, const QPolygonF & selectionRect, qreal rotationAngle, QString pagename, SELECTION_AREA_TYPE selectionType, SELECTION_MODE mode, QGraphicsItem * parent) :
QGraphicsPolygonItem(parent),
m_id(id),
m_rotationAngle(rotationAngle),
m_pageName(pagename),
m_selectionType(selectionType),
m_mode(mode)
{
//image is color coded red //tim_tle is color coded bule //body is color coded green
QColor color = Qt::red;
if(m_selectionType == BODY)
color = Qt::green;
else if(m_selectionType == TITLE)
color = Qt::blue;
// color & styles
QPen pen(Qt::DashDotLine);
pen.setColor(color);
pen.setWidth(2);
setPen(pen);
QBrush m_brush;
m_brush.setStyle(Qt::Dense7Pattern);
m_brush.setColor(color);
setBrush(m_brush);
// size
m_rectangle = selectionRect.boundingRect().toRect();
setPolygon(selectionRect);
// zorder on top
setZValue(1.0);
setFlag(QGraphicsItem::ItemIsSelectable, true);
setFlag(QGraphicsItem::ItemIsFocusable,true);
m_isScreenshot = false;
m_tweaking = false;
m_tweakingpart = "";
m_orderTextItem = 0;
m_order = 0;
m_orderTextItem = new QGraphicsSimpleTextItem("", this);
QFont serifFont("Times", 60);
m_orderTextItem->setFont(serifFont);
m_orderTextItem->setPen( QPen( Qt::darkBlue, 3) );
m_orderTextItem->setBrush( Qt::darkBlue);
m_orderTextItem->setPos( m_rectangle.topLeft());
m_orderTextItem->setVisible(false);
}
ImageCutout::~ImageCutout()
{
if(m_orderTextItem)
delete m_orderTextItem;
m_orderTextItem = 0;
}
void ImageCutout::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (m_mode != SELECT)
return;
if (event->button() != Qt::LeftButton)
{
event->ignore();
return;
}
checkBoundary(event->pos().toPoint(), true);
if(m_tweakingpart != "")
m_tweaking = true;
}
void ImageCutout::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if (m_mode != SELECT)
{
if(m_mode == ORDER)
setCursor( QCursor(Qt::PointingHandCursor) );
else
setCursor( QCursor(Qt::ArrowCursor) );
return;
}
if(m_orderTextItem)
m_orderTextItem->setVisible(false);
if(m_tweaking)
{
QPoint pt = event->pos().toPoint();
m_rectangle = this->boundingRect().toRect();
if ( m_tweakingpart == "topLeft" ) m_rectangle . setTopLeft ( pt ) ;
else if ( m_tweakingpart == "topRight" ) m_rectangle . setTopRight ( pt ) ;
else if ( m_tweakingpart == "bottomLeft" ) m_rectangle . setBottomLeft ( pt ) ;
else if ( m_tweakingpart == "bottomRight" ) m_rectangle . setBottomRight ( pt ) ;
else if ( m_tweakingpart == "top" ) m_rectangle . setTop ( pt . y () ) ;
else if ( m_tweakingpart == "bottom" ) m_rectangle . setBottom ( pt . y () ) ;
else if ( m_tweakingpart == "left" ) m_rectangle . setLeft ( pt . x () ) ;
else if ( m_tweakingpart == "right" ) m_rectangle . setRight ( pt . x () ) ;
update(m_rectangle);
}
else
{
QImage cutout = createCutout();
if (cutout.isNull())
return;
//qDebug() << "create image ...";
QDrag *drag = new QDrag(event->widget());
QMimeData *mime = new QMimeData;
QByteArray output;
QBuffer outputBuffer(&output);
outputBuffer.open(QIODevice::WriteOnly);
cutout.save(&outputBuffer, "jpg", 100);
mime->setData("image/jpg", output); //save a copy
drag->setMimeData(mime);
mime->setImageData(cutout);
qreal scale = (static_cast<FullPageScene*>(scene()) )->A4PageScale();
drag->setPixmap(QPixmap::fromImage(cutout).scaledToWidth( cutout.width()*scale) );
//drag->setPixmap(selectedImage);
drag->setHotSpot(QPoint(0,0));
drag->exec();
}
}
void ImageCutout::mouseReleaseEvent(QGraphicsSceneMouseEvent *)
{
if(m_mode == VIEW)
return;
if(m_mode == ORDER)
{
orderItems();
return;
}
m_tweaking = false ;
m_tweakingpart = "" ;
//this -> unsetCursor () ;
setCursor(QCursor(Qt::OpenHandCursor));
m_rectangle = m_rectangle.normalized();
update(this->boundingRect().toRect());
if(m_orderTextItem)
m_orderTextItem->setPos( m_orderTextItem->mapToParent(0, 0) );
}
QImage ImageCutout::createCutout() const
{
if(m_mode != SELECT)
return QImage();
// get selection rect in scene coordinates.
QRectF sceneRect = mapRectToScene(boundingRect());
// convert the scene coordinates to item coordinates.
QPointF topLeftCorner = static_cast<FullPageScene*>(scene())->mapToImageItem(QPointF(sceneRect.left(), sceneRect.top()));
QPointF bottomRightCorner = static_cast<FullPageScene*>(scene())->mapToImageItem(QPointF(sceneRect.right(), sceneRect.bottom()));
// exm_tract the selection fragment from the pixmap.
QPixmap px = static_cast<FullPageScene*>(scene())->getImageCutoutPixmap(QRectF(topLeftCorner, bottomRightCorner));
if (!px.isNull())
{
// after calculating the pixmap, we rotate it if needed
QImage image = px.toImage();
QMatrix mx;
mx = mx.rotate(m_rotationAngle);
// mx = mx.scale(.5, .5); //dont do this
image = image.transformed(mx);
return image;
}
return QImage();
}
void ImageCutout::keyPressEvent(QKeyEvent *key)
{
if(m_mode != SELECT)
return;
if(key->key() == Qt::Key_I)
m_selectionType = IMAGE;
else if(key->key() == Qt::Key_T)
m_selectionType = TITLE;
else if(key->key() == Qt::Key_B)
m_selectionType = BODY;
else if(key->key() == Qt::Key_Delete)
{
decreaseOrderByOne(m_order);
//staticCount--;
static_cast<FullPageScene*>(scene())->removeImageCutout(this);
//scene()->removeItem(this);
return;
}
else
{
QGraphicsPolygonItem::keyPressEvent(key);
return;
}
scene()->update(sceneBoundingRect());
//update();
}
bool ImageCutout::operator == (const ImageCutout & cutout)
{
return this->boundingRect() == cutout.boundingRect();
}
void ImageCutout::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget */*widget*/)
{
painter->setClipRect(option->exposedRect);
QColor color = Qt::yellow;
if(m_selectionType == IMAGE)
color = Qt::red;
if(m_selectionType == BODY)
color = Qt::green;
else if(m_selectionType == TITLE)
color = Qt::blue;
QPen pen(Qt::NoPen);
if(m_mode == VIEW)
pen.setStyle(Qt::SolidLine);
pen.setColor(color);
pen.setWidth(2);
painter->setPen(pen);
QBrush m_brush;
if (m_mode == VIEW)
{
m_brush.setStyle(Qt::NoBrush);
this->setSelected(false);
}
else
{
m_brush.setStyle(Qt::SolidPattern);
if(m_isScreenshot)
{
this->setOpacity(.7);
this->setSelected(false);
}
else
this->setOpacity(.2);
}
if(m_orderTextItem)
{
if(m_mode == ORDER)
{
QString text = QString("%1").arg(m_order);
m_orderTextItem->setText(text);
m_orderTextItem->setPos( boundingRect().topLeft() );
m_orderTextItem->setVisible(true);
}
else
m_orderTextItem->setVisible(false);
}
m_brush.setColor(color);
painter->setBrush(m_brush);
QPolygon ply(m_rectangle, true);
setPolygon(ply);
painter->drawPolygon(polygon(), fillRule());
scene()->update(sceneBoundingRect());
}
int ImageCutout::id()
{
return m_id;
}
QString ImageCutout::pageName()
{
return m_pageName;
}
int ImageCutout::pageNumber()
{
QString page = m_pageName;
int index = page.lastIndexOf("/");
int pagenumber = page.right(page.length()-index-1).replace(".jpg", "").toInt();
return pagenumber;
}
int ImageCutout::sectionNumber()
{
QString page = m_pageName;
int index = page.lastIndexOf("/");
int index2 = page.lastIndexOf("/", index-1);
int id_section = page.mid(index2+1, abs(index2-index)-1).toInt();
return id_section;
}
int ImageCutout::areaType()
{
return static_cast<int> (m_selectionType);
}
void ImageCutout::setScreenshot(bool screenshot)
{
m_isScreenshot = screenshot;
update(this->boundingRect().toRect());
}
void ImageCutout::checkBoundary(QPoint pt, bool t)
{
if(m_mode == VIEW)
return;
m_rectangle = this->boundingRect().toRect();
if ( m_rectangle.isValid() )
{
QPoint m_tl = m_rectangle.topLeft();
QPoint m_tr = m_rectangle.topRight();
QPoint m_bl = m_rectangle.bottomLeft();
QPoint m_br = m_rectangle.bottomRight();
const QPoint off(20, 20), offx(20, -20), offy(-20, 20);
if ( QRect(m_tl-off,m_tl+off).contains(pt) )
{
if (t)
m_tweakingpart = "topLeft";
this->setCursor( Qt::SizeFDiagCursor ) ;
}
else if( QRect(m_tr-off, m_tr+off).contains(pt) )
{
if (t)
m_tweakingpart = "topRight";
this->setCursor( Qt::SizeBDiagCursor ) ;
}
else if( QRect( m_bl-off, m_bl+off ).contains(pt) )
{
if (t)
m_tweakingpart = "bottomLeft";
this->setCursor( Qt::SizeBDiagCursor) ;
}
else if( QRect( m_br-off, m_br+off).contains(pt) )
{
if (t)
m_tweakingpart = "bottomRight" ;
this->setCursor( Qt::SizeFDiagCursor );
}
else if( QRect( m_tl+offx, m_tr-offx ).contains(pt) )
{
if (t)
m_tweakingpart = "top";
this->setCursor( Qt::SizeVerCursor ) ;
}
else if( QRect( m_bl+offx, m_br-offx ).contains(pt) )
{
if (t)
m_tweakingpart = "bottom";
this->setCursor( Qt::SizeVerCursor ) ;
}
else if( QRect( m_tl+offy, m_bl-offy ).contains(pt) )
{
if (t)
m_tweakingpart = "left";
this->setCursor( Qt::SizeHorCursor ) ;
}
else if( QRect( m_tr+offy, m_br-offy ).contains(pt) )
{
if (t)
m_tweakingpart = "right";
this->setCursor( Qt::SizeHorCursor );
}
else
this->setCursor( Qt::OpenHandCursor );
}
}
QRectF ImageCutout::boundingRect() const
{
return QRectF(m_rectangle);
}
QString ImageCutout::pages(QList<ImageCutout*> &list)
{
if (list.count() <= 0 )
return "";
QStringList names;
QStringList fullnamesList;
for(int i=0; i< list.count() ; i++)
{
QString page = list[i]->pageName();
if ( !fullnamesList.contains(page) )
{
fullnamesList.append(page);
int index = page.lastIndexOf("/");
QString name = page.right(page.length()-index-1).replace(".jpg", "");
int number = name.toInt();
name = QString("%1").arg(number);
names.append(name);
}
}
return names.join(",");
}
QStringList ImageCutout::fullPages(QList<ImageCutout*> &list)
{
QStringList fullnamesList;
if (list.count() <= 0 )
return fullnamesList;
for(int i=0; i< list.count() ; i++)
{
QString page = list[i]->pageName();
if ( !fullnamesList.contains(page) )
fullnamesList.append(page);
}
return fullnamesList;
}
void ImageCutout::decreaseOrderByOne(int greaterThanOrder)
{
QList<ImageCutout*> list = static_cast<FullPageScene*> (scene() )->imageCutoutsList();
foreach (ImageCutout *cutout, list)
{
if(cutout->order() >= greaterThanOrder)
cutout->setOrder(cutout->order()-1);
}
}
void ImageCutout::orderItems()
{
FullPageScene *fullpageScene = static_cast<FullPageScene*> (scene() );
QList<ImageCutout*> list = fullpageScene->imageCutoutsList();
ImageCutout * firstItem = 0;
foreach (ImageCutout *cutout, list)
{
if(cutout->order() == fullpageScene->currentOrder() )
{
fullpageScene->increaseCurrentOrder();
firstItem = cutout;
break;
}
}
//swap between the 2 m_orderTextItems
int firstOrder = firstItem->order();
int secondOrder= this->order();
this->setOrder(firstOrder);
firstItem->setOrder(secondOrder);
this->update(this->boundingRect());
firstItem->update(firstItem->boundingRect());
}
void ImageCutout::setMode(SELECTION_MODE mode)
{
m_mode = mode;
update(this->boundingRect().toRect());
}
void ImageCutout::setOrder(int order)
{
m_order = order;
}
int ImageCutout::order()
{
return m_order;
}
int ImageCutout::getTotalCount()
{
return totalCount;
}
void ImageCutout::setTotalCount(int count)
{
totalCount = count;
}
void ImageCutout::incrementTotalCount()
{
totalCount++;
}
void ImageCutout::decrementTotalCount()
{
totalCount--;
}
+230
View File
@@ -0,0 +1,230 @@
/************************************************************************
* $Id: imagecutout.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/imagecutout.h $
*
************************************************************************/
#ifndef IMAGECUTOUT_H
#define IMAGECUTOUT_H
#include <QGraphicsPolygonItem>
#include <QGraphicsSimpleTextItem>
#include <QKeyEvent>
#include <QtDebug>
#include "constants.h"
class ImageCutout : public QGraphicsPolygonItem
{
public:
//! \fn ImageCutout()
//! constructor
//! \param[in] id: of the cutout
//! \param[in] selectionRect: the selection rectangle
//! \param[in] roation: the rotation angle;
//! \param[in] type of the created selection, image, title or body
//! \param[in] mode of the selection
//! \author elzubeir
ImageCutout(int id, const QPolygonF & selectionRect, qreal rotationAngle, QString pagename, SELECTION_AREA_TYPE selectionType, SELECTION_MODE mode = SELECT, QGraphicsItem * parent = 0); ///< ctor
//! \fn ~ImageCutout()
//! destructor
//! \author elzubeir
virtual ~ImageCutout(); ///< dtor
//! \fn operator ==()
//! assignment operator
//! \author elzubeir
bool operator == (const ImageCutout & cutout);
//! \fn paint()
//! override the paints function
//! \author elzubeir
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
//! \fn id()
//! returns the id of the cutout
//! \author elzubeir
int id();
//! \fn order()
//! returns the order of the cutout
//! \author elzubeir
int order();
//! \fn pageName()
//! returns the page name of the cutout
//! \author elzubeir
QString pageName();
//! \fn pageName()
//! returns the number in the page name of the cutout
//! \author elzubeir
int pageNumber();
//! \fn sectionNumber()
//! returns the section id of the cutout
//! \author elzubeir
int sectionNumber();
//! \fn areaType()
//! returns the area type of the cutout
//! \author elzubeir
int areaType();
//! \fn setScreenshot()
//! is this is a screen-shot mode
//! \param[in] screenshot value to check if a screen shot mode or not
//! \author elzubeir
void setScreenshot(bool screenshot = false);
//! \fn setMode()
//! set the seletion mode of the cutout
//! \param[in] selectiom mode type
//! \author elzubeir
void setMode(SELECTION_MODE mode);
//! \fn boundingRect()
//! the bounding rectangle of the item
//! \returns the bounding rectangle of the item
//! \author elzubeir
QRectF boundingRect() const;
//! \fn checkBoundary()
//! check if the point is on the item's boundaries
//! \param[in] point of the current point to check
//! \param[in] bool for tweaking part.
//! \author elzubeir
void checkBoundary(QPoint pt, bool t);
void decreaseOrderByOne(int greaterThanOrder);
//! \fn setOrder()
//! set the order of the cutout
//! \param[in] order number
//! \author elzubeir
void setOrder(int order);
//! \fn orderItems()
//! order cutouts
//! \author elzubeir
void orderItems();
//! \fn createCutout()
//! creates the image cutout
//! \author elzubeir
QImage createCutout() const;
//! \fn pages()
//! retusn the distinct pages of the cutouts list, seperated by ,
//! \param[in] list of cutouts
//! \return name of pages seperated by ,
//! \author elzubeir
static QString pages(QList<ImageCutout*> &list);
//! \fn pages()
//! retusn the distinct fu ll page names of the cutouts list, seperated by ,
//! \param[in] list of cutouts
//! \return string list of page names
//! \author elzubeir
static QStringList fullPages(QList<ImageCutout*> &list);
//! \fn getTotalCount()
//! returns the totoal number of cutouts
//! \author elzubeir
static int getTotalCount();
//! \fn setTotalCount()
//! set the total number of count
//! \param[in] count number
//! \author elzubeir
static void setTotalCount(int count);
//! \fn incrementTotalCount()
//! increment the total number of count by 1
//! \author elzubeir
static void incrementTotalCount();
//! \fn decrementTotalCount()
//! decrement the total number of count by 1
//! \author elzubeir
static void decrementTotalCount();
protected:
//! \fn mousePressEvent()
//! overrides the function
//! \author elzubeir
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
//! \fn mouseMoveEvent()
//! overrides the function
//! \author elzubeir
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event);
//! \fn mouseReleaseEvent()
//! overrides the function
//! \author elzubeir
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
//! \fn keyPressEvent()
//! overrides the keyPressEvent() function
//! \author elzubeir
virtual void keyPressEvent(QKeyEvent *key);
private:
//! id of the cutout
int m_id;
//! order of the cutout
int m_order;
//! rotation angle
qreal m_rotationAngle;
//! page name from where the cutout is taken
QString m_pageName;
//! is the mode in screenshot
bool m_isScreenshot;
//! are we twaking, or not
bool m_tweaking;
//! what is the tweaking part
QString m_tweakingpart ;
//! points for top/let, top/right, bottom/left, bottom/right
QPoint m_tl, m_tr, m_bl, m_br ;
//! rectangle of the current item
QRect m_rectangle;
//! selection type
SELECTION_AREA_TYPE m_selectionType;
//! selection mode
SELECTION_MODE m_mode;
//! order item to show the order number
QGraphicsSimpleTextItem *m_orderTextItem;
//! total cutout count
static int totalCount;
};
#endif // IMAGECUTOUT_H
+49
View File
@@ -0,0 +1,49 @@
/************************************************************************
* $Id: imageitem.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/imageitem.cpp $
*
************************************************************************/
#include "imageitem.h"
#include <QGraphicsSceneMouseEvent>
#include <QCursor>
#include <QtDebug>
ImageItem::ImageItem(const QPixmap & pixmap, QGraphicsItem * parent) :
QGraphicsPixmapItem(pixmap, parent)
{
setZValue(0.5);
setCursor(QCursor(Qt::CrossCursor));
}
ImageItem::~ImageItem()
{
}
QPixmap ImageItem::getImageCutoutPixmap(const QRectF & selectionRect) const
{
QPixmap sourcePixmap = pixmap();
if (sourcePixmap.isNull())
return QPixmap();
// qDebug() << "sel rect " << selectionRect << " image rect " << sourcePixmap.rect();
// we cut selection rect to pixmap limit.
// if we don't do this, resulting pixmap after copy operation could be filled with black
return sourcePixmap.copy(selectionRect.toRect());
}
+50
View File
@@ -0,0 +1,50 @@
/************************************************************************
* $Id: imageitem.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/imageitem.h $
*
************************************************************************/
#ifndef IMAGE_ITEM_H
#define IMAGE_ITEM_H
#include <QGraphicsPixmapItem>
/**
\brief Purpose of this class is to dispaly the source image loaded by the user.
*/
class ImageItem : public QGraphicsPixmapItem
{
public:
//! \fn ImageItem()
//! constructor
//! \param[in] pixmp the image pixmap
//! \param[in] parent
//! \author elzubeir
ImageItem(const QPixmap & pixmap, QGraphicsItem * parent = 0); ///< ctor
//! \fn ~ImageCutout()
//! destructor
virtual ~ImageItem(); ///< dtor
//! \fn getImageCutoutPixmap()
//! copy the selectted rectnagle
//! \param[in] the selected rectangle
//! \returns pixmap cut.
//! \author elzubeir
QPixmap getImageCutoutPixmap(const QRectF & selectionRect) const;
};
#endif // IMAGE_ITEM_H
+234
View File
@@ -0,0 +1,234 @@
/************************************************************************
* $Id: importerthread.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/importerthread.cpp $
*
************************************************************************/
#include "importerthread.h"
#include "Importer/importerdialog.h"
#include "globalfunctions.h"
#include "constants.h"
#include <QMessageBox>
#include <curl/curl.h>
ImporterThread::ImporterThread(ImporterDialog *dlg)
: m_dlg(*dlg)
{
}
void ImporterThread::set(QString srcPath, QStringList srcFiles, QString dstPath, QStringList dstFiles, bool skipOcr)
{
m_srcPath = srcPath;
m_srcFiles= srcFiles;
m_dstPath = dstPath;
m_dstFiles= dstFiles;
m_skipOcr = skipOcr;
}
void ImporterThread::run()
{
if(m_dlg.m_useFtp)
upload();
else
copy();
emit importerThreadCompleted();
}
void ImporterThread::copy()
{
QDir dir;
qDebug() << "Creating the directory for the " << m_dstPath << "/" << HIGH_RES_IMAGE_DIR;
if ( !dir.exists(m_dstPath + HIGH_RES_IMAGE_DIR) )
{
bool ok = dir.mkpath(m_dstPath + HIGH_RES_IMAGE_DIR); //this function creates the path, with all its necessary parents;
if(!ok)
{
//error message, could not create the required directory structure!
//qDebug() << "Path: " << destPath + HIGH_RES_IMAGE_DIR;
QMessageBox::critical(NULL, tr("Error!"), tr("Error creating directory structure for path %1").arg(m_dstPath));
m_dlg.m_completedSuccessfully = false;
return;
}
}
m_dlg.m_totalFilesCompleted = 0; //number of completed files it set to zero
for( int i=0; i< m_srcFiles.count(); i++) //iterate thru the files to upload
{
g_currentUpload = 0; //sets the gloal variable that represents the numer of bytes currently uploaded ot the ftp server, its reset for every file uploaded
QFileInfo f(QString(m_srcPath + m_srcFiles[i])); //get the current files size
m_dlg.m_currentFileSize = f.size();
//get a 96 dip image to save.
QString image96DpiFilePath = get96DPIImagePath(m_srcPath+ m_srcFiles[i]);
if(image96DpiFilePath == "")
continue;
if( !QFile::copy(image96DpiFilePath, m_dstPath+ m_dstFiles[i]) )
{
//QMessageBox::critical(this, tr("Error!"), tr("Error copying 96 dpi image %1 to %2.%3").arg(image96DpiFilePath).arg(dstPath).arg(dstFiles[i]) );
//m_dlg.m_errorString = "";
qDebug() << "Error copying 96 dpi image " << image96DpiFilePath << " to " << m_dstPath << "/" << m_dstFiles[i];
m_dlg.m_completedSuccessfully = false;
//m_dlg.m_generalError = true;
}
else
{
//we double check that its really copied
int j = 0;
while(!QFile::exists(m_dstPath + m_dstFiles[i]) && j < 2)
{
if( !QFile::copy(image96DpiFilePath, m_dstPath+ m_dstFiles[i]) )
{
//QMessageBox::critical(this, tr("Error!"), tr("Error copying 96 dpi image %1 to %2.%3").arg(filepath).arg(dstPath).arg(dstFiles[i]) );
//m_dlg.m_errorString = "";
qDebug() << "Error copying 96 dpi image " << image96DpiFilePath << " to " << m_dstPath << "/" << m_dstFiles[i];
m_dlg.m_completedSuccessfully = false;
//m_dlg.m_generalError = true;
}
j++;
}
if(j < 2)
m_dlg.m_totalFilesCompleted++;//no error happened, increase the number of completed files by 1
}
//finally we remove the 96 dip from our station
QFile::remove(image96DpiFilePath);
if(!m_skipOcr)
{
if( !QFile::copy(m_srcPath+ m_srcFiles[i], m_dstPath+ HIGH_RES_IMAGE_DIR + m_dstFiles[i]) )
{
//QMessageBox::critical(this, tr("Error!"), tr("Error copying 300dip image %1 to %2").arg(m_srcFiles[i]).arg(m_dstPath).arg(m_dstFiles[i]) );
qDebug() << "Error copying 300 dpi image " << m_srcPath+ m_srcFiles[i] << " to " << m_dstPath+ HIGH_RES_IMAGE_DIR + m_dstFiles[i];
}
}
}
/*
for(int i=0; i< dstFiles.count(); i++)
{
if ( conflictList.contains(dstFiles[i], Qt::CaseInsensitive) )
{
if( !QFile::remove(dstPath+dstFiles[i]))
{
QMessageBox::critical(this, tr("Error!"), tr("Error deleting image %1 from issues path %2").arg(dstFiles[i]).arg(dstPath) );
}
}
}
*/
}
void ImporterThread::upload()
{
CURL *curlhandle = NULL; //the libcurl easy handle
curl_global_init(CURL_GLOBAL_ALL); //initate it
curlhandle = curl_easy_init();
m_dlg.m_totalFilesCompleted = 0; //number of completed files it set to zero
char strerror[256]; //string to hold the error message, if any occurs
for( int i=0; i< m_srcFiles.count(); i++) //iterate thru the files to upload
{
g_currentUpload = 0; //sets the gloal variable that represents the numer of bytes currently uploaded ot the ftp server, its reset for every file uploaded
QString image96DpiFilePath = get96DPIImagePath(m_srcPath+ m_srcFiles[i]);
if(image96DpiFilePath == "")
continue;
QFileInfo f(image96DpiFilePath); //get the current files size
m_dlg.m_currentFileSize = f.size();
//do the actual upload process
//first we upload the 96 dpi, then we upload the 300 dpi
if (!::upload(curlhandle, QString(m_dstPath + m_dstFiles[i]).toAscii(), image96DpiFilePath.toAscii(), 0, 1, strerror))
{
//if error happens, then set the apropriate values for the calling object, and exit the thread
QString errMsg(strerror);
//m_dlg.m_errorString = errMsg;
m_dlg.m_completedSuccessfully = false;
//m_dlg.m_generalError = true;
}
else
{
if(!m_skipOcr)
{
g_currentUpload = 0; //sets the gloal variable that represents the numer of bytes currently uploaded ot the ftp server, its reset for every file uploaded
QFileInfo f2(QString(m_srcPath + m_srcFiles[i])); //get the current files size
m_dlg.m_currentFileSize = f2.size();
if (!::upload(curlhandle, QString(m_dstPath + m_dstFiles[i]).toAscii(), QString(m_srcPath + m_srcFiles[i]).toAscii(), 0, 1, strerror))
{
//if error happens, then set the apropriate values for the calling object, and exit the thread
QString errMsg(strerror);
//m_dlg.m_errorString = errMsg;
m_dlg.m_completedSuccessfully = false;
}
}
m_dlg.m_totalFilesCompleted++;//no error happened, increase the number of completed files by 1
}
QFile::remove(image96DpiFilePath);
}
//clean up before exit
curl_easy_cleanup(curlhandle);
curl_global_cleanup();
}
QString ImporterThread::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";
//qDebug() << "get96DPIImagePath(): 96 dpi Image path: " << filename96;
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 "";
}
}
+105
View File
@@ -0,0 +1,105 @@
/************************************************************************
* $Id: importerthread.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/importerthread.h $
*
************************************************************************/
#ifndef IMPORTERTHREAD_H
#define IMPORTERTHREAD_H
#include <QtCore>
#include <QThread>
class ImporterDialog;
//! \class ImporterThread
//! This is a thread class to implement different ftp operations like uploading of files inside a thread
class ImporterThread : public QThread
{
Q_OBJECT
public:
//! \fn ImporterThread()
//! The constructor
//! \see ImporterDialog();
//! \param[in] ftp ImporterDialog pointer to the UI dialog that created this thread
//! \author elzubeir
ImporterThread(ImporterDialog* dlg);
//! \fn set()
//! sets the value for the thread
//! \param[in] srcPath QString source path for the files to be copied
//! \param[in] srcFiles QStringList list of files to be copiled
//! \param[in] dstPath QString destination path for the files to be copied
//! \param[in] dstFiles QStringList list of destination names files
//! \author elzubeir
void set(QString srcPath, QStringList srcFiles, QString dstPath, QStringList dstFiles, bool skipOcr);
signals:
//! \fn importerThreadCompleted()
//! signal is fired when the thread has completed
//! \author elzubeir
void importerThreadCompleted();
protected:
//! \fn run()
//! The starting point for the thread. After calling start(), the thread calls this function
//! where it does the actual ftp process, like uploading of files
//! \author elzubeir
void run();
private:
//! \fn upload()
//! upload the image to ftp server
//! \author elzubeir
void upload();
//! \fn copy()
//! copy the image to file server
//! \author elzubeir
void copy();
//! \fn get96DPIImagePath()
//! get the 96 dip image path to copy to file server while importing
//! \param[in] filename: name of the 300 dpi image
//! \author elzubeir
QString get96DPIImagePath(QString filename);
private:
//! a reference to the calling ImporterDialog instance that created this thread
ImporterDialog& m_dlg;
//! to hold the path of the source files
QString m_srcPath;
//! to hold a list of the source files
QStringList m_srcFiles;
//! to hold the path to the destination path, it will be of ftp address,
//! mainly in this format ftp://user:password@ftpaddress/location/to/desired/path
QString m_dstPath;
//! to hold a list of the destination files
QStringList m_dstFiles;
//! skip ocr
bool m_skipOcr;
};
#endif // IMPORTERTHREAD_H
+575
View File
@@ -0,0 +1,575 @@
/************************************************************************
* $Id: issue.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/issue.cpp $
*
************************************************************************/
#include "issue.h"
#include "imagecutout.h"
Issue::Issue(int id, QString date, int publication_id) : m_id(id)
, m_date(date), m_publicationId(publication_id)
{
//m_currentSectionIndex = -1;
m_model = 0;
m_isArticleLoaded = false;
m_isLoaded = false;
}
Issue::~Issue()
{
//qDebug("~Issue()");
if(m_model)
delete m_model;
//qDebug("end of ~Issue()");
}
bool Issue::operator == (const Issue &issue)
{
//qDebug() << "Compare between " << m_date << " and " << issue.m_date;
return (this->m_date == issue.m_date);
}
void Issue::set(int id, QString date, int pubid, int status, QString created)
{
m_id = id;
m_date = date;
m_publicationId = pubid;
m_status = status;
m_created = created;
}
void Issue::setIssuePaths(QString lpath, QString rpath)
{
m_localIssuePath = lpath;
m_remoteIssuePath = rpath;
}
void Issue::addSection(Section section)
{
m_sections.append(section);
}
void Issue::setIsLoaded(bool isLoaded)
{
m_isLoaded = isLoaded;
}
int Issue::id()
{
return m_id;
}
QString Issue::date()
{
return m_date;
}
int Issue::status()
{
return m_status;
}
QString Issue::created()
{
return m_created;
}
bool Issue::isLoaded()
{
return m_isLoaded;
}
QList<Section> Issue::sections()
{
return m_sections;
}
Section& Issue::section(QString sectionName)
{
int index = m_sections.indexOf(Section(0, sectionName) );
Q_ASSERT(index > -1);
return m_sections[index];
}
Article& Issue::preclip(int id)
{
//Article x;
//x.setId(id);
//int index = m_preclipped.indexOf(x);
//Q_ASSERT(index > -1);
for(int i=0; i< m_preclipped.count(); i++)
{
if(m_preclipped[i].id() == id)
return m_preclipped[i];
}
return m_preclipped[0];
}
Article& Issue::clip(int id)
{
/* Article x;
x.setId(id);
int index = m_clipped.indexOf(x);
Q_ASSERT(index > -1);
return m_clipped[index];*/
for(int i=0; i< m_clipped.count(); i++)
{
if(m_clipped[i].id() == id)
return m_clipped[i];
}
return m_clipped[0];
}
/*
void Issue::setCurrentSection(QString sectionName)
{
//m_currentSectionIndex = m_sections.indexOf(Section(0, sectionName) );
//qDebug("Current Issue is %d", m_currentSectionIndex);
}
*/
/*
Section Issue::currentSection()
{
qDebug("*******************Current Issue is %d", m_currentSectionIndex);
if( m_currentSectionIndex > -1)
return m_sections[m_currentSectionIndex];
return Section(0, "");
}
*/
void Issue::loadArticles(QSqlDatabase &database, FILTER_MODE mode)
{
if (mode == NO_FILTER)
{
m_preclipped = Article::preclippedArticles(database, m_publicationId, m_id, m_localIssuePath, m_remoteIssuePath);
m_clipped = Article::clippedArticles (database, m_publicationId, m_id, m_localIssuePath, m_remoteIssuePath);
}
else
{
m_preclipped = Article::preclippedArticles(database, m_publicationId, m_id, m_localIssuePath, m_remoteIssuePath);
m_clipped = QList<Article>();
}
setModelData();
}
void Issue::showArticlesInView(QSqlDatabase &database, QTreeView *view, FILTER_MODE mode)
{
if(!m_isArticleLoaded)
{
loadArticles(database, mode);
m_isArticleLoaded = true;
}
m_model->setParent(view->parent());
view->setModel(m_model);
view->hideColumn(1);
}
void Issue::addArticleToView(QSqlDatabase &database, QTreeView *view, int articleId, bool isclip, bool frompreclip)
{
//the addition can be a clip or a preclip
//if its a preclip, we get its data from database
if(!isclip) //its a preclip
{
if(frompreclip) //a modification of a preclip
{
Article ar = Article::article(database, articleId, m_localIssuePath, m_remoteIssuePath);
int index = -1;
//we remove the preclip from the preclip itemlist, and add it to the clip item list
for(int i=0; i< m_preclipped.count(); i++)
{
if(m_preclipped[i].id() == articleId)
{
index = i;
break;
}
}
if(index == -1)
return; //something wrong, it should not be there
m_preclipped.removeAt(index);
m_preclipped.insert(index, ar);
QStandardItemModel *model = static_cast<QStandardItemModel*> ( view->model() );
QModelIndex preclipRootIndex = model->index(0, 0, QModelIndex() ); //now we remove the data from the model
QStandardItem * preclipRootItem = model->item(0, 0);
preclipRootItem->removeRow(index);
QIcon icon( (ar.status() == 1) ? ":/icons/red_circle.png" : ":/icons/green_circle.png");
QStandardItem * preclipItem = new QStandardItem(icon, QObject::tr("Preclip (%1)").arg(index+1));
preclipRootItem->insertRow(index, preclipItem);
preclipRootItem->setChild(index, 1, new QStandardItem(QString("%1").arg( articleId )) );
QStringList pages = ar.pageNames();
for(int i= 0; i < pages.count(); i++)
preclipItem->appendRow(new QStandardItem(QString("%1").arg(pages[i]) ) );
}
else
{
//its a fresh preclip
Article ar = Article::article(database, articleId, m_localIssuePath, m_remoteIssuePath);
m_preclipped.append(ar);
QStandardItemModel *model = static_cast<QStandardItemModel*> ( view->model() );
QModelIndex preclipRootIndex = model->index(0, 0, QModelIndex() ); //now we remove the data from the model
QStandardItem * preclipRootItem = model->item(0, 0);
QIcon icon( (ar.status() == 1) ? ":/icons/red_circle.png" : ":/icons/green_circle.png");
QStandardItem * preclipItem = new QStandardItem(icon, QObject::tr("Preclip (%1)").arg(m_preclipped.count()));
preclipRootItem->appendRow(preclipItem);
preclipRootItem->setChild(m_preclipped.count() -1 , 1, new QStandardItem(QString("%1").arg( articleId )) );
QStringList pages = ar.pageNames();
for(int i= 0; i < pages.count(); i++)
preclipItem->appendRow(new QStandardItem(QString("%1").arg(pages[i]) ) );
}
}
else
{
//its a clip
//we have 2 cases, either it came from a preclip
if(frompreclip)
{
int index = -1;
//we remove the preclip from the preclip itemlist, and add it to the clip item list
for(int i=0; i< m_preclipped.count(); i++)
{
if(m_preclipped[i].id() == articleId)
{
index = i;
break;
}
}
if(index == -1)
return; //something wrong, it should not be there
//Article ar = m_preclipped[index];
Article ar = Article::article(database, articleId, m_localIssuePath, m_remoteIssuePath);
m_preclipped.removeAt(index);
m_clipped.append(ar);
QStandardItemModel *model = static_cast<QStandardItemModel*> ( view->model() );
QModelIndex preclipRootIndex = model->index(0, 0, QModelIndex() ); //now we remove the data from the model
model->removeRow(index, preclipRootIndex);
//add an entry in the model view
QModelIndex clipIndex = model->index(1, 0, QModelIndex() );
//now we remove the data from the model
QStandardItem * clipRootItem = model->item(1, 0);
QStandardItem * clipItem = new QStandardItem( QObject::tr("Clip (%1)").arg(m_clipped.count()));
clipRootItem->appendRow(clipItem);
clipRootItem->setChild(m_clipped.count() -1 , 1, new QStandardItem(QString("%1").arg( articleId )) );
//columns.append(new QStandardItem(QString("%1").arg( articleId ); //save the article ID
QStringList pages = ar.pageNames();
for(int i= 0; i < pages.count(); i++)
clipItem->appendRow(new QStandardItem(QString("%1").arg(pages[i]) ) );
}
else //or its a new clip, not from a preclip
{
Article ar = Article::article(database, articleId, m_localIssuePath, m_remoteIssuePath);
m_clipped.append(ar);
QStandardItemModel *model = static_cast<QStandardItemModel*> ( view->model() );
QStandardItem * clipRootItem = model->item(1, 0);
QStandardItem * clipItem = new QStandardItem( QObject::tr("Clip (%1)").arg(m_clipped.count()));
clipRootItem->appendRow(clipItem);
clipRootItem->setChild(m_clipped.count() -1 , 1, new QStandardItem(QString("%1").arg( articleId )) );
QStringList pages = ar.pageNames();
for(int i= 0; i < pages.count(); i++)
clipItem->appendRow(new QStandardItem(QString("%1").arg(pages[i]) ) );
}
}
}
void Issue::deleteArticleFromView(QTreeView *view, int articleId, bool preclip)
{
if(preclip)
{
int index = -1;
//we remove the preclip from the preclip itemlist, and add it to the clip item list
for(int i=0; i< m_preclipped.count(); i++)
{
if(m_preclipped[i].id() == articleId)
{
index = i;
break;
}
}
if(index == -1)
return; //something wrong, it should not be there
m_preclipped.removeAt(index);
QStandardItemModel *model = static_cast<QStandardItemModel*> ( view->model() );
//QModelIndex preclipRootIndex = model->index(0, 0, QModelIndex() ); //now we remove the row from the model
QStandardItem * preclipRootItem = model->item(0, 0);
preclipRootItem->removeRow(index); //now we remove the row from the model
}
else
{
int index = -1;
//we remove the preclip from the preclip itemlist, and add it to the clip item list
for(int i=0; i< m_clipped.count(); i++)
{
if(m_clipped[i].id() == articleId)
{
index = i;
break;
}
}
if(index == -1)
return; //something wrong, it should not be there
m_clipped.removeAt(index);
QStandardItemModel *model = static_cast<QStandardItemModel*> ( view->model() );
//QModelIndex clipRootIndex = model->index(1, 0, QModelIndex() ); //now we remove the row from the model
QStandardItem * clipRootItem = model->item(1, 0);
clipRootItem->removeRow(index); //now we remove the row from the model
}
}
void Issue::addImageCutoutsToSections(QSqlDatabase &database, QStandardItem *issueItem)
{
QList<Section> sections = Section::sections(database);
QHash<QString, int> sectionsHash;
for(int i=0; i<sections.count(); i++)
sectionsHash[sections[i].name()] = sections[i].id();
//loadClippingCoordinates(database);
//loadArticles(database, NO_FILTER);
QStandardItemModel *model = issueItem->model();
QModelIndex issueIndex = issueItem->index();
int sectionsCount = model->rowCount(issueIndex);
for(int j=0; j < sectionsCount; j++)
{
QString section = model->index(j, 0, issueIndex).data(Qt::DisplayRole).toString();
QModelIndex sectionIndex = model->index(j, 0, issueIndex);
int pagesCount = model->rowCount(sectionIndex);
for(int k=0; k< pagesCount; k++)
{
QModelIndex pageIndex = model->index(k, 0, sectionIndex);
QStandardItem *pageItem = model->itemFromIndex(pageIndex);
QString pagename = pageIndex.data(Qt::DisplayRole).toString();
pagename = QString("%1.jpg").arg(pagename.remove(QRegExp("[^\\d]")), 4, QChar('0'));
pageItem->removeRows(0, pageItem->rowCount() );
foreach(Article ar, m_preclipped)
{
//QStringList pages = ImageCutout::pages(ar.imageCutoutsList()).split(",");
foreach( ImageCutout* rec, ar.imageCutoutsList() )
{
if(rec->sectionNumber() != sectionsHash[section])
continue;
if(!rec->pageName().contains(pagename))
continue;
QIcon icon(":/icons/red_selection.png");
QStandardItem * selectionItem = new QStandardItem(icon, QString("%1").arg( ar.id() ) );
pageItem->appendRow(selectionItem);
break;
}
}
foreach(Article ar, m_clipped)
{
//QStringList pages = ImageCutout::pages(ar.imageCutoutsList()).split(",");
foreach( ImageCutout* rec, ar.imageCutoutsList() )
{
if(rec->sectionNumber() != sectionsHash[section])
continue;
if(!rec->pageName().contains(pagename))
continue;
QIcon icon(":/icons/green_selection.png");
//if (rec->areaType() == IMAGE)
// icon.addFile(":/icons/red_selection.png");
//else if(rec->areaType() == BODY)
// icon.addFile(":/icons/green_selection.png");
//else if(rec->areaType() == TITLE)
// icon.addFile(":/icons/blue_selection.png");
QStandardItem * selectionItem = new QStandardItem(icon, QString("%1").arg( ar.id() ) );
pageItem->appendRow(selectionItem);
break;
}
}
}
///////*******************************************************************************////////
}
}
QList<ImageCutout*> Issue::getImageCutouts(int articleId)
{
foreach(Article ar, m_preclipped)
{
if(ar.id() == articleId)
return ar.imageCutoutsList();
}
foreach(Article ar, m_clipped)
{
if(ar.id() == articleId)
return ar.imageCutoutsList();
}
return QList<ImageCutout*>();
}
QList<Tag> Issue::articleTags(int articleId)
{
foreach(Article ar, m_preclipped)
{
if(ar.id() == articleId)
return ar.tags();
}
foreach(Article ar, m_clipped)
{
if(ar.id() == articleId)
return ar.tags();
}
return QList<Tag>();
}
void Issue::setModelData()
{
if(m_model)
{
delete m_model;
}
m_model = new QStandardItemModel(2, 2 );
m_model->setHorizontalHeaderItem(0, new QStandardItem( QObject::tr("Preclipped/Clipped") ) );
m_model->setHorizontalHeaderItem(1, new QStandardItem( QObject::tr("Values") ) );
//m_date
QStandardItem * preclipRootItem = new QStandardItem( QObject::tr("Preclippings"));
m_model->setItem(0, 0, preclipRootItem);
QList<QStandardItem*> columns;
//columns.append(new QStandardItem("PreclippXXX") );
int row=0;
foreach (Article pc, m_preclipped)
{
QIcon icon( (pc.status() == 1) ? ":/icons/red_circle.png" : ":/icons/green_circle.png");
QStandardItem * preclipItem = new QStandardItem(icon, QObject::tr("Preclip (%1)").arg(row+1));
preclipRootItem->appendRow(preclipItem);
columns.append(new QStandardItem(QString("%1").arg( pc.id()) ) ); //save the article ID
QStringList pages = pc.pageNames();
for(int i= 0; i < pages.count(); i++)
preclipItem->appendRow(new QStandardItem(QString("%1").arg(pages[i]) ) );
row++;
}
preclipRootItem->appendColumn(columns);
QStandardItem * clipRootItem = new QStandardItem( QObject::tr("Clippings"));
m_model->setItem(1, 0, clipRootItem);
row=0;
columns.clear();
foreach (Article ca, m_clipped)
{
QStandardItem * clipItem = new QStandardItem( QObject::tr("Clip (%1)").arg(row+1));
clipRootItem->appendRow(clipItem);
columns.append(new QStandardItem(QString("%1").arg( ca.id()) ) ); //save the article ID
QStringList pages = ca.pageNames();
for(int i= 0; i < pages.count(); i++)
clipItem->appendRow(new QStandardItem(QString("%1").arg(pages[i]) ) );
row++;
}
clipRootItem->appendColumn(columns);
}
void Issue::markIssueAsDone(QSqlDatabase &database, bool isDone, int userId)
{
if(isDone)
m_status = 2;
else
m_status = 1;
QSqlQuery query(database);
query.prepare("UPDATE publication_issue SET publication_status = :status, done_by = :id, done_time = NOW() "
"WHERE id_publication = :id_publication AND id_issue = :id_issue "); //AND issue_date = :issue_date
query.bindValue(":status", m_status);
query.bindValue(":id_publication", m_publicationId);
query.bindValue(":id_issue", m_id ); //query.bindValue(":issue_date", m_date);
query.bindValue(":id", userId);
qDebug() << "mark issue as done by user id: " << userId;
if(!query.exec())
{
qDebug() << "markIssueAsDone() SQL Error: " << query.lastError().databaseText().toAscii();
return;
}
}
+240
View File
@@ -0,0 +1,240 @@
/************************************************************************
* $Id: issue.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/issue.h $
*
************************************************************************/
#ifndef ISSUE_H
#define ISSUE_H
#include <QtCore>
#include <QtSql>
#include <QStandardItemModel>
#include <QTreeView>
//class QDate;
#include "section.h"
#include "article.h"
class Issue
{
public:
//! \fn Issue()
//! default constructor
//! \param[in] id of the issue
//! \param[in] date of the issue
//! \param[in] publication id
//! \author elzubeir
Issue(int id = 0, QString date = "", int publicationId = 0);
//! \fn ~Issue()
//! descturoctor
//! \author elzubeir
~Issue();
//! \fn operator ==()
//! assignment operator, compares issues by date
//! \author elzubeir
bool operator == (const Issue &issue);
//! \fn set()
//! sets the value for the issue
//! \param[in] id of the issue
//! \param[in] date of the issue
//! \param[in] publication id
//! \param[in] status of the issue
//! \author elzubeir
void set(int id, QString date, int pubid, int status, QString created);
//! \fn setIssuePaths()
//! sets the paths for the issue
//! \param[in] lpath QString local path of the issue
//! \param[in] rpath QString remoate path of the issue
//! \author elzubeir
void setIssuePaths(QString lpath, QString rpath);
//! \fn addSection()
//! add section to the issue
//! \param[in] Section object to be added
//! \author elzubeir
void addSection(Section sec);
//! \fn setIsLoaded()
//! sets the loaded variable
//! \param[in] isLoaded value to set the function
//! \author elzubeir
void setIsLoaded(bool isLoaded);
//! \fn id()
//! returns the id of the issue
//! \author elzubeir
int id();
//! \fn date()
//! returns the issue date
//! \author elzubeir
QString date();
//! \fn status()
//! returns the status of the issue
//! \author elzubeir
int status();
QString created();
//! \fn isLoaded()
//! sets the isLoaded flag of the issus
//! \author elzubeir
bool isLoaded();
//! \fn sections()
//! retuns a list of sections of issue
//! \author elzubeir
QList<Section> sections();
//! \fn preclip()
//! returns the id of the preclipped article
//! \param[in] id of the preclipped article
//! \return preclipped article
//! \author elzubeir
Article& preclip(int id);
//! \fn clip()
//! returns the id of the clipped article
//! \param[in] id of the clipped article
//! \return clipped article
//! \author elzubeir
Article& clip(int id);
//Section currentSection();
//! \fn section()
//! returns the section object of the name passed
//! \param[in] name of the section
//! \return section object
//! \author elzubeir
Section& section(QString sectionName);
//! \fn loadArticles()
//! load articles beloning to the current issue
//! \param[in] database object
//! \param[in] filter mode, all articles, or preclipped aricles
//! \author elzubeir
void loadArticles(QSqlDatabase &database, FILTER_MODE mode);
//! \fn showArticlesInView()
//! show articles in the view
//! \param[in] database object
//! \param[in] view wher to show the articles
//! \param[in] filter mode, all articles, or preclipped aricles
//! \author elzubeir
void showArticlesInView(QSqlDatabase &database, QTreeView *view, FILTER_MODE mode);
//! \fn addArticleToView()
//! add article to the view
//! \param[in] database object
//! \param[in] view wher to add the articles
//! \param[in] article id to add
//! \param[in] is this a clip or preclip article
//! \param[in] has it come from preclip
//! \author elzubeir
void addArticleToView(QSqlDatabase &database, QTreeView *view, int articleId, bool isclip, bool preclip);
//! \fn deleteArticleFromView()
//! delete article from the view
//! \param[in] view wher to add the articles
//! \param[in] article id to add
//! \param[in] has it come from preclip
//! \author elzubeir
void deleteArticleFromView(QTreeView *view, int articleId, bool frompreclip = true);
//! \fn addImageCutoutsToSections()
//! add cutouts to section pages
//! \param[in] database object
//! \param[in] item in the issues view
//! \author elzubeir
void addImageCutoutsToSections(QSqlDatabase &database, QStandardItem *issueItem);
//! \fn getImageCutouts()
//! gets the imague cutous of an article
//! \param[in] article id
//! \return a list of image cutouts
//! \author elzubeir
QList<ImageCutout *> getImageCutouts(int articleId);
//! \fn articleTags()
//! tags of an article
//! \param[in] article id to add
//! \return a list of tags belonging to the article
//! \author elzubeir
QList<Tag> articleTags(int articleId);
//! \fn markIssueAsDone()
//! mark the issue as done
//! \param[in] database object
//! \param[in] mark the issue as done or not
//! \author elzubeir
void markIssueAsDone(QSqlDatabase &database, bool isDone, int userId);
private:
//! \fn setModelData();
//! prepare the model to add the issues to it
//! \author elzubeir
void setModelData();
private:
//! id of the issue
int m_id;
//! date of the issue
QString m_date;
//! publication id
int m_publicationId;
//! status of the issue 1: undone, 2: done
int m_status;
//! issue creation time
QString m_created;
//! list of sections
QList<Section> m_sections;
//! list of preclipped articles
QList<Article> m_preclipped;
//! list of clipped aritcles
QList<Article> m_clipped;
//! this is used for re-constructing the clipped, and preclipped articles filename
QString m_localIssuePath;
//! this is used for re-constructing the clipped, and preclipped articles filename
QString m_remoteIssuePath;
//! is the article loaded
bool m_isArticleLoaded;
//! model to show the issues at
QStandardItemModel *m_model;
//! is the issue loaded
bool m_isLoaded;
};
#endif // ISSUE_H
+41
View File
@@ -0,0 +1,41 @@
/************************************************************************
* $Id: main.cpp 667 2011-05-15 10:41:45Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-05-15 14:41:45 +0400 (Sun, 15 May 2011) $
* $Author: elzubeir $
* $Revision: 667 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/main.cpp $
*
************************************************************************/
#include <QtGui/QApplication>
#include <QPluginLoader>
#include "globalfunctions.h"
#include "clippingstation.h"
int main(int argc, char *argv[])
{
QApplication::setGraphicsSystem("raster");
QApplication a(argc, argv);
//g_logfile.open("clippingstation.log", ios::app);
qInstallMsgHandler(MyOutputHandler);
ClippingStation w;
QObject::connect(&a, SIGNAL(focusChanged( QWidget*, QWidget* ) ), &w, SLOT( onAppFocusChanged()));
w.show();
return a.exec();
}
+267
View File
@@ -0,0 +1,267 @@
/************************************************************************
* $Id: pageitem.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/pageitem.cpp $
*
************************************************************************/
#include "pageitem.h"
#include <QBrush>
#include <QApplication>
#include <QDesktopWidget>
#include <QGraphicsSceneDragDropEvent>
#include <QMimeData>
#include <QGraphicsScene>
#include <QtDebug>
#include "constants.h"
#include "droppeditem.h"
#include "pagemargin.h"
PageItem::PageItem(const QString & paperFormat, bool isfirst) :
QGraphicsRectItem(),
m_paperFormat(paperFormat),
m_isFirstPage(isfirst),
m_pageMargin(isfirst),
m_thumbnail(0)
{
if (m_paperFormat != "A4")
return; // error ! by now we don't support others page format !
// we compute pixels dimensions for the page.
int dpi = QApplication::desktop()->logicalDpiX();
m_pageWidth = dpi * A4_WIDTH;
m_pageHeight = dpi * A4_HEIGHT;
setRect(QRectF(0, 0, m_pageWidth, m_pageHeight));
// page color is white.
setBrush(QBrush(Qt::white));
setZValue(0.1);
setAcceptDrops(true);
m_pageMargin.setPageParent(this);
}
PageItem::~PageItem()
{
qDebug("~PageItem()");
if(m_thumbnail)
{
delete m_thumbnail;
m_thumbnail = 0;
}
QList<QGraphicsItem*> items = this->childItems();
//qDebug("Items count : %d", items.count());
for(int i=0; i< items.count(); i++)
{
DroppedItem *item = static_cast<DroppedItem*>(items[i]);
if(item->type() == UserType + 1 )
delete item;
}
qDebug("end of ~PageItem()");
}
void PageItem::hideMargins(bool hide)
{
m_pageMargin.hideMargins(hide);
}
void PageItem::unselectItems()
{
QList<QGraphicsItem*> items = this->childItems();
foreach(QGraphicsItem *item, items)
item->setSelected(false);
}
void PageItem::dragMoveEvent(QGraphicsSceneDragDropEvent * event)
{
// if dragged mime data is not a image, we forbid the drop action.
if (event->mimeData()->hasImage())
event->acceptProposedAction();
else
event->ignore();
QGraphicsRectItem::dragMoveEvent(event);
}
void PageItem::dropEvent(QGraphicsSceneDragDropEvent * event)
{
// verify that we drop an image.
if (event->mimeData()->hasImage())
{
QPointF pt = event->pos(); //QPointF pt = mapToItem(this, event->pos());
QByteArray byteArray = event->mimeData()->data("image/jpg");
QPixmap pixmap = QPixmap::fromImage( QImage::fromData(byteArray, "jpg") );
QPixmap originalPixmap = pixmap;
int width = pixmap.width();
int height = pixmap.height();
withinMarginBoundaries( pt, width, height );
qreal w = m_pageWidth - m_pageMargin.right() - pt.x();
qreal h = m_pageHeight - m_pageMargin.bottom() - pt.y();
qreal precW = w/originalPixmap.width();
qreal precH = h/originalPixmap.height();
qreal prec = qMin(precW, precH);
if (prec > 1.0)
prec = 1.0;
new DroppedItem(originalPixmap, pt, prec, this);
}
}
void PageItem::withinMarginBoundaries(QPointF &point, int width, int height)
{
//notice that this order is IMPORTANT, because if its to the right, and bigger than the margin width
//it will be shrinked automatically
if ( point.x() > m_pageWidth - m_pageMargin.right() )
point.setX(m_pageWidth- m_pageMargin.right() - width ); //return false;
if ( point.y() > m_pageHeight - m_pageMargin.bottom() )
point.setY( m_pageHeight - m_pageMargin.bottom() - height );
if ( point.x() < m_pageMargin.left() )
point.setX(m_pageMargin.left() ); //return false;
if ( point.y() < m_pageMargin.top() )
point.setY(m_pageMargin.top() ); //return false;
}
QPointF PageItem::calculateDropEvent(const QPointF & itemPos, int pixmapWidth, int pixmapHeight) const
{
QPointF dropPos(itemPos);
// this computation is allowed cause drop position is on the hotspot point and it is set to 0,0 when drag starts.
// If it changes, we have to compute things taking in account the drag hot spot too.
if ((itemPos.x() + pixmapWidth > m_pageWidth) && (pixmapWidth <= m_pageWidth))
{
//dropPos.setX(m_pageWidth - pixmapWidth);
//dropPos.setX( m_pageMargin->left() );
}
if ((itemPos.y() + pixmapHeight > m_pageHeight) && (pixmapHeight <= m_pageHeight))
{
dropPos.setY(m_pageHeight - pixmapHeight);
}
// convert scene pos to page item pos
return QPointF(dropPos);
}
void PageItem::addThumbnail(QImage &img)
{
if (m_thumbnail)
delete m_thumbnail;
m_thumbnail = new Thumbnail(QPixmap::fromImage(img), QPointF(650, 20), this);
}
void PageItem::addCutout(QImage &img, QPointF &pos, qreal scale)
{
new DroppedItem(QPixmap::fromImage(img), pos, scale, this);
}
qreal PageItem::width()
{
return m_pageWidth;
}
qreal PageItem::height()
{
return m_pageHeight;
}
PageMargin& PageItem::margin()
{
return m_pageMargin;
}
void PageItem::setPixmap(const QPixmap &pix)
{
hideMargins(true);
QGraphicsPixmapItem *pixItem = new QGraphicsPixmapItem(pix, this);
pixItem->setPos(0,0);
}
int PageItem::cutoutsCount()
{
QList<QGraphicsItem*> list = this->children();
int count = childItems().count() - 5; //5 is for the margin items
if(m_isFirstPage)
count -=1; //remove the thumbnamil item
return count;
}
QRectF PageItem::centerCutouts(bool isArabic)
{
QList<QGraphicsItem*> items = this->childItems();
double top, bottom, left, right;
top = left = 1000;
bottom = right = -1;
//QRectF rect(0,0,0,0);
//qDebug("Items count : %d", items.count());
for(int i=0; i< items.count(); i++)
{
DroppedItem *item = static_cast<DroppedItem*>(items[i]);
if(item->type() == UserType + 1 )
{
if (item->pos().x() + item->boundingRect().topLeft().x() < left )
left = item->pos().x() + item->boundingRect().topLeft().x();
if (item->pos().y() + item->boundingRect().topLeft().y() < top )
top = item->pos().y() +item->boundingRect().topLeft().y();
if (item->pos().x() + item->boundingRect().bottomRight().x() > right )
right = item->pos().x() + item->boundingRect().bottomRight().x();
if (item->pos().y() + item->boundingRect().bottomRight().y() > bottom )
bottom = item->pos().y() + item->boundingRect().bottomRight().y();
}
}
QRectF rect(QPointF(left, top), QPoint(right, bottom) );
//QRectF br = this->boundingRect();
double w = m_pageWidth - m_pageMargin.left() - m_pageMargin.right();
double h = m_pageHeight - m_pageMargin.top() - m_pageMargin.bottom();
double moveX = ( w - rect.width())/2.0;
double moveY = ( h - rect.height())/2.0;
int orientation = 1;
if(isArabic)
orientation = -1;
for(int i=0; i< items.count(); i++)
{
DroppedItem *item = static_cast<DroppedItem*>(items[i]);
if(item->type() == UserType + 1 )
item->moveBy(orientation*moveX, moveY);
}
return rect;
}
+161
View File
@@ -0,0 +1,161 @@
/************************************************************************
* $Id: pageitem.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/pageitem.h $
*
************************************************************************/
#ifndef PAGE_ITEM_H
#define PAGE_ITEM_H
#include <QGraphicsRectItem>
#include "pagemargin.h"
#include "thumbnail.h"
#include "globalfunctions.h"
/**
\brief Purpose of this class is to display the page item.
This item takes care of drop operations in the right panel.
*/
class PageItem : public QGraphicsRectItem
{
public:
//! \fn PageItem()
//! constructor
//! \param[in] paper format (default to A4)
//! \param[in] isfirst is this is the firat A4 page
//! \author elzubeir
PageItem(const QString & paperFormat, bool isfirst); //ctor
//! \fn ~PageItem()
//! desctructor
//! \author elzubeir
virtual ~PageItem(); //dtor
//! \fn hideMargins()
//! hide the margins
//! \param[in] hid: to show or to hide
//! \author elzubeir
void hideMargins(bool hide = true);
//! \fn addThumbnail()
//! add a thumbnail to the page
//! \param[in] thumbnail image
//! \author elzubeir
void addThumbnail(QImage &img);
//! \fn addCutout()
//! add cutout to the A4 page
//! \param[in] cutout image
//! \param[in] position point to where to add the cutout to page
//! \param[in] the scale to which zoom the image
//! \author elzubeir
void addCutout(QImage &img, QPointF &pos, qreal scale);
//! \fn width()
//! the pages width
//! \return the pages width
//! \author elzubeir
qreal width();
//! \fn height()
//! the pages height
//! \return the pages height
//! \author elzubeir
qreal height();
//! \fn margin()
//! the pages margin
//! \return the pages margin
//! \author elzubeir
PageMargin& margin();
//! \fn withinMarginBoundaries()
//! sets the point to within the pages boundaries
//! \author elzubeir
//! \param[out] the point within the boundary of the margin
//! \param[in] margins width
//! \param[in] margins height
//! \author elzubeir
void withinMarginBoundaries(QPointF &point, int width, int height);
//! \fn unselectItems();
//! unselect cutout items in the image
//! \author elzubeir
void unselectItems();
//! \fn setPixmap()
//! set the pixmap value of the image
//! \author elzubeir
void setPixmap(const QPixmap &pix);
//! \fn cutoutsCount()
//! the total count of the cutouts in the page
//! \return the number of cutouts in the page
//! \author elzubeir
int cutoutsCount();
//! \fn centerCutouts()
//! center the cutouts in the drawer
//! \param[in] is this an arabic cutout of not
//! \returns a rectangle holding the centered cutouts
//! \author elzubeir
QRectF centerCutouts(bool isArabic);
protected:
// overrides QGraphicsRectItem events.
//! \fn dragMoveEvent()
//! called when a drag operation is initaated
//! \author elzubeir
virtual void dragMoveEvent(QGraphicsSceneDragDropEvent * event);
//! \fn dropEvent()
//! called when a drop event happens
//! \author elzubeir
virtual void dropEvent(QGraphicsSceneDragDropEvent * event);
private:
//! \fn calculateDropEvent()
//! calculates the cutout drop position within margins
//! \param[in] top left position of the cutout
//! \param[in] cutouts width
//! \param[in] cutouts heigh
//! \returns a point for the top left position of the cutout
//! \author elzubeir
QPointF calculateDropEvent(const QPointF & itemPos, int pixmapWidth, int pixmapHeight) const;
private:
//! paper format (defulat to A4)
QString m_paperFormat;
//! page width
qreal m_pageWidth;
//! page height
qreal m_pageHeight;
//! is this the first page
bool m_isFirstPage;
//! page margin
PageMargin m_pageMargin;
//! thumbnail image
Thumbnail * m_thumbnail;
};
#endif // PAGE_ITEM_H
+122
View File
@@ -0,0 +1,122 @@
/************************************************************************
* $Id: pagemargin.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/pagemargin.cpp $
*
************************************************************************/
#include "pagemargin.h"
#include <QPen>
#include <QDesktopWidget>
#include <QApplication>
#include <QGraphicsLineItem>
#include "constants.h"
#include "systemconfiguration.h"
PageMargin::PageMargin(bool isfirst,QGraphicsRectItem * parent)
: QGraphicsRectItem(parent)
{
// we compute pixels dimensions for the page.
int dpi = QApplication::desktop()->logicalDpiX();
qreal pageWidth = dpi * A4_WIDTH;
qreal pageHeight = dpi * A4_HEIGHT;
MarginValues mv ;
if(isfirst)
mv = SystemConfiguration::firstPageMargin();
else
mv = SystemConfiguration::otherPagesMargin();
m_top = mv.top * dpi / 2.54;
m_bottom = mv.bottom * dpi / 2.54;
m_left = mv.left * dpi / 2.54;
m_right = mv.right * dpi / 2.54;
qreal w = pageWidth - (m_left + m_right);
qreal h = pageHeight - (m_top + m_bottom);
QColor color = Qt::gray;
QPen pen(Qt::DashDotLine);
pen.setColor(color);
//pen.setWidth(1); //DONT uncomment this
m_topMargin .setLine(m_left , m_top , m_left+w, m_top );
m_bottomMargin .setLine(m_left , m_top+h, m_left+w, m_top+h );
m_leftMargin .setLine(m_left , m_top , m_left , m_top+h );
m_rightMargin .setLine(m_left+w, m_top , m_left+w, m_top+h );
m_topMargin .setPen(pen);
m_bottomMargin .setPen(pen);
m_leftMargin .setPen(pen);
m_rightMargin .setPen(pen);
}
PageMargin::~PageMargin()
{
}
void PageMargin::setPageParent(QGraphicsRectItem* parent)
{
this ->setParentItem(parent);
m_topMargin .setParentItem(parent);
m_bottomMargin .setParentItem(parent);
m_leftMargin .setParentItem(parent);
m_rightMargin .setParentItem(parent);
}
void PageMargin::hideMargins(bool hide)
{
if(hide)
{
m_topMargin .hide();
m_bottomMargin .hide();
m_leftMargin .hide();
m_rightMargin .hide();
}
else
{
m_topMargin .show();
m_bottomMargin .show();
m_leftMargin .show();
m_rightMargin .show();
}
}
qreal PageMargin::top()
{
return m_top;
}
qreal PageMargin::bottom()
{
return m_bottom;
}
qreal PageMargin::left()
{
return m_left;
}
qreal PageMargin::right()
{
return m_right;
}
+91
View File
@@ -0,0 +1,91 @@
/************************************************************************
* $Id: pagemargin.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/pagemargin.h $
*
************************************************************************/
#ifndef PAGEMARGIN_H
#define PAGEMARGIN_H
#include <QtCore>
#include <QGraphicsRectItem>
#include "globalfunctions.h"
class PageMargin : public QGraphicsRectItem
{
public:
//! \fn PageMargin()
//! default constructor
//! \param[in] is this the first page's margin
//! \author elzubeir
PageMargin(bool isfirst, QGraphicsRectItem* parent = 0);
//! \fn ~PageMargin()
//! destructor
//! \author elzubeir
~PageMargin();
//! \fn setPageParent()
//! set the pages graphics item parent
//! \author elzubeir
void setPageParent(QGraphicsRectItem* parent);
//! \fn top()
//! return the top value of the margin
//! \author elzubeir
qreal top();
//! \fn bottom()
//! return the bottom value of the margin
//! \author elzubeir
qreal bottom();
//! \fn right()
//! return the right value of the margin
//! \author elzubeir
qreal right();
//! \fn left()
//! return the left value of the margin
//! \author elzubeir
qreal left();
//! \fn hideMargins()
//! hide the margins
//! \param[in] hide or show
//! \author elzubeir
void hideMargins(bool hide = true);
private:
//! graphics line edit item for top margin
QGraphicsLineItem m_topMargin;
//! graphics line edit item for bottom margin
QGraphicsLineItem m_bottomMargin;
//! graphics line edit item for left margin
QGraphicsLineItem m_leftMargin;
//! graphics line edit item for right margin
QGraphicsLineItem m_rightMargin;
//! qreal top, bottom, left, and right vlaues of the margin
qreal m_top, m_bottom, m_left, m_right;
};
#endif // PAGEMARGIN_H
+92
View File
@@ -0,0 +1,92 @@
/************************************************************************
* $Id: pagetextdialog.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/pagetextdialog.cpp $
*
************************************************************************/
#include "pagetextdialog.h"
#include "ui_pagetextdialog.h"
PageTextDialog::PageTextDialog(QWidget *parent, QString text) :
QDialog(parent),
m_ui(new Ui::PageTextDialog),
m_text(text)
{
m_ui->setupUi(this);
m_ui->textBrowser->setText(m_text);
}
PageTextDialog::~PageTextDialog()
{
delete m_ui;
}
void PageTextDialog::changeEvent(QEvent *e)
{
QDialog::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
m_ui->retranslateUi(this);
break;
default:
break;
}
}
void PageTextDialog::setText(QString &text)
{
m_text = text;
}
void PageTextDialog::find()
{
QString str = m_ui->findLineEdit->text().trimmed();
static QString oldsearch;
if(oldsearch != str) //return to search from beginning.
{
m_ui->textBrowser->moveCursor(QTextCursor::Start);
QList<QTextEdit::ExtraSelection> extraSelections;
m_ui->textBrowser->setExtraSelections(extraSelections);
}
oldsearch = str;
if( m_ui->textBrowser->find(str) )
m_ui->textBrowser->setFocus();
}
void PageTextDialog::findAll()
{
QString str = m_ui->findLineEdit->text().trimmed();
m_ui->textBrowser->moveCursor(QTextCursor::Start);
QColor color = QColor(Qt::blue).lighter(130);
QList<QTextEdit::ExtraSelection> extraSelections;
while(m_ui->textBrowser->find(str))
{
QTextEdit::ExtraSelection extra;
extra.format.setBackground(color);
extra.cursor = m_ui->textBrowser->textCursor();
extraSelections.append(extra);
}
m_ui->textBrowser->setExtraSelections(extraSelections);
}
+70
View File
@@ -0,0 +1,70 @@
/************************************************************************
* $Id: pagetextdialog.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/pagetextdialog.h $
*
************************************************************************/
#ifndef PAGETEXTDIALOG_H
#define PAGETEXTDIALOG_H
#include <QtGui/QDialog>
namespace Ui {
class PageTextDialog;
}
class PageTextDialog : public QDialog {
Q_OBJECT
public:
//! \fn PageTextDialog()
//! default constructor
//! \param[in] text to add to the dialog
//! \author elzubeir
PageTextDialog(QWidget *parent = 0, QString text = "");
//! \fn ~PageTextDialog()
//! destructor
//! \author elzubeir
~PageTextDialog();
//! \fn setText()
//! set text of the dialog
//! \param[in] text to add to the dialog
//! \author elzubeir
void setText(QString &text);
private slots:
//! \fn find()
//! find the word in the dialog's text and heighlight it
//! \author elzubeir
void find();
//! \fn findAll();
//! find all the words in the dialog's text and heighlight them
//! \author elzubeir
void findAll();
protected:
void changeEvent(QEvent *e);
private:
Ui::PageTextDialog *m_ui;
//! dialog text
QString m_text;
};
#endif // PAGETEXTDIALOG_H
+177
View File
@@ -0,0 +1,177 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PageTextDialog</class>
<widget class="QDialog" name="PageTextDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>587</width>
<height>495</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTextBrowser" name="textBrowser"/>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string> Find: </string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="findLineEdit"/>
</item>
<item>
<widget class="QPushButton" name="findBushButton">
<property name="text">
<string>Find</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Find All</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</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="sizeHint" stdset="0">
<size>
<width>85</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PageTextDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>257</x>
<y>485</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PageTextDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>325</x>
<y>485</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>findBushButton</sender>
<signal>clicked()</signal>
<receiver>PageTextDialog</receiver>
<slot>find()</slot>
<hints>
<hint type="sourcelabel">
<x>285</x>
<y>438</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>437</y>
</hint>
</hints>
</connection>
<connection>
<sender>pushButton</sender>
<signal>clicked()</signal>
<receiver>PageTextDialog</receiver>
<slot>findAll()</slot>
<hints>
<hint type="sourcelabel">
<x>362</x>
<y>449</y>
</hint>
<hint type="destinationlabel">
<x>479</x>
<y>439</y>
</hint>
</hints>
</connection>
<connection>
<sender>findLineEdit</sender>
<signal>returnPressed()</signal>
<receiver>PageTextDialog</receiver>
<slot>find()</slot>
<hints>
<hint type="sourcelabel">
<x>177</x>
<y>448</y>
</hint>
<hint type="destinationlabel">
<x>537</x>
<y>438</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>find()</slot>
<slot>findAll()</slot>
</slots>
</ui>
+29
View File
@@ -0,0 +1,29 @@
/************************************************************************
* $Id: prominence.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/prominence.cpp $
*
************************************************************************/
#include "prominence.h"
Prominence::Prominence()
{
m_mentionScore = 1;
m_visualScore = 0;
m_toneScore = 1;
m_note = "";
m_size = 0.0;
}
+49
View File
@@ -0,0 +1,49 @@
/************************************************************************
* $Id: prominence.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/prominence.h $
*
************************************************************************/
#ifndef PROMINENCE_H
#define PROMINENCE_H
#include <QtCore>
class Prominence
{
public:
//! \fn Prominence()
//! default constructor
//! \author elzubeir
Prominence();
//! visual score
int m_visualScore;
//! mention score
int m_mentionScore;
//! tone score
int m_toneScore;
//! size
double m_size;
//! note
QString m_note;
};
#endif // PROMINENCE_H
+122
View File
@@ -0,0 +1,122 @@
/************************************************************************
* $Id: prominencedialog.cpp 558 2010-04-21 09:00:15Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009,2010 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2010-04-21 13:00:15 +0400 (Wed, 21 Apr 2010) $
* $Author: elzubeir $
* $Revision: 558 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/prominencedialog.cpp $
*
************************************************************************/
#include "prominencedialog.h"
#include "ui_prominencedialog.h"
ProminenceDialog::ProminenceDialog(QWidget *parent) :
QDialog(parent),
m_ui(new Ui::ProminenceDialog)
{
m_ui->setupUi(this);
}
ProminenceDialog::~ProminenceDialog()
{
delete m_ui;
}
void ProminenceDialog::changeEvent(QEvent *e)
{
QDialog::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
m_ui->retranslateUi(this);
break;
default:
break;
}
}
void ProminenceDialog::accept()
{
m_prominence.m_note = m_ui->noteLineEdit->text().trimmed();
m_prominence.m_size = m_ui->sizeLineEdit->text().toDouble();
int index = m_ui->mentionScoreComboBox->currentIndex();
if(index == 0)
m_prominence.m_mentionScore = 1;
else if (index == 1)
m_prominence.m_mentionScore = 2;
else
m_prominence.m_mentionScore = 3;
index = m_ui->visualScoreComboBox->currentIndex();
if(index == 0)
m_prominence.m_visualScore = 0;
else if(index == 1)
m_prominence.m_visualScore = -99;
else if (index == 2)
m_prominence.m_visualScore = 1;
else
m_prominence.m_visualScore = 2;
index = m_ui->toneScoreComboBox->currentIndex();
if(index == 0)
m_prominence.m_toneScore = 1;
else if(index == 1)
m_prominence.m_toneScore = 2;
else
m_prominence.m_toneScore = -2;
QDialog::accept();
}
Prominence ProminenceDialog::prominence()
{
return m_prominence;
}
void ProminenceDialog::setProminence(Prominence pr)
{
m_prominence = pr;
updateUi();
}
void ProminenceDialog::updateUi()
{
m_ui->noteLineEdit->setText(m_prominence.m_note);
m_ui->sizeLineEdit->setText(QString("%1").arg(m_prominence.m_size) );
int index = m_prominence.m_mentionScore;
if(index == 1)
m_ui->mentionScoreComboBox->setCurrentIndex(0);
else if (index == 2)
m_ui->mentionScoreComboBox->setCurrentIndex(1);
else
m_ui->mentionScoreComboBox->setCurrentIndex(2);
index = m_prominence.m_visualScore;
if(index == 0)
m_ui->visualScoreComboBox->setCurrentIndex(0);
else if(index == -99)
m_ui->visualScoreComboBox->setCurrentIndex(1);
else if (index == 1)
m_ui->visualScoreComboBox->setCurrentIndex(2);
else
m_ui->visualScoreComboBox->setCurrentIndex(3);
index = m_prominence.m_toneScore;
if(index == 1)
m_ui->toneScoreComboBox->setCurrentIndex(0);
else if(index == 2)
m_ui->toneScoreComboBox->setCurrentIndex(1);
else
m_ui->toneScoreComboBox->setCurrentIndex(2);
}
+78
View File
@@ -0,0 +1,78 @@
/************************************************************************
* $Id: prominencedialog.h 583 2010-05-15 09:54:58Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009,2010 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2010-05-15 13:54:58 +0400 (Sat, 15 May 2010) $
* $Author: elzubeir $
* $Revision: 583 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/prominencedialog.h $
*
************************************************************************/
#ifndef PROMINENCEDIALOG_H
#define PROMINENCEDIALOG_H
#include <QtGui/QDialog>
#include "prominence.h"
namespace Ui {
class ProminenceDialog;
}
class ProminenceDialog : public QDialog {
Q_OBJECT
public:
//! \fn ProminenceDialog()
//! default constructor
//! \author elzubeir
ProminenceDialog(QWidget *parent = 0);
//! \fn ~ProminenceDialog()
//! destrct
//! \author elzubeir
~ProminenceDialog();
//! \fn prominenceDialog()
//! returns an object of the Prominence class containing the data populated
//! \author elzubeir
Prominence prominence();
//! \fn setProminence()
//! set the prominence values
//! \param[in] Prominence object to set its value
//! \author elzubeir
void setProminence(Prominence pr);
protected:
//! \fn changeEvent()
//! a change event has occured
//! \author elzubeir
void changeEvent(QEvent *e);
//! \fn accept()
//! the ok button is clicked
//! \author elzubeir
void accept();
private:
//! \fn updateUi()
//! updates the ui with the values from the prominence object
//! \author elzubeir
void updateUi();
private:
Ui::ProminenceDialog *m_ui;
//! prominence object
Prominence m_prominence;
};
#endif // PROMINENCEDIALOG_H
+184
View File
@@ -0,0 +1,184 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ProminenceDialog</class>
<widget class="QDialog" name="ProminenceDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>232</width>
<height>212</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Visual Score</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="visualScoreComboBox">
<item>
<property name="text">
<string>Undefined</string>
</property>
</item>
<item>
<property name="text">
<string>None</string>
</property>
</item>
<item>
<property name="text">
<string>Black &amp; White</string>
</property>
</item>
<item>
<property name="text">
<string>Color</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Mention Score</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="mentionScoreComboBox">
<item>
<property name="text">
<string>Marginal </string>
</property>
</item>
<item>
<property name="text">
<string>Prominence</string>
</property>
</item>
<item>
<property name="text">
<string>Headline </string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Tone Score</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="toneScoreComboBox">
<item>
<property name="text">
<string>Neutral </string>
</property>
</item>
<item>
<property name="text">
<string>Favorable </string>
</property>
</item>
<item>
<property name="text">
<string>Unfavorable </string>
</property>
</item>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Size</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="sizeLineEdit"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Note</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="noteLineEdit"/>
</item>
</layout>
</item>
<item row="1" column="0">
<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>
<item row="2" column="0">
<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>ProminenceDialog</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>ProminenceDialog</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>
File diff suppressed because it is too large Load Diff
+303
View File
@@ -0,0 +1,303 @@
/************************************************************************
* $Id: publication.h 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/publication.h $
*
************************************************************************/
#ifndef PUBLICATION_H
#define PUBLICATION_H
#include <QtCore>
#include <QtSql>
#include <QStandardItemModel>
#include <QStandardItem>
#include <QList>
#include <QMessageBox>
#include "issue.h"
class Publication
{
public:
//! \fn Publication()
//! default contructor
//! \author elzubeir
Publication();
//! \fn
//! desctructor
//! \author elzubeir
~Publication();
//! \fn setId()
//! set the publication id
//! \param[in] id of the publication
//! \author elzubeir
void setId(int id);
//! \fn setName()
//! set the name of the publication
//! \param[in] name of the publication
//! \author elzubeir
void setName(QString name);
//! \fn setDatabase()
//! set the database object of the publication
//! \param[in] database object
//! \author elzubeir
void setDatabase(QSqlDatabase &database);
//! \fn id()
//! gets the id of the publicaiton
//! \returns id of the publication
//! \author elzubeir
int id();
//! \fn name()
//! name of the publication
//! \returns the name of the publication
//! \author elzubeir
QString name();
//! \fn circulation()
//! gives the publication circulation
//! \returns the pub circulation
//! \author elzubeir
int circulation();
//! \fn country()
//! the pub countries
//! \returns the pub countries
//! \author elzubeir
QString country();
//! \fn columnWidth()
//! the pub (newspaper) column width
//! \returns the column width
//! \author elzubeir
int columnWidth();
//! \fn type()
//! the pub type (mag or newspaper)
//! \returns returns te pub type
//! \author elzubeir
int type();
//! \fn size()
//! the pub size
//! \returns returns the pub size
//! \author elzubeir
int size();
//! \fn adRate()
//! the pub ad rate
//! \returns returns the pub add rate
//! \author elzubeir
qreal adRate();
//! \fn skipOcr()
//! returns the skip ocr of the publication
//! \returns skip ocr flag
//! \author elzubeir
bool skipOcr();
//! \fn language()
//! language of the publication
//! \returns the language of the publication
//! \author elzubeir
QString language();
//! \fn initalizeViews()
//! initalize the issues and articles view
//! \param[out] issue view object to be initalized
//! \param[out] article view object to be initalized
//! \author elzubeir
void initalizeViews(QTreeView *issuesView, QTreeView *clippingsView);
//! \fn loadIssues()
//! load the issues and their sections and pages and add them to the view
//! \param[out] the view to add the issues to
//! \param[in] the local cache directory
//! \author elzubeir
void loadIssues (QTreeView *view, QString localcachDir);
//! \fn loadIssuesWithPreclipsOnly()
//! load the issues that contains the preclips only and add them to the view
//! \param[out] the view to add the issues to
//! \param[in] the local cache directory
//! \author elzubeir
void loadIssuesWithPreclipsOnly (QTreeView *view, QString localcachDir);
void loadUndoneIssuesOnly(QTreeView *view);
//! \fn loadIssuesOnly()
//! load the issues only and add them to the view
//! \param[out] the view to add the issues to
//! \author elzubeir
void loadIssuesOnly (QTreeView *view);
//! \fn loadIssueSections()
//! load the sections and pages for a certain issue
//! \param[out] the issue item where to add the sections to
//! \param[in] the issue date to load its sections
//! \param[in] the local cache directory
//! \author elzubeir
void loadIssueSections (QStandardItem *issueItem, QString issueDate, QString localcachDir);
//! \fn loadFilteredIssues()
//! load filtered issues based on the filter criteria passed
//! \param[out] the view to add the issues to
//! \param[in] the local cache directory
//! \param[in] the start date of the issue
//! \param[in] the end date of the issue
//! \param[in] keyword to search for
//! \param[in] ocr searchword to search for
//! \author elzubeir
void loadFilteredIssues (QTreeView *view, QSqlDatabase &ocrDatabase, QString localcachDir, QString &startDate, QString &endDate, QString keyword, QString ocrSearchword, QString status);
//! \fn addImageCutoutsToIssues()
//! load cutouts of the pages in the issue, and add them to the view
//! \param[out] the view to add the cutouts to
//! \param[in] should we populate the cutouts in all the sections or just for a specific section
//! \author elzubeir
void addImageCutoutsToIssues (QTreeView *view, bool populateAllSections);
//! \fn setCurrentIssue()
//! set the current selected issue for the pub
//! \param[in] the issue date to be selected
//! \author elzubeir
void setCurrentIssue(QString date);
//! \fn removeIssueFromIssues()
//! removes issue from view
//! \param[out] the view to remove the issues from
//! \param[in] the issue date to be removed
//! \author elzubeir
void removeIssueFromIssues (QTreeView*view, QString issueDate);
//! \fn currentIssue()
//! the current selected issue
//! \return a pointer to the current selected issue
//! \author elzubeir
Issue* currentIssue();
//! \fn issue()
//! the issue of a certain date
//! \param[in] the issue date to retreive
//! \returns a pointer to the issue where the date's passed
//! \author elzubeir
Issue* issue(QString date);
//! \fn isMagazine()
//! is the current publication's type is magazine
//! \returns true if magazine, false if newspaper
//! \author elzubeir
bool isMagazine();
//! \fn publicationsWithPreclips()
//! gets a list of publication names that contains a preclipps
//! \param[in] the database object
//! \returns list of publication name
//! \author elzubeir
static QStringList publicationsWithPreclips(QSqlDatabase &database);
//! \fn publicationsFiltered()
//! gets a list of publications
//! \param[in] the database object
//! \param[in] keyword to search for
//! \param[in] the start date of the issue
//! \param[in] the end date of the issue
//! \param[in] type of publicaiton
//! \param[in] id of country
//! \param[in] ocr searchword to search for
//! \returns list of publication name
//! \author elzubeir
static QStringList publicationsFiltered(QSqlDatabase &database, QSqlDatabase &ocrDatabase, QString &keyword, QString &startDate, QString &endDate,
int type, int country, QString &ocrSearchword, QString &status);
static QStringList publicationsWithUndoneIssues(QSqlDatabase &database);
private:
//! \fn getFilenamesFromDatabase()
//! get image names from the database for a certain section in the issues
//! \param[in] the publication id
//! \param[in] the issue date
//! \param[in] section id
//! \param[in] local cache directory path
//! \param[out] list of files with their local paths
//! \param[out] list of files with their remote paths
//! \param[out] the issues local path
//! \param[out] the issues remote path
//! \returns list of items containing the image names and their info
//! \author elzubeir
QList<QStandardItem*> getFilenamesFromDatabase(int publicationId, QString issueDate, int sectionId, QString localcachDir,
QStringList &localFiles, QStringList &remoteFiles,
QString &localIssuePath, QString &remoteIssuePath);
//! \fn retrievePublicationInfo()
//! populate the publication info from database
//! \author elzubeir
void retrievePublicationInfo();
private:
//! database object
QSqlDatabase m_database;
//! id
int m_id;
//! name
QString m_name;
//! country
QString m_country;
//! circulation
int m_circulation;
//! colum width
int m_columnWidth;
//! type
int m_type;
//! size
int m_size;
//! ad rate value
qreal m_adRate;
//! skip ocr for the publication
bool m_skipOcr;
//! language
QString m_language;
//! list of issues
QList<Issue*> m_issues;
//! current selected issue
int m_currentIssueIndex;
//! list of section files selected
QStringList m_currentIssueSectionFilesList;
//! list of selected image index
int m_currentSelectedImageIndex;
//! current selected section in the issue
QString m_currentIssueSection;
};
#endif // PUBLICATION_H
+70
View File
@@ -0,0 +1,70 @@
/************************************************************************
* $Id: pushbuttondelegate.cpp 661 2011-04-05 13:16:53Z elzubeir $
*
* ------------
* Description:
* ------------
*
* (C) Copyright 2009-2011 ALLCONTENT. All rights reserved.
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2011-04-05 17:16:53 +0400 (Tue, 05 Apr 2011) $
* $Author: elzubeir $
* $Revision: 661 $
* $HeadURL: file:///opt/svn/socialhose/trunk/app/ClippingStation/pushbuttondelegate.cpp $
*
************************************************************************/
#include <QtGui>
#include "pushbuttondelegate.h"
PushButtonDelegate::PushButtonDelegate(QObject *parent, TagsWrapper* sw)
:QItemDelegate(parent), m_sw(sw)
{
}
QWidget *PushButtonDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem & option,
const QModelIndex & index) const
{
QPushButton *editor = new QPushButton(parent);
editor->setEnabled(true);
editor->setText("Pr");
connect(editor, SIGNAL(clicked()), m_sw, SLOT( showProminenceDialog()) );
return editor;
}
void PushButtonDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
}
void PushButtonDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
}
void PushButtonDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
editor->setGeometry(option.rect);
}
void PushButtonDelegate::paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
QStyleOptionButton buttonOption;
buttonOption.rect = option.rect;
buttonOption.text = QString("Pr");
QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter);
}
QSize PushButtonDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
return QSize(option.rect.width(), option.rect.height()+25);
}

Some files were not shown because too many files have changed in this diff Show More