/* This file is part of KOrganizer. Copyright (c) 2001 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 KOAGENDA_H #define KOAGENDA_H #include #include #include #include class QPopupMenu; class QTime; class QLabel; class KConfig; class KOAgenda; class KOAgendaItem; using namespace KOrg; namespace KOrg { class IncidenceChangerBase; } using namespace KCal; namespace KCal { class Event; class Todo; class Calendar; } class MarcusBains : public QFrame { Q_OBJECT public: MarcusBains( KOAgenda *agenda = 0, const char *name = 0 ); virtual ~MarcusBains(); public slots: void updateLocation( bool recalculate = false ); private: int todayColumn(); QTimer *minutes; QLabel *mTimeBox; KOAgenda *agenda; QTime oldTime; int oldToday; }; class KOAgenda : public QScrollView { Q_OBJECT public: KOAgenda ( int columns, int rows, int columnSize, QWidget *parent=0, const char *name = 0, WFlags f = 0 ); KOAgenda ( int columns, QWidget *parent = 0, const char *name = 0, WFlags f = 0 ); virtual ~KOAgenda(); Incidence *selectedIncidence() const; QDate selectedIncidenceDate() const; /** * Returns the uid of the last incidence that was selected. This * persists across reloads and clear, so that if the same uid * reappears, it can be reselected. */ const QString lastSelectedUid() const; virtual bool eventFilter ( QObject *, QEvent * ); QPoint contentsToGrid ( const QPoint &pos ) const; QPoint gridToContents ( const QPoint &gpos ) const; int timeToY ( const QTime &time ); QTime gyToTime ( int y ); QMemArray minContentsY(); QMemArray maxContentsY(); int visibleContentsYMin(); int visibleContentsYMax(); void setStartTime( const QTime &startHour ); KOAgendaItem *insertItem ( Incidence *incidence, const QDate &qd, int X, int YTop, int YBottom ); KOAgendaItem *insertAllDayItem ( Incidence *event, const QDate &qd, int XBegin, int XEnd ); void insertMultiItem ( Event *event, const QDate &qd, int XBegin, int XEnd, int YTop, int YBottom ); /** remove an event and all its multi-items from the agenda. * This function removes the items from the view, but doesn't delete them immediately. * Instead, they are queued in mItemsToDelete and later deleted by * the slot deleteItemsToDelete() (called by QTimer::singleShot ) */ void removeIncidence( Incidence *incidence ); void changeColumns( int columns ); int columns() { return mColumns; } int rows() { return mRows; } double gridSpacingX() const { return mGridSpacingX; } double gridSpacingY() const { return mGridSpacingY; } // virtual QSizePolicy sizePolicy() const; void clear(); /** Calculates the minimum width */ virtual int minimumWidth() const; /** Update configuration from preference settings */ void updateConfig(); void checkScrollBoundaries(); void setHolidayMask( QMemArray * ); void setDateList( const DateList &selectedDates ); DateList dateList() const; void setTypeAheadReceiver( QObject * ); QObject *typeAheadReceiver() const; void finishTypeAhead(); void setCalendar( Calendar*cal ) { mCalendar = cal; } void setIncidenceChanger( IncidenceChangerBase *changer ) { mChanger = changer; } public slots: void scrollUp(); void scrollDown(); void checkScrollBoundaries( int ); /** Deselect selected items. This function does not emit any signals. */ void deselectItem(); void clearSelection(); /** Select item. If the argument is 0, the currently selected item gets deselected. This function emits the itemSelected(bool) signal to inform about selection/deselection of events. */ void selectItem( KOAgendaItem * ); /** Select the item associated with a given uid. Linear search, use carefully. */ void selectItemByUID( const QString& uid ); bool removeAgendaItem( KOAgendaItem *item ); void showAgendaItem( KOAgendaItem *item ); signals: void newEventSignal(); void newTimeSpanSignal( const QPoint &, const QPoint & ); void newStartSelectSignal(); void showIncidenceSignal( Incidence * ); void editIncidenceSignal( Incidence * ); void deleteIncidenceSignal( Incidence * ); void showIncidencePopupSignal( Incidence *, const QDate &); void showNewEventPopupSignal(); void itemModified( KOAgendaItem *item ); void incidenceSelected( Incidence * ); void startMultiModify( const QString & ); void endMultiModify(); void lowerYChanged( int ); void upperYChanged( int ); void startDragSignal(Incidence *); void droppedToDo( Todo*todo, const QPoint &gpos, bool allDay ); void enableAgendaUpdate( bool enable ); void zoomView( const int delta, const QPoint &pos, const Qt::Orientation ); void mousePosSignal(const QPoint &pos); void enterAgenda(); void leaveAgenda(); void gridSpacingYChanged( double ); private: enum MouseActionType { NOP, MOVE, SELECT, RESIZETOP, RESIZEBOTTOM, RESIZELEFT, RESIZERIGHT }; protected: void drawContents( QPainter *p, int cx, int cy, int cw, int ch ); int columnWidth( int column ); virtual void resizeEvent ( QResizeEvent * ); /** Handles mouse events. Called from eventFilter */ virtual bool eventFilter_mouse ( QObject *, QMouseEvent * ); #ifndef QT_NO_WHEELEVENT /** Handles mousewheel events. Called from eventFilter */ virtual bool eventFilter_wheel ( QObject *, QWheelEvent * ); #endif /** Handles key events. Called from eventFilter */ virtual bool eventFilter_key ( QObject *, QKeyEvent * ); /** Handles drag and drop events. Called from eventFilter */ virtual bool eventFilter_drag( QObject *, QDropEvent * ); /** returns RESIZELEFT if pos is near the lower edge of the action item, RESIZERIGHT if pos is near the higher edge, and MOVE otherwise. If --reverse is used, RESIZELEFT still means resizing the beginning of the event, although that means moving to the right! horizontal is the same as mAllDayAgenda. */ MouseActionType isInResizeArea( bool horizontal, const QPoint &pos, KOAgendaItem *item ); /** Return whether the cell specified by the grid point belongs to the current select */ bool ptInSelection( QPoint gpos ) const; /** Start selecting time span. */ void startSelectAction( const QPoint &viewportPos ); /** Select time span. */ void performSelectAction( const QPoint &viewportPos ); /** Emd selecting time span. */ void endSelectAction( const QPoint &viewportPos ); /** Start moving/resizing agenda item */ void startItemAction(const QPoint& viewportPos); /** Move/resize agenda item */ void performItemAction(const QPoint& viewportPos); /** End moving/resizing agenda item */ void endItemAction(); /** Set cursor, when no item action is in progress */ void setNoActionCursor( KOAgendaItem *moveItem, const QPoint &viewportPos ); /** Sets the cursor according to the given action type. If acting==true, the corresponding action is running (i.e. the item is really moved). If acting==false the cursor should just indicate that the corresponding action is possible */ void setActionCursor( int actionType, bool acting=false ); /** calculate the width of the column subcells of the given item */ double calcSubCellWidth( KOAgendaItem *item ); /** Move and resize the given item to the correct position */ void placeAgendaItem( KOAgendaItem *item, double subCellWidth ); /** Place agenda item in agenda and adjust other cells if necessary */ void placeSubCells( KOAgendaItem *placeItem ); /** Place the agenda item at the correct position (ignoring conflicting items) */ void adjustItemPosition( KOAgendaItem *item ); /** Process the keyevent, including the ignored keyevents of eventwidgets. * Implements pgup/pgdn and cursor key navigation in the view. */ void keyPressEvent( QKeyEvent * ); void calculateWorkingHours(); virtual void contentsMousePressEvent ( QMouseEvent * ); void emitNewEventForSelection(); protected slots: /** delete the items that are queued for deletion */ void deleteItemsToDelete(); /** Resizes all the child elements after the size of the agenda changed. This is needed because Qt seems to have a bug when the resizeEvent of one of the widgets in a splitter takes a lot of time / does a lot of resizes.... see bug 80114 */ void resizeAllContents(); private: void init(); void marcus_bains(); bool mAllDayMode; // We need the calendar for drag'n'drop and for paint the ResourceColor Calendar *mCalendar; // Width and height of agenda cells. mDesiredGridSpacingY is the height // set in the config. The actual height might be larger since otherwise // more than 24 hours might be displayed. double mGridSpacingX; double mGridSpacingY; double mDesiredGridSpacingY; // size of border, where mouse action will resize the KOAgendaItem int mResizeBorderWidth; // size of border, where mouse mve will cause a scroll of the agenda int mScrollBorderWidth; int mScrollDelay; int mScrollOffset; QTimer mScrollUpTimer; QTimer mScrollDownTimer; // Number of Columns/Rows of agenda grid int mColumns; int mRows; // Cells to store Move and Resize coordiantes while performing the action QPoint mStartCell; QPoint mEndCell; // Working Hour coordiantes bool mWorkingHoursEnable; QMemArray *mHolidayMask; int mWorkingHoursYTop; int mWorkingHoursYBottom; // Selection bool mHasSelection; QPoint mSelectionStartPoint; QPoint mSelectionStartCell; QPoint mSelectionEndCell; // List of dates to be displayed DateList mSelectedDates; // The KOAgendaItem, which has been right-clicked last QGuardedPtr mClickedItem; // The KOAgendaItem, which is being moved/resized QGuardedPtr mActionItem; // Currently selected item QGuardedPtr mSelectedItem; // Uid of the last selected item. Used for reselecting in situations // where the selected item points to a no longer valid incidence, for // example during resource reload. QString mSelectedUid; // The Marcus Bains Line widget. MarcusBains *mMarcusBains; MouseActionType mActionType; bool mItemMoved; // List of all Items contained in agenda QPtrList mItems; QPtrList mItemsToDelete; QPopupMenu *mItemPopup; // Right mouse button popup menu for KOAgendaItems int mOldLowerScrollValue; int mOldUpperScrollValue; bool mTypeAhead; QObject *mTypeAheadReceiver; QPtrList mTypeAheadEvents; bool mReturnPressed; KOrg::IncidenceChangerBase *mChanger; }; #endif // KOAGENDA_H