diff options
Diffstat (limited to 'kalarm/eventlistviewbase.cpp')
-rw-r--r-- | kalarm/eventlistviewbase.cpp | 466 |
1 files changed, 466 insertions, 0 deletions
diff --git a/kalarm/eventlistviewbase.cpp b/kalarm/eventlistviewbase.cpp new file mode 100644 index 000000000..1a25e2ac0 --- /dev/null +++ b/kalarm/eventlistviewbase.cpp @@ -0,0 +1,466 @@ +/* + * eventlistviewbase.cpp - base classes for widget showing list of events + * Program: kalarm + * Copyright (c) 2004-2006 by David Jarvie <[email protected]> + * + * 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. + */ + +#include "kalarm.h" + +#include <qwhatsthis.h> +#include <qheader.h> + +#include <kiconloader.h> +#include <kdebug.h> + +#include "find.h" +#include "eventlistviewbase.moc" + + +class EventListWhatsThisBase : public QWhatsThis +{ + public: + EventListWhatsThisBase(EventListViewBase* lv) : QWhatsThis(lv), mListView(lv) { } + virtual QString text(const QPoint&); + private: + EventListViewBase* mListView; +}; + + +/*============================================================================= += Class: EventListViewBase += Base class for displaying a list of events. +=============================================================================*/ + +EventListViewBase::EventListViewBase(QWidget* parent, const char* name) + : KListView(parent, name), + mFind(0), + mLastColumn(-1), + mLastColumnHeaderWidth(0) +{ + setAllColumnsShowFocus(true); + setShowSortIndicator(true); + + new EventListWhatsThisBase(this); +} + +void EventListViewBase::addLastColumn(const QString& title) +{ + addColumn(title); + mLastColumn = columns() - 1; + mLastColumnHeaderWidth = columnWidth(mLastColumn); + setColumnWidthMode(mLastColumn, QListView::Maximum); +} + +/****************************************************************************** +* Refresh the list by clearing it and redisplaying all the current alarms. +*/ +void EventListViewBase::refresh() +{ + QString currentID; + if (currentItem()) + currentID = currentItem()->event().id(); // save current item for restoration afterwards + clear(); + populate(); + resizeLastColumn(); + EventListViewItemBase* current = getEntry(currentID); + if (current) + { + setCurrentItem(current); + ensureItemVisible(current); + } +} + +/****************************************************************************** +* Get the item for a given event ID. +*/ +EventListViewItemBase* EventListViewBase::getEntry(const QString& eventID) const +{ + if (!eventID.isEmpty()) + { + for (EventListViewItemBase* item = firstChild(); item; item = item->nextSibling()) + if (item->event().id() == eventID) + return item; + } + return 0; +} + +/****************************************************************************** +* Add an event to every list instance. +* If 'selectionView' is non-null, the selection highlight is moved to the new +* event in that listView instance. +*/ +void EventListViewBase::addEvent(const KAEvent& event, const InstanceList& instanceList, EventListViewBase* selectionView) +{ + for (InstanceListConstIterator it = instanceList.begin(); it != instanceList.end(); ++it) + (*it)->addEntry(event, true, (*it == selectionView)); +} + +/****************************************************************************** +* Modify an event in every list instance. +* If 'selectionView' is non-null, the selection highlight is moved to the +* modified event in that listView instance. +*/ +void EventListViewBase::modifyEvent(const QString& oldEventID, const KAEvent& newEvent, + const InstanceList& instanceList, EventListViewBase* selectionView) +{ + for (InstanceListConstIterator it = instanceList.begin(); it != instanceList.end(); ++it) + { + EventListViewBase* v = *it; + EventListViewItemBase* item = v->getEntry(oldEventID); + if (item) + v->deleteEntry(item, false); + v->addEntry(newEvent, true, (v == selectionView)); + } +} + +/****************************************************************************** +* Delete an event from every displayed list. +*/ +void EventListViewBase::deleteEvent(const QString& eventID, const InstanceList& instanceList) +{ + for (InstanceListConstIterator it = instanceList.begin(); it != instanceList.end(); ++it) + { + EventListViewBase* v = *it; + EventListViewItemBase* item = v->getEntry(eventID); + if (item) + v->deleteEntry(item, true); + else + v->refresh(); + } +} + +/****************************************************************************** +* Add a new item to the list. +* If 'reselect' is true, select/highlight the new item. +*/ +EventListViewItemBase* EventListViewBase::addEntry(const KAEvent& event, bool setSize, bool reselect) +{ + if (!shouldShowEvent(event)) + return 0; + return addEntry(createItem(event), setSize, reselect); +} + +EventListViewItemBase* EventListViewBase::addEntry(EventListViewItemBase* item, bool setSize, bool reselect) +{ + if (setSize) + resizeLastColumn(); + if (reselect) + { + clearSelection(); + setSelected(item, true); + } + return item; +} + +/****************************************************************************** +* Update a specified item in the list. +* If 'reselect' is true, select the updated item. +*/ +EventListViewItemBase* EventListViewBase::updateEntry(EventListViewItemBase* item, const KAEvent& newEvent, bool setSize, bool reselect) +{ + deleteEntry(item); + return addEntry(newEvent, setSize, reselect); +} + +/****************************************************************************** +* Delete a specified item from the list. +*/ +void EventListViewBase::deleteEntry(EventListViewItemBase* item, bool setSize) +{ + if (item) + { + delete item; + if (setSize) + resizeLastColumn(); + emit itemDeleted(); + } +} + +/****************************************************************************** +* Called when the Find action is selected. +* Display the non-modal Find dialog. +*/ +void EventListViewBase::slotFind() +{ + if (!mFind) + { + mFind = new Find(this); + connect(mFind, SIGNAL(active(bool)), SIGNAL(findActive(bool))); + } + mFind->display(); +} + +/****************************************************************************** +* Called when the Find Next or Find Prev action is selected. +*/ +void EventListViewBase::findNext(bool forward) +{ + if (mFind) + mFind->findNext(forward); +} + +/****************************************************************************** +* Called when the Select All action is selected. +* Select all items in the list. +*/ +void EventListViewBase::slotSelectAll() +{ + if (selectionMode() == QListView::Multi || selectionMode() == QListView::Extended) + selectAll(true); +} + +/****************************************************************************** +* Called when the Deselect action is selected. +* Deselect all items in the list. +*/ +void EventListViewBase::slotDeselect() +{ + selectAll(false); +} + +/****************************************************************************** +* Check whether there are any selected items. +*/ +bool EventListViewBase::anySelected() const +{ + for (QListViewItem* item = KListView::firstChild(); item; item = item->nextSibling()) + if (isSelected(item)) + return true; + return false; +} + +/****************************************************************************** +* Get the single selected event. +* Reply = the event +* = 0 if no event is selected or multiple events are selected. +*/ +const KAEvent* EventListViewBase::selectedEvent() const +{ + EventListViewItemBase* sel = selectedItem(); + return sel ? &sel->event() : 0; +} + +/****************************************************************************** +* Fetch the single selected item. +* This method works in both Single and Multi selection mode, unlike +* QListView::selectedItem(). +* Reply = null if no items are selected, or if multiple items are selected. +*/ +EventListViewItemBase* EventListViewBase::selectedItem() const +{ + if (selectionMode() == QListView::Single) + return (EventListViewItemBase*)KListView::selectedItem(); + + QListViewItem* item = 0; + for (QListViewItem* it = firstChild(); it; it = it->nextSibling()) + { + if (isSelected(it)) + { + if (item) + return 0; + item = it; + } + } + return (EventListViewItemBase*)item; +} + +/****************************************************************************** +* Fetch all selected items. +*/ +QValueList<EventListViewItemBase*> EventListViewBase::selectedItems() const +{ + QValueList<EventListViewItemBase*> items; + for (QListViewItem* item = firstChild(); item; item = item->nextSibling()) + { + if (isSelected(item)) + items.append((EventListViewItemBase*)item); + } + return items; +} + +/****************************************************************************** +* Return how many items are selected. +*/ +int EventListViewBase::selectedCount() const +{ + int count = 0; + for (QListViewItem* item = firstChild(); item; item = item->nextSibling()) + { + if (isSelected(item)) + ++count; + } + return count; +} + +/****************************************************************************** +* Sets the last column in the list view to extend at least to the right hand +* edge of the list view. +*/ +void EventListViewBase::resizeLastColumn() +{ + int lastColumnWidth = mLastColumnHeaderWidth; + for (EventListViewItemBase* item = firstChild(); item; item = item->nextSibling()) + { + int mw = item->lastColumnWidth(); + if (mw > lastColumnWidth) + lastColumnWidth = mw; + } + QHeader* head = header(); + int x = head->sectionPos(mLastColumn); + int availableWidth = visibleWidth() - x; + int rightColWidth = 0; + int index = head->mapToIndex(mLastColumn); + if (index < mLastColumn) + { + // The last column has been dragged by the user to a different position. + // Ensure that the columns now to the right of it are still shown. + for (int i = index + 1; i <= mLastColumn; ++i) + rightColWidth += columnWidth(head->mapToSection(i)); + availableWidth -= rightColWidth; + } + if (availableWidth < lastColumnWidth) + availableWidth = lastColumnWidth; + setColumnWidth(mLastColumn, availableWidth); + if (contentsWidth() > x + availableWidth + rightColWidth) + resizeContents(x + availableWidth + rightColWidth, contentsHeight()); +} + +/****************************************************************************** +* Called when the widget's size has changed (before it is painted). +* Sets the last column in the list view to extend at least to the right hand +* edge of the list view. +*/ +void EventListViewBase::resizeEvent(QResizeEvent* re) +{ + KListView::resizeEvent(re); + resizeLastColumn(); +} + +/****************************************************************************** +* Called when the widget is first displayed. +* Sets the last column in the list view to extend at least to the right hand +* edge of the list view. +*/ +void EventListViewBase::showEvent(QShowEvent* se) +{ + KListView::showEvent(se); + resizeLastColumn(); +} + +/****************************************************************************** +* Find the height of one list item. +*/ +int EventListViewBase::itemHeight() +{ + EventListViewItemBase* item = firstChild(); + if (!item) + { + // The list is empty, so create a temporary item to find its height + QListViewItem* item = new QListViewItem(this, QString::null); + int height = item->height(); + delete item; + return height; + } + else + return item->height(); +} + + +/*============================================================================= += Class: EventListViewItemBase += Base class containing the details of one event for display in an +* EventListViewBase. +=============================================================================*/ +QPixmap* EventListViewItemBase::mTextIcon; +QPixmap* EventListViewItemBase::mFileIcon; +QPixmap* EventListViewItemBase::mCommandIcon; +QPixmap* EventListViewItemBase::mEmailIcon; +int EventListViewItemBase::mIconWidth = 0; + + +EventListViewItemBase::EventListViewItemBase(EventListViewBase* parent, const KAEvent& event) + : QListViewItem(parent), + mEvent(event) +{ + iconWidth(); // load the icons +} + +/****************************************************************************** +* Set the text for the last column, and find its width. +*/ +void EventListViewItemBase::setLastColumnText() +{ + EventListViewBase* parent = (EventListViewBase*)listView(); + setText(parent->lastColumn(), lastColumnText()); + mLastColumnWidth = width(parent->fontMetrics(), parent, parent->lastColumn()); +} + +/****************************************************************************** +* Return the width of the widest alarm type icon. +*/ +int EventListViewItemBase::iconWidth() +{ + if (!mIconWidth) + { + mTextIcon = new QPixmap(SmallIcon("message")); + mFileIcon = new QPixmap(SmallIcon("file")); + mCommandIcon = new QPixmap(SmallIcon("exec")); + mEmailIcon = new QPixmap(SmallIcon("mail_generic")); + if (mTextIcon) + mIconWidth = mTextIcon->width(); + if (mFileIcon && mFileIcon->width() > mIconWidth) + mIconWidth = mFileIcon->width(); + if (mCommandIcon && mCommandIcon->width() > mIconWidth) + mIconWidth = mCommandIcon->width(); + if (mEmailIcon && mEmailIcon->width() > mIconWidth) + mIconWidth = mEmailIcon->width(); + } + return mIconWidth; +} + +/****************************************************************************** +* Return the icon associated with the event's action. +*/ +QPixmap* EventListViewItemBase::eventIcon() const +{ + switch (mEvent.action()) + { + case KAAlarm::FILE: return mFileIcon; + case KAAlarm::COMMAND: return mCommandIcon; + case KAAlarm::EMAIL: return mEmailIcon; + case KAAlarm::MESSAGE: + default: return mTextIcon; + } +} + + +/*============================================================================= += Class: EventListWhatsThisBase += Sets What's This? text depending on where in the list view is clicked. +=============================================================================*/ + +QString EventListWhatsThisBase::text(const QPoint& pt) +{ + int column = -1; + QPoint viewportPt = mListView->viewport()->mapFrom(mListView, pt); + QRect frame = mListView->header()->frameGeometry(); + if (frame.contains(pt) + || mListView->itemAt(QPoint(mListView->itemMargin(), viewportPt.y())) && frame.contains(QPoint(pt.x(), frame.y()))) + column = mListView->header()->sectionAt(pt.x()); + return mListView->whatsThisText(column); +} + |