/*
* The ManaPlus Client
* Copyright (C) 2011-2018 The ManaPlus Developers
*
* This file is part of The ManaPlus Client.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* 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, see .
*/
#include "gui/windows/mailwindow.h"
#include "settings.h"
#include "enums/gui/layouttype.h"
#include "net/mail2handler.h"
#include "net/mailhandler.h"
#include "gui/models/extendednamesmodel.h"
#include "gui/mailmessage.h"
#include "gui/windows/maileditwindow.h"
#include "gui/windows/mailviewwindow.h"
#include "gui/windows/setupwindow.h"
#include "gui/widgets/button.h"
#include "gui/widgets/containerplacer.h"
#include "gui/widgets/createwidget.h"
#include "gui/widgets/extendedlistbox.h"
#include "gui/widgets/layout.h"
#include "gui/widgets/scrollarea.h"
#include "utils/delete2.h"
#include "utils/dtor.h"
#include "utils/foreach.h"
#include "utils/gettext.h"
#include "utils/stringutils.h"
#include "debug.h"
MailWindow *mailWindow = nullptr;
MailWindow::MailWindow() :
// TRANSLATORS: mail window name
Window(_("Mail"), Modal_false, nullptr, "mail.xml"),
ActionListener(),
mMessages(),
mMessagesMap(),
mMailModel(new ExtendedNamesModel),
mListBox(CREATEWIDGETR(ExtendedListBox,
this, mMailModel, "extendedlistbox.xml", 0)),
mListScrollArea(new ScrollArea(this, mListBox,
fromBool(getOptionBool("showlistbackground", false), Opaque),
"mail_listbackground.xml")),
// TRANSLATORS: mail window button
mRefreshButton(new Button(this, _("Refresh"), "refresh",
BUTTON_SKIN, this)),
// TRANSLATORS: mail window button
mNewButton(new Button(this, _("New"), "new", BUTTON_SKIN, this)),
// TRANSLATORS: mail window button
mDeleteButton(new Button(this, _("Delete"), "delete", BUTTON_SKIN, this)),
mReturnButton(new Button(this,
// TRANSLATORS: mail window button
settings.enableNewMailSystem ? _("Get old") : _("Return"),
"return", BUTTON_SKIN, this)),
// TRANSLATORS: mail window button
mOpenButton(new Button(this, _("Open"), "open", BUTTON_SKIN, this)),
mOpenType(MailOpenType::Mail),
mUseMail2(settings.enableNewMailSystem),
mLastPage(false)
{
setWindowName("Mail");
setCloseButton(true);
setResizable(true);
setCloseButton(true);
setSaveVisible(true);
setStickyButtonLock(true);
if (setupWindow != nullptr)
setupWindow->registerWindowForReset(this);
setDefaultSize(310, 180, ImagePosition::CENTER, 0, 0);
setMinWidth(310);
setMinHeight(250);
center();
mListScrollArea->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER);
ContainerPlacer placer(nullptr, nullptr);
placer = getPlacer(0, 0);
placer(0, 0, mListScrollArea, 4, 5).setPadding(3);
placer(4, 0, mRefreshButton, 1, 1);
placer(4, 1, mOpenButton, 1, 1);
placer(4, 2, mNewButton, 1, 1);
placer(4, 3, mDeleteButton, 1, 1);
placer(4, 4, mReturnButton, 1, 1);
Layout &layout = getLayout();
layout.setRowHeight(0, LayoutType::SET);
loadWindowState();
enableVisibleSound(true);
}
MailWindow::~MailWindow()
{
delete_all(mMessages);
delete2(mMailModel)
delete2(mailViewWindow)
delete2(mailEditWindow)
}
void MailWindow::action(const ActionEvent &event)
{
const std::string &eventId = event.getId();
if (eventId == "refresh")
{
refreshMails();
}
else if (eventId == "new")
{
if (mailEditWindow == nullptr)
{
CREATEWIDGETV0(mailEditWindow, MailEditWindow);
}
}
else if (eventId == "open")
{
const int sel = mListBox->getSelected();
if (sel < 0)
return;
const MailMessage *const mail = mMessages[sel];
if (mUseMail2)
mail2Handler->readMail(mOpenType, mail->id);
else
mailHandler->readMessage(CAST_S32(mail->id));
}
else if (eventId == "delete")
{
const int sel = mListBox->getSelected();
if (sel < 0)
return;
const MailMessage *const mail = mMessages[sel];
if (mUseMail2)
mail2Handler->deleteMail(mOpenType, mail->id);
else
mailHandler->deleteMessage(CAST_S32(mail->id));
}
else if (eventId == "return")
{
if (mUseMail2)
{
const size_t idx = mMessages.size();
if (idx == 0)
mail2Handler->refreshMailList(MailOpenType::Mail, 0);
else
mail2Handler->nextPage(mOpenType, mMessages[idx - 1]->id);
}
else
{
const int sel = mListBox->getSelected();
if (sel < 0)
return;
const MailMessage *const mail = mMessages[sel];
mailHandler->returnMessage(CAST_S32(mail->id));
}
}
}
void MailWindow::clear()
{
delete_all(mMessages);
mMessages.clear();
mMessagesMap.clear();
mMailModel->clear();
mListBox->setSelected(-1);
}
std::string MailWindow::getMailHeader(const MailMessage *const message) const
{
if (mUseMail2)
{
std::string header;
if (message->expired)
{
// TRANSLATORS: expired mail message prefix
header = _("(expired)");
}
if (message->read)
header.append(" ");
else
header.append("U");
const MailMessageType::Type type = message->type;
if ((type & MailMessageType::Money) != 0)
header.append("M");
else
header.append(" ");
if ((type & MailMessageType::Item) != 0)
header.append("I");
else
header.append(" ");
header.append(" ").append(message->title);
return header;
}
return strprintf("%s %s",
message->read ? " " : "U",
message->title.c_str());
}
void MailWindow::addMail(MailMessage *const message)
{
if (message == nullptr)
return;
mMessages.push_back(message);
mMailModel->add(getMailHeader(message));
mMessagesMap[message->id] = message;
}
void MailWindow::removeMail(const int64_t id)
{
std::map::iterator it1 = mMessagesMap.find(id);
if (it1 != mMessagesMap.end())
mMessagesMap.erase(it1);
mMailModel->clear();
FOR_EACH (STD_VECTOR::iterator, it, mMessages)
{
MailMessage *message = *it;
if ((message != nullptr) && message->id == id)
{
mMessages.erase(it);
delete message;
break;
}
}
FOR_EACH (STD_VECTOR::iterator, it, mMessages)
{
MailMessage *message = *it;
if (message != nullptr)
mMailModel->add(getMailHeader(message));
}
}
void MailWindow::showMessage(MailMessage *const mail,
const int itemsCount)
{
if (mail == nullptr)
return;
const std::map::const_iterator
it = mMessagesMap.find(mail->id);
if (it != mMessagesMap.end())
{
const MailMessage *const mail2 = (*it).second;
mail->time = mail2->time;
mail->strTime = mail2->strTime;
}
delete mailViewWindow;
CREATEWIDGETV(mailViewWindow, MailViewWindow, mail,
itemsCount);
}
void MailWindow::viewNext(const int64_t id)
{
FOR_EACH (STD_VECTOR::iterator, it, mMessages)
{
MailMessage *message = *it;
if (message != nullptr &&
message->id == id)
{
++ it;
if (it == mMessages.end())
{
it = mMessages.begin();
mListBox->setSelected(0);
}
else
{
mListBox->setSelected(mListBox->getSelected() + 1);
}
message = *it;
if (mUseMail2)
mail2Handler->readMail(mOpenType, message->id);
else
mailHandler->readMessage(CAST_S32(message->id));
return;
}
}
}
void MailWindow::viewPrev(const int64_t id)
{
FOR_EACH (STD_VECTOR::iterator, it, mMessages)
{
MailMessage *message = *it;
if (message != nullptr &&
message->id == id)
{
if (it == mMessages.begin())
{
it = mMessages.end();
mListBox->setSelected(CAST_S32(mMessages.size()) - 1);
}
else
{
mListBox->setSelected(mListBox->getSelected() - 1);
}
-- it;
message = *it;
if (mUseMail2)
mail2Handler->readMail(mOpenType, message->id);
else
mailHandler->readMessage(CAST_S32(message->id));
return;
}
}
}
void MailWindow::mouseClicked(MouseEvent &event)
{
if (event.getButton() == MouseButton::LEFT)
{
event.consume();
if (event.getClickCount() == 2 &&
event.getSource() == mListBox)
{
action(ActionEvent(mListBox, "open"));
}
}
}
void MailWindow::postConnection()
{
refreshMails();
}
void MailWindow::refreshMails()
{
if (mUseMail2)
{
clear();
mail2Handler->refreshMailList(MailOpenType::Mail, 0);
mLastPage = false;
mReturnButton->setEnabled(true);
}
else
{
mailHandler->refresh();
}
}
void MailWindow::createMail(const std::string &to)
{
if (mailEditWindow != nullptr)
return;
CREATEWIDGETV0(mailEditWindow, MailEditWindow);
mailEditWindow->setTo(to);
}
MailMessage *MailWindow::findMail(const int64_t id)
{
std::map::iterator it = mMessagesMap.find(id);
if (it != mMessagesMap.end())
return (*it).second;
return nullptr;
}
void MailWindow::setLastPage()
{
mLastPage = true;
mReturnButton->setEnabled(false);
}
void MailWindow::refreshMailNames()
{
mMailModel->clear();
FOR_EACH (STD_VECTOR::iterator, it, mMessages)
{
MailMessage *message = *it;
if (message != nullptr)
mMailModel->add(getMailHeader(message));
}
}