summaryrefslogtreecommitdiffabout
path: root/korganizer
Side-by-side diff
Diffstat (limited to 'korganizer') (more/less context) (ignore whitespace changes)
-rw-r--r--korganizer/journalentry.cpp4
-rw-r--r--korganizer/koagenda.cpp6
-rw-r--r--korganizer/koagenda.h2
-rw-r--r--korganizer/kotodoview.cpp4
4 files changed, 11 insertions, 5 deletions
diff --git a/korganizer/journalentry.cpp b/korganizer/journalentry.cpp
index 5fc3f2f..7f6f221 100644
--- a/korganizer/journalentry.cpp
+++ b/korganizer/journalentry.cpp
@@ -1,371 +1,373 @@
/*
This file is part of KOrganizer.
Copyright (c) 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.
*/
//
// Journal Entry
#include <qlabel.h>
#include <qlayout.h>
#include <qvbox.h>
#include <qfile.h>
#include <qdir.h>
#include <qtextstream.h>
#include <qtextcodec.h>
#include <qpixmap.h>
#include <qpushbutton.h>
#include <qapplication.h>
#include <kdebug.h>
#include <kglobal.h>
#include <klocale.h>
#include <ktextedit.h>
#include <kfiledialog.h>
#include <kmessagebox.h>
#include "koprefs.h"
#include <klineedit.h>
#include <kdialog.h>
#include "kolocationbox.h"
#include <libkcal/journal.h>
#include <libkcal/calendarresources.h>
#include <libkcal/resourcecalendar.h>
#include <kresources/resourceselectdialog.h>
#include "journalentry.h"
//#include "journalentry.moc"
#ifndef DESKTOP_VERSION
#include <qpe/qpeapplication.h>
#endif
JournalEntry::JournalEntry(Calendar *calendar,QWidget *parent) :
QFrame(parent)
{
int fac = 5;
heiHint = QApplication::desktop()->height();
if ( heiHint > 800 )
fac += 2;
heiHint = heiHint / fac;
showOnlyMode = false;
mCalendar = calendar;
mJournal = 0;
visibleMode = true;
QHBox * vb = new QHBox ( this );
QPixmap iconp;
vb->setMargin ( KDialog::marginHint()-1 );
QPushButton * toggleJournal = new QPushButton( vb );
iconp = SmallIcon("1updownarrow");
toggleJournal->setPixmap (iconp ) ;
QLabel* textLabel = new QLabel(" "+i18n("Title: "),vb);
mTitle = new KOLocationBox(TRUE, vb, 30);
mTitle->setSizePolicy( QSizePolicy( QSizePolicy::Preferred ,QSizePolicy::Fixed ,FALSE) );
mCalendarBox = new QComboBox(vb);
mCalendarBox->setSizePolicy( QSizePolicy( QSizePolicy::Preferred ,QSizePolicy::Fixed ,FALSE) );
#ifndef DESKTOP_VERSION
mTitle->setSizeLimit( 8 );
mCalendarBox->setSizeLimit( 8 );
#endif
vb->setStretchFactor ( mTitle, 8 );
int limit = 3;
if ( QApplication::desktop()->width() < 640 )
limit = 6;
vb->setStretchFactor ( mCalendarBox, limit );
//mTitleLabel->setMargin(0);
//mTitleLabel->setAlignment(AlignCenter);
QPushButton * loadTemplate = new QPushButton( vb );
QPushButton * saveTemplate = new QPushButton( vb );
if ( QApplication::desktop()->width() < 321 )
iconp = SmallIcon("fileexport16");
else
iconp = SmallIcon("fileexport");
saveTemplate->setPixmap (iconp ) ;
int size = saveTemplate->sizeHint().height();
if ( QApplication::desktop()->width() < 321 )
iconp = SmallIcon("fileimport16");
else
iconp = SmallIcon("fileimport");
loadTemplate->setPixmap (iconp ) ;
loadTemplate->setFixedSize( size, size );
saveTemplate->setFixedSize( size, size );
int widwid = size;
if ( QApplication::desktop()->width() < 320 )
widwid = size/2+1;
toggleJournal->setFixedSize( widwid , size );
mTitle->setFixedHeight( size+4);
mCalendarBox->setFixedHeight( size+4);
mEditor = new KTextEdit(this);
#ifndef DESKTOP_VERSION
QPEApplication::setStylusOperation( mEditor, QPEApplication::RightOnHold );
#endif
mMaxWidDiff = 3*size - 2*frameWidth() - textLabel->sizeHint().width();
mDeskWid = QApplication::desktop()->width();
int maxwid = mDeskWid - mMaxWidDiff;
if ( QApplication::desktop()->width() < 640 ) {
mTitle->setMaximumWidth( maxwid/2 +20 );
mCalendarBox->setMaximumWidth( maxwid/2 -20);
} else {
mTitle->setMaximumWidth( (maxwid/4)*3);
mCalendarBox->setMaximumWidth( maxwid/2 );
}
//mCalendarBox->setMaximumWidth( maxwid/2 -20 );
mEditor->setWordWrap( KTextEdit::WidgetWidth );
QBoxLayout *topLayout = new QVBoxLayout(this);
topLayout->addWidget(vb);
topLayout->addWidget(mEditor);
mEditor->installEventFilter(this);
connect( saveTemplate, SIGNAL( clicked() ), this , SLOT( slotSaveTemplate() ) );
connect( loadTemplate, SIGNAL( clicked() ), this , SLOT( slotLoadTemplate() ) );
connect( toggleJournal, SIGNAL( clicked() ), this , SLOT( toggleShowJournal() ) );
mTitle->load( KOLocationBox::SUMMARYJOURNAL );
mTitle->lineEdit ()->setText("");
}
JournalEntry::~JournalEntry()
{
//qDebug("JournalEntry::~JournalEntry() ");
}
void JournalEntry::resizeEvent(QResizeEvent* e )
{
#ifndef DESKTOP_VERSION
if ( mDeskWid != QApplication::desktop()->width() ) {
mDeskWid == QApplication::desktop()->width();
int maxwid = mDeskWid - mMaxWidDiff;
if ( QApplication::desktop()->width() < 640 ) {
mTitle->setMaximumWidth( maxwid/2 +20 );
mCalendarBox->setMaximumWidth( maxwid/2 -20);
}
else {
mTitle->setMaximumWidth( (maxwid/4)*3);
mCalendarBox->setMaximumWidth( maxwid/2 );
}
//mCalendarBox->setMaximumWidth( maxwid/2 -20 );
}
//setMaximumWidth( QApplication::desktop()->width() );
//qDebug("MAXXX %d ", QApplication::desktop()->width());
#endif
QFrame::resizeEvent( e );
}
QSize JournalEntry::sizeHint() const
{
return QSize ( 240, heiHint );
}
void JournalEntry::slotSaveTemplate()
{
QString fileName =locateLocal( "templates", "journals" );
QDir t_dir;
if ( !t_dir.exists(fileName) )
t_dir.mkdir ( fileName );
fileName += "/journal";
fileName = KFileDialog::getSaveFileName( fileName , i18n("Save as Journal template"), this );
if ( fileName.length() == 0 )
return;
QFile fileIn( fileName );
if (!fileIn.open( IO_WriteOnly ) ) {
KMessageBox::error( this, i18n("Error saving template file\n '%1'.")
.arg( fileName ) );
return;
}
// QString text;
QTextStream tsIn( &fileIn );
tsIn.setCodec( QTextCodec::codecForName("utf8") );
tsIn << mEditor->text();
fileIn.close();
}
void JournalEntry::slotLoadTemplate()
{
QString fileName =locateLocal( "templates", "journals" );
QDir t_dir;
if ( !t_dir.exists(fileName) )
t_dir.mkdir ( fileName );
fileName += "/journal";
fileName = KFileDialog::getOpenFileName( fileName , i18n("Insert Journal template"), this );
if ( fileName.length() == 0 )
return;
QFile fileIn( fileName );
if (!fileIn.open( IO_ReadOnly ) ) {
KMessageBox::error( this, i18n("Error loading template file\n '%1'.")
.arg( fileName ) );
return;
}
QTextStream tsIn( &fileIn );
tsIn.setCodec( QTextCodec::codecForName("utf8") );
QString text = tsIn.read();
fileIn.close();
int line, col;
mEditor->getCursorPosition (& line, & col );
mEditor-> insertAt ( text, line, col, true );
//mEditor->setIgnoreMark( true );
}
void JournalEntry::setDate(const QDate &date)
{
showOnlyMode = false;
writeJournal();
mDate = date;
fillCalendar( mCalendar->defaultCalendar() );
}
void JournalEntry::fillCalendar( int setToID )
{
mCalendarBox->clear();
KopiCalendarFile * kkf = KOPrefs::instance()->mCalendars.first();
int std = 0;
int count = 0;
while ( kkf ) {
if ( (!kkf->mErrorOnLoad &&! kkf->isReadOnly) || setToID == kkf->mCalNumber ) {
if ( setToID ) {
if ( kkf->mCalNumber == setToID )
std = count;
} else {
if ( kkf->isStandard ) {
std = count;
}
}
++count;
mCalendarBox->insertItem( kkf->mName );
}
kkf = KOPrefs::instance()->mCalendars.next();
}
mCalendarBox->setCurrentItem( std );
}
void JournalEntry::toggleShowJournal()
-{
+{
+ if ( mEditor->text().isEmpty() && mTitle->currentText ().isEmpty() )
+ return;
if (!mEditor->text().isEmpty() || !mTitle->currentText ().isEmpty())
flushEntry();
if ( showOnlyMode )
emit showJournalOnly( 0 );
else {
// we have to protect mJournal from deleting if mJournal has empty text
visibleMode = false; // set to true via :setShowOnly()
emit showJournalOnly( mJournal );
//QTimer::singleShot( 0, this, SLOT( setVisibleOn() ) );
}
}
void JournalEntry::setVisibleOn()
{
visibleMode = true;
}
void JournalEntry::setShowOnly()
{
showOnlyMode = true;
if ( mTitle->currentText().isEmpty() )
mTitle->setFocus();
else
mEditor->setFocus();
}
void JournalEntry::setJournal(Journal *journal, bool saveJournal )
{
if ( saveJournal )
writeJournal();
mTitle->load( KOLocationBox::SUMMARYJOURNAL );
mJournal = journal;
if ( journal->isReadOnly() )
mTitle->lineEdit ()->setText(mJournal->summary()+" ("+i18n("readonly")+")");
else
mTitle->lineEdit ()->setText(mJournal->summary());
mEditor->setText(mJournal->description());
mTitle->setEnabled (!journal->isReadOnly() );
mEditor->setReadOnly ( journal->isReadOnly() );
mCalendarBox->setEnabled (!journal->isReadOnly() );
fillCalendar( mJournal->calID() );
}
Journal *JournalEntry::journal() const
{
return mJournal;
}
void JournalEntry::clear()
{
mJournal = 0;
mEditor->setText("");
mTitle->load( KOLocationBox::SUMMARYJOURNAL );
mTitle->lineEdit ()->setText("");
}
bool JournalEntry::eventFilter( QObject *o, QEvent *e )
{
// kdDebug() << "JournalEntry::event received " << e->type() << endl;
if ( e->type() == QEvent::FocusOut ) {
writeJournal();
}
if ( e->type() == QEvent::KeyPress ) {
QKeyEvent * k = (QKeyEvent *) e;
if ( k->state() == Qt::ControlButton ) {
k->ignore();
//return true;
}
}
return QFrame::eventFilter( o, e ); // standard event processing
}
void JournalEntry::writeJournal()
{
if ( !visibleMode ) return;
if ( !mTitle->isEnabled() ) return;
if (mEditor->text().isEmpty() && mTitle->currentText().isEmpty()) {
if ( mJournal ) {
Journal* j = mJournal;
mJournal = 0;
bool conf = KOPrefs::instance()->mConfirm;
KOPrefs::instance()->mConfirm = false;
emit deleteJournal(j);
KOPrefs::instance()->mConfirm = conf;
}
return;
}
// kdDebug() << "JournalEntry::writeJournal()..." << endl;
if (!mJournal) {
mJournal = new Journal;
mJournal->setDtStart(QDateTime(mDate,QTime(0,0,0)));
mCalendar->addJournal(mJournal);
}
if ( mJournal->description() != mEditor->text() ) {
mJournal->setDescription(mEditor->text());
}
if ( mJournal->summary() != mTitle->currentText() ) {
mJournal->setSummary(mTitle->currentText());
mTitle->save(KOLocationBox::SUMMARYJOURNAL);
}
int id = KOPrefs::instance()->getCalendarID( mCalendarBox->currentText() );
if ( mJournal->calID() != id ) {
mJournal->setCalID( id );
}
}
void JournalEntry::flushEntry()
{
writeJournal();
}
void JournalEntry::keyPressEvent ( QKeyEvent * e )
{
e->ignore();
}
diff --git a/korganizer/koagenda.cpp b/korganizer/koagenda.cpp
index c738f7e..7e9fa71 100644
--- a/korganizer/koagenda.cpp
+++ b/korganizer/koagenda.cpp
@@ -1,1142 +1,1146 @@
/*
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;
}
-
+void MarcusBains::hideMe()
+{
+ hide(); mTimeBox->hide();
+}
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);
int secs = QTime::currentTime().second();
minutes->start( (60 - secs +1)*1000 ,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)
{
mAllAgendaPopup = 0;
mColumns = columns;
mRows = rows;
mGridSpacingY = rowSize;
mAllDayMode = false;
#ifndef DESKTOP_VERSION
//QPEApplication::setStylusOperation( viewport(), QPEApplication::RightOnHold );
#endif
mHolidayMask = 0;
init();
connect ( this, SIGNAL (contentsMoving ( int , int ) ), this, SLOT ( slotContentMove(int,int)) );
}
/*
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)
{
mAllAgendaPopup = 0;
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 );
#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("This 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;
mInvalidPixmap = false;
}
void KOAgenda::shrinkPixmap()
{
mPaintPixmap.resize( 20,20);
mInvalidPixmap = true;
}
void KOAgenda::slotContentMove(int,int)
{
emit sendPing();
if ( mActionType == NOP )
slotClearSelection();
if ( mSelectedItem && !mActionItem ) {
deselectItem();
emit incidenceSelected( 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) {
qDebug("KOAgenda::changeColumns() called with argument 0 ");
return;
}
clear();
mColumns = columns;
computeSizes();
+ if(mMarcusBains) mMarcusBains->hideMe();
}
/*
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 || mPopupKind == 3 ) {
if (mActionItem ) {
endItemAction();
}
mLeftMouseDown = false; // no more leftMouse computation
if (mPopupItem) {
//mClickedItem = mPopupItem;
selectItem(mPopupItem);
if ( mAllAgendaPopup && KOPrefs::instance()->mBlockPopupMenu && mPopupKind == 1 )
mAllAgendaPopup->installEventFilter( this );
emit showIncidencePopupSignal(mPopupItem->incidence());
}
} else if ( mPopupKind == 2 || mPopupKind == 4 ) {
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
}
if ( KOPrefs::instance()->mBlockPopupMenu && mPopupKind == 2 )
mNewItemPopup->installEventFilter( this );
mNewItemPopup->popup( mPopupPos);
}
mLeftMouseDown = false;
mPopupItem = 0;
mPopupKind = 0;
}
void KOAgenda::categoryChanged(Incidence * inc)
{
KOAgendaItem *item;
for ( item=mItems.first(); item != 0; item=mItems.next() ) {
if ( item->incidence() == inc ) {
item->initColor ();
item->updateItem();
}
}
}
bool KOAgenda::eventFilter_mouse(QObject *object, QMouseEvent *me)
{
if ( mInvalidPixmap ) {
mInvalidPixmap = false;
qDebug("KO: Upsizing Pixmaps ");
computeSizes();
emit updateViewSignal();
return true;
}
emit sendPing();
static int startX = 0;
static int startY = 0;
int blockmoveDist = ( QApplication::desktop()->width() < 480 ? 7 : 9 );
static bool blockMoving = true;
//qDebug("KOAgenda::eventFilter_mous ");
if ( object == mNewItemPopup ) {
//qDebug("mNewItemPopup ");
if ( me->type() == QEvent::MouseButtonRelease ) {
mNewItemPopup->removeEventFilter( this );
int dX = me->globalPos().x() - mPopupPos.x();;
if ( dX < 0 )
dX = -dX;
int dY = me->globalPos().y() - mPopupPos.y();
if ( dY < 0 )
dY = -dY;
if ( dX > blockmoveDist || dY > blockmoveDist ) {
mNewItemPopup->hide();
}
}
return true;
}
if ( object == mAllAgendaPopup ) {
//qDebug(" mAllAgendaPopup ");
if ( me->type() == QEvent::MouseButtonRelease ) {
mAllAgendaPopup->removeEventFilter( this );
int dX = me->globalPos().x() - mPopupPos.x();;
if ( dX < 0 )
dX = -dX;
int dY = me->globalPos().y() - mPopupPos.y();
if ( dY < 0 )
dY = -dY;
if ( dX > blockmoveDist || dY > blockmoveDist ) {
mAllAgendaPopup->hide();
}
}
return true;
}
QPoint viewportPos;
if (object != viewport()) {
blockmoveDist = blockmoveDist*2;
viewportPos = ((QWidget *)object)->mapToParent(me->pos());
} else {
viewportPos = me->pos();
}
bool objIsNotViewport = (object != viewport());
bool leftButt = false;
#ifdef DESKTOP_VERSION
leftButt = (me->button() == LeftButton);
#endif
switch (me->type()) {
case QEvent::MouseButtonPress:
if (me->button() == LeftButton) {
mPopupTimer->start( 600 );
mLeftMouseDown = true;
}
blockMoving = true;
startX = viewportPos.x();
startY = viewportPos.y();
mPopupPos = me->globalPos();
if ( objIsNotViewport && !leftButt ) {
KOAgendaItem * tempItem = (KOAgendaItem *)object;
if (mAllDayMode) {
if ( tempItem->height() > 10 ) {
int minV = tempItem->height()/4;
if ( minV > (blockmoveDist/2)-2 ) {
if ( minV > blockmoveDist )
minV = blockmoveDist;
else
minV = (blockmoveDist/2);
}
bool border = false;
int diff = tempItem->y() - viewportPos.y();
if ( diff < 0 )
diff *= -1;
if ( diff < minV ) {
border = true;
objIsNotViewport = false;
}
if ( ! border ) {
diff = tempItem->y() + tempItem->height()- viewportPos.y();
if ( diff < 0 )
diff *= -1;
if ( diff < minV ) {
border = true;
objIsNotViewport = false;
}
}
}
} else { // not allday
if ( tempItem->width() > 10 ) {
int minH = tempItem->width()/4;
if ( minH > (blockmoveDist/2)-2 ) {
if ( minH > blockmoveDist )
minH = blockmoveDist;
else
minH = (blockmoveDist/2);
}
bool border = false;
int diff = tempItem->x() - viewportPos.x();
if ( diff < 0 )
diff *= -1;
if ( diff < minH ) {
border = true;
objIsNotViewport = false;
}
if ( ! border ) {
diff = tempItem->x() + tempItem->width() - viewportPos.x();
if ( diff < 0 )
diff *= -1;
if ( diff < minH ) {
border = true;
objIsNotViewport = false;
}
}
}
}
}
if ( objIsNotViewport ) {
mPopupItem = (KOAgendaItem *)object;
mPopupKind = 1;
if (me->button() == RightButton) {
mPopupKind = 3;
popupMenu();
} else if (me->button() == LeftButton) {
mActionItem = (KOAgendaItem *)object;
if (mActionItem) {
emit signalClearSelection();
slotClearSelection();
selectItem(mActionItem);
Incidence *incidence = mActionItem->incidence();
if ( incidence->isReadOnly() /*|| incidence->doesRecur() */) {
mActionItem = 0;
} else {
startItemAction(viewportPos);
}
}
}
} else { // ---------- viewport()
mPopupItem = 0;
mPopupKind = 2;
selectItem(0);
mActionItem = 0;
if (me->button() == RightButton) {
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;
mPopupKind = 4;
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:
//qDebug("mm ");
if ( !mLeftMouseDown )
return false;
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;
}
void KOAgenda::newItem( int item )
{
if ( item == 1 ) { //new event
newEventSignal(mStartCellX ,mStartCellY );
} else
if ( item == 2 ) { //new event
newTodoSignal(mStartCellX ,mStartCellY );
} else
{
emit showDateView( item, mStartCellX );
// 3Day view
// 4Week view
// 5Month view
// 6Journal view
}
}
void KOAgenda::slotClearSelection()
{
if (mSelectionHeight) {
int selectionX = mSelectionCellX * mGridSpacingX;
int top = mSelectionYTop - 2 *mGridSpacingY;
int hei = mSelectionHeight + 4 *mGridSpacingY;
clearSelection();
repaintContents( selectionX, top,
mGridSpacingX, hei ,false );
}
}
void KOAgenda::startSelectAction(QPoint viewportPos)
{
emit signalClearSelection();
slotClearSelection();
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 new selection
mSelectionCellX = gx;
mSelectionYTop = gy * mGridSpacingY;
mSelectionHeight = mGridSpacingY;
// Paint new selection
repaintContents( mSelectionCellX * mGridSpacingX+1, mSelectionYTop,
mGridSpacingX-1, 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;
repaintContents( (KOGlobals::self()->reverseLayout() ?
mColumns - 1 - mSelectionCellX : mSelectionCellX) *
mGridSpacingX, mSelectionYTop,
mGridSpacingX, mSelectionHeight , false);
mCurrentCellY = gy;
} else if ( gy < mCurrentCellY ) {
if ( gy >= mStartCellY ) {
int selectionHeight = mSelectionHeight;
mSelectionHeight = ( gy + 1 ) * mGridSpacingY - mSelectionYTop;
repaintContents( (KOGlobals::self()->reverseLayout() ?
mColumns - 1 - mSelectionCellX : mSelectionCellX) *
mGridSpacingX, mSelectionYTop,
mGridSpacingX, selectionHeight,false );
mCurrentCellY = gy;
} else {
}
}
}
void KOAgenda::endSelectAction( bool emitNewEvent )
{
mActionType = NOP;
mScrollUpTimer.stop();
mScrollDownTimer.stop();
emit newTimeSpanSignal(mStartCellX,mStartCellY,mCurrentCellX,mCurrentCellY);
if ( emitNewEvent && mStartCellY < mCurrentCellY ) {
emit newEventSignal(mStartCellX,mStartCellY,mCurrentCellX,mCurrentCellY);
}
}
void KOAgenda::startItemAction(QPoint viewportPos)
{
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;
if (mAllDayMode) {
int gridDistanceX = (x - gx * mGridSpacingX);
if (gridDistanceX < mResizeBorderWidth &&
mActionItem->cellX() == mCurrentCellX) {
mActionType = RESIZELEFT;
setCursor(sizeHorCursor);
} else if ((mGridSpacingX - gridDistanceX) < mResizeBorderWidth &&
mActionItem->cellXWidth() == mCurrentCellX) {
mActionType = RESIZERIGHT;
setCursor(sizeHorCursor);
} else {
mActionType = MOVE;
mActionItem->startMove();
setCursor(sizeAllCursor);
}
} else {
int gridDistanceY = (y - gy * mGridSpacingY);
bool allowResize = ( mActionItem->incidence()->typeID() != todoID );
if (allowResize && gridDistanceY < mResizeBorderWidth &&
mActionItem->cellYTop() == mCurrentCellY &&
!mActionItem->firstMultiItem()) {
mActionType = RESIZETOP;
setCursor(sizeVerCursor);
} else if (allowResize &&(mGridSpacingY - gridDistanceY) < mResizeBorderWidth &&
mActionItem->cellYBottom() == mCurrentCellY &&
!mActionItem->lastMultiItem()) {
mActionType = RESIZEBOTTOM;
setCursor(sizeVerCursor);
} else {
mActionType = MOVE;
mActionItem->startMove();
setCursor(sizeAllCursor);
}
}
}
void KOAgenda::performItemAction(QPoint viewportPos)
{
// kdDebug() << "viewportPos: " << viewportPos.x() << "," << viewportPos.y() << endl;
// QPoint point = viewport()->mapToGlobal(viewportPos);
// kdDebug() << "Global: " << point.x() << "," << point.y() << endl;
// point = clipper()->mapFromGlobal(point);
// kdDebug() << "clipper: " << point.x() << "," << point.y() << endl;
// kdDebug() << "visible height: " << visibleHeight() << endl;
int x,y;
viewportToContents(viewportPos.x(),viewportPos.y(),x,y);
// kdDebug() << "contents: " << x << "," << y << "\n" << endl;
int gx,gy;
contentsToGrid(x,y,gx,gy);
QPoint clipperPos = clipper()->
mapFromGlobal(viewport()->mapToGlobal(viewportPos));
// Cursor left active agenda area.
// This starts a drag.
if ( /*clipperPos.y() < 0 || clipperPos.y() > visibleHeight() ||*/
clipperPos.x() < 0 || clipperPos.x() > visibleWidth() ) {
if ( mActionType == MOVE ) {
mScrollUpTimer.stop();
mScrollDownTimer.stop();
mActionItem->resetMove();
placeSubCells( mActionItem );
// emit startDragSignal( mActionItem->incidence() );
setCursor( arrowCursor );
mActionItem = 0;
mActionType = NOP;
mItemMoved = 0;
return;
}
} else {
switch ( mActionType ) {
case MOVE:
setCursor( sizeAllCursor );
break;
case RESIZETOP:
case RESIZEBOTTOM:
setCursor( sizeVerCursor );
break;
case RESIZELEFT:
case RESIZERIGHT:
setCursor( sizeHorCursor );
break;
default:
setCursor( arrowCursor );
}
}
// Scroll if item 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();
}
// Move or resize item if necessary
if (mCurrentCellX != gx || mCurrentCellY != gy) {
mItemMoved = true;
mActionItem->raise();
if (mActionType == MOVE) {
// Move all items belonging to a multi item
KOAgendaItem *moveItem = mActionItem->firstMultiItem();
bool isMultiItem = (moveItem || mActionItem->lastMultiItem());
if (!moveItem) moveItem = mActionItem;
while (moveItem) {
int dy;
if (isMultiItem) dy = 0;
else dy = gy - mCurrentCellY;
moveItem->moveRelative(gx - mCurrentCellX,dy);
int x,y;
gridToContents(moveItem->cellX(),moveItem->cellYTop(),x,y);
moveItem->resize(mGridSpacingX * moveItem->cellWidth(),
mGridSpacingY * moveItem->cellHeight());
moveItem->raise();
moveChild(moveItem,x,y);
moveItem = moveItem->nextMultiItem();
}
} else if (mActionType == RESIZETOP) {
if (mCurrentCellY <= mActionItem->cellYBottom()) {
mActionItem->expandTop(gy - mCurrentCellY);
mActionItem->resize(mActionItem->width(),
mGridSpacingY * mActionItem->cellHeight());
int x,y;
gridToContents(mCurrentCellX,mActionItem->cellYTop(),x,y);
//moveChild(mActionItem,childX(mActionItem),y);
QScrollView::moveChild( mActionItem,childX(mActionItem),y );
}
} else if (mActionType == RESIZEBOTTOM) {
if (mCurrentCellY >= mActionItem->cellYTop()) {
mActionItem->expandBottom(gy - mCurrentCellY);
mActionItem->resize(mActionItem->width(),
mGridSpacingY * mActionItem->cellHeight());
}
} else if (mActionType == RESIZELEFT) {
if (mCurrentCellX <= mActionItem->cellXWidth()) {
mActionItem->expandLeft(gx - mCurrentCellX);
mActionItem->resize(mGridSpacingX * mActionItem->cellWidth(),
mActionItem->height());
int x,y;
gridToContents(mActionItem->cellX(),mActionItem->cellYTop(),x,y);
moveChild(mActionItem,x,childY(mActionItem));
}
} else if (mActionType == RESIZERIGHT) {
if (mCurrentCellX >= mActionItem->cellX()) {
mActionItem->expandRight(gx - mCurrentCellX);
mActionItem->resize(mGridSpacingX * mActionItem->cellWidth(),
mActionItem->height());
}
}
mCurrentCellX = gx;
mCurrentCellY = gy;
}
}
void KOAgenda::endItemAction()
{
if ( mItemMoved ) {
KOAgendaItem *placeItem = mActionItem->firstMultiItem();
if ( !placeItem ) {
placeItem = mActionItem;
}
if ( placeItem->incidence()->doesRecur() ) {
Incidence* oldInc = placeItem->incidence();
placeItem->recreateIncidence();
emit addToCalSignal(placeItem->incidence(), oldInc );
}
int type = mActionType;
if ( mAllDayMode )
type = -1;
KOAgendaItem *modifiedItem = placeItem;
//emit itemModified( placeItem, mActionType /*KOGlobals::EVENTEDITED */);
QPtrList<KOAgendaItem> oldconflictItems ;//= placeItem->conflictItems();
KOAgendaItem *item;
if ( placeItem->incidence()->typeID() == todoID ) {
mSelectedItem = 0;
//qDebug("todo %d %d %d ", mCurrentCellX, modifiedItem->cellX() ,modifiedItem->cellXWidth());
modifiedItem->mLastMoveXPos = mCurrentCellX;
emit itemModified( modifiedItem, mActionType );
}
else {
globalFlagBlockAgendaItemPaint = 1;
for ( item=oldconflictItems.first(); item != 0;
item=oldconflictItems.next() ) {
placeSubCells(item);
}
while ( placeItem ) {
//qDebug("placeItem %s ", placeItem->incidence()->summary().latin1());
oldconflictItems = placeItem->conflictItems();
for ( item=oldconflictItems.first(); item != 0;
item=oldconflictItems.next() ) {
placeSubCells(item);
}
placeSubCells( placeItem );
placeItem = placeItem->nextMultiItem();
}
globalFlagBlockAgendaItemPaint = 0;
for ( item=oldconflictItems.first(); item != 0;
item=oldconflictItems.next() ) {
globalFlagBlockAgendaItemUpdate = 0;
item->repaintMe();
globalFlagBlockAgendaItemUpdate = 1;
item->repaint( false );
}
placeItem = modifiedItem;
while ( placeItem ) {
//qDebug("placeItem %s ", placeItem->incidence()->summary().latin1());
globalFlagBlockAgendaItemUpdate = 0;
placeItem->repaintMe();
globalFlagBlockAgendaItemUpdate = 1;
placeItem->repaint(false);
placeItem = placeItem->nextMultiItem();
}
emit itemModified( modifiedItem, mActionType );
placeItem = modifiedItem;
while ( placeItem ) {
oldconflictItems = placeItem->conflictItems();
for ( item=oldconflictItems.first(); item != 0;
item=oldconflictItems.next() ) {
placeSubCells(item);
}
placeSubCells( placeItem );
placeItem = placeItem->nextMultiItem();
}
placeItem = modifiedItem;
while ( placeItem ) {
oldconflictItems = placeItem->conflictItems();
for ( item=oldconflictItems.first(); item != 0;
item=oldconflictItems.next() ) {
globalFlagBlockAgendaItemUpdate = 0;
item->repaintMe();
globalFlagBlockAgendaItemUpdate = 1;
item->repaint(false);
}
placeItem = placeItem->nextMultiItem();
}
/*
oldconflictItems = modifiedItem->conflictItems();
for ( item=oldconflictItems.first(); item != 0;
item=oldconflictItems.next() ) {
globalFlagBlockAgendaItemUpdate = 0;
item->paintMe(false);
globalFlagBlockAgendaItemUpdate = 1;
item->repaint(false);
}
*/
}
}
if ( mActionItem )
emit incidenceSelected( mActionItem->incidence() );
mScrollUpTimer.stop();
mScrollDownTimer.stop();
setCursor( arrowCursor );
mActionItem = 0;
mActionType = NOP;
mItemMoved = 0;
}
void KOAgenda::setNoActionCursor(KOAgendaItem *moveItem,QPoint viewportPos)
{
// kdDebug() << "viewportPos: " << viewportPos.x() << "," << viewportPos.y() << endl;
// QPoint point = viewport()->mapToGlobal(viewportPos);
// kdDebug() << "Global: " << point.x() << "," << point.y() << endl;
// point = clipper()->mapFromGlobal(point);
// kdDebug() << "clipper: " << point.x() << "," << point.y() << endl;
int x,y;
viewportToContents(viewportPos.x(),viewportPos.y(),x,y);
// kdDebug() << "contents: " << x << "," << y << "\n" << endl;
int gx,gy;
contentsToGrid(x,y,gx,gy);
// Change cursor to resize cursor if appropriate
if (mAllDayMode) {
int gridDistanceX = (x - gx * mGridSpacingX);
if (gridDistanceX < mResizeBorderWidth &&
moveItem->cellX() == gx) {
setCursor(sizeHorCursor);
} else if ((mGridSpacingX - gridDistanceX) < mResizeBorderWidth &&
moveItem->cellXWidth() == gx) {
setCursor(sizeHorCursor);
} else {
setCursor(arrowCursor);
}
} else {
int gridDistanceY = (y - gy * mGridSpacingY);
if (gridDistanceY < mResizeBorderWidth &&
moveItem->cellYTop() == gy &&
!moveItem->firstMultiItem()) {
setCursor(sizeVerCursor);
} else if ((mGridSpacingY - gridDistanceY) < mResizeBorderWidth &&
diff --git a/korganizer/koagenda.h b/korganizer/koagenda.h
index 86cf2f4..59e7472 100644
--- a/korganizer/koagenda.h
+++ b/korganizer/koagenda.h
@@ -1,307 +1,307 @@
/*
This file is part of KOrganizer.
Copyright (c) 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 KOAGENDA_H
#define KOAGENDA_H
#include <qscrollview.h>
#include <qtimer.h>
#include <qmemarray.h>
#include <qpainter.h>
#include <qpixmap.h>
#include <qguardedptr.h>
#include "koagendaitem.h"
#include "koeventview.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();
-
+ void hideMe();
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();
bool mInvalidPixmap;
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();
void setPopup( KOEventPopupMenu * p ) { mAllAgendaPopup = p; }
void shrinkPixmap();
QTime getEndTime();
public slots:
void slotContentMove(int,int);
void categoryChanged(Incidence * inc);
void slotClearSelection();
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 signalClearSelection();
void showDateView( int, int);
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();
void updateViewSignal();
void sendPing();
protected:
KOEventPopupMenu * mAllAgendaPopup;
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/kotodoview.cpp b/korganizer/kotodoview.cpp
index f46a103..82c0f4c 100644
--- a/korganizer/kotodoview.cpp
+++ b/korganizer/kotodoview.cpp
@@ -592,1133 +592,1133 @@ KOTodoView::KOTodoView(Calendar *calendar,QWidget* parent,const char* name) :
mTodoListView->addColumn(i18n("Created"));
mTodoListView->addColumn(i18n("Last Modified Sub"));
#if 0
mTodoListView->addColumn(i18n("Sort Id"));
mTodoListView->setColumnAlignment(4,AlignHCenter);
#endif
mTodoListView->setMinimumHeight( 60 );
mTodoListView->setItemsRenameable( true );
mTodoListView->setRenameable( 0 );
mTodoListView->setColumnWidth( 0, 120 );
int iii = 0;
for ( iii = 0; iii< 12 ; ++iii )
mTodoListView->setColumnWidthMode( iii, QListView::Manual );
mKOTodoViewWhatsThis = new KOTodoViewWhatsThis(mTodoListView->viewport(),this);
mPriorityPopupMenu = new QPopupMenu(this);
for (int i = 1; i <= 5; i++) {
QString label = QString ("%1").arg (i);
mPriority[mPriorityPopupMenu->insertItem (label)] = i;
}
connect (mPriorityPopupMenu, SIGNAL(activated (int)), SLOT (setNewPriority(int)));
mPercentageCompletedPopupMenu = new QPopupMenu(this);
for (int i = 0; i <= 100; i+=20) {
QString label = QString ("%1 %").arg (i);
mPercentage[mPercentageCompletedPopupMenu->insertItem (label)] = i;
}
connect (mPercentageCompletedPopupMenu, SIGNAL (activated (int)), SLOT (setNewPercentage (int)));
mCategoryPopupMenu = new QPopupMenu (this);
mCategoryPopupMenu->setCheckable (true);
connect (mCategoryPopupMenu, SIGNAL (activated (int)), SLOT (changedCategories (int)));
connect (mCategoryPopupMenu, SIGNAL (aboutToShow ()), SLOT (fillCategories ()));
mCalPopupMenu = new QPopupMenu (this);
mCalPopupMenu->setCheckable (true);
connect (mCalPopupMenu, SIGNAL (activated (int)), SLOT (changedCal (int)));
connect (mCalPopupMenu, SIGNAL (aboutToShow ()), SLOT (fillCal ()));
mItemPopupMenu = new QPopupMenu(this);
mItemPopupMenu->insertItem(i18n("Show"), this,
SLOT (showTodo()));
mItemPopupMenu->insertItem(i18n("Edit..."), this,
SLOT (editTodo()));
mItemPopupMenu->insertItem( i18n("Delete..."), this,
SLOT (deleteTodo()));
mItemPopupMenu->insertItem( i18n("Clone..."), this,
SLOT (cloneTodo()));
mItemPopupMenu->insertItem( i18n("Move..."), this,
SLOT (moveTodo()));
#ifndef DESKTOP_VERSION
mItemPopupMenu->insertItem( i18n("Beam..."), this,
SLOT (beamTodo()));
#endif
mItemPopupMenu->insertItem( i18n("Toggle Cancel"), this,
SLOT (cancelTodo()));
mItemPopupMenu->insertItem( i18n("Categories"), mCategoryPopupMenu);
mItemPopupMenu->insertItem( i18n("Calendar"), mCalPopupMenu);
mItemPopupMenu->insertSeparator();
mItemPopupMenu->insertItem( i18n("Start/Stop todo..."), this,
SLOT (toggleRunningItem()));
mItemPopupMenu->insertSeparator();
/*
mItemPopupMenu->insertItem( i18n("New Todo..."), this,
SLOT (newTodo()));
*/
mItemPopupMenu->insertItem(i18n("New Sub-Todo..."), this,
SLOT (newSubTodo()));
mItemPopupMenu->insertItem(i18n("Unparent Todo"), this,
SLOT (unparentTodo()),0,21);
mItemPopupMenu->insertItem(i18n("Reparent Todo"), this,
SLOT (reparentTodo()),0,22);
mItemPopupMenu->insertSeparator();
#if 0
mItemPopupMenu->insertItem(i18n("Delete completed To-Dos","Purge Completed..."),
this, SLOT( purgeCompleted() ) );
mItemPopupMenu->insertItem(i18n("toggle completed To-Dos","Show Completed"),
this, SLOT( toggleCompleted() ),0, 33 );
mItemPopupMenu->insertItem(i18n("toggle quick todo","Show Quick Todo"),
this, SLOT( toggleQuickTodo() ),0, 34 );
mItemPopupMenu->insertItem(i18n("toggle running todo","Hide not Running"),
this, SLOT( toggleRunning() ),0, 35 );
#endif
mPopupMenu = new QPopupMenu(this);
mPopupMenu->insertItem(SmallIconSet("todo"), i18n("New Todo..."), this,
SLOT (newTodo()),0,1);
mPopupMenu->insertItem(i18n("delete completed To-Dos","Purge Completed..."),
this, SLOT(purgeCompleted()),0,2);
mPopupMenu->insertItem(i18n("Show Completed"),
this, SLOT( toggleCompleted() ),0,3 );
mPopupMenu->insertItem(i18n("toggle running todo","Hide not Running"),
this, SLOT( toggleRunning() ),0,5 );
mPopupMenu->insertItem(i18n(" set all open","Display all opened"),
this, SLOT( setAllOpen() ),0,6 );
mPopupMenu->insertItem(i18n(" set all close","Display all closed"),
this, SLOT( setAllClose() ),0,7 );
mPopupMenu->insertItem(i18n(" set all flat","Display all flat"),
this, SLOT( setAllFlat() ),0,8 );
mPopupMenu->insertSeparator();
mPopupMenu->insertItem(i18n("toggle quick todo","Show Quick Todo"),
this, SLOT( toggleQuickTodo() ),0,4 );
mDocPrefs = new DocPrefs( name );
mItemPopupMenu->insertItem(i18n("Todo View"),mPopupMenu );
mPopupMenu->setCheckable( true );
mItemPopupMenu->setCheckable( true );
mPopupMenu->setItemChecked( 3,KOPrefs::instance()->mShowCompletedTodo );
mItemPopupMenu->setItemChecked( 33 , KOPrefs::instance()->mShowCompletedTodo );
mPopupMenu->setItemChecked(4,KOPrefs::instance()->mEnableQuickTodo);
mItemPopupMenu->setItemChecked( 34 , KOPrefs::instance()->mEnableQuickTodo );
mPopupMenu->setItemChecked(5,KOPrefs::instance()->mHideNonStartedTodos);
mItemPopupMenu->setItemChecked( 35 , KOPrefs::instance()->mHideNonStartedTodos );
// Double clicking conflicts with opening/closing the subtree
connect( mTodoListView, SIGNAL( doubleClicked( QListViewItem *) ),
SLOT( editItem( QListViewItem *) ) );
/*
connect( mTodoListView, SIGNAL( rightButtonClicked ( QListViewItem *,
const QPoint &,int ) ),
SLOT( popupMenu( QListViewItem *, const QPoint & ,int) ) );
*/
connect( mTodoListView, SIGNAL( contextRequest ( QListViewItem *,
const QPoint &,int ) ),
SLOT( popupMenu( QListViewItem *, const QPoint & ,int) ) );
connect( mTodoListView, SIGNAL( clicked( QListViewItem * ) ),
SLOT( itemClicked( QListViewItem * ) ) );
connect( mTodoListView, SIGNAL( double_Clicked( QListViewItem * ) ),
SLOT( itemDoubleClicked( QListViewItem * ) ) );
connect( mTodoListView, SIGNAL( todoDropped( Todo *, int ) ),
SLOT( updateView() ) );
connect( mTodoListView, SIGNAL( todoDropped( Todo *, int ) ),
SLOT( todoModified(Todo *, int) ) );
connect( mTodoListView, SIGNAL( expanded( QListViewItem * ) ),
SLOT( itemStateChanged( QListViewItem * ) ) );
connect( mTodoListView, SIGNAL( collapsed( QListViewItem * ) ),
SLOT( itemStateChanged( QListViewItem * ) ) );
connect( mTodoListView, SIGNAL( paintNeeded() ),
SLOT( paintNeeded()) );
#if 0
connect(mTodoListView,SIGNAL(selectionChanged(QListViewItem *)),
SLOT(selectionChanged(QListViewItem *)));
connect(mTodoListView,SIGNAL(clicked(QListViewItem *)),
SLOT(selectionChanged(QListViewItem *)));
connect(mTodoListView,SIGNAL(pressed(QListViewItem *)),
SLOT(selectionChanged(QListViewItem *)));
#endif
connect( mTodoListView, SIGNAL(reparentTodoSignal( Todo *,Todo * ) ), SIGNAL(reparentTodoSignal( Todo *,Todo * ) ));
connect( mTodoListView, SIGNAL(unparentTodoSignal(Todo *) ), SIGNAL(unparentTodoSignal(Todo *) ));
connect( mTodoListView, SIGNAL( deleteTodo(Todo *) ), SIGNAL(deleteTodoSignal(Todo *) ));
connect( mTodoListView, SIGNAL(selectionChanged() ),
SLOT( processSelectionChange() ) );
connect( mQuickAdd, SIGNAL( returnPressed () ),
SLOT( addQuickTodo() ) );
}
KOTodoView::~KOTodoView()
{
#if QT_VERSION >= 0x030000
#else
delete mKOTodoViewWhatsThis;
#endif
delete mDocPrefs;
}
QString KOTodoView::getWhatsThisText(QPoint p)
{
KOTodoViewItem* item = ( KOTodoViewItem* ) mTodoListView->itemAt( p );
if ( item )
return KIncidenceFormatter::instance()->getFormattedText( item->todo(),
KOPrefs::instance()->mWTshowDetails,
KOPrefs::instance()->mWTshowCreated,
KOPrefs::instance()->mWTshowChanged);
return i18n("That is the todo view" );
}
void KOTodoView::jumpToDate ()
{
// if (mActiveItem) {
// mActiveItem->todo());
// if ( mActiveItem->todo()->hasDueDate() )
// emit mActiveItem->todo()jumpToTime( mTodo->dtDue().date() );
}
void KOTodoView::paintNeeded()
{
if ( mPendingUpdateBeforeRepaint ) {
updateView();
mPendingUpdateBeforeRepaint = false;
}
}
void KOTodoView::paintEvent(QPaintEvent * pevent)
{
if ( mPendingUpdateBeforeRepaint ) {
updateView();
mPendingUpdateBeforeRepaint = false;
}
KOrg::BaseView::paintEvent( pevent);
}
void KOTodoView::updateView()
{
pendingSubtodo = 0;
if ( mBlockUpdate ) {
return;
}
if ( !isVisible() ) {
mPendingUpdateBeforeRepaint = true;
return;
}
//qDebug("KOTodoView::updateView() %x", this);
if ( isFlatDisplay ) {
displayAllFlat();
return;
}
storeCurrentItem();
//qDebug("update ");
// kdDebug() << "KOTodoView::updateView()" << endl;
QFont fo = KOPrefs::instance()->mTodoViewFont;
mTodoListView->clear();
if ( mName == "todolistsmall" ) {
if ( KOPrefs::instance()->mTodoViewUsesSmallFont ) {
int ps = fo.pointSize() -2;
if ( ps > 12 )
ps -= 2;
fo.setPointSize( ps );
}
}
mTodoListView->setFont( fo );
// QFontMetrics fm ( KOPrefs::instance()->mTodoViewFont );
//mTodoListView->header()->setMaximumHeight(fm.height());
QPtrList<Todo> todoList = calendar()->todos();
/*
kdDebug() << "KOTodoView::updateView(): Todo List:" << endl;
Event *t;
for(t = todoList.first(); t; t = todoList.next()) {
kdDebug() << " " << t->getSummary() << endl;
if (t->getRelatedTo()) {
kdDebug() << " (related to " << t->getRelatedTo()->getSummary() << ")" << endl;
}
QPtrList<Event> l = t->getRelations();
Event *c;
for(c=l.first();c;c=l.next()) {
kdDebug() << " - relation: " << c->getSummary() << endl;
}
}
*/
// Put for each Event a KOTodoViewItem in the list view. Don't rely on a
// specific order of events. That means that we have to generate parent items
// recursively for proper hierarchical display of Todos.
mTodoMap.clear();
Todo *todo;
todo = todoList.first();// todo; todo = todoList.next()) {
while ( todo ) {
bool next = true;
// qDebug("todo %s ", todo->summary().latin1());
Incidence *incidence = todo->relatedTo();
while ( incidence ) {
if ( incidence->typeID() == todoID ) {
//qDebug("related %s ",incidence->summary().latin1() );
if ( !(todoList.contains ( ((Todo* )incidence ) ) ) && incidence->calEnabled() ) {
//qDebug("related not found ");
todoList.remove( );
todo = todoList.current();
next = false;
incidence = 0;
} else {
//qDebug("related found ");
incidence = incidence->relatedTo();
}
} else
incidence = 0;
}
if ( next )
todo = todoList.next();
}
for(todo = todoList.first(); todo; todo = todoList.next()) {
if (!mTodoMap.contains(todo) && checkTodo( todo ) )
{
insertTodoItem(todo);
}
}
// Restore opened/closed state
mTodoListView->blockSignals( true );
if( mDocPrefs ) restoreItemState( mTodoListView->firstChild() );
mTodoListView->blockSignals( false );
resetCurrentItem();
}
void KOTodoView::storeCurrentItem()
{
mCurItem = 0;
mCurItemRootParent = 0;
mCurItemParent = 0;
mCurItemAbove = 0;
mActiveItem = (KOTodoViewItem*)mTodoListView->currentItem();
if (mActiveItem) {
mCurItem = mActiveItem->todo();
KOTodoViewItem* activeItemAbove = (KOTodoViewItem*)mActiveItem->itemAbove ();
if ( activeItemAbove )
mCurItemAbove = activeItemAbove->todo();
mCurItemRootParent = mCurItem;
mCurItemParent = mCurItemRootParent->relatedTo();
while ( mCurItemRootParent->relatedTo() != 0 )
mCurItemRootParent = mCurItemRootParent->relatedTo();
}
mActiveItem = 0;
}
void KOTodoView::resetCurrentItem()
{
//mTodoListView->setFocus();
KOTodoViewItem* foundItem = 0;
KOTodoViewItem* foundItemRoot = 0;
KOTodoViewItem* foundItemParent = 0;
KOTodoViewItem* foundItemAbove = 0;
if ( mTodoListView->firstChild () ) {
if ( mCurItem ) {
KOTodoViewItem* item = (KOTodoViewItem*)mTodoListView->firstChild ();
while ( item ) {
if ( item->todo() == mCurItem ) {
foundItem = item;
break;
} else if ( item->todo() == mCurItemAbove ) {
foundItemAbove = item;
}
if ( item->todo() == mCurItemRootParent ) {
foundItemRoot = item;
}
if ( item->todo() == mCurItemParent ) {
foundItemParent = item;
}
item = (KOTodoViewItem*)item->itemBelow();
}
if ( ! foundItem ) {
if ( foundItemParent ) {
foundItem = foundItemParent;
} else {
if ( foundItemRoot )
foundItem = foundItemRoot;
else
foundItem = foundItemAbove;
}
}
}
if ( foundItem ) {
mTodoListView->setSelected ( foundItem, true );
mTodoListView->setCurrentItem( foundItem );
mTodoListView->ensureItemVisible( foundItem );
} else {
if ( mTodoListView->firstChild () ) {
mTodoListView->setSelected ( mTodoListView->firstChild (), true );
mTodoListView->setCurrentItem( mTodoListView->firstChild () );
}
}
}
processSelectionChange();
QTimer::singleShot( 100, this, SLOT ( resetFocusToList() ));
}
void KOTodoView::resetFocusToList()
{
topLevelWidget()->setActiveWindow();
mTodoListView->setFocus();
}
//Incidence * mCurItem, *mCurItemRootParent,*mCurItemAbove;
bool KOTodoView::checkTodo( Todo * todo )
{
if ( !KOPrefs::instance()->mShowCompletedTodo && todo->isCompleted() )
return false;
if ( !todo->isCompleted() ) {
if ( todo->hasDueDate() && todo->dtDue().date() <= QDate::currentDate() )
return true;
}
if ( KOPrefs::instance()->mHideNonStartedTodos && mNavigator ) {
if ( todo->hasStartDate() )
if ( mNavigator->selectedDates().last() < todo->dtStart().date() )
return false;
if ( todo->hasDueDate() )
if ( mNavigator->selectedDates().first() > todo->dtDue().date() )
return false;
}
return true;
}
void KOTodoView::restoreItemState( QListViewItem *item )
{
pendingSubtodo = 0;
while( item ) {
KOTodoViewItem *todoItem = (KOTodoViewItem *)item;
todoItem->setOpen( mDocPrefs->readBoolEntry( todoItem->todo()->uid() ) );
if( item->childCount() > 0 ) restoreItemState( item->firstChild() );
item = item->nextSibling();
}
}
QMap<Todo *,KOTodoViewItem *>::ConstIterator
KOTodoView::insertTodoItem(Todo *todo)
{
// kdDebug() << "KOTodoView::insertTodoItem(): " << todo->getSummary() << endl;
// TODO: Check, if dynmaic cast is necessary
pendingSubtodo = 0;
Incidence *incidence = todo->relatedTo();
while ( incidence && !incidence->calEnabled() )
incidence = incidence->relatedTo();
if (incidence && incidence->typeID() == todoID ) {
Todo *relatedTodo = static_cast<Todo *>(incidence);
// kdDebug() << " has Related" << endl;
QMap<Todo *,KOTodoViewItem *>::ConstIterator itemIterator;
itemIterator = mTodoMap.find(relatedTodo);
if (itemIterator == mTodoMap.end()) {
// kdDebug() << " related not yet in list" << endl;
itemIterator = insertTodoItem (relatedTodo);
}
// isn't this pretty stupid? We give one Todo to the KOTodoViewItem
// and one into the map. Sure finding is more easy but why? -zecke
KOTodoViewItem *todoItem = new KOTodoViewItem(*itemIterator,todo,this);
return mTodoMap.insert(todo,todoItem);
} else {
// kdDebug() << " no Related" << endl;
// see above -zecke
KOTodoViewItem *todoItem = new KOTodoViewItem(mTodoListView,todo,this);
return mTodoMap.insert(todo,todoItem);
}
}
void KOTodoView::updateConfig()
{
updateView();
mTodoListView->repaintContents();
}
QPtrList<Incidence> KOTodoView::selectedIncidences()
{
QPtrList<Incidence> selected;
KOTodoViewItem *item = (KOTodoViewItem *)(mTodoListView->selectedItem());
// if (!item) item = mActiveItem;
if (item) selected.append(item->todo());
return selected;
}
QPtrList<Todo> KOTodoView::selectedTodos()
{
QPtrList<Todo> selected;
KOTodoViewItem *item = (KOTodoViewItem *)(mTodoListView->selectedItem());
// if (!item) item = mActiveItem;
if (item) selected.append(item->todo());
return selected;
}
void KOTodoView::changeEventDisplay(Event *, int)
{
updateView();
}
void KOTodoView::showDates(const QDate &, const QDate &)
{
}
void KOTodoView::showEvents(QPtrList<Event>)
{
kdDebug() << "KOTodoView::selectEvents(): not yet implemented" << endl;
}
void KOTodoView::printPreview(CalPrinter *calPrinter, const QDate &fd,
const QDate &td)
{
#ifndef KORG_NOPRINTER
calPrinter->preview(CalPrinter::Todolist, fd, td);
#endif
}
void KOTodoView::editItem(QListViewItem *item )
{
emit editTodoSignal(((KOTodoViewItem *)item)->todo());
}
void KOTodoView::showItem(QListViewItem *item,const QPoint &,int)
{
emit showTodoSignal(((KOTodoViewItem *)item)->todo());
}
void KOTodoView::popupMenu(QListViewItem *item,const QPoint &p,int column)
{
pendingSubtodo = 0;
mActiveItem = (KOTodoViewItem *)item;
if (item) {
switch (column){
case 1:
mPriorityPopupMenu->popup(QCursor::pos ()); break;
case 2:
mPercentageCompletedPopupMenu->popup(QCursor::pos ()); break;
case 3:
moveTodo();
break;
case 7:
mCategoryPopupMenu->popup(QCursor::pos ()); break;
case 8:
mCalPopupMenu->popup(QCursor::pos ()); break;
default:
mItemPopupMenu->popup(QCursor::pos());
}
} else mPopupMenu->popup(QCursor::pos());
}
void KOTodoView::newTodo()
{
emit newTodoSignal();
}
void KOTodoView::newSubTodo()
{
mActiveItem = (KOTodoViewItem*)mTodoListView->currentItem();
if (mActiveItem) {
if ( mQuickAdd->isVisible() && !mQuickAdd->text().isEmpty() && mQuickAdd->text() != i18n("Click to add new Todo") ) {
addQuickTodoPar( mActiveItem->todo());
} else
emit newSubTodoSignal(mActiveItem->todo());
}
}
void KOTodoView::unparentTodo()
{
if (mActiveItem) {
emit unparentTodoSignal(mActiveItem->todo());
}
}
void KOTodoView::reparentTodo()
{
if (mActiveItem) {
topLevelWidget()->setCaption(i18n("Click on new parent item"));
pendingSubtodo = mActiveItem;
}
}
void KOTodoView::editTodo()
{
if (mActiveItem) {
emit editTodoSignal(mActiveItem->todo());
}
}
void KOTodoView::cloneTodo()
{
if (mActiveItem) {
emit cloneTodoSignal((Incidence*)mActiveItem->todo());
}
}
void KOTodoView::cancelTodo()
{
if (mActiveItem) {
emit cancelTodoSignal((Incidence*)mActiveItem->todo());
}
}
void KOTodoView::moveTodo()
{
if (mActiveItem) {
emit moveTodoSignal((Incidence*)mActiveItem->todo());
}
}
void KOTodoView::beamTodo()
{
if (mActiveItem) {
emit beamTodoSignal((Incidence*)mActiveItem->todo());
}
}
void KOTodoView::showTodo()
{
if (mActiveItem) {
emit showTodoSignal(mActiveItem->todo());
}
}
void KOTodoView::deleteTodo()
{
if (mActiveItem) {
emit deleteTodoSignal(mActiveItem->todo());
}
}
void KOTodoView::setNewPriority(int index)
{
if (mActiveItem && !mActiveItem->todo()->isReadOnly ()) {
mActiveItem->todo()->setPriority(mPriority[index]);
mActiveItem->construct();
todoModified (mActiveItem->todo(), KOGlobals::PRIORITY_MODIFIED);
mActiveItem->todo()->setRevision( mActiveItem->todo()->revision()+1 );
}
processSelectionChange();
}
void KOTodoView::setNewPercentage(int index)
{
if (mActiveItem && !mActiveItem->todo()->isReadOnly ()) {
if ( mPercentage[index] == 100 && !mActiveItem->isOn() ) {
mActiveItem->setOn( true );
processSelectionChange();
return;
} else if ( mPercentage[index] != 100 && mActiveItem->isOn() ) {
KOTodoViewItem* par = (static_cast<KOTodoViewItem*>(mActiveItem->parent()));
if ( par && par->isOn() )
par->setOn( false );
}
if (mPercentage[index] == 100) {
mActiveItem->todo()->setCompleted(QDateTime::currentDateTime());
} else {
mActiveItem->todo()->setCompleted(false);
}
mActiveItem->todo()->setPercentComplete(mPercentage[index]);
mActiveItem->construct();
todoModified (mActiveItem->todo (), KOGlobals::COMPLETION_MODIFIED);
mActiveItem->todo()->setRevision( mActiveItem->todo()->revision()+1 );
}
processSelectionChange();
}
void KOTodoView::fillCategories ()
{
mCategoryPopupMenu->clear();
if ( ! mActiveItem ) return;
QStringList checkedCategories = mActiveItem->todo()->categories ();
for (QStringList::Iterator it = KOPrefs::instance()->mCustomCategories.begin ();
it != KOPrefs::instance()->mCustomCategories.end ();
++it) {
int index = mCategoryPopupMenu->insertItem (*it);
mCategory[index] = *it;
if (checkedCategories.find (*it) != checkedCategories.end ()) mCategoryPopupMenu->setItemChecked (index, true);
}
}
void KOTodoView::fillCal ()
{
mCalPopupMenu->clear();
if (!mActiveItem) return;
bool readO = mActiveItem->todo()->isReadOnly();
KopiCalendarFile * kkf = KOPrefs::instance()->mCalendars.first();
while ( kkf ) {
int index = mCalPopupMenu->insertItem( kkf->mName, kkf->mCalNumber);
if ( kkf->mErrorOnLoad || kkf->isReadOnly || readO )
mCalPopupMenu->setItemEnabled( index, false );
mCalPopupMenu->setItemChecked (index, kkf->mCalNumber == mActiveItem->todo()->calID());
kkf = KOPrefs::instance()->mCalendars.next();
}
}
void KOTodoView::changedCal (int index )
{
if (!mActiveItem) return;
mActiveItem->todo()->setCalID( index );
mActiveItem->construct();
}
void KOTodoView::changedCategories(int index)
{
if (mActiveItem && !mActiveItem->todo()->isReadOnly ()) {
QStringList categories = mActiveItem->todo()->categories ();
QString colcat = categories.first();
if (categories.find (mCategory[index]) != categories.end ())
categories.remove (mCategory[index]);
else
categories.insert (categories.end(), mCategory[index]);
categories.sort ();
if ( !colcat.isEmpty() ) {
if ( categories.find ( colcat ) != categories.end () ) {
categories.remove( colcat );
categories.prepend( colcat );
}
}
mActiveItem->todo()->setCategories (categories);
mActiveItem->construct();
mActiveItem->todo()->setRevision( mActiveItem->todo()->revision()+1 );
todoModified (mActiveItem->todo (), KOGlobals::CATEGORY_MODIFIED);
}
}
void KOTodoView::itemDoubleClicked(QListViewItem *item)
{
if ( pendingSubtodo != 0 ) {
topLevelWidget()->setCaption(i18n("Reparenting aborted!"));
}
pendingSubtodo = 0;
//int row = mTodoListView->header()->sectionAt ( mTodoListView->header()->mapFromGlobal( QCursor::pos()).x() );
int row = mTodoListView->header()->sectionAt ( mTodoListView->viewportToContents(mTodoListView->viewport()->mapFromGlobal( QCursor::pos())) .x() );
//qDebug("ROW %d ", row);
if (!item) {
newTodo();
return;
} else {
if ( row == 1 ) {
mActiveItem = (KOTodoViewItem *) item;
newSubTodo();
return;
}
if ( row == 5 || row == 6 || row == 2) {
mActiveItem = (KOTodoViewItem *) item;
Todo * t = mActiveItem->todo();
if ( t->isRunning() ) {
if ( t->runTime() < 15) {
t->stopRunning();
mActiveItem->construct();
topLevelWidget()->setCaption(i18n("Todo stopped - no data saved because runtime was < 15 sec!"));
return;
}
else
toggleRunningItem();
return;
} else {
t->setRunning( true );
mActiveItem->construct();
topLevelWidget()->setCaption(i18n("Todo started! Double click again to stop!"));
return;
}
}
}
if ( KOPrefs::instance()->mEditOnDoubleClick )
editItem( item );
else
showItem( item , QPoint(), 0 );
}
void KOTodoView::toggleRunningItem()
{
// qDebug("KOTodoView::toggleRunning() ");
if ( ! mActiveItem )
return;
Todo * t = mActiveItem->todo();
if ( t->isRunning() ) {
KOStopTodoPrefs tp ( t, this );
if (QApplication::desktop()->width() <= 800 ){
int wid = tp.width();
int hei = tp.height();
int xx = (QApplication::desktop()->width()-wid)/2;
int yy = (QApplication::desktop()->height()-hei)/2;
tp.setGeometry( xx,yy,wid,hei );
}
tp.exec();
- mActiveItem->construct();
+ updateTodo ( t, 0 );
} else {
KOStartTodoPrefs tp ( t->summary(), this );
if (QApplication::desktop()->width() <= 800 ){
int wid = tp.width();
int hei = tp.height();
int xx = (QApplication::desktop()->width()-wid)/2;
int yy = (QApplication::desktop()->height()-hei)/2;
tp.setGeometry( xx,yy,wid,hei );
}
if ( !tp.exec() ) return;
if ( tp.stopAll() ) {
mCalendar->stopAllTodos();
t->setRunning( true );
updateView();
} else {
t->setRunning( true );
- mActiveItem->construct();
+ updateTodo ( t, 0 );
}
}
}
void KOTodoView::itemClicked(QListViewItem *item)
{
//qDebug("KOTodoView::itemClicked %d", item);
if (!item) {
if ( pendingSubtodo != 0 ) {
topLevelWidget()->setCaption(i18n("Reparenting aborted!"));
}
pendingSubtodo = 0;
return;
}
KOTodoViewItem *todoItem = (KOTodoViewItem *)item;
if ( pendingSubtodo != 0 ) {
bool allowReparent = true;
QListViewItem *par = item;
while ( par ) {
if ( par == pendingSubtodo ) {
allowReparent = false;
break;
}
par = par->parent();
}
if ( !allowReparent ) {
topLevelWidget()->setCaption(i18n("Recursive reparenting not possible!"));
pendingSubtodo = 0;
} else {
Todo* newParent = todoItem->todo();
Todo* newSub = pendingSubtodo->todo();
pendingSubtodo = 0;
emit reparentTodoSignal( newParent,newSub );
return;
}
}
}
void KOTodoView::setDocumentId( const QString &id )
{
mDocPrefs->setDoc( id );
}
void KOTodoView::itemStateChanged( QListViewItem *item )
{
if (!item) return;
KOTodoViewItem *todoItem = (KOTodoViewItem *)item;
// kdDebug() << "KOTodoView::itemStateChanged(): " << todoItem->todo()->summary() << endl;
if( mDocPrefs ) mDocPrefs->writeEntry( todoItem->todo()->uid(), todoItem->isOpen() );
}
void KOTodoView::saveLayout(KConfig *config, const QString &group) const
{
mTodoListView->saveLayout(config,group);
}
void KOTodoView::restoreLayout(KConfig *config, const QString &group)
{
mTodoListView->restoreLayout(config,group);
}
void KOTodoView::processSelectionChange()
{
// kdDebug() << "KOTodoView::processSelectionChange()" << endl;
KOTodoViewItem *item =
static_cast<KOTodoViewItem *>( mTodoListView->selectedItem() );
if ( !item ) {
emit incidenceSelected( 0 );
mNewSubBut->setEnabled( false );
} else {
emit incidenceSelected( item->todo() );
mNewSubBut->setEnabled( true );
}
}
void KOTodoView::modified(bool b)
{
emit isModified(b);
}
void KOTodoView::setTodoModified( Todo* todo )
{
todoModified( todo, KOGlobals::UNKNOWN_MODIFIED );
}
void KOTodoView::clearSelection()
{
mTodoListView->selectAll( false );
}
void KOTodoView::setAllOpen()
{
if ( isFlatDisplay ) {
isFlatDisplay = false;
mPopupMenu->setItemChecked( 8,false );
updateView();
} else {
storeCurrentItem();
}
setOpen(mTodoListView->firstChild(), true);
resetCurrentItem();
}
void KOTodoView::setAllClose()
{
if ( isFlatDisplay ) {
isFlatDisplay = false;
mPopupMenu->setItemChecked( 8,false );
updateView();
} else {
storeCurrentItem();
}
setOpen(mTodoListView->firstChild(), false);
resetCurrentItem();
}
void KOTodoView::setOpen( QListViewItem* item, bool setOpenI)
{
while ( item ) {
setOpen( item->firstChild(), setOpenI );
item->setOpen( setOpenI );
item = item->nextSibling();
}
}
void KOTodoView::displayAllFlat()
{
storeCurrentItem();
pendingSubtodo = 0;
if ( mBlockUpdate ) {
return;
}
mPopupMenu->setItemChecked( 8,true );
isFlatDisplay = true;
QPtrList<Todo> todoList = calendar()->todos();
mTodoMap.clear();
mTodoListView->clear();
Todo *todo;
for(todo = todoList.first(); todo; todo = todoList.next()) {
if ( checkTodo( todo ) ) {
KOTodoViewItem *todoItem = new KOTodoViewItem(mTodoListView,todo,this);
mTodoMap.insert(todo,todoItem);
}
}
resetCurrentItem();
}
void KOTodoView::setAllFlat()
{
if ( isFlatDisplay ) {
isFlatDisplay = false;
mPopupMenu->setItemChecked( 8,false );
updateView();
return;
}
displayAllFlat();
}
void KOTodoView::purgeCompleted()
{
emit purgeCompletedSignal();
}
void KOTodoView::toggleQuickTodo()
{
if ( mQuickBar->isVisible() ) {
mQuickBar->hide();
KOPrefs::instance()->mEnableQuickTodo = false;
}
else {
mQuickBar->show();
KOPrefs::instance()->mEnableQuickTodo = true;
}
mPopupMenu->setItemChecked(4,KOPrefs::instance()->mEnableQuickTodo);
mItemPopupMenu->setItemChecked( 34 , KOPrefs::instance()->mEnableQuickTodo );
}
void KOTodoView::toggleRunning()
{
KOPrefs::instance()->mHideNonStartedTodos = !KOPrefs::instance()->mHideNonStartedTodos;
mPopupMenu->setItemChecked(5,KOPrefs::instance()->mHideNonStartedTodos);
mItemPopupMenu->setItemChecked( 35 , KOPrefs::instance()->mHideNonStartedTodos );
updateView();
if ( KOPrefs::instance()->mHideNonStartedTodos )
topLevelWidget()->setCaption(i18n("Hide not Running"));
else
topLevelWidget()->setCaption(i18n("Show not Running"));
}
void KOTodoView::toggleCompleted()
{
KOPrefs::instance()->mShowCompletedTodo = !KOPrefs::instance()->mShowCompletedTodo;
mPopupMenu->setItemChecked( 3,KOPrefs::instance()->mShowCompletedTodo );
mItemPopupMenu->setItemChecked( 33 , KOPrefs::instance()->mShowCompletedTodo );
updateView();
if ( KOPrefs::instance()->mShowCompletedTodo )
topLevelWidget()->setCaption(i18n("Show Completed"));
else
topLevelWidget()->setCaption(i18n("Hide Completed"));
}
void KOTodoView::addQuickTodo()
{
addQuickTodoPar( 0 );
}
void KOTodoView::addQuickTodoPar( Todo * parentTodo)
{
Todo *todo = new Todo();
todo->setSummary(mQuickAdd->text());
todo->setOrganizer(KOPrefs::instance()->email());
if ( parentTodo ) {
todo->setRelatedTo(parentTodo);
todo->setCategories (parentTodo->categoriesStr ());
todo->setSecrecy (parentTodo->secrecy ());
if ( parentTodo->priority() < 3 )
todo->setPriority( parentTodo->priority() );
todo->setCalID( parentTodo->calID() );
} else {
CalFilter * cf = mCalendar->filter();
if ( cf ) {
if ( cf->isEnabled()&& cf->showCategories()) {
todo->setCategories(cf->categoryList());
}
if ( cf->isEnabled() )
todo->setSecrecy( cf->getSecrecy());
}
}
mCalendar->addTodo(todo);
mQuickAdd->setText("");
todoModified (todo, KOGlobals::EVENTADDED );
updateView();
}
void KOTodoView::keyPressEvent ( QKeyEvent * e )
{
// e->ignore();
//return;
if ( !isVisible() ) {
e->ignore();
return;
}
switch ( e->key() ) {
case Qt::Key_Down:
case Qt::Key_Up:
// KOrg::BaseView::keyPressEvent ( e );
e->ignore();
break;
case Qt::Key_Q:
if ( e->state() == Qt::ControlButton || e->state() == Qt::ShiftButton ) {
e->ignore();
break;
}
toggleQuickTodo();
break;
case Qt::Key_U:
if ( e->state() == Qt::ControlButton|| e->state() == Qt::ShiftButton ) {
mActiveItem = (KOTodoViewItem*)mTodoListView->currentItem();
unparentTodo();
e->accept();
} else
e->ignore();
break;
case Qt::Key_S:
if ( e->state() == Qt::ControlButton ) {
e->ignore();
break;
}
if ( e->state() == Qt::ShiftButton ) {
mActiveItem = (KOTodoViewItem*)mTodoListView->currentItem();
reparentTodo();
e->accept();
} else
e->ignore();
break;
case Qt::Key_P:
if ( e->state() == Qt::ControlButton|| e->state() == Qt::ShiftButton ) {
mActiveItem = (KOTodoViewItem*)mTodoListView->currentItem();
if ( pendingSubtodo )
itemClicked(mActiveItem);
e->accept();
} else
e->ignore();
break;
case Qt::Key_Escape:
if ( pendingSubtodo ) {
itemClicked(0);
e->accept();
} else
e->ignore();
break;
default:
e->ignore();
}
if ( true ) {
if ( e->key() == Qt::Key_I ) {
KOTodoViewItem*cn = (KOTodoViewItem*)mTodoListView->currentItem();
if ( cn ) {
mActiveItem = cn;
KOTodoViewItem* ci = (KOTodoViewItem*)( cn );
if ( ci ){
showTodo();
cn = (KOTodoViewItem*)cn->itemBelow();
if ( cn ) {
mTodoListView->setCurrentItem ( cn );
mTodoListView->ensureItemVisible ( cn );
}
}
}
e->accept();
}
}
}
void KOTodoView::updateTodo( Todo * t, int type )
{
if ( mBlockUpdate)
return;
QMap<Todo *,KOTodoViewItem *>::ConstIterator itemIterator;
itemIterator = mTodoMap.find(t);
if (itemIterator != mTodoMap.end()) {
(*itemIterator)->construct();
} else {
if ( type == KOGlobals::EVENTADDED ) {
insertTodoItem( t );
}
}
}
void KOTodoView::todoModified(Todo * t , int p )
{
mBlockUpdate = true;
emit todoModifiedSignal ( t, p );
mBlockUpdate = false;
}