summaryrefslogtreecommitdiffabout
path: root/korganizer
Side-by-side diff
Diffstat (limited to 'korganizer') (more/less context) (ignore whitespace changes)
-rw-r--r--korganizer/koagenda.cpp195
-rw-r--r--korganizer/koagenda.h6
-rw-r--r--korganizer/koagendaitem.cpp2
-rw-r--r--korganizer/koagendaview.cpp14
-rw-r--r--korganizer/koagendaview.h1
-rw-r--r--korganizer/kolistview.cpp55
-rw-r--r--korganizer/kolistview.h7
7 files changed, 259 insertions, 21 deletions
diff --git a/korganizer/koagenda.cpp b/korganizer/koagenda.cpp
index 66ad4ec..14f52b8 100644
--- a/korganizer/koagenda.cpp
+++ b/korganizer/koagenda.cpp
@@ -1,657 +1,842 @@
/*
This file is part of KOrganizer.
Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
Marcus Bains line.
Copyright (c) 2001 Ali Rahimi
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 _WIN32_
#define protected public
#include <qwidget.h>
#undef protected
#endif
#include <qintdict.h>
#include <qdatetime.h>
#include <qapplication.h>
#include <qpopupmenu.h>
#include <qcursor.h>
#include <qpainter.h>
#include <kdebug.h>
#include <klocale.h>
#include <kiconloader.h>
#include <kglobal.h>
#include "koagendaitem.h"
#include "koprefs.h"
#include "koglobals.h"
#include "koagenda.h"
#include <libkcal/event.h>
#include <libkcal/todo.h>
#ifndef DESKTOP_VERSION
#include <qpe/qpeapplication.h>
#endif
//extern bool globalFlagBlockPainting;
extern int globalFlagBlockAgenda;
extern int globalFlagBlockAgendaItemPaint;
extern int globalFlagBlockAgendaItemUpdate;
extern int globalFlagBlockStartup;
////////////////////////////////////////////////////////////////////////////
MarcusBains::MarcusBains(KOAgenda *_agenda,const char *name)
: QFrame(_agenda->viewport(),name), agenda(_agenda)
{
setLineWidth(0);
setMargin(0);
setBackgroundColor(Qt::red);
minutes = new QTimer(this);
connect(minutes, SIGNAL(timeout()), this, SLOT(updateLoc()));
minutes->start(0, true);
-
mTimeBox = new QLabel(this);
mTimeBox->setAlignment(Qt::AlignRight | Qt::AlignBottom);
QPalette pal = mTimeBox->palette();
pal.setColor(QColorGroup::Foreground, Qt::red);
mTimeBox->setPalette(pal);
//mTimeBox->setAutoMask(true);
agenda->addChild(mTimeBox);
oldToday = -1;
}
MarcusBains::~MarcusBains()
{
delete minutes;
}
int MarcusBains::todayColumn()
{
QDate currentDate = QDate::currentDate();
DateList dateList = agenda->dateList();
DateList::ConstIterator it;
int col = 0;
for(it = dateList.begin(); it != dateList.end(); ++it) {
if((*it) == currentDate)
return KOGlobals::self()->reverseLayout() ?
agenda->columns() - 1 - col : col;
++col;
}
return -1;
}
void MarcusBains::updateLoc()
{
updateLocation();
}
void MarcusBains::updateLocation(bool recalculate)
{
QTime tim = QTime::currentTime();
//qDebug(" MarcusBains::updateLocation %s ", tim.toString().latin1());
if((tim.hour() == 0) && (oldTime.hour()==23))
recalculate = true;
int mins = tim.hour()*60 + tim.minute();
int minutesPerCell = 24 * 60 / agenda->rows();
int y = mins*agenda->gridSpacingY()/minutesPerCell;
int today = recalculate ? todayColumn() : oldToday;
int x = agenda->gridSpacingX()*today;
bool disabled = !(KOPrefs::instance()->mMarcusBainsEnabled);
oldTime = tim;
oldToday = today;
if(disabled || (today<0)) {
hide(); mTimeBox->hide();
return;
} else {
show(); mTimeBox->show();
}
if(recalculate)
setFixedSize(agenda->gridSpacingX(),1);
agenda->moveChild(this, x, y);
raise();
if(recalculate)
//mTimeBox->setFont(QFont("helvetica",10));
mTimeBox->setFont(KOPrefs::instance()->mMarcusBainsFont);
mTimeBox->setText(KGlobal::locale()->formatTime(tim, KOPrefs::instance()->mMarcusBainsShowSeconds));
mTimeBox->adjustSize();
// the -2 below is there because there is a bug in this program
// somewhere, where the last column of this widget is a few pixels
// narrower than the other columns.
int offs = (today==agenda->columns()-1) ? -4 : 0;
agenda->moveChild(mTimeBox,
x+agenda->gridSpacingX()-mTimeBox->width()+offs-1,
y-mTimeBox->height());
mTimeBox->raise();
//mTimeBox->setAutoMask(true);
minutes->start(5000,true);
}
////////////////////////////////////////////////////////////////////////////
/*
Create an agenda widget with rows rows and columns columns.
*/
KOAgenda::KOAgenda(int columns,int rows,int rowSize,QWidget *parent,
const char *name,WFlags f) :
QScrollView(parent,name,f)
{
mColumns = columns;
mRows = rows;
mGridSpacingY = rowSize;
mAllDayMode = false;
#ifndef DESKTOP_VERSION
- QPEApplication::setStylusOperation( viewport(), QPEApplication::RightOnHold );
+ //QPEApplication::setStylusOperation( viewport(), QPEApplication::RightOnHold );
#endif
mHolidayMask = 0;
init();
}
/*
Create an agenda widget with columns columns and one row. This is used for
all-day events.
*/
KOAgenda::KOAgenda(int columns,QWidget *parent,const char *name,WFlags f) :
QScrollView(parent,name,f)
{
blockResize = false;
mColumns = columns;
mRows = 1;
//qDebug("aaaaaaaaaaaaaaaaaaldays %d ", KOPrefs::instance()->mAllDaySize);
mGridSpacingY = KOPrefs::instance()->mAllDaySize;
mAllDayMode = true;
#ifndef DESKTOP_VERSION
- QPEApplication::setStylusOperation( viewport(), QPEApplication::RightOnHold );
+ //QPEApplication::setStylusOperation( viewport(), QPEApplication::RightOnHold );
#endif
mHolidayMask = 0;
init();
}
KOAgenda::~KOAgenda()
{
if(mMarcusBains) delete mMarcusBains;
}
Incidence *KOAgenda::selectedIncidence() const
{
return (mSelectedItem ? mSelectedItem->incidence() : 0);
}
QDate KOAgenda::selectedIncidenceDate() const
{
return (mSelectedItem ? mSelectedItem->itemDate() : QDate());
}
void KOAgenda::init()
{
+ mPopupTimer = new QTimer(this);
+ connect(mPopupTimer , SIGNAL(timeout()), this, SLOT(popupMenu()));
+
mNewItemPopup = new QPopupMenu( this );
connect ( mNewItemPopup, SIGNAL (activated ( int ) ), this, SLOT ( newItem(int)) );
QString pathString = "";
if ( !KOPrefs::instance()->mToolBarMiniIcons ) {
if ( QApplication::desktop()->width() < 480 )
pathString += "icons16/";
} else
pathString += "iconsmini/";
mNewItemPopup->insertItem ( SmallIcon( pathString +"newevent" ), i18n("New Event..."), 1 );
mNewItemPopup->insertItem ( SmallIcon( pathString +"newtodo" ), i18n("New Todo..."),2 );
mNewItemPopup->insertSeparator ( );
mNewItemPopup->insertItem ( SmallIcon( pathString +"day" ), i18n("Day view"),3 );
mNewItemPopup->insertItem ( SmallIcon( pathString +"xdays" ), i18n("Next days"),8 );
mNewItemPopup->insertItem ( SmallIcon( pathString +"week" ), i18n("Next week"),4 );
mNewItemPopup->insertItem ( SmallIcon( pathString +"week" ), i18n("Next two weeks"),5 );
mNewItemPopup->insertItem ( SmallIcon( pathString +"month" ), i18n("Next month"),6 );
mNewItemPopup->insertItem ( SmallIcon( pathString +"journal" ), i18n("Journal view"),7 );
#ifndef _WIN32_
int wflags = viewport()-> getWFlags() |WRepaintNoErase;//WResizeNoErase
viewport()->setWFlags ( wflags);
#endif
mGridSpacingX = 80;
mResizeBorderWidth = 8;
mScrollBorderWidth = 8;
mScrollDelay = 30;
mScrollOffset = 10;
mPaintPixmap.resize( 20,20);
//enableClipper(true);
// Grab key strokes for keyboard navigation of agenda. Seems to have no
// effect. Has to be fixed.
setFocusPolicy(WheelFocus);
connect(&mScrollUpTimer,SIGNAL(timeout()),SLOT(scrollUp()));
connect(&mScrollDownTimer,SIGNAL(timeout()),SLOT(scrollDown()));
connect(&mResizeTimer,SIGNAL(timeout()),SLOT(finishResize()));
mStartCellX = 0;
mStartCellY = 0;
mCurrentCellX = 0;
mCurrentCellY = 0;
mSelectionCellX = 0;
mSelectionYTop = 0;
mSelectionHeight = 0;
mOldLowerScrollValue = -1;
mOldUpperScrollValue = -1;
mClickedItem = 0;
mActionItem = 0;
mActionType = NOP;
mItemMoved = false;
mSelectedItem = 0;
// mItems.setAutoDelete(true);
resizeContents( mGridSpacingX * mColumns + 1 , mGridSpacingY * mRows + 1 );
viewport()->update();
setMinimumSize(30, 1);
// setMaximumHeight(mGridSpacingY * mRows + 5);
// Disable horizontal scrollbar. This is a hack. The geometry should be
// controlled in a way that the contents horizontally always fits. Then it is
// not necessary to turn off the scrollbar.
setHScrollBarMode(AlwaysOff);
if ( ! mAllDayMode )
setVScrollBarMode(AlwaysOn);
else
setVScrollBarMode(AlwaysOff);
setStartHour(KOPrefs::instance()->mDayBegins);
calculateWorkingHours();
connect(verticalScrollBar(),SIGNAL(valueChanged(int)),
SLOT(checkScrollBoundaries(int)));
// Create the Marcus Bains line.
if(mAllDayMode)
mMarcusBains = 0;
else {
mMarcusBains = new MarcusBains(this);
addChild(mMarcusBains);
- }
+ }
+ mPopupKind = 0;
+ mPopupItem = 0;
}
void KOAgenda::clear()
{
KOAgendaItem *item;
for ( item=mItems.first(); item != 0; item=mItems.next() ) {
mUnusedItems.append( item );
//item->hide();
}
mItems.clear();
mSelectedItem = 0;
clearSelection();
}
void KOAgenda::clearSelection()
{
mSelectionCellX = 0;
mSelectionYTop = 0;
mSelectionHeight = 0;
}
void KOAgenda::marcus_bains()
{
if(mMarcusBains) mMarcusBains->updateLocation(true);
}
void KOAgenda::changeColumns(int columns)
{
if (columns == 0) {
kdDebug() << "KOAgenda::changeColumns() called with argument 0" << endl;
return;
}
clear();
mColumns = columns;
// setMinimumSize(mColumns * 10, mGridSpacingY + 1);
// init();
// update();
//qDebug("KOAgenda::changeColumns ");
computeSizes();
// QResizeEvent event( size(), size() );
//QApplication::sendEvent( this, &event );
}
/*
This is the eventFilter function, which gets all events from the KOAgendaItems
contained in the agenda. It has to handle moving and resizing for all items.
*/
bool KOAgenda::eventFilter ( QObject *object, QEvent *event )
{
// kdDebug() << "KOAgenda::eventFilter" << endl;
switch(event->type()) {
case QEvent::MouseButtonPress:
case QEvent::MouseButtonDblClick:
case QEvent::MouseButtonRelease:
case QEvent::MouseMove:
return eventFilter_mouse(object, static_cast<QMouseEvent *>(event));
case (QEvent::Leave):
if (!mActionItem)
setCursor(arrowCursor);
return true;
default:
return QScrollView::eventFilter(object,event);
}
}
-
+void KOAgenda::popupMenu()
+{
+ mPopupTimer->stop();
+ if ( mPopupKind == 1 ) {
+ if (mActionItem ) {
+ endItemAction();
+ }
+ mLeftMouseDown = false; // no more leftMouse computation
+ if (mPopupItem) {
+ selectItem(mPopupItem);
+ emit showIncidencePopupSignal(mPopupItem->incidence());
+
+ }
+ } else if ( mPopupKind == 2 ) {
+ if ( mLeftMouseDown ) { // we have a simulated right click - clear left mouse action
+ endSelectAction( false ); // do not emit new event signal
+ mLeftMouseDown = false; // no more leftMouse computation
+ }
+ mNewItemPopup->popup( mPopupPos);
+ }
+ mLeftMouseDown = false;
+ mPopupItem = 0;
+ mPopupKind = 0;
+}
bool KOAgenda::eventFilter_mouse(QObject *object, QMouseEvent *me)
{
+ //qDebug("KOAgenda::eventFilter_mous ");
+ QPoint viewportPos;
+ if (object != viewport()) {
+ viewportPos = ((QWidget *)object)->mapToParent(me->pos());
+ } else {
+ viewportPos = me->pos();
+ }
+ static int startX = 0;
+ static int startY = 0;
+ static int blockmoveDist = ( QApplication::desktop()->width() < 480 ? 15 : 20 );
+ static bool blockMoving = true;
+ switch (me->type()) {
+ case QEvent::MouseButtonPress:
+ if (me->button() == LeftButton) {
+ mPopupTimer->start( 600 );
+ mLeftMouseDown = true;
+ }
+ blockMoving = true;
+ startX = viewportPos.x();
+ startY = viewportPos.y();
+ if (object != viewport()) {
+ mPopupItem = (KOAgendaItem *)object;
+ mPopupKind = 1;
+ if (me->button() == RightButton) {
+ popupMenu();
+ } else if (me->button() == LeftButton) {
+ mActionItem = (KOAgendaItem *)object;
+ if (mActionItem) {
+ if ( mSelectionHeight > 0 ) {
+ int selectionCellX = mSelectionCellX * mGridSpacingX;
+ int selectionYTop = mSelectionYTop;
+ int gridSpacingX = mGridSpacingX;
+ int selectionHeight = mSelectionHeight;
+ clearSelection();
+ repaintContents( selectionCellX, selectionYTop,
+ gridSpacingX, selectionHeight,false );
+ }
+ selectItem(mActionItem);
+ Incidence *incidence = mActionItem->incidence();
+ if ( incidence->isReadOnly() /*|| incidence->recurrence()->doesRecur() */) {
+ mActionItem = 0;
+ } else {
+ startItemAction(viewportPos);
+ }
+ }
+ }
+ } else { // ---------- viewport()
+ mPopupItem = 0;
+ mPopupKind = 2;
+ selectItem(0);
+ mActionItem = 0;
+ mPopupPos = viewport()->mapToGlobal( me->pos() );
+ if (me->button() == RightButton) {
+ popupMenu();
+ } else if (me->button() == LeftButton) {
+ setCursor(arrowCursor);
+ startSelectAction(viewportPos);
+ }
+ }
+ break;
+
+ case QEvent::MouseButtonRelease:
+ if (me->button() == LeftButton ) {
+ mPopupTimer->stop();
+ }
+ if (object != viewport()) {
+ if (me->button() == LeftButton && mLeftMouseDown) {
+ if (mActionItem) {
+ QPoint clipperPos = clipper()->mapFromGlobal(viewport()->mapToGlobal(viewportPos));
+ //qDebug(" %d %d %d ",clipperPos.y(),visibleHeight() , 9 );
+ if ( mActionType == MOVE && (clipperPos.y() > visibleHeight()-2 ||clipperPos.y() < 0 ) ) {
+ mScrollUpTimer.stop();
+ mScrollDownTimer.stop();
+ mActionItem->resetMove();
+ placeSubCells( mActionItem );
+ // emit startDragSignal( mActionItem->incidence() );
+ setCursor( arrowCursor );
+ mActionItem = 0;
+ mActionType = NOP;
+ mItemMoved = 0;
+ mLeftMouseDown = false;
+ return true;
+ }
+ endItemAction();
+ }
+ }
+
+ } else { // ---------- viewport()
+ if (me->button() == LeftButton && mLeftMouseDown ) { //left click
+ endSelectAction( true ); // emit new event signal
+ }
+ }
+ if (me->button() == LeftButton)
+ mLeftMouseDown = false;
+
+ break;
+
+ case QEvent::MouseMove:
+ if ( !mLeftMouseDown )
+ return true;
+ if ( blockMoving ) {
+ int dX, dY;
+ dX = startX - viewportPos.x();
+ if ( dX < 0 )
+ dX = -dX;
+ dY = viewportPos.y() - startY;
+ if ( dY < 0 )
+ dY = -dY;
+ //qDebug("%d %d %d ", dX, dY , blockmoveDist );
+ if ( dX > blockmoveDist || dY > blockmoveDist ) {
+ blockMoving = false;
+ }
+ }
+ if ( ! blockMoving )
+ mPopupTimer->stop();
+ if (object != viewport()) {
+ KOAgendaItem *moveItem = (KOAgendaItem *)object;
+ if (!moveItem->incidence()->isReadOnly() ) {
+ if (!mActionItem)
+ setNoActionCursor(moveItem,viewportPos);
+ else {
+ if ( !blockMoving )
+ performItemAction(viewportPos);
+ }
+ }
+ } else { // ---------- viewport()
+ mPopupPos = viewport()->mapToGlobal( me->pos() );
+ if ( mActionType == SELECT ) {
+ performSelectAction( viewportPos );
+ }
+ }
+ break;
+
+ case QEvent::MouseButtonDblClick:
+ mPopupTimer->stop();
+ if (object == viewport()) {
+ selectItem(0);
+ int x,y;
+ viewportToContents(viewportPos.x(),viewportPos.y(),x,y);
+ int gx,gy;
+ contentsToGrid(x,y,gx,gy);
+ emit newEventSignal(gx,gy);
+ } else {
+ KOAgendaItem *doubleClickedItem = (KOAgendaItem *)object;
+ selectItem(doubleClickedItem);
+ if ( KOPrefs::instance()->mEditOnDoubleClick )
+ emit editIncidenceSignal(doubleClickedItem->incidence());
+ else
+ emit showIncidenceSignal(doubleClickedItem->incidence());
+ }
+ break;
+
+ default:
+ break;
+ }
+ return true;
+#if 0
//qDebug("KOAgenda::eventFilter_mous ");
QPoint viewportPos;
if (object != viewport()) {
viewportPos = ((QWidget *)object)->mapToParent(me->pos());
} else {
viewportPos = me->pos();
}
static int startX = 0;
static int startY = 0;
static int blockmoveDist = ( QApplication::desktop()->width() < 480 ? 15 : 20 );
static bool blockMoving = true;
static bool leftMouseDown = false;
bool rightButtonPressed = false;
switch (me->type()) {
case QEvent::MouseButtonPress:
if (me->button() == LeftButton) {
leftMouseDown = true;
}
else if (me->button() == RightButton) {
leftMouseDown = false;
}
blockMoving = true;
startX = viewportPos.x();
startY = viewportPos.y();
if (object != viewport()) { // item clicked **************
if (me->button() == RightButton) {
leftMouseDown = false;
mClickedItem = (KOAgendaItem *)object;
if (mActionItem ) {
endItemAction();
}
if (mClickedItem) {
selectItem(mClickedItem);
emit showIncidencePopupSignal(mClickedItem->incidence());
}
return true;
} else if (me->button() == LeftButton) {
mActionItem = (KOAgendaItem *)object;
if (mActionItem) {
if ( mSelectionHeight > 0 ) {
int selectionCellX = mSelectionCellX * mGridSpacingX;
int selectionYTop = mSelectionYTop;
int gridSpacingX = mGridSpacingX;
int selectionHeight = mSelectionHeight;
clearSelection();
repaintContents( selectionCellX, selectionYTop,
gridSpacingX, selectionHeight,false );
}
selectItem(mActionItem);
Incidence *incidence = mActionItem->incidence();
if ( incidence->isReadOnly() /*|| incidence->recurrence()->doesRecur() */) {
mActionItem = 0;
} else {
startItemAction(viewportPos);
}
}
}
} else { // ---------- viewport()
selectItem(0);
mActionItem = 0;
if (me->button() == LeftButton ) {
setCursor(arrowCursor);
startSelectAction(viewportPos);
} else if (me->button() == RightButton ) {
setCursor(arrowCursor);
if ( leftMouseDown ) { // we have a simulated right click - clear left mouse action
endSelectAction( false ); // do not emit new event signal
leftMouseDown = false; // no more leftMouse computation
}
int x,y;
viewportToContents(viewportPos.x(),viewportPos.y(),x,y);
int gx,gy;
contentsToGrid(x,y,gx,gy);
mCurrentCellX = gx;
mCurrentCellY = gy;
mStartCellX = gx;
mStartCellY = gy;
mNewItemPopup->popup( viewport()->mapToGlobal( me->pos() ) );
}
}
break;
case QEvent::MouseButtonRelease:
if (object != viewport()) {
if (me->button() == LeftButton && leftMouseDown) {
if (mActionItem) {
QPoint clipperPos = clipper()->mapFromGlobal(viewport()->mapToGlobal(viewportPos));
//qDebug(" %d %d %d ",clipperPos.y(),visibleHeight() , 9 );
if ( mActionType == MOVE && (clipperPos.y() > visibleHeight()-2 ||clipperPos.y() < 0 ) ) {
mScrollUpTimer.stop();
mScrollDownTimer.stop();
mActionItem->resetMove();
placeSubCells( mActionItem );
// emit startDragSignal( mActionItem->incidence() );
setCursor( arrowCursor );
mActionItem = 0;
mActionType = NOP;
mItemMoved = 0;
leftMouseDown = false;
return true;
}
endItemAction();
}
}
} else { // ---------- viewport()
if (me->button() == LeftButton && leftMouseDown ) { //left click
endSelectAction( true ); // emit new event signal
}
}
if (me->button() == LeftButton)
leftMouseDown = false;
break;
case QEvent::MouseMove:
if ( !leftMouseDown )
return true;
if ( blockMoving ) {
int dX, dY;
dX = startX - viewportPos.x();
if ( dX < 0 )
dX = -dX;
dY = viewportPos.y() - startY;
if ( dY < 0 )
dY = -dY;
//qDebug("%d %d %d ", dX, dY , blockmoveDist );
if ( dX > blockmoveDist || dY > blockmoveDist ) {
blockMoving = false;
}
}
if (object != viewport()) {
KOAgendaItem *moveItem = (KOAgendaItem *)object;
if (!moveItem->incidence()->isReadOnly() ) {
if (!mActionItem)
setNoActionCursor(moveItem,viewportPos);
else {
if ( !blockMoving )
performItemAction(viewportPos);
}
}
} else { // ---------- viewport()
if ( mActionType == SELECT ) {
performSelectAction( viewportPos );
}
}
break;
case QEvent::MouseButtonDblClick:
blockMoving = false;
leftMouseDown = false;
if (object == viewport()) {
selectItem(0);
int x,y;
viewportToContents(viewportPos.x(),viewportPos.y(),x,y);
int gx,gy;
contentsToGrid(x,y,gx,gy);
emit newEventSignal(gx,gy);
} else {
KOAgendaItem *doubleClickedItem = (KOAgendaItem *)object;
selectItem(doubleClickedItem);
if ( KOPrefs::instance()->mEditOnDoubleClick )
emit editIncidenceSignal(doubleClickedItem->incidence());
else
emit showIncidenceSignal(doubleClickedItem->incidence());
}
break;
default:
break;
}
return true;
+#endif
}
void KOAgenda::newItem( int item )
{
if ( item == 1 ) { //new event
newEventSignal(mStartCellX ,mStartCellY );
} else
if ( item == 2 ) { //new event
newTodoSignal(mStartCellX ,mStartCellY );
} else
{
QDate day = mSelectedDates[mStartCellX];
emit showDateView( item, day );
// 3Day view
// 4Week view
// 5Month view
// 6Journal view
}
}
void KOAgenda::startSelectAction(QPoint viewportPos)
{
//emit newStartSelectSignal();
mActionType = SELECT;
int x,y;
viewportToContents(viewportPos.x(),viewportPos.y(),x,y);
int gx,gy;
contentsToGrid(x,y,gx,gy);
mStartCellX = gx;
mStartCellY = gy;
mCurrentCellX = gx;
mCurrentCellY = gy;
// Store coordinates of old selection
int selectionX = mSelectionCellX * mGridSpacingX;
int selectionYTop = mSelectionYTop;
int selectionHeight = mSelectionHeight;
// Store new selection
mSelectionCellX = gx;
mSelectionYTop = gy * mGridSpacingY;
mSelectionHeight = mGridSpacingY;
// Clear old selection
repaintContents( selectionX, selectionYTop,
mGridSpacingX, selectionHeight,false );
// Paint new selection
// repaintContents( mSelectionCellX * mGridSpacingX, mSelectionYTop,
// mGridSpacingX, mSelectionHeight );
}
void KOAgenda::performSelectAction(QPoint viewportPos)
{
int x,y;
viewportToContents(viewportPos.x(),viewportPos.y(),x,y);
int gx,gy;
contentsToGrid(x,y,gx,gy);
QPoint clipperPos = clipper()->
mapFromGlobal(viewport()->mapToGlobal(viewportPos));
// Scroll if cursor was moved to upper or lower end of agenda.
if (clipperPos.y() < mScrollBorderWidth) {
mScrollUpTimer.start(mScrollDelay);
} else if (visibleHeight() - clipperPos.y() <
mScrollBorderWidth) {
mScrollDownTimer.start(mScrollDelay);
} else {
mScrollUpTimer.stop();
mScrollDownTimer.stop();
}
if ( gy > mCurrentCellY ) {
mSelectionHeight = ( gy + 1 ) * mGridSpacingY - mSelectionYTop;
#if 0
// FIXME: Repaint only the newly selected region
repaintContents( mSelectionCellX * mGridSpacingX,
mCurrentCellY + mGridSpacingY,
mGridSpacingX,
mSelectionHeight - ( gy - mCurrentCellY - 1 ) * mGridSpacingY );
#else
repaintContents( (KOGlobals::self()->reverseLayout() ?
mColumns - 1 - mSelectionCellX : mSelectionCellX) *
mGridSpacingX, mSelectionYTop,
mGridSpacingX, mSelectionHeight , false);
#endif
mCurrentCellY = gy;
} else if ( gy < mCurrentCellY ) {
if ( gy >= mStartCellY ) {
int selectionHeight = mSelectionHeight;
mSelectionHeight = ( gy + 1 ) * mGridSpacingY - mSelectionYTop;
diff --git a/korganizer/koagenda.h b/korganizer/koagenda.h
index f3f1772..3d33ae5 100644
--- a/korganizer/koagenda.h
+++ b/korganizer/koagenda.h
@@ -33,258 +33,264 @@
#include "koagendaitem.h"
class QPopupMenu;
class QTime;
class KConfig;
class QFrame;
class KOAgenda;
class KCal::Event;
class KCal::Todo;
using namespace KCal;
class MarcusBains : public QFrame {
Q_OBJECT
public:
MarcusBains(KOAgenda *agenda=0,const char *name=0);
virtual ~MarcusBains();
public slots:
void updateLocation(bool recalculate=false);
void updateLoc();
private:
int todayColumn();
QTimer *minutes;
QLabel *mTimeBox;
KOAgenda *agenda;
QTime oldTime;
int oldToday;
};
class KOAgenda : public QScrollView
{
Q_OBJECT
public:
enum MouseActionType { NOP, MOVE, SELECT,
RESIZETOP, RESIZEBOTTOM, RESIZELEFT, RESIZERIGHT };
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;
virtual bool eventFilter ( QObject *, QEvent * );
void contentsToGrid (int x, int y, int& gx, int& gy);
void gridToContents (int gx, int gy, int& x, int& y);
int timeToY (const QTime &time);
QTime gyToTime (int y);
void setStartHour(int startHour);
KOAgendaItem *insertItem (Incidence *event,QDate qd,int X,int YTop,int YBottom);
KOAgendaItem *insertAllDayItem (Incidence *event,QDate qd,int XBegin,int XEnd);
void insertMultiItem (Event *event,QDate qd,int XBegin,int XEnd,
int YTop,int YBottom);
void changeColumns(int columns);
int columns() { return mColumns; }
int rows() { return mRows; }
int gridSpacingX() const { return mGridSpacingX; }
int gridSpacingY() const { return mGridSpacingY; }
// virtual QSizePolicy sizePolicy() const;
void clear();
void clearSelection();
void hideUnused();
/** Calculates the minimum width */
virtual int minimumWidth() const;
/** Update configuration from preference settings */
void updateConfig();
void checkScrollBoundaries();
void setHolidayMask(QMemArray<bool> *);
void setDateList(const DateList &selectedDates);
DateList dateList() const;
void drawContentsToPainter( QPainter* paint = 0, bool backgroundOnly = false);
void finishUpdate();
void printSelection();
void storePosition();
void restorePosition();
public slots:
+ void popupMenu();
void newItem( int );
void moveChild( QWidget *, int, int );
void scrollUp();
void scrollDown();
void updateTodo( Todo * t, int , bool );
void popupAlarm();
void checkScrollBoundaries(int);
/** Deselect selected items. This function does not emit any signals. */
void deselectItem();
/** Select item. If the argument is 0, the currently selected item gets
deselected. This function emits the itemSelected(bool) signal to inform
about selection/deseelction of events. */
void selectItem(KOAgendaItem *);
void finishResize();
signals:
void showDateView( int, QDate );
void newEventSignal();
void newEventSignal(int gx,int gy);
void newTodoSignal(int gx,int gy);
void newEventSignal(int gxStart, int gyStart, int gxEnd, int gyEnd);
void newTimeSpanSignal(int gxStart, int gyStart, int gxEnd, int gyEnd);
void newStartSelectSignal();
void showIncidenceSignal(Incidence *);
void editIncidenceSignal(Incidence *);
void deleteIncidenceSignal(Incidence *);
void showIncidencePopupSignal(Incidence *);
void itemModified(KOAgendaItem *item, int );
void incidenceSelected(Incidence *);
void lowerYChanged(int);
void upperYChanged(int);
void startDragSignal(Incidence *);
void addToCalSignal(Incidence *, Incidence *);
void resizedSignal();
protected:
QPainter mPixPainter;
QPixmap mPaintPixmap;
QPixmap mHighlightPixmap;
void drawContents(QPainter *p,int cx, int cy, int cw, int ch);
virtual void resizeEvent ( QResizeEvent * );
/** Handles mouse events. Called from eventFilter */
virtual bool eventFilter_mouse ( QObject *, QMouseEvent * );
/** Start selecting time span. */
void startSelectAction(QPoint viewportPos);
/** Select time span. */
void performSelectAction(QPoint viewportPos);
/** Emd selecting time span. */
void endSelectAction( bool emitNewEvent = false );
/** Start moving/resizing agenda item */
void startItemAction(QPoint viewportPos);
/** Move/resize agenda item */
void performItemAction(QPoint viewportPos);
/** End moving/resizing agenda item */
void endItemAction();
/** Set cursor, when no item action is in progress */
void setNoActionCursor(KOAgendaItem *moveItem,QPoint viewportPos);
/** Place agenda item in agenda and adjust other cells if necessary */
void placeSubCells(KOAgendaItem *placeItem);
/** 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 * );
private:
void init();
void marcus_bains();
bool mAllDayMode;
bool blockResize;
+ bool mLeftMouseDown;
+ KOAgendaItem *mPopupItem;
+ QTimer* mPopupTimer;
+ int mPopupKind;
+ QPoint mPopupPos;
QTimer mResizeTimer;
double mContentPosition;
// Width and height of agenda cells
int mGridSpacingX;
int mGridSpacingY;
// 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
int mStartCellX;
int mStartCellY;
int mCurrentCellX;
int mCurrentCellY;
// Working Hour coordiantes
bool mWorkingHoursEnable;
int mWorkingHoursYTop;
int mWorkingHoursYBottom;
// Selection
int mSelectionCellX;
int mSelectionYTop;
int mSelectionHeight;
// List of dates to be displayed
DateList mSelectedDates;
// The KOAgendaItem, which has been right-clicked last
KOAgendaItem *mClickedItem;
// The KOAgendaItem, which is being moved/resized
QGuardedPtr<KOAgendaItem> mActionItem;
// Currently selected item
QGuardedPtr<KOAgendaItem> mSelectedItem;
// The Marcus Bains Line widget.
MarcusBains *mMarcusBains;
void computeSizes();
MouseActionType mActionType;
bool mItemMoved;
// List of all Items contained in agenda
QPtrList<KOAgendaItem> mItems;
QPtrList<KOAgendaItem> mUnusedItems;
KOAgendaItem* getNewItem(Incidence * event,QDate qd, QWidget* viewport);
QPopupMenu *mItemPopup; // Right mouse button popup menu for KOAgendaItems
QPopupMenu *mNewItemPopup;
int mOldLowerScrollValue;
int mOldUpperScrollValue;
KOAgendaItem * getItemForTodo ( Todo * todo );
QMemArray<bool> *mHolidayMask;
int mCurPixWid;
int mCurPixHei;
};
#endif // KOAGENDA_H
diff --git a/korganizer/koagendaitem.cpp b/korganizer/koagendaitem.cpp
index 905c1bf..b30ad75 100644
--- a/korganizer/koagendaitem.cpp
+++ b/korganizer/koagendaitem.cpp
@@ -1,174 +1,174 @@
/*
This file is part of KOrganizer.
Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <qlabel.h>
#include <qlayout.h>
#include <qhbox.h>
#include <qvbox.h>
#include <qtooltip.h>
#include <qwhatsthis.h>
#include <qdragobject.h>
#include <qdrawutil.h>
#include <qpainter.h>
#include <kiconloader.h>
#include <kdebug.h>
#include <kglobal.h>
#include <klocale.h>
#ifndef DESKTOP_VERSION
#include <qpe/qpeapplication.h>
#define AGENDA_ICON_SIZE 5
#else
#define AGENDA_ICON_SIZE 7
#endif
#include <libkcal/icaldrag.h>
#include <libkcal/vcaldrag.h>
#include <libkcal/kincidenceformatter.h>
extern int globalFlagBlockAgenda;
extern int globalFlagBlockAgendaItemPaint;
extern int globalFlagBlockAgendaItemUpdate;
#include "koprefs.h"
#include "koagendaitem.h"
//#include "koagendaitem.moc"
//--------------------------------------------------------------------------
QToolTipGroup *KOAgendaItem::mToolTipGroup = 0;
//--------------------------------------------------------------------------
class KOAgendaItemWhatsThis :public QWhatsThis
{
public:
KOAgendaItemWhatsThis( KOAgendaItem* view ) : QWhatsThis( view ),_view (view) { };
protected:
virtual QString text( const QPoint& )
{
return _view->getWhatsThisText() ;
}
private:
KOAgendaItem * _view;
};
KOAgendaItem::KOAgendaItem(Incidence *incidence, QDate qd, QWidget *parent,bool allday,
const char *name,WFlags) :
QWidget(parent, name), mIncidence(incidence), mDate(qd)
{
#ifndef DESKTOP_VERSION
- QPEApplication::setStylusOperation( this, QPEApplication::RightOnHold );
+ //QPEApplication::setStylusOperation( this, QPEApplication::RightOnHold );
#endif
mKOAgendaItemWhatsThis = new KOAgendaItemWhatsThis(this);
int wflags = getWFlags() |WRepaintNoErase;// WResizeNoErase
setWFlags ( wflags);
mAllDay = allday;
init ( incidence, qd );
//setMouseTracking(true);
//setAcceptDrops(true);
xPaintCoord = -1;
yPaintCoord = -1;
}
QString KOAgendaItem::getWhatsThisText()
{
if ( mIncidence )
return KIncidenceFormatter::instance()->getFormattedText( mIncidence,
KOPrefs::instance()->mWTshowDetails,
KOPrefs::instance()->mWTshowCreated,
KOPrefs::instance()->mWTshowChanged);
return "KOAgendaItem::getWhatsThisText()::internal error";
}
void KOAgendaItem::init ( Incidence *incidence, QDate qd )
{
mIncidence = incidence;
mDate = qd;
mFirstMultiItem = 0;
mNextMultiItem = 0;
mLastMultiItem = 0;
computeText();
if ( (incidence->type() == "Todo") &&
( !((static_cast<Todo*>(incidence))->isCompleted()) &&
((static_cast<Todo*>(incidence))->dtDue().date() <= QDate::currentDate()) ) ) {
if ( (static_cast<Todo*>(incidence))->dtDue() < QDateTime::currentDateTime().date())
mBackgroundColor = KOPrefs::instance()->mTodoOverdueColor ;
else
mBackgroundColor = KOPrefs::instance()->mTodoDueTodayColor;
}
else {
QStringList categories = mIncidence->categories();
QString cat = categories.first();
if (cat.isEmpty()) {
if ( (incidence->type() == "Todo") &&((static_cast<Todo*>(incidence))->isCompleted()) )
mBackgroundColor =KOPrefs::instance()->mTodoDoneColor;
else
mBackgroundColor =KOPrefs::instance()->mEventColor;
} else {
mBackgroundColor = *KOPrefs::instance()->categoryColor(cat);
if ( (incidence->type() == "Todo") &&((static_cast<Todo*>(incidence))->isCompleted()) ) {
if ( mBackgroundColor == KOPrefs::instance()->mEventColor )
mBackgroundColor =KOPrefs::instance()->mTodoDoneColor;
}
}
}
mColorGroup = QColorGroup( mBackgroundColor.light(),
mBackgroundColor.dark(),mBackgroundColor.light(),
mBackgroundColor.dark(),mBackgroundColor, black, mBackgroundColor) ;
setBackgroundColor( mBackgroundColor );
mConflictItems.clear();
setCellXY(0,0,1);
setCellXWidth(0);
setSubCell(0);
setSubCells(1);
setMultiItem(0,0,0);
startMove();
mSelected = true;
select(false);
QFontMetrics fontinf(KOPrefs::instance()->mAgendaViewFont);
mFontPixelSize = fontinf.height();;
hide();
xPaintCoord = -1;
yPaintCoord = -1;
}
KOAgendaItem::~KOAgendaItem()
{
// qDebug("deleteKOAgendaItem::~KOAgendaItem( ");
// delete mKOAgendaItemWhatsThis;
}
void KOAgendaItem::recreateIncidence()
{
#if 0
Incidence* newInc = mIncidence->clone();
newInc->recreate();
if ( mIncidence->doesRecur() ) {
mIncidence->addExDate( mDate );
newInc->recurrence()->unsetRecurs();
int len = mIncidence->dtStart().secsTo( ((Event*)mIncidence)->dtEnd());
QTime tim = mIncidence->dtStart().time();
newInc->setDtStart( QDateTime(mDate, tim) );
((Event*)newInc)->setDtEnd( newInc->dtStart().addSecs( len ) );
}
#endif
diff --git a/korganizer/koagendaview.cpp b/korganizer/koagendaview.cpp
index 957ac52..b9c7dec 100644
--- a/korganizer/koagendaview.cpp
+++ b/korganizer/koagendaview.cpp
@@ -36,261 +36,253 @@
#include <qpainter.h>
#include <qpushbutton.h>
#include <qapplication.h>
#include <kapplication.h>
#include <KDGanttMinimizeSplitter.h>
#include <kdebug.h>
#include <kstandarddirs.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kconfig.h>
#include <kglobal.h>
#include "calendarview.h"
#include "koviewmanager.h"
#include <libkcal/calendar.h>
#include <libkcal/icaldrag.h>
#include <libkcal/dndfactory.h>
#include <kcalendarsystem.h>
#include "koglobals.h"
#ifndef KORG_NOPLUGINS
#include "kocore.h"
#endif
#include "koprefs.h"
#include "koagenda.h"
#include "koagendaitem.h"
#ifndef KORG_NOPRINTER
#include "calprinter.h"
#endif
#include "koagendaview.h"
//#include "koagendaview.moc"
//extern bool globalFlagBlockPainting;
extern int globalFlagBlockAgenda;
extern int globalFlagBlockStartup;
extern int globalFlagBlockAgendaItemPaint;
extern int globalFlagBlockAgendaItemUpdate;
extern int globalFlagBlockLabel;
using namespace KOrg;
TimeLabels::TimeLabels(int rows,QWidget *parent,const char *name,WFlags f) :
QScrollView(parent,name,f)
{
mRows = rows;
setMinimumHeight( 20 );
mCellHeight = KOPrefs::instance()->mHourSize*4;
enableClipper(true);
setHScrollBarMode(AlwaysOff);
setVScrollBarMode(AlwaysOff);
resizeContents(50,mRows * mCellHeight);
viewport()->setBackgroundMode( PaletteBackground );
}
void TimeLabels::setCellHeight(int height)
{
mCellHeight = height;
}
/*
Optimization so that only the "dirty" portion of the scroll view
is redrawn. Unfortunately, this is not called by default paintEvent() method.
*/
void TimeLabels::drawContents(QPainter *p,int cx, int cy, int cw, int ch)
{
// if ( globalFlagBlockAgenda )
// return;
// bug: the parameters cx, cy, cw, ch are the areas that need to be
// redrawn, not the area of the widget. unfortunately, this
// code assumes the latter...
// now, for a workaround...
// these two assignments fix the weird redraw bug
cx = contentsX() + 2;
cw = contentsWidth() - 2;
// end of workaround
int cell = ((int)(cy/mCellHeight));
int y = cell * mCellHeight;
QFontMetrics fm = fontMetrics();
QString hour;
QString suffix;
QString fullTime;
int tW = fm.width("24:00i");
int timeHeight = fm.height();
timeHeight -= (timeHeight/4-2);
- int borderWidth = 5;
+ int borderWidth = 2;
QFont nFont = p->font();
QFont sFont = nFont;
sFont.setPointSize( sFont.pointSize()/2+2 );
if (!KGlobal::locale()->use12Clock())
suffix = "00";
QFontMetrics fmS( sFont );
int sHei = fmS.height();
if ( timeHeight > mCellHeight ) {
timeHeight = mCellHeight-1;
sHei -= 2;
}
while (y < cy + ch) {
p->drawLine(cx,y,cx+tW,y);
hour.setNum(cell);
// handle 24h and am/pm time formats
if (KGlobal::locale()->use12Clock()) {
if (cell > 11) suffix = "pm";
else
suffix = "am";
if (cell == 0) hour.setNum(12);
if (cell > 12) hour.setNum(cell - 12);
}
// create string in format of "XX:XX" or "XXpm/am"
fullTime = hour;// + suffix;
// center and draw the time label
int timeWidth = fm.width(fullTime+"i");
int tw2 = fm.width(suffix);
int offset = this->width() - timeWidth - tw2;
p->setFont( nFont );
p->drawText(cx - borderWidth + offset, y+ timeHeight, fullTime);
p->setFont( sFont );
offset += timeWidth;
p->drawText(cx - borderWidth + offset, y+ sHei, suffix);
// increment indices
y += mCellHeight;
cell++;
}
}
/**
Calculates the minimum width.
*/
int TimeLabels::minimumWidth() const
{
- QFontMetrics fm = fontMetrics();
-
- //TODO: calculate this value
- int borderWidth = 4;
-
- // the maximum width possible
- int width = fm.width("88:88x") + borderWidth;
-
- return width;
+ return mMiniWidth;
}
/** updates widget's internal state */
void TimeLabels::updateConfig()
{
// set the font
// config->setGroup("Fonts");
// QFont font = config->readFontEntry("TimeBar Font");
setFont(KOPrefs::instance()->mTimeBarFont);
-
+ mMiniWidth = fontMetrics().width("88:88") + 2 ;
// update geometry restrictions based on new settings
setFixedWidth(minimumWidth());
// update HourSize
mCellHeight = KOPrefs::instance()->mHourSize*4;
resizeContents(50,mRows * mCellHeight);
}
/** update time label positions */
void TimeLabels::positionChanged()
{
int adjustment = mAgenda->contentsY();
setContentsPos(0, adjustment);
}
/** */
void TimeLabels::setAgenda(KOAgenda* agenda)
{
mAgenda = agenda;
}
void TimeLabels::contentsMousePressEvent ( QMouseEvent * e)
{
mMouseDownY = e->pos().y();
mOrgCap = topLevelWidget()->caption();
}
void TimeLabels::contentsMouseMoveEvent ( QMouseEvent * e )
{
int diff = mMouseDownY - e->pos().y();
if ( diff < 10 && diff > -10 )
return;
int tSize = KOPrefs::instance()->mHourSize + (diff/10) ;
if ( tSize < 4 )
tSize = 4;
if ( tSize > 22 )
tSize = 22;
tSize = (tSize-2)/2;
topLevelWidget()->setCaption(i18n("New Agendasize: %1").arg(tSize));
}
void TimeLabels::contentsMouseReleaseEvent ( QMouseEvent * e )
{
topLevelWidget()->setCaption( mOrgCap );
int diff = mMouseDownY - e->pos().y();
if ( diff < 10 && diff > -10 )
return;
int tSize = KOPrefs::instance()->mHourSize + (diff/10);
if ( tSize < 4 )
tSize = 4;
if ( tSize > 22 )
tSize = 22;
tSize = (tSize/2)*2;
if ( tSize == KOPrefs::instance()->mHourSize )
return;
KOPrefs::instance()->mHourSize = tSize;
emit scaleChanged();
}
/** This is called in response to repaint() */
void TimeLabels::paintEvent(QPaintEvent*)
{
// kdDebug() << "paintevent..." << endl;
// this is another hack!
// QPainter painter(this);
//QString c
repaintContents(contentsX(), contentsY(), visibleWidth(), visibleHeight());
}
////////////////////////////////////////////////////////////////////////////
EventIndicator::EventIndicator(Location loc,QWidget *parent,const char *name)
: QFrame(parent,name)
{
mColumns = 1;
mTopBox = 0;
mLocation = loc;
mTopLayout = 0;
mPaintWidget = 0;
mXOffset = 0;
if (mLocation == Top) mPixmap = SmallIcon("1uparrow");
else mPixmap = SmallIcon("1downarrow");
mEnabled.resize(mColumns);
mEnabled.fill( false );
setMinimumHeight(mPixmap.height());
}
EventIndicator::~EventIndicator()
{
}
void EventIndicator::drawContents(QPainter *p)
{
// kdDebug() << "======== top: " << contentsRect().top() << " bottom " << // contentsRect().bottom() << " left " << contentsRect().left() << " right " << contentsRect().right() << endl;
diff --git a/korganizer/koagendaview.h b/korganizer/koagendaview.h
index 8b8bac0..0cb9310 100644
--- a/korganizer/koagendaview.h
+++ b/korganizer/koagendaview.h
@@ -8,192 +8,193 @@
(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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 KOAGENDAVIEW_H
#define KOAGENDAVIEW_H
#include <qscrollview.h>
#include <qdatetime.h>
#include <qpushbutton.h>
#include <qlayout.h>
#ifndef DESKTOP_VERSION
#include <qksplitter.h>
#else
#include <qsplitter.h>
#endif
#include <qmemarray.h>
#include "koeventview.h"
class QHBox;
class QFrame;
class QLabel;
class QPushButton;
class CalendarView;
class KOAgenda;
class KOAgendaItem;
class KConfig;
class KDGanttMinimizeSplitter;
class KOAgendaButton : public QPushButton
{
Q_OBJECT
public:
KOAgendaButton( QWidget *parent=0, const char *name=0 ) :
QPushButton( parent, name )
{
mNum = -3;
setFlat( true );
setFocusPolicy(NoFocus);
setSizePolicy(QSizePolicy( QSizePolicy::Expanding ,QSizePolicy::Expanding ));
connect( this, SIGNAL( clicked() ), this, SLOT ( bClicked() ) );
};
QSize sizeHint () const { return QSize( 5,5) ;}
void setNum( int n) { mNum = n; }
private slots:
void bClicked() {emit numClicked( mNum);}
signals:
void numClicked( int );
private:
int mNum;
};
class TimeLabels : public QScrollView {
Q_OBJECT
public:
TimeLabels(int rows,QWidget *parent=0,const char *name=0,WFlags f=0);
void setCellHeight(int height);
/** Calculates the minimum width */
virtual int minimumWidth() const;
/** updates widget's internal state */
void updateConfig();
/** */
void setAgenda(KOAgenda* agenda);
/** */
virtual void paintEvent(QPaintEvent* e);
void contentsMousePressEvent ( QMouseEvent * ) ;
void contentsMouseReleaseEvent ( QMouseEvent * );
void contentsMouseMoveEvent ( QMouseEvent * );
public slots:
/** update time label positions */
void positionChanged();
signals:
void scaleChanged();
protected:
void drawContents(QPainter *p,int cx, int cy, int cw, int ch);
private:
+ int mMiniWidth;
int mMouseDownY;
QString mOrgCap;
int mRows;
int mCellHeight;
/** */
KOAgenda* mAgenda;
};
class EventIndicator : public QFrame {
Q_OBJECT
public:
enum Location { Top, Bottom };
EventIndicator(Location loc=Top,QWidget *parent=0,const char *name=0);
virtual ~EventIndicator();
void changeColumns(int columns);
void setPaintWidget( KDGanttMinimizeSplitter* );
void setXOffset( int );
void enableColumn(int column, bool enable);
protected:
void drawContents(QPainter *);
private:
int mXOffset;
KDGanttMinimizeSplitter* mPaintWidget;
int mColumns;
QHBox *mTopBox;
QBoxLayout *mTopLayout;
Location mLocation;
QPixmap mPixmap;
QMemArray<bool> mEnabled;
};
/**
KOAgendaView is the agenda-like view used to display events in an one or
multi-day view.
*/
class KOAgendaView : public KOEventView {
Q_OBJECT
public:
KOAgendaView(Calendar *cal,QWidget *parent = 0,const char *name = 0 );
virtual ~KOAgendaView();
void setStartHour( int );
void toggleAllDay();
/** Returns maximum number of days supported by the koagendaview */
virtual int maxDatesHint();
/** Returns number of currently shown dates. */
virtual int currentDateCount();
/** returns the currently selected events */
virtual QPtrList<Incidence> selectedIncidences();
/** returns the currently selected events */
virtual DateList selectedDates();
/** Remove all events from view */
void clearView();
KOAgenda *agenda() { return mAgenda;}
virtual void printPreview(CalPrinter *calPrinter,
const QDate &, const QDate &);
/** start-datetime of selection */
QDateTime selectionStart() {return mTimeSpanBegin;}
/** end-datetime of selection */
QDateTime selectionEnd() {return mTimeSpanEnd;}
/** returns true if selection is for whole day */
bool selectedIsAllDay() {return mTimeSpanInAllDay;}
/** make selected start/end invalid */
void deleteSelectedDateTime();
void repaintAgenda();
public slots:
void setInitStartHour();
virtual void updateView();
virtual void updateConfig();
virtual void showDates(const QDate &start, const QDate &end);
virtual void showEvents(QPtrList<Event> eventList);
void updateTodo( Todo *, int );
void changeEventDisplay(Event *, int);
void clearSelection();
void newTodo(int gx,int gy);
void newEvent(int gx,int gy);
void newEvent(int gxStart, int gyStart, int gxEnd, int gyEnd);
void newEventAllDay(int gx, int gy);
void newTodoAllDay(int gx, int gy);
void startDrag(Event *);
void readSettings();
diff --git a/korganizer/kolistview.cpp b/korganizer/kolistview.cpp
index 6b63d7f..09d70f1 100644
--- a/korganizer/kolistview.cpp
+++ b/korganizer/kolistview.cpp
@@ -1061,135 +1061,182 @@ void KOListViewListView::keyPressEvent ( QKeyEvent *e)
}
if ( e->state() == ControlButton ) {
int count = childCount ();
int jump = count / 5;
QListViewItem* cn;
cn = currentItem();
if ( ! cn )
return;
if ( jump == 0 )
jump = 1;
while ( jump && cn->nextSibling() ) {
cn = cn->nextSibling();
--jump;
}
setCurrentItem ( cn );
ensureItemVisible ( cn );
} else
QListView::keyPressEvent ( e ) ;
e->accept();
break;
case Qt::Key_Up:
if ( e->state() == ShiftButton ) {
QListViewItem* cn = firstChild();
if ( cn ) {
setCurrentItem ( cn );
ensureItemVisible ( cn );
}
e->accept();
return;
}
if ( e->state() == ControlButton ) {
int count = childCount ();
int jump = count / 5;
QListViewItem* cn;
cn = currentItem();
if ( ! cn )
return;
if ( jump == 0 )
jump = 1;
while ( jump && cn->itemAbove ()) {
cn = cn->itemAbove ();
--jump;
}
setCurrentItem ( cn );
ensureItemVisible ( cn );
} else
QListView::keyPressEvent ( e ) ;
e->accept();
break;
case Qt::Key_I: {
QListViewItem* cn;
cn = currentItem();
if ( cn ) {
KOListViewItem* ci = (KOListViewItem*)( cn );
if ( ci ){
//emit showIncidence( ci->data());
cn = cn->nextSibling();
if ( cn ) {
setCurrentItem ( cn );
ensureItemVisible ( cn );
}
emit showIncidence( ci->data());
}
}
e->accept();
}
break;
case Qt::Key_Return:
case Qt::Key_Enter:
{
QListViewItem* cn;
cn = currentItem();
if ( cn ) {
KOListViewItem* ci = (KOListViewItem*)( cn );
if ( ci ){
if ( e->state() == ShiftButton )
ci->setSelected( false );
else
ci->setSelected( true );
cn = cn->nextSibling();
if ( cn ) {
setCurrentItem ( cn );
ensureItemVisible ( cn );
}
}
}
e->accept();
}
break;
default:
e->ignore();
}
}
KOListViewListView::KOListViewListView(KOListView * lv )
- : KListView( lv )
-{
+ : KListView( lv, "kolistlistview", false )
+{
+ mPopupTimer = new QTimer(this);
+ connect(mPopupTimer , SIGNAL(timeout()), this, SLOT(popupMenu()));
#ifndef DESKTOP_VERSION
- QPEApplication::setStylusOperation(viewport(), QPEApplication::RightOnHold );
+ //QPEApplication::setStylusOperation(viewport(), QPEApplication::RightOnHold );
#endif
setSelectionMode( QListView::Multi );
setMultiSelection( true);
}
void KOListViewListView::contentsMouseDoubleClickEvent(QMouseEvent *e)
{
if (!e) return;
QPoint vp = contentsToViewport(e->pos());
QListViewItem *item = itemAt(vp);
if (!item) {
emit newEvent();
return;
}
KListView::contentsMouseDoubleClickEvent(e);
}
-
+#if 0
void KOListViewListView::contentsMousePressEvent(QMouseEvent *e)
{
//qDebug("contentsMousePressEvent++++ ");
KListView::contentsMousePressEvent( e );
if ( e->button() == RightButton ) {
QListViewItem* ci = currentItem();
clearSelection () ;
if ( ci )
ci->setSelected( true );
}
}
void KOListViewListView::contentsMouseReleaseEvent(QMouseEvent *e)
{
KListView::contentsMouseReleaseEvent(e);
}
void KOListViewListView::contentsMouseMoveEvent(QMouseEvent *e)
{
KListView::contentsMouseMoveEvent(e);
}
+#endif
+void KOListViewListView::popupMenu()
+{
+ mPopupTimer->stop();
+ //qDebug("HUUUUUUUUUUUUUUUUUUUU ");
+ QMouseEvent* e = new QMouseEvent( QEvent::MouseButtonPress, mEventPos ,mEventGlobalPos, RightButton , RightButton );
+ QApplication::postEvent( this->viewport(), e );
+}
+void KOListViewListView::contentsMousePressEvent(QMouseEvent *e)
+{
+ //qDebug("contentsMousePressEvent++++ ");
+ mYMousePos = mapToGlobal( (e->pos())).y();
+ if ( e->button() == LeftButton ) {
+ mPopupTimer->start( 600 );
+ mEventPos = e->pos();
+ mEventGlobalPos = e->globalPos();
+ }
+ KListView::contentsMousePressEvent( e );
+ if ( e->button() == RightButton ) {
+ QListViewItem* ci = currentItem();
+ clearSelection();
+ if ( ci )
+ ci->setSelected( true );
+ }
+}
+void KOListViewListView::contentsMouseReleaseEvent(QMouseEvent *e)
+{
+ mPopupTimer->stop();
+ KListView::contentsMouseReleaseEvent(e);
+}
+void KOListViewListView::contentsMouseMoveEvent(QMouseEvent *e)
+{
+ // qDebug("contentsMouseMoveEv....... ");
+ // qDebug("start: %d current %d ",mYMousePos , mapToGlobal( (e->pos())).y() );
+ int diff = mYMousePos - mapToGlobal( (e->pos())).y();
+ if ( diff < 0 ) diff = -diff;
+ if ( diff > 15 )
+ mPopupTimer->stop();
+ else {
+ mEventPos = e->pos();
+ mEventGlobalPos = e->globalPos();
+ }
+ KListView::contentsMouseMoveEvent(e);
+}
+
diff --git a/korganizer/kolistview.h b/korganizer/kolistview.h
index eca71e2..bb0e23e 100644
--- a/korganizer/kolistview.h
+++ b/korganizer/kolistview.h
@@ -1,304 +1,311 @@
/*
This file is part of KOrganizer.
Copyright (c) 1999 Preston Brown
Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 _KOLISTVIEW_H
#define _KOLISTVIEW_H
#include <qlistview.h>
#include <qmap.h>
#include <qdict.h>
#include <klistview.h>
#ifndef DESKTOP_VERSION
#include <qtopia/ir.h>
#else
#define Ir char
#endif
#include <libkcal/incidence.h>
#include "koeventview.h"
#include "customlistviewitem.h"
using namespace KCal;
#include <qpushbutton.h>
#include <qlayout.h>
#include <qdialog.h>
+#include <qtimer.h>
#include <qcombobox.h>
#include <qspinbox.h>
#include <qtooltip.h>
#include <qcheckbox.h>
#include <qhbox.h>
#include <qlabel.h>
#include <kiconloader.h>
#include "kfiledialog.h"
#include "koprefs.h"
class KOAlarmPrefs : public QDialog
{
Q_OBJECT
public:
KOAlarmPrefs( QWidget *par=0, const char *name=0 ) :
QDialog( par, name, true )
{
setCaption( i18n("Alarm Options") );
QVBoxLayout* alarmLayout = new QVBoxLayout( this );
alarmLayout->setSpacing( 3 );
alarmLayout->setMargin( 3 );
QWidget *parent = this;
mAlarmButton = new QCheckBox(i18n("Set reminder ON with offset to:"),parent);
alarmLayout->addWidget(mAlarmButton);
mAlarmTimeEdit = new QSpinBox ( 0, 9999, 1, parent, "mAlarmTimeEdit " ) ;
mAlarmTimeEdit->setValue( 15 );
alarmLayout->addWidget(mAlarmTimeEdit);
mAlarmIncrCombo = new QComboBox(false, parent);
mAlarmIncrCombo->insertItem(i18n("minute(s)"));
mAlarmIncrCombo->insertItem(i18n("hour(s)"));
mAlarmIncrCombo->insertItem(i18n("day(s)"));
alarmLayout->addWidget(mAlarmIncrCombo);
QHBox * hb = new QHBox ( parent );
alarmLayout->addWidget(hb);
mAlarmSoundButton = new QPushButton(hb);
mAlarmSoundButton->setPixmap(SmallIcon("playsound"));
mAlarmSoundButton->setToggleButton(true);
connect(mAlarmSoundButton, SIGNAL(clicked()), SLOT(pickAlarmSound()));
mAlarmProgramButton = new QPushButton(hb);
mAlarmProgramButton->setPixmap(SmallIcon("run"));
mAlarmProgramButton->setToggleButton(true);
connect(mAlarmProgramButton, SIGNAL(clicked()), SLOT(pickAlarmProgram()));
mAlarmSoundButton->setMaximumWidth( mAlarmSoundButton->sizeHint().width() + 4 );
mAlarmProgramButton->setMaximumWidth(mAlarmProgramButton->sizeHint().width() + 4 );
mAlarmLabel = new QLabel( this );
alarmLayout->addWidget( mAlarmLabel );
mAlarmLabel->setText( "..."+KOPrefs::instance()->mDefaultAlarmFile.right( 30 ) );
mAlarmSound = KOPrefs::instance()->mDefaultAlarmFile;
mAlarmSoundButton->setOn( true );
QPushButton * ok = new QPushButton( i18n("Set Alarm!"), this );
alarmLayout->addWidget( ok );
QPushButton * cancel = new QPushButton( i18n("Cancel"), this );
alarmLayout->addWidget( cancel );
connect ( ok,SIGNAL(clicked() ),this , SLOT ( accept() ) );
connect (cancel, SIGNAL(clicked() ), this, SLOT ( reject()) );
resize( 200, 200 );
}
QString mAlarmSound, mAlarmProgram ;
QCheckBox* mAlarmButton;
QSpinBox* mAlarmTimeEdit;
QLabel* mAlarmLabel;
QComboBox* mAlarmIncrCombo ;
QPushButton* mAlarmSoundButton ,*mAlarmProgramButton;
private slots:
void pickAlarmSound()
{
//QString prefix = mAlarmSound;
if (!mAlarmSoundButton->isOn()) {
//mAlarmSound = "";
QToolTip::remove(mAlarmSoundButton);
QToolTip::add(mAlarmSoundButton, i18n("No sound set"));
mAlarmProgramButton->setOn(true);
mAlarmSoundButton->setOn(false);
} else {
QString fileName(KFileDialog::getOpenFileName(mAlarmSound,
i18n("*.wav|Wav Files"), 0));
if (!fileName.isEmpty()) {
mAlarmSound = fileName;
mAlarmLabel->setText( "..."+fileName.right( 30 ) );
QToolTip::remove(mAlarmSoundButton);
QString dispStr = i18n("Playing '%1'").arg(fileName);
QToolTip::add(mAlarmSoundButton, dispStr);
mAlarmProgramButton->setOn(false);
mAlarmSoundButton->setOn(true);
} else {
mAlarmProgramButton->setOn(true);
mAlarmSoundButton->setOn(false);
}
}
};
void pickAlarmProgram()
{
if (!mAlarmProgramButton->isOn()) {
//mAlarmProgram = "";
QToolTip::remove(mAlarmProgramButton);
QToolTip::add(mAlarmProgramButton, i18n("No program set"));
mAlarmProgramButton->setOn(false);
mAlarmSoundButton->setOn(true);
} else {
QString fileName(KFileDialog::getOpenFileName(mAlarmProgram,i18n("Procedure Alarm.: ") , 0));
if (!fileName.isEmpty()) {
mAlarmProgram = fileName;
mAlarmLabel->setText( "..."+fileName.right( 30 ) );
QToolTip::remove(mAlarmProgramButton);
QString dispStr = i18n("Running '%1'").arg(fileName);
QToolTip::add(mAlarmProgramButton, dispStr);
mAlarmSoundButton->setOn(false);
mAlarmProgramButton->setOn(true);
} else {
mAlarmProgramButton->setOn(false);
mAlarmSoundButton->setOn(true);
}
}
};
};
typedef CustomListViewItem<Incidence *> KOListViewItem;
/**
This class provides the initialisation of a KOListViewItem for calendar
components using the Incidence::Visitor.
*/
class ListItemVisitor : public Incidence::Visitor
{
public:
ListItemVisitor(KOListViewItem *, QDate d);
~ListItemVisitor();
bool visit(Event *);
bool visit(Todo *);
bool visit(Journal *);
private:
KOListViewItem *mItem;
QDate mDate;
};
/**
This class provides a multi-column list view of events. It can
display events from one particular day or several days, it doesn't
matter. To use a view that only handles one day at a time, use
KODayListView.
@short multi-column list view of various events.
@author Preston Brown <pbrown@kde.org>
@see KOBaseView, KODayListView
*/
class KOListView;
class KOListViewListView : public KListView
{
Q_OBJECT
public:
KOListViewListView(KOListView * lv );
signals:
void newEvent();
void showIncidence( Incidence* );
+ public slots:
+ void popupMenu();
private:
+ QPoint mEventPos;
+ QPoint mEventGlobalPos;
+ QTimer* mPopupTimer;
+ int mYMousePos;
void keyPressEvent ( QKeyEvent * ) ;
void contentsMouseDoubleClickEvent(QMouseEvent *e);
void contentsMousePressEvent(QMouseEvent *e);
void contentsMouseReleaseEvent(QMouseEvent *e);
void contentsMouseMoveEvent(QMouseEvent *e);
bool mMouseDown;
};
class KOListView : public KOEventView
{
Q_OBJECT
public:
KOListView(Calendar *calendar, QWidget *parent = 0,
const char *name = 0);
~KOListView();
virtual int maxDatesHint();
virtual int currentDateCount();
virtual QPtrList<Incidence> selectedIncidences();
virtual DateList selectedDates();
void showDates(bool show);
Incidence* currentItem();
void addTodos(QPtrList<Todo> eventList);
void addJournals(QPtrList<Journal> eventList);
virtual void printPreview(CalPrinter *calPrinter,
const QDate &, const QDate &);
void readSettings(KConfig *config, QString setting = "KOListView Layout");
void writeSettings(KConfig *config, QString setting = "KOListView Layout");
void updateList();
void setStartDate(const QDate &start);
int count();
QString getWhatsThisText(QPoint p);
void resetFocus();
signals:
void signalNewEvent();
void beamIncidenceList(QPtrList<Incidence>);
public slots:
virtual void updateView();
virtual void showDates(const QDate &start, const QDate &end);
virtual void showEvents(QPtrList<Event> eventList);
void clearSelection();
void allSelection();
void clear();
void beamDone( Ir *ir );
void showDates();
void hideDates();
void deleteAll();
void saveToFile();
void saveToFileVCS();
void saveDescriptionToFile();
void beamSelected();
void updateConfig();
void addCat();
void setCat();
void setAlarm();
void setCategories( bool removeOld );
void changeEventDisplay(Event *, int);
void defaultItemAction(QListViewItem *item);
void popupMenu(QListViewItem *item,const QPoint &,int);
protected slots:
void processSelectionChange(QListViewItem *);
protected:
void writeToFile( bool iCal );
void addEvents(QPtrList<Event> eventList);
void addIncidence(Incidence *);
KOListViewItem *getItemForEvent(Event *event);
private:
KOListViewListView *mListView;
KOEventPopupMenu *mPopupMenu;
KOListViewItem *mActiveItem;
QDict<Incidence> mUidDict;
QDate mStartDate;
void keyPressEvent ( QKeyEvent * ) ;
};
#endif