diff --git a/calendarviews/helper.cpp b/calendarviews/helper.cpp index 8ca2b62d73..b499d9c4b0 100644 --- a/calendarviews/helper.cpp +++ b/calendarviews/helper.cpp @@ -1,71 +1,75 @@ /* Copyright (C) 2005 Reinhold Kainhofer 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 (at your option) 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include "helper.h" #include "prefs.h" #include #include +#include #include #include #include QColor EventViews::getTextColor( const QColor &c ) { double luminance = ( c.red() * 0.299 ) + ( c.green() * 0.587 ) + ( c.blue() * 0.114 ); return ( luminance > 128.0 ) ? QColor( 0, 0, 0 ) : QColor( 255, 255, 255 ); } QColor EventViews::resourceColor( const Akonadi::Collection &coll, const PrefsPtr &preferences ) { if ( !coll.isValid() ) { return QColor(); } + Akonadi::CollectionColorAttribute *colorAttribute = coll.attribute(); + if (colorAttribute) { + return colorAttribute->color(); + } const QString id = QString::number( coll.id() ); return preferences->resourceColor( id ); } QColor EventViews::resourceColor( const Akonadi::Item &item, const PrefsPtr &preferences ) { if ( !item.isValid() ) { return QColor(); } - const QString id = QString::number( item.parentCollection().id() ); - return preferences->resourceColor( id ); + return resourceColor(item.parentCollection(), preferences); } int EventViews::yearDiff( const QDate &start, const QDate &end ) { return end.year() - start.year(); } QPixmap EventViews::cachedSmallIcon( const QString &name ) { QPixmap p; if ( !QPixmapCache::find( name, &p ) ) { p = SmallIcon( name ); } return p; } diff --git a/calendarviews/viewcalendar.cpp b/calendarviews/viewcalendar.cpp index f4cbe73b7b..765ff40b33 100644 --- a/calendarviews/viewcalendar.cpp +++ b/calendarviews/viewcalendar.cpp @@ -1,223 +1,224 @@ #include "viewcalendar.h" #include "eventview.h" #include "helper.h" #include #include using namespace EventViews; ViewCalendar::~ViewCalendar() { } MultiViewCalendar::~MultiViewCalendar() { } KCalCore::Incidence::List MultiViewCalendar::incidences() const { KCalCore::Incidence::List list; foreach(const ViewCalendar::Ptr &cal, mSubCalendars) { if (cal->getCalendar()) { list += cal->getCalendar()->incidences(); } } return list; } KCalCore::Journal::List MultiViewCalendar::journals(const QDate &date) const { KCalCore::Journal::List list; foreach(const ViewCalendar::Ptr &cal, mSubCalendars) { if (cal->getCalendar()) { list += cal->getCalendar()->journals(date); } } return list; } int MultiViewCalendar::calendars() const { return mSubCalendars.size(); } ViewCalendar::Ptr MultiViewCalendar::findCalendar(const KCalCore::Incidence::Ptr &incidence) const { foreach(const ViewCalendar::Ptr &cal, mSubCalendars) { if (cal->isValid(incidence)) { return cal; } } return ViewCalendar::Ptr(); } void MultiViewCalendar::addCalendar(const ViewCalendar::Ptr &calendar) { if (!mSubCalendars.contains(calendar)) { mSubCalendars.append(calendar); } } void MultiViewCalendar::setETMCalendar(const Akonadi::ETMCalendar::Ptr &calendar) { if (!mETMCalendar) { mETMCalendar = AkonadiViewCalendar::Ptr(new AkonadiViewCalendar); mETMCalendar->mEventView = mEventView; } mETMCalendar->mCalendar = calendar; addCalendar(mETMCalendar); } Akonadi::ETMCalendar::Ptr MultiViewCalendar::etmCalendar() const { if (mETMCalendar) { return mETMCalendar->mCalendar; } else { return Akonadi::ETMCalendar::Ptr(); } } QString MultiViewCalendar::displayName(const KCalCore::Incidence::Ptr &incidence) const { ViewCalendar::Ptr cal = findCalendar(incidence); if (cal) { return cal->displayName(incidence); } return QString(); } QString MultiViewCalendar::iconForIncidence(const KCalCore::Incidence::Ptr &incidence) const { ViewCalendar::Ptr cal = findCalendar(incidence); if (cal) { return cal->iconForIncidence(incidence); } return QString(); } bool MultiViewCalendar::isValid(const KCalCore::Incidence::Ptr &incidence) const { ViewCalendar::Ptr cal = findCalendar(incidence); return cal; } QColor MultiViewCalendar::resourceColor(const KCalCore::Incidence::Ptr &incidence) const { ViewCalendar::Ptr cal = findCalendar(incidence); if (cal) { return cal->resourceColor(incidence); } return QColor(); } QString MultiViewCalendar::uid(const KCalCore::Incidence::Ptr &incidence) const { ViewCalendar::Ptr cal = findCalendar(incidence); if (cal) { return cal->uid(incidence); } else if (incidence) { kWarning() << "Unknown incidence for MultiViewCalendar" << incidence->uid(); } //using it without a valid incidence don't make sense, so ASSERT Q_ASSERT(incidence); return QString(); } Akonadi::Item MultiViewCalendar::item(const KCalCore::Incidence::Ptr &incidence) const { if (mETMCalendar->isValid(incidence)) { return mETMCalendar->item(incidence); } return Akonadi::Item(); } QList< ViewCalendar::Ptr > MultiViewCalendar::subCalendars() const { return mSubCalendars; } AkonadiViewCalendar::~AkonadiViewCalendar() { } bool AkonadiViewCalendar::isValid(const KCalCore::Incidence::Ptr &incidence) const { if (!mCalendar) { return false; } return mCalendar->isValid(incidence); } Akonadi::Item AkonadiViewCalendar::item(const KCalCore::Incidence::Ptr &incidence) const { if (!mCalendar || !incidence) { return Akonadi::Item(); } bool ok = false; //FIXME Akonadi::Item::Id id = incidence->customProperty("VOLATILE", "AKONADI-ID").toLongLong(&ok); if (id == -1 || !ok) { id = mCalendar->item(incidence).id(); if (id == -1) { // Ok, we really don't know the ID, give up. kDebug() << "Item is invalid. uid = " << incidence->instanceIdentifier(); return Akonadi::Item(); } return mCalendar->item(incidence); } return mCalendar->item(id); } QString AkonadiViewCalendar::displayName(const KCalCore::Incidence::Ptr &incidence) const { return CalendarSupport::displayName( mCalendar.data(), item(incidence).parentCollection() ); } QColor AkonadiViewCalendar::resourceColor(const KCalCore::Incidence::Ptr &incidence) const { - return EventViews::resourceColor( item(incidence), mEventView->preferences() ); + // We need the uptodate parent collection and not an old version of it. + return EventViews::resourceColor(mCalendar->collection(item(incidence).parentCollection().id()), mEventView->preferences() ); } QString AkonadiViewCalendar::uid(const KCalCore::Incidence::Ptr &incidence) const { return mCalendar->uniqueInstanceIdentifier(incidence); } QString AkonadiViewCalendar::iconForIncidence(const KCalCore::Incidence::Ptr &incidence) const { QString iconName; Akonadi::Collection collection = item(incidence).parentCollection(); while ( collection.parentCollection().isValid() && collection.parentCollection() != Akonadi::Collection::root() ) { collection = mCalendar->collection( collection.parentCollection().id() ); } if ( collection.isValid() && collection.hasAttribute() ) { iconName = collection.attribute()->iconName(); } return iconName; } KDateTime::Spec AkonadiViewCalendar::timeSpec() const { return mCalendar->timeSpec(); } KCalCore::Calendar::Ptr AkonadiViewCalendar::getCalendar() const { return mCalendar; } diff --git a/korganizer/akonadicollectionview.cpp b/korganizer/akonadicollectionview.cpp index 5027778b6a..d14e3f3c6d 100644 --- a/korganizer/akonadicollectionview.cpp +++ b/korganizer/akonadicollectionview.cpp @@ -1,1114 +1,1124 @@ /* This file is part of KOrganizer. Copyright (c) 2003,2004 Cornelius Schumacher Copyright (C) 2003-2004 Reinhold Kainhofer Copyright (C) 2009 Sebastian Sauer Copyright (C) 2010 Laurent Montel Copyright (C) 2012 Sérgio Martins 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 (at your option) 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include "akonadicollectionview.h" #include "kocore.h" #include "kohelper.h" #include "koprefs.h" #include "koglobals.h" #include "views/collectionview/reparentingmodel.h" #include "views/collectionview/calendardelegate.h" #include "views/collectionview/quickview.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static Akonadi::EntityTreeModel *findEtm(QAbstractItemModel *model) { QAbstractProxyModel *proxyModel; while (model) { proxyModel = qobject_cast(model); if (proxyModel && proxyModel->sourceModel()) { model = proxyModel->sourceModel(); } else { break; } } return qobject_cast(model); } /** * Automatically checks new calendar entries */ class NewCalendarChecker : public QObject { Q_OBJECT public: NewCalendarChecker(QAbstractItemModel *model) :QObject(model), mCheckableProxy(model) { connect(model, SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(onSourceRowsInserted(QModelIndex, int, int))); qRegisterMetaType("QPersistentModelIndex"); } private slots: void onSourceRowsInserted(const QModelIndex &parent, int start, int end) { Akonadi::EntityTreeModel *etm = findEtm(mCheckableProxy); //Only check new collections and not during initial population if (!etm || !etm->isCollectionTreeFetched()) { return; } for (int i = start; i <= end; i++) { kDebug() << "checking " << i << parent << mCheckableProxy->index(i, 0, parent).data().toString(); const QModelIndex index = mCheckableProxy->index(i, 0, parent); QMetaObject::invokeMethod(this, "setCheckState", Qt::QueuedConnection, QGenericReturnArgument(), Q_ARG(QPersistentModelIndex, index)); } } void setCheckState(const QPersistentModelIndex &index) { mCheckableProxy->setData(index, Qt::Checked, Qt::CheckStateRole); if (mCheckableProxy->hasChildren(index)) { onSourceRowsInserted(index, 0, mCheckableProxy->rowCount(index) - 1); } } private: QAbstractItemModel *mCheckableProxy; }; /** * Handles expansion state of a treeview * * Persists state, and automatically expands new entries. * With expandAll enabled this class simply ensures that all indexes are fully expanded. */ class NewNodeExpander : public QObject { Q_OBJECT public: NewNodeExpander(QTreeView *view, bool expandAll, const QString &treeStateConfig) :QObject(view), mTreeView(view), mExpandAll(expandAll), mTreeStateConfig(treeStateConfig) { connect(view->model(), SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(onSourceRowsInserted(QModelIndex, int, int))); connect(view->model(), SIGNAL(layoutChanged()), this, SLOT(onLayoutChanged())); connect(view->model(), SIGNAL(modelReset()), this, SLOT(onModelReset())); restoreTreeState(); } virtual ~NewNodeExpander() { //Ideally we'd automatically save the treestate of the parent view here, //but that unfortunately doesn't seem to work } public Q_SLOTS: void saveState() { saveTreeState(); } private Q_SLOTS: void onSourceRowsInserted(const QModelIndex &parent, int start, int end) { //The initial expansion is handled by the state saver if (!mExpandAll) { Akonadi::EntityTreeModel *etm = findEtm(mTreeView->model()); if (!etm || !etm->isCollectionTreeFetched()) { restoreTreeState(); return; } } for (int i = start; i <= end; i++) { const QModelIndex index = mTreeView->model()->index(i, 0, parent); // kDebug() << "expanding " << index.data().toString(); if (index.data(NodeTypeRole).toInt() == PersonNodeRole) { mTreeView->collapse(index); } else { mTreeView->expand(index); } if (mTreeView->model()->hasChildren(index)) { onSourceRowsInserted(index, 0, mTreeView->model()->rowCount(index) - 1); } } } void onLayoutChanged() { if (mExpandAll) { onSourceRowsInserted(QModelIndex(), 0, mTreeView->model()->rowCount(QModelIndex()) - 1); } } void onModelReset() { if (mExpandAll) { onSourceRowsInserted(QModelIndex(), 0, mTreeView->model()->rowCount(QModelIndex()) - 1); } } private: void saveTreeState() { Akonadi::ETMViewStateSaver treeStateSaver; KConfigGroup group(KOGlobals::self()->config(), mTreeStateConfig); treeStateSaver.setView(mTreeView); treeStateSaver.setSelectionModel(0); // we only save expand state treeStateSaver.saveState(group); } void restoreTreeState() { if (mTreeStateConfig.isEmpty()) { return; } //Otherwise ETMViewStateSaver crashes if (!findEtm(mTreeView->model())) { return; } if ( treeStateRestorer ) {// We don't need more than one to be running at the same time delete treeStateRestorer; } kDebug() << "Restore tree state"; treeStateRestorer = new Akonadi::ETMViewStateSaver(); // not a leak KConfigGroup group( KOGlobals::self()->config(), mTreeStateConfig ); treeStateRestorer->setView( mTreeView ); treeStateRestorer->setSelectionModel( 0 ); // we only restore expand state treeStateRestorer->restoreState( group ); } QPointer treeStateRestorer; QTreeView *mTreeView; bool mExpandAll; QString mTreeStateConfig; }; AkonadiCollectionViewFactory::AkonadiCollectionViewFactory( CalendarView *view ) : mView( view ), mAkonadiCollectionView( 0 ) { } namespace { static bool hasCompatibleMimeTypes( const Akonadi::Collection &collection ) { static QStringList goodMimeTypes; if ( goodMimeTypes.isEmpty() ) { goodMimeTypes << QLatin1String( "text/calendar" ) << KCalCore::Event::eventMimeType() << KCalCore::Todo::todoMimeType() << KCalCore::Journal::journalMimeType(); } for ( int i=0; i() && !collection.attribute()->iconName().isEmpty() ) { return collection.attribute()->icon(); } } } else if ( role == Qt::FontRole ) { const Akonadi::Collection collection = CalendarSupport::collectionFromIndex( index ); if ( !collection.contentMimeTypes().isEmpty() && KOHelper::isStandardCalendar( collection.id() ) && collection.rights() & Akonadi::Collection::CanCreateItem ) { QFont font = qvariant_cast( QSortFilterProxyModel::data( index, Qt::FontRole ) ); font.setBold( true ); if ( !mInitDefaultCalendar ) { mInitDefaultCalendar = true; CalendarSupport::KCalPrefs::instance()->setDefaultCalendarId( collection.id() ); } return font; } } return QSortFilterProxyModel::data( index, role ); } /* reimp */ Qt::ItemFlags flags( const QModelIndex &index ) const { return Qt::ItemIsSelectable | QSortFilterProxyModel::flags( index ); } private: mutable bool mInitDefaultCalendar; }; class CollectionFilter : public QSortFilterProxyModel { public: explicit CollectionFilter( QObject *parent=0 ) : QSortFilterProxyModel( parent ) { setDynamicSortFilter(true); } protected: virtual bool filterAcceptsRow(int row, const QModelIndex &sourceParent) const { const QModelIndex sourceIndex = sourceModel()->index(row, 0, sourceParent); Q_ASSERT(sourceIndex.isValid()); const Akonadi::Collection &col = sourceIndex.data(Akonadi::EntityTreeModel::CollectionRole).value(); CollectionIdentificationAttribute *attr = col.attribute(); //We filter the user folders because we insert person nodes for user folders. if ( (attr && attr->collectionNamespace().startsWith("usertoplevel")) || col.name().contains(QLatin1String("Other Users"))) { return false; } return true; } }; class EnabledModel : public QSortFilterProxyModel { public: explicit EnabledModel(QObject *parent=0) : QSortFilterProxyModel(parent) { } protected: virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const { if (role == EnabledRole) { Akonadi::Collection col = index.data(Akonadi::EntityTreeModel::CollectionRole).value(); if (col.enabled()) { return Qt::Checked; } else { return Qt::Unchecked; } } return QSortFilterProxyModel::data(index, role); } }; class CalendarDelegateModel : public QSortFilterProxyModel { public: explicit CalendarDelegateModel(QObject *parent=0) : QSortFilterProxyModel(parent) { } protected: bool checkChildren(const QModelIndex &index, int role, const QVariant &value) const { const QModelIndex sourceIndex = mapToSource(index); for (int i = 0; i < sourceModel()->rowCount(sourceIndex); i++) { const QModelIndex child = sourceModel()->index(i, 0, sourceIndex); if (child.data(role) != value) { return false; } } return true; } virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const { if (role == Qt::CheckStateRole) { if (sourceModel()->hasChildren(mapToSource(index)) && index.data(NodeTypeRole).toInt() == PersonNodeRole) { bool allChecked = checkChildren(index, role, Qt::Checked); bool allUnchecked = checkChildren(index, role, Qt::Unchecked); if (allChecked) { return Qt::Checked; } else if (allUnchecked) { return Qt::Unchecked; } else { return Qt::PartiallyChecked; } } } if (role == EnabledRole) { if (sourceModel()->hasChildren(mapToSource(index)) && index.data(NodeTypeRole).toInt() == PersonNodeRole) { bool allChecked = checkChildren(index, role, Qt::Checked); bool allUnchecked = checkChildren(index, role, Qt::Unchecked); // kDebug() << "person node " << index.data().toString() << allChecked << allUnchecked; if (allChecked) { return Qt::Checked; } else if (allUnchecked) { return Qt::Unchecked; } else { return Qt::PartiallyChecked; } } } return QSortFilterProxyModel::data(index, role); } void setChildren(const QModelIndex &sourceIndex, const QVariant &value, int role) const { if (!sourceIndex.isValid()) { return; } for (int i = 0; i < sourceModel()->rowCount(sourceIndex); i++) { const QModelIndex child = sourceModel()->index(i, 0, sourceIndex); sourceModel()->setData(child, value, role); setChildren(child, value, role); } } virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) { if (role == Qt::CheckStateRole) { if (sourceModel()->hasChildren(mapToSource(index)) && index.data(NodeTypeRole).toInt() == PersonNodeRole) { setChildren(mapToSource(index), value, role); } } return QSortFilterProxyModel::setData(index, value, role); } }; } // anonymous namespace CalendarViewExtension *AkonadiCollectionViewFactory::create( QWidget *parent ) { mAkonadiCollectionView = new AkonadiCollectionView( view(), true, parent ); QObject::connect( mAkonadiCollectionView, SIGNAL(resourcesChanged(bool)), mView, SLOT(resourcesChanged()) ); QObject::connect( mAkonadiCollectionView, SIGNAL(resourcesAddedRemoved()), mView, SLOT(resourcesChanged()) ); return mAkonadiCollectionView; } CalendarView *AkonadiCollectionViewFactory::view() const { return mView; } AkonadiCollectionView *AkonadiCollectionViewFactory::collectionView() const { return mAkonadiCollectionView; } AkonadiCollectionView::AkonadiCollectionView( CalendarView *view, bool hasContextMenu, QWidget *parent ) : CalendarViewExtension( parent ), mActionManager(0), mCollectionView(0), mBaseModel( 0 ), mSelectionProxyModel( 0 ), mNotSendAddRemoveSignal( false ), mWasDefaultCalendar( false ), mHasContextMenu( hasContextMenu ), mSearchCol(0) { QVBoxLayout *topLayout = new QVBoxLayout( this ); topLayout->setMargin( 0 ); topLayout->setSpacing( KDialog::spacingHint() ); QHBoxLayout *searchLayout = new QHBoxLayout(this); mSearchCol = new KLineEdit(this); mSearchCol->setClearButtonShown(true); mSearchCol->setClickMessage( i18nc("@info/plain Displayed grayed-out inside the " "textbox, verb to search", "Search")); QPushButton *allButton = new QPushButton(this); allButton->setText(i18nc("@info/plain show all personal folders", "Show all")); connect(allButton, SIGNAL(clicked(bool)), this, SLOT(allButtonClicked(bool))); searchLayout->addWidget(mSearchCol); searchLayout->addWidget(allButton); topLayout->addLayout(searchLayout); ColorProxyModel *colorProxy = new ColorProxyModel( this ); colorProxy->setObjectName( QLatin1String("Show calendar colors") ); colorProxy->setDynamicSortFilter( true ); mBaseModel = colorProxy; //Model that displays users ReparentingModel *userProxy = new ReparentingModel( this ); userProxy->setNodeManager(ReparentingModel::NodeManager::Ptr(new PersonNodeManager(*userProxy))); userProxy->setSourceModel(colorProxy); EnabledModel *enabledModel = new EnabledModel(this); enabledModel->setSourceModel(userProxy); CalendarDelegateModel *calendarDelegateModel = new CalendarDelegateModel(this); calendarDelegateModel->setSourceModel(enabledModel); //Hide collections that are not required CollectionFilter *collectionFilter = new CollectionFilter( this ); collectionFilter->setSourceModel( calendarDelegateModel ); SortProxyModel *sortProxy = new SortProxyModel( this ); sortProxy->setSourceModel(collectionFilter); sortProxy->setObjectName(QLatin1String("sortproxy")); mCollectionView = new Akonadi::EntityTreeView( this ); mCollectionView->header()->hide(); mCollectionView->setRootIsDecorated( true ); // mCollectionView->setSorting( true ); { StyledCalendarDelegate *delegate = new StyledCalendarDelegate(mCollectionView); connect(delegate, SIGNAL(action(QModelIndex, int)), this, SLOT(onAction(QModelIndex, int))); mCollectionView->setItemDelegate( delegate ); } mCollectionView->setModel( sortProxy ); connect( mCollectionView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(updateMenu()) ); mNewNodeExpander = new NewNodeExpander(mCollectionView, false, QLatin1String("CollectionTreeView")); //Filter tree view. ReparentingModel *searchProxy = new ReparentingModel( this ); searchProxy->setSourceModel(collectionFilter); searchProxy->setObjectName(QLatin1String("searchProxy")); KRecursiveFilterProxyModel *filterTreeViewModel = new KRecursiveFilterProxyModel( this ); filterTreeViewModel->setDynamicSortFilter( true ); filterTreeViewModel->setSourceModel( searchProxy ); filterTreeViewModel->setFilterCaseSensitivity( Qt::CaseInsensitive ); // filterTreeViewModel->setObjectName( "Recursive filtering, for the search bar" ); connect(mSearchCol, SIGNAL(textChanged(QString)), filterTreeViewModel, SLOT(setFilterWildcard(QString))); SortProxyModel *searchSortProxy = new SortProxyModel( this ); searchSortProxy->setSourceModel(filterTreeViewModel); Akonadi::EntityTreeView *mSearchView = new Akonadi::EntityTreeView( this ); mSearchView->header()->hide(); mSearchView->setRootIsDecorated( true ); { StyledCalendarDelegate *delegate = new StyledCalendarDelegate(mCollectionView); connect(delegate, SIGNAL(action(QModelIndex, int)), this, SLOT(onAction(QModelIndex, int))); mSearchView->setItemDelegate( delegate ); } mSearchView->setModel( searchSortProxy ); new NewNodeExpander(mSearchView, true, QString()); mController = new Controller(userProxy, searchProxy, this); connect(mSearchCol, SIGNAL(textChanged(QString)), mController, SLOT(setSearchString(QString))); connect( mController, SIGNAL(searchIsActive(bool)), this, SLOT(onSearchIsActive(bool)) ); mStackedWidget = new QStackedWidget(this); mStackedWidget->addWidget(mCollectionView); mStackedWidget->addWidget(mSearchView); mStackedWidget->setCurrentWidget(mCollectionView); topLayout->addWidget( mStackedWidget ); KMessageWidget *msgWidget = new KMessageWidget(this); msgWidget->setCloseButtonVisible(false); msgWidget->setMessageType(KMessageWidget::Positive); msgWidget->setObjectName(QLatin1String("msgwidget")); msgWidget->setVisible(false); msgWidget->setText(i18n("searching...")); connect(mController, SIGNAL(searching(bool)), msgWidget, SLOT(setVisible(bool))); topLayout->addWidget(msgWidget); connect( mBaseModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(rowsInserted(QModelIndex,int,int)) ); KXMLGUIClient *xmlclient = KOCore::self()->xmlguiClient( view ); if ( xmlclient ) { mCollectionView->setXmlGuiClient( xmlclient ); mActionManager = new Akonadi::StandardCalendarActionManager( xmlclient->actionCollection(), mCollectionView ); QList standardActions; standardActions << Akonadi::StandardActionManager::CreateCollection << Akonadi::StandardActionManager::CopyCollections << Akonadi::StandardActionManager::DeleteCollections << Akonadi::StandardActionManager::SynchronizeCollections << Akonadi::StandardActionManager::CollectionProperties << Akonadi::StandardActionManager::CopyItems << Akonadi::StandardActionManager::Paste << Akonadi::StandardActionManager::DeleteItems << Akonadi::StandardActionManager::CutItems << Akonadi::StandardActionManager::CutCollections << Akonadi::StandardActionManager::CreateResource << Akonadi::StandardActionManager::DeleteResources << Akonadi::StandardActionManager::ResourceProperties << Akonadi::StandardActionManager::SynchronizeResources << Akonadi::StandardActionManager::SynchronizeCollectionTree << Akonadi::StandardActionManager::SynchronizeCollectionsRecursive; Q_FOREACH( Akonadi::StandardActionManager::Type standardAction, standardActions ) { mActionManager->createAction( standardAction ); } QList calendarActions; calendarActions << Akonadi::StandardCalendarActionManager::CreateEvent << Akonadi::StandardCalendarActionManager::CreateTodo << Akonadi::StandardCalendarActionManager::CreateSubTodo << Akonadi::StandardCalendarActionManager::CreateJournal << Akonadi::StandardCalendarActionManager::EditIncidence; Q_FOREACH( Akonadi::StandardCalendarActionManager::Type calendarAction, calendarActions ) { mActionManager->createAction( calendarAction ); } mActionManager->setCollectionSelectionModel( mCollectionView->selectionModel() ); mActionManager->interceptAction( Akonadi::StandardActionManager::CreateResource ); mActionManager->interceptAction( Akonadi::StandardActionManager::DeleteResources ); mActionManager->interceptAction( Akonadi::StandardActionManager::DeleteCollections ); connect( mActionManager->action( Akonadi::StandardActionManager::CreateResource ), SIGNAL(triggered(bool)), this, SLOT(newCalendar()) ); connect( mActionManager->action( Akonadi::StandardActionManager::DeleteResources ), SIGNAL(triggered(bool)), this, SLOT(deleteCalendar()) ); connect( mActionManager->action( Akonadi::StandardActionManager::DeleteCollections ), SIGNAL(triggered(bool)), this, SLOT(deleteCalendar()) ); mActionManager->setContextText( Akonadi::StandardActionManager::CollectionProperties, Akonadi::StandardActionManager::DialogTitle, ki18nc( "@title:window", "Properties of Calendar Folder %1" ) ); mActionManager->action( Akonadi::StandardActionManager::CreateCollection )->setProperty("ContentMimeTypes", QStringList() << Akonadi::Collection::mimeType() << KCalCore::Event::eventMimeType()); const QStringList pages = QStringList() << QLatin1String( "CalendarSupport::CollectionGeneralPage" ) << QLatin1String( "Akonadi::CachePolicyPage" ) << QLatin1String( "PimCommon::CollectionAclPage" ); mActionManager->setCollectionPropertiesPageNames( pages ); mDisableColor = new KAction( mCollectionView ); mDisableColor->setText( i18n( "&Disable Color" ) ); mDisableColor->setEnabled( false ); xmlclient->actionCollection()->addAction( QString::fromLatin1( "disable_color" ), mDisableColor ); connect( mDisableColor, SIGNAL(triggered(bool)), this, SLOT(disableColor()) ); mAssignColor = new KAction( mCollectionView ); mAssignColor->setText( i18n( "&Assign Color..." ) ); mAssignColor->setEnabled( false ); xmlclient->actionCollection()->addAction( QString::fromLatin1( "assign_color" ), mAssignColor ); connect( mAssignColor, SIGNAL(triggered(bool)), this, SLOT(assignColor()) ); mDefaultCalendar = new KAction( mCollectionView ); mDefaultCalendar->setText( i18n( "Use as &Default Calendar" ) ); mDefaultCalendar->setEnabled( false ); xmlclient->actionCollection()->addAction( QString::fromLatin1( "set_standard_calendar" ), mDefaultCalendar ); //Disable a calendar or remove a referenced calendar QAction *disableAction = xmlclient->actionCollection()->addAction( QLatin1String("collection_disable"), this, SLOT(edit_disable()) ); disableAction->setText( i18n( "Remove from list" ) ); disableAction->setIcon(KIconLoader().loadIcon(QLatin1String("list-remove"), KIconLoader::Small)); //Enable (subscribe) to a calendar. mEnableAction = xmlclient->actionCollection()->addAction( QLatin1String("collection_enable"), this, SLOT(edit_enable()) ); mEnableAction->setText( i18n( "Add to list permanently" ) ); mEnableAction->setIcon(KIconLoader().loadIcon(QLatin1String("bookmarks"), KIconLoader::Small)); connect( mDefaultCalendar, SIGNAL(triggered(bool)), this, SLOT(setDefaultCalendar()) ); + + connect(collectionFilter, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(calendarColorChanged(QModelIndex,QModelIndex))); } } AkonadiCollectionView::~AkonadiCollectionView() { //Necessary because it's apparently impossible to detect in the note expander when to save the state before view get's deleted mNewNodeExpander->saveState(); } void AkonadiCollectionView::allButtonClicked(bool) { mSearchCol->setText(QLatin1String("*")); } void AkonadiCollectionView::onSearchIsActive(bool active) { if (!active) { mStackedWidget->setCurrentIndex(0); } else { mStackedWidget->setCurrentIndex(1); } } void AkonadiCollectionView::setDefaultCalendar() { QModelIndex index = mCollectionView->selectionModel()->currentIndex(); //selectedRows() Q_ASSERT( index.isValid() ); const Akonadi::Collection collection = CalendarSupport::collectionFromIndex( index ); CalendarSupport::KCalPrefs::instance()->setDefaultCalendarId( collection.id() ); CalendarSupport::KCalPrefs::instance()->usrWriteConfig(); updateMenu(); updateView(); emit defaultResourceChanged( collection ); } void AkonadiCollectionView::assignColor() { - QModelIndex index = mCollectionView->selectionModel()->currentIndex(); //selectedRows() + const QModelIndex index = mCollectionView->selectionModel()->currentIndex(); //selectedRows() Q_ASSERT( index.isValid() ); - const Akonadi::Collection collection = CalendarSupport::collectionFromIndex( index ); + Akonadi::Collection collection = CalendarSupport::collectionFromIndex( index ); Q_ASSERT( collection.isValid() ); - const QString identifier = QString::number( collection.id() ); - const QColor defaultColor = KOPrefs::instance()->resourceColor( identifier ); + const QColor defaultColor = KOHelper::resourceColor(collection); QColor myColor; const int result = KColorDialog::getColor( myColor, defaultColor ); if ( result == KColorDialog::Accepted && myColor != defaultColor ) { - KOPrefs::instance()->setResourceColor( identifier, myColor ); - emit colorsChanged(); + KOHelper::setResourceColor(collection, myColor); + + mCollectionView->model()->setData(index, QVariant::fromValue(collection), Akonadi::EntityTreeModel::CollectionRole); updateMenu(); updateView(); } } +void AkonadiCollectionView::calendarColorChanged(const QModelIndex &topLeft, const QModelIndex &buttomRight) +{ + //We may want to have here a logic to detect only color changes + Q_UNUSED(topLeft); + Q_UNUSED(buttomRight); + Akonadi::Collection collection = CalendarSupport::collectionFromIndex(topLeft); + Q_ASSERT( collection.isValid() ); + emit colorsChanged(); +} + void AkonadiCollectionView::disableColor() { QModelIndex index = mCollectionView->selectionModel()->currentIndex(); //selectedRows() Q_ASSERT( index.isValid() ); - const Akonadi::Collection collection = CalendarSupport::collectionFromIndex( index ); + Akonadi::Collection collection = CalendarSupport::collectionFromIndex( index ); Q_ASSERT( collection.isValid() ); - const QString identifier = QString::number( collection.id() ); - KOPrefs::instance()->setResourceColor( identifier, QColor() ); + KOHelper::setResourceColor(collection, QColor()); + mCollectionView->model()->setData(index, QVariant::fromValue(collection), Akonadi::EntityTreeModel::CollectionRole); updateMenu(); updateView(); - emit colorsChanged(); } void AkonadiCollectionView::setCollectionSelectionProxyModel( KCheckableProxyModel *m ) { if ( mSelectionProxyModel == m ) { return; } mSelectionProxyModel = m; if ( !mSelectionProxyModel ) { return; } new NewCalendarChecker( m ); mBaseModel->setSourceModel( mSelectionProxyModel ); } KCheckableProxyModel *AkonadiCollectionView::collectionSelectionProxyModel() const { return mSelectionProxyModel; } Akonadi::EntityTreeView *AkonadiCollectionView::view() const { return mCollectionView; } void AkonadiCollectionView::updateView() { emit resourcesChanged( mSelectionProxyModel ? mSelectionProxyModel->selectionModel()->hasSelection() : false ); } void AkonadiCollectionView::updateMenu() { if ( !mHasContextMenu ) { return; } bool enableAction = mCollectionView->selectionModel()->hasSelection(); enableAction = enableAction && ( KOPrefs::instance()->agendaViewColors() != KOPrefs::CategoryOnly ); mAssignColor->setEnabled( enableAction ); QModelIndex index = mCollectionView->selectionModel()->currentIndex(); //selectedRows() bool disableStuff = true; if ( index.isValid() ) { //Returns an invalid collection on person nodes const Akonadi::Collection collection = CalendarSupport::collectionFromIndex( index ); if ( collection.isValid() && !collection.contentMimeTypes().isEmpty() ) { - const QString identifier = QString::number( collection.id() ); - const QColor defaultColor = KOPrefs::instance()->resourceColor( identifier ); + const QColor defaultColor = KOHelper::resourceColor(collection); enableAction = enableAction && defaultColor.isValid(); mDisableColor->setEnabled( enableAction ); mDefaultCalendar->setEnabled( !KOHelper::isStandardCalendar( collection.id() ) && collection.rights() & Akonadi::Collection::CanCreateItem ); disableStuff = false; } if ( collection.isValid() && collection.shouldList(Akonadi::Collection::ListDisplay) ) { mEnableAction->setEnabled(false); } else { mEnableAction->setEnabled(true); } } if ( disableStuff ) { mDisableColor->setEnabled( false ); mDefaultCalendar->setEnabled( false ); mAssignColor->setEnabled( false ); } } void AkonadiCollectionView::newCalendar() { Akonadi::AgentTypeDialog dlg( this ); dlg.setWindowTitle( i18n( "Add Calendar" ) ); dlg.agentFilterProxyModel()->addMimeTypeFilter( QString::fromLatin1( "text/calendar" ) ); dlg.agentFilterProxyModel()->addCapabilityFilter( QLatin1String("Resource") ); // show only resources, no agents if ( dlg.exec() ) { mNotSendAddRemoveSignal = true; const Akonadi::AgentType agentType = dlg.agentType(); if ( agentType.isValid() ) { Akonadi::AgentInstanceCreateJob *job = new Akonadi::AgentInstanceCreateJob( agentType, this ); job->configure( this ); connect( job, SIGNAL(result(KJob*)), this, SLOT(newCalendarDone(KJob*)) ); job->start(); } } } void AkonadiCollectionView::newCalendarDone( KJob *job ) { Akonadi::AgentInstanceCreateJob *createjob = static_cast( job ); if ( createjob->error() ) { //TODO(AKONADI_PORT) // this should show an error dialog and should be merged // with the identical code in ActionManager kWarning() << "Create calendar failed:" << createjob->errorString(); mNotSendAddRemoveSignal = false; return; } mNotSendAddRemoveSignal = false; //TODO } void AkonadiCollectionView::deleteCalendar() { QModelIndex index = mCollectionView->selectionModel()->currentIndex(); //selectedRows() Q_ASSERT( index.isValid() ); const Akonadi::Collection collection = CalendarSupport::collectionFromIndex( index ); Q_ASSERT( collection.isValid() ); const QString displayname = index.model()->data( index, Qt::DisplayRole ).toString(); Q_ASSERT( !displayname.isEmpty() ); if ( KMessageBox::warningContinueCancel( this, i18n( "Do you really want to delete calendar %1?", displayname ), i18n( "Delete Calendar" ), KStandardGuiItem::del(), KStandardGuiItem::cancel(), QString(), KMessageBox::Dangerous ) == KMessageBox::Continue ) { bool isTopLevel = collection.parentCollection() == Akonadi::Collection::root(); mNotSendAddRemoveSignal = true; mWasDefaultCalendar = KOHelper::isStandardCalendar( collection.id() ); if ( !isTopLevel ) { // deletes contents Akonadi::CollectionDeleteJob *job = new Akonadi::CollectionDeleteJob( collection, this ); connect( job, SIGNAL(result(KJob*)), this, SLOT(deleteCalendarDone(KJob*)) ); } else { // deletes the agent, not the contents const Akonadi::AgentInstance instance = Akonadi::AgentManager::self()->instance( collection.resource() ); if ( instance.isValid() ) { Akonadi::AgentManager::self()->removeInstance( instance ); } } } } void AkonadiCollectionView::deleteCalendarDone( KJob *job ) { Akonadi::CollectionDeleteJob *deletejob = static_cast( job ); if ( deletejob->error() ) { kWarning() << "Delete calendar failed:" << deletejob->errorString(); mNotSendAddRemoveSignal = false; return; } if ( mWasDefaultCalendar ) { CalendarSupport::KCalPrefs::instance()->setDefaultCalendarId( Akonadi::Collection().id() ); } mNotSendAddRemoveSignal = false; //TODO } void AkonadiCollectionView::rowsInserted( const QModelIndex &, int, int ) { if ( !mNotSendAddRemoveSignal ) { emit resourcesAddedRemoved(); } } Akonadi::Collection AkonadiCollectionView::selectedCollection() const { Akonadi::Collection collection; QItemSelectionModel *selectionModel = mCollectionView->selectionModel(); if ( !selectionModel ) { return collection; } QModelIndexList indexes = selectionModel->selectedIndexes(); if ( !indexes.isEmpty() ) { collection = indexes.first().data( Akonadi::EntityTreeModel::CollectionRole ).value(); } return collection; } Akonadi::Collection::List AkonadiCollectionView::checkedCollections() const { Akonadi::Collection::List collections; if ( !mSelectionProxyModel ) { return collections; } QItemSelectionModel *selectionModel = mSelectionProxyModel->selectionModel(); if ( !selectionModel ) { return collections; } QModelIndexList indexes = selectionModel->selectedIndexes(); foreach( const QModelIndex &index, indexes ) { if ( index.isValid() ) { Akonadi::Collection collection = index.data( Akonadi::EntityTreeModel::CollectionRole ).value(); if ( collection.isValid() ) collections << collection; } } return collections; } bool AkonadiCollectionView::isChecked(const Akonadi::Collection &collection) const { if (!mSelectionProxyModel) return false; QItemSelectionModel *selectionModel = mSelectionProxyModel->selectionModel(); if (!selectionModel) return false; QModelIndexList indexes = selectionModel->selectedIndexes(); foreach(const QModelIndex &index, indexes) { if (index.isValid()) { Akonadi::Collection c = index.data(Akonadi::EntityTreeModel::CollectionRole).value(); if (c.id() == collection.id()) { return true; } } } return false; } Akonadi::EntityTreeModel *AkonadiCollectionView::entityTreeModel() const { QAbstractProxyModel *proxy = qobject_cast( mCollectionView->model() ); while( proxy ) { Akonadi::EntityTreeModel *etm = qobject_cast( proxy->sourceModel() ); if ( etm ) { return etm; } proxy = qobject_cast( proxy->sourceModel() ); } kWarning() << "Couldn't find EntityTreeModel"; return 0; } void AkonadiCollectionView::edit_disable() { Akonadi::Collection col = mCollectionView->currentIndex().data(Akonadi::EntityTreeModel::CollectionRole).value(); if (col.isValid()) { mController->setCollectionState(col, Controller::Disabled); } const QVariant var = mCollectionView->currentIndex().data(PersonRole); if (var.isValid()) { mController->removePerson(var.value()); } } void AkonadiCollectionView::edit_enable() { Akonadi::Collection col = mCollectionView->currentIndex().data(Akonadi::EntityTreeModel::CollectionRole).value(); kDebug() << col.name(); if (col.isValid()) { mController->setCollectionState(col, Controller::Enabled); } const QVariant var = mCollectionView->currentIndex().data(PersonRole); if (var.isValid()) { mController->addPerson(var.value()); } } void AkonadiCollectionView::onAction(const QModelIndex &index, int a) { const StyledCalendarDelegate::Action action = static_cast(a); switch (action) { case StyledCalendarDelegate::AddToList: { const QVariant var = index.data(PersonRole); if (var.isValid()) { mController->addPerson(var.value()); } else { const Akonadi::Collection col = CalendarSupport::collectionFromIndex(index); if (col.isValid()) { mController->setCollectionState(col, Controller::Referenced); } } } break; case StyledCalendarDelegate::RemoveFromList: { const QVariant var = index.data(PersonRole); if (var.isValid()) { mController->removePerson(var.value()); } else { const Akonadi::Collection col = CalendarSupport::collectionFromIndex(index); if (col.isValid()) { mController->setCollectionState(col, Controller::Disabled); } } } break; case StyledCalendarDelegate::Enable: { const QVariant var = index.data(PersonRole); if (var.isValid()) { mController->setCollectionState(Akonadi::Collection(var.value().rootCollection), Controller::Enabled, true); } else { const Akonadi::Collection col = CalendarSupport::collectionFromIndex(index); if (col.isValid()) { mController->setCollectionState(col, Controller::Enabled); } } } break; case StyledCalendarDelegate::Quickview: { QVariant person = index.data(PersonRole); QModelIndex i = index; while (!person.isValid()) { i = i.parent(); if (!i.isValid()) { break; } person = i.data(PersonRole); } if (person.isValid()) { Quickview *quickview = new Quickview(person.value(), CalendarSupport::collectionFromIndex(index)); quickview->setAttribute(Qt::WA_DeleteOnClose, true); quickview->show(); } else { kWarning() << "No valid person found for" << index; Quickview *quickview = new Quickview(Person(), CalendarSupport::collectionFromIndex(index)); quickview->setAttribute(Qt::WA_DeleteOnClose, true); quickview->show(); } } break; } } #include "akonadicollectionview.moc" diff --git a/korganizer/akonadicollectionview.h b/korganizer/akonadicollectionview.h index 3680c8e738..4862556290 100644 --- a/korganizer/akonadicollectionview.h +++ b/korganizer/akonadicollectionview.h @@ -1,137 +1,138 @@ /* This file is part of KOrganizer. Copyright (c) 2003,2004 Cornelius Schumacher Copyright (C) 2003-2004 Reinhold Kainhofer Copyright (C) 2009 Sebastian Sauer 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 (at your option) 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #ifndef KORG_AKONADICOLLECTIONVIEW_H #define KORG_AKONADICOLLECTIONVIEW_H #include "calendarview.h" #include "views/collectionview/reparentingmodel.h" #include "views/collectionview/controller.h" #include #include class AkonadiCollectionView; namespace Akonadi { class EntityTreeView; class EntityTreeModel; class StandardCalendarActionManager; } class KAction; class KJob; class KLineEdit; class QAbstractProxyModel; class QModelIndex; /** * The factory for AkonadiCollectionView instances. */ class AkonadiCollectionViewFactory : public CalendarViewExtension::Factory { public: explicit AkonadiCollectionViewFactory( CalendarView *view ); CalendarView *view() const; AkonadiCollectionView *collectionView() const; CalendarViewExtension *create( QWidget * ); private: CalendarView *mView; AkonadiCollectionView *mAkonadiCollectionView; }; class NewNodeExpander; /** * This class provides a view of calendar resources. */ class AkonadiCollectionView : public CalendarViewExtension { Q_OBJECT public: explicit AkonadiCollectionView( CalendarView *view, bool hasContextMenu = true, QWidget *parent = 0 ); ~AkonadiCollectionView(); Akonadi::EntityTreeView *view() const; KCheckableProxyModel *collectionSelectionProxyModel() const; void setCollectionSelectionProxyModel( KCheckableProxyModel * ); Akonadi::Collection selectedCollection() const; Akonadi::Collection::List checkedCollections() const; bool isChecked(const Akonadi::Collection &) const; public Q_SLOTS: void edit_disable(); void edit_enable(); Q_SIGNALS: void resourcesChanged( bool enabled ); void resourcesAddedRemoved(); void defaultResourceChanged( const Akonadi::Collection & ); void colorsChanged(); private Q_SLOTS: void updateView(); void updateMenu(); void newCalendar(); void newCalendarDone( KJob * ); void deleteCalendar(); void deleteCalendarDone( KJob * ); void rowsInserted( const QModelIndex &, int, int ); void assignColor(); void disableColor(); void setDefaultCalendar(); void onSearchIsActive(bool); void onAction(const QModelIndex &index, int action); void allButtonClicked(bool); + void calendarColorChanged(const QModelIndex &topleft, const QModelIndex &buttomDown); private: Akonadi::EntityTreeModel *entityTreeModel() const; Akonadi::StandardCalendarActionManager *mActionManager; Akonadi::EntityTreeView *mCollectionView; QStackedWidget *mStackedWidget; QAbstractProxyModel *mBaseModel; KCheckableProxyModel *mSelectionProxyModel; KAction *mAssignColor; KAction *mDisableColor; KAction *mDefaultCalendar; QAction *mEnableAction; bool mNotSendAddRemoveSignal; bool mWasDefaultCalendar; bool mHasContextMenu; Controller *mController; NewNodeExpander *mNewNodeExpander; KLineEdit *mSearchCol; }; #endif diff --git a/korganizer/kohelper.cpp b/korganizer/kohelper.cpp index c114dfa55e..699aaea640 100644 --- a/korganizer/kohelper.cpp +++ b/korganizer/kohelper.cpp @@ -1,95 +1,100 @@ /* This file is part of KOrganizer. Copyright (C) 2005 Reinhold Kainhofer 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 (at your option) 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include "kohelper.h" #include "koprefs.h" #include +#include #include QColor KOHelper::getTextColor( const QColor &c ) { double luminance = ( c.red() * 0.299 ) + ( c.green() * 0.587 ) + ( c.blue() * 0.114 ); return ( luminance > 128.0 ) ? QColor( 0, 0, 0 ) : QColor( 255, 255, 255 ); } QColor KOHelper::resourceColor( const Akonadi::Collection &coll ) { if ( !coll.isValid() ) { return QColor(); } + Akonadi::CollectionColorAttribute *colorAttribute = coll.attribute(); + if (colorAttribute) { + return colorAttribute->color(); + } + const QString id = QString::number( coll.id() ); return KOPrefs::instance()->resourceColor( id ); } QColor KOHelper::resourceColorKnown( const Akonadi::Collection &coll ) { if ( !coll.isValid() ) { return QColor(); } - const QString id = QString::number( coll.id() ); - return KOPrefs::instance()->resourceColorKnown( id ); + Akonadi::CollectionColorAttribute *colorAttribute = coll.attribute(); + if (colorAttribute) { + return colorAttribute->color(); + } } -void KOHelper::setResourceColor(const Akonadi::Collection &collection, const QColor &color) +void KOHelper::setResourceColor(Akonadi::Collection &collection, const QColor &color) { if ( collection.isValid() ) { - const QString id = QString::number( collection.id() ); - return KOPrefs::instance()->setResourceColor(id, color); + collection.attribute(Akonadi::Collection::AddIfMissing)->setColor(color); } } - QColor KOHelper::resourceColor( const Akonadi::Item &item ) { if ( !item.isValid() ) { return QColor(); } - const QString id = QString::number( item.storageCollectionId() ); - return KOPrefs::instance()->resourceColor( id ); + return resourceColor(item.parentCollection()); } int KOHelper::yearDiff( const QDate &start, const QDate &end ) { return end.year() - start.year(); } bool KOHelper::isStandardCalendar( const Akonadi::Entity::Id &id ) { return id == CalendarSupport::KCalPrefs::instance()->defaultCalendarId(); } void KOHelper::showSaveIncidenceErrorMsg( QWidget *parent, const KCalCore::Incidence::Ptr &incidence ) { KMessageBox::sorry( parent, i18n( "Unable to save %1 \"%2\".", i18n( incidence->typeStr() ), incidence->summary() ) ); } diff --git a/korganizer/kohelper.h b/korganizer/kohelper.h index 4e8c559a41..c86f874d18 100644 --- a/korganizer/kohelper.h +++ b/korganizer/kohelper.h @@ -1,79 +1,79 @@ /* This file is part of KOrganizer. Copyright (C) 2005 Reinhold Kainhofer 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 (at your option) 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #ifndef KORG_KOHELPER_H #define KORG_KOHELPER_H #include "korganizer_export.h" #include #include namespace Akonadi { class Collection; class Item; } class QColor; class QDate; // Provides static methods that are useful to all views. namespace KOHelper { /** Returns a nice QColor for text, give the input color &c. */ KORGANIZERPRIVATE_EXPORT QColor getTextColor( const QColor &c ); /** This method returns the proper resource / subresource color for the view. @return The resource color for the incidence. If the incidence belongs to a subresource, the color for the subresource is returned (if set). @param calendar the calendar for which the resource color should be obtained @param incidence the incidence for which the color is needed (to determine which subresource needs to be used) */ KORGANIZERPRIVATE_EXPORT QColor resourceColor( const Akonadi::Item &incidence ); KORGANIZERPRIVATE_EXPORT QColor resourceColor( const Akonadi::Collection &collection ); KORGANIZERPRIVATE_EXPORT QColor resourceColorKnown( const Akonadi::Collection &collection ); - KORGANIZERPRIVATE_EXPORT void setResourceColor( const Akonadi::Collection &collection, const QColor &color ); + KORGANIZERPRIVATE_EXPORT void setResourceColor( Akonadi::Collection &collection, const QColor &color ); /** Returns the number of years between the @p start QDate and the @p end QDate (i.e. the difference in the year number of both dates) */ KORGANIZERPRIVATE_EXPORT int yearDiff( const QDate &start, const QDate &end ); /** Return true if it's the standard calendar */ KORGANIZERPRIVATE_EXPORT bool isStandardCalendar( const Akonadi::Entity::Id &id ); KORGANIZERPRIVATE_EXPORT void showSaveIncidenceErrorMsg( QWidget *parent, const KCalCore::Incidence::Ptr &incidence ); } #endif diff --git a/korganizer/koprefsdialog.cpp b/korganizer/koprefsdialog.cpp index 06bb6cc51b..7796642024 100644 --- a/korganizer/koprefsdialog.cpp +++ b/korganizer/koprefsdialog.cpp @@ -1,1587 +1,1590 @@ /* This file is part of KOrganizer. Copyright (c) 2000-2003 Cornelius Schumacher Copyright (C) 2003-2004 Reinhold Kainhofer 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 (at your option) 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include "koprefsdialog.h" #include "kitemiconcheckcombo.h" #include "kocore.h" #include "koglobals.h" +#include "kohelper.h" #include "koprefs.h" #include "ui_kogroupwareprefspage.h" #include #include +#include #include #include #include #include #include #include #include #include #include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include KOPrefsDialogMain::KOPrefsDialogMain( const KComponentData &inst, QWidget *parent ) : KPrefsModule( KOPrefs::instance(), inst, parent ) { QBoxLayout *topTopLayout = new QVBoxLayout( this ); KTabWidget *tabWidget = new KTabWidget( this ); topTopLayout->addWidget( tabWidget ); // Personal Settings QWidget *personalFrame = new QWidget( this ); QVBoxLayout *personalLayout = new QVBoxLayout( personalFrame ); tabWidget->addTab( personalFrame, KIcon( QLatin1String("preferences-desktop-personal") ), i18nc( "@title:tab personal settings", "Personal" ) ); KPIM::KPrefsWidBool *emailControlCenter = addWidBool( CalendarSupport::KCalPrefs::instance()->emailControlCenterItem(), personalFrame ); connect( emailControlCenter->checkBox(), SIGNAL(toggled(bool)), SLOT(toggleEmailSettings(bool)) ); personalLayout->addWidget( emailControlCenter->checkBox() ); mUserEmailSettings = new QGroupBox( i18nc( "@title:group email settings", "Email Settings" ), personalFrame ); personalLayout->addWidget( mUserEmailSettings ); QFormLayout *emailSettingsLayout = new QFormLayout( mUserEmailSettings ); KPIM::KPrefsWidString *s = addWidString( CalendarSupport::KCalPrefs::instance()->userNameItem(), mUserEmailSettings ); emailSettingsLayout->addRow ( s->label(), s->lineEdit() ); s=addWidString( CalendarSupport::KCalPrefs::instance()->userEmailItem(), mUserEmailSettings ); emailSettingsLayout->addRow ( s->label(), s->lineEdit() ); KPIM::KPrefsWidRadios *defaultEmailAttachMethod = addWidRadios( IncidenceEditorNG::GlobalSettings::self()->defaultEmailAttachMethodItem(), personalFrame ); personalLayout->addWidget( defaultEmailAttachMethod->groupBox() ); personalLayout->addStretch( 1 ); // Save Settings QFrame *saveFrame = new QFrame( this ); tabWidget->addTab( saveFrame, KIcon( QLatin1String("document-save") ), i18nc( "@title:tab", "Save" ) ); QVBoxLayout *saveLayout = new QVBoxLayout( saveFrame ); QGroupBox *saveGroupBox = new QGroupBox( i18nc( "@title:group", "Exporting Calendar" ), saveFrame ); saveLayout->addWidget( saveGroupBox ); QVBoxLayout *saveGroupLayout = new QVBoxLayout; saveGroupBox->setLayout( saveGroupLayout ); KPIM::KPrefsWidBool *autoExportHTML = addWidBool( KOPrefs::instance()->autoExportItem(), saveGroupBox ); saveGroupLayout->addWidget( autoExportHTML->checkBox() ); QBoxLayout *intervalLayout = new QHBoxLayout; saveGroupLayout->addLayout( intervalLayout ); KPIM::KPrefsWidInt *autoExportInterval = addWidInt( KOPrefs::instance()->autoExportIntervalItem(), saveGroupBox ); connect( autoExportHTML->checkBox(), SIGNAL(toggled(bool)), autoExportInterval->label(), SLOT(setEnabled(bool)) ); connect( autoExportHTML->checkBox(), SIGNAL(toggled(bool)), autoExportInterval->spinBox(), SLOT(setEnabled(bool)) ); intervalLayout->addWidget( autoExportInterval->label() ); intervalLayout->addWidget( autoExportInterval->spinBox() ); KPIM::KPrefsWidBool *confirmItem = addWidBool( KOPrefs::instance()->confirmItem(), saveFrame ); saveLayout->addWidget( confirmItem->checkBox() ); KPIM::KPrefsWidRadios *destinationItem = addWidRadios( KOPrefs::instance()->destinationItem(), saveFrame ); saveLayout->addWidget( destinationItem->groupBox() ); saveLayout->addStretch( 1 ); // System Tray Settings QFrame *systrayFrame = new QFrame( this ); QVBoxLayout *systrayLayout = new QVBoxLayout( systrayFrame ); tabWidget->addTab( systrayFrame, KIcon( QLatin1String("preferences-other") ), i18nc( "@title:tab systray settings", "System Tray" ) ); QGroupBox *systrayGroupBox = new QGroupBox( i18nc( "@title:group", "Show/Hide Options" ), systrayFrame ); systrayLayout->addWidget( systrayGroupBox ); QVBoxLayout *systrayGroupLayout = new QVBoxLayout; systrayGroupBox->setLayout( systrayGroupLayout ); KPIM::KPrefsWidBool *showReminderDaemonItem = addWidBool( KOPrefs::instance()->showReminderDaemonItem(), systrayGroupBox ); systrayGroupLayout->addWidget( showReminderDaemonItem->checkBox() ); showReminderDaemonItem->checkBox()->setToolTip( i18nc( "@info:tooltip", "Enable this setting to show the KOrganizer " "reminder daemon in your system tray (recommended)." ) ); QLabel *note = new QLabel( i18nc( "@info", "The daemon will continue running even if it is not shown " "in the system tray." ) ); systrayGroupLayout->addWidget( note ); systrayLayout->addStretch( 1 ); //Calendar Account QFrame *calendarFrame = new QFrame( this ); tabWidget->addTab( calendarFrame, KIcon( QLatin1String("office-calendar") ), i18nc( "@title:tab calendar account settings", "Calendars" ) ); mAccountsCalendar.setupUi( calendarFrame ); mAccountsCalendar.vlay->setSpacing( KDialog::spacingHint() ); mAccountsCalendar.vlay->setMargin( KDialog::marginHint() ); mAccountsCalendar.mAccountList->agentFilterProxyModel()-> addMimeTypeFilter( QLatin1String("text/calendar") ); mAccountsCalendar.mAccountList->agentFilterProxyModel()-> addCapabilityFilter( QLatin1String("Resource") ); // show only resources, no agents mAccountsCalendar.mFilterAccount-> setProxy( mAccountsCalendar.mAccountList->agentFilterProxyModel() ); connect( mAccountsCalendar.mAccountList->view()->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(slotAccountSelected())); connect( mAccountsCalendar.mAccountList, SIGNAL(doubleClicked(Akonadi::AgentInstance)), this, SLOT(slotModifySelectedAccount()) ); mAccountsCalendar.hlay->insertWidget( 0, mAccountsCalendar.mAccountList ); connect( mAccountsCalendar.mAddAccountButton, SIGNAL(clicked()), this, SLOT(slotAddAccount()) ); connect( mAccountsCalendar.mModifyAccountButton, SIGNAL(clicked()), this, SLOT(slotModifySelectedAccount()) ); const bool hasSelection = !mAccountsCalendar.mAccountList->selectedAgentInstances().isEmpty(); mAccountsCalendar.mModifyAccountButton->setEnabled( hasSelection ); mAccountsCalendar.mRemoveAccountButton->setEnabled( hasSelection ); connect( mAccountsCalendar.mRemoveAccountButton, SIGNAL(clicked()), this, SLOT(slotRemoveSelectedAccount()) ); load(); } void KOPrefsDialogMain::slotAccountSelected() { if ( mAccountsCalendar.mAccountList->selectedAgentInstances().isEmpty() ) { mAccountsCalendar.mModifyAccountButton->setEnabled( false ); mAccountsCalendar.mRemoveAccountButton->setEnabled( false ); } else { Akonadi::AgentInstance selectedAgent = mAccountsCalendar.mAccountList->selectedAgentInstances().first(); mAccountsCalendar.mModifyAccountButton->setEnabled( !selectedAgent.type().capabilities().contains( QLatin1String( "NoConfig" ) ) ); mAccountsCalendar.mRemoveAccountButton->setEnabled( true ); } } void KOPrefsDialogMain::slotAddAccount() { //TODO verify this dialog box. We can see note etc... Akonadi::AgentTypeDialog dlg( this ); Akonadi::AgentFilterProxyModel *filter = dlg.agentFilterProxyModel(); filter->addMimeTypeFilter( QLatin1String("text/calendar") ); filter->addCapabilityFilter( QLatin1String("Resource") ); if ( dlg.exec() ) { const Akonadi::AgentType agentType = dlg.agentType(); if ( agentType.isValid() ) { Akonadi::AgentInstanceCreateJob *job = new Akonadi::AgentInstanceCreateJob( agentType, this ); job->configure( this ); job->start(); } } } void KOPrefsDialogMain::slotModifySelectedAccount() { Akonadi::AgentInstance instance = mAccountsCalendar.mAccountList->currentAgentInstance(); if ( instance.isValid() ) { KWindowSystem::allowExternalProcessWindowActivation(); instance.configure( this ); } } void KOPrefsDialogMain::slotRemoveSelectedAccount() { const Akonadi::AgentInstance instance = mAccountsCalendar.mAccountList->currentAgentInstance(); if ( instance.isValid() ) { Akonadi::AgentManager::self()->removeInstance( instance ); } slotAccountSelected(); } void KOPrefsDialogMain::toggleEmailSettings( bool on ) { mUserEmailSettings->setEnabled( !on ); /* if (on) { KEMailSettings settings; mNameEdit->setText( settings.getSetting(KEMailSettings::RealName) ); mEmailEdit->setText( settings.getSetting(KEMailSettings::EmailAddress) ); } else { mNameEdit->setText( CalendarSupport::KCalPrefs::instance()->mName ); mEmailEdit->setText( CalendarSupport::KCalPrefs::instance()->mEmail ); }*/ } extern "C" { KDE_EXPORT KCModule *create_korganizerconfigmain( QWidget *parent, const char * ) { return new KOPrefsDialogMain( KOGlobals::self()->componentData(), parent ); } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// class KOPrefsDialogTime : public KPIM::KPrefsModule { public: KOPrefsDialogTime( const KComponentData &inst, QWidget *parent ) : KPIM::KPrefsModule( KOPrefs::instance(), inst, parent ) { QVBoxLayout *layout = new QVBoxLayout( this ); KTabWidget *tabWidget = new KTabWidget( this ); layout->addWidget( tabWidget ); QFrame *regionalPage = new QFrame( parent ); tabWidget->addTab( regionalPage, KIcon( QLatin1String("flag") ), i18nc( "@title:tab", "Regional" ) ); QGridLayout *regionalLayout = new QGridLayout( regionalPage ); regionalLayout->setSpacing( KDialog::spacingHint() ); QGroupBox *datetimeGroupBox = new QGroupBox( i18nc( "@title:group", "General Time and Date" ), regionalPage ); regionalLayout->addWidget( datetimeGroupBox, 0, 0 ); QGridLayout *datetimeLayout = new QGridLayout( datetimeGroupBox ); KPIM::KPrefsWidTime *dayBegins = addWidTime( KOPrefs::instance()->dayBeginsItem(), regionalPage ); datetimeLayout->addWidget( dayBegins->label(), 1, 0 ); datetimeLayout->addWidget( dayBegins->timeEdit(), 1, 1 ); QGroupBox *holidaysGroupBox = new QGroupBox( i18nc( "@title:group", "Holidays" ), regionalPage ); regionalLayout->addWidget( holidaysGroupBox, 1, 0 ); QGridLayout *holidaysLayout = new QGridLayout( holidaysGroupBox ); // holiday region selection KHBox *holidayRegBox = new KHBox( regionalPage ); holidaysLayout->addWidget( holidayRegBox, 1, 0, 1, 2 ); QLabel *holidayLabel = new QLabel( i18nc( "@label", "Use holiday region:" ), holidayRegBox ); holidayLabel->setWhatsThis( KOPrefs::instance()->holidaysItem()->whatsThis() ); mHolidayCombo = new KComboBox( holidayRegBox ); connect( mHolidayCombo, SIGNAL(activated(int)), SLOT(slotWidChanged()) ); mHolidayCombo->setWhatsThis( KOPrefs::instance()->holidaysItem()->whatsThis() ); QStringList regions = KHolidays::HolidayRegion::regionCodes(); QMap regionsMap; foreach ( const QString & regionCode, regions ) { QString name = KHolidays::HolidayRegion::name( regionCode ); QString languageName = KGlobal::locale()->languageCodeToName( KHolidays::HolidayRegion::languageCode( regionCode ) ); QString label; if ( languageName.isEmpty() ) { label = name; } else { label = i18nc( "Holday region, region language", "%1 (%2)", name, languageName ); } regionsMap.insert( label, regionCode ); } mHolidayCombo->addItem( i18nc( "No holiday region", "None" ), QString() ); QMapIterator i( regionsMap ); while ( i.hasNext() ) { i.next(); mHolidayCombo->addItem( i.key(), i.value() ); } if ( KOGlobals::self()->holidays() && KOGlobals::self()->holidays()->isValid() ) { mHolidayCombo->setCurrentIndex( mHolidayCombo->findData( KOGlobals::self()->holidays()->regionCode() ) ); } else { mHolidayCombo->setCurrentIndex( 0 ); } QGroupBox *workingHoursGroupBox = new QGroupBox( i18nc( "@title:group", "Working Period" ), regionalPage ); regionalLayout->addWidget( workingHoursGroupBox, 2, 0 ); QBoxLayout *workingHoursLayout = new QVBoxLayout( workingHoursGroupBox ); QBoxLayout *workDaysLayout = new QHBoxLayout; workingHoursLayout->addLayout( workDaysLayout ); // Respect start of week setting int weekStart = KGlobal::locale()->weekStartDay(); for ( int i=0; i < 7; ++i ) { const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem(); QString weekDayName = calSys->weekDayName( ( i + weekStart + 6 ) % 7 + 1, KCalendarSystem::ShortDayName ); int index = ( i + weekStart + 6 ) % 7; mWorkDays[ index ] = new QCheckBox( weekDayName ); mWorkDays[ index ]->setWhatsThis( i18nc( "@info:whatsthis", "Check this box to make KOrganizer mark the " "working hours for this day of the week. " "If this is a work day for you, check " "this box, or the working hours will not be " "marked with color." ) ); connect( mWorkDays[ index ], SIGNAL(stateChanged(int)), SLOT(slotWidChanged()) ); workDaysLayout->addWidget( mWorkDays[ index ] ); } KPIM::KPrefsWidTime *workStart = addWidTime( KOPrefs::instance()->workingHoursStartItem() ); QHBoxLayout *workStartLayout = new QHBoxLayout; workingHoursLayout->addLayout( workStartLayout ); workStartLayout->addWidget( workStart->label() ); workStartLayout->addWidget( workStart->timeEdit() ); KPIM::KPrefsWidTime *workEnd = addWidTime( KOPrefs::instance()->workingHoursEndItem() ); QHBoxLayout *workEndLayout = new QHBoxLayout; workingHoursLayout->addLayout( workEndLayout ); workEndLayout->addWidget( workEnd->label() ); workEndLayout->addWidget( workEnd->timeEdit() ); KPIM::KPrefsWidBool *excludeHolidays = addWidBool( KOPrefs::instance()->excludeHolidaysItem() ); workingHoursLayout->addWidget( excludeHolidays->checkBox() ); regionalLayout->setRowStretch( 4, 1 ); QFrame *defaultPage = new QFrame( parent ); tabWidget->addTab( defaultPage, KIcon( QLatin1String("draw-eraser") ), i18nc( "@title:tab", "Default Values" ) ); QGridLayout *defaultLayout = new QGridLayout( defaultPage ); defaultLayout->setSpacing( KDialog::spacingHint() ); QGroupBox *timesGroupBox = new QGroupBox( i18nc( "@title:group", "Appointments" ), defaultPage ); defaultLayout->addWidget( timesGroupBox, 0, 0 ); QGridLayout *timesLayout = new QGridLayout( timesGroupBox ); KPIM::KPrefsWidTime *defaultTime = addWidTime( CalendarSupport::KCalPrefs::instance()->startTimeItem(), defaultPage ); timesLayout->addWidget( defaultTime->label(), 0, 0 ); timesLayout->addWidget( defaultTime->timeEdit(), 0, 1 ); KPIM::KPrefsWidDuration *defaultDuration = addWidDuration( CalendarSupport::KCalPrefs::instance()->defaultDurationItem(), QLatin1String("hh:mm"), defaultPage ); timesLayout->addWidget( defaultDuration->label(), 1, 0 ); timesLayout->addWidget( defaultDuration->timeEdit(), 1, 1 ); QGroupBox *remindersGroupBox = new QGroupBox( i18nc( "@title:group", "Reminders" ), defaultPage ); defaultLayout->addWidget( remindersGroupBox, 1, 0 ); QGridLayout *remindersLayout = new QGridLayout( remindersGroupBox ); QLabel *reminderLabel = new QLabel( i18nc( "@label", "Default reminder time:" ), defaultPage ); remindersLayout->addWidget( reminderLabel, 0, 0 ); reminderLabel->setWhatsThis( CalendarSupport::KCalPrefs::instance()->reminderTimeItem()->whatsThis() ); mReminderTimeSpin = new KIntSpinBox( defaultPage ); mReminderTimeSpin->setWhatsThis( CalendarSupport::KCalPrefs::instance()->reminderTimeItem()->whatsThis() ); mReminderTimeSpin->setToolTip( CalendarSupport::KCalPrefs::instance()->reminderTimeItem()->toolTip() ); connect( mReminderTimeSpin, SIGNAL(valueChanged(int)), SLOT(slotWidChanged()) ); remindersLayout->addWidget( mReminderTimeSpin, 0, 1 ); mReminderUnitsCombo = new KComboBox( defaultPage ); mReminderUnitsCombo->setToolTip( CalendarSupport::KCalPrefs::instance()->reminderTimeUnitsItem()->toolTip() ); mReminderUnitsCombo->setWhatsThis( CalendarSupport::KCalPrefs::instance()->reminderTimeUnitsItem()->whatsThis() ); connect( mReminderUnitsCombo, SIGNAL(activated(int)), SLOT(slotWidChanged()) ); mReminderUnitsCombo->addItem( i18nc( "@item:inlistbox reminder units in minutes", "minute(s)" ) ); mReminderUnitsCombo->addItem( i18nc( "@item:inlistbox reminder time units in hours", "hour(s)" ) ); mReminderUnitsCombo->addItem( i18nc( "@item:inlistbox reminder time units in days", "day(s)" ) ); remindersLayout->addWidget( mReminderUnitsCombo, 0, 2 ); QCheckBox *cb = addWidBool( CalendarSupport::KCalPrefs::instance()->defaultAudioFileRemindersItem() )->checkBox(); cb->setText( QString() ); if ( CalendarSupport::KCalPrefs::instance()->audioFilePathItem()->value().isEmpty() ) { QString defAudioFile = KGlobal::dirs()->findResourceDir( "sound", QLatin1String("KDE-Sys-Warning.ogg") ); CalendarSupport::KCalPrefs::instance()->audioFilePathItem()->setValue( defAudioFile + QLatin1String("KDE-Sys-Warning.ogg") ); } QString filter = i18n( "*.ogg *.wav *.mp3 *.wma *.flac *.aiff *.raw *.au *.ra|" "Audio Files (*.ogg *.wav *.mp3 *.wma *.flac *.aiff *.raw *.au *.ra)" ); KUrlRequester *rq = addWidPath( CalendarSupport::KCalPrefs::instance()->audioFilePathItem(), 0, filter )->urlRequester(); rq->setEnabled( cb->isChecked() ); connect( cb, SIGNAL(toggled(bool)), rq, SLOT(setEnabled(bool)) ); QHBoxLayout *audioFileRemindersBox = new QHBoxLayout( remindersGroupBox ); audioFileRemindersBox->addWidget( cb ); audioFileRemindersBox->addWidget( rq ); remindersLayout->addLayout( audioFileRemindersBox, 1, 0 ); remindersLayout->addWidget( addWidBool( CalendarSupport::KCalPrefs::instance()->defaultEventRemindersItem() )->checkBox(), 2, 0 ); remindersLayout->addWidget( addWidBool( CalendarSupport::KCalPrefs::instance()->defaultTodoRemindersItem() )->checkBox(), 3, 0 ); defaultLayout->setRowStretch( 3, 1 ); load(); } protected: void usrReadConfig() { mReminderTimeSpin->setValue( CalendarSupport::KCalPrefs::instance()->mReminderTime ); mReminderUnitsCombo->setCurrentIndex( CalendarSupport::KCalPrefs::instance()->mReminderTimeUnits ); for ( int i = 0; i < 7; ++i ) { mWorkDays[i]->setChecked( ( 1 << i ) & ( KOPrefs::instance()->mWorkWeekMask ) ); } } void usrWriteConfig() { KOPrefs::instance()->mHolidays = mHolidayCombo->itemData( mHolidayCombo->currentIndex() ).toString(); CalendarSupport::KCalPrefs::instance()->mReminderTime = mReminderTimeSpin->value(); CalendarSupport::KCalPrefs::instance()->mReminderTimeUnits = mReminderUnitsCombo->currentIndex(); int mask = 0; for ( int i = 0; i < 7; ++i ) { if ( mWorkDays[i]->isChecked() ) { mask = mask | ( 1 << i ); } } KOPrefs::instance()->mWorkWeekMask = mask; KOPrefs::instance()->writeConfig(); CalendarSupport::KCalPrefs::instance()->writeConfig(); } void setCombo( KComboBox *combo, const QString &text, const QStringList *tags = 0 ) { if ( tags ) { int i = tags->indexOf( text ); if ( i > 0 ) { combo->setCurrentIndex( i ); } } else { for ( int i=0; i < combo->count(); ++i ) { if ( combo->itemText( i ) == text ) { combo->setCurrentIndex( i ); break; } } } } private: QStringList tzonenames; KComboBox *mHolidayCombo; KIntSpinBox *mReminderTimeSpin; KComboBox *mReminderUnitsCombo; QCheckBox *mWorkDays[7]; }; extern "C" { KDE_EXPORT KCModule *create_korganizerconfigtime( QWidget *parent, const char * ) { KGlobal::locale()->insertCatalog( QLatin1String("timezones4") ); return new KOPrefsDialogTime( KOGlobals::self()->componentData(), parent ); } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// class KOPrefsDialogViews : public KPIM::KPrefsModule { public: KOPrefsDialogViews( const KComponentData &inst, QWidget *parent ) : KPIM::KPrefsModule( KOPrefs::instance(), inst, parent ), mMonthIconComboBox( new KItemIconCheckCombo( KItemIconCheckCombo::MonthType, this ) ), mAgendaIconComboBox( new KItemIconCheckCombo( KItemIconCheckCombo::AgendaType, this ) ) { QBoxLayout *topTopLayout = new QVBoxLayout( this ); KTabWidget *tabWidget = new KTabWidget( this ); topTopLayout->addWidget( tabWidget ); connect( mMonthIconComboBox, SIGNAL(checkedItemsChanged(QStringList)), SLOT(slotWidChanged()) ); connect( mAgendaIconComboBox, SIGNAL(checkedItemsChanged(QStringList)), SLOT(slotWidChanged()) ); // Tab: Views->General QFrame *generalFrame = new QFrame( this ); tabWidget->addTab( generalFrame, KIcon( QLatin1String("view-choose") ), i18nc( "@title:tab general settings", "General" ) ); QBoxLayout *generalLayout = new QVBoxLayout( generalFrame ); // GroupBox: Views->General->Display Options QVBoxLayout *gdisplayLayout = new QVBoxLayout; QGroupBox *gdisplayBox = new QGroupBox( i18nc( "@title:group", "Display Options" ) ); QBoxLayout *nextDaysLayout = new QHBoxLayout; gdisplayLayout->addLayout( nextDaysLayout ); KPIM::KPrefsWidInt *nextDays = addWidInt( KOPrefs::instance()->nextXDaysItem() ); nextDays->spinBox()->setSuffix( i18nc( "@label suffix in the N days spin box", " days" ) ); nextDaysLayout->addWidget( nextDays->label() ); nextDaysLayout->addWidget( nextDays->spinBox() ); nextDaysLayout->addStretch( 1 ); gdisplayLayout->addWidget( addWidBool( KOPrefs::instance()->enableToolTipsItem() )->checkBox() ); gdisplayLayout->addWidget( addWidBool( KOPrefs::instance()->todosUseCategoryColorsItem() )->checkBox() ); gdisplayBox->setLayout( gdisplayLayout ); generalLayout->addWidget( gdisplayBox ); // GroupBox: Views->General->Date Navigator QVBoxLayout *datenavLayout = new QVBoxLayout; QGroupBox *datenavBox = new QGroupBox( i18nc( "@title:group", "Date Navigator" ) ); datenavLayout->addWidget( addWidBool( KOPrefs::instance()->dailyRecurItem() )->checkBox() ); datenavLayout->addWidget( addWidBool( KOPrefs::instance()->weeklyRecurItem() )->checkBox() ); datenavLayout->addWidget( addWidBool( KOPrefs::instance()->highlightTodosItem() )->checkBox() ); datenavLayout->addWidget( addWidBool( KOPrefs::instance()->highlightJournalsItem() )->checkBox() ); datenavLayout->addWidget( addWidBool( KOPrefs::instance()->weekNumbersShowWorkItem() )->checkBox() ); datenavBox->setLayout( datenavLayout ); generalLayout->addWidget( datenavBox ); generalLayout->addStretch( 1 ); // Tab: Views->Agenda View QFrame *agendaFrame = new QFrame( this ); tabWidget->addTab( agendaFrame, KIcon( QLatin1String("view-calendar-workweek") ), i18nc( "@title:tab", "Agenda View" ) ); QBoxLayout *agendaLayout = new QVBoxLayout( agendaFrame ); // GroupBox: Views->Agenda View->Display Options QVBoxLayout *adisplayLayout = new QVBoxLayout; QGroupBox *adisplayBox = new QGroupBox( i18nc( "@title:group", "Display Options" ) ); QHBoxLayout *hourSizeLayout = new QHBoxLayout; adisplayLayout->addLayout( hourSizeLayout ); KPIM::KPrefsWidInt *hourSize = addWidInt( KOPrefs::instance()->hourSizeItem() ); hourSize->spinBox()->setSuffix( i18nc( "@label suffix in the hour size spin box", " pixels" ) ); hourSizeLayout->addWidget( hourSize->label() ); hourSizeLayout->addWidget( hourSize->spinBox() ); hourSizeLayout->addStretch( 1 ); adisplayLayout->addWidget( addWidBool( KOPrefs::instance()->enableAgendaItemIconsItem() )->checkBox() ); adisplayLayout->addWidget( addWidBool( KOPrefs::instance()->showTodosAgendaViewItem() )->checkBox() ); KPIM::KPrefsWidBool *marcusBainsEnabled = addWidBool( KOPrefs::instance()->marcusBainsEnabledItem() ); adisplayLayout->addWidget( marcusBainsEnabled->checkBox() ); KPIM::KPrefsWidBool *marcusBainsShowSeconds = addWidBool( KOPrefs::instance()->marcusBainsShowSecondsItem() ); connect( marcusBainsEnabled->checkBox(), SIGNAL(toggled(bool)), marcusBainsShowSeconds->checkBox(), SLOT(setEnabled(bool)) ); adisplayLayout->addWidget( marcusBainsShowSeconds->checkBox() ); adisplayLayout->addWidget( addWidBool( KOPrefs::instance()->selectionStartsEditorItem() )->checkBox() ); mAgendaIconComboBox->setCheckedIcons( KOPrefs::instance()->eventViewsPreferences()->agendaViewIcons() ); adisplayLayout->addWidget( mAgendaIconComboBox ); adisplayBox->setLayout( adisplayLayout ); agendaLayout->addWidget( adisplayBox ); // GroupBox: Views->Agenda View->Color Usage agendaLayout->addWidget( addWidRadios( KOPrefs::instance()->agendaViewColorsItem() )->groupBox() ); agendaLayout->addWidget( addWidBool( KOPrefs::instance()->colorBusyDaysEnabledItem() )->checkBox() ); // GroupBox: Views->Agenda View->Multiple Calendars agendaLayout->addWidget( addWidRadios( KOPrefs::instance()->agendaViewCalendarDisplayItem() )->groupBox() ); agendaLayout->addStretch( 1 ); // Tab: Views->Month View QFrame *monthFrame = new QFrame( this ); tabWidget->addTab( monthFrame, KIcon( QLatin1String("view-calendar-month") ), i18nc( "@title:tab", "Month View" ) ); QBoxLayout *monthLayout = new QVBoxLayout( monthFrame ); // GroupBox: Views->Month View->Display Options QVBoxLayout *mdisplayLayout = new QVBoxLayout; QGroupBox *mdisplayBox = new QGroupBox( i18nc( "@title:group", "Display Options" ) ); /*mdisplayLayout->addWidget( addWidBool( KOPrefs::instance()->enableMonthScrollItem() )->checkBox() );*/ mdisplayLayout->addWidget( addWidBool( KOPrefs::instance()->showTimeInMonthViewItem() )->checkBox() ); mdisplayLayout->addWidget( addWidBool( KOPrefs::instance()->enableMonthItemIconsItem() )->checkBox() ); mdisplayLayout->addWidget( addWidBool( KOPrefs::instance()->showTodosMonthViewItem() )->checkBox() ); mdisplayLayout->addWidget( addWidBool( KOPrefs::instance()->showJournalsMonthViewItem() )->checkBox() ); mdisplayBox->setLayout( mdisplayLayout ); mMonthIconComboBox->setCheckedIcons( KOPrefs::instance()->eventViewsPreferences()->monthViewIcons() ); mdisplayLayout->addWidget( mMonthIconComboBox ); monthLayout->addWidget( mdisplayBox ); monthLayout->addWidget( addWidBool( KOPrefs::instance()->colorMonthBusyDaysEnabledItem() )->checkBox() ); // GroupBox: Views->Month View->Color Usage monthLayout->addWidget( addWidRadios( KOPrefs::instance()->monthViewColorsItem() )->groupBox() ); monthLayout->addStretch( 1 ); // Tab: Views->Todo View QFrame *todoFrame = new QFrame( this ); tabWidget->addTab( todoFrame, KIcon( QLatin1String("view-calendar-tasks") ), i18nc( "@title:tab", "Todo View" ) ); QBoxLayout *todoLayout = new QVBoxLayout( todoFrame ); // GroupBox: Views->Todo View->Display Options QVBoxLayout *tdisplayLayout = new QVBoxLayout; QGroupBox *tdisplayBox = new QGroupBox( i18nc( "@title:group", "Display Options" ) ); tdisplayLayout->addWidget( addWidBool( KOPrefs::instance()->sortCompletedTodosSeparatelyItem() )->checkBox() ); tdisplayBox->setLayout( tdisplayLayout ); todoLayout->addWidget( tdisplayBox ); // GroupBox: Views->Todo View->Other QVBoxLayout *otherLayout = new QVBoxLayout; QGroupBox *otherBox = new QGroupBox( i18nc( "@title:group", "Other Options" ) ); otherLayout->addWidget( addWidBool( KOPrefs::instance()->recordTodosInJournalsItem() )->checkBox() ); otherBox->setLayout( otherLayout ); todoLayout->addWidget( otherBox ); todoLayout->addStretch( 1 ); load(); } protected: void usrWriteConfig() { KOPrefs::instance()->eventViewsPreferences()->setAgendaViewIcons( mAgendaIconComboBox->checkedIcons() ); KOPrefs::instance()->eventViewsPreferences()->setMonthViewIcons( mMonthIconComboBox->checkedIcons() ); } private: KItemIconCheckCombo *mMonthIconComboBox; KItemIconCheckCombo *mAgendaIconComboBox; }; extern "C" { KDE_EXPORT KCModule *create_korganizerconfigviews( QWidget *parent, const char * ) { return new KOPrefsDialogViews( KOGlobals::self()->componentData(), parent ); } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// KOPrefsDialogColorsAndFonts::KOPrefsDialogColorsAndFonts( const KComponentData &inst, QWidget *parent ) : KPIM::KPrefsModule( KOPrefs::instance(), inst, parent ) { QBoxLayout *topTopLayout = new QVBoxLayout( this ); KTabWidget *tabWidget = new KTabWidget( this ); topTopLayout->addWidget( tabWidget ); QWidget *colorFrame = new QWidget( this ); topTopLayout->addWidget( colorFrame ); QGridLayout *colorLayout = new QGridLayout(colorFrame); colorLayout->setSpacing( KDialog::spacingHint() ); tabWidget->addTab( colorFrame, KIcon( QLatin1String("preferences-desktop-color") ), i18nc( "@title:tab", "Colors" ) ); // Holiday Color KPIM::KPrefsWidColor *holidayColor = addWidColor( KOPrefs::instance()->agendaHolidaysBackgroundColorItem(), colorFrame ); colorLayout->addWidget( holidayColor->label(), 0, 0 ); colorLayout->addWidget( holidayColor->button(), 0, 1 ); // agenda view background color KPIM::KPrefsWidColor *agendaBgColor = addWidColor( KOPrefs::instance()->agendaGridBackgroundColorItem(), colorFrame ); colorLayout->addWidget( agendaBgColor->label(), 3, 0 ); colorLayout->addWidget( agendaBgColor->button(), 3, 1 ); // agenda view Marcus Bains line color KPIM::KPrefsWidColor *mblColor = addWidColor( KOPrefs::instance()->agendaMarcusBainsLineLineColorItem(), colorFrame ); colorLayout->addWidget( mblColor->label(), 5, 0 ); colorLayout->addWidget( mblColor->button(), 5, 1 ); KPIM::KPrefsWidColor *viewBgBusyColor = addWidColor( KOPrefs::instance()->viewBgBusyColorItem(), colorFrame ); colorLayout->addWidget( viewBgBusyColor->label(), 4, 0 ); colorLayout->addWidget( viewBgBusyColor->button(), 4, 1 ); // working hours color KPIM::KPrefsWidColor *agendaGridWorkHoursBackgroundColor = addWidColor( KOPrefs::instance()->workingHoursColorItem(), colorFrame ); colorLayout->addWidget( agendaGridWorkHoursBackgroundColor->label(), 6, 0 ); colorLayout->addWidget( agendaGridWorkHoursBackgroundColor->button(), 6, 1 ); // Todo due today color KPIM::KPrefsWidColor *todoDueTodayColor = addWidColor( KOPrefs::instance()->todoDueTodayColorItem(), colorFrame ); colorLayout->addWidget( todoDueTodayColor->label(), 7, 0 ); colorLayout->addWidget( todoDueTodayColor->button(), 7, 1 ); // Todo overdue color KPIM::KPrefsWidColor *todoOverdueColor = addWidColor( KOPrefs::instance()->todoOverdueColorItem(), colorFrame ); colorLayout->addWidget( todoOverdueColor->label(), 8, 0 ); colorLayout->addWidget( todoOverdueColor->button(), 8, 1 ); // categories colors QGroupBox *categoryGroup = new QGroupBox( i18nc( "@title:group", "Categories" ), colorFrame ); colorLayout->addWidget( categoryGroup, 9, 0, 1, 2 ); QGridLayout *categoryLayout = new QGridLayout; categoryGroup->setLayout( categoryLayout ); KPIM::KPrefsWidColor *unsetCategoryColor = addWidColor( CalendarSupport::KCalPrefs::instance()->unsetCategoryColorItem(), categoryGroup ); categoryLayout->addWidget( unsetCategoryColor->label(), 0, 0 ); categoryLayout->addWidget( unsetCategoryColor->button(), 0, 1 ); unsetCategoryColor->label()->setWhatsThis( unsetCategoryColor->button()->whatsThis() ); unsetCategoryColor->label()->setToolTip( unsetCategoryColor->button()->toolTip() ); mCategoryCombo = new KPIM::TagCombo( categoryGroup ); mCategoryCombo->setWhatsThis( i18nc( "@info:whatsthis", "Select here the event category you want to modify. " "You can change the selected category color using " "the button below." ) ); connect( mCategoryCombo, SIGNAL(activated(int)), SLOT(updateCategoryColor()) ); categoryLayout->addWidget( mCategoryCombo, 1, 0 ); mCategoryButton = new KColorButton( categoryGroup ); mCategoryButton->setWhatsThis( i18nc( "@info:whatsthis", "Choose here the color of the event category selected " "using the combo box above." ) ); connect( mCategoryButton, SIGNAL(changed(QColor)), SLOT(setCategoryColor()) ); categoryLayout->addWidget( mCategoryButton, 1, 1 ); updateCategoryColor(); // resources colors QGroupBox *resourceGroup = new QGroupBox( i18nc( "@title:group", "Resources" ), colorFrame ); colorLayout->addWidget( resourceGroup, 10, 0, 1, 2 ); QBoxLayout *resourceLayout = new QHBoxLayout; resourceGroup->setLayout( resourceLayout ); mResourceCombo = new Akonadi::CollectionComboBox( resourceGroup ); //mResourceCombo->addExcludedSpecialResources(Akonadi::Collection::SearchResource); QStringList mimetypes; mimetypes << KCalCore::Todo::todoMimeType(); mimetypes << KCalCore::Journal::journalMimeType(); mimetypes << KCalCore::Event::eventMimeType(); mResourceCombo->setMimeTypeFilter( mimetypes ); mResourceCombo->setWhatsThis( i18nc( "@info:whatsthis", "Select the calendar you want to modify. " "You can change the selected calendar color using " "the button below." ) ); connect( mResourceCombo, SIGNAL(activated(int)), SLOT(updateResourceColor()) ); resourceLayout->addWidget( mResourceCombo ); mResourceButton = new KColorButton( resourceGroup ); mResourceButton->setWhatsThis( i18nc( "@info:whatsthis", "Choose here the color of the calendar selected " "using the combo box above." ) ); connect( mResourceButton, SIGNAL(changed(QColor)), SLOT(setResourceColor()) ); resourceLayout->addWidget( mResourceButton ); colorLayout->setRowStretch( 11, 1 ); QWidget *fontFrame = new QWidget( this ); tabWidget->addTab( fontFrame, KIcon( QLatin1String("preferences-desktop-font") ), i18nc( "@title:tab", "Fonts" ) ); QGridLayout *fontLayout = new QGridLayout( fontFrame ); fontLayout->setSpacing( KDialog::spacingHint() ); KPIM::KPrefsWidFont *timeBarFont = addWidFont( KOPrefs::instance()->agendaTimeLabelsFontItem(), fontFrame, KGlobal::locale()->formatTime( QTime( 12, 34 ) ) ); fontLayout->addWidget( timeBarFont->label(), 0, 0 ); fontLayout->addWidget( timeBarFont->preview(), 0, 1 ); fontLayout->addWidget( timeBarFont->button(), 0, 2 ); KPIM::KPrefsWidFont *monthViewFont = addWidFont( KOPrefs::instance()->monthViewFontItem(), fontFrame, KGlobal::locale()->formatTime( QTime( 12, 34 ) ) + QLatin1Char(' ') + i18nc( "@label", "Event text" ) ); fontLayout->addWidget( monthViewFont->label(), 1, 0 ); fontLayout->addWidget( monthViewFont->preview(), 1, 1 ); fontLayout->addWidget( monthViewFont->button(), 1, 2 ); KPIM::KPrefsWidFont *agendaViewFont = addWidFont( KOPrefs::instance()->agendaViewFontItem(), fontFrame, i18nc( "@label", "Event text" ) ); fontLayout->addWidget( agendaViewFont->label(), 2, 0 ); fontLayout->addWidget( agendaViewFont->preview(), 2, 1 ); fontLayout->addWidget( agendaViewFont->button(), 2, 2 ); KPIM::KPrefsWidFont *marcusBainsFont = addWidFont( KOPrefs::instance()->agendaMarcusBainsLineFontItem(), fontFrame, KGlobal::locale()->formatTime( QTime( 12, 34, 23 ) ) ); fontLayout->addWidget( marcusBainsFont->label(), 3, 0 ); fontLayout->addWidget( marcusBainsFont->preview(), 3, 1 ); fontLayout->addWidget( marcusBainsFont->button(), 3, 2 ); fontLayout->setColumnStretch( 1, 1 ); fontLayout->setRowStretch( 4, 1 ); load(); } void KOPrefsDialogColorsAndFonts::usrWriteConfig() { - QHash::const_iterator i = mCategoryDict.constBegin(); - while ( i != mCategoryDict.constEnd() ) { - CalendarSupport::KCalPrefs::instance()->setCategoryColor( i.key(), i.value() ); - ++i; + { + QHash::const_iterator i = mCategoryDict.constBegin(); + while ( i != mCategoryDict.constEnd() ) { + CalendarSupport::KCalPrefs::instance()->setCategoryColor( i.key(), i.value() ); + ++i; + } } - i = mResourceDict.constBegin(); - while ( i != mResourceDict.constEnd() ) { - KOPrefs::instance()->setResourceColor( i.key(), i.value() ); - ++i; + { + QHash::const_iterator i = mResourceDict.constBegin(); + while ( i != mResourceDict.constEnd() ) { + const QModelIndex index = i.key(); + if (index.isValid()) { + Akonadi::Collection col = CalendarSupport::collectionFromIndex(index); + KOHelper::setResourceColor(col, i.value()); + mResourceCombo->model()->setData(index, QVariant::fromValue(col), Akonadi::EntityTreeModel::CollectionRole); + } + ++i; + } } - //mCalendarViewsPrefs->writeConfig(); } void KOPrefsDialogColorsAndFonts::usrReadConfig() { updateCategories(); updateResources(); //mCalendarViewsPrefs->readConfig(); } void KOPrefsDialogColorsAndFonts::updateCategories() { updateCategoryColor(); } void KOPrefsDialogColorsAndFonts::setCategoryColor() { mCategoryDict.insert( mCategoryCombo->currentText(), mCategoryButton->color() ); slotWidChanged(); } void KOPrefsDialogColorsAndFonts::updateCategoryColor() { const QString cat = mCategoryCombo->currentText(); QColor color = mCategoryDict.value( cat ); if ( !color.isValid() ) { //TODO get this from the tag color = CalendarSupport::KCalPrefs::instance()->categoryColor( cat ); } if ( color.isValid() ) { mCategoryButton->setColor( color ); } } void KOPrefsDialogColorsAndFonts::updateResources() { updateResourceColor(); } void KOPrefsDialogColorsAndFonts::setResourceColor() { - bool ok; - const QString id = - QString::number( mResourceCombo->itemData( - mResourceCombo->currentIndex(), - Akonadi::CollectionModel::CollectionIdRole ).toLongLong( &ok ) ); - if( ! ok ) { - return; + const QModelIndex index = mResourceCombo->model()->index(mResourceCombo->currentIndex(), 0); + if (!index.isValid()) { + return; } - mResourceDict.insert( id, mResourceButton->color() ); + + mResourceDict.insert(QPersistentModelIndex(index), mResourceButton->color()); slotWidChanged(); } void KOPrefsDialogColorsAndFonts::updateResourceColor() { - bool ok; - const QString id = - QString::number( mResourceCombo->itemData( - mResourceCombo->currentIndex(), - Akonadi::CollectionModel::CollectionIdRole ).toLongLong( &ok ) ); - if ( !ok ) { - return; + const QModelIndex index = mResourceCombo->model()->index(mResourceCombo->currentIndex(), 0); + if (!index.isValid()) { + return; } - kDebug() << id << mResourceCombo->itemText( mResourceCombo->currentIndex() ); - QColor color = mResourceDict.value( id ); + QColor color = mResourceDict.value(QPersistentModelIndex(index)); if ( ! color.isValid() ) { - color = KOPrefs::instance()->resourceColor( id ); + color = KOHelper::resourceColor(mResourceCombo->currentCollection()); } mResourceButton->setColor( color ); } extern "C" { KDE_EXPORT KCModule *create_korganizerconfigcolorsandfonts( QWidget *parent, const char * ) { return new KOPrefsDialogColorsAndFonts( KOGlobals::self()->componentData(), parent ); } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// KOPrefsDialogGroupScheduling::KOPrefsDialogGroupScheduling( const KComponentData &inst, QWidget *parent ) : KPIM::KPrefsModule( KOPrefs::instance(), inst, parent ) { QBoxLayout *topTopLayout = new QVBoxLayout( this ); QWidget *topFrame = new QWidget( this ); topTopLayout->addWidget( topFrame ); QGridLayout *topLayout = new QGridLayout( topFrame ); topLayout->setSpacing( KDialog::spacingHint() ); KPIM::KPrefsWidBool *useGroupwareBool = addWidBool( CalendarSupport::KCalPrefs::instance()->useGroupwareCommunicationItem(), topFrame ); topLayout->addWidget( useGroupwareBool->checkBox(), 0, 0, 1, 2 ); KPIM::KPrefsWidCombo *defaultSendPolicy = addWidCombo( CalendarSupport::KCalPrefs::instance()->sendPolicyItem(), topFrame ); topLayout->addWidget( defaultSendPolicy->label(), 1, 0, 1, 2 ); topLayout->addWidget( defaultSendPolicy->comboBox(), 2, 0, 1, 2 ); KPIM::KPrefsWidBool *bcc = addWidBool( Akonadi::CalendarSettings::self()->bccItem(), topFrame ); topLayout->addWidget( bcc->checkBox(), 3, 0, 1, 2 ); QLabel *aTransportLabel = new QLabel( i18nc( "@label", "Mail transport:" ), topFrame ); topLayout->addWidget( aTransportLabel, 4, 0, 1, 2 ); MailTransport::TransportManagementWidget *tmw = new MailTransport::TransportManagementWidget( topFrame ); tmw->layout()->setContentsMargins( 0, 0, 0, 0 ); topLayout->addWidget( tmw, 5, 0, 1, 2 ); //topLayout->setRowStretch( 2, 1 ); load(); } void KOPrefsDialogGroupScheduling::usrReadConfig() { } void KOPrefsDialogGroupScheduling::usrWriteConfig() { } extern "C" { KDE_EXPORT KCModule *create_korganizerconfiggroupscheduling( QWidget *parent, const char * ) { return new KOPrefsDialogGroupScheduling( KOGlobals::self()->componentData(), parent ); } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// KOPrefsDialogGroupwareScheduling::KOPrefsDialogGroupwareScheduling( const KComponentData &inst, QWidget *parent ) : KPrefsModule( CalendarSupport::KCalPrefs::instance(), inst, parent ) { mGroupwarePage = new Ui::KOGroupwarePrefsPage(); QWidget *widget = new QWidget( this ); widget->setObjectName( QLatin1String("KOGrouparePrefsPage") ); mGroupwarePage->setupUi( widget ); mGroupwarePage->groupwareTab->setTabIcon( 0, KIcon( QLatin1String("go-up") ) ); mGroupwarePage->groupwareTab->setTabIcon( 1, KIcon( QLatin1String("go-down") ) ); // signals and slots connections connect( mGroupwarePage->publishDays, SIGNAL(valueChanged(int)), SLOT(slotWidChanged()) ); connect( mGroupwarePage->publishUrl, SIGNAL(textChanged(QString)), SLOT(slotWidChanged()) ); connect( mGroupwarePage->publishUser, SIGNAL(textChanged(QString)), SLOT(slotWidChanged()) ); connect( mGroupwarePage->publishPassword, SIGNAL(textChanged(QString)), SLOT(slotWidChanged()) ); connect( mGroupwarePage->publishSavePassword, SIGNAL(toggled(bool)), SLOT(slotWidChanged()) ); connect( mGroupwarePage->retrieveEnable, SIGNAL(toggled(bool)), SLOT(slotWidChanged()) ); connect( mGroupwarePage->retrieveUser, SIGNAL(textChanged(QString)), SLOT(slotWidChanged()) ); connect( mGroupwarePage->retrievePassword, SIGNAL(textChanged(QString)), SLOT(slotWidChanged()) ); connect( mGroupwarePage->retrieveSavePassword, SIGNAL(toggled(bool)), SLOT(slotWidChanged()) ); connect( mGroupwarePage->retrieveUrl, SIGNAL(textChanged(QString)), SLOT(slotWidChanged())); connect( mGroupwarePage->publishDelay, SIGNAL(valueChanged(int)), SLOT(slotWidChanged()) ); connect( mGroupwarePage->fullDomainRetrieval, SIGNAL(toggled(bool)), SLOT(slotWidChanged()) ); connect( mGroupwarePage->publishEnable, SIGNAL(toggled(bool)), SLOT(slotWidChanged()) ); ( new QVBoxLayout( this ) )->addWidget( widget ); load(); } KOPrefsDialogGroupwareScheduling::~KOPrefsDialogGroupwareScheduling() { delete mGroupwarePage; } void KOPrefsDialogGroupwareScheduling::usrReadConfig() { mGroupwarePage->publishEnable->setChecked( Akonadi::CalendarSettings::self()->freeBusyPublishAuto() ); mGroupwarePage->publishDelay->setValue( Akonadi::CalendarSettings::self()->freeBusyPublishDelay() ); mGroupwarePage->publishDays->setValue( Akonadi::CalendarSettings::self()->freeBusyPublishDays() ); mGroupwarePage->publishUrl->setText( Akonadi::CalendarSettings::self()->freeBusyPublishUrl() ); mGroupwarePage->publishUser->setText( Akonadi::CalendarSettings::self()->freeBusyPublishUser() ); mGroupwarePage->publishPassword->setText( Akonadi::CalendarSettings::self()->freeBusyPublishPassword() ); mGroupwarePage->publishSavePassword->setChecked( Akonadi::CalendarSettings::self()->freeBusyPublishSavePassword() ); mGroupwarePage->retrieveEnable->setChecked( Akonadi::CalendarSettings::self()->freeBusyRetrieveAuto() ); mGroupwarePage->fullDomainRetrieval->setChecked( Akonadi::CalendarSettings::self()->freeBusyFullDomainRetrieval() ); mGroupwarePage->retrieveUrl->setText( Akonadi::CalendarSettings::self()->freeBusyRetrieveUrl() ); mGroupwarePage->retrieveUser->setText( Akonadi::CalendarSettings::self()->freeBusyRetrieveUser() ); mGroupwarePage->retrievePassword->setText( Akonadi::CalendarSettings::self()->freeBusyRetrievePassword() ); mGroupwarePage->retrieveSavePassword->setChecked( Akonadi::CalendarSettings::self()->freeBusyRetrieveSavePassword() ); } void KOPrefsDialogGroupwareScheduling::usrWriteConfig() { Akonadi::CalendarSettings::self()->setFreeBusyPublishAuto( mGroupwarePage->publishEnable->isChecked()); Akonadi::CalendarSettings::self()->setFreeBusyPublishDelay(mGroupwarePage->publishDelay->value()); Akonadi::CalendarSettings::self()->setFreeBusyPublishDays( mGroupwarePage->publishDays->value()); Akonadi::CalendarSettings::self()->setFreeBusyPublishUrl( mGroupwarePage->publishUrl->text()); Akonadi::CalendarSettings::self()->setFreeBusyPublishUser( mGroupwarePage->publishUser->text()); Akonadi::CalendarSettings::self()->setFreeBusyPublishPassword( mGroupwarePage->publishPassword->text()); Akonadi::CalendarSettings::self()->setFreeBusyPublishSavePassword( mGroupwarePage->publishSavePassword->isChecked()); Akonadi::CalendarSettings::self()->setFreeBusyRetrieveAuto( mGroupwarePage->retrieveEnable->isChecked()); Akonadi::CalendarSettings::self()->setFreeBusyFullDomainRetrieval( mGroupwarePage->fullDomainRetrieval->isChecked()); Akonadi::CalendarSettings::self()->setFreeBusyRetrieveUrl( mGroupwarePage->retrieveUrl->text()); Akonadi::CalendarSettings::self()->setFreeBusyRetrieveUser( mGroupwarePage->retrieveUser->text()); Akonadi::CalendarSettings::self()->setFreeBusyRetrievePassword( mGroupwarePage->retrievePassword->text()); Akonadi::CalendarSettings::self()->setFreeBusyRetrieveSavePassword( mGroupwarePage->retrieveSavePassword->isChecked()); // clear the url cache for our user const QString configFile = KStandardDirs::locateLocal( "data", QLatin1String("korganizer/freebusyurls") ); KConfig cfg( configFile ); cfg.deleteGroup( CalendarSupport::KCalPrefs::instance()->email() ); Akonadi::CalendarSettings::self()->writeConfig(); } extern "C" { KDE_EXPORT KCModule *create_korganizerconfigfreebusy( QWidget *parent, const char * ) { return new KOPrefsDialogGroupwareScheduling( KOGlobals::self()->componentData(), parent ); } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// class PluginItem : public QTreeWidgetItem { public: PluginItem( QTreeWidget *parent, KService::Ptr service ) : QTreeWidgetItem( parent, QStringList( service->name() ) ), mService( service ) {} PluginItem( QTreeWidgetItem *parent, KService::Ptr service ) : QTreeWidgetItem( parent, QStringList( service->name() ) ), mService( service ) {} KService::Ptr service() { return mService; } private: KService::Ptr mService; }; /** Dialog for selecting and configuring KOrganizer plugins */ KOPrefsDialogPlugins::KOPrefsDialogPlugins( const KComponentData &inst, QWidget *parent ) : KPrefsModule( KOPrefs::instance(), inst, parent ) { QBoxLayout *topTopLayout = new QVBoxLayout( this ); QWidget *topFrame = new QWidget( this ); topTopLayout->addWidget( topFrame ); QBoxLayout *topLayout = new QVBoxLayout( topFrame ); topLayout->setSpacing( KDialog::spacingHint() ); mTreeWidget = new QTreeWidget( topFrame ); mTreeWidget->setColumnCount( 1 ); mTreeWidget->setHeaderLabel( i18nc( "@title:column plugin name", "Name" ) ); topLayout->addWidget( mTreeWidget ); mDescription = new QLabel( topFrame ); mDescription->setAlignment( Qt::AlignVCenter ); mDescription->setWordWrap( true ); mDescription->setFrameShape( QLabel::Panel ); mDescription->setFrameShadow( QLabel::Sunken ); mDescription->setMinimumSize( QSize( 0, 55 ) ); QSizePolicy policy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed ); policy.setHorizontalStretch( 0 ); policy.setVerticalStretch( 0 ); policy.setHeightForWidth( mDescription->sizePolicy().hasHeightForWidth() ); mDescription->setSizePolicy( policy ); topLayout->addWidget( mDescription ); QWidget *buttonRow = new QWidget( topFrame ); QBoxLayout *buttonRowLayout = new QHBoxLayout( buttonRow ); mConfigureButton = new KPushButton( KGuiItem( i18nc( "@action:button", "Configure &Plugin..." ), QLatin1String("configure"), QString(), i18nc( "@info:whatsthis", "This button allows you to configure" " the plugin that you have selected in the list above" ) ), buttonRow ); buttonRowLayout->addWidget( mConfigureButton ); buttonRowLayout->addItem( new QSpacerItem( 1, 1, QSizePolicy::Expanding ) ); topLayout->addWidget( buttonRow ); mPositioningGroupBox = new QGroupBox( i18nc( "@title:group", "Position" ), topFrame ); //mPositionMonthTop = new QCheckBox( //i18nc( "@option:check", "Show in the month view" ), mPositioningGroupBox ); mPositionAgendaTop = new QRadioButton( i18nc( "@option:check", "Show at the top of the agenda views" ), mPositioningGroupBox ); mPositionAgendaBottom = new QRadioButton( i18nc( "@option:check", "Show at the bottom of the agenda views" ), mPositioningGroupBox ); QVBoxLayout *positioningLayout = new QVBoxLayout( mPositioningGroupBox ); //positioningLayout->addWidget( mPositionMonthTop ); positioningLayout->addWidget( mPositionAgendaTop ); positioningLayout->addWidget( mPositionAgendaBottom ); positioningLayout->addStretch( 1 ); topLayout->addWidget( mPositioningGroupBox ); connect( mConfigureButton, SIGNAL(clicked()), SLOT(configure()) ); //connect( mPositionMonthTop, SIGNAL(clicked()), SLOT(positioningChanged()) ); connect( mPositionAgendaTop, SIGNAL(clicked()), SLOT(positioningChanged()) ); connect( mPositionAgendaBottom, SIGNAL(clicked()), SLOT(positioningChanged()) ); connect( mTreeWidget, SIGNAL(itemSelectionChanged()), SLOT(selectionChanged()) ); connect( mTreeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)), SLOT(selectionChanged()) ); connect( mTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), SLOT(slotWidChanged()) ); load(); selectionChanged(); } void KOPrefsDialogPlugins::usrReadConfig() { mTreeWidget->clear(); KService::List plugins = KOCore::self()->availablePlugins(); plugins += KOCore::self()->availableParts(); EventViews::PrefsPtr viewPrefs = KOPrefs::instance()->eventViewsPreferences(); QStringList selectedPlugins = viewPrefs->selectedPlugins(); QTreeWidgetItem *decorations = new QTreeWidgetItem( mTreeWidget, QStringList( i18nc( "@title:group", "Calendar Decorations" ) ) ); QTreeWidgetItem *others = new QTreeWidgetItem( mTreeWidget, QStringList( i18nc( "@title:group", "Other Plugins" ) ) ); KService::List::ConstIterator it; for ( it = plugins.constBegin(); it != plugins.constEnd(); ++it ) { QTreeWidgetItem *item = 0; if ( (*it)->hasServiceType( EventViews::CalendarDecoration::Decoration::serviceType() ) ) { item = new PluginItem( decorations, *it ); } else if ( !(*it)->hasServiceType( QLatin1String( "KOrganizer/PrintPlugin" ) ) ) { // we specifically skip print plugins since we no longer support them item = new PluginItem( others, *it ); } else { continue; } if ( selectedPlugins.contains( (*it)->desktopEntryName() ) ) { item->setCheckState( 0, Qt::Checked ); } else { item->setCheckState( 0, Qt::Unchecked ); } } decorations->setExpanded( true ); others->setExpanded( true ); mDecorationsAtMonthViewTop = KOPrefs::instance()->decorationsAtMonthViewTop().toSet(); mDecorationsAtAgendaViewTop = viewPrefs->decorationsAtAgendaViewTop().toSet(); mDecorationsAtAgendaViewBottom = viewPrefs->decorationsAtAgendaViewBottom().toSet(); } void KOPrefsDialogPlugins::usrWriteConfig() { QStringList selectedPlugins; for ( int i = 0; i < mTreeWidget->topLevelItemCount(); ++i) { QTreeWidgetItem *serviceTypeGroup = mTreeWidget->topLevelItem( i ); for ( int j = 0; j < serviceTypeGroup->childCount(); j++) { PluginItem *item = static_cast( serviceTypeGroup->child( j ) ); if( item->checkState( 0 ) == Qt::Checked ) { selectedPlugins.append( item->service()->desktopEntryName() ); } } } EventViews::PrefsPtr viewPrefs = KOPrefs::instance()->eventViewsPreferences(); viewPrefs->setSelectedPlugins( selectedPlugins ); KOPrefs::instance()->setDecorationsAtMonthViewTop( mDecorationsAtMonthViewTop.toList() ); viewPrefs->setDecorationsAtAgendaViewTop( mDecorationsAtAgendaViewTop.toList() ); viewPrefs->setDecorationsAtAgendaViewBottom( mDecorationsAtAgendaViewBottom.toList() ); } void KOPrefsDialogPlugins::configure() { if ( mTreeWidget->selectedItems().count() != 1 ) { return; } PluginItem *item = static_cast( mTreeWidget->selectedItems().last() ); if ( !item ) { return; } CalendarSupport::Plugin *plugin = KOCore::self()->loadPlugin( item->service() ); if ( plugin ) { plugin->configure( this ); delete plugin; slotWidChanged(); } else { KMessageBox::sorry( this, i18nc( "@info", "Unable to configure this plugin" ), QLatin1String("PluginConfigUnable") ); } } void KOPrefsDialogPlugins::positioningChanged() { if ( mTreeWidget->selectedItems().count() != 1 ) { return; } PluginItem *item = dynamic_cast( mTreeWidget->selectedItems().last() ); if ( !item ) { return; } QString decoration = item->service()->desktopEntryName(); /*if ( mPositionMonthTop->checkState() == Qt::Checked ) { if ( !mDecorationsAtMonthViewTop.contains( decoration ) ) { mDecorationsAtMonthViewTop.insert( decoration ); } } else { mDecorationsAtMonthViewTop.remove( decoration ); }*/ if ( mPositionAgendaTop->isChecked() ) { if ( !mDecorationsAtAgendaViewTop.contains( decoration ) ) { mDecorationsAtAgendaViewTop.insert( decoration ); } } else { mDecorationsAtAgendaViewTop.remove( decoration ); } if ( mPositionAgendaBottom->isChecked() ) { if ( !mDecorationsAtAgendaViewBottom.contains( decoration ) ) { mDecorationsAtAgendaViewBottom.insert( decoration ); } } else { mDecorationsAtAgendaViewBottom.remove( decoration ); } slotWidChanged(); } void KOPrefsDialogPlugins::selectionChanged() { mPositioningGroupBox->hide(); //mPositionMonthTop->setChecked( false ); mPositionAgendaTop->setChecked( false ); mPositionAgendaBottom->setChecked( false ); if ( mTreeWidget->selectedItems().count() != 1 ) { mConfigureButton->setEnabled( false ); mDescription->setText( QString() ); return; } PluginItem *item = dynamic_cast( mTreeWidget->selectedItems().last() ); if ( !item ) { mConfigureButton->setEnabled( false ); mDescription->setText( QString() ); return; } QVariant variant = item->service()->property( QLatin1String("X-KDE-KOrganizer-HasSettings") ); bool hasSettings = true; if ( variant.isValid() ) { hasSettings = variant.toBool(); } mDescription->setText( item->service()->comment() ); if ( !hasSettings ) { mConfigureButton->hide(); } else { mConfigureButton->show(); mConfigureButton->setEnabled( item->checkState(0) == Qt::Checked ); } bool hasPosition = false; if ( item->service()->hasServiceType( EventViews::CalendarDecoration::Decoration::serviceType() ) ) { QString decoration = item->service()->desktopEntryName(); /*if ( mDecorationsAtMonthViewTop.contains( decoration ) ) { mPositionMonthTop->setChecked( true ); hasPosition = true; }*/ if ( mDecorationsAtAgendaViewTop.contains( decoration ) ) { mPositionAgendaTop->setChecked( true ); hasPosition = true; } if ( mDecorationsAtAgendaViewBottom.contains( decoration ) ) { mPositionAgendaBottom->setChecked( true ); hasPosition = true; } if ( !hasPosition ) { // no position has been selected, so default to Agenda Top mDecorationsAtAgendaViewTop << decoration; mPositionAgendaTop->setChecked( true ); } mPositioningGroupBox->setEnabled( item->checkState(0) == Qt::Checked ); mPositioningGroupBox->show(); } slotWidChanged(); } extern "C" { KDE_EXPORT KCModule *create_korganizerconfigplugins( QWidget *parent, const char * ) { return new KOPrefsDialogPlugins( KOGlobals::self()->componentData(), parent ); } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// extern "C" { KDE_EXPORT KCModule *create_korgdesignerfields( QWidget *parent, const char * ) { return new KOPrefsDesignerFields( KOGlobals::self()->componentData(), parent ); } } KOPrefsDesignerFields::KOPrefsDesignerFields( const KComponentData &inst, QWidget *parent ) : KCMDesignerFields( inst, parent ) { } QString KOPrefsDesignerFields::localUiDir() { const QString dir = KStandardDirs::locateLocal( "data", QLatin1String("korganizer/designer/event/") ); return dir; } QString KOPrefsDesignerFields::uiPath() { return QLatin1String("korganizer/designer/event/"); } void KOPrefsDesignerFields::writeActivePages( const QStringList &activePages ) { CalendarSupport::KCalPrefs::instance()->setActiveDesignerFields( activePages ); CalendarSupport::KCalPrefs::instance()->writeConfig(); } QStringList KOPrefsDesignerFields::readActivePages() { return CalendarSupport::KCalPrefs::instance()->activeDesignerFields(); } QString KOPrefsDesignerFields::applicationName() { return QLatin1String("KORGANIZER"); } diff --git a/korganizer/koprefsdialog.h b/korganizer/koprefsdialog.h index cd90f36db1..8ce433c891 100644 --- a/korganizer/koprefsdialog.h +++ b/korganizer/koprefsdialog.h @@ -1,175 +1,175 @@ /* This file is part of KOrganizer. Copyright (c) 2000,2001,2002,2003 Cornelius Schumacher Copyright (C) 2003-2004 Reinhold Kainhofer 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 (at your option) 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #ifndef KORG_KOPREFSDIALOG_H #define KORG_KOPREFSDIALOG_H #include "korganizer_export.h" #include "kcmdesignerfields.h" #include "ui_accountscalendarwidget.h" #include namespace Ui { class KOGroupwarePrefsPage; } namespace Akonadi { class CollectionComboBox; } class QRadioButton; class KCM_KORGANIZER_EXPORT KOPrefsDialogMain : public KPIM::KPrefsModule { Q_OBJECT public: KOPrefsDialogMain( const KComponentData &inst, QWidget *parent ); protected slots: void toggleEmailSettings( bool on ); void slotAccountSelected(); void slotAddAccount(); void slotModifySelectedAccount(); void slotRemoveSelectedAccount(); private: QWidget *mUserEmailSettings; Ui_AccountsCalendarWidget mAccountsCalendar; }; class KCM_KORGANIZER_EXPORT KOPrefsDialogColorsAndFonts : public KPIM::KPrefsModule { Q_OBJECT public: KOPrefsDialogColorsAndFonts( const KComponentData &inst, QWidget *parent ); protected: void usrWriteConfig(); void usrReadConfig(); protected slots: void updateCategories(); void setCategoryColor(); void updateCategoryColor(); void updateResources(); void setResourceColor(); void updateResourceColor(); private: KComboBox *mCategoryCombo; KColorButton *mCategoryButton; QHash mCategoryDict; Akonadi::CollectionComboBox *mResourceCombo; KColorButton *mResourceButton; - QHash mResourceDict; + QHash mResourceDict; }; class KCM_KORGANIZER_EXPORT KOPrefsDialogGroupScheduling : public KPIM::KPrefsModule { Q_OBJECT public: KOPrefsDialogGroupScheduling( const KComponentData &inst, QWidget *parent ); protected: void usrReadConfig(); void usrWriteConfig(); }; class KOGroupwarePrefsPage; class KCM_KORGANIZER_EXPORT KOPrefsDialogGroupwareScheduling : public KPIM::KPrefsModule { Q_OBJECT public: KOPrefsDialogGroupwareScheduling( const KComponentData &inst, QWidget *parent ); ~KOPrefsDialogGroupwareScheduling(); protected: void usrReadConfig(); void usrWriteConfig(); private: Ui::KOGroupwarePrefsPage *mGroupwarePage; }; class KCM_KORGANIZER_EXPORT KOPrefsDialogPlugins : public KPIM::KPrefsModule { Q_OBJECT public: KOPrefsDialogPlugins( const KComponentData &inst, QWidget *parent ); protected slots: void usrReadConfig(); void usrWriteConfig(); void configure(); void selectionChanged(); void positioningChanged(); private: void buildList(); QTreeWidget *mTreeWidget; QLabel *mDescription; KPushButton *mConfigureButton; QGroupBox *mPositioningGroupBox; //Decorations are not implemented in month view yet //QCheckBox *mPositionMonthTop; QRadioButton *mPositionAgendaTop; QRadioButton *mPositionAgendaBottom; QSet mDecorationsAtMonthViewTop; QSet mDecorationsAtAgendaViewTop; QSet mDecorationsAtAgendaViewBottom; }; class KCM_KORGANIZER_EXPORT KOPrefsDesignerFields : public KCMDesignerFields { public: explicit KOPrefsDesignerFields( const KComponentData &inst, QWidget *parent = 0 ); protected: QString localUiDir(); QString uiPath(); void writeActivePages( const QStringList & ); QStringList readActivePages(); QString applicationName(); }; /*class KCM_KORGANIZER_EXPORT KOPrefsDialogThemes : public KPrefsModule { Q_OBJECT public: KOPrefsDialogThemes( const KComponentData &inst, QWidget *parent ); protected slots: void usrReadConfig(); void usrWriteConfig(); void importTheme(); void exportTheme(); };*/ #endif diff --git a/korganizer/views/collectionview/calendardelegate.cpp b/korganizer/views/collectionview/calendardelegate.cpp index f1f3514630..18066531bc 100644 --- a/korganizer/views/collectionview/calendardelegate.cpp +++ b/korganizer/views/collectionview/calendardelegate.cpp @@ -1,278 +1,277 @@ /* Copyright (c) 2014 Christian Mollekopf 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 "calendardelegate.h" #include #include #include #include #include #include #include #include #include "controller.h" StyledCalendarDelegate::StyledCalendarDelegate(QObject * parent) : QStyledItemDelegate(parent) { mPixmap.insert(Enable, KIconLoader().loadIcon(QLatin1String("bookmarks"), KIconLoader::Small)); mPixmap.insert(RemoveFromList, KIconLoader().loadIcon(QLatin1String("list-remove"), KIconLoader::Small)); mPixmap.insert(AddToList, KIconLoader().loadIcon(QLatin1String("list-add"), KIconLoader::Small)); mPixmap.insert(Quickview, KIconLoader().loadIcon(QLatin1String("quickview"), KIconLoader::Small)); } StyledCalendarDelegate::~StyledCalendarDelegate() { } static QRect enableButtonRect(const QRect &rect, int pos = 1) { //2px border on each side of the icon static int border = 2; const int side = rect.height() - (2 * border); const int offset = side * pos + border * (pos + 1); return rect.adjusted(rect.width() - (offset + side), border, -offset, -border); } static QStyle *style(const QStyleOptionViewItem &option) { QWidget const *widget = 0; if (const QStyleOptionViewItemV3 *v3 = qstyleoption_cast(&option)) { widget = v3->widget; } QStyle *style = widget ? widget->style() : QApplication::style(); return style; } static QStyleOptionButton buttonOpt(const QStyleOptionViewItemV4 &opt, const QPixmap &pixmap, int pos = 1) { QStyleOptionButton option; option.icon = pixmap; QRect r = opt.rect; const int h = r.height() - 4; option.rect = enableButtonRect(r, pos); option.state = QStyle::State_Active | QStyle::State_Enabled; option.iconSize = QSize(h, h); return option; } static bool isChildOfPersonCollection(const QModelIndex &index) { QModelIndex parent = index.parent(); while (parent.isValid()) { if (parent.data(NodeTypeRole).toInt() == PersonNodeRole) { return true; } parent = parent.parent(); } return false; } static Akonadi::Collection personCollection(const QModelIndex &index) { QModelIndex parent = index.parent(); while (parent.isValid()) { if (parent.data(NodeTypeRole).toInt() == PersonNodeRole) { return CalendarSupport::collectionFromIndex(parent); } parent = parent.parent(); } return Akonadi::Collection(); } static bool isPersonNode(const QModelIndex &index) { if (index.data(NodeTypeRole).toInt() == PersonNodeRole) { return true; } return false; } QList StyledCalendarDelegate::getActions(const QStyleOptionViewItem &option, const QModelIndex &index) const { const bool isSearchResult = index.data(IsSearchResultRole).toBool(); const bool hover = option.state & QStyle::State_MouseOver; const Akonadi::Collection col = CalendarSupport::collectionFromIndex(index); Qt::CheckState enabled = static_cast(index.data(EnabledRole).toInt()); // kDebug() << index.data().toString() << enabled; const bool isSearchCollection = col.resource().startsWith(QLatin1String("akonadi_search_resource")); const bool isKolabCollection = col.resource().startsWith(QLatin1String("akonadi_kolab_resource")); const bool isTopLevelCollection = (col.parentCollection() == Akonadi::Collection::root()); const bool isToplevelSearchCollection = (isTopLevelCollection && isSearchCollection); const bool isToplevelKolabCollection = (isTopLevelCollection && isKolabCollection); QList buttons; if (!isSearchCollection && !isToplevelKolabCollection) { if (isSearchResult) { buttons << AddToList; } else { if (hover) { if (enabled != Qt::Checked) { buttons << Enable; } //The remove button should not be available for person subfolders if (!isChildOfPersonCollection(index)) { buttons << RemoveFromList; } } else { if (enabled == Qt::Checked) { buttons << Enable; } } } } if (!isToplevelSearchCollection && !isToplevelKolabCollection) { buttons << Quickview; } if (isSearchCollection && !isToplevelSearchCollection) { buttons << Total; } return buttons; } void StyledCalendarDelegate::paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const { Q_ASSERT(index.isValid()); - const Akonadi::Collection col = CalendarSupport::collectionFromIndex(index); + Akonadi::Collection col = CalendarSupport::collectionFromIndex(index); //We display the toolbuttons while hovering const bool showButtons = option.state & QStyle::State_MouseOver; // const bool enabled = col.shouldList(Akonadi::Collection::ListDisplay); Qt::CheckState enabled = static_cast(index.data(EnabledRole).toInt()); QStyleOptionViewItemV4 opt = option; initStyleOption(&opt, index); QStyledItemDelegate::paint(painter, opt, index); QStyle *s = style(option); //Buttons { QList buttons; int i = 1; Q_FOREACH (Action action, getActions(option, index)) { if (action != Total) { QStyleOptionButton buttonOption = buttonOpt(opt, mPixmap.value(action), i); if (action == Enable && showButtons) { buttonOption.state = QStyle::State_Active; } if (action == Enable && !showButtons && enabled == Qt::PartiallyChecked) { buttonOption.state = QStyle::State_Active; } s->drawControl(QStyle::CE_PushButton, &buttonOption, painter, 0); } else { QStyleOptionButton buttonOption = buttonOpt(opt, QPixmap(), i); buttonOption.features = QStyleOptionButton::Flat; buttonOption.rect.setHeight(buttonOption.rect.height() + 4); if (col.statistics().count() > 0) { buttonOption.text = QString::number(col.statistics().count()); } s->drawControl(QStyle::CE_PushButton, &buttonOption, painter, 0); } i++; } } //Color indicator if (opt.checkState){ QColor color = KOHelper::resourceColorKnown(col); if (!color.isValid() && isChildOfPersonCollection(index)){ const Akonadi::Collection parentCol = personCollection(index); if (parentCol.isValid()) { color = KOHelper::resourceColor(parentCol); - KOHelper::setResourceColor(col, color); } else { color = KOHelper::resourceColor(col); } } else { color = KOHelper::resourceColor(col); } if (color.isValid()){ painter->save(); painter->setRenderHint(QPainter::Antialiasing); QPen pen = painter->pen(); pen.setColor(color); QPainterPath path; path.addRoundedRect(enableButtonRect(opt.rect, 0), 5, 5); color.setAlpha(200); painter->fillPath(path, color); painter->strokePath(path, pen); painter->restore(); } } } bool StyledCalendarDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { Q_ASSERT(event); Q_ASSERT(model); int button = -1; // make sure that we have the right event type if ((event->type() == QEvent::MouseButtonRelease) || (event->type() == QEvent::MouseButtonDblClick) || (event->type() == QEvent::MouseButtonPress)) { QMouseEvent *me = static_cast(event); for (int i = 1; i < 4; i++) { if (enableButtonRect(option.rect, i).contains(me->pos())) { button = i; break; } } if (me->button() != Qt::LeftButton || button < 0) { return QStyledItemDelegate::editorEvent(event, model, option, index); } if ((event->type() == QEvent::MouseButtonPress) || (event->type() == QEvent::MouseButtonDblClick)) { return true; } } else { return QStyledItemDelegate::editorEvent(event, model, option, index); } Q_ASSERT(button > 0); QStyleOptionViewItem opt = option; opt.state |= QStyle::State_MouseOver; QList actions = getActions(opt, index); if (actions.count() >= button) { const Action a = actions.at(button - 1); emit action(index, a); return true; } return QStyledItemDelegate::editorEvent(event, model, option, index); } QSize StyledCalendarDelegate::sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const { QSize size = QStyledItemDelegate::sizeHint(option, index); //Without this adjustment toplevel resource folders get a slightly greater height, which looks silly and breaks the toolbutton position. size.setHeight(mPixmap.value(AddToList).height() + 4); return size; }