|
|
|
/*
|
|
|
|
This file is part of KOrganizer.
|
|
|
|
|
|
|
|
Copyright (c) 2001 Eitzenberger Thomas <thomas.eitzenberger@siemens.at>
|
|
|
|
Parts of the source code have been copied from kdpdatebutton.cpp
|
|
|
|
|
|
|
|
Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
|
|
|
|
Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
|
|
|
As a special exception, permission is given to link this program
|
|
|
|
with any edition of TQt, and distribute the resulting executable,
|
|
|
|
without including the source code for TQt in the source distribution.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <tqevent.h>
|
|
|
|
#include <tqpainter.h>
|
|
|
|
#include <tqptrlist.h>
|
|
|
|
|
|
|
|
#include <kglobal.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
|
|
|
|
#include <libkcal/vcaldrag.h>
|
|
|
|
#include <libkcal/icaldrag.h>
|
|
|
|
#include <libkcal/dndfactory.h>
|
|
|
|
#include <libkcal/calendarresources.h>
|
|
|
|
#include <libkcal/resourcecalendar.h>
|
|
|
|
|
|
|
|
#include <kcalendarsystem.h>
|
|
|
|
|
|
|
|
#include "koprefs.h"
|
|
|
|
#include "koglobals.h"
|
|
|
|
#include "kodialogmanager.h"
|
|
|
|
|
|
|
|
#include "kodaymatrix.h"
|
|
|
|
#include "kodaymatrix.moc"
|
|
|
|
|
|
|
|
#ifndef NODND
|
|
|
|
#include <tqcursor.h>
|
|
|
|
#include <tdepopupmenu.h>
|
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#undef FocusIn
|
|
|
|
#undef KeyPress
|
|
|
|
#undef None
|
|
|
|
#undef Status
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
// D Y N A M I C T I P
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
DynamicTip::DynamicTip( TQWidget * parent )
|
|
|
|
: TQToolTip( parent )
|
|
|
|
{
|
|
|
|
mMatrix = static_cast<KODayMatrix *>( parent );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DynamicTip::maybeTip( const TQPoint &pos )
|
|
|
|
{
|
|
|
|
//calculate which cell of the matrix the mouse is in
|
|
|
|
TQRect sz = mMatrix->frameRect();
|
|
|
|
int dheight = sz.height() * 7 / 42;
|
|
|
|
int dwidth = sz.width() / 7;
|
|
|
|
int row = pos.y() / dheight;
|
|
|
|
int col = pos.x() / dwidth;
|
|
|
|
|
|
|
|
TQRect rct( col * dwidth, row * dheight, dwidth, dheight );
|
|
|
|
|
|
|
|
// kdDebug(5850) << "DynamicTip::maybeTip matrix cell index [" <<
|
|
|
|
// col << "][" << row << "] => " <<(col+row*7) << endl;
|
|
|
|
|
|
|
|
//show holiday names only
|
|
|
|
TQString str = mMatrix->getHolidayLabel( col + row * 7 );
|
|
|
|
if ( str.isEmpty() ) return;
|
|
|
|
tip( rct, str );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
// K O D A Y M A T R I X
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
const int KODayMatrix::NOSELECTION = -1000;
|
|
|
|
const int KODayMatrix::NUMDAYS = 42;
|
|
|
|
|
|
|
|
KODayMatrix::KODayMatrix( TQWidget *parent, const char *name )
|
|
|
|
: TQFrame( parent, name ), mCalendar( 0 ), mStartDate(), mPendingChanges( false )
|
|
|
|
{
|
|
|
|
// initialize dynamic arrays
|
|
|
|
mDays = new TQDate[ NUMDAYS ];
|
|
|
|
mDayLabels = new TQString[ NUMDAYS ];
|
|
|
|
mEvents = new int[ NUMDAYS ];
|
|
|
|
mToolTip = new DynamicTip( this );
|
|
|
|
|
|
|
|
mTodayMarginWidth = 2;
|
|
|
|
mSelEnd = mSelStart = NOSELECTION;
|
|
|
|
setBackgroundMode( NoBackground );
|
|
|
|
recalculateToday();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KODayMatrix::setCalendar( Calendar *cal )
|
|
|
|
{
|
|
|
|
if ( mCalendar ) {
|
|
|
|
mCalendar->unregisterObserver( this );
|
|
|
|
mCalendar->disconnect( this );
|
|
|
|
}
|
|
|
|
|
|
|
|
mCalendar = cal;
|
|
|
|
mCalendar->registerObserver( this );
|
|
|
|
CalendarResources *calres = dynamic_cast<CalendarResources*>( cal );
|
|
|
|
if ( calres ) {
|
|
|
|
connect( calres, TQT_SIGNAL(signalResourceAdded(ResourceCalendar *)), TQT_SLOT(resourcesChanged()) );
|
|
|
|
connect( calres, TQT_SIGNAL(signalResourceModified( ResourceCalendar *)), TQT_SLOT(resourcesChanged()) );
|
|
|
|
connect( calres, TQT_SIGNAL(signalResourceDeleted(ResourceCalendar *)), TQT_SLOT(resourcesChanged()) );
|
|
|
|
}
|
|
|
|
|
|
|
|
setAcceptDrops( mCalendar );
|
|
|
|
|
|
|
|
updateEvents();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQColor KODayMatrix::getShadedColor( const TQColor &color )
|
|
|
|
{
|
|
|
|
TQColor shaded;
|
|
|
|
int h = 0;
|
|
|
|
int s = 0;
|
|
|
|
int v = 0;
|
|
|
|
color.hsv( &h, &s, &v );
|
|
|
|
s = s / 4;
|
|
|
|
v = 192 + v / 4;
|
|
|
|
shaded.setHsv( h, s, v );
|
|
|
|
|
|
|
|
return shaded;
|
|
|
|
}
|
|
|
|
|
|
|
|
KODayMatrix::~KODayMatrix()
|
|
|
|
{
|
|
|
|
if ( mCalendar )
|
|
|
|
mCalendar->unregisterObserver( this );
|
|
|
|
delete [] mDays;
|
|
|
|
delete [] mDayLabels;
|
|
|
|
delete [] mEvents;
|
|
|
|
delete mToolTip;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KODayMatrix::addSelectedDaysTo( DateList &selDays )
|
|
|
|
{
|
|
|
|
kdDebug(5850) << "KODayMatrix::addSelectedDaysTo() - " << "mSelStart:" << mSelStart << endl;
|
|
|
|
|
|
|
|
if ( mSelStart == NOSELECTION ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// cope with selection being out of matrix limits at top (< 0)
|
|
|
|
int i0 = mSelStart;
|
|
|
|
if ( i0 < 0 ) {
|
|
|
|
for ( int i = i0; i < 0; i++ ) {
|
|
|
|
selDays.append( mDays[ 0 ].addDays( i ) );
|
|
|
|
}
|
|
|
|
i0 = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// cope with selection being out of matrix limits at bottom (> NUMDAYS-1)
|
|
|
|
if ( mSelEnd > NUMDAYS-1 ) {
|
|
|
|
for ( int i = i0; i <= NUMDAYS - 1; i++ ) {
|
|
|
|
selDays.append( mDays[ i ] );
|
|
|
|
}
|
|
|
|
for ( int i = NUMDAYS; i < mSelEnd; i++ ) {
|
|
|
|
selDays.append( mDays[ 0 ].addDays( i ) );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// apply normal routine to selection being entirely within matrix limits
|
|
|
|
for ( int i = i0; i <= mSelEnd; i++ ) {
|
|
|
|
selDays.append( mDays[ i ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KODayMatrix::setSelectedDaysFrom( const TQDate &start, const TQDate &end )
|
|
|
|
{
|
|
|
|
if ( mStartDate.isValid() ) {
|
|
|
|
mSelStart = mStartDate.daysTo( start );
|
|
|
|
mSelEnd = mStartDate.daysTo( end );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KODayMatrix::clearSelection()
|
|
|
|
{
|
|
|
|
mSelEnd = mSelStart = NOSELECTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KODayMatrix::recalculateToday()
|
|
|
|
{
|
|
|
|
if ( !mStartDate.isValid() ) return;
|
|
|
|
mToday = -1;
|
|
|
|
for ( int i = 0; i < NUMDAYS; i++ ) {
|
|
|
|
mDays[ i ] = mStartDate.addDays( i );
|
|
|
|
mDayLabels[ i ] = TQString::number( KOGlobals::self()->calendarSystem()->day( mDays[i] ));
|
|
|
|
|
|
|
|
// if today is in the currently displayed month, hilight today
|
|
|
|
if ( mDays[ i ].year() == TQDate::currentDate().year() &&
|
|
|
|
mDays[ i ].month() == TQDate::currentDate().month() &&
|
|
|
|
mDays[ i ].day() == TQDate::currentDate().day() ) {
|
|
|
|
mToday = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// kdDegug(5850) << "Today is visible at "<< today << "." << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* slot */ void KODayMatrix::updateView()
|
|
|
|
{
|
|
|
|
updateView( mStartDate );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KODayMatrix::setUpdateNeeded()
|
|
|
|
{
|
|
|
|
mPendingChanges = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KODayMatrix::updateView( const TQDate &actdate )
|
|
|
|
{
|
|
|
|
kdDebug(5850) << "KODayMatrix::updateView() " << actdate << ", day start="<<mStartDate<< endl;
|
|
|
|
if ( !actdate.isValid() ) return;
|
|
|
|
//flag to indicate if the starting day of the matrix has changed by this call
|
|
|
|
bool daychanged = false;
|
|
|
|
|
|
|
|
// if a new startdate is to be set then apply Cornelius's calculation
|
|
|
|
// of the first day to be shown
|
|
|
|
if ( actdate != mStartDate ) {
|
|
|
|
// reset index of selection according to shift of starting date from startdate to actdate
|
|
|
|
if ( mSelStart != NOSELECTION ) {
|
|
|
|
int tmp = actdate.daysTo( mStartDate );
|
|
|
|
//kdDebug(5850) << "Shift of Selection1: " << mSelStart << " - " << mSelEnd << " -> " << tmp << "(" << offset << ")" << endl;
|
|
|
|
// shift selection if new one would be visible at least partly !
|
|
|
|
|
|
|
|
if ( mSelStart + tmp < NUMDAYS && mSelEnd + tmp >= 0 ) {
|
|
|
|
// nested if is required for next X display pushed from a different month - correction required
|
|
|
|
// otherwise, for month forward and backward, it must be avoided
|
|
|
|
if( mSelStart > NUMDAYS || mSelStart < 0 )
|
|
|
|
mSelStart = mSelStart + tmp;
|
|
|
|
if( mSelEnd > NUMDAYS || mSelEnd < 0 )
|
|
|
|
mSelEnd = mSelEnd + tmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mStartDate = actdate;
|
|
|
|
daychanged = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( daychanged ) {
|
|
|
|
recalculateToday();
|
|
|
|
}
|
|
|
|
|
|
|
|
// the calendar hasn't changed in the meantime and the selected range is still the same
|
|
|
|
// so we can safe the expensive updateEvents() call
|
|
|
|
if ( !daychanged && !mPendingChanges )
|
|
|
|
return;
|
|
|
|
|
|
|
|
// TODO_Recurrence: If we just change the selection, but not the data, there's
|
|
|
|
// no need to update the whole list of events... This is just a waste of
|
|
|
|
// computational power (and it takes forever!)
|
|
|
|
updateEvents();
|
|
|
|
for( int i = 0; i < NUMDAYS; i++ ) {
|
|
|
|
//if it is a holy day then draw it red. Sundays are consider holidays, too
|
|
|
|
TQStringList holidays = KOGlobals::self()->holiday( mDays[ i ] );
|
|
|
|
TQString holiStr = TQString();
|
|
|
|
|
|
|
|
if ( ( KOGlobals::self()->calendarSystem()->dayOfWeek( mDays[ i ] ) ==
|
|
|
|
KOGlobals::self()->calendarSystem()->weekDayOfPray() ) ||
|
|
|
|
!holidays.isEmpty() ) {
|
|
|
|
if ( !holidays.isEmpty() ) holiStr = holidays.join( i18n("delimiter for joining holiday names", ", " ) );
|
|
|
|
if ( holiStr.isNull() ) holiStr = "";
|
|
|
|
}
|
|
|
|
mHolidays[ i ] = holiStr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KODayMatrix::updateEvents()
|
|
|
|
{
|
|
|
|
kdDebug( 5850 ) << k_funcinfo << endl;
|
|
|
|
if ( !mCalendar ) return;
|
|
|
|
|
|
|
|
for( int i = 0; i < NUMDAYS; i++ ) {
|
|
|
|
// if events are set for the day then remember to draw it bold
|
|
|
|
Event::List eventlist = mCalendar->events( mDays[ i ] );
|
|
|
|
int numEvents = eventlist.count();
|
|
|
|
Event::List::ConstIterator it;
|
|
|
|
for( it = eventlist.begin(); it != eventlist.end(); ++it ) {
|
|
|
|
Event *event = *it;
|
|
|
|
ushort recurType = event->recurrenceType();
|
|
|
|
if ( ( recurType == Recurrence::rDaily &&
|
|
|
|
!KOPrefs::instance()->mDailyRecur ) ||
|
|
|
|
( recurType == Recurrence::rWeekly &&
|
|
|
|
!KOPrefs::instance()->mWeeklyRecur ) ) {
|
|
|
|
numEvents--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mEvents[ i ] = numEvents;
|
|
|
|
}
|
|
|
|
|
|
|
|
mPendingChanges = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const TQDate& KODayMatrix::getDate( int offset )
|
|
|
|
{
|
|
|
|
if ( offset < 0 || offset > NUMDAYS - 1 ) {
|
|
|
|
kdDebug(5850) << "Wrong offset (" << offset << ") in KODayMatrix::getDate(int)" << endl;
|
|
|
|
return mDays[ 0 ];
|
|
|
|
}
|
|
|
|
return mDays[ offset ];
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KODayMatrix::getHolidayLabel( int offset )
|
|
|
|
{
|
|
|
|
if ( offset < 0 || offset > NUMDAYS - 1 ) {
|
|
|
|
kdDebug(5850) << "Wrong offset (" << offset << ") in KODayMatrix::getHolidayLabel(int)" << endl;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return mHolidays[ offset ];
|
|
|
|
}
|
|
|
|
|
|
|
|
int KODayMatrix::getDayIndexFrom( int x, int y )
|
|
|
|
{
|
|
|
|
return 7 * ( y / mDaySize.height() ) +
|
|
|
|
( KOGlobals::self()->reverseLayout() ?
|
|
|
|
6 - x / mDaySize.width() : x / mDaySize.width() );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KODayMatrix::calendarIncidenceAdded(Incidence * incidence)
|
|
|
|
{
|
|
|
|
Q_UNUSED( incidence );
|
|
|
|
mPendingChanges = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KODayMatrix::calendarIncidenceChanged(Incidence * incidence)
|
|
|
|
{
|
|
|
|
Q_UNUSED( incidence );
|
|
|
|
mPendingChanges = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KODayMatrix::calendarIncidenceDeleted(Incidence * incidence)
|
|
|
|
{
|
|
|
|
Q_UNUSED( incidence );
|
|
|
|
mPendingChanges = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KODayMatrix::resourcesChanged()
|
|
|
|
{
|
|
|
|
mPendingChanges = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// M O U S E E V E N T H A N D L I N G
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void KODayMatrix::mousePressEvent( TQMouseEvent *e )
|
|
|
|
{
|
|
|
|
mSelStart = getDayIndexFrom(e->x(), e->y());
|
|
|
|
if (mSelStart > NUMDAYS-1) mSelStart=NUMDAYS-1;
|
|
|
|
mSelInit = mSelStart;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KODayMatrix::mouseReleaseEvent( TQMouseEvent *e )
|
|
|
|
{
|
|
|
|
int tmp = getDayIndexFrom(e->x(), e->y());
|
|
|
|
if (tmp > NUMDAYS-1) tmp=NUMDAYS-1;
|
|
|
|
|
|
|
|
if (mSelInit > tmp) {
|
|
|
|
mSelEnd = mSelInit;
|
|
|
|
if (tmp != mSelStart) {
|
|
|
|
mSelStart = tmp;
|
|
|
|
repaint();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
mSelStart = mSelInit;
|
|
|
|
|
|
|
|
//repaint only if selection has changed
|
|
|
|
if (tmp != mSelEnd) {
|
|
|
|
mSelEnd = tmp;
|
|
|
|
repaint();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DateList daylist;
|
|
|
|
if ( mSelStart < 0 ) mSelStart = 0;
|
|
|
|
for ( int i = mSelStart; i <= mSelEnd; ++i ) {
|
|
|
|
daylist.append( mDays[i] );
|
|
|
|
}
|
|
|
|
emit selected((const DateList)daylist);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KODayMatrix::mouseMoveEvent( TQMouseEvent *e )
|
|
|
|
{
|
|
|
|
int tmp = getDayIndexFrom(e->x(), e->y());
|
|
|
|
if (tmp > NUMDAYS-1) tmp=NUMDAYS-1;
|
|
|
|
|
|
|
|
if (mSelInit > tmp) {
|
|
|
|
mSelEnd = mSelInit;
|
|
|
|
if ( tmp != mSelStart ) {
|
|
|
|
mSelStart = tmp;
|
|
|
|
repaint();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
mSelStart = mSelInit;
|
|
|
|
|
|
|
|
//repaint only if selection has changed
|
|
|
|
if ( tmp != mSelEnd ) {
|
|
|
|
mSelEnd = tmp;
|
|
|
|
repaint();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// D R A G ' N D R O P H A N D L I N G
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Drag and Drop handling -- based on the Troll Tech dirview example
|
|
|
|
|
|
|
|
enum {
|
|
|
|
DRAG_COPY = 0,
|
|
|
|
DRAG_MOVE = 1,
|
|
|
|
DRAG_CANCEL = 2
|
|
|
|
};
|
|
|
|
|
|
|
|
void KODayMatrix::dragEnterEvent( TQDragEnterEvent *e )
|
|
|
|
{
|
|
|
|
#ifndef KORG_NODND
|
|
|
|
if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) {
|
|
|
|
e->ignore();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// some visual feedback
|
|
|
|
// oldPalette = palette();
|
|
|
|
// setPalette(my_HilitePalette);
|
|
|
|
// update();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void KODayMatrix::dragMoveEvent( TQDragMoveEvent *e )
|
|
|
|
{
|
|
|
|
#ifndef KORG_NODND
|
|
|
|
if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) {
|
|
|
|
e->ignore();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
e->accept();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void KODayMatrix::dragLeaveEvent( TQDragLeaveEvent * /*dl*/ )
|
|
|
|
{
|
|
|
|
#ifndef KORG_NODND
|
|
|
|
// setPalette(oldPalette);
|
|
|
|
// update();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void KODayMatrix::dropEvent( TQDropEvent *e )
|
|
|
|
{
|
|
|
|
#ifndef KORG_NODND
|
|
|
|
kdDebug(5850) << "KODayMatrix::dropEvent(e) begin" << endl;
|
|
|
|
|
|
|
|
if ( !mCalendar ||
|
|
|
|
( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) ) {
|
|
|
|
e->ignore();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
DndFactory factory( mCalendar );
|
|
|
|
Event *event = factory.createDrop( e );
|
|
|
|
Todo *todo = factory.createDropTodo( e );
|
|
|
|
if ( !event && !todo ) {
|
|
|
|
e->ignore();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Todo *existingTodo = 0;
|
|
|
|
Event *existingEvent = 0;
|
|
|
|
|
|
|
|
// Find the incidence in the calendar, then we don't need the drag object any more
|
|
|
|
if ( event ) existingEvent = mCalendar->event( event->uid() );
|
|
|
|
if ( todo ) existingTodo = mCalendar->todo( todo->uid() );
|
|
|
|
|
|
|
|
int action = DRAG_CANCEL;
|
|
|
|
|
|
|
|
int root_x, root_y, win_x, win_y;
|
|
|
|
uint keybstate;
|
|
|
|
Window rootw, childw;
|
|
|
|
XQueryPointer( tqt_xdisplay(), tqt_xrootwin(), &rootw, &childw,
|
|
|
|
&root_x, &root_y, &win_x, &win_y, &keybstate );
|
|
|
|
|
|
|
|
if ( keybstate & ControlMask ) {
|
|
|
|
action = DRAG_COPY;
|
|
|
|
} else if ( keybstate & ShiftMask ) {
|
|
|
|
action = DRAG_MOVE;
|
|
|
|
} else {
|
|
|
|
TDEPopupMenu *menu = new TDEPopupMenu( this );
|
|
|
|
if ( existingEvent || existingTodo ) {
|
|
|
|
menu->insertItem( i18n("Move"), DRAG_MOVE, 0 );
|
|
|
|
if (existingEvent)
|
|
|
|
menu->insertItem( KOGlobals::self()->smallIcon("editcopy"), i18n("Copy"), DRAG_COPY, 1 );
|
|
|
|
} else {
|
|
|
|
menu->insertItem( i18n("Add"), DRAG_MOVE, 0 );
|
|
|
|
}
|
|
|
|
menu->insertSeparator();
|
|
|
|
menu->insertItem( KOGlobals::self()->smallIcon("cancel"), i18n("Cancel"), DRAG_CANCEL, 3 );
|
|
|
|
action = menu->exec( TQCursor::pos(), 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( action == DRAG_COPY || action == DRAG_MOVE ) {
|
|
|
|
e->accept();
|
|
|
|
int idx = getDayIndexFrom( e->pos().x(), e->pos().y() );
|
|
|
|
|
|
|
|
if ( action == DRAG_COPY ) {
|
|
|
|
if ( event ) emit incidenceDropped( event, mDays[idx] );
|
|
|
|
if ( todo ) emit incidenceDropped( todo, mDays[idx] );
|
|
|
|
} else if ( action == DRAG_MOVE ) {
|
|
|
|
if ( event ) emit incidenceDroppedMove( event, mDays[idx] );
|
|
|
|
if ( todo ) emit incidenceDroppedMove( todo, mDays[idx] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
delete event;
|
|
|
|
delete todo;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// P A I N T E V E N T H A N D L I N G
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void KODayMatrix::paintEvent( TQPaintEvent * )
|
|
|
|
{
|
|
|
|
// kdDebug(5850) << "KODayMatrix::paintEvent() BEGIN" << endl;
|
|
|
|
|
|
|
|
TQPainter p;
|
|
|
|
TQRect sz = frameRect();
|
|
|
|
TQPixmap pm( sz.size() );
|
|
|
|
int dheight = mDaySize.height();
|
|
|
|
int dwidth = mDaySize.width();
|
|
|
|
int row,col;
|
|
|
|
int selw, selh;
|
|
|
|
bool isRTL = KOGlobals::self()->reverseLayout();
|
|
|
|
|
|
|
|
TQColorGroup cg = palette().active();
|
|
|
|
|
|
|
|
p.begin( &pm, this );
|
|
|
|
pm.fill( cg.base() );
|
|
|
|
|
|
|
|
// draw topleft frame
|
|
|
|
p.setPen( cg.mid() );
|
|
|
|
p.drawRect(0, 0, sz.width()-1, sz.height()-1);
|
|
|
|
// don't paint over borders
|
|
|
|
p.translate(1,1);
|
|
|
|
|
|
|
|
// draw selected days with highlighted background color
|
|
|
|
if (mSelStart != NOSELECTION) {
|
|
|
|
|
|
|
|
row = mSelStart/7;
|
|
|
|
// fix larger selections starting in the previous month
|
|
|
|
if ( row < 0 && mSelEnd > 0 ) row = 0;
|
|
|
|
col = mSelStart -row*7;
|
|
|
|
TQColor selcol = KOPrefs::instance()->mHighlightColor;
|
|
|
|
|
|
|
|
if ( row < 6 && row >= 0 ) {
|
|
|
|
if (row == mSelEnd/7) {
|
|
|
|
// Single row selection
|
|
|
|
p.fillRect(isRTL ? (7 - (mSelEnd-mSelStart+1) - col)*dwidth : col*dwidth,
|
|
|
|
row*dheight, (mSelEnd-mSelStart+1)*dwidth, dheight, selcol);
|
|
|
|
} else {
|
|
|
|
// draw first row to the right
|
|
|
|
p.fillRect(isRTL ? 0 : col*dwidth, row*dheight, (7-col)*dwidth,
|
|
|
|
dheight, selcol);
|
|
|
|
// draw full block till last line
|
|
|
|
selh = mSelEnd/7-row;
|
|
|
|
if ( selh + row >= 6 ) selh = 6-row;
|
|
|
|
if ( selh > 1 ) {
|
|
|
|
p.fillRect(0, (row+1)*dheight, 7*dwidth, (selh-1)*dheight,selcol);
|
|
|
|
}
|
|
|
|
// draw last block from left to mSelEnd
|
|
|
|
if ( mSelEnd/7 < 6 ) {
|
|
|
|
selw = mSelEnd-7*(mSelEnd/7)+1;
|
|
|
|
p.fillRect(isRTL ? (7-selw)*dwidth : 0, (row+selh)*dheight,
|
|
|
|
selw*dwidth, dheight, selcol);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// iterate over all days in the matrix and draw the day label in appropriate colors
|
|
|
|
TQColor textColor = cg.text();
|
|
|
|
TQColor textColorShaded = getShadedColor( textColor );
|
|
|
|
TQColor actcol = textColorShaded;
|
|
|
|
p.setPen(actcol);
|
|
|
|
TQPen tmppen;
|
|
|
|
for ( int i = 0; i < NUMDAYS; ++i ) {
|
|
|
|
row = i/7;
|
|
|
|
col = isRTL ? 6-(i-row*7) : i-row*7;
|
|
|
|
|
|
|
|
// if it is the first day of a month switch color from normal to shaded and vice versa
|
|
|
|
if ( KOGlobals::self()->calendarSystem()->day( mDays[i] ) == 1) {
|
|
|
|
if (actcol == textColorShaded) {
|
|
|
|
actcol = textColor;
|
|
|
|
} else {
|
|
|
|
actcol = textColorShaded;
|
|
|
|
}
|
|
|
|
p.setPen(actcol);
|
|
|
|
}
|
|
|
|
|
|
|
|
//Reset pen color after selected days block
|
|
|
|
if (i == mSelEnd+1) {
|
|
|
|
p.setPen(actcol);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool holiday = ! KOGlobals::self()->isWorkDay( mDays[ i ] );
|
|
|
|
|
|
|
|
TQColor holidayColorShaded = getShadedColor( KOPrefs::instance()->mHolidayColor );
|
|
|
|
// if today then draw rectangle around day
|
|
|
|
if (mToday == i) {
|
|
|
|
tmppen = p.pen();
|
|
|
|
TQPen mTodayPen(p.pen());
|
|
|
|
|
|
|
|
mTodayPen.setWidth(mTodayMarginWidth);
|
|
|
|
//draw red rectangle for holidays
|
|
|
|
if (holiday) {
|
|
|
|
if (actcol == textColor) {
|
|
|
|
mTodayPen.setColor(KOPrefs::instance()->mHolidayColor);
|
|
|
|
} else {
|
|
|
|
mTodayPen.setColor(holidayColorShaded);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//draw gray rectangle for today if in selection
|
|
|
|
if (i >= mSelStart && i <= mSelEnd) {
|
|
|
|
TQColor grey("grey");
|
|
|
|
mTodayPen.setColor(grey);
|
|
|
|
}
|
|
|
|
p.setPen(mTodayPen);
|
|
|
|
p.drawRect(col*dwidth, row*dheight, dwidth, dheight);
|
|
|
|
p.setPen(tmppen);
|
|
|
|
}
|
|
|
|
|
|
|
|
// if any events are on that day then draw it using a bold font
|
|
|
|
if (mEvents[i] > 0) {
|
|
|
|
TQFont myFont = font();
|
|
|
|
myFont.setBold(true);
|
|
|
|
p.setFont(myFont);
|
|
|
|
}
|
|
|
|
|
|
|
|
// if it is a holiday then use the default holiday color
|
|
|
|
if (holiday) {
|
|
|
|
if (actcol == textColor) {
|
|
|
|
p.setPen(KOPrefs::instance()->mHolidayColor);
|
|
|
|
} else {
|
|
|
|
p.setPen(holidayColorShaded);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// draw selected days with special color
|
|
|
|
if ( i >= mSelStart && i <= mSelEnd && !holiday ) {
|
|
|
|
p.setPen( TQColor( "white" ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
p.drawText(col*dwidth, row*dheight, dwidth, dheight,
|
|
|
|
TQt::AlignHCenter | TQt::AlignVCenter, mDayLabels[i]);
|
|
|
|
|
|
|
|
// reset color to actual color
|
|
|
|
if ( holiday ) {
|
|
|
|
p.setPen(actcol);
|
|
|
|
}
|
|
|
|
// reset bold font to plain font
|
|
|
|
if (mEvents[i] > 0) {
|
|
|
|
TQFont myFont = font();
|
|
|
|
myFont.setBold(false);
|
|
|
|
p.setFont(myFont);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
p.end();
|
|
|
|
bitBlt( this, 0, 0, &pm );
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// R E SI Z E E V E N T H A N D L I N G
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void KODayMatrix::resizeEvent( TQResizeEvent * )
|
|
|
|
{
|
|
|
|
TQRect sz = frameRect();
|
|
|
|
mDaySize.setHeight( sz.height() * 7 / NUMDAYS );
|
|
|
|
mDaySize.setWidth( sz.width() / 7 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */
|
|
|
|
TQPair<TQDate,TQDate> KODayMatrix::matrixLimits( const TQDate &month )
|
|
|
|
{
|
|
|
|
const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
|
|
|
|
TQDate d = month;
|
|
|
|
calSys->setYMD( d, calSys->year( month ), calSys->month( month ), 1 );
|
|
|
|
|
|
|
|
const int dayOfWeek = calSys->dayOfWeek( d );
|
|
|
|
const int weekstart = TDEGlobal::locale()->weekStartDay();
|
|
|
|
|
|
|
|
d = d.addDays( weekstart - dayOfWeek );
|
|
|
|
|
|
|
|
if ( dayOfWeek == weekstart ) {
|
|
|
|
d = d.addDays( -7 ); // Start on the second line
|
|
|
|
}
|
|
|
|
|
|
|
|
return tqMakePair( d, d.addDays( NUMDAYS-1 ) );
|
|
|
|
}
|