Source file: src/mailing_window.cpp
/* Copyright (C) 2004-2011 Daniel Verite
This file is part of Manitou-Mail (see http://www.manitou-mail.org)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include "main.h"
#include "mailing_window.h"
#include "mailing_viewer.h"
#include "mailing_wizard.h"
#include "icons.h"
#include "date.h"
#include <QTreeWidget>
#include <QPushButton>
#include <QBoxLayout>
#include <QProgressBar>
#include <QHeaderView>
#include <QTimer>
#include <QTreeWidgetItemIterator>
#include <QMessageBox>
mailing_window*
mailing_window::m_current_instance; // singleton
void
open_mailing_window()
{
mailing_window* w = mailing_window::open_unique();
w->show();
w->activateWindow();
w->raise();
}
mailing_window*
mailing_window::open_unique()
{
if (!m_current_instance)
m_current_instance = new mailing_window();
return m_current_instance;
}
mailing_window::mailing_window()
{
setAttribute(Qt::WA_DeleteOnClose);
setWindowIcon(UI_ICON(ICON16_MAIL_MERGE));
setWindowTitle(tr("Mailings"));
QVBoxLayout* top_layout = new QVBoxLayout(this);
top_layout->setMargin(5);
QTreeWidget* w = new QTreeWidget();
m_treewidget = w;
top_layout->addWidget(w);
QStringList labels;
labels << tr("Title") << tr("Date") << tr("Status") << tr("Sent") << tr("Completion");
w->setHeaderLabels(labels);
w->header()->resizeSection(0, 200);
w->setRootIsDecorated(false);
w->setAllColumnsShowFocus(true);
QHBoxLayout* buttons = new QHBoxLayout();
top_layout->addLayout(buttons);
m_btn_stop_restart = new QPushButton(tr("Stop"));
buttons->addWidget(m_btn_stop_restart);
connect(m_btn_stop_restart, SIGNAL(clicked()), this, SLOT(start_stop()));
m_btn_delete = new QPushButton(tr("Delete"));
buttons->addWidget(m_btn_delete);
connect(m_btn_delete, SIGNAL(clicked()), this, SLOT(delete_mailing()));
m_btn_view = new QPushButton(tr("View"));
buttons->addWidget(m_btn_view);
connect(m_btn_view, SIGNAL(clicked()), this, SLOT(view_mailing()));
#if 0
m_btn_clone = new QPushButton(tr("Clone..."));
buttons->addWidget(m_btn_clone);
connect(m_btn_clone, SIGNAL(clicked()), this, SLOT(clone_mailing()));
#endif
buttons->addStretch(5);
m_btn_refresh = new QPushButton(tr("Refresh"));
buttons->addWidget(m_btn_refresh);
connect(m_btn_refresh, SIGNAL(clicked()), this, SLOT(refresh()));
m_btn_new = new QPushButton(tr("New..."));
buttons->addWidget(m_btn_new);
connect(m_btn_new, SIGNAL(clicked()), this, SLOT(new_mailing()));
connect(w, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
this, SLOT(item_changed(QTreeWidgetItem*,QTreeWidgetItem*)));
w->setSortingEnabled(true);
w->sortByColumn(mailing_window_widget_item::index_column_date, Qt::DescendingOrder);
load();
m_timer = new QTimer(this);
m_timer->start(5000);
connect(m_timer, SIGNAL(timeout()), this, SLOT(refresh()));
resize(600,300);
}
mailing_window::~mailing_window()
{
m_current_instance=NULL;
}
void
mailing_window::item_changed(QTreeWidgetItem* item, QTreeWidgetItem* old)
{
Q_UNUSED(old);
if (item) {
mailing_db* m = get_mailing(item->data(0, mailing_window_widget_item::mailing_id_role).toInt());
if (m) {
update_buttons(m);
}
}
else {
DBG_PRINTF(2, "item_changed for NULL");
}
}
void
mailing_window::update_buttons(mailing_db* m)
{
if (m->status()==mailing_db::status_not_started || m->status()==mailing_db::status_stopped ) {
m_btn_stop_restart->setText(tr("Start"));
m_btn_stop_restart->setEnabled(true);
}
else if (m->status()==mailing_db::status_running) {
m_btn_stop_restart->setText(tr("Stop"));
m_btn_stop_restart->setEnabled(true);
}
else if (m->status()==mailing_db::status_finished) {
m_btn_stop_restart->setText(tr("Stop"));
m_btn_stop_restart->setEnabled(false);
}
}
mailing_db*
mailing_window::get_mailing(int mailing_id)
{
mailings::iterator iter = m_mailings.begin();
for (; iter != m_mailings.end(); ++iter) {
if (iter->id() == mailing_id)
return &(*iter);
}
return NULL;
}
// retrieve the item in the treeview by the mailing_id
mailing_window_widget_item*
mailing_window::get_item(int mailing_id)
{
QTreeWidgetItemIterator it(m_treewidget);
while (*it) {
if ((*it)->data(0,mailing_window_widget_item::mailing_id_role).toInt() == mailing_id)
return static_cast<mailing_window_widget_item*>(*it);
++it;
}
return NULL;
}
mailing_db*
mailing_window::selected_item()
{
QTreeWidgetItem* item = m_treewidget->currentItem();
return item ? get_mailing(item->data(0, mailing_window_widget_item::mailing_id_role).toInt()) : NULL;
}
// Populate the list with contents from the database
void
mailing_window::load()
{
m_mailings.load();
mailings::const_iterator iter = m_mailings.constBegin();
for (; iter != m_mailings.constEnd(); ++iter) {
add_item(&(*iter));
}
}
mailing_window_widget_item*
mailing_window::add_item(const mailing_db* m)
{
mailing_window_widget_item* item = new mailing_window_widget_item();
QProgressBar* bar = new QProgressBar();
m_progress_bars[m->id()] = bar;
/* m_nb_sent should be lower or equal than m_nb_total, but if it
happens to be greater, we take it as the upper boundary */
bar->setRange(0, m->m_nb_total>=m->m_nb_sent ? m->m_nb_total : m->m_nb_sent);
m_treewidget->addTopLevelItem(item);
m_treewidget->setItemWidget(item, 4, bar);
item->setData(0, mailing_window_widget_item::mailing_id_role, m->id());
QVariant vdate;
vdate.setValue(m->creation_date());
item->setData(mailing_window_widget_item::index_column_date,
mailing_window_widget_item::mailing_date_role, vdate);
display_entry(item, m);
return item;
}
void
mailing_window::display_entry(QTreeWidgetItem* item, const mailing_db* m)
{
if (!item)
return;
int col=0;
item->setText(col++, m->title());
item->setText(col++, m->creation_date().output_8());
item->setText(col++, m->status_text());
item->setText(col++, QString("%1 / %2").arg(m->m_nb_sent).arg(m->m_nb_total));
QProgressBar* bar = m_progress_bars[m->id()];
if (bar) {
bar->setValue(m->m_nb_sent);
QString color="#1e8bd8"; // blue
switch(m->status()) {
case mailing_db::status_running:
color="green";
break;
case mailing_db::status_stopped:
color="red";
break;
}
QString style=QString("QProgressBar:horizontal {"
"border: 1px solid gray;"
"border-radius: 3px;"
"background: white;"
"padding: 1px;"
"text-align: center;"
"font-weight: bold;"
"}"
"QProgressBar::chunk:horizontal {"
"background: qlineargradient(x1: 0, y1: 0.5, x2: 1, y2: 0.5, stop: 0 %1, stop: 1 white);"
"}").arg(color);
bar->setStyleSheet(style);
}
}
void
mailing_window::start_stop()
{
mailing_db* m = selected_item();
if (!m) return;
if (m->status()==mailing_db::status_not_started || m->status()==mailing_db::status_stopped ) {
m->instantiate_job();
}
else if (m->status()==mailing_db::status_running) {
m->stop();
}
update_buttons(m);
display_entry(m_treewidget->currentItem(), m);
}
// Refetch from the database the status and progress of running mailings
void
mailing_window::refresh()
{
mailings list;
mailing_db* msel = selected_item();
if (list.load()) {
// foreach mailing, check if changes have occurred
mailings::iterator iter = list.begin();
for (; iter != list.end(); ++iter) {
DBG_PRINTF(4, "mailing_id=%d in the list", iter->id());
mailing_db* m = get_mailing(iter->id());
if (!m) {
// add new entry
m_mailings.append(*iter); // a new mailing has appeared
add_item(&(*iter));
}
else if (m->status()!=iter->status() || m->m_nb_sent!=iter->m_nb_sent) {
// redisplay entry
mailing_window_widget_item* item = get_item(iter->id());
if (item)
display_entry(item, &(*iter));
*m = *iter;
}
if (msel!=NULL && msel==m) {
update_buttons(m);
}
}
}
}
void
mailing_window::view_mailing()
{
mailing_db* m = selected_item();
if (!m) return;
mailing_viewer* w = new mailing_viewer;
w->setAttribute(Qt::WA_DeleteOnClose);
w->show_merge_existing(m);
}
void
mailing_window::new_mailing()
{
mailing_wizard* mw = new mailing_wizard();
connect(mw, SIGNAL(accepted()), this, SLOT(new_mailing_started()));
mw->show();
}
void
mailing_window::new_mailing_started()
{
show();
activateWindow();
raise();
refresh();
}
#if 0
void
mailing_window::clone_mailing()
{
mailing_db* m = selected_item();
if (!m) return;
mailing_wizard* mw = new mailing_wizard();
connect(mw, SIGNAL(accepted()), this, SLOT(refresh()));
m->load_definition(&mw->m_options);
mw->show();
}
#endif
void
mailing_window::delete_mailing()
{
mailing_db* m = selected_item();
if (!m)
return;
int rep = QMessageBox::question(this, tr("Confirmation"),
tr("Please confirm the complete removal of the mailing"),
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
if (rep==QMessageBox::Cancel) {
return;
}
else {
if (m->purge()) {
QTreeWidgetItem* item = m_treewidget->currentItem();
if (item) {
int index = m_treewidget->indexOfTopLevelItem(item);
m_treewidget->takeTopLevelItem(index);
}
}
}
}
bool
mailing_window_widget_item::operator<(const QTreeWidgetItem& other) const
{
int column = treeWidget()->header()->sortIndicatorSection();
if (column==index_column_date) {
QVariant v1 = data(column, mailing_date_role);
QVariant v2 = other.data(column, mailing_date_role);
return v1.value<date>() < v2.value<date>();
}
else
return QTreeWidgetItem::operator<(other);
}
HTML source code generated by GNU Source-Highlight plus some custom post-processing
List of all available source files