You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

556 lines
18 KiB

/*
This file is part of KDE Kontact.
Copyright (C) 2003 Sven Lüppken <sven@kde.org>
Copyright (C) 2003 Tobias König <tokoe@kde.org>
Copyright (C) 2003 Daniel Molkentin <molkentin@kde.org>
Copyright (C) 2008 Allen Winter <winter@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "summaryview_part.h"
#include "dropwidget.h"
#include <PimCommon/BroadcastStatus>
using PimCommon::BroadcastStatus;
#include <KIdentityManagement/Identity>
#include <KIdentityManagement/IdentityManager>
#include <KontactInterface/Core>
#include <KontactInterface/Plugin>
#include <KontactInterface/Summary>
#include <QAction>
#include <KActionCollection>
#include <KCMultiDialog>
#include <KConfigGroup>
#include <QIcon>
#include <KLocalizedString>
#include <KParts/PartActivateEvent>
#include <KConfig>
#include <QApplication>
#include <QDate>
#include <QHBoxLayout>
#include <QLabel>
#include <QScrollArea>
#include <QTimer>
#include <QVBoxLayout>
#include <QLocale>
SummaryViewPart::SummaryViewPart(KontactInterface::Core *core, const KAboutData &aboutData, QObject *parent)
: KParts::Part(parent)
, mCore(core)
{
Q_UNUSED(aboutData);
setComponentName(QStringLiteral("kontactsummary"), i18n("Kontact Summary"));
loadLayout();
initGUI(core);
setDate(QDate::currentDate());
connect(mCore, &KontactInterface::Core::dayChanged, this, &SummaryViewPart::setDate);
mConfigAction = new QAction(QIcon::fromTheme(QStringLiteral("configure")), i18n("&Configure Summary View..."), this);
actionCollection()->addAction(QStringLiteral("summaryview_configure"), mConfigAction);
connect(mConfigAction, &QAction::triggered, this, &SummaryViewPart::slotConfigure);
const QString str = i18n("Configure the summary view");
mConfigAction->setStatusTip(str);
mConfigAction->setToolTip(str);
mConfigAction->setWhatsThis(
i18nc("@info:whatsthis",
"Choosing this will show a dialog where you can select which "
"summaries you want to see and also allow you to configure "
"the summaries to your liking."));
setXMLFile(QStringLiteral("kontactsummary_part.rc"));
QTimer::singleShot(0, this, &SummaryViewPart::slotTextChanged);
}
SummaryViewPart::~SummaryViewPart()
{
saveLayout();
}
void SummaryViewPart::partActivateEvent(KParts::PartActivateEvent *event)
{
// inform the plugins that the part has been activated so that they can
// update the displayed information
if (event->activated() && (event->part() == this)) {
updateSummaries();
}
KParts::Part::partActivateEvent(event);
}
void SummaryViewPart::updateSummaries()
{
QMap<QString, KontactInterface::Summary *>::ConstIterator it;
QMap<QString, KontactInterface::Summary *>::ConstIterator end(mSummaries.constEnd());
for (it = mSummaries.constBegin(); it != end; ++it) {
it.value()->updateSummary(false);
}
}
void SummaryViewPart::updateWidgets()
{
mMainWidget->setUpdatesEnabled(false);
delete mFrame;
const KIdentityManagement::Identity &id = KIdentityManagement::IdentityManager::self()->defaultIdentity();
const QString currentUser = i18n("Summary for %1", id.fullName());
mUsernameLabel->setText(QStringLiteral("<b>%1</b>").arg(currentUser));
mSummaries.clear();
mFrame = new DropWidget(mMainWidget);
connect(mFrame, &DropWidget::summaryWidgetDropped, this, &SummaryViewPart::summaryWidgetMoved);
mMainLayout->insertWidget(2, mFrame);
KConfig config(QStringLiteral("kontact_summaryrc"));
KConfigGroup grp(&config, QString());
QStringList activeSummaries;
if (grp.hasKey("ActiveSummaries")) {
activeSummaries = grp.readEntry("ActiveSummaries", QStringList());
} else {
activeSummaries << QStringLiteral("kontact_korganizerplugin");
activeSummaries << QStringLiteral("kontact_todoplugin");
activeSummaries << QStringLiteral("kontact_specialdatesplugin");
activeSummaries << QStringLiteral("kontact_kmailplugin");
activeSummaries << QStringLiteral("kontact_knotesplugin");
}
// Collect all summary widgets with a summaryHeight > 0
QStringList loadedSummaries;
QList<KontactInterface::Plugin *> plugins = mCore->pluginList();
QList<KontactInterface::Plugin *>::ConstIterator end = plugins.constEnd();
QList<KontactInterface::Plugin *>::ConstIterator it = plugins.constBegin();
for (; it != end; ++it) {
KontactInterface::Plugin *plugin = *it;
if (!activeSummaries.contains(plugin->identifier())) {
continue;
}
KontactInterface::Summary *summary = plugin->createSummaryWidget(mFrame);
if (summary) {
if (summary->summaryHeight() > 0) {
mSummaries.insert(plugin->identifier(), summary);
connect(summary, &KontactInterface::Summary::message,
BroadcastStatus::instance(), &PimCommon::BroadcastStatus::setStatusMsg);
connect(summary, &KontactInterface::Summary::summaryWidgetDropped,
this, &SummaryViewPart::summaryWidgetMoved);
if (!mLeftColumnSummaries.contains(plugin->identifier())
&& !mRightColumnSummaries.contains(plugin->identifier())) {
mLeftColumnSummaries.append(plugin->identifier());
}
loadedSummaries.append(plugin->identifier());
} else {
summary->hide();
}
}
}
// Remove all unavailable summary widgets
{
QStringList::Iterator strIt;
for (strIt = mLeftColumnSummaries.begin(); strIt != mLeftColumnSummaries.end(); ++strIt) {
if (!loadedSummaries.contains(*strIt)) {
strIt = mLeftColumnSummaries.erase(strIt);
--strIt;
}
}
for (strIt = mRightColumnSummaries.begin(); strIt != mRightColumnSummaries.end(); ++strIt) {
if (!loadedSummaries.contains(*strIt)) {
strIt = mRightColumnSummaries.erase(strIt);
--strIt;
}
}
}
// Add vertical line between the two rows of summary widgets.
QFrame *vline = new QFrame(mFrame);
vline->setFrameStyle(QFrame::VLine | QFrame::Plain);
QHBoxLayout *layout = new QHBoxLayout(mFrame);
int margin = 20; // margin width: insert margins so there is space to dnd a
// summary when either column is empty. looks nicer too.
layout->insertSpacing(0, margin);
mLeftColumn = new QVBoxLayout();
layout->addLayout(mLeftColumn);
layout->addWidget(vline);
mRightColumn = new QVBoxLayout();
layout->addLayout(mRightColumn);
layout->insertSpacing(-1, margin);
QStringList::ConstIterator strIt;
QStringList::ConstIterator strEnd(mLeftColumnSummaries.constEnd());
for (strIt = mLeftColumnSummaries.constBegin(); strIt != strEnd; ++strIt) {
if (mSummaries.contains(*strIt)) {
mLeftColumn->addWidget(mSummaries[ *strIt ]);
}
}
strEnd = mRightColumnSummaries.constEnd();
for (strIt = mRightColumnSummaries.constBegin(); strIt != strEnd; ++strIt) {
if (mSummaries.contains(*strIt)) {
mRightColumn->addWidget(mSummaries[ *strIt ]);
}
}
QSpacerItem *lspacer = new QSpacerItem(1, 10,
QSizePolicy::MinimumExpanding,
QSizePolicy::MinimumExpanding);
QSpacerItem *rspacer = new QSpacerItem(1, 10,
QSizePolicy::MinimumExpanding,
QSizePolicy::MinimumExpanding);
mLeftColumn->addSpacerItem(lspacer);
mRightColumn->addSpacerItem(rspacer);
mFrame->show();
mMainWidget->setUpdatesEnabled(true);
mMainWidget->update();
mLeftColumn->addStretch();
mRightColumn->addStretch();
}
void SummaryViewPart::summaryWidgetMoved(QWidget *target, QObject *obj, int alignment)
{
QWidget *widget = qobject_cast<QWidget *>(obj);
if (!widget || (target == widget)) {
return;
}
if (target == mFrame) {
if (mLeftColumn->indexOf(widget) == -1 && mRightColumn->indexOf(widget) == -1) {
return;
}
} else {
if ((mLeftColumn->indexOf(target) == -1 && mRightColumn->indexOf(target) == -1)
|| (mLeftColumn->indexOf(widget) == -1 && mRightColumn->indexOf(widget) == -1)) {
return;
}
}
if (!QApplication::isRightToLeft()) {
drawLtoR(target, widget, alignment);
} else {
drawRtoL(target, widget, alignment);
}
}
void SummaryViewPart::drawLtoR(QWidget *target, QWidget *widget, int alignment)
{
if (mLeftColumn->indexOf(widget) != -1) {
mLeftColumn->removeWidget(widget);
mLeftColumnSummaries.removeAll(widgetName(widget));
} else if (mRightColumn->indexOf(widget) != -1) {
mRightColumn->removeWidget(widget);
mRightColumnSummaries.removeAll(widgetName(widget));
}
if (target == mFrame) {
int pos = 0;
if (alignment & Qt::AlignTop) {
pos = 0;
}
if (alignment & Qt::AlignLeft) {
if (alignment & Qt::AlignBottom) {
pos = mLeftColumnSummaries.count();
}
mLeftColumn->insertWidget(pos, widget);
mLeftColumnSummaries.insert(pos, widgetName(widget));
} else {
if (alignment & Qt::AlignBottom) {
pos = mRightColumnSummaries.count();
}
mRightColumn->insertWidget(pos, widget);
mRightColumnSummaries.insert(pos, widgetName(widget));
}
mFrame->updateGeometry();
return;
}
int targetPos = mLeftColumn->indexOf(target);
if (targetPos != -1) {
if (alignment == Qt::AlignBottom) {
targetPos++;
}
mLeftColumn->insertWidget(targetPos, widget);
mLeftColumnSummaries.insert(targetPos, widgetName(widget));
} else {
targetPos = mRightColumn->indexOf(target);
if (alignment == Qt::AlignBottom) {
targetPos++;
}
mRightColumn->insertWidget(targetPos, widget);
mRightColumnSummaries.insert(targetPos, widgetName(widget));
}
mFrame->updateGeometry();
}
void SummaryViewPart::drawRtoL(QWidget *target, QWidget *widget, int alignment)
{
if (mRightColumn->indexOf(widget) != -1) {
mRightColumn->removeWidget(widget);
mRightColumnSummaries.removeAll(widgetName(widget));
} else if (mLeftColumn->indexOf(widget) != -1) {
mLeftColumn->removeWidget(widget);
mLeftColumnSummaries.removeAll(widgetName(widget));
}
if (target == mFrame) {
int pos = 0;
if (alignment & Qt::AlignTop) {
pos = 0;
}
if (alignment & Qt::AlignLeft) {
if (alignment & Qt::AlignBottom) {
pos = mRightColumnSummaries.count();
}
mRightColumn->insertWidget(pos, widget);
mRightColumnSummaries.insert(pos, widgetName(widget));
} else {
if (alignment & Qt::AlignBottom) {
pos = mLeftColumnSummaries.count();
}
mLeftColumn->insertWidget(pos, widget);
mLeftColumnSummaries.insert(pos, widgetName(widget));
}
mFrame->updateGeometry();
return;
}
int targetPos = mRightColumn->indexOf(target);
if (targetPos != -1) {
if (alignment == Qt::AlignBottom) {
targetPos++;
}
mRightColumn->insertWidget(targetPos, widget);
mRightColumnSummaries.insert(targetPos, widgetName(widget));
} else {
targetPos = mLeftColumn->indexOf(target);
if (alignment == Qt::AlignBottom) {
targetPos++;
}
mLeftColumn->insertWidget(targetPos, widget);
mLeftColumnSummaries.insert(targetPos, widgetName(widget));
}
mFrame->updateGeometry();
}
void SummaryViewPart::slotTextChanged()
{
Q_EMIT textChanged(i18n("What's next?"));
}
void SummaryViewPart::slotAdjustPalette()
{
if (!QApplication::isRightToLeft()) {
mMainWidget->setStyleSheet(
QStringLiteral("#mMainWidget { "
" background: palette(base);"
" color: palette(text);"
" background-image: url(:/summaryview/kontact_bg.png);"
" background-position: bottom right;"
" background-repeat: no-repeat; }"
"QLabel { "
" color: palette(text); }"
"KUrlLabel { "
" color: palette(link); }"));
} else {
mMainWidget->setStyleSheet(
QStringLiteral("#mMainWidget { "
" background: palette(base);"
" color: palette(text);"
" background-image: url(:/summaryview/kontact_bg.png);"
" background-position: bottom left;"
" background-repeat: no-repeat; }"
"QLabel { "
" color: palette(text); }"
"KUrlLabel { "
" color: palette(link); }"));
}
}
void SummaryViewPart::setDate(const QDate &newDate)
{
QString date(QStringLiteral("<b>%1</b>"));
date = date.arg(QLocale().toString(newDate));
mDateLabel->setText(date);
}
void SummaryViewPart::slotConfigure()
{
QPointer<KCMultiDialog> dlg = new KCMultiDialog(mMainWidget);
dlg->setObjectName(QStringLiteral("ConfigDialog"));
dlg->setModal(true);
QStringList modules = configModules();
modules.prepend(QStringLiteral("kcmkontactsummary.desktop"));
connect(dlg.data(), qOverload<>(&KCMultiDialog::configCommitted),
this, &SummaryViewPart::updateWidgets);
QStringList::ConstIterator strIt;
QStringList::ConstIterator end(modules.constEnd());
for (strIt = modules.constBegin(); strIt != end; ++strIt) {
dlg->addModule(*strIt);
}
dlg->exec();
delete dlg;
}
QStringList SummaryViewPart::configModules() const
{
QStringList modules;
QMap<QString, KontactInterface::Summary *>::ConstIterator it;
QMap<QString, KontactInterface::Summary *>::ConstIterator end(mSummaries.constEnd());
for (it = mSummaries.constBegin(); it != end; ++it) {
QStringList cm = it.value()->configModules();
QStringList::ConstIterator strIt;
QStringList::ConstIterator strEnd(cm.constEnd());
for (strIt = cm.constBegin(); strIt != strEnd; ++strIt) {
if (!(*strIt).isEmpty() && !modules.contains(*strIt)) {
modules.append(*strIt);
}
}
}
return modules;
}
void SummaryViewPart::initGUI(KontactInterface::Core *core)
{
QScrollArea *sa = new QScrollArea(core);
sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
sa->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
sa->setWidgetResizable(true);
mMainWidget = new QFrame;
mMainWidget->setObjectName(QStringLiteral("mMainWidget"));
sa->setWidget(mMainWidget);
mMainWidget->setFocusPolicy(Qt::StrongFocus);
setWidget(sa);
//KF5: port it
//connect(KGlobalSettings::self(), &KGlobalSettings::kdisplayPaletteChanged, this, &SummaryViewPart::slotAdjustPalette);
slotAdjustPalette();
mMainLayout = new QVBoxLayout(mMainWidget);
QHBoxLayout *hbl = new QHBoxLayout();
mMainLayout->addItem(hbl);
mUsernameLabel = new QLabel(mMainWidget);
mDateLabel = new QLabel(mMainWidget);
if (!QApplication::isRightToLeft()) {
mUsernameLabel->setAlignment(Qt::AlignLeft);
hbl->addWidget(mUsernameLabel);
mDateLabel->setAlignment(Qt::AlignRight);
hbl->addWidget(mDateLabel);
} else {
mDateLabel->setAlignment(Qt::AlignRight);
hbl->addWidget(mDateLabel);
mUsernameLabel->setAlignment(Qt::AlignLeft);
hbl->addWidget(mUsernameLabel);
}
QFrame *hline = new QFrame(mMainWidget);
hline->setFrameStyle(QFrame::HLine | QFrame::Plain);
mMainLayout->insertWidget(1, hline);
mFrame = new DropWidget(mMainWidget);
mMainLayout->insertWidget(2, mFrame);
connect(mFrame, &DropWidget::summaryWidgetDropped, this, &SummaryViewPart::summaryWidgetMoved);
updateWidgets();
}
void SummaryViewPart::loadLayout()
{
KConfig config(QStringLiteral("kontact_summaryrc"));
KConfigGroup grp(&config, QString());
if (grp.hasKey("LeftColumnSummaries")) {
mLeftColumnSummaries = grp.readEntry("LeftColumnSummaries", QStringList());
} else {
mLeftColumnSummaries << QStringLiteral("kontact_korganizerplugin");
mLeftColumnSummaries << QStringLiteral("kontact_todoplugin");
mLeftColumnSummaries << QStringLiteral("kontact_specialdatesplugin");
}
if (grp.hasKey("RightColumnSummaries")) {
mRightColumnSummaries = grp.readEntry("RightColumnSummaries", QStringList());
} else {
mRightColumnSummaries << QStringLiteral("kontact_kmailplugin");
mRightColumnSummaries << QStringLiteral("kontact_knotesplugin");
}
}
void SummaryViewPart::saveLayout()
{
KConfig config(QStringLiteral("kontact_summaryrc"));
KConfigGroup grp(&config, QString());
grp.writeEntry("LeftColumnSummaries", mLeftColumnSummaries);
grp.writeEntry("RightColumnSummaries", mRightColumnSummaries);
config.sync();
}
QString SummaryViewPart::widgetName(QWidget *widget) const
{
QMap<QString, KontactInterface::Summary *>::ConstIterator it;
QMap<QString, KontactInterface::Summary *>::ConstIterator end(mSummaries.constEnd());
for (it = mSummaries.constBegin(); it != end; ++it) {
if (it.value() == widget) {
return it.key();
}
}
return QString();
}