File indexing completed on 2024-11-24 04:41:38

0001 /*
0002     SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
0003     SPDX-FileContributor: Kevin Krammer <krake@kdab.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "mainwindow.h"
0009 
0010 #include "settings.h"
0011 
0012 #include "agenda/agenda.h"
0013 #include "agenda/agendaview.h"
0014 #include "calendarview_debug.h"
0015 #include "month/monthview.h"
0016 #include "multiagenda/multiagendaview.h"
0017 #include "prefs.h"
0018 #include "timeline/timelineview.h"
0019 
0020 #include <Akonadi/Collection>
0021 #include <Akonadi/CollectionFilterProxyModel>
0022 #include <Akonadi/ControlGui>
0023 #include <Akonadi/EntityTreeModel>
0024 #include <Akonadi/IncidenceChanger>
0025 #include <Akonadi/ItemFetchScope>
0026 #include <Akonadi/Monitor>
0027 
0028 #include <CalendarSupport/CollectionSelection>
0029 
0030 #include <KCalendarCore/Event>
0031 
0032 #include <KCheckableProxyModel>
0033 
0034 using namespace Akonadi;
0035 using namespace CalendarSupport;
0036 using namespace EventViews;
0037 
0038 MainWindow::MainWindow(const QStringList &viewNames)
0039     : QMainWindow()
0040     , mViewNames(viewNames)
0041     , mIncidenceChanger(nullptr)
0042     , mSettings(nullptr)
0043     , mViewPreferences(nullptr)
0044 {
0045     mUi.setupUi(this);
0046     mUi.tabWidget->clear();
0047 
0048     connect(mUi.addViewMenu, &QMenu::triggered, this, &MainWindow::addViewTriggered);
0049 
0050     Akonadi::ControlGui::widgetNeedsAkonadi(this);
0051 
0052     setGeometry(0, 0, 800, 600);
0053     QMetaObject::invokeMethod(this, "delayedInit", Qt::QueuedConnection);
0054 }
0055 
0056 MainWindow::~MainWindow()
0057 {
0058     delete mViewPreferences;
0059     delete mSettings;
0060 }
0061 
0062 void MainWindow::addView(const QString &viewName)
0063 {
0064     EventView *eventView = nullptr;
0065 
0066     const auto start = QDateTime::currentDateTime().addDays(-1);
0067     const auto end = QDateTime::currentDateTime().addDays(1);
0068 
0069     if (viewName == QLatin1StringView("agenda")) {
0070         eventView = new AgendaView(start.date(), end.date(), true, false, this);
0071     } else if (viewName == QLatin1StringView("multiagenda")) {
0072         eventView = new MultiAgendaView(this);
0073     } else if (viewName == QLatin1StringView("month")) {
0074         eventView = new MonthView(MonthView::Visible, this);
0075     } else if (viewName == QLatin1StringView("timeline")) {
0076         eventView = new TimelineView(this);
0077     }
0078 
0079     if (eventView) {
0080         eventView->setPreferences(*mViewPreferences);
0081         eventView->setIncidenceChanger(mIncidenceChanger);
0082         eventView->updateConfig();
0083 
0084         for (const auto &calendar : mCalendars) {
0085             eventView->addCalendar(calendar);
0086         }
0087 
0088         eventView->setDateRange(start, end);
0089 
0090         mUi.tabWidget->addTab(eventView, viewName);
0091         mEventViews.push_back(eventView);
0092     } else {
0093         qCCritical(CALENDARVIEW_LOG) << "Cannot create view" << viewName;
0094     }
0095 }
0096 
0097 void MainWindow::delayedInit()
0098 {
0099     // create our application settings
0100     mSettings = new Settings;
0101 
0102     // create view preferences so that matching values are retrieved from
0103     // application settings
0104     mViewPreferences = new PrefsPtr(new Prefs(mSettings));
0105 
0106     mMonitor = new Akonadi::Monitor(this);
0107     for (const auto &mt : KCalendarCore::Incidence::mimeTypes()) {
0108         mMonitor->setMimeTypeMonitored(mt);
0109     }
0110     mMonitor->itemFetchScope().fetchFullPayload();
0111     mMonitor->itemFetchScope().setAncestorRetrieval(Akonadi::ItemFetchScope::Parent);
0112     mEtm = new Akonadi::EntityTreeModel(mMonitor, this);
0113 
0114     auto collectionProxy = new Akonadi::CollectionFilterProxyModel(mEtm);
0115     collectionProxy->addMimeTypeFilters(KCalendarCore::Incidence::mimeTypes());
0116     collectionProxy->setSourceModel(mEtm);
0117 
0118     auto selectionModel = new QItemSelectionModel(collectionProxy, mEtm);
0119 
0120     auto checkableProxy = new KCheckableProxyModel(mEtm);
0121     checkableProxy->setSourceModel(collectionProxy);
0122     checkableProxy->setSelectionModel(selectionModel);
0123 
0124     mUi.calendarView->setModel(checkableProxy);
0125 
0126     CalendarSupport::CollectionSelection *collectionSelection = new CalendarSupport::CollectionSelection(selectionModel, this);
0127     EventViews::EventView::setGlobalCollectionSelection(collectionSelection);
0128 
0129     connect(collectionSelection, &CalendarSupport::CollectionSelection::collectionSelected, this, &MainWindow::collectionSelected);
0130     connect(collectionSelection, &CalendarSupport::CollectionSelection::collectionDeselected, this, &MainWindow::collectionDeselected);
0131 
0132     for (const auto &collection : collectionSelection->selectedCollections()) {
0133         collectionSelected(collection);
0134     }
0135 
0136     mIncidenceChanger = new IncidenceChanger(this);
0137 
0138     for (const QString &viewName : std::as_const(mViewNames)) {
0139         addView(viewName);
0140     }
0141 }
0142 
0143 void MainWindow::addViewTriggered(QAction *action)
0144 {
0145     QString viewName = action->text().toLower();
0146     viewName.remove(QLatin1Char('&'));
0147     addView(viewName);
0148 }
0149 
0150 void MainWindow::collectionSelected(const Akonadi::Collection &col)
0151 {
0152     qDebug() << "Collection selected id=" << col.id() << "name=" << col.displayName();
0153     auto calendar = Akonadi::CollectionCalendar::Ptr::create(mEtm, col);
0154     mCalendars.push_back(calendar);
0155 
0156     for (auto view : mEventViews) {
0157         view->addCalendar(calendar);
0158         view->updateView();
0159     }
0160 }
0161 
0162 void MainWindow::collectionDeselected(const Akonadi::Collection &col)
0163 {
0164     qDebug() << "Collection deselected id=" << col.id() << "name=" << col.displayName();
0165     auto calendar = std::find_if(mCalendars.begin(), mCalendars.end(), [col](const auto &cal) {
0166         return cal->collection() == col;
0167     });
0168     if (calendar == mCalendars.cend()) {
0169         return;
0170     }
0171 
0172     const auto start = QDateTime::currentDateTime().addDays(-1);
0173     const auto end = QDateTime::currentDateTime().addDays(1);
0174 
0175     for (auto view : mEventViews) {
0176         view->removeCalendar(*calendar);
0177         view->updateView();
0178     }
0179 
0180     mCalendars.erase(calendar);
0181 }
0182 #include "moc_mainwindow.cpp"