author | zautrix <zautrix> | 2004-06-26 19:01:18 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2004-06-26 19:01:18 (UTC) |
commit | b9aad1f15dc600e4dbe4c62d3fcced6363188ba3 (patch) (side-by-side diff) | |
tree | 2c3d4004fb21c72cba65793859f9bcd8ffd3a49c /korganizer | |
download | kdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.zip kdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.tar.gz kdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.tar.bz2 |
Initial revision
193 files changed, 40853 insertions, 0 deletions
diff --git a/korganizer/alarmclient.h b/korganizer/alarmclient.h new file mode 100644 index 0000000..dac4776 --- a/dev/null +++ b/korganizer/alarmclient.h @@ -0,0 +1,60 @@ +/* + This file is part of the KOrganizer interfaces. + Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#ifndef ALARMCLIENT_H +#define ALARMCLIENT_H + +#include <qstring.h> +#include <qstringlist.h> + +/** + This class provides the abstract interface for communicating with the alarm + daemon. It has to be implemented by subclasses for specific daemons. The + default implementation does nothing. +*/ +class AlarmClient +{ + public: + /** + Start alarm daemon. + */ + virtual void startDaemon() = 0; + + /** + Set the list of monitored calendars. Deletes previous settings. + */ + virtual bool setCalendars( const QStringList & ) = 0; + + /** + Add calendar for monitoring by alarm daemon. + */ + virtual bool addCalendar( const QString & ) = 0; + + /** + Remove calendar from monitoring by alarm daemon. + */ + virtual bool removeCalendar( const QString & ) = 0; + + /** + Reload calendar at URL. + */ + virtual bool reloadCalendar( const QString & ) = 0; +}; + +#endif diff --git a/korganizer/baseview.moc b/korganizer/baseview.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/baseview.moc diff --git a/korganizer/calendarview.cpp b/korganizer/calendarview.cpp new file mode 100644 index 0000000..7292dcd --- a/dev/null +++ b/korganizer/calendarview.cpp @@ -0,0 +1,3476 @@ +/* + This file is part of KOrganizer. + + Requires the Qt and KDE widget libraries, available at no cost at + http://www.troll.no and http://www.kde.org respectively + + Copyright (c) 1997, 1998, 1999 + Preston Brown (preston.brown@yale.edu) + Fester Zigterman (F.J.F.ZigtermanRustenburg@student.utwente.nl) + Ian Dawes (iadawes@globalserve.net) + Laszlo Boloni (boloni@cs.purdue.edu) + + Copyright (c) 2000, 2001, 2002 + Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include <stdlib.h> + +#include <qapplication.h> +#include <qradiobutton.h> +#include <qbuttongroup.h> +#include <qlayout.h> +#include <qclipboard.h> +#include <qcursor.h> +#include <qmessagebox.h> +#include <qprogressbar.h> +#include <qmultilineedit.h> +#include <qtimer.h> +#include <qwidgetstack.h> +#include <qptrlist.h> +#include <qregexp.h> +#include <qgroupbox.h> +#include <qfile.h> +#include <qdir.h> +#ifndef KORG_NOSPLITTER +#include <qsplitter.h> +#endif + +#include <kglobal.h> +#include <kdebug.h> +#include <kstandarddirs.h> +#include <kfiledialog.h> +#include <kmessagebox.h> +#include <knotifyclient.h> +#include <kconfig.h> + +#include "kosyncprefsdialog.h" +#include <krun.h> +#include <kdirwatch.h> +#include <libkdepim/kdatepicker.h> +#include <libkdepim/ksyncprofile.h> + +#include <libkcal/vcaldrag.h> +#include <libkcal/icaldrag.h> +#include <libkcal/icalformat.h> +#include <libkcal/vcalformat.h> +#include <libkcal/scheduler.h> +#include <libkcal/calendarlocal.h> +#include <libkcal/journal.h> +#include <libkcal/calfilter.h> +#include <libkcal/attendee.h> +#include <libkcal/dndfactory.h> +#include <libkcal/freebusy.h> +#include <libkcal/filestorage.h> +#include <libkcal/calendarresources.h> +#include <libkcal/qtopiaformat.h> +#include "../kalarmd/alarmdialog.h" + +#ifndef DESKTOP_VERSION +#include <libkcal/sharpformat.h> +#endif +#ifndef KORG_NOMAIL +#include "komailclient.h" +#endif +#ifndef KORG_NOPRINTER +#include "calprinter.h" +#endif +#ifndef KORG_NOPLUGINS +#include "kocore.h" +#endif +#include "koeventeditor.h" +#include "kotodoeditor.h" +#include "koprefs.h" +#include "koeventviewerdialog.h" +#include "publishdialog.h" +#include "kofilterview.h" +#include "koglobals.h" +#include "koviewmanager.h" +#include "koagendaview.h" +#include "kodialogmanager.h" +#include "outgoingdialog.h" +#include "incomingdialog.h" +#include "statusdialog.h" +#include "kdatenavigator.h" +#include "kotodoview.h" +#include "datenavigator.h" +#include "resourceview.h" +#include "navigatorbar.h" +#include "searchdialog.h" +#include "mainwindow.h" + +#include "calendarview.h" +#ifndef DESKTOP_VERSION +#include <qtopia/alarmserver.h> +#endif +#ifndef _WIN32_ +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#else +#include <qprocess.h> +#endif +using namespace KOrg; +extern int globalFlagBlockAgenda; +extern int globalFlagBlockStartup; + +#define SYNC_MODE_NORMAL 0 +#define SYNC_MODE_SHARP 1 +#define SYNC_MODE_QTOPIA 2 + +class KOBeamPrefs : public QDialog +{ + public: + KOBeamPrefs( QWidget *parent=0, const char *name=0 ) : + QDialog( parent, name, true ) + { + setCaption( i18n("Beam Options") ); + QVBoxLayout* lay = new QVBoxLayout( this ); + lay->setSpacing( 3 ); + lay->setMargin( 3 ); + QButtonGroup* format = new QButtonGroup( 1, Horizontal, i18n("File format"), this ); + lay->addWidget( format ); + format->setExclusive ( true ) ; + QButtonGroup* time = new QButtonGroup(1, Horizontal, i18n("Time format"), this ); + lay->addWidget( time ); time->setExclusive ( true ) ; + vcal = new QRadioButton(" vCalendar ", format ); + ical = new QRadioButton(" iCalendar ", format ); + vcal->setChecked( true ); + tz = new QRadioButton(i18n(" With timezone "), time ); + local = new QRadioButton(i18n(" Local time "), time ); + tz->setChecked( true ); + QPushButton * ok = new QPushButton( i18n("Beam via IR!"), this ); + lay->addWidget( ok ); + QPushButton * cancel = new QPushButton( i18n("Cancel"), this ); + lay->addWidget( cancel ); + connect ( ok,SIGNAL(clicked() ),this , SLOT ( accept() ) ); + connect (cancel, SIGNAL(clicked() ), this, SLOT ( reject()) ); + resize( 200, 200 ); + } + + bool beamVcal() { return vcal->isChecked(); } + bool beamLocal() { return local->isChecked(); } +private: + QRadioButton* vcal, *ical, *local, *tz; +}; +class KOCatPrefs : public QDialog +{ + public: + KOCatPrefs( QWidget *parent=0, const char *name=0 ) : + QDialog( parent, name, true ) + { + setCaption( i18n("Manage new Categories") ); + QVBoxLayout* lay = new QVBoxLayout( this ); + lay->setSpacing( 3 ); + lay->setMargin( 3 ); + QLabel * lab = new QLabel( i18n("After importing/loading/syncing\nthere may be new categories in\nevents or todos\nwhich are not in the category list.\nPlease choose what to do:\n "), this ); + lay->addWidget( lab ); + QButtonGroup* format = new QButtonGroup( 1, Horizontal, i18n("New categories not in list:"), this ); + lay->addWidget( format ); + format->setExclusive ( true ) ; + addCatBut = new QRadioButton(i18n("Add to category list"), format ); + new QRadioButton(i18n("Remove from Events/Todos"), format ); + addCatBut->setChecked( true ); + QPushButton * ok = new QPushButton( i18n("OK"), this ); + lay->addWidget( ok ); + QPushButton * cancel = new QPushButton( i18n("Cancel"), this ); + lay->addWidget( cancel ); + connect ( ok,SIGNAL(clicked() ),this , SLOT ( accept() ) ); + connect (cancel, SIGNAL(clicked() ), this, SLOT ( reject()) ); + resize( 200, 200 ); + } + + bool addCat() { return addCatBut->isChecked(); } +private: + QRadioButton* addCatBut; +}; + + + +CalendarView::CalendarView( CalendarResources *calendar, + QWidget *parent, const char *name ) + : CalendarViewBase( parent, name ), + mCalendar( calendar ), + mResourceManager( calendar->resourceManager() ) +{ + + mEventEditor = 0; + mTodoEditor = 0; + + init(); +} + +CalendarView::CalendarView( Calendar *calendar, + QWidget *parent, const char *name ) + : CalendarViewBase( parent, name ), + mCalendar( calendar ), + mResourceManager( 0 ) +{ + + mEventEditor = 0; + mTodoEditor = 0; + init();} + +void CalendarView::init() +{ + beamDialog = new KOBeamPrefs(); + mDatePickerMode = 0; + mCurrentSyncDevice = ""; + writeLocale(); + mViewManager = new KOViewManager( this ); + mDialogManager = new KODialogManager( this ); + mEventViewerDialog = 0; + mModified = false; + mReadOnly = false; + mSelectedIncidence = 0; + mSyncProfiles.setAutoDelete(true); + mCalPrinter = 0; + mFilters.setAutoDelete(true); + + mCalendar->registerObserver( this ); + // TODO: Make sure that view is updated, when calendar is changed. + + mStorage = new FileStorage( mCalendar ); + mNavigator = new DateNavigator( this, "datevav", mViewManager ); + + QBoxLayout *topLayout = (QBoxLayout*)layout(); +#ifndef KORG_NOSPLITTER + // create the main layout frames. + mPanner = new QSplitter(QSplitter::Horizontal,this,"CalendarView::Panner"); + topLayout->addWidget(mPanner); + + mLeftSplitter = new QSplitter(QSplitter::Vertical,mPanner, + "CalendarView::LeftFrame"); + mPanner->setResizeMode(mLeftSplitter,QSplitter::KeepSize); + + mDateNavigator = new KDateNavigator(mLeftSplitter, mCalendar, TRUE, + "CalendarView::DateNavigator", QDate::currentDate() ); + mLeftSplitter->setResizeMode(mDateNavigator,QSplitter::KeepSize); + mTodoList = new KOTodoView(mCalendar, mLeftSplitter, "todolist_small2"); + mFilterView = new KOFilterView(&mFilters,mLeftSplitter,"CalendarView::FilterView"); + +#ifdef KORG_NORESOURCEVIEW + mResourceView = 0; +#else + if ( mResourceManager ) { + mResourceView = new ResourceView( mResourceManager, mLeftSplitter ); + mResourceView->updateView(); + connect( mResourceView, SIGNAL( resourcesChanged() ), + SLOT( updateView() ) ); + } else { + mResourceView = 0; + } +#endif + QWidget *rightBox = new QWidget( mPanner ); + QBoxLayout *rightLayout = new QVBoxLayout( rightBox ); + + mNavigatorBar = new NavigatorBar( QDate::currentDate(), rightBox, "useBigPixmaps" ); + rightLayout->addWidget( mNavigatorBar ); + + mRightFrame = new QWidgetStack( rightBox ); + rightLayout->addWidget( mRightFrame, 1 ); + + mLeftFrame = mLeftSplitter; +#else + QWidget *mainBox = new QWidget( this ); + QWidget *leftFrame = new QWidget( mainBox ); + + QBoxLayout * mainBoxLayout; + QBoxLayout * leftFrameLayout; + if ( KOPrefs::instance()->mVerticalScreen ) { + mainBoxLayout = new QVBoxLayout(mainBox); + leftFrameLayout = new QHBoxLayout(leftFrame ); + } else { + mainBoxLayout = new QHBoxLayout(mainBox); + leftFrameLayout = new QVBoxLayout(leftFrame ); + } + topLayout->addWidget( mainBox ); + mainBoxLayout->addWidget (leftFrame); + mDateNavigator = new KDateNavigator(leftFrame, mCalendar, TRUE, + "CalendarView::DateNavigator", QDate::currentDate()); + // mDateNavigator->blockSignals( true ); + leftFrameLayout->addWidget( mDateNavigator ); + mFilterView = new KOFilterView(&mFilters,leftFrame,"CalendarView::FilterView"); + mTodoList = new KOTodoView(mCalendar, leftFrame, "todolist"); + + if ( QApplication::desktop()->width() < 480 ) { + leftFrameLayout->addWidget(mFilterView); + leftFrameLayout->addWidget(mTodoList, 2 ); + + } else { + leftFrameLayout->addWidget(mTodoList,2 ); + leftFrameLayout->addWidget(mFilterView ); + } + mFilterView->hide(); + QWidget *rightBox = new QWidget( mainBox ); + mainBoxLayout->addWidget ( rightBox, 10 ); + QBoxLayout *rightLayout = new QVBoxLayout( rightBox ); + mNavigatorBar = new NavigatorBar( QDate::currentDate(), rightBox, "useBigPixmaps" ); + mRightFrame = new QWidgetStack( rightBox ); + rightLayout->addWidget( mNavigatorBar ); + rightLayout->addWidget( mRightFrame, 10 ); + + mLeftFrame = leftFrame; + if ( KOPrefs::instance()->mVerticalScreen ) { + mTodoList->setFixedHeight( mDateNavigator->sizeHint().height() ); + leftFrame->setFixedHeight( mDateNavigator->sizeHint().height() ); + } else { + mTodoList->setFixedWidth( mDateNavigator->sizeHint().width() ); + leftFrame->setFixedWidth( mDateNavigator->sizeHint().width() ); + } + + //qDebug("Calendarview Size %d %d ", width(), height()); +#endif + + connect( mNavigator, SIGNAL( datesSelected( const KCal::DateList & ) ), + SLOT( showDates( const KCal::DateList & ) ) ); + connect( mNavigator, SIGNAL( datesSelected( const KCal::DateList & ) ), + mDateNavigator, SLOT( selectDates( const KCal::DateList & ) ) ); + + connect( mNavigatorBar, SIGNAL( goPrevYear() ), + mNavigator, SLOT( selectPreviousYear() ) ); + connect( mNavigatorBar, SIGNAL( goNextYear() ), + mNavigator, SLOT( selectNextYear() ) ); + connect( mNavigatorBar, SIGNAL( goPrevMonth() ), + mNavigator, SLOT( selectPreviousMonth() ) ); + connect( mNavigatorBar, SIGNAL( goNextMonth() ), + mNavigator, SLOT( selectNextMonth() ) ); + + connect( mNavigator, SIGNAL( datesSelected( const KCal::DateList & ) ), + mNavigatorBar, SLOT( selectDates( const KCal::DateList & ) ) ); + + connect( mDateNavigator, SIGNAL( weekClicked( const QDate & ) ), + mNavigator, SLOT( selectWeek( const QDate & ) ) ); + + connect( mDateNavigator, SIGNAL( goPrevYear() ), + mNavigator, SLOT( selectPreviousYear() ) ); + connect( mDateNavigator, SIGNAL( goNextYear() ), + mNavigator, SLOT( selectNextYear() ) ); + connect( mDateNavigator, SIGNAL( goPrevMonth() ), + mNavigator, SLOT( selectPreviousMonth() ) ); + connect( mDateNavigator, SIGNAL( goNextMonth() ), + mNavigator, SLOT( selectNextMonth() ) ); + + connect( mDateNavigator, SIGNAL( goPrevious() ), + mNavigator, SLOT( selectPrevious() ) ); + connect( mDateNavigator, SIGNAL( goNext() ), + mNavigator, SLOT( selectNext() ) ); + connect( mDateNavigator, SIGNAL( monthSelected ( int ) ), + mNavigator, SLOT( slotMonthSelect( int ) ) ); + connect( mNavigatorBar, SIGNAL( monthSelected ( int ) ), + mNavigator, SLOT( slotMonthSelect( int ) ) ); + + connect( mDateNavigator, SIGNAL( datesSelected( const KCal::DateList & ) ), + mNavigator, SLOT( selectDates( const KCal::DateList & ) ) ); + + connect( mDateNavigator, SIGNAL( eventDropped( Event * ) ), + SLOT( eventAdded( Event *) ) ); + + connect(mDateNavigator,SIGNAL(dayPassed(QDate)),SLOT(updateView())); + + connect( this, SIGNAL( configChanged() ), + mDateNavigator, SLOT( updateConfig() ) ); + + connect( mTodoList, SIGNAL( newTodoSignal() ), + SLOT( newTodo() ) ); + connect( mTodoList, SIGNAL( newSubTodoSignal( Todo *) ), + SLOT( newSubTodo( Todo * ) ) ); + connect( mTodoList, SIGNAL( editTodoSignal( Todo * ) ), + SLOT( editTodo( Todo * ) ) ); + connect( mTodoList, SIGNAL( showTodoSignal( Todo * ) ), + SLOT( showTodo( Todo *) ) ); + connect( mTodoList, SIGNAL( deleteTodoSignal( Todo *) ), + SLOT( deleteTodo( Todo *) ) ); + connect( this, SIGNAL( configChanged()), mTodoList, SLOT( updateConfig() ) ); + connect( mTodoList, SIGNAL( purgeCompletedSignal() ), + SLOT( purgeCompleted() ) ); + connect( mTodoList, SIGNAL( todoModifiedSignal( Todo *, int ) ), + SIGNAL( todoModified( Todo *, int ) ) ); + + connect( mTodoList, SIGNAL( cloneTodoSignal( Incidence * ) ), + this, SLOT ( cloneIncidence( Incidence * ) ) ); + connect( mTodoList, SIGNAL( cancelTodoSignal( Incidence * ) ), + this, SLOT (cancelIncidence( Incidence * ) ) ); + + connect( mTodoList, SIGNAL( moveTodoSignal( Incidence * ) ), + this, SLOT ( moveIncidence( Incidence * ) ) ); + connect( mTodoList, SIGNAL( beamTodoSignal( Incidence * ) ), + this, SLOT ( beamIncidence( Incidence * ) ) ); + + connect( mTodoList, SIGNAL( unparentTodoSignal( Todo * ) ), + this, SLOT ( todo_unsub( Todo * ) ) ); + + connect( this, SIGNAL( todoModified( Todo *, int )), mTodoList, + SLOT( updateTodo( Todo *, int ) ) ); + connect( this, SIGNAL( todoModified( Todo *, int )), this, + SLOT( changeTodoDisplay( Todo *, int ) ) ); + + + connect( mFilterView, SIGNAL( filterChanged() ), SLOT( updateFilter() ) ); + connect( mFilterView, SIGNAL( editFilters() ), SLOT( editFilters() ) ); + connect( mCalendar, SIGNAL( addAlarm(const QDateTime &, const QString & ) ), SLOT( addAlarm(const QDateTime &, const QString & ) ) ); + connect( mCalendar, SIGNAL( removeAlarm(const QDateTime &, const QString & ) ), SLOT( removeAlarm(const QDateTime &, const QString & ) ) ); + + + + + + connect(QApplication::clipboard(),SIGNAL(dataChanged()), + SLOT(checkClipboard())); + connect( mTodoList,SIGNAL( incidenceSelected( Incidence * ) ), + SLOT( processTodoListSelection( Incidence * ) ) ); + connect(mTodoList,SIGNAL(isModified(bool)),SLOT(setModified(bool))); + + // kdDebug() << "CalendarView::CalendarView() done" << endl; + + mDateFrame = new QVBox(0,0,WType_Popup); + //mDateFrame->setFrameStyle(QFrame::PopupPanel | QFrame::Raised); + mDateFrame->setFrameStyle( QFrame::WinPanel |QFrame::Raised ); + mDateFrame->setLineWidth(3); + mDateFrame->hide(); + mDateFrame->setCaption( i18n( "Pick a date to display")); + mDatePicker = new KDatePicker ( mDateFrame , QDate::currentDate() ); + + connect(mDatePicker,SIGNAL(dateSelected(QDate)),SLOT(slotSelectPickerDate(QDate))); + + mEventEditor = mDialogManager->getEventEditor(); + mTodoEditor = mDialogManager->getTodoEditor(); + + mFlagEditDescription = false; + + mSuspendTimer = new QTimer( this ); + mAlarmTimer = new QTimer( this ); + connect( mSuspendTimer, SIGNAL( timeout () ), SLOT( suspendAlarm() ) ); + connect( mAlarmTimer, SIGNAL( timeout () ), SLOT( timerAlarm() ) ); + mAlarmDialog = new AlarmDialog( this ); + connect( mAlarmDialog, SIGNAL( addAlarm(const QDateTime &, const QString & ) ), SLOT( addSuspendAlarm(const QDateTime &, const QString & ) ) ); + mAlarmDialog->setServerNotification( false ); + mAlarmDialog->setSuspendTime( KOPrefs::instance()->mAlarmSuspendTime ); +} + + +CalendarView::~CalendarView() +{ + // kdDebug() << "~CalendarView()" << endl; + //qDebug("CalendarView::~CalendarView() "); + delete mDialogManager; + delete mViewManager; + delete mStorage; + delete mDateFrame ; + delete beamDialog; + //kdDebug() << "~CalendarView() done" << endl; +} +void CalendarView::timerAlarm() +{ + //qDebug("CalendarView::timerAlarm() "); + computeAlarm(mAlarmNotification ); +} + +void CalendarView::suspendAlarm() +{ + //qDebug(" CalendarView::suspendAlarm() "); + computeAlarm(mSuspendAlarmNotification ); + +} + +void CalendarView::startAlarm( QString mess , QString filename) +{ + mAlarmDialog->eventNotification( mess, KOPrefs::instance()->mAlarmPlayBeeps, filename, true,KOPrefs::instance()->mAlarmBeepInterval ,KOPrefs::instance()->mAlarmSuspendCount ); + +} + + +void CalendarView::computeAlarm( QString msg ) +{ + + QString mess = msg; + QString mAlarmMessage = mess.mid( 9 ); + QString filename = MainWindow::resourcePath(); + filename += "koalarm.wav"; + QString tempfilename; + if ( mess.left( 13 ) == "suspend_alarm") { + bool error = false; + int len = mess.mid( 13 ).find("+++"); + if ( len < 2 ) + error = true; + else { + tempfilename = mess.mid( 13, len ); + if ( !QFile::exists( tempfilename ) ) + error = true; + } + if ( ! error ) { + filename = tempfilename; + } + mAlarmMessage = mess.mid( 13+len+3 ); + //qDebug("suspend file %s ",tempfilename.latin1() ); + startAlarm( mAlarmMessage, filename); + return; + } + if ( mess.left( 11 ) == "timer_alarm") { + //mTimerTime = 0; + startAlarm( mess.mid( 11 ), filename ); + return; + } + if ( mess.left( 10 ) == "proc_alarm") { + bool error = false; + int len = mess.mid( 10 ).find("+++"); + if ( len < 2 ) + error = true; + else { + tempfilename = mess.mid( 10, len ); + if ( !QFile::exists( tempfilename ) ) + error = true; + } + if ( error ) { + mAlarmMessage = "Procedure Alarm\nError - File not found\n"; + mAlarmMessage += mess.mid( 10+len+3+9 ); + } else { + //QCopEnvelope e("QPE/Application/kopi", "-writeFileSilent"); + //qDebug("-----system command %s ",tempfilename.latin1() ); +#ifndef _WIN32_ + if ( vfork () == 0 ) { + execl ( tempfilename.latin1(), 0 ); + return; + } +#else + QProcess* p = new QProcess(); + p->addArgument( tempfilename.latin1() ); + p->start(); + return; +#endif + + return; + } + + //qDebug("+++++++system command %s ",tempfilename.latin1() ); + } + if ( mess.left( 11 ) == "audio_alarm") { + bool error = false; + int len = mess.mid( 11 ).find("+++"); + if ( len < 2 ) + error = true; + else { + tempfilename = mess.mid( 11, len ); + if ( !QFile::exists( tempfilename ) ) + error = true; + } + if ( ! error ) { + filename = tempfilename; + } + mAlarmMessage = mess.mid( 11+len+3+9 ); + //qDebug("audio file command %s ",tempfilename.latin1() ); + } + if ( mess.left( 9 ) == "cal_alarm") { + mAlarmMessage = mess.mid( 9 ) ; + } + + startAlarm( mAlarmMessage, filename ); + + +} + +void CalendarView::addSuspendAlarm(const QDateTime &qdt, const QString ¬i ) +{ + //qDebug("+++++addSUSPENDAlarm %s %s ", qdt.toString().latin1() , noti.latin1() ); + + mSuspendAlarmNotification = noti; + int ms = QDateTime::currentDateTime().secsTo( qdt )*1000; + //qDebug("Suspend Alarm timer started with secs: %d ", ms/1000); + mSuspendTimer->start( ms , true ); + +} + +void CalendarView::addAlarm(const QDateTime &qdt, const QString ¬i ) +{ + //qDebug("+++++addAlarm %s %s ", qdt.toString().latin1() , noti.latin1() ); + if ( ! KOPrefs::instance()->mUseInternalAlarmNotification ) { +#ifndef DESKTOP_VERSION + AlarmServer::addAlarm ( qdt,"koalarm", noti.latin1() ); +#endif + return; + } + mAlarmNotification = noti; + int ms = QDateTime::currentDateTime().secsTo( qdt )*1000; + //qDebug("Alarm timer started with secs: %d ", ms/1000); + mAlarmTimer->start( ms , true ); + +} +void CalendarView::removeAlarm(const QDateTime &qdt, const QString ¬i ) +{ + //qDebug("-----removeAlarm %s %s ", qdt.toString().latin1() , noti.latin1() ); + if ( ! KOPrefs::instance()->mUseInternalAlarmNotification ) { +#ifndef DESKTOP_VERSION + AlarmServer::deleteAlarm (qdt ,"koalarm" ,noti.latin1() ); +#endif + return; + } + mAlarmTimer->stop(); +} +void CalendarView::selectWeekNum ( int num ) +{ + dateNavigator()->selectWeek( num ); + mViewManager->showWeekView(); +} +KOViewManager *CalendarView::viewManager() +{ + return mViewManager; +} + +KODialogManager *CalendarView::dialogManager() +{ + return mDialogManager; +} + +QDate CalendarView::startDate() +{ + DateList dates = mNavigator->selectedDates(); + + return dates.first(); +} + +QDate CalendarView::endDate() +{ + DateList dates = mNavigator->selectedDates(); + + return dates.last(); +} + + +void CalendarView::createPrinter() +{ +#ifndef KORG_NOPRINTER + if (!mCalPrinter) { + mCalPrinter = new CalPrinter(this, mCalendar); + connect(this, SIGNAL(configChanged()), mCalPrinter, SLOT(updateConfig())); + } +#endif +} + +void CalendarView::confSync() +{ + static KOSyncPrefsDialog* sp = 0; + if ( ! sp ) { + sp = new KOSyncPrefsDialog( this, "syncprefs", true ); + } + sp->usrReadConfig(); +#ifndef DESKTOP_VERSION + sp->showMaximized(); +#else + sp->show(); +#endif + sp->exec(); + +} + + +//KOPrefs::instance()->mWriteBackFile +//KOPrefs::instance()->mWriteBackExistingOnly + +// 0 syncPrefsGroup->addRadio(i18n("Take local entry on conflict")); +// 1 syncPrefsGroup->addRadio(i18n("Take remote entry on conflict")); +// 2 syncPrefsGroup->addRadio(i18n("Take newest entry on conflict")); +// 3 syncPrefsGroup->addRadio(i18n("Ask for every entry on conflict")); +// 4 syncPrefsGroup->addRadio(i18n("Force take local entry always")); +// 5 syncPrefsGroup->addRadio(i18n("Force take remote entry always")); + +int CalendarView::takeEvent( Incidence* local, Incidence* remote, int mode , bool full ) +{ + + //void setZaurusId(int id); + // int zaurusId() const; + // void setZaurusUid(int id); + // int zaurusUid() const; + // void setZaurusStat(int id); + // int zaurusStat() const; + // 0 equal + // 1 take local + // 2 take remote + // 3 cancel + QDateTime lastSync = mLastCalendarSync; + if ( mGlobalSyncMode == SYNC_MODE_SHARP ) { + bool remCh, locCh; + remCh = ( remote->zaurusUid() != local->zaurusUid() ); + locCh = ( local->zaurusStat() != local->revision() ); + //qDebug("locCh %d remCh %d locuid %d remuid %d", locCh, remCh,local->zaurusUid(), remote->zaurusUid() ); + if ( !remCh && ! locCh ) { + //qDebug("both not changed "); + lastSync = local->lastModified().addDays(1); + } else { + if ( locCh ) { + //qDebug("loc changed %d %d", local->zaurusStat(), local->revision() ); + lastSync = local->lastModified().addDays( -1 ); + if ( !remCh ) + remote->setLastModified( lastSync.addDays( -1 ) ); + } else { + //qDebug(" not loc changed "); + lastSync = local->lastModified().addDays( 1 ); + if ( remCh ) + remote->setLastModified( lastSync.addDays( 1 ) ); + + } + } + full = true; + if ( mode < 3 ) + mode = 3; + } else { + if ( local->lastModified() == remote->lastModified() ) + if ( local->revision() == remote->revision() ) + return 0; + + } + // qDebug(" %d %d conflict on %s %s ", mode, full, local->summary().latin1(), remote->summary().latin1() ); + + //qDebug("%s %d %s %d", local->lastModified().toString().latin1() , local->revision(), remote->lastModified().toString().latin1(), remote->revision()); + //qDebug("%d %d %d %d ", local->lastModified().time().second(), local->lastModified().time().msec(), remote->lastModified().time().second(), remote->lastModified().time().msec() ); + //full = true; //debug only + if ( full ) { + bool equ = false; + if ( local->type() == "Event" ) { + equ = (*((Event*) local) == *((Event*) remote)); + } + else if ( local->type() =="Todo" ) + equ = (*((Todo*) local) == (*(Todo*) remote)); + else if ( local->type() =="Journal" ) + equ = (*((Journal*) local) == *((Journal*) remote)); + if ( equ ) { + //qDebug("equal "); + if ( mGlobalSyncMode == SYNC_MODE_SHARP ) { + local->setZaurusUid( remote->zaurusUid() ); + } + if ( mode < 4 ) + return 0; + + }//else //debug only + //qDebug("not equal %s %s ", local->summary().latin1(), remote->summary().latin1()); + } + int result; + bool localIsNew; + if ( full && mode < 2 ) + mode = 3; + + switch( mode ) { + case 0: + if ( lastSync > remote->lastModified() ) + return 1; + if ( lastSync > local->lastModified() ) + return 2; + return 1; + break; + case 1: + if ( lastSync > remote->lastModified() ) + return 1; + if ( lastSync > local->lastModified() ) + return 2; + return 2; + break; + case 2: + if ( local->lastModified() > remote->lastModified() ) + return 1; + else + return 2; + break; + case 3: + //qDebug("lsy %s --- lo %s --- re %s ", lastSync.toString().latin1(), local->lastModified().toString().latin1(), remote->lastModified().toString().latin1() ); + if ( lastSync > remote->lastModified() ) + return 1; + if ( lastSync > local->lastModified() ) + return 2; + //qDebug("lsy %s --- lo %s --- re %s ", lastSync.toString().latin1(), local->lastModified().toString().latin1(), remote->lastModified().toString().latin1() ); + localIsNew = local->lastModified() > remote->lastModified(); + if ( localIsNew ) + getEventViewerDialog()->setColorMode( 1 ); + else + getEventViewerDialog()->setColorMode( 2 ); + getEventViewerDialog()->setIncidence(local); + if ( localIsNew ) + getEventViewerDialog()->setColorMode( 2 ); + else + getEventViewerDialog()->setColorMode( 1 ); + getEventViewerDialog()->addIncidence(remote); + getEventViewerDialog()->setColorMode( 0 ); + //qDebug("local %d remote %d ",local->relatedTo(),remote->relatedTo() ); + getEventViewerDialog()->setCaption( mCurrentSyncDevice +i18n(" : Conflict! Please choose entry!")); + getEventViewerDialog()->showMe(); + result = getEventViewerDialog()->executeS( localIsNew ); + return result; + + break; + case 4: + return 1; + break; + case 5: + return 2; + break; + + default: + break; + } + return 0; +} +Event* CalendarView::getLastSyncEvent() +{ + Event* lse; + //qDebug("CurrentSyncDevice %s ",mCurrentSyncDevice .latin1() ); + lse = mCalendar->event( "last-syncEvent-device-"+mCurrentSyncDevice ); + if (!lse) { + lse = new Event(); + lse->setUid( "last-syncEvent-device-"+mCurrentSyncDevice ); + lse->setSummary(mCurrentSyncDevice + i18n(" - sync event")); + lse->setDtStart( mLastCalendarSync ); + lse->setDtEnd( mLastCalendarSync.addSecs( 7200 ) ); + lse->setCategories( i18n("SyncEvent") ); + lse->setReadOnly( true ); + mCalendar->addEvent( lse ); + } + + return lse; + +} +void CalendarView::checkSharpEvent( Event* lastSync, Incidence* toDelete ) +{ + if ( ! lastSync ) + return; + if ( toDelete->zaurusId() < 0 ) + return; + if ( toDelete->type() == "Journal" ) + return; + QString des = lastSync->description(); + QString pref = "e"; + if ( toDelete->type() == "Todo" ) + pref = "t"; + des += pref+ QString::number ( toDelete->zaurusId() ) + ","; + lastSync->setReadOnly( false ); + lastSync->setDescription( des ); + lastSync->setReadOnly( true ); + +} +bool CalendarView::synchronizeCalendar( Calendar* local, Calendar* remote, int mode ) +{ + bool syncOK = true; + int addedEvent = 0; + int addedEventR = 0; + int deletedEventR = 0; + int deletedEventL = 0; + int changedLocal = 0; + int changedRemote = 0; + //QPtrList<Event> el = local->rawEvents(); + Event* eventR; + QString uid; + int take; + Event* eventL; + Event* eventRSync; + Event* eventLSync; + Event* eventRSyncSharp = remote->event( "last-syncEvent-device-Sharp-DTM"); + Event* eventLSyncSharp = local->event( "last-syncEvent-device-Sharp-DTM"); + bool fullDateRange = false; + mLastCalendarSync = QDateTime::currentDateTime(); + QDateTime modifiedCalendar = mLastCalendarSync;; + eventR = remote->event("last-syncEvent-device-"+mCurrentSyncName ); + if ( eventR ) { + eventRSync = (Event*) eventR->clone(); + remote->deleteEvent(eventR ); + + } else { + fullDateRange = true; + eventRSync = new Event(); + eventRSync->setSummary(mCurrentSyncName + i18n(" - sync event")); + eventRSync->setUid("last-syncEvent-device-"+mCurrentSyncName ); + eventRSync->setDtStart( mLastCalendarSync ); + eventRSync->setDtEnd( mLastCalendarSync.addSecs( 7200 ) ); + eventRSync->setCategories( i18n("SyncEvent") ); + } + eventLSync = getLastSyncEvent(); + if ( eventLSync->dtStart() == mLastCalendarSync ) + fullDateRange = true; + + if ( ! fullDateRange ) { + if ( eventLSync->dtStart() != eventRSync->dtStart() ) { + + // qDebug("set fulldate to true %s %s" ,eventLSync->dtStart().toString().latin1(), eventRSync->dtStart().toString().latin1() ); + //qDebug("%d %d %d %d ", eventLSync->dtStart().time().second(), eventLSync->dtStart().time().msec() , eventRSync->dtStart().time().second(), eventRSync->dtStart().time().msec()); + fullDateRange = true; + } + } + if ( fullDateRange ) + mLastCalendarSync = QDateTime::currentDateTime().addDays( -100*365); + else + mLastCalendarSync = eventLSync->dtStart(); + // for resyncing if own file has changed + if ( mCurrentSyncDevice == "deleteaftersync" ) { + mLastCalendarSync = loadedFileVersion; + qDebug("setting mLastCalendarSync "); + } + //qDebug("*************************** "); + qDebug("mLastCalendarSync %s ",mLastCalendarSync.toString().latin1() ); + QPtrList<Incidence> er = remote->rawIncidences(); + Incidence* inR = er.first(); + Incidence* inL; + QProgressBar bar( er.count(),0 ); + bar.setCaption (i18n("Syncing - close to abort!") ); + + int w = 300; + if ( QApplication::desktop()->width() < 320 ) + w = 220; + int h = bar.sizeHint().height() ; + int dw = QApplication::desktop()->width(); + int dh = QApplication::desktop()->height(); + bar.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); + bar.show(); + int modulo = (er.count()/10)+1; + int incCounter = 0; + while ( inR ) { + if ( ! bar.isVisible() ) + return false; + if ( incCounter % modulo == 0 ) + bar.setProgress( incCounter ); + ++incCounter; + uid = inR->uid(); + bool skipIncidence = false; + if ( uid.left(21) == QString("last-syncEvent-device") ) + skipIncidence = true; + + qApp->processEvents(); + if ( !skipIncidence ) { + inL = local->incidence( uid ); + if ( inL ) { // maybe conflict - same uid in both calendars + int maxrev = inL->revision(); + if ( maxrev < inR->revision() ) + maxrev = inR->revision(); + if ( (take = takeEvent( inL, inR, mode, fullDateRange )) > 0 ) { + //qDebug("take %d %s ", take, inL->summary().latin1()); + if ( take == 3 ) + return false; + if ( take == 1 ) {// take local + inL->setZaurusUid( inR->zaurusUid() ); + remote->deleteIncidence( inR ); + if ( inL->revision() < maxrev ) + inL->setRevision( maxrev ); + remote->addIncidence( inL->clone() ); + ++changedRemote; + } else { + if ( inR->revision() < maxrev ) + inR->setRevision( maxrev ); + local->deleteIncidence( inL ); + local->addIncidence( inR->clone() ); + ++changedLocal; + } + } + } else { // no conflict + if ( mGlobalSyncMode == SYNC_MODE_SHARP ) { + QString des = eventLSync->description(); + QString pref = "e"; + if ( inR->type() == "Todo" ) + pref = "t"; + if ( des.find(pref+QString::number( inR->zaurusId() ) +"," ) >= 0 && mode != 5) { // delete it + inR->setZaurusStat( -3 ); + //remote->deleteIncidence( inR ); + ++deletedEventR; + } else { + inR->setLastModified( modifiedCalendar ); + local->addIncidence( inR->clone() ); + ++addedEvent; + } + } else { + if ( inR->lastModified() > mLastCalendarSync || mode == 5 ) { + inR->setLastModified( modifiedCalendar ); + local->addIncidence( inR->clone() ); + ++addedEvent; + } else { + checkSharpEvent(eventRSyncSharp, inR); + remote->deleteIncidence( inR ); + ++deletedEventR; + } + } + } + } + inR = er.next(); + } + QPtrList<Incidence> el = local->rawIncidences(); + inL = el.first(); + modulo = (el.count()/10)+1; + bar.setCaption (i18n("Add / remove events") ); + bar.setTotalSteps ( el.count() ) ; + bar.show(); + incCounter = 0; + + while ( inL ) { + + qApp->processEvents(); + if ( ! bar.isVisible() ) + return false; + if ( incCounter % modulo == 0 ) + bar.setProgress( incCounter ); + ++incCounter; + uid = inL->uid(); + bool skipIncidence = false; + if ( uid.left(21) == QString("last-syncEvent-device") ) + skipIncidence = true; + if ( mGlobalSyncMode == SYNC_MODE_SHARP && inL->type() == "Journal" ) + skipIncidence = true; + if ( !skipIncidence ) { + inR = remote->incidence( uid ); + if ( ! inR ) { + if ( mGlobalSyncMode == SYNC_MODE_SHARP ) { + if ( inL->zaurusId() >= 0 && mode != 4 ) { + local->deleteIncidence( inL ); + ++deletedEventL; + } else { + if ( ! KOPrefs::instance()->mWriteBackExistingOnly ) { + inL->setZaurusId( -1 ); + ++addedEventR; + inL->setLastModified( modifiedCalendar ); + remote->addIncidence( inL->clone() ); + } + } + } else { + if ( inL->lastModified() < mLastCalendarSync && mode != 4 ) { + checkSharpEvent(eventLSyncSharp, inL); + local->deleteIncidence( inL ); + ++deletedEventL; + } else { + if ( ! KOPrefs::instance()->mWriteBackExistingOnly ) { + ++addedEventR; + inL->setLastModified( modifiedCalendar ); + remote->addIncidence( inL->clone() ); + } + } + } + } + } + inL = el.next(); + } + + bar.hide(); + mLastCalendarSync = QDateTime::currentDateTime().addSecs( 1 ); + eventLSync->setReadOnly( false ); + eventLSync->setDtStart( mLastCalendarSync ); + eventRSync->setDtStart( mLastCalendarSync ); + eventLSync->setDtEnd( mLastCalendarSync.addSecs( 3600 ) ); + eventRSync->setDtEnd( mLastCalendarSync.addSecs( 3600 ) ); + eventRSync->setLocation( i18n("Remote from: ")+mCurrentSyncName ) ; + eventLSync->setLocation(i18n("Local from: ") + mCurrentSyncName ); + eventLSync->setReadOnly( true ); + if ( mGlobalSyncMode == SYNC_MODE_NORMAL) + remote->addEvent( eventRSync ); + QString mes; + mes .sprintf( i18n("Synchronization summary:\n\n %d items added to local\n %d items added to remote\n %d items updated on local\n %d items updated on remote\n %d items deleted on local\n %d items deleted on remote\n"),addedEvent, addedEventR, changedLocal, changedRemote, deletedEventL, deletedEventR ); + if ( KOPrefs::instance()->mShowSyncSummary ) { + KMessageBox::information(this, mes, i18n("KO/Pi Synchronization") ); + } + qDebug( mes ); + mCalendar->checkAlarmForIncidence( 0, true ); + return syncOK; +} + +void CalendarView::setSyncDevice( QString s ) +{ + mCurrentSyncDevice= s; +} +void CalendarView::setSyncName( QString s ) +{ + mCurrentSyncName= s; +} +bool CalendarView::syncCalendar(QString filename, int mode) +{ + mGlobalSyncMode = SYNC_MODE_NORMAL; + CalendarLocal* calendar = new CalendarLocal(); + calendar->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); + FileStorage* storage = new FileStorage( calendar ); + bool syncOK = false; + storage->setFileName( filename ); + // qDebug("loading ... "); + if ( storage->load(KOPrefs::instance()->mUseQuicksave) ) { + getEventViewerDialog()->setSyncMode( true ); + syncOK = synchronizeCalendar( mCalendar, calendar, mode ); + getEventViewerDialog()->setSyncMode( false ); + if ( syncOK ) { + if ( KOPrefs::instance()->mWriteBackFile ) + { + storage->setSaveFormat( new ICalFormat( KOPrefs::instance()->mUseQuicksave) ); + storage->save(); + } + } + setModified( true ); + } + delete storage; + delete calendar; + if ( syncOK ) + updateView(); + return syncOK; +} +void CalendarView::syncSharp() +{ +#ifndef DESKTOP_VERSION + mGlobalSyncMode = SYNC_MODE_SHARP; + //mCurrentSyncDevice = "sharp-DTM"; + if ( KOPrefs::instance()->mAskForPreferences ) + edit_sync_options(); + qApp->processEvents(); + CalendarLocal* calendar = new CalendarLocal(); + calendar->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); + bool syncOK = false; + SharpFormat sharpFormat; + if ( sharpFormat.load( calendar, mCalendar ) ) { + getEventViewerDialog()->setSyncMode( true ); + syncOK = synchronizeCalendar( mCalendar, calendar, KOPrefs::instance()->mSyncAlgoPrefs ); + getEventViewerDialog()->setSyncMode( false ); + qApp->processEvents(); + if ( syncOK ) { + if ( KOPrefs::instance()->mWriteBackFile ) + { + QPtrList<Incidence> iL = mCalendar->rawIncidences(); + Incidence* inc = iL.first(); + while ( inc ) { + inc->setZaurusStat( inc->revision () ); + inc = iL.next(); + } + // pending: clean last sync event description + sharpFormat.save(calendar); + iL = calendar->rawIncidences(); + inc = iL.first(); + Incidence* loc; + while ( inc ) { + if ( inc->zaurusStat() == -4 ) { + loc = mCalendar->incidence(inc->uid() ); + if ( loc ) { + loc->setZaurusId( inc->zaurusId() ); + loc->setZaurusUid( inc->zaurusUid() ); + } + } + inc = iL.next(); + } + Incidence* lse = getLastSyncEvent(); + if ( lse ) { + lse->setReadOnly( false ); + lse->setDescription( "" ); + lse->setReadOnly( true ); + } + } + } + setModified( true ); + } else { + QString question = i18n("Sorry, the database access\ncommand failed!\n\nNothing synced!\n") ; + QMessageBox::information( 0, i18n("KO/Pi Import - ERROR"), + question, i18n("Ok")) ; + + } + delete calendar; + updateView(); + return ;//syncOK; +#endif +} + + +#include <kabc/stdaddressbook.h> +bool CalendarView::importBday() +{ + KABC::StdAddressBook* AddressBook = KABC::StdAddressBook::self( true ); + KABC::AddressBook::Iterator it; + int count = 0; + for( it = AddressBook->begin(); it != AddressBook->end(); ++it ) { + ++count; + } + QProgressBar bar(count,0 ); + int w = 300; + if ( QApplication::desktop()->width() < 320 ) + w = 220; + int h = bar.sizeHint().height() ; + int dw = QApplication::desktop()->width(); + int dh = QApplication::desktop()->height(); + bar.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); + bar.show(); + bar.setCaption (i18n("Reading addressbook - close to abort!") ); + qApp->processEvents(); + count = 0; + int addCount = 0; + KCal::Attendee* a = 0; + for( it = AddressBook->begin(); it != AddressBook->end(); ++it ) { + if ( ! bar.isVisible() ) + return false; + bar.setProgress( count++ ); + qApp->processEvents(); + //qDebug("add BDay %s %s", (*it).realName().latin1(),(*it).birthday().date().toString().latin1() ); + if ( (*it).birthday().date().isValid() ){ + a = new KCal::Attendee( (*it).realName(), (*it).preferredEmail(),false,KCal::Attendee::NeedsAction,KCal::Attendee::ReqParticipant,(*it).uid()) ; + if ( addAnniversary( (*it).birthday().date(), (*it).assembledName(), a, true ) ) + ++addCount; + } + QDate anni = KGlobal::locale()->readDate( (*it).custom("KADDRESSBOOK", "X-Anniversary" ), "%Y-%m-%d"); + if ( anni.isValid() ){ + a = new KCal::Attendee( (*it).realName(), (*it).preferredEmail(),false,KCal::Attendee::NeedsAction,KCal::Attendee::ReqParticipant,(*it).uid()) ; + if ( addAnniversary( anni, (*it).assembledName(), a, false ) ) + ++addCount; + } + } + updateView(); + topLevelWidget()->setCaption(QString::number( addCount )+ i18n(" birthdays/anniversaries added!")); + return true; +} + +bool CalendarView::addAnniversary( QDate date, QString name, KCal::Attendee* a, bool birthday) +{ + //qDebug("addAnni "); + Event * ev = new Event(); + if ( a ) { + ev->addAttendee( a ); + } + QString kind; + if ( birthday ) + kind = i18n( "Birthday" ); + else + kind = i18n( "Anniversary" ); + ev->setSummary( name + " - " + kind ); + ev->setOrganizer( "nobody@nowhere" ); + ev->setCategories( kind ); + ev->setDtStart( QDateTime(date) ); + ev->setDtEnd( QDateTime(date) ); + ev->setFloats( true ); + Recurrence * rec = ev->recurrence(); + rec->setYearly(Recurrence::rYearlyMonth,1,-1); + rec->addYearlyNum( date.month() ); + if ( !mCalendar->addEventNoDup( ev ) ) { + delete ev; + return false; + } + return true; + +} +bool CalendarView::importQtopia( const QString &categories, + const QString &datebook, + const QString &todolist ) +{ + + QtopiaFormat qtopiaFormat; + qtopiaFormat.setCategoriesList ( &(KOPrefs::instance()->mCustomCategories)); + if ( !categories.isEmpty() ) qtopiaFormat.load( mCalendar, categories ); + if ( !datebook.isEmpty() ) qtopiaFormat.load( mCalendar, datebook ); + if ( !todolist.isEmpty() ) qtopiaFormat.load( mCalendar, todolist ); + + updateView(); + return true; + +#if 0 + mGlobalSyncMode = SYNC_MODE_QTOPIA; + mCurrentSyncDevice = "qtopia-XML"; + if ( KOPrefs::instance()->mAskForPreferences ) + edit_sync_options(); + qApp->processEvents(); + CalendarLocal* calendar = new CalendarLocal(); + calendar->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); + bool syncOK = false; + QtopiaFormat qtopiaFormat; + qtopiaFormat.setCategoriesList ( &(KOPrefs::instance()->mCustomCategories)); + bool loadOk = true; + if ( !categories.isEmpty() ) + loadOk = qtopiaFormat.load( calendar, categories ); + if ( loadOk && !datebook.isEmpty() ) + loadOk = qtopiaFormat.load( calendar, datebook ); + if ( loadOk && !todolist.isEmpty() ) + loadOk = qtopiaFormat.load( calendar, todolist ); + + if ( loadOk ) { + getEventViewerDialog()->setSyncMode( true ); + syncOK = synchronizeCalendar( mCalendar, calendar, KOPrefs::instance()->mSyncAlgoPrefs ); + getEventViewerDialog()->setSyncMode( false ); + qApp->processEvents(); + if ( syncOK ) { + if ( KOPrefs::instance()->mWriteBackFile ) + { + // write back XML file + + } + setModified( true ); + } + } else { + QString question = i18n("Sorry, the file loading\ncommand failed!\n\nNothing synced!\n") ; + QMessageBox::information( 0, i18n("KO/Pi Sync - ERROR"), + question, i18n("Ok")) ; + } + delete calendar; + updateView(); + return syncOK; + + +#endif + +} + +void CalendarView::setSyncEventsReadOnly() +{ + Event * ev; + QPtrList<Event> eL = mCalendar->rawEvents(); + ev = eL.first(); + while ( ev ) { + if ( ev->uid().left(21) == QString("last-syncEvent-device") ) + ev->setReadOnly( true ); + ev = eL.next(); + } +} +bool CalendarView::openCalendar(QString filename, bool merge) +{ + + if (filename.isEmpty()) { + return false; + } + + if (!QFile::exists(filename)) { + KMessageBox::error(this,i18n("File does not exist:\n '%1'.").arg(filename)); + return false; + } + + globalFlagBlockAgenda = 1; + if (!merge) mCalendar->close(); + + mStorage->setFileName( filename ); + + if ( mStorage->load(KOPrefs::instance()->mUseQuicksave) ) { + if ( merge ) ;//setModified( true ); + else { + //setModified( true ); + mViewManager->setDocumentId( filename ); + mDialogManager->setDocumentId( filename ); + mTodoList->setDocumentId( filename ); + } + globalFlagBlockAgenda = 2; + // if ( getLastSyncEvent() ) + // getLastSyncEvent()->setReadOnly( true ); + mCalendar->reInitAlarmSettings(); + setSyncEventsReadOnly(); + updateUnmanagedViews(); + updateView(); + if ( filename != MainWindow::defaultFileName() ) + saveCalendar( MainWindow::defaultFileName() ); + loadedFileVersion = QDateTime::currentDateTime(); + return true; + } else { + // while failing to load, the calendar object could + // have become partially populated. Clear it out. + if ( !merge ) mCalendar->close(); + + KMessageBox::error(this,i18n("Couldn't load calendar\n '%1'.").arg(filename)); + + globalFlagBlockAgenda = 2; + updateView(); + } + return false; +} +void CalendarView::setLoadedFileVersion(QDateTime dt) +{ + loadedFileVersion = dt; +} +bool CalendarView::checkFileChanged(QString fn) +{ + QFileInfo finf ( fn ); + if ( !finf.exists() ) + return true; + QDateTime dt = finf.lastModified (); + if ( dt <= loadedFileVersion ) + return false; + return true; + +} +bool CalendarView::checkFileVersion(QString fn) +{ + QFileInfo finf ( fn ); + if ( !finf.exists() ) + return true; + QDateTime dt = finf.lastModified (); + //qDebug("loaded file version %s",loadedFileVersion.toString().latin1()); + //qDebug("file on disk version %s",dt.toString().latin1()); + if ( dt <= loadedFileVersion ) + return true; + int km = KMessageBox::warningYesNoCancel(this, i18n("\nThe file on disk has changed!\nFile size: %1 bytes.\nLast modified: %2\nDo you want to:\n\n - Save and overwrite file?\n - Sync with file, then save?\n - Cancel without saving? \n").arg( QString::number( finf.size())).arg( KGlobal::locale()->formatDateTime(finf.lastModified (), true, false)) , + i18n("KO/Pi Warning"),i18n("Overwrite"), + i18n("Sync+save")); + + if ( km == KMessageBox::Cancel ) + return false; + if ( km == KMessageBox::Yes ) + return true; + + setSyncDevice("deleteaftersync" ); + KOPrefs::instance()->mAskForPreferences = true; + KOPrefs::instance()->mSyncAlgoPrefs = 3; + KOPrefs::instance()->mWriteBackFile = false; + KOPrefs::instance()->mWriteBackExistingOnly = false; + KOPrefs::instance()->mShowSyncSummary = false; + syncCalendar( fn, 3 ); + Event * e = getLastSyncEvent(); + mCalendar->deleteEvent ( e ); + updateView(); + return true; +} + +bool CalendarView::saveCalendar( QString filename ) +{ + + // Store back all unsaved data into calendar object + // qDebug("file %s %d ", filename.latin1() , mViewManager->currentView() ); + if ( mViewManager->currentView() ) + mViewManager->currentView()->flushView(); + + //mStorage->setFileName( filename ); + + mStorage->setSaveFormat( new ICalFormat( KOPrefs::instance()->mUseQuicksave) ); + mStorage->setFileName( filename ); + bool success; + success = mStorage->save(); + if ( !success ) { + return false; + } + + return true; +} + +void CalendarView::closeCalendar() +{ + + // child windows no longer valid + emit closingDown(); + + mCalendar->close(); + setModified(false); + updateView(); +} + +void CalendarView::archiveCalendar() +{ + mDialogManager->showArchiveDialog(); +} + + +void CalendarView::readSettings() +{ + + + // mViewManager->showAgendaView(); + QString str; + //qDebug("CalendarView::readSettings() "); + // read settings from the KConfig, supplying reasonable + // defaults where none are to be found + KConfig *config = KOGlobals::config(); +#ifndef KORG_NOSPLITTER + config->setGroup("KOrganizer Geometry"); + + QValueList<int> sizes = config->readIntListEntry("Separator1"); + if (sizes.count() != 2) { + sizes << mDateNavigator->minimumSizeHint().width(); + sizes << 300; + } + mPanner->setSizes(sizes); + + sizes = config->readIntListEntry("Separator2"); + if ( ( mResourceView && sizes.count() == 4 ) || + ( !mResourceView && sizes.count() == 3 ) ) { + mLeftSplitter->setSizes(sizes); + } +#endif + globalFlagBlockAgenda = 1; + mViewManager->showAgendaView(); + //mViewManager->readSettings( config ); + mTodoList->restoreLayout(config,QString("Todo Layout")); + readFilterSettings(config); + config->setGroup( "Views" ); + int dateCount = config->readNumEntry( "ShownDatesCount", 7 ); + if ( dateCount == 5 ) mNavigator->selectWorkWeek(); + else if ( dateCount == 7 ) mNavigator->selectWeek(); + else mNavigator->selectDates( dateCount ); + // mViewManager->readSettings( config ); + updateConfig(); + globalFlagBlockAgenda = 2; + mViewManager->readSettings( config ); +#ifdef DESKTOP_VERSION + config->setGroup("WidgetLayout"); + QStringList list; + list = config->readListEntry("MainLayout"); + int x,y,w,h; + if ( ! list.isEmpty() ) { + x = list[0].toInt(); + y = list[1].toInt(); + w = list[2].toInt(); + h = list[3].toInt(); + topLevelWidget()->setGeometry(x,y,w,h); + + } else { + topLevelWidget()->setGeometry( 40 ,40 , 640, 440); + } + list = config->readListEntry("EditEventLayout"); + if ( ! list.isEmpty() ) { + x = list[0].toInt(); + y = list[1].toInt(); + w = list[2].toInt(); + h = list[3].toInt(); + mEventEditor->setGeometry(x,y,w,h); + + } + list = config->readListEntry("EditTodoLayout"); + if ( ! list.isEmpty() ) { + x = list[0].toInt(); + y = list[1].toInt(); + w = list[2].toInt(); + h = list[3].toInt(); + mTodoEditor->setGeometry(x,y,w,h); + + } + list = config->readListEntry("ViewerLayout"); + if ( ! list.isEmpty() ) { + x = list[0].toInt(); + y = list[1].toInt(); + w = list[2].toInt(); + h = list[3].toInt(); + getEventViewerDialog()->setGeometry(x,y,w,h); + } +#endif + + + // pending read sync settings; + mSyncProfileNames.clear(); + mSyncProfileNames << "Profile_1"; + mSyncProfileNames << "Profile_2"; + mSyncProfileNames << "Profile_3"; + mSyncProfileNames << "Profile_4"; + mSyncProfileNames << "Profile_5"; + KSyncProfile* temp = new KSyncProfile (); + temp->setName("Profile_1" ); + mSyncProfiles.append( temp ); + temp = new KSyncProfile (); + temp->setName("Profile_2" ); + mSyncProfiles.append( temp ); + temp = new KSyncProfile (); + temp->setName("Profile_3" ); + mSyncProfiles.append( temp ); + temp = new KSyncProfile (); + temp->setName("Profile_4" ); + mSyncProfiles.append( temp ); + temp = new KSyncProfile (); + temp->setName("Profile_5" ); + mSyncProfiles.append( temp ); +} + + +void CalendarView::writeSettings() +{ + // kdDebug() << "CalendarView::writeSettings" << endl; + + KConfig *config = KOGlobals::config(); + +#ifndef KORG_NOSPLITTER + config->setGroup("KOrganizer Geometry"); + + QValueList<int> list = mPanner->sizes(); + config->writeEntry("Separator1",list); + + list = mLeftSplitter->sizes(); + config->writeEntry("Separator2",list); +#endif + + mViewManager->writeSettings( config ); + mTodoList->saveLayout(config,QString("Todo Layout")); + mDialogManager->writeSettings( config ); + //KOPrefs::instance()->usrWriteConfig(); + KOPrefs::instance()->writeConfig(); + + writeFilterSettings(config); + + config->setGroup( "Views" ); + config->writeEntry( "ShownDatesCount", mNavigator->selectedDates().count() ); + +#ifdef DESKTOP_VERSION + config->setGroup("WidgetLayout"); + QStringList list ;//= config->readListEntry("MainLayout"); + int x,y,w,h; + QWidget* wid; + wid = topLevelWidget(); + x = wid->geometry().x(); + y = wid->geometry().y(); + w = wid->width(); + h = wid->height(); + list.clear(); + list << QString::number( x ); + list << QString::number( y ); + list << QString::number( w ); + list << QString::number( h ); + config->writeEntry("MainLayout",list ); + + wid = mEventEditor; + x = wid->geometry().x(); + y = wid->geometry().y(); + w = wid->width(); + h = wid->height(); + list.clear(); + list << QString::number( x ); + list << QString::number( y ); + list << QString::number( w ); + list << QString::number( h ); + config->writeEntry("EditEventLayout",list ); + + wid = mTodoEditor; + x = wid->geometry().x(); + y = wid->geometry().y(); + w = wid->width(); + h = wid->height(); + list.clear(); + list << QString::number( x ); + list << QString::number( y ); + list << QString::number( w ); + list << QString::number( h ); + config->writeEntry("EditTodoLayout",list ); + wid = getEventViewerDialog(); + x = wid->geometry().x(); + y = wid->geometry().y(); + w = wid->width(); + h = wid->height(); + list.clear(); + list << QString::number( x ); + list << QString::number( y ); + list << QString::number( w ); + list << QString::number( h ); + config->writeEntry("ViewerLayout",list ); + wid = mDialogManager->getSearchDialog(); + if ( wid ) { + x = wid->geometry().x(); + y = wid->geometry().y(); + w = wid->width(); + h = wid->height(); + list.clear(); + list << QString::number( x ); + list << QString::number( y ); + list << QString::number( w ); + list << QString::number( h ); + config->writeEntry("SearchLayout",list ); + } +#endif + + + config->sync(); +} + +void CalendarView::readFilterSettings(KConfig *config) +{ + // kdDebug() << "CalendarView::readFilterSettings()" << endl; + + mFilters.clear(); + + config->setGroup("General"); + QStringList filterList = config->readListEntry("CalendarFilters"); + + QStringList::ConstIterator it = filterList.begin(); + QStringList::ConstIterator end = filterList.end(); + while(it != end) { + // kdDebug() << " filter: " << (*it) << endl; + + CalFilter *filter; + filter = new CalFilter(*it); + config->setGroup("Filter_" + (*it)); + //qDebug("readFilterSettings %d ",config->readNumEntry("Criteria",0) ); + filter->setCriteria(config->readNumEntry("Criteria",0)); + filter->setCategoryList(config->readListEntry("CategoryList")); + mFilters.append(filter); + + ++it; + } + + if (mFilters.count() == 0) { + CalFilter *filter = new CalFilter(i18n("Default")); + mFilters.append(filter); + } + mFilterView->updateFilters(); + config->setGroup("FilterView"); + + mFilterView->blockSignals(true); + mFilterView->setFiltersEnabled(config->readBoolEntry("FilterEnabled")); + mFilterView->setSelectedFilter(config->readEntry("Current Filter")); + mFilterView->blockSignals(false); + // We do it manually to avoid it being done twice by the above calls + updateFilter(); +} + +void CalendarView::writeFilterSettings(KConfig *config) +{ + // kdDebug() << "CalendarView::writeFilterSettings()" << endl; + + QStringList filterList; + + CalFilter *filter = mFilters.first(); + while(filter) { + // kdDebug() << " fn: " << filter->name() << endl; + filterList << filter->name(); + config->setGroup("Filter_" + filter->name()); + config->writeEntry("Criteria",filter->criteria()); + config->writeEntry("CategoryList",filter->categoryList()); + filter = mFilters.next(); + } + config->setGroup("General"); + config->writeEntry("CalendarFilters",filterList); + + config->setGroup("FilterView"); + config->writeEntry("FilterEnabled",mFilterView->filtersEnabled()); + config->writeEntry("Current Filter",mFilterView->selectedFilter()->name()); +} + + +void CalendarView::goToday() +{ + mNavigator->selectToday(); +} + +void CalendarView::goNext() +{ + mNavigator->selectNext(); +} + +void CalendarView::goPrevious() +{ + mNavigator->selectPrevious(); +} +void CalendarView::goNextMonth() +{ + mNavigator->selectNextMonth(); +} + +void CalendarView::goPreviousMonth() +{ + mNavigator->selectPreviousMonth(); +} +void CalendarView::writeLocale() +{ + KGlobal::locale()->setHore24Format( !KOPrefs::instance()->mPreferredTime ); + KGlobal::locale()->setWeekStartMonday( !KOPrefs::instance()->mWeekStartsOnSunday ); + KGlobal::locale()->setIntDateFormat( KOPrefs::instance()->mPreferredDate ); + KGlobal::locale()->setLanguage( KOPrefs::instance()->mPreferredLanguage ); + QString dummy = KOPrefs::instance()->mUserDateFormatLong; + KGlobal::locale()->setDateFormat(dummy.replace( QRegExp("K"), QString(",") )); + dummy = KOPrefs::instance()->mUserDateFormatShort; + KGlobal::locale()->setDateFormatShort(dummy.replace( QRegExp("K"), QString(",") )); + KGlobal::locale()->setDaylightSaving( KOPrefs::instance()->mUseDaylightsaving, + KOPrefs::instance()->mDaylightsavingStart, + KOPrefs::instance()->mDaylightsavingEnd ); + KGlobal::locale()->setTimezone( KOPrefs::instance()->mTimeZoneId ); +} +void CalendarView::updateConfig() +{ + writeLocale(); + if ( KOPrefs::instance()->mUseAppColors ) + QApplication::setPalette( QPalette (KOPrefs::instance()->mAppColor1, KOPrefs::instance()->mAppColor2), true ); + emit configChanged(); + mTodoList->updateConfig(); + // mDateNavigator->setFont ( KOPrefs::instance()->mDateNavigatorFont); + mCalendar->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); + // To make the "fill window" configurations work + //mViewManager->raiseCurrentView(); +} + + +void CalendarView::eventChanged(Event *event) +{ + changeEventDisplay(event,KOGlobals::EVENTEDITED); + //updateUnmanagedViews(); +} + +void CalendarView::eventAdded(Event *event) +{ + changeEventDisplay(event,KOGlobals::EVENTADDED); +} + +void CalendarView::eventToBeDeleted(Event *) +{ + kdDebug() << "CalendarView::eventToBeDeleted(): to be implemented" << endl; +} + +void CalendarView::eventDeleted() +{ + changeEventDisplay(0,KOGlobals::EVENTDELETED); +} +void CalendarView::changeTodoDisplay(Todo *which, int action) +{ + changeIncidenceDisplay((Incidence *)which, action); +} +void CalendarView::checkZaurusId( int id, bool todo ) +{ + if ( id >= 0 ) { + Incidence* lse = mCalendar->event( "last-syncEvent-device-Sharp-DTM"); + if ( lse ) { + QString des = lse->description(); + QString pref = "e"; + if ( todo ) + pref = "t"; + des += pref+ QString::number ( id ) + ","; + lse->setReadOnly( false ); + lse->setDescription( des ); + lse->setReadOnly( true ); + } + } +} +void CalendarView::changeIncidenceDisplay(Incidence *which, int action) +{ + updateUnmanagedViews(); + //qDebug(" CalendarView::changeIncidenceDisplay++++++++++++++++++++++++++ %d %d ",which, action ); + if ( action == KOGlobals::EVENTDELETED ) { //delete + mCalendar->checkAlarmForIncidence( 0, true ); + if ( mEventViewerDialog ) + mEventViewerDialog->hide(); + } + else + mCalendar->checkAlarmForIncidence( which , false ); +} + +// most of the changeEventDisplays() right now just call the view's +// total update mode, but they SHOULD be recoded to be more refresh-efficient. +void CalendarView::changeEventDisplay(Event *which, int action) +{ + // kdDebug() << "CalendarView::changeEventDisplay" << endl; + changeIncidenceDisplay((Incidence *)which, action); + mDateNavigator->updateView(); + //mDialogManager->updateSearchDialog(); + + if (which) { + // If there is an event view visible update the display + mViewManager->currentView()->changeEventDisplay(which,action); + // TODO: check, if update needed + // if (which->getTodoStatus()) { + mTodoList->updateView(); + // } + } else { + mViewManager->currentView()->updateView(); + } +} + + +void CalendarView::updateTodoViews() +{ + + mTodoList->updateView(); + mViewManager->currentView()->updateView(); + +} + + +void CalendarView::updateView(const QDate &start, const QDate &end) +{ + mTodoList->updateView(); + mViewManager->updateView(start, end); + //mDateNavigator->updateView(); +} + +void CalendarView::updateView() +{ + DateList tmpList = mNavigator->selectedDates(); + + // We assume that the navigator only selects consecutive days. + updateView( tmpList.first(), tmpList.last() ); +} + +void CalendarView::updateUnmanagedViews() +{ + mDateNavigator->updateDayMatrix(); +} + +int CalendarView::msgItemDelete() +{ + return KMessageBox::warningContinueCancel(this, + i18n("This item will be\npermanently deleted."), + i18n("KO/Pi Confirmation"),i18n("Delete")); +} + + +void CalendarView::edit_cut() +{ + Event *anEvent=0; + + Incidence *incidence = mViewManager->currentView()->selectedIncidences().first(); + + if (mViewManager->currentView()->isEventView()) { + if ( incidence && incidence->type() == "Event" ) { + anEvent = static_cast<Event *>(incidence); + } + } + + if (!anEvent) { + KNotifyClient::beep(); + return; + } + DndFactory factory( mCalendar ); + factory.cutEvent(anEvent); + changeEventDisplay(anEvent, KOGlobals::EVENTDELETED); +} + +void CalendarView::edit_copy() +{ + Event *anEvent=0; + + Incidence *incidence = mViewManager->currentView()->selectedIncidences().first(); + + if (mViewManager->currentView()->isEventView()) { + if ( incidence && incidence->type() == "Event" ) { + anEvent = static_cast<Event *>(incidence); + } + } + + if (!anEvent) { + KNotifyClient::beep(); + return; + } + DndFactory factory( mCalendar ); + factory.copyEvent(anEvent); +} + +void CalendarView::edit_paste() +{ + QDate date = mNavigator->selectedDates().first(); + + DndFactory factory( mCalendar ); + Event *pastedEvent = factory.pasteEvent( date ); + + changeEventDisplay( pastedEvent, KOGlobals::EVENTADDED ); +} + +void CalendarView::edit_options() +{ + mDialogManager->showOptionsDialog(); + //writeSettings(); +} +void CalendarView::edit_sync_options() +{ + //mDialogManager->showSyncOptions(); + //KOPrefs::instance()->mSyncAlgoPrefs + QDialog dia( this, "dia", true ); + dia.setCaption( i18n("Device: " ) +mCurrentSyncDevice ); + QButtonGroup gr ( 1, Qt::Horizontal, i18n("Sync preferences"), &dia); + QVBoxLayout lay ( &dia ); + lay.setSpacing( 2 ); + lay.setMargin( 3 ); + lay.addWidget(&gr); + QRadioButton loc ( i18n("Take local entry on conflict"), &gr ); + QRadioButton rem ( i18n("Take remote entry on conflict"), &gr ); + QRadioButton newest( i18n("Take newest entry on conflict"), &gr ); + QRadioButton ask( i18n("Ask for every entry on conflict"), &gr ); + QRadioButton f_loc( i18n("Force: Take local entry always"), &gr ); + QRadioButton f_rem( i18n("Force: Take remote entry always"), &gr ); + //QRadioButton both( i18n("Take both on conflict"), &gr ); + QPushButton pb ( "OK", &dia); + lay.addWidget( &pb ); + connect(&pb, SIGNAL( clicked() ), &dia, SLOT ( accept() ) ); + switch ( KOPrefs::instance()->mSyncAlgoPrefs ) { + case 0: + loc.setChecked( true); + break; + case 1: + rem.setChecked( true ); + break; + case 2: + newest.setChecked( true); + break; + case 3: + ask.setChecked( true); + break; + case 4: + f_loc.setChecked( true); + break; + case 5: + f_rem.setChecked( true); + break; + case 6: + // both.setChecked( true); + break; + default: + break; + } + if ( dia.exec() ) { + KOPrefs::instance()->mSyncAlgoPrefs = rem.isChecked()*1+newest.isChecked()*2+ ask.isChecked()*3+ f_loc.isChecked()*4+ f_rem.isChecked()*5;//+ both.isChecked()*6 ; + } + +} + +void CalendarView::slotSelectPickerDate( QDate d) +{ + mDateFrame->hide(); + if ( mDatePickerMode == 1 ) { + mNavigator->slotDaySelect( d ); + } else if ( mDatePickerMode == 2 ) { + if ( mMoveIncidence->type() == "Todo" ) { + Todo * to = (Todo *) mMoveIncidence; + QTime tim; + if ( to->hasDueDate() ) + tim = to->dtDue().time(); + else { + tim = QTime ( 0,0,0 ); + to->setFloats( true ); + to->setHasDueDate( true ); + } + QDateTime dt ( d,tim ); + to->setDtDue( dt ); + todoChanged( to ); + } else { + QTime tim = mMoveIncidence->dtStart().time(); + int secs = mMoveIncidence->dtStart().secsTo( mMoveIncidence->dtEnd()); + QDateTime dt ( d,tim ); + mMoveIncidence->setDtStart( dt ); + ((Event*)mMoveIncidence)->setDtEnd( dt.addSecs( secs ) ); + changeEventDisplay((Event*)mMoveIncidence, KOGlobals::EVENTEDITED); + } + + mMoveIncidence->setRevision( mMoveIncidence->revision()+1 ); + } +} + +void CalendarView::removeCategories() +{ + QPtrList<Incidence> incList = mCalendar->rawIncidences(); + QStringList catList = KOPrefs::instance()->mCustomCategories; + QStringList catIncList; + QStringList newCatList; + Incidence* inc = incList.first(); + int i; + int count = 0; + while ( inc ) { + newCatList.clear(); + catIncList = QStringList::split (",", inc->categoriesStr() ); + for( i = 0; i< catIncList.count(); ++i ) { + if ( catList.contains (catIncList[i])) + newCatList.append( catIncList[i] ); + } + newCatList.sort(); + inc->setCategories( newCatList.join(",") ); + inc = incList.next(); + } +} + +int CalendarView::addCategories() +{ + QPtrList<Incidence> incList = mCalendar->rawIncidences(); + QStringList catList = KOPrefs::instance()->mCustomCategories; + QStringList catIncList; + Incidence* inc = incList.first(); + int i; + int count = 0; + while ( inc ) { + catIncList = QStringList::split (",", inc->categoriesStr() ); + for( i = 0; i< catIncList.count(); ++i ) { + if ( !catList.contains (catIncList[i])) { + catList.append( catIncList[i] ); + //qDebug("add cat %s ", catIncList[i].latin1()); + ++count; + } + } + inc = incList.next(); + } + catList.sort(); + KOPrefs::instance()->mCustomCategories = catList; + return count; +} + +void CalendarView::manageCategories() +{ + KOCatPrefs* cp = new KOCatPrefs(); + cp->show(); + int w =cp->sizeHint().width() ; + int h = cp->sizeHint().height() ; + int dw = QApplication::desktop()->width(); + int dh = QApplication::desktop()->height(); + cp->setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); + if ( !cp->exec() ) { + delete cp; + return; + } + int count = 0; + if ( cp->addCat() ) { + count = addCategories(); + if ( count ) { + topLevelWidget()->setCaption(QString::number( count )+ i18n(" Categories added to list! ")); + writeSettings(); + } + } else { + removeCategories(); + updateView(); + } + delete cp; +} + +void CalendarView::beamIncidence(Incidence * Inc) +{ + QPtrList<Incidence> delSel ; + delSel.append(Inc); + beamIncidenceList( delSel ); +} +void CalendarView::beamCalendar() +{ + QPtrList<Incidence> delSel = mCalendar->rawIncidences(); + //qDebug("beamCalendar() "); + beamIncidenceList( delSel ); +} +void CalendarView::beamFilteredCalendar() +{ + QPtrList<Incidence> delSel = mCalendar->incidences(); + //qDebug("beamFilteredCalendar() "); + beamIncidenceList( delSel ); +} +void CalendarView::beamIncidenceList(QPtrList<Incidence> delSel ) +{ + if ( beamDialog->exec () == QDialog::Rejected ) + return; + + QString fn = "/tmp/kopibeamfile"; + QString mes; + bool createbup = true; + if ( createbup ) { + QString description = "\n"; + CalendarLocal* cal = new CalendarLocal(); + if ( beamDialog->beamLocal() ) + cal->setLocalTime(); + else + cal->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); + Incidence *incidence = delSel.first(); + bool addText = false; + if ( delSel.count() < 10 ) + addText = true; + else { + description.sprintf(i18n(" %d items?"),delSel.count() ); + } + while ( incidence ) { + Incidence *in = incidence->clone(); + if ( addText ) + description += in->summary() + "\n"; + cal->addIncidence( in ); + incidence = delSel.next(); + } + if ( beamDialog->beamVcal() ) { + fn += ".vcs"; + FileStorage storage( cal, fn, new VCalFormat ); + storage.save(); + } else { + fn += ".ics"; + FileStorage storage( cal, fn, new ICalFormat( KOPrefs::instance()->mUseQuicksave) ); + storage.save(); + } + delete cal; + mes = i18n("KO/Pi: Ready for beaming"); + setCaption(mes); + +#ifndef DESKTOP_VERSION + Ir *ir = new Ir( this ); + connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) ); + ir->send( fn, description, "text/x-vCalendar" ); +#endif + } +} +void CalendarView::beamDone( Ir *ir ) +{ +#ifndef DESKTOP_VERSION + delete ir; +#endif +} + +void CalendarView::moveIncidence(Incidence * inc ) +{ + if ( !inc ) return; + // qDebug("showDatePickerForIncidence( ) "); + if ( mDateFrame->isVisible() ) + mDateFrame->hide(); + else { + int w =mDatePicker->sizeHint().width()+2*mDateFrame->lineWidth() ; + int h = mDatePicker->sizeHint().height()+2*mDateFrame->lineWidth() ; + int dw = QApplication::desktop()->width(); + int dh = QApplication::desktop()->height(); + mDateFrame->setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); + mDateFrame->show(); + } + mDatePickerMode = 2; + mMoveIncidence = inc ; + QDate da; + if ( mMoveIncidence->type() == "Todo" ) { + Todo * to = (Todo *) mMoveIncidence; + if ( to->hasDueDate() ) + da = to->dtDue().date(); + else + da = QDate::currentDate(); + } else { + da = mMoveIncidence->dtStart().date(); + } + mDatePicker->setDate( da ); +} +void CalendarView::showDatePicker( ) +{ + //qDebug("CalendarView::showDatePicker( ) "); + if ( mDateFrame->isVisible() ) + mDateFrame->hide(); + else { + int w =mDatePicker->sizeHint().width() ; + int h = mDatePicker->sizeHint().height() ; + int dw = QApplication::desktop()->width(); + int dh = QApplication::desktop()->height(); + mDateFrame->setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); + mDateFrame->show(); + } + mDatePickerMode = 1; + mDatePicker->setDate( mNavigator->selectedDates().first() ); +} + +void CalendarView::showEventEditor() +{ +#ifdef DESKTOP_VERSION + mEventEditor->show(); +#else + mEventEditor->showMaximized(); +#endif +} +void CalendarView::showTodoEditor() +{ +#ifdef DESKTOP_VERSION + mTodoEditor->show(); +#else + mTodoEditor->showMaximized(); +#endif +} +void CalendarView::cancelIncidence(Incidence * inc ) +{ + inc->setCancelled( ! inc->cancelled() ); + changeIncidenceDisplay( inc,KOGlobals::EVENTEDITED ); + updateView(); +} +void CalendarView::cloneIncidence(Incidence * orgInc ) +{ + Incidence * newInc = orgInc->clone(); + newInc->recreate(); + + if ( newInc->type() == "Todo" ) { + Todo* t = (Todo*) newInc; + mTodoEditor->editTodo( t ); + showTodoEditor(); + if ( mTodoEditor->exec() ) { + mCalendar->addTodo( t ); + updateView(); + } else { + delete t; + } + } + else { + Event* e = (Event*) newInc; + mEventEditor->editEvent( e ); + showEventEditor(); + if ( mEventEditor->exec() ) { + mCalendar->addEvent( e ); + updateView(); + } else { + delete e; + } + } +} + +void CalendarView::newEvent() +{ + // TODO: Replace this code by a common eventDurationHint of KOBaseView. + KOAgendaView *aView = mViewManager->agendaView(); + if (aView) { + if (aView->selectionStart().isValid()) { + if (aView->selectedIsAllDay()) { + newEvent(aView->selectionStart(),aView->selectionEnd(),true); + } else { + newEvent(aView->selectionStart(),aView->selectionEnd()); + } + return; + } + } + + QDate date = mNavigator->selectedDates().first(); + QDateTime current = QDateTime::currentDateTime(); + if ( date <= current.date() ) { + int hour = current.time().hour() +1; + newEvent( QDateTime( current.date(), QTime( hour, 0, 0 ) ), + QDateTime( current.date(), QTime( hour+ KOPrefs::instance()->mDefaultDuration, 0, 0 ) ) ); + } else + newEvent( QDateTime( date, QTime( KOPrefs::instance()->mStartTime, 0, 0 ) ), + QDateTime( date, QTime( KOPrefs::instance()->mStartTime + + KOPrefs::instance()->mDefaultDuration, 0, 0 ) ) ); +} + +void CalendarView::newEvent(QDateTime fh) +{ + newEvent(fh, + QDateTime(fh.addSecs(3600*KOPrefs::instance()->mDefaultDuration))); +} + +void CalendarView::newEvent(QDate dt) +{ + newEvent(QDateTime(dt, QTime(0,0,0)), + QDateTime(dt, QTime(0,0,0)), true); +} + +void CalendarView::newEvent(QDateTime fromHint, QDateTime toHint, bool allDay) +{ + + mEventEditor->newEvent(fromHint,toHint,allDay); + if ( mFilterView->filtersEnabled() ) { + CalFilter *filter = mFilterView->selectedFilter(); + if (filter && filter->showCategories()) { + mEventEditor->setCategories(filter->categoryList().join(",") ); + } + if ( filter ) + mEventEditor->setSecrecy( filter->getSecrecy() ); + } + showEventEditor(); +} +void CalendarView::todoAdded(Todo * t) +{ + + changeTodoDisplay ( t ,KOGlobals::EVENTADDED); + updateTodoViews(); +} +void CalendarView::todoChanged(Todo * t) +{ + emit todoModified( t, 4 ); + // updateTodoViews(); +} +void CalendarView::todoToBeDeleted(Todo *) +{ + //qDebug("todoToBeDeleted(Todo *) "); + updateTodoViews(); +} +void CalendarView::todoDeleted() +{ + //qDebug(" todoDeleted()"); + updateTodoViews(); +} + + + +void CalendarView::newTodo() +{ + + mTodoEditor->newTodo(QDateTime::currentDateTime().addDays(7),0,true); + if ( mFilterView->filtersEnabled() ) { + CalFilter *filter = mFilterView->selectedFilter(); + if (filter && filter->showCategories()) { + mTodoEditor->setCategories(filter->categoryList().join(",") ); + } + if ( filter ) + mTodoEditor->setSecrecy( filter->getSecrecy() ); + } + showTodoEditor(); +} + +void CalendarView::newSubTodo() +{ + Todo *todo = selectedTodo(); + if ( todo ) newSubTodo( todo ); +} + +void CalendarView::newSubTodo(Todo *parentEvent) +{ + + mTodoEditor->newTodo(QDateTime::currentDateTime().addDays(7),parentEvent,true); + showTodoEditor(); +} + +void CalendarView::newFloatingEvent() +{ + DateList tmpList = mNavigator->selectedDates(); + QDate date = tmpList.first(); + + newEvent( QDateTime( date, QTime( 12, 0, 0 ) ), + QDateTime( date, QTime( 12, 0, 0 ) ), true ); +} + + +void CalendarView::editEvent( Event *event ) +{ + + if ( !event ) return; + if ( event->isReadOnly() ) { + showEvent( event ); + return; + } + mEventEditor->editEvent( event , mFlagEditDescription); + showEventEditor(); +} +void CalendarView::editJournal( Journal *jour ) +{ + if ( !jour ) return; + mDialogManager->hideSearchDialog(); + mViewManager->showJournalView(); + mNavigator->slotDaySelect( jour->dtStart().date() ); +} +void CalendarView::editTodo( Todo *todo ) +{ + if ( !todo ) return; + + if ( todo->isReadOnly() ) { + showTodo( todo ); + return; + } + mTodoEditor->editTodo( todo ,mFlagEditDescription); + showTodoEditor(); + +} + +KOEventViewerDialog* CalendarView::getEventViewerDialog() +{ + if ( !mEventViewerDialog ) { + mEventViewerDialog = new KOEventViewerDialog(this); + connect( mEventViewerDialog, SIGNAL( editIncidence( Incidence* )), this, SLOT(editIncidence( Incidence* ) ) ); + connect( this, SIGNAL(configChanged()), mEventViewerDialog, SLOT(updateConfig())); + connect( mEventViewerDialog, SIGNAL(jumpToTime( const QDate &)), + dateNavigator(), SLOT( selectWeek( const QDate & ) ) ); + connect( mEventViewerDialog, SIGNAL(showAgendaView( bool ) ), + viewManager(), SLOT( showAgendaView( bool ) ) ); + mEventViewerDialog->resize( 640, 480 ); + + } + return mEventViewerDialog; +} +void CalendarView::showEvent(Event *event) +{ + getEventViewerDialog()->setEvent(event); + getEventViewerDialog()->showMe(); +} + +void CalendarView::showTodo(Todo *event) +{ + getEventViewerDialog()->setTodo(event); + getEventViewerDialog()->showMe(); +} +void CalendarView::showJournal( Journal *jour ) +{ + getEventViewerDialog()->setJournal(jour); + getEventViewerDialog()->showMe(); + +} +// void CalendarView::todoModified (Todo *event, int changed) +// { +// // if (mDialogList.find (event) != mDialogList.end ()) { +// // kdDebug() << "Todo modified and open" << endl; +// // KOTodoEditor* temp = (KOTodoEditor *) mDialogList[event]; +// // temp->modified (changed); + +// // } + +// mViewManager->updateView(); +// } + +void CalendarView::appointment_show() +{ + Event *anEvent = 0; + + Incidence *incidence = mViewManager->currentView()->selectedIncidences().first(); + + if (mViewManager->currentView()->isEventView()) { + if ( incidence && incidence->type() == "Event" ) { + anEvent = static_cast<Event *>(incidence); + } + } + + if (!anEvent) { + KNotifyClient::beep(); + return; + } + + showEvent(anEvent); +} + +void CalendarView::appointment_edit() +{ + Event *anEvent = 0; + + Incidence *incidence = mViewManager->currentView()->selectedIncidences().first(); + + if (mViewManager->currentView()->isEventView()) { + if ( incidence && incidence->type() == "Event" ) { + anEvent = static_cast<Event *>(incidence); + } + } + + if (!anEvent) { + KNotifyClient::beep(); + return; + } + + editEvent(anEvent); +} + +void CalendarView::appointment_delete() +{ + Event *anEvent = 0; + + Incidence *incidence = mViewManager->currentView()->selectedIncidences().first(); + + if (mViewManager->currentView()->isEventView()) { + if ( incidence && incidence->type() == "Event" ) { + anEvent = static_cast<Event *>(incidence); + } + } + + if (!anEvent) { + KNotifyClient::beep(); + return; + } + + deleteEvent(anEvent); +} + +void CalendarView::todo_unsub(Todo *anTodo ) +{ + // Todo *anTodo = selectedTodo(); + if (!anTodo) return; + if (!anTodo->relatedTo()) return; + anTodo->relatedTo()->removeRelation(anTodo); + anTodo->setRelatedTo(0); + anTodo->updated(); + anTodo->setRelatedToUid(""); + setModified(true); + updateView(); +} + +void CalendarView::deleteTodo(Todo *todo) +{ + if (!todo) { + KNotifyClient::beep(); + return; + } + if (KOPrefs::instance()->mConfirm) { + switch (msgItemDelete()) { + case KMessageBox::Continue: // OK + if (!todo->relations().isEmpty()) { + KMessageBox::sorry(this,i18n("Cannot delete To-Do\nwhich has children."), + i18n("Delete To-Do")); + } else { + checkZaurusId( todo->zaurusId(), true ); + calendar()->deleteTodo(todo); + changeTodoDisplay( todo,KOGlobals::EVENTDELETED ); + updateView(); + } + break; + } // switch + } else { + if (!todo->relations().isEmpty()) { + KMessageBox::sorry(this,i18n("Cannot delete To-Do\nwhich has children."), + i18n("Delete To-Do")); + } else { + checkZaurusId( todo->zaurusId(), true ); + mCalendar->deleteTodo(todo); + changeTodoDisplay( todo,KOGlobals::EVENTDELETED ); + updateView(); + } + } + emit updateSearchDialog(); +} +void CalendarView::deleteJournal(Journal *jour) +{ + if (!jour) { + KNotifyClient::beep(); + return; + } + if (KOPrefs::instance()->mConfirm) { + switch (msgItemDelete()) { + case KMessageBox::Continue: // OK + calendar()->deleteJournal(jour); + updateView(); + break; + } // switch + } else { + calendar()->deleteJournal(jour);; + updateView(); + } + emit updateSearchDialog(); +} + +void CalendarView::deleteEvent(Event *anEvent) +{ + if (!anEvent) { + KNotifyClient::beep(); + return; + } + + if (anEvent->recurrence()->doesRecur()) { + QDate itemDate = mViewManager->currentSelectionDate(); + int km; + if (!itemDate.isValid()) { + //kdDebug() << "Date Not Valid" << endl; + if (KOPrefs::instance()->mConfirm) { + km = KMessageBox::warningContinueCancel(this,anEvent->summary() + + i18n("\nThis event recurs\nover multiple dates.\nAre you sure you want\nto delete this event\nand all its recurrences?"), + i18n("KO/Pi Confirmation"),i18n("Delete All")); + if ( km == KMessageBox::Continue ) + km = KMessageBox::No; // No = all below + } else + km = KMessageBox::No; + } else { + km = KMessageBox::warningYesNoCancel(this,anEvent->summary() + + i18n("\nThis event recurs\nover multiple dates.\nDo you want to delete\nall it's recurrences,\nor only the current one on:\n")+ + KGlobal::locale()->formatDate(itemDate)+i18n(" ?\n\nDelete:\n"), + i18n("KO/Pi Confirmation"),i18n("Current"), + i18n("All")); + } + switch(km) { + + case KMessageBox::No: // Continue // all + //qDebug("KMessageBox::No "); + if (anEvent->organizer()==KOPrefs::instance()->email() && anEvent->attendeeCount()>0) + schedule(Scheduler::Cancel,anEvent); + + checkZaurusId( anEvent->zaurusId()); + mCalendar->deleteEvent(anEvent); + changeEventDisplay(anEvent,KOGlobals::EVENTDELETED); + break; + + // Disabled because it does not work + //#if 0 + case KMessageBox::Yes: // just this one + //QDate qd = mNavigator->selectedDates().first(); + //if (!qd.isValid()) { + // kdDebug() << "no date selected, or invalid date" << endl; + // KNotifyClient::beep(); + // return; + //} + //while (!anEvent->recursOn(qd)) qd = qd.addDays(1); + if (itemDate!=QDate(1,1,1) || itemDate.isValid()) { + anEvent->addExDate(itemDate); + int duration = anEvent->recurrence()->duration(); + if ( duration > 0 ) { + anEvent->recurrence()->setDuration( duration - 1 ); + } + changeEventDisplay(anEvent, KOGlobals::EVENTEDITED); + } + break; + //#endif + } // switch + } else { + if (KOPrefs::instance()->mConfirm) { + switch (KMessageBox::warningContinueCancel(this,anEvent->summary() + + i18n("\nAre you sure you want\nto delete this event?"), + i18n("KO/Pi Confirmation"),i18n("Delete"))) { + case KMessageBox::Continue: // OK + if (anEvent->organizer()==KOPrefs::instance()->email() && anEvent->attendeeCount()>0) + schedule(Scheduler::Cancel,anEvent); + checkZaurusId( anEvent->zaurusId()); + mCalendar->deleteEvent(anEvent); + changeEventDisplay(anEvent, KOGlobals::EVENTDELETED); + break; + } // switch + } else { + if (anEvent->organizer()==KOPrefs::instance()->email() && anEvent->attendeeCount()>0) + schedule(Scheduler::Cancel,anEvent); + checkZaurusId( anEvent->zaurusId()); + mCalendar->deleteEvent(anEvent); + changeEventDisplay(anEvent, KOGlobals::EVENTDELETED); + } + } // if-else + emit updateSearchDialog(); +} + +bool CalendarView::deleteEvent(const QString &uid) +{ + Event *ev = mCalendar->event(uid); + if (ev) { + deleteEvent(ev); + return true; + } else { + return false; + } +} + +/*****************************************************************************/ + +void CalendarView::action_mail() +{ +#ifndef KORG_NOMAIL + KOMailClient mailClient; + + Incidence *incidence = currentSelection(); + + if (!incidence) { + KMessageBox::sorry(this,i18n("Can't generate mail:\nNo event selected.")); + return; + } + if(incidence->attendeeCount() == 0 ) { + KMessageBox::sorry(this, + i18n("Can't generate mail:\nNo attendees defined.\n")); + return; + } + + CalendarLocal cal_tmp; + Event *event = 0; + Event *ev = 0; + if ( incidence && incidence->type() == "Event" ) { + event = static_cast<Event *>(incidence); + ev = new Event(*event); + cal_tmp.addEvent(ev); + } + ICalFormat mForm( KOPrefs::instance()->mUseQuicksave); + QString attachment = mForm.toString( &cal_tmp ); + if (ev) delete(ev); + + mailClient.mailAttendees(currentSelection(), attachment); + +#endif + +#if 0 + Event *anEvent = 0; + if (mViewManager->currentView()->isEventView()) { + anEvent = dynamic_cast<Event *>((mViewManager->currentView()->selectedIncidences()).first()); + } + + if (!anEvent) { + KMessageBox::sorry(this,i18n("Can't generate mail:\nNo event selected.")); + return; + } + if(anEvent->attendeeCount() == 0 ) { + KMessageBox::sorry(this, + i18n("Can't generate mail:\nNo attendees defined.\n")); + return; + } + + mailobject.emailEvent(anEvent); +#endif +} + + +void CalendarView::schedule_publish(Incidence *incidence) +{ + Event *event = 0; + Todo *todo = 0; + + if (incidence == 0) { + incidence = mViewManager->currentView()->selectedIncidences().first(); + if (incidence == 0) { + incidence = mTodoList->selectedIncidences().first(); + } + } + if ( incidence && incidence->type() == "Event" ) { + event = static_cast<Event *>(incidence); + } else { + if ( incidence && incidence->type() == "Todo" ) { + todo = static_cast<Todo *>(incidence); + } + } + + if (!event && !todo) { + KMessageBox::sorry(this,i18n("No event selected.")); + return; + } + + PublishDialog *publishdlg = new PublishDialog(); + if (incidence->attendeeCount()>0) { + QPtrList<Attendee> attendees = incidence->attendees(); + attendees.first(); + while ( attendees.current()!=0 ) { + publishdlg->addAttendee(attendees.current()); + attendees.next(); + } + } + bool send = true; + if ( KOPrefs::instance()->mMailClient == KOPrefs::MailClientSendmail ) { + if ( publishdlg->exec() != QDialog::Accepted ) + send = false; + } + if ( send ) { + OutgoingDialog *dlg = mDialogManager->outgoingDialog(); + if ( event ) { + Event *ev = new Event(*event); + ev->registerObserver(0); + ev->clearAttendees(); + if (!dlg->addMessage(ev,Scheduler::Publish,publishdlg->addresses())) { + delete(ev); + } + } else { + if ( todo ) { + Todo *ev = new Todo(*todo); + ev->registerObserver(0); + ev->clearAttendees(); + if (!dlg->addMessage(ev,Scheduler::Publish,publishdlg->addresses())) { + delete(ev); + } + } + } + } + delete publishdlg; +} + +void CalendarView::schedule_request(Incidence *incidence) +{ + schedule(Scheduler::Request,incidence); +} + +void CalendarView::schedule_refresh(Incidence *incidence) +{ + schedule(Scheduler::Refresh,incidence); +} + +void CalendarView::schedule_cancel(Incidence *incidence) +{ + schedule(Scheduler::Cancel,incidence); +} + +void CalendarView::schedule_add(Incidence *incidence) +{ + schedule(Scheduler::Add,incidence); +} + +void CalendarView::schedule_reply(Incidence *incidence) +{ + schedule(Scheduler::Reply,incidence); +} + +void CalendarView::schedule_counter(Incidence *incidence) +{ + schedule(Scheduler::Counter,incidence); +} + +void CalendarView::schedule_declinecounter(Incidence *incidence) +{ + schedule(Scheduler::Declinecounter,incidence); +} + +void CalendarView::schedule_publish_freebusy(int daysToPublish) +{ + QDateTime start = QDateTime::currentDateTime(); + QDateTime end = start.addDays(daysToPublish); + + FreeBusy *freebusy = new FreeBusy(mCalendar, start, end); + freebusy->setOrganizer(KOPrefs::instance()->email()); + + + PublishDialog *publishdlg = new PublishDialog(); + if ( publishdlg->exec() == QDialog::Accepted ) { + OutgoingDialog *dlg = mDialogManager->outgoingDialog(); + if (!dlg->addMessage(freebusy,Scheduler::Publish,publishdlg->addresses())) { + delete(freebusy); + } + } + delete publishdlg; +} + +void CalendarView::schedule(Scheduler::Method method, Incidence *incidence) +{ + Event *event = 0; + Todo *todo = 0; + + if (incidence == 0) { + incidence = mViewManager->currentView()->selectedIncidences().first(); + if (incidence == 0) { + incidence = mTodoList->selectedIncidences().first(); + } + } + if ( incidence && incidence->type() == "Event" ) { + event = static_cast<Event *>(incidence); + } + if ( incidence && incidence->type() == "Todo" ) { + todo = static_cast<Todo *>(incidence); + } + + if (!event && !todo) { + KMessageBox::sorry(this,i18n("No event selected.")); + return; + } + + if( incidence->attendeeCount() == 0 && method != Scheduler::Publish ) { + KMessageBox::sorry(this,i18n("The event has no attendees.")); + return; + } + + Event *ev = 0; + if (event) ev = new Event(*event); + Todo *to = 0; + if (todo) to = new Todo(*todo); + + if (method == Scheduler::Reply || method == Scheduler::Refresh) { + Attendee *me = incidence->attendeeByMails(KOPrefs::instance()->mAdditionalMails,KOPrefs::instance()->email()); + if (!me) { + KMessageBox::sorry(this,i18n("Could not find your attendee entry.\nPlease check the emails.")); + return; + } + if (me->status()==Attendee::NeedsAction && me->RSVP() && method==Scheduler::Reply) { + StatusDialog *statdlg = new StatusDialog(this); + if (!statdlg->exec()==QDialog::Accepted) return; + me->setStatus( statdlg->status() ); + delete(statdlg); + } + Attendee *menew = new Attendee(*me); + if (ev) { + ev->clearAttendees(); + ev->addAttendee(menew,false); + } else { + if (to) { + todo->clearAttendees(); + todo->addAttendee(menew,false); + } + } + } + + OutgoingDialog *dlg = mDialogManager->outgoingDialog(); + if (ev) { + if ( !dlg->addMessage(ev,method) ) delete(ev); + } else { + if (to) { + if ( !dlg->addMessage(to,method) ) delete(to); + } + } +} + +void CalendarView::openAddressbook() +{ + KRun::runCommand("kaddressbook"); +} + +void CalendarView::setModified(bool modified) +{ + if ( modified ) + emit signalmodified(); + if (mModified != modified) { + mModified = modified; + emit modifiedChanged(mModified); + } +} + +bool CalendarView::isReadOnly() +{ + return mReadOnly; +} + +void CalendarView::setReadOnly(bool readOnly) +{ + if (mReadOnly != readOnly) { + mReadOnly = readOnly; + emit readOnlyChanged(mReadOnly); + } +} + +bool CalendarView::isModified() +{ + return mModified; +} + +void CalendarView::printSetup() +{ +#ifndef KORG_NOPRINTER + createPrinter(); + + mCalPrinter->setupPrinter(); +#endif +} + +void CalendarView::print() +{ +#ifndef KORG_NOPRINTER + createPrinter(); + + DateList tmpDateList = mNavigator->selectedDates(); + mCalPrinter->print(CalPrinter::Month, + tmpDateList.first(), tmpDateList.last()); +#endif +} + +void CalendarView::printPreview() +{ +#ifndef KORG_NOPRINTER + kdDebug() << "CalendarView::printPreview()" << endl; + + createPrinter(); + + DateList tmpDateList = mNavigator->selectedDates(); + + mViewManager->currentView()->printPreview(mCalPrinter,tmpDateList.first(), + tmpDateList.last()); +#endif +} + +void CalendarView::exportICalendar() +{ + QString filename = KFileDialog::getSaveFileName("icalout.ics",i18n("*.ics|ICalendars"),this); + + // Force correct extension + if (filename.right(4) != ".ics") filename += ".ics"; + + FileStorage storage( mCalendar, filename, new ICalFormat( KOPrefs::instance()->mUseQuicksave) ); + storage.save(); +} + +bool CalendarView::exportVCalendar( QString filename ) +{ + if (mCalendar->journals().count() > 0) { + int result = KMessageBox::warningContinueCancel(this, + i18n("The journal entries can not be\nexported to a vCalendar file."), + i18n("Data Loss Warning"),i18n("Proceed"),i18n("Cancel"), + true); + if (result != KMessageBox::Continue) return false; + } + + //QString filename = KFileDialog::getSaveFileName("vcalout.vcs",i18n("*.vcs|VCalendars"),this); + + // Force correct extension + if (filename.right(4) != ".vcs") filename += ".vcs"; + + FileStorage storage( mCalendar, filename, new VCalFormat ); + return storage.save(); + +} + +void CalendarView::eventUpdated(Incidence *) +{ + setModified(); + // Don't call updateView here. The code, which has caused the update of the + // event is responsible for updating the view. + // updateView(); +} + +void CalendarView::adaptNavigationUnits() +{ + if (mViewManager->currentView()->isEventView()) { + int days = mViewManager->currentView()->currentDateCount(); + if (days == 1) { + emit changeNavStringPrev(i18n("&Previous Day")); + emit changeNavStringNext(i18n("&Next Day")); + } else { + emit changeNavStringPrev(i18n("&Previous Week")); + emit changeNavStringNext(i18n("&Next Week")); + } + } +} + +void CalendarView::processMainViewSelection( Incidence *incidence ) +{ + if ( incidence ) mTodoList->clearSelection(); + processIncidenceSelection( incidence ); +} + +void CalendarView::processTodoListSelection( Incidence *incidence ) +{ + if ( incidence && mViewManager->currentView() ) { + mViewManager->currentView()->clearSelection(); + } + processIncidenceSelection( incidence ); +} + +void CalendarView::processIncidenceSelection( Incidence *incidence ) +{ + if ( incidence == mSelectedIncidence ) return; + + mSelectedIncidence = incidence; + + emit incidenceSelected( mSelectedIncidence ); + + if ( incidence && incidence->type() == "Event" ) { + Event *event = static_cast<Event *>( incidence ); + if ( event->organizer() == KOPrefs::instance()->email() ) { + emit organizerEventsSelected( true ); + } else { + emit organizerEventsSelected(false); + } + if (event->attendeeByMails( KOPrefs::instance()->mAdditionalMails, + KOPrefs::instance()->email() ) ) { + emit groupEventsSelected( true ); + } else { + emit groupEventsSelected(false); + } + return; + } else { + if ( incidence && incidence->type() == "Todo" ) { + emit todoSelected( true ); + Todo *event = static_cast<Todo *>( incidence ); + if ( event->organizer() == KOPrefs::instance()->email() ) { + emit organizerEventsSelected( true ); + } else { + emit organizerEventsSelected(false); + } + if (event->attendeeByMails( KOPrefs::instance()->mAdditionalMails, + KOPrefs::instance()->email() ) ) { + emit groupEventsSelected( true ); + } else { + emit groupEventsSelected(false); + } + return; + } else { + emit todoSelected( false ); + emit organizerEventsSelected(false); + emit groupEventsSelected(false); + } + return; + } + + /* if ( incidence && incidence->type() == "Todo" ) { + emit todoSelected( true ); + } else { + emit todoSelected( false ); + }*/ +} + + +void CalendarView::checkClipboard() +{ +#ifndef KORG_NODND + if (ICalDrag::canDecode(QApplication::clipboard()->data())) { + emit pasteEnabled(true); + } else { + emit pasteEnabled(false); + } +#endif +} + +void CalendarView::showDates(const DateList &selectedDates) +{ + // kdDebug() << "CalendarView::selectDates()" << endl; + + if ( mViewManager->currentView() ) { + updateView( selectedDates.first(), selectedDates.last() ); + } else { + mViewManager->showAgendaView(); + } + + QString selDates; + selDates = KGlobal::locale()->formatDate( selectedDates.first(), true); + if (selectedDates.first() < selectedDates.last() ) + selDates += " - " + KGlobal::locale()->formatDate( selectedDates.last(),true); + topLevelWidget()->setCaption( i18n("Dates: ") + selDates ); + +} + +void CalendarView::editFilters() +{ + // kdDebug() << "CalendarView::editFilters()" << endl; + + CalFilter *filter = mFilters.first(); + while(filter) { + kdDebug() << " Filter: " << filter->name() << endl; + filter = mFilters.next(); + } + + mDialogManager->showFilterEditDialog(&mFilters); +} +void CalendarView::toggleFilter() +{ + showFilter(! mFilterView->isVisible()); +} + +void CalendarView::selectFilter( int fil ) +{ + mFilterView->setSelectedFilter( fil ); +} +void CalendarView::showFilter(bool visible) +{ + if (visible) mFilterView->show(); + else mFilterView->hide(); +} +void CalendarView::toggleFilerEnabled( ) +{ + mFilterView->setFiltersEnabled ( !mFilterView->filtersEnabled() ); + if ( !mFilterView->filtersEnabled() ) + topLevelWidget()->setCaption( i18n("Filter disabled ") ); + +} +void CalendarView::updateFilter() +{ + CalFilter *filter = mFilterView->selectedFilter(); + if (filter) { + if (mFilterView->filtersEnabled()) { + topLevelWidget()->setCaption( i18n("Filter selected: ")+filter->name() ); + filter->setEnabled(true); + } + else filter->setEnabled(false); + mCalendar->setFilter(filter); + updateView(); + } +} + +void CalendarView::filterEdited() +{ + mFilterView->updateFilters(); + updateFilter(); + writeSettings(); +} + + +void CalendarView::takeOverEvent() +{ + Incidence *incidence = currentSelection(); + + if (!incidence) return; + + incidence->setOrganizer(KOPrefs::instance()->email()); + incidence->recreate(); + incidence->setReadOnly(false); + + updateView(); +} + +void CalendarView::takeOverCalendar() +{ + // TODO: Create Calendar::allIncidences() function and use it here + + QPtrList<Event> events = mCalendar->events(); + for(uint i=0; i<events.count(); ++i) { + events.at(i)->setOrganizer(KOPrefs::instance()->email()); + events.at(i)->recreate(); + events.at(i)->setReadOnly(false); + } + + QPtrList<Todo> todos = mCalendar->todos(); + for(uint i=0; i<todos.count(); ++i) { + todos.at(i)->setOrganizer(KOPrefs::instance()->email()); + todos.at(i)->recreate(); + todos.at(i)->setReadOnly(false); + } + + QPtrList<Journal> journals = mCalendar->journals(); + for(uint i=0; i<journals.count(); ++i) { + journals.at(i)->setOrganizer(KOPrefs::instance()->email()); + journals.at(i)->recreate(); + journals.at(i)->setReadOnly(false); + } + + updateView(); +} + +void CalendarView::showIntro() +{ + kdDebug() << "To be implemented." << endl; +} + +QWidgetStack *CalendarView::viewStack() +{ + return mRightFrame; +} + +QWidget *CalendarView::leftFrame() +{ + return mLeftFrame; +} + +DateNavigator *CalendarView::dateNavigator() +{ + return mNavigator; +} + +KDateNavigator* CalendarView::dateNavigatorWidget() +{ + return mDateNavigator; +} +void CalendarView::toggleDateNavigatorWidget() +{ + if (mDateNavigator->isVisible()) + mDateNavigator->hide(); + else + mDateNavigator->show(); +} +void CalendarView::addView(KOrg::BaseView *view) +{ + mViewManager->addView(view); +} + +void CalendarView::showView(KOrg::BaseView *view) +{ + mViewManager->showView(view, mLeftFrame->isVisible()); +} + +Incidence *CalendarView::currentSelection() +{ + return mViewManager->currentSelection(); +} +void CalendarView::toggleAllDaySize() +{ + /* + if ( KOPrefs::instance()->mAllDaySize > 47 ) + KOPrefs::instance()->mAllDaySize = KOPrefs::instance()->mAllDaySize /2; + else + KOPrefs::instance()->mAllDaySize = KOPrefs::instance()->mAllDaySize *2; + */ + viewManager()->agendaView()->toggleAllDay(); +} +void CalendarView::toggleExpand() +{ + // if ( mLeftFrame->isHidden() ) { + // mLeftFrame->show(); + // emit calendarViewExpanded( false ); + // } else { + // mLeftFrame->hide(); + // emit calendarViewExpanded( true ); + // } + + globalFlagBlockAgenda = 1; + emit calendarViewExpanded( !mLeftFrame->isHidden() ); + globalFlagBlockAgenda = 5; + mViewManager->raiseCurrentView( !mLeftFrame->isHidden() ); + //mViewManager->showView( 0, true ); +} + +void CalendarView::calendarModified( bool modified, Calendar * ) +{ + setModified( modified ); +} + +Todo *CalendarView::selectedTodo() +{ + Incidence *incidence = currentSelection(); + if ( incidence && incidence->type() == "Todo" ) { + return static_cast<Todo *>( incidence ); + } + + incidence = mTodoList->selectedIncidences().first(); + if ( incidence && incidence->type() == "Todo" ) { + return static_cast<Todo *>( incidence ); + } + + return 0; +} + +void CalendarView::dialogClosing(Incidence *in) +{ + // mDialogList.remove(in); +} + +void CalendarView::showIncidence() +{ + Incidence *incidence = currentSelection(); + if ( !incidence ) incidence = mTodoList->selectedIncidences().first(); + if ( incidence ) { + ShowIncidenceVisitor v; + v.act( incidence, this ); + } +} +void CalendarView::editIncidenceDescription() +{ + mFlagEditDescription = true; + editIncidence(); + mFlagEditDescription = false; +} +void CalendarView::editIncidence() +{ + // qDebug("editIncidence() "); + Incidence *incidence = currentSelection(); + if ( !incidence ) incidence = mTodoList->selectedIncidences().first(); + if ( incidence ) { + EditIncidenceVisitor v; + v.act( incidence, this ); + } +} + +void CalendarView::deleteIncidence() +{ + Incidence *incidence = currentSelection(); + if ( !incidence ) incidence = mTodoList->selectedIncidences().first(); + if ( incidence ) { + deleteIncidence(incidence); + } +} + +void CalendarView::showIncidence(Incidence *incidence) +{ + if ( incidence ) { + ShowIncidenceVisitor v; + v.act( incidence, this ); + } +} + +void CalendarView::editIncidence(Incidence *incidence) +{ + if ( incidence ) { + + EditIncidenceVisitor v; + v.act( incidence, this ); + + } +} + +void CalendarView::deleteIncidence(Incidence *incidence) +{ + //qDebug(" CalendarView::deleteIncidence "); + if ( incidence ) { + DeleteIncidenceVisitor v; + v.act( incidence, this ); + } +} + + +void CalendarView::lookForOutgoingMessages() +{ + OutgoingDialog *ogd = mDialogManager->outgoingDialog(); + ogd->loadMessages(); +} + +void CalendarView::lookForIncomingMessages() +{ + IncomingDialog *icd = mDialogManager->incomingDialog(); + icd->retrieve(); +} + +bool CalendarView::removeCompletedSubTodos( Todo* t ) +{ + bool deleteTodo = true; + QPtrList<Incidence> subTodos; + Incidence *aTodo; + subTodos = t->relations(); + for (aTodo = subTodos.first(); aTodo; aTodo = subTodos.next()) { + if (! removeCompletedSubTodos( (Todo*) aTodo )) + deleteTodo = false; + } + if ( deleteTodo ) { + if ( t->isCompleted() ) { + checkZaurusId( t->zaurusId(), true ); + mCalendar->deleteTodo( t ); + changeTodoDisplay( t,KOGlobals::EVENTDELETED ); + } + else + deleteTodo = false; + } + return deleteTodo; + +} +void CalendarView::purgeCompleted() +{ + int result = KMessageBox::warningContinueCancel(this, + i18n("Delete all\ncompleted To-Dos?"),i18n("Purge To-Dos"),i18n("Purge")); + + if (result == KMessageBox::Continue) { + + QPtrList<Todo> todoCal; + QPtrList<Todo> rootTodos; + //QPtrList<Incidence> rel; + Todo *aTodo;//, *rTodo; + Incidence *rIncidence; + bool childDelete = false; + bool deletedOne = true; + todoCal = calendar()->todos(); + for (aTodo = todoCal.first(); aTodo; aTodo = todoCal.next()) { + if ( !aTodo->relatedTo() ) + rootTodos.append( aTodo ); + } + for (aTodo = rootTodos.first(); aTodo; aTodo = rootTodos.next()) { + removeCompletedSubTodos( aTodo ); + } + + updateView(); + } +} + +void CalendarView::slotCalendarChanged() +{ + ; +} + +NavigatorBar *CalendarView::navigatorBar() +{ + return mNavigatorBar; +} + + + +void CalendarView::keyPressEvent ( QKeyEvent *e) +{ + //qDebug(" alendarView::keyPressEvent "); + e->ignore(); +} + +#include "calendarview.moc" + +#include "calendarviewbase.moc" diff --git a/korganizer/calendarview.h b/korganizer/calendarview.h new file mode 100644 index 0000000..e7aa351 --- a/dev/null +++ b/korganizer/calendarview.h @@ -0,0 +1,586 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000, 2001 + Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + 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 CALENDARVIEW_H +#define CALENDARVIEW_H + +#include <qframe.h> +#include <qlayout.h> +#include <qwidget.h> +#include <qptrlist.h> +#include <qvbox.h> +#include <qmap.h> +#ifndef DESKTOP_VERSION +#include <qtopia/ir.h> +#else +#define Ir char +#endif +#include <libkcal/calendar.h> +#include <libkcal/scheduler.h> +#include <libkcal/calendarresources.h> +#include <libkcal/resourcecalendar.h> + +#include <korganizer/calendarviewbase.h> + +class QWidgetStack; +class QSplitter; + +class CalPrinter; +class KOFilterView; +class KOViewManager; +class KODialogManager; +class KOTodoView; +class KDateNavigator; +class DateNavigator; +class KOIncidenceEditor; +class KDatePicker; +class ResourceView; +class NavigatorBar; +class KOEventEditor; +class KOTodoEditor ; +class KOEventViewerDialog; +class KOBeamPrefs; +class KSyncProfile; +class AlarmDialog; +class KCal::Attendee; + +namespace KCal { class FileStorage; } + +using namespace KCal; + +/** + This is the main calendar widget. It provides the different vies on t he + calendar data as well as the date navigator. It also handles synchronisation + of the different views and controls the different dialogs like preferences, + event editor, search dialog etc. + + @short main calendar view widget + @author Cornelius Schumacher +*/ +class CalendarView : public KOrg::CalendarViewBase, public KCal::Calendar::Observer +{ + Q_OBJECT + public: + /** + Constructs a new calendar view widget. + + @param calendar calendar document + @param parent parent window + @param name Qt internal widget object name + */ + CalendarView( CalendarResources *calendar, QWidget *parent = 0, + const char *name = 0 ); + CalendarView( Calendar *calendar, QWidget *parent = 0, + const char *name = 0 ); + virtual ~CalendarView(); + + Calendar *calendar() { return mCalendar; } + + KOViewManager *viewManager(); + KODialogManager *dialogManager(); + + QDate startDate(); + QDate endDate(); + + QWidgetStack *viewStack(); + QWidget *leftFrame(); + NavigatorBar *navigatorBar(); + + DateNavigator *dateNavigator(); + KDateNavigator *dateNavigatorWidget(); + + void addView(KOrg::BaseView *); + void showView(KOrg::BaseView *); + KOEventViewerDialog* getEventViewerDialog(); + Incidence *currentSelection(); + + signals: + /** This todo has been modified */ + void todoModified(Todo *, int); + + /** when change is made to options dialog, the topwidget will catch this + * and emit this signal which notifies all widgets which have registered + * for notification to update their settings. */ + void configChanged(); + /** emitted when the topwidget is closing down, so that any attached + child windows can also close. */ + void closingDown(); + /** emitted right before we die */ + void closed(QWidget *); + + /** Emitted when state of modified flag changes */ + void modifiedChanged(bool); + void signalmodified(); + + /** Emitted when state of read-only flag changes */ + void readOnlyChanged(bool); + + /** Emitted when the unit of navigation changes */ + void changeNavStringPrev(const QString &); + void changeNavStringNext(const QString &); + + /** Emitted when state of events selection has changed and user is organizer*/ + void organizerEventsSelected(bool); + /** Emitted when state of events selection has changed and user is attendee*/ + void groupEventsSelected(bool); + /** + Emitted when an incidence gets selected. If the selection is cleared the + signal is emitted with 0 as argument. + */ + void incidenceSelected( Incidence * ); + /** Emitted, when a todoitem is selected or deselected. */ + void todoSelected( bool ); + + /** + Emitted, when clipboard content changes. Parameter indicates if paste + is possible or not. + */ + void pasteEnabled(bool); + + /** Emitted, when the number of incoming messages has changed. */ + void numIncomingChanged(int); + + /** Emitted, when the number of outgoing messages has changed. */ + void numOutgoingChanged(int); + + /** Send status message, which can e.g. be displayed in the status bar. */ + void statusMessage(const QString &); + + void calendarViewExpanded( bool ); + void updateSearchDialog(); + + + public slots: + + void addAlarm(const QDateTime &qdt, const QString ¬i ); + void addSuspendAlarm(const QDateTime &qdt, const QString ¬i ); + void removeAlarm(const QDateTime &qdt, const QString ¬i ); + + /** options dialog made a changed to the configuration. we catch this + * and notify all widgets which need to update their configuration. */ + void updateConfig(); + + /** + Load calendar from file \a filename. If \a merge is true, load + calendar into existing one, if it is false, clear calendar, before + loading. Return true, if calendar could be successfully loaded. + */ + bool openCalendar(QString filename, bool merge=false); + bool syncCalendar(QString filename,int mode = 0 ); + + /** + Save calendar data to file. Return true if calendar could be + successfully saved. + */ + bool saveCalendar(QString filename); + + /** + Close calendar. Clear calendar data and reset views to display an empty + calendar. + */ + void closeCalendar(); + + /** Archive old events of calendar */ + void archiveCalendar(); + + void showIncidence(); + void editIncidence(); + void editIncidenceDescription(); + void deleteIncidence(); + + /** create an editeventwin with supplied date/time, and if bool is true, + * make the event take all day. */ + void newEvent(QDateTime, QDateTime, bool allDay = false); + void newEvent(QDateTime fh); + void newEvent(QDate dt); + /** create new event without having a date hint. Takes current date as + default hint. */ + void newEvent(); + void newFloatingEvent(); + + /** Create a read-only viewer dialog for the supplied incidence. It calls the correct showXXX method*/ + void showIncidence(Incidence *); + /** Create an editor for the supplied incidence. It calls the correct editXXX method*/ + void editIncidence(Incidence *); + /** Delete the supplied incidence. It calls the correct deleteXXX method*/ + void deleteIncidence(Incidence *); + void cloneIncidence(Incidence *); + void cancelIncidence(Incidence *); + /** Create an editor for the supplied event. */ + void editEvent(Event *); + /** Delete the supplied event. */ + void deleteEvent(Event *); + /** Delete the event with the given unique ID. Returns false, if event wasn't + found. */ + bool deleteEvent(const QString &uid); + /** Create a read-only viewer dialog for the supplied event. */ + void showEvent(Event *); + + void editJournal(Journal *); + void showJournal(Journal *); + void deleteJournal(Journal *); + /** Create an editor dialog for a todo */ + void editTodo(Todo *); + /** Create a read-only viewer dialog for the supplied todo */ + void showTodo(Todo *); + /** create new todo */ + void newTodo(); + /** create new todo with a parent todo */ + void newSubTodo(); + /** create new todo with a parent todo */ + void newSubTodo(Todo *); + /** Delete todo */ + void deleteTodo(Todo *); + + + /** Check if clipboard contains vCalendar event. The signal pasteEnabled() is + * emitted as result. */ + void checkClipboard(); + + /** using the KConfig associated with the kapp variable, read in the + * settings from the config file. + */ + void readSettings(); + + /** write current state to config file. */ + void writeSettings(); + + /** read settings for calendar filters */ + void readFilterSettings(KConfig *config); + + /** write settings for calendar filters */ + void writeFilterSettings(KConfig *config); + + /** passes on the message that an event has changed to the currently + * activated view so that it can make appropriate display changes. */ + void changeEventDisplay(Event *, int); + void changeIncidenceDisplay(Incidence *, int); + void changeTodoDisplay(Todo *, int); + + void eventAdded(Event *); + void eventChanged(Event *); + void eventToBeDeleted(Event *); + void eventDeleted(); + + void todoAdded(Todo *); + void todoChanged(Todo *); + void todoToBeDeleted(Todo *); + void todoDeleted(); + + void updateView(const QDate &start, const QDate &end); + void updateView(); + + /** Full update of visible todo views */ + void updateTodoViews(); + + void updateUnmanagedViews(); + + /** cut the current appointment to the clipboard */ + void edit_cut(); + + /** copy the current appointment(s) to the clipboard */ + void edit_copy(); + + /** paste the current vobject(s) in the clipboard buffer into calendar */ + void edit_paste(); + + /** edit viewing and configuration options. */ + void edit_options(); + void edit_sync_options(); + /** + Functions for printing, previewing a print, and setting up printing + parameters. + */ + void print(); + void printSetup(); + void printPreview(); + + /** Export as iCalendar file */ + void exportICalendar(); + + /** Export as vCalendar file */ + bool exportVCalendar( QString fn); + + /** pop up a dialog to show an existing appointment. */ + void appointment_show(); + /** + * pop up an Appointment Dialog to edit an existing appointment. Get + * information on the appointment from the list of unique IDs that is + * currently in the View, called currIds. + */ + void appointment_edit(); + /** + * pop up dialog confirming deletion of currently selected event in the + * View. + */ + void appointment_delete(); + + /** mails the currently selected event to a particular user as a vCalendar + attachment. */ + void action_mail(); + + /* frees a subtodo from it's relation */ + void todo_unsub( Todo * ); + + /** Take ownership of selected event. */ + void takeOverEvent(); + + /** Take ownership of all events in calendar. */ + void takeOverCalendar(); + + /** query whether or not the calendar is "dirty". */ + bool isModified(); + /** set the state of calendar. Modified means "dirty", i.e. needing a save. */ + void setModified(bool modified=true); + + /** query if the calendar is read-only. */ + bool isReadOnly(); + /** set state of calendar to read-only */ + void setReadOnly(bool readOnly=true); + + void eventUpdated(Incidence *); + + /* iTIP scheduling actions */ + void schedule_publish(Incidence *incidence = 0); + void schedule_request(Incidence *incidence = 0); + void schedule_refresh(Incidence *incidence = 0); + void schedule_cancel(Incidence *incidence = 0); + void schedule_add(Incidence *incidence = 0); + void schedule_reply(Incidence *incidence = 0); + void schedule_counter(Incidence *incidence = 0); + void schedule_declinecounter(Incidence *incidence = 0); + void schedule_publish_freebusy(int daysToPublish = 30); + + void openAddressbook(); + + void editFilters(); + void toggleFilerEnabled(); + + void toggleFilter(); + void showFilter(bool visible); + void updateFilter(); + void filterEdited(); + void selectFilter( int ); + + void showIntro(); + + /** Move the curdatepient view date to today */ + void goToday(); + + /** Move to the next date(s) in the current view */ + void goNext(); + + /** Move to the previous date(s) in the current view */ + void goPrevious(); + /** Move to the next date(s) in the current view */ + void goNextMonth(); + + /** Move to the previous date(s) in the current view */ + void goPreviousMonth(); + + void toggleExpand(); + void toggleDateNavigatorWidget(); + void toggleAllDaySize(); + void dialogClosing(Incidence *); + + /** Look for new messages in the inbox */ + void lookForIncomingMessages(); + /** Look for new messages in the outbox */ + void lookForOutgoingMessages(); + + void processMainViewSelection( Incidence * ); + void processTodoListSelection( Incidence * ); + + void processIncidenceSelection( Incidence * ); + + void purgeCompleted(); + bool removeCompletedSubTodos( Todo* ); + void slotCalendarChanged(); + bool importBday(); + bool addAnniversary( QDate data, QString name, KCal::Attendee* a , bool birthday ); + bool importQtopia( const QString &categoriesFile, + const QString &datebookFile, + const QString &tasklistFile ); + void syncSharp( ); + void slotSelectPickerDate( QDate ) ; + void showDatePicker( ) ; + void moveIncidence(Incidence *) ; + void beamIncidence(Incidence *) ; + void beamCalendar() ; + void beamFilteredCalendar() ; + void beamIncidenceList(QPtrList<Incidence>) ; + void manageCategories(); + int addCategories(); + void removeCategories(); + void setSyncDevice( QString ); + void setSyncName( QString ); + protected slots: + void timerAlarm(); + void suspendAlarm(); + void beamDone( Ir *ir ); + /** Select a view or adapt the current view to display the specified dates. */ + void showDates( const KCal::DateList & ); + void selectWeekNum ( int ); + + public: + // show a standard warning + // returns KMsgBox::yesNoCancel() + int msgCalModified(); + void confSync(); + void setLoadedFileVersion(QDateTime); + bool checkFileVersion(QString fn); + bool checkFileChanged(QString fn); + Event* getLastSyncEvent(); + /** Adapt navigation units correpsonding to step size of navigation of the + * current view. + */ + void adaptNavigationUnits(); + bool synchronizeCalendar( Calendar* local, Calendar* remote, int mode ); + int takeEvent( Incidence* local, Incidence* remote, int mode, bool full = false ); + //Attendee* getYourAttendee(Event *event); + protected: + void schedule(Scheduler::Method, Incidence *incidence = 0); + + // returns KMsgBox::OKCandel() + int msgItemDelete(); + void showEventEditor(); + void showTodoEditor(); + void writeLocale(); + Todo *selectedTodo(); + + private: + AlarmDialog * mAlarmDialog; + QString mAlarmNotification; + QString mSuspendAlarmNotification; + QTimer* mSuspendTimer; + QTimer* mAlarmTimer; + void computeAlarm( QString ); + void startAlarm( QString, QString ); + void setSyncEventsReadOnly(); + + QDateTime loadedFileVersion; + void checkSharpEvent( Event* lastSync, Incidence* toDelete ); + QPtrList<KSyncProfile> mSyncProfiles; + QStringList mSyncProfileNames; + void checkZaurusId( int id, bool todo = false ); + int mGlobalSyncMode; + QString mCurrentSyncDevice; + QString mCurrentSyncName; + KOBeamPrefs* beamDialog; + void init(); + int mDatePickerMode; + bool mFlagEditDescription; + QDateTime mLastCalendarSync; + void createPrinter(); + + void calendarModified( bool, Calendar * ); + + CalPrinter *mCalPrinter; + + QSplitter *mPanner; + QSplitter *mLeftSplitter; + QWidget *mLeftFrame; + QWidgetStack *mRightFrame; + + KDatePicker* mDatePicker; + QVBox* mDateFrame; + NavigatorBar *mNavigatorBar; + + KDateNavigator *mDateNavigator; // widget showing small month view. + + KOFilterView *mFilterView; + + ResourceView *mResourceView; + + // calendar object for this viewing instance + Calendar *mCalendar; + + CalendarResourceManager *mResourceManager; + + FileStorage *mStorage; + + DateNavigator *mNavigator; + + KOViewManager *mViewManager; + KODialogManager *mDialogManager; + + // Calendar filters + QPtrList<CalFilter> mFilters; + + // various housekeeping variables. + bool mModified; // flag indicating if calendar is modified + bool mReadOnly; // flag indicating if calendar is read-only + QDate mSaveSingleDate; + + Incidence *mSelectedIncidence; + Incidence *mMoveIncidence; + + KOTodoView *mTodoList; + KOEventEditor * mEventEditor; + KOTodoEditor * mTodoEditor; + KOEventViewerDialog * mEventViewerDialog; + void keyPressEvent ( QKeyEvent *e) ; + //QMap<Incidence*,KOIncidenceEditor*> mDialogList; +}; + + +class CalendarViewVisitor : public Incidence::Visitor +{ + public: + CalendarViewVisitor() : mView( 0 ) {} + + bool act( Incidence *incidence, CalendarView *view ) + { + mView = view; + return incidence->accept( *this ); + } + + protected: + CalendarView *mView; +}; + +class ShowIncidenceVisitor : public CalendarViewVisitor +{ + protected: + bool visit( Event *event ) { mView->showEvent( event ); return true; } + bool visit( Todo *todo ) { mView->showTodo( todo ); return true; } + bool visit( Journal * j ) { mView->showJournal( j );return true; } +}; + +class EditIncidenceVisitor : public CalendarViewVisitor +{ + protected: + bool visit( Event *event ) { mView->editEvent( event ); return true; } + bool visit( Todo *todo ) { mView->editTodo( todo ); return true; } + bool visit( Journal *j ) { mView->editJournal( j); return true; } +}; + +class DeleteIncidenceVisitor : public CalendarViewVisitor +{ + protected: + bool visit( Event *event ) { mView->deleteEvent( event ); return true; } + bool visit( Todo *todo ) { mView->deleteTodo( todo ); return true; } + bool visit( Journal * j) {mView->deleteJournal( j ); return true; } +}; + +#endif diff --git a/korganizer/calendarview.moc b/korganizer/calendarview.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/calendarview.moc diff --git a/korganizer/calendarviewbase.moc b/korganizer/calendarviewbase.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/calendarviewbase.moc diff --git a/korganizer/calprintbase.cpp b/korganizer/calprintbase.cpp new file mode 100644 index 0000000..af32ebc --- a/dev/null +++ b/korganizer/calprintbase.cpp @@ -0,0 +1,1304 @@ +/* + This file is part of KOrganizer. + + Copyright (c) 1998 Preston Brown + Copyright (c) 2003 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., 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. +*/ + +#include <qpainter.h> +#include <qlayout.h> +#include <qframe.h> +#include <qlabel.h> +#include <qptrlist.h> +#include <qintdict.h> +#include <qfontmetrics.h> + +#include <kglobal.h> +#include <klocale.h> +#include <kdebug.h> +#include <kconfig.h> +#include <kcalendarsystem.h> +#include <kprinter.h> + +#include <libkcal/todo.h> +#include <libkcal/event.h> +#include <libkcal/calendar.h> + +#include "koprefs.h" +#include "koglobals.h" +#ifndef KORG_NOPLUGINS +#include "kocore.h" +#endif +#include "cellitem.h" + +#include "calprintbase.h" + +#ifndef KORG_NOPRINTER +//#include "calprintbase.moc" + +int CalPrintBase::mHeaderHeight=90; +int CalPrintBase::mSubHeaderHeight=20; +int CalPrintBase::mMargin=36; + + + +class CalPrintBase::TodoParentStart +{ + public: + TodoParentStart( QRect pt = QRect(), bool page = true ) + : mRect( pt ), mSamePage( page ) {} + + QRect mRect; + bool mSamePage; +}; + +class PrintCellItem : public KOrg::CellItem +{ + public: + PrintCellItem( Event *event, const QDate &day ) + : mEvent( event ), mDay( day ) + { + } + + Event *event() const { return mEvent; } + + QString label() const { return mEvent->summary(); } + + bool overlaps( KOrg::CellItem *o ) const + { + PrintCellItem *other = static_cast<PrintCellItem *>( o ); + + QDateTime start = event()->dtStart(); + QDateTime end = event()->dtEnd(); + if ( event()->doesRecur() ) { + start.setDate( mDay ); + end.setDate( mDay ); + } + QDateTime otherStart = other->event()->dtStart(); + QDateTime otherEnd = other->event()->dtEnd(); + if ( other->event()->doesRecur() ) { + otherStart.setDate( mDay ); + otherEnd.setDate( mDay ); + } + +#if 0 + kdDebug() << "PrintCellItem::overlaps() " << event()->summary() + << " <-> " << other->event()->summary() << endl; + kdDebug() << " start : " << start.toString() << endl; + kdDebug() << " end : " << end.toString() << endl; + kdDebug() << " otherStart: " << otherStart.toString() << endl; + kdDebug() << " otherEnd : " << otherEnd.toString() << endl; +#endif + + return !( otherStart >= end || otherEnd <= start ); + } + + private: + Event *mEvent; + QDate mDay; +}; + +void setCategoryColors( QPainter &p, Incidence *incidence) +{ + QColor bgColor; + QStringList categories = incidence->categories(); + QString cat = categories.first(); + if (cat.isEmpty()) + bgColor = KOPrefs::instance()->mEventColor; + else + bgColor = *(KOPrefs::instance()->categoryColor(cat)); + QColor textColor = Qt::black;//getTextColor(bgColor); + p.setPen( textColor ); + p.setBrush( bgColor ); +} + + + +CalPrintBase::CalPrintBase( KPrinter *printer, Calendar *cal, KConfig *cfg ) + : QObject(), mPrinter( printer ), mCalendar( cal ), mConfig( cfg ) +{ +} + +CalPrintBase::~CalPrintBase() +{ +} + + + +QWidget *CalPrintBase::configWidget( QWidget *w ) +{ + QFrame *wdg = new QFrame( w ); + QVBoxLayout *layout = new QVBoxLayout( wdg ); + + QLabel *title = new QLabel( description(), wdg ); + QFont titleFont( title->font() ); + titleFont.setPointSize( 20 ); + titleFont.setBold( true ); + title->setFont( titleFont ); + + layout->addWidget( title ); + layout->addWidget( new QLabel( longDescription(), wdg ) ); + layout->addSpacing( 20 ); + layout->addWidget( new QLabel( i18n("This printing style does not " + "have any configuration options."), + wdg ) ); + layout->addStretch(); + return wdg; +} +#include <qapplication.h> +void CalPrintBase::doPrint() +{ + QPainter p; + + mPrinter->setColorMode( (mUseColors)?(KPrinter::Color):(KPrinter::GrayScale)); + //#define DUMMY_PRINTER +#ifdef DUMMY_PRINTER + + static QWidget* dummy = 0; + if ( ! dummy ) + dummy = new QWidget( ); + else { + delete dummy; + dummy = new QWidget( ); + + } + dummy->resize( 1024, 1024 ); + dummy->repaint(); + dummy->show(); + dummy->raise(); + dummy->setBackgroundColor( Qt::white); + qApp->processEvents(); + p.begin(dummy); +#else + p.begin(mPrinter); +#endif + // the painter initially begins at 72 dpi per the Qt docs. + // we want half-inch margins. + p.setViewport(mMargin, mMargin, + p.viewport().width()-mMargin, + p.viewport().height()-mMargin); + int pageWidth = p.viewport().width(); + int pageHeight = p.viewport().height(); + + print(p, pageWidth, pageHeight); + + p.end(); +} + +void CalPrintBase::doLoadConfig() +{ + if ( mConfig ) { + mConfig->setGroup(description()); + //KConfigGroupSaver saver( mConfig, description() ); + mConfig->sync(); + QDateTime currDate( QDate::currentDate() ); + mFromDate = mConfig->readDateTimeEntry( "FromDate", &currDate ).date(); + mToDate = mConfig->readDateTimeEntry( "ToDate" ).date(); + mUseColors = mConfig->readBoolEntry( "UseColors", false ); + loadConfig(); + } else { + qDebug("no config in CalPrintBase::doLoadConfig "); + } +} + +void CalPrintBase::doSaveConfig() +{ + if ( mConfig ) { + mConfig->setGroup(description()); + // KConfigGroupSaver saver( mConfig, description() ); + saveConfig(); + mConfig->writeEntry( "FromDate", QDateTime( mFromDate ) ); + mConfig->writeEntry( "ToDate", QDateTime( mToDate ) ); + mConfig->writeEntry( "UseColors", mUseColors ); + mConfig->sync(); + } else { + qDebug("no config in CalPrintBase::doSveConfig "); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void CalPrintBase::drawHeader( QPainter &p, QString title, + const QDate &month1, const QDate &month2, + int x, int y, int width, int height ) +{ + p.drawRect(x, y, width, height); + // p.fillRect( x+1, y+1, +// width-2,height-2, +// QBrush(Dense7Pattern) ); + + QString myOwner(mCalendar->getOwner()); + + int right=x+width; + + // print previous month for month view, print current for todo, day and week + int smallMonthWidth=width/4-10; + if (smallMonthWidth>100) smallMonthWidth=100; + if (month2.isValid()) { + right -= (10+smallMonthWidth); + drawSmallMonth(p, QDate(month2.year(), month2.month(), 1), + right, y+2, smallMonthWidth, height-4); + right-=10; + } + if (month1.isValid()) { + right -= (10+smallMonthWidth); + drawSmallMonth(p, QDate(month1.year(), month1.month(), 1), + right, y+2, smallMonthWidth, height-4); + right-=10; + } + + // Print the titles... + QFont font("helvetica", 18, QFont::Bold); + p.setFont(font); + QRect textRect( x+5, y+5, right-10-x, height-10 ); + p.drawText( textRect, Qt::AlignLeft | Qt::AlignTop | Qt::WordBreak, title ); +} + + +void CalPrintBase::drawSmallMonth(QPainter &p, const QDate &qd, + int x, int y, int width, int height) +{ + bool firstCol = true; + QDate monthDate(QDate(qd.year(), qd.month(), 1)); + QDate monthDate2; + int month = monthDate.month(); + + // draw the title + p.setFont(QFont("helvetica", 7, QFont::Bold)); + // int lineSpacing = p.fontMetrics().lineSpacing(); + const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem(); + p.drawText(x, y, width, height/4, AlignCenter, calSys->monthName( qd ) ); + + int cellWidth = width/7; + int cellHeight = height/8; + QString tmpStr; + + // correct begin of week + int weekdayCol = weekdayColumn( qd.dayOfWeek() ); + monthDate2 = monthDate.addDays(-weekdayCol); + + // draw days of week + p.setFont(QFont("helvetica", 7, QFont::Bold)); + for (int col = 0; col < 7; col++) { + // tmpStr.sprintf("%c",(const char*)monthDate2.dayName(monthDate2.dayOfWeek())); + tmpStr=calSys->weekDayName( monthDate2 )[0].upper(); + p.drawText(x+col*cellWidth, y+height/4, cellWidth, cellHeight, + AlignCenter, tmpStr); + monthDate2 = monthDate2.addDays(1); + } + + // draw separator line + p.drawLine(x, y+height/4+cellHeight, x+width, y+height/4+cellHeight); + + for (int row = 0; row < 5; row++) { + for (int col = 0; col < 7; col++) { + if (monthDate.month() != month) + break; + if (firstCol) { + firstCol = true; + col = weekdayColumn( monthDate.dayOfWeek() ); + } + p.drawText( x+col*cellWidth, + y+height/4+cellHeight+(row*cellHeight), + cellWidth, cellHeight, AlignCenter, + tmpStr.setNum(monthDate.day()) ); + monthDate = monthDate.addDays(1); + } + } +} + + +/////////////////////////////////////////////////////////////////////////////// + +/* + * This routine draws a header box over the main part of the calendar + * containing the days of the week. + */ +void CalPrintBase::drawDaysOfWeek(QPainter &p, + const QDate &fromDate, const QDate &toDate, + int x, int y, int width, int height) +{ + int cellWidth = width/(fromDate.daysTo( toDate )+1); + int currx=x; + QDate cellDate(fromDate); + + while (cellDate<=toDate) { + drawDaysOfWeekBox(p, cellDate, currx, y, cellWidth, height); + currx+=cellWidth; + cellDate = cellDate.addDays(1); + } +} + + +void CalPrintBase::drawDaysOfWeekBox(QPainter &p, const QDate &qd, + int x, int y, int width, int height) +{ + const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem(); + + p.setFont( QFont( "helvetica", 10, QFont::Bold ) ); + p.drawRect( x, y, width, height ); +// p.fillRect( x+1, y+1, +// width-2, height-2, +// QBrush( Dense7Pattern ) ); + p.drawText( x+5, y, width-10, height, AlignCenter | AlignVCenter, + calSys->weekDayName( qd ) ); +} + + +void CalPrintBase::drawTimeLine(QPainter &p, + const QTime &fromTime, const QTime &toTime, + int x, int y, int width, int height) +{ + p.drawRect(x, y, width, height); + + int totalsecs=fromTime.secsTo(toTime); + float minlen=(float)height*60./(float)totalsecs; + float cellHeight=(60.*(float)minlen); + float currY=y; + + QTime curTime( fromTime ); + QTime endTime( toTime ); + if ( fromTime.minute() > 30 ) + curTime = QTime( fromTime.hour()+1, 0, 0 ); + else if ( fromTime.minute() > 0 ) { + curTime = QTime( fromTime.hour(), 30, 0 ); + float yy = currY + minlen*(float)fromTime.secsTo( curTime )/60.; + p.drawLine( x+width/2, (int)yy, x+width, (int)yy ); + curTime = QTime( fromTime.hour()+1, 0, 0 ); + } + currY += ( fromTime.secsTo(curTime)*minlen/60 ); + + while ( curTime < endTime ) { + p.drawLine( x, (int)currY, x+width, (int)currY ); + int newY=(int)(currY+cellHeight/2.); + QString numStr; + if (newY < y+height) { + p.drawLine(x+width/2, (int)newY, x+width, (int)newY); + // draw the time: + if ( !KGlobal::locale()->use12Clock() ) { + numStr.setNum(curTime.hour()); + if (cellHeight > 30) { + p.setFont(QFont("helvetica", 16, QFont::Bold)); + } else { + p.setFont(QFont("helvetica", 12, QFont::Bold)); + } + p.drawText(x+2, (int)currY+2, width/2-2, (int)cellHeight, + AlignTop|AlignRight, numStr); + p.setFont(QFont("helvetica", 10, QFont::Normal)); + p.drawText(x+width/2, (int)currY+2, width/2+2, (int)(cellHeight/2)-3, + AlignTop | AlignLeft, "00"); + } else { + QTime time( curTime.hour(), 0 ); + numStr = KGlobal::locale()->formatTime( time ); + p.setFont(QFont("helvetica", 14, QFont::Bold)); + p.drawText(x+2, (int)currY+2, width-4, (int)cellHeight/2-3, + AlignTop|AlignLeft, numStr); + } + currY+=cellHeight; + } // enough space for half-hour line and time + if (curTime.secsTo(endTime)>3600) + curTime=curTime.addSecs(3600); + else curTime=endTime; + } // currTime<endTime +} + + +/////////////////////////////////////////////////////////////////////////////// + +/** prints the all-day box for the agenda print view. if expandable is set, + height is the cell height of a single cell, and the returned height will + be the total height used for the all-day events. If !expandable, only one + cell will be used, and multiple events are concatenated using ", ". +*/ +void CalPrintBase::drawAllDayBox(QPainter &p, Event::List &eventList, + const QDate &qd, bool expandable, + int x, int y, int width, int &height) +{ + Event::List::Iterator it, itold; + + int offset=y; + + //p.setBrush(QBrush(Dense7Pattern)); + QPen oldPen(p.pen()); + QColor oldBgColor(p.backgroundColor()); + QBrush oldBrush(p.brush()); + QString multiDayStr; + + it = eventList.begin(); +#ifndef KORG_NOPLUGINS + QString hstring(KOCore::self()->holiday(qd)); + if (!hstring.isEmpty()) { + Event*holiday=new Event(); + holiday->setDtStart(qd); + holiday->setDtEnd(qd); + holiday->setFloats(true); + holiday->setCategories(i18n("Holiday")); + eventList.prepend(holiday); + } +#endif + Event *currEvent = 0; + // First, print all floating events + while( it!=eventList.end() ) { + currEvent=*it; + itold=it; + ++it; + if ( currEvent->doesFloat() ) { + // set the colors according to the categories + QString text = currEvent->summary() ; + if ( ! currEvent->location().isEmpty() ) + text += " ("+currEvent->location()+")"; + if (expandable) { + if (mUseColors) + setCategoryColors(p, currEvent); + + p.drawRect( x, offset, width, height ); + + p.drawText( x+5, offset+5, width-10, height-10, + AlignCenter | AlignVCenter | AlignJustify | WordBreak, + text ); + // reset the colors + p.setBrush( oldBrush ); + p.setPen( oldPen ); + p.setBackgroundColor(oldBgColor); + + offset += height; + } else { + //if (!multiDayStr.isEmpty()) multiDayStr+=", "; + multiDayStr += text+"\n"; + } + eventList.remove( itold ); + } + } + + if (!expandable) { + p.drawRect(x, offset, width, height); + if (!multiDayStr.isEmpty()) { + // p.fillRect(x+1, offset+1, width-2, height-2, QBrush(Dense5Pattern) ); + p.drawText( x+5, offset+5, width-10, height-10, + AlignLeft | AlignTop | AlignJustify , + multiDayStr); + } + } else { + height=offset-y; + } +} + + +void CalPrintBase::drawAgendaDayBox( QPainter &p, Event::List &events, + const QDate &qd, bool expandable, + QTime &fromTime, QTime &toTime, + int x, int y, int width, int height ) +{ + p.drawRect( x, y, width, height ); + + Event *event; + + if ( expandable ) { + // Adapt start/end times to include complete events + Event::List::ConstIterator it; + for ( it = events.begin(); it != events.end(); ++it ) { + event = *it; + if ( event->dtStart().time() < fromTime ) + fromTime = event->dtStart().time(); + if ( event->dtEnd().time() > toTime ) + toTime = event->dtEnd().time(); + } + } + + // Show at least one hour + if ( fromTime.secsTo( toTime ) < 3600 ) { + fromTime = QTime( fromTime.hour(), 0, 0 ); + toTime = fromTime.addSecs( 3600 ); + } + + // calculate the height of a cell and of a minute + int totalsecs = fromTime.secsTo( toTime ); + float minlen = height * 60. / totalsecs; + float cellHeight = 60. * minlen; + float currY = y; + + // print grid: + QTime curTime( QTime( fromTime.hour(), 0, 0 ) ); + currY += fromTime.secsTo( curTime ) * minlen / 60; + + while ( curTime < toTime && curTime.isValid() ) { + if ( currY > y ) p.drawLine( x, int( currY ), x + width, int( currY ) ); + currY += cellHeight / 2; + if ( ( currY > y ) && ( currY < y + height ) ) { + QPen oldPen( p.pen() ); + p.setPen( QColor( 192, 192, 192 ) ); + p.drawLine( x, int( currY ), x + width, int( currY ) ); + p.setPen( oldPen ); + } // enough space for half-hour line + if ( curTime.secsTo( toTime ) > 3600 ) + curTime = curTime.addSecs( 3600 ); + else curTime = toTime; + currY += cellHeight / 2; + } + + QDateTime startPrintDate = QDateTime( qd, fromTime ); + QDateTime endPrintDate = QDateTime( qd, toTime ); + + // Calculate horizontal positions and widths of events taking into account + // overlapping events + + QPtrList<KOrg::CellItem> cells; + cells.setAutoDelete( true ); + + Event::List::ConstIterator itEvents; + for( itEvents = events.begin(); itEvents != events.end(); ++itEvents ) { + cells.append( new PrintCellItem( *itEvents, qd ) ); + } + + QPtrListIterator<KOrg::CellItem> it1( cells ); + for( it1.toFirst(); it1.current(); ++it1 ) { + KOrg::CellItem *placeItem = it1.current(); + + KOrg::CellItem::placeItem( cells, placeItem ); + } + + QPen oldPen = p.pen(); + QColor oldBgColor = p.backgroundColor(); + QBrush oldBrush = p.brush(); + + p.setFont( QFont( "helvetica", 10 ) ); + //p.setBrush( QBrush( Dense7Pattern ) ); + + for( it1.toFirst(); it1.current(); ++it1 ) { + PrintCellItem *placeItem = static_cast<PrintCellItem *>( it1.current() ); + + drawAgendaItem( placeItem, p, qd, startPrintDate, endPrintDate, minlen, x, + y, width ); + + p.setBrush( oldBrush ); + p.setPen( oldPen ); + p.setBackgroundColor( oldBgColor ); + } + + p.setBrush( QBrush( NoBrush ) ); +} + + +void CalPrintBase::drawAgendaItem( PrintCellItem *item, QPainter &p, + const QDate &qd, + const QDateTime &startPrintDate, + const QDateTime &endPrintDate, + float minlen, int x, int y, int width ) +{ + Event *event = item->event(); + + // set the colors according to the categories + if ( mUseColors ) setCategoryColors( p, event ); + else p.setBrush( Qt::white ); + // start/end of print area for event + QDateTime startTime = event->dtStart(); + QDateTime endTime = event->dtEnd(); + if ( event->doesRecur() ) { + startTime.setDate( qd ); + endTime.setDate( qd ); + } + if ( ( startTime < endPrintDate && endTime > startPrintDate ) || + ( endTime > startPrintDate && startTime < endPrintDate ) ) { + if ( startTime < startPrintDate ) startTime = startPrintDate; + if ( endTime > endPrintDate ) endTime = endPrintDate; + int eventLength = int( startTime.secsTo( endTime ) / 60. * minlen ); + int currentyPos = int( y + startPrintDate.secsTo( startTime ) * + minlen / 60. ); + int currentWidth = width / item->subCells(); + int currentX = x + item->subCell() * currentWidth; + QString text = KGlobal::locale()->formatTime(event->dtStart().time())+ + "-"+KGlobal::locale()->formatTime(event->dtEnd().time())+ + " "+event->summary(); + if ( !event->location().isEmpty() ) + text += " (" +event->location()+")"; + // p.save(); + QPen pe = p.pen(); + pe.setWidth( 2 ); + p.setPen( pe ); + p.drawRect( currentX, currentyPos+1, currentWidth+1, eventLength+1 ); + p.drawText( currentX+3, currentyPos+2, currentWidth-5, eventLength-3, + AlignLeft | AlignTop | AlignJustify | WordBreak, + text); + // p.restore(); + } +} + +void CalPrintBase::drawDayBox(QPainter &p, const QDate &qd, + int x, int y, int width, int height, + bool fullDate) +{ + QString dayNumStr; + QString ampm; + const KLocale*local = KGlobal::locale(); + + + // This has to be localized + if (fullDate) { + /*int index; + dayNumStr= qd.toString(); + index = dayNumStr.find(' '); + dayNumStr.remove(0, index); + index = dayNumStr.findRev(' '); + dayNumStr.truncate(index);*/ + + const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem(); + dayNumStr = i18n("weekday month date", "%1 %2 %3") + .arg( calSys->weekDayName( qd ) ) + .arg( calSys->monthName( qd ) ) + .arg( qd.day() ); +// dayNumStr = local->formatDate(qd); + } else { + dayNumStr = QString::number( qd.day() ); + } + + p.eraseRect( x, y, width, height ); + p.drawRect( x, y, width, height ); + // p.fillRect( x+1, y+1, width-2,height, QBrush(Dense7Pattern) ); + p.drawRect( x, y, width, mSubHeaderHeight ); + //p.fillRect( x+1, y+1, width-2, mSubHeaderHeight-2, QBrush(Dense7Pattern) ); + QString hstring; +#ifndef KORG_NOPLUGINS + hstring=KOCore::self()->holiday(qd); +#endif + + if (!hstring.isEmpty()) { + p.setFont( QFont( "helvetica", 8, QFont::Bold, true ) ); + + p.drawText( x+5, y, width-25, mSubHeaderHeight, AlignLeft | AlignVCenter, + hstring ); + } + p.setFont(QFont("helvetica", 10, QFont::Bold)); + p.drawText(x+5, y, width-10, mSubHeaderHeight, AlignRight | AlignVCenter, + dayNumStr); + Event::List eventList; + eventList.fill( mCalendar->events( qd, true )); + Todo::List todos; + todos.fill( mCalendar->todos( qd )); + QString outStr; + p.setFont( QFont( "helvetica", 8 ) ); + int lineSpacing = p.fontMetrics().lineSpacing(); + + int textY=mSubHeaderHeight+3; // gives the relative y-coord of the next printed entry + Event::List::ConstIterator it; + int entryCount = eventList.count() +todos.count(); + if ( p.fontMetrics().lineSpacing()* entryCount > height-textY ) { + if ( (p.fontMetrics().lineSpacing()-1) * entryCount > height-textY ) { + p.setFont( QFont( "helvetica", 7 ) ); + if ( (p.fontMetrics().lineSpacing()-1) * entryCount > height-textY ) + p.setFont( QFont( "helvetica", 6 ) ); + } + lineSpacing = p.fontMetrics().lineSpacing()-1; + } + // qDebug("fm %d %d %d ",p.fontMetrics().height(), eventList.count() , height-textY ); + for( it = eventList.begin(); it != eventList.end() && textY<height; ++it ) { + Event *currEvent = *it; + if (currEvent->doesFloat() || currEvent->isMultiDay()) + outStr = currEvent->summary(); + + else { + if ( fullDate ) { + outStr = KGlobal::locale()->formatTime( currEvent->dtStart().time())+ + "-"+KGlobal::locale()->formatTime( currEvent->dtEnd().time())+ + " "+ currEvent->summary(); + if ( ! currEvent->location().isEmpty() ) + outStr += " (" + currEvent->location()+")"; + } else { + QTime t1 = currEvent->dtStart().time(); + + outStr = local->formatTime(t1); + outStr += " " + currEvent->summary(); + } + + } // doesFloat + + p.drawText(x+5, y+textY, width-10, lineSpacing, + AlignLeft|AlignBottom, outStr); + textY+=lineSpacing; + } + + if ( textY<height ) { + + Todo::List::ConstIterator it2; + for( it2 = todos.begin(); it2 != todos.end() && textY<height; ++it2 ) { + Todo *todo = *it2; + QString text; + if (todo->hasDueDate()) { + if (!todo->doesFloat()) { + text += KGlobal::locale()->formatTime(todo->dtDue().time()); + text += " "; + } + } + text += i18n("To-Do: %1").arg(todo->summary()); + + p.drawText(x+5, y+textY, width-10, lineSpacing, + AlignLeft|AlignBottom, text); + textY+=lineSpacing; + } + } +} + + +/////////////////////////////////////////////////////////////////////////////// + +void CalPrintBase::drawWeek(QPainter &p, const QDate &qd, + int x, int y, int width, int height) +{ + QDate weekDate = qd; + bool portrait = ( mPrinter->orientation() == KPrinter::Portrait ); + int cellWidth, cellHeight; + int vcells; + if (portrait) { + cellWidth = width/2; + vcells=3; + } else { + cellWidth = width/6; + vcells=1; + } + cellHeight = height/vcells; + + // correct begin of week + int weekdayCol = weekdayColumn( qd.dayOfWeek() ); + weekDate = qd.addDays( -weekdayCol ); + + for (int i = 0; i < 7; i++, weekDate = weekDate.addDays(1)) { + if (i<5) { + drawDayBox(p, weekDate, x+cellWidth*(int)(i/vcells), y+cellHeight*(i%vcells), + cellWidth, cellHeight, true); + } else if (i==5) { + drawDayBox(p, weekDate, x+cellWidth*(int)(i/vcells), y+cellHeight*(i%vcells), + cellWidth, cellHeight/2, true); + } else if (i==6) { + drawDayBox(p, weekDate, x+cellWidth*(int)((i-1)/vcells), + y+cellHeight*((i-1)%vcells)+cellHeight/2, cellWidth, cellHeight/2, true); + } + } // for i through all weekdays +} + + +void CalPrintBase::drawTimeTable(QPainter &p, + const QDate &fromDate, const QDate &toDate, + QTime &fromTime, QTime &toTime, + int x, int y, int width, int height) +{ + // timeline is 1.5 hours: + int alldayHeight = (int)( 3600.*height/(fromTime.secsTo(toTime)+3600.) ); + int timelineWidth = 60; + int cellWidth = (int)( (width-timelineWidth)/(fromDate.daysTo(toDate)+1) ); + int currY=y; + int currX=x; + + drawDaysOfWeek( p, fromDate, toDate, x+timelineWidth, currY, width-timelineWidth, mSubHeaderHeight); + currY+=mSubHeaderHeight; + drawTimeLine( p, fromTime, toTime, x, currY+alldayHeight, + timelineWidth, height-mSubHeaderHeight-alldayHeight ); + + currX=x+timelineWidth; + // draw each day + QDate curDate(fromDate); + while (curDate<=toDate) {Event::List eventList; + eventList.fill( mCalendar->events(curDate, true)); + drawAllDayBox( p, eventList, curDate, false, currX, currY, cellWidth, alldayHeight); + drawAgendaDayBox( p, eventList, curDate, false, fromTime, toTime, currX, + currY+alldayHeight, cellWidth, height-mSubHeaderHeight-alldayHeight ); + currX+=cellWidth; + curDate=curDate.addDays(1); + } + +} + + +/////////////////////////////////////////////////////////////////////////////// + +void CalPrintBase::drawMonth(QPainter &p, const QDate &qd, bool weeknumbers, + int x, int y, int width, int height) +{ + + int yoffset = mSubHeaderHeight; + int xoffset = 0; + + QDate monthDate(QDate(qd.year(), qd.month(), 1)); + QDate monthFirst(monthDate); + QDate monthLast(monthDate.addMonths(1).addDays(-1)); + + + int weekdayCol = weekdayColumn( monthDate.dayOfWeek() ); + monthDate = monthDate.addDays(-weekdayCol); + + int rows=(weekdayCol + qd.daysInMonth() - 1)/7 +1; + int cellHeight = (height-yoffset) / rows; + + if (weeknumbers) { + QFont oldFont(p.font()); + QFont newFont(p.font()); + newFont.setPointSize(7); + p.setFont(newFont); + xoffset += 18; + QDate weekDate(monthDate); + for (int row = 0; row<rows; row++) { + int calWeek = weekDate.weekNumber(); + QRect rc(x, y+yoffset+cellHeight*row, xoffset-1, cellHeight); + p.drawText( rc, AlignRight|AlignVCenter, QString::number(calWeek) ); + weekDate = weekDate.addDays(7); + } + p.setFont(oldFont); + } + + drawDaysOfWeek( p, monthDate, monthDate.addDays(6), x+xoffset, y, width-xoffset, mSubHeaderHeight ); + int cellWidth = (width-xoffset) / 7; + + QColor back = p.backgroundColor(); + bool darkbg = false; + for (int row = 0; row < rows; row++) { + for (int col = 0; col < 7; col++) { + // show days from previous/next month with a grayed background + if ( (monthDate < monthFirst) || (monthDate > monthLast) ) { + p.setBackgroundColor( QColor( 240, 240, 240) ); + darkbg = true; + } + drawDayBox(p, monthDate, x+xoffset+col*cellWidth, y+yoffset+row*cellHeight, cellWidth, cellHeight); + if ( darkbg ) { + p.setBackgroundColor( back ); + darkbg = false; + } + monthDate = monthDate.addDays(1); + } + } +} + + +/////////////////////////////////////////////////////////////////////////////// + +void CalPrintBase::drawTodo( bool completed, int &count, Todo * item, QPainter &p, bool connectSubTodos, + bool desc, int pospriority, int possummary, int posDueDt, int level, + int x, int &y, int width, int &height, int pageHeight, + TodoParentStart *r ) +{ + if ( !completed && item->isCompleted() ) + return; + QString outStr; +// int fontHeight = 10; + const KLocale *local = KGlobal::locale(); + int priority=item->priority(); + int posdue=posDueDt; + if (posdue<0) posdue=x+width; + QRect rect; + TodoParentStart startpt; + // This list keeps all starting points of the parent todos so the connection + // lines of the tree can easily be drawn (needed if a new page is started) + static QPtrList<TodoParentStart> startPoints; + if (level<1) { + startPoints.clear(); + } + + // size of item + outStr=item->summary(); + if ( ! item->location().isEmpty() ) + outStr += " ("+item->location()+")"; + if ( item->hasDueDate() && posDueDt>=0 ) { + outStr += " [" +local->formatDate(item->dtDue().date(),true)+"]"; + } + int left = possummary+(level*10); + rect = p.boundingRect(left, y, (posdue-left-5),-1, WordBreak, outStr); + if ( !item->description().isEmpty() && !desc ) { + outStr = item->description(); + rect = p.boundingRect( left+20, rect.bottom()+5, width-(left+10-x), -1, + WordBreak, outStr ); + } + // if too big make new page + if ( rect.bottom() > y+height) { + // first draw the connection lines from parent todos: + if (level > 0 && connectSubTodos) { + TodoParentStart *rct; + for ( rct = startPoints.first(); rct; rct = startPoints.next() ) { + int start; + int center = rct->mRect.left() + (rct->mRect.width()/2); + int to = p.viewport().bottom(); + + // draw either from start point of parent or from top of the page + if (rct->mSamePage) + start = rct->mRect.bottom() + 1; + else + start = p.viewport().top(); + p.moveTo( center, start ); + p.lineTo( center, to ); + rct->mSamePage=false; + } + } + y=0; + height=pageHeight-y; + mPrinter->newPage(); + } + + // If this is a sub-item, r will not be 0, and we want the LH side of the priority line up + //to the RH side of the parent item's priority + if (r && pospriority >= 0 ) { + pospriority = r->mRect.right() + 1; + } + + // Priority + outStr.setNum(priority); + rect = p.boundingRect(pospriority, y + 10, 5, -1, AlignCenter, outStr); + // Make it a more reasonable size + rect.setWidth(19); + rect.setHeight(19); + if ( priority > 0 && pospriority>=0 ) { + p.drawText(rect, AlignCenter, outStr); + p.drawRect(rect); + // cross out the rectangle for completed items + if ( item->isCompleted() ) { + p.drawLine( rect.topLeft(), rect.bottomRight() ); + p.drawLine( rect.topRight(), rect.bottomLeft() ); + } + } + startpt.mRect = rect; //save for later + + // Connect the dots + if (level > 0 && connectSubTodos) { + int bottom; + int center( r->mRect.left() + (r->mRect.width()/2)+1 ); + if (r->mSamePage ) + bottom = r->mRect.bottom();//lutz + 1; + else + bottom = 0; + int to( rect.top() + (rect.height()/2)+1 ); + int endx( rect.left() ); + p.moveTo(center, bottom); + p.lineTo(center, to); + p.lineTo(endx, to); + } + + // if completed, use strike out font + QFont ft=p.font(); + ft.setStrikeOut( item->isCompleted() ); + p.setFont( ft ); + // summary + outStr=item->summary(); + if ( ! item->location().isEmpty() ) + outStr += " ("+item->location()+")"; + if ( item->hasDueDate() && posDueDt>=0 ) { + outStr += " [" +local->formatDate(item->dtDue().date(),true)+"]"; + } + rect = p.boundingRect( left, rect.top(), (posdue-(left + rect.width() + 5)), + -1, WordBreak, outStr); + QRect newrect; + p.drawText( rect, WordBreak, outStr, -1, &newrect ); + ft.setStrikeOut(false); + p.setFont(ft); + + // due + // if ( item->hasDueDate() && posDueDt>=0 ) { +// outStr = local->formatDate(item->dtDue().date(),true); +// rect = p.boundingRect(posdue, y, x+width, -1, AlignTop|AlignLeft, outStr); +// p.drawText(rect, AlignTop|AlignLeft, outStr); +// } + + if ( !item->description().isEmpty() && desc ) { + y=newrect.bottom() + 5; + outStr = item->description(); + rect = p.boundingRect( left+20, y, x+width-(left+10), -1, + WordBreak, outStr ); + p.drawText( rect, WordBreak, outStr, -1, &newrect ); + } + + // Set the new line position + y=newrect.bottom() + 10; //set the line position + + // If the item has subitems, we need to call ourselves recursively + Incidence::List l;l.fill( item->relations()); + Incidence::List::ConstIterator it; + startPoints.append( &startpt ); + for( it = l.begin(); it != l.end(); ++it ) { + count++; + drawTodo( completed, count, static_cast<Todo *>( *it ), p, connectSubTodos, + desc, pospriority, possummary, posDueDt, level+1, + x, y, width, height, pageHeight, &startpt); + } + startPoints.remove(&startpt); +} + +int CalPrintBase::weekdayColumn( int weekday ) +{ + return ( weekday + 7 - KGlobal::locale()->weekStartDay() ) % 7; +} + +void CalPrintBase::drawSplitWeek( QPainter &p, const QDate &fd, + const QDate &td ) +{ + QDate curDay, fromDay, toDay, curWeek, fromWeek, toWeek; + + mPrinter->setOrientation(KPrinter::Portrait); + + int minus = 0; + if (KGlobal::locale()->weekStartsMonday()) { + // correct to monday + fromWeek = fd.addDays(-(fd.dayOfWeek()-1)); + // correct to sunday + toWeek = td.addDays(7-fd.dayOfWeek()); + minus = 1; + } else { + // correct to sunday + fromWeek = fd.addDays(-(fd.dayOfWeek()%7)); + // correct to saturday + toWeek = td.addDays(6-td.dayOfWeek()); + } + + fromDay = fd; + curDay = fd; + toDay = td; + p.setFont( QFont("Helvetica") ); + // the painter initially begins at 72 dpi per the Qt docs. + int pageWidth = p.viewport().width(); + int pageHeight = p.viewport().height(); + int margin=0; + mHeaderHeight = 110; + mSubHeaderHeight = 20; + + p.setViewport(margin, margin, + p.viewport().width()-margin, + p.viewport().height()-margin); + + curWeek = fromWeek.addDays(6); + + int columnWidth = int( pageWidth / 4.5 ); + + do { + + // if ( (curDay.dayOfWeek()-1)%7 < 3 ) + switch((curDay.dayOfWeek()-minus)%7){ + case 0: + drawSplitTimes( p, pageWidth, columnWidth, pageHeight ); + drawSplitDay( p, curDay, columnWidth, pageHeight, + int( columnWidth * 0.5 ) ); + break; + case 1: + drawSplitDay( p, curDay, columnWidth, pageHeight, + int( columnWidth * 1.5 ) ); + break; + case 2: + drawSplitDay( p, curDay, columnWidth, pageHeight, + int( columnWidth * 2.5 ) ); + break; + case 3: + drawSplitDay( p, curDay, columnWidth, pageHeight, + int( columnWidth * 3.5 ) ); + mPrinter->newPage(); + break; + case 4: + drawSplitTimes( p, int( pageWidth * ( 3.5/ 4.5 ) ), columnWidth, + pageHeight ); + drawSplitDay( p, curDay, columnWidth, pageHeight, + int( columnWidth * 0.5 ) ); + drawSplitHeaderRight( p, curWeek.addDays( -6 ), curWeek, + curWeek, pageWidth, mHeaderHeight ); + break; + case 5: + drawSplitDay( p, curDay, columnWidth, pageHeight, + int( columnWidth * 1.5 ) ); + break; + case 6: + drawSplitDay( p, curDay, columnWidth, pageHeight, + int( columnWidth * 2.5 ) ); + if ( curDay < toDay ) + mPrinter->newPage(); + curWeek = curWeek.addDays( 7 ); + break; + } + curDay = curDay.addDays(1); + + } while (curDay <= toDay); + +} + +void CalPrintBase::drawSplitHeaderRight( QPainter &p, const QDate &fd, + const QDate &td, + const QDate &, + int width, int ) +{ + int tempStore = mSubHeaderHeight; + mSubHeaderHeight+= mSubHeaderHeight; + KLocale *local = KGlobal::locale(); + QFont font("helvetica", 18, QFont::Bold); + QPen penA( black,0); + QPen penB( black,3); + p.setFont(font); + int lineSpacing = p.fontMetrics().lineSpacing(); + QString title; + QString myOwner(mCalendar->getOwner()); + if ( fd.month() == td.month() ) { + title = local->monthName(fd.month(), false) + ' ' + QString::number(fd.day()) + ' ' + + '-' + ' ' + QString::number(td.day()); + } else { + title = local->monthName(fd.month(), false) + ' ' + QString::number(fd.day()) + ' ' + + '-' + ' ' + local->monthName(td.month(), false) + ' ' + QString::number(td.day()); + } + +// Grrrrrrr! why can't I set the font to a serif font?!?!? + QFont serifFont("Helvetica", 30); +// serifFont.setFamily("Serif"); +// serifFont.setWeight(87); +// serifFont.setItalic(true); + p.setFont(serifFont); + QFontInfo info(p.font()); + + lineSpacing = p.fontMetrics().lineSpacing(); + p.drawText(0, lineSpacing * 0, width, lineSpacing, AlignRight |AlignTop, title ); + + title.truncate(0); + + p.setPen(penB ); + p.drawLine(200, lineSpacing * 1, width, lineSpacing * 1); + p.setPen(penA ); + + p.setFont(QFont("Helvetica", 20, QFont::Bold, TRUE)); + title += QString::number(fd.year()); + p.drawText(0, lineSpacing * 1, width, lineSpacing, AlignRight |AlignTop, title ); + mSubHeaderHeight = tempStore ; +} + +void CalPrintBase::drawSplitDay( QPainter &p, const QDate &qd, int width, + int height, int offsetLeft ) +{ + int tempStore = mSubHeaderHeight; + mSubHeaderHeight+= mSubHeaderHeight; + int startHour = KOPrefs::instance()->mDayBegins; + int endHour = 20; + int offset = mHeaderHeight + mSubHeaderHeight + 10; + Event::List eventList; eventList.fill( mCalendar->events( qd, true )); + Event::List::Iterator it; + Event *currEvent; + KLocale *local = KGlobal::locale(); + QString dayName; + + dayName = local->weekDayName(qd.dayOfWeek()) + ' ' + ' ' + QString::number(qd.day()); + //p.setBrush(QBrush(black)); +// width+1 to make sure there's a continuous, black bar across the top. + p.setPen( QPen(Qt::black,2)); + p.drawRect(offsetLeft, mHeaderHeight + 5, width +1, mSubHeaderHeight); + p.setPen( Qt::black); + p.setFont(QFont("helvetica", 12, QFont::Bold, true)); + p.drawText(offsetLeft, mHeaderHeight + 5, + width, mSubHeaderHeight, AlignHCenter | AlignVCenter, + dayName); + + p.setPen( QPen(Qt::black,2)); + p.setFont(QFont("helvetica", 12)); + p.setBrush(Qt::white); + it = eventList.begin(); + int allDays = 0; + /* + while( it != eventList.end() ) { + Event *currEvent = *it; + if ( currEvent->doesFloat() ) { + p.drawRect( offsetLeft, offset, width, 35 ); + p.drawText( offsetLeft + 5, offset + 10, width - 10, 30, + AlignLeft | AlignTop, currEvent->summary() ); + offset += 40; + allDays++; + it = eventList.remove( it ); + } else { + ++it; + } + } + */ + //p.setBrush(QBrush()); + int tmpEnd; + for ( it = eventList.begin(); it != eventList.end(); ++it ) { + Event *currEvent = *it; + tmpEnd = currEvent->dtEnd().time().hour(); + if (currEvent->dtEnd().time().minute() > 0) + tmpEnd++; + if (tmpEnd > endHour) + endHour = tmpEnd; + } + int hours = endHour - startHour; + int cellHeight = (height-offset) / hours; // hour increments. + + p.setFont(QFont("helvetica", 12)); + //p.setBrush(QBrush(Dense7Pattern)); + p.setBrush(Qt::white); + for ( it = eventList.begin(); it != eventList.end(); ++it ) { + Event *currEvent = *it; + int startTime = currEvent->dtStart().time().hour(); + int endTime = currEvent->dtEnd().time().hour(); + float minuteInc = cellHeight / 60.0; + if ((startTime >= startHour) && (endTime <= (startHour + hours))) { + startTime -= startHour; + int startMinuteOff = (int) (minuteInc * + currEvent->dtStart().time().minute()); + QString text = currEvent->summary() ; + if ( ! currEvent->location().isEmpty() ) + text += "\n("+currEvent->location()+")"; + int endMinuteOff = (int) (minuteInc * currEvent->dtEnd().time().minute()); + int cheight = (int) (minuteInc * + currEvent->dtStart().secsTo(currEvent->dtEnd()) / 60 ); + p.drawRect(offsetLeft+2, 1+offset+startMinuteOff+startTime*cellHeight, + width-4, cheight); + p.drawText(offsetLeft+12, offset+startMinuteOff+startTime*cellHeight+5, width-24, + cheight-10, AlignHCenter | AlignTop, text); + } + } + p.setBrush(QBrush(NoBrush)); + mSubHeaderHeight = tempStore ; +} + +void CalPrintBase::drawSplitTimes( QPainter &p, int width, int timeWidth, + int height ) +{ + int tempStore = mSubHeaderHeight; + mSubHeaderHeight+= mSubHeaderHeight; + int startHour = KOPrefs::instance()->mDayBegins; + int endHour = 20; + int offset = mHeaderHeight + mSubHeaderHeight + 10; + int hours = endHour - startHour; + int cellHeight = (height-offset) / hours; // hour increments. + + QString numStr; + for (int i = 0; i < hours; i++) { + p.setPen(QPen(black,1)); + p.drawLine(0, offset+i*cellHeight, width, offset+i*cellHeight); + p.setPen(QPen(gray,0)); + p.drawLine(37, offset+i*cellHeight+(cellHeight/2), + width, offset+i*cellHeight+(cellHeight/2)); + p.setPen(QPen(black,0)); + + if ( !KGlobal::locale()->use12Clock() ) { + numStr.setNum(i+startHour); + if (cellHeight > 40) { + p.setFont(QFont("helvetica", 16, QFont::Bold)); + } else { + p.setFont(QFont("helvetica", 14, QFont::Bold)); + } + p.drawText(0, offset+i*cellHeight, 33, cellHeight/2, + AlignTop|AlignRight, numStr); + p.setFont(QFont("helvetica", 12, QFont::Bold)); + p.drawText(37, offset+i*cellHeight, 45, cellHeight/2, + AlignTop | AlignLeft, "00"); + } else { + QTime time( i + startHour, 0 ); + numStr = KGlobal::locale()->formatTime( time ); + p.setFont(QFont("helvetica", 12, QFont::Bold)); + p.drawText(4, offset+i*cellHeight, 70, cellHeight/2, + AlignTop|AlignLeft, numStr); + } + } mSubHeaderHeight = tempStore ; +} + +#endif diff --git a/korganizer/calprintbase.h b/korganizer/calprintbase.h new file mode 100644 index 0000000..7409143 --- a/dev/null +++ b/korganizer/calprintbase.h @@ -0,0 +1,379 @@ +/* + This file is part of KOrganizer. + + Copyright (c) 1998 Preston Brown + Copyright (c) 2003 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., 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 CALPRINTBASE_H +#define CALPRINTBASE_H +// #define KORG_NOPRINTER + +#ifndef KORG_NOPRINTER + +#include <qwidget.h> +#include <qdatetime.h> +#include <kprinter.h> +#include <kconfig.h> +#include <libkcal/event.h> + +class PrintCellItem; + +namespace KCal { +class Calendar; +class Todo; +} + +using namespace KCal; + +/** + Base class for KOrganizer printing classes. Each sub class represents one + calendar print format. +*/ +class CalPrintBase : public QObject +{ + Q_OBJECT + public: + /** + Constructor + + \param pr KPrinter object used to print. + \param cal Calendar to be printed. + \param cfg KConfig object for reading/writing printing configuration + */ + CalPrintBase( KPrinter *pr, Calendar *cal, KConfig *cfg ); + virtual ~CalPrintBase(); + + /** + Returns short description of print format. + */ + virtual QString description() = 0; + /** + Returns long description of print format. + */ + virtual QString longDescription() = 0; + + /** + Returns widget for configuring the print format. + */ + virtual QWidget *configWidget( QWidget * ); + + /** + Actually do the printing. + + \param p QPainter the print result is painted to + \param width Width of printable area + \param height Height of printable area + */ + virtual void print( QPainter &p, int width, int height ) = 0; + /** + Start printing. + */ + virtual void doPrint(); + + /** + Orientation of printout. Default is Portrait. If your plugin wants + to use some other orientation as default (e.g. depending on some + config settings), implement this function in your subclass and + return the desired orientation. + */ + virtual KPrinter::Orientation orientation() { return KPrinter::Portrait; } + + /** + Load print format configuration from config file. + */ + virtual void loadConfig() = 0; + /** + Write print format configuration to config file. + */ + virtual void saveConfig() = 0; + + /** + Load complete config. This also calls loadConfig() of the derived class. + */ + void doLoadConfig(); + /** + Save complete config. This also calls saveConfig() of the derived class. + */ + void doSaveConfig(); + + + public slots: + /** + Read settings from configuration widget and apply them to current object. + */ + virtual void readSettingsWidget() {} + /** + Set configuration widget to reflect settings of current object. + */ + virtual void setSettingsWidget() {} + + /** + Set date range which should be printed. + */ + virtual void setDateRange( const QDate &from, const QDate &to ) + { + mFromDate = from; + mToDate = to; + } + + protected: + int weekdayColumn( int weekday ); + + QDate mFromDate; + QDate mToDate; + bool mUseColors; + + public: + /** + Internal class representing the start of a todo. + */ + class TodoParentStart; + + protected: + /** + Draw the gray header bar of the printout to the QPainter. + It prints the given text and optionally one or two small + month views, as specified by the two QDate. The printed + text can also contain a line feed. + If month2 is invalid, only the month that contains month1 + is printed. + E.g. the filofax week view draws just the current month, + while the month view draws the previous and the next month. + \param p QPainter of the printout + \param title The string printed as the title of the page + (e.g. the date, date range or todo list title) + \param month1 Date specifying the month for the left one of + the small month views in the title bar. If left + empty, only month2 will be printed (or none, + it that is invalid as well). + \param month2 Date specifying the month for the right one of + the small month views in the title bar. If left + empty, only month1 will be printed (or none, + it that is invalid as well). + \param x x-coordinate of the upper left coordinate of the title bar + \param y y-coordinate of the upper left coordinate of the title bar + \param width width of the title bar + \param height height of the title bar + */ + void drawHeader( QPainter &p, QString title, + const QDate &month1, const QDate &month2, + int x, int y, int width, int height ); + /** + Draw a small calendar with the days of a month into the given area. + Used for example in the title bar of the sheet. + \param p QPainter of the printout + \param qd Arbitrary Date within the month to be printed. + \param x x-coordinate of the upper left coordinate of the small calendar + \param y y-coordinate of the upper left coordinate of the small calendar + \param width width of the small calendar + \param height height of the small calendar + */ + void drawSmallMonth( QPainter &p, const QDate &qd, + int x, int y, int width, int height ); + + /** + Draw a horizontal bar with the weekday names of the given date range + in the given area of the painter. + This is used for the weekday-bar on top of the timetable view and the month view. + \param p QPainter of the printout + \param fromDate First date of the printed dates + \param toDate Last date of the printed dates + */ + void drawDaysOfWeek( QPainter &p, + const QDate &fromDate, const QDate &toDate, + int x, int y, int width, int height ); + /** + Draw a single weekday name in a box inside the given area of the painter. + This is called in a loop by drawDaysOfWeek. + \param p QPainter of the printout + \param qd Date of the printed day + */ + void drawDaysOfWeekBox( QPainter &p, const QDate &qd, + int x, int y, int width, int height ); + /** + Draw a (vertical) time scale from time fromTime to toTime inside the given area of the painter. + Every hour will have a one-pixel line over the whole width, every + half-hour the line will only span the left half of the width. + This is used in the day and timetable print styles + \param p QPainter of the printout + \param fromTime Start time of the time range to display + \param toTime End time of the time range to display + */ + void drawTimeLine( QPainter &p, + const QTime &fromTime, const QTime &toTime, + int x, int y, int width, int height ); + /** + Draw the all-day box for the agenda print view (the box on top which + doesn't have a time on the time scale associated). If expandable is set, + height is the cell height of a single cell, and the returned height will + be the total height used for the all-day events. If !expandable, only one + cell will be used, and multiple events are concatenated using ", ". + \param p QPainter of the printout + \param eventList The list of all-day events that are supposed to be printed + inside this box + \param qd The date of the currently printed day + \param expandable If true, height is the height of one single cell, the printout + will use as many cells as events in the list and return the total height + needed for all of them. If false, height specifies the total height + allowed for all events, and the events are displayed in one cell, + with their summaries concatenated by ", ". + */ + void drawAllDayBox( QPainter &p, Event::List &eventList, + const QDate &qd, bool expandable, + int x, int y, int width, int &height ); + /** + Draw the agenda box for the day print style (the box showing all events of that day). + Also draws a grid with half-hour spacing of the grid lines. + \param p QPainter of the printout + \param eventList The list of the events that are supposed to be printed + inside this box + \param qd The date of the currently printed day + \param expandable If true, the start and end times are adjusted to include + the whole range of all events of that day, not just of the given time range. + The height of the box will not be affected by this (but the height + of one hour will be scaled down so that the whole range fits into + the box. fromTime and toTime receive the actual time range printed + by this function). + \param fromTime Start of the time range to be printed. Might be adjusted + to include all events if expandable==true + \param toTime End of the time range to be printed. Might be adjusted + to include all events if expandable==true + */ + void drawAgendaDayBox( QPainter &p, Event::List &eventList, + const QDate &qd, bool expandable, + QTime &fromTime, QTime &toTime, + int x, int y, int width, int height); + + void drawAgendaItem( PrintCellItem *item, QPainter &p, const QDate &, + const QDateTime &startPrintDate, + const QDateTime &endPrintDate, + float minlen, int x, int y, int width ); + /** + Draw the box containing a list of all events of the given day (with their times, + of course). Used in the Filofax and the month print style. + \param p QPainter of the printout + \param qd The date of the currently printed day. All events of the calendar + that appear on that day will be printed. + \param fullDate Whether the title bar of the box should contain the full + date string or just a short. + */ + void drawDayBox( QPainter &p, const QDate &qd, + int x, int y, int width, int height, + bool fullDate = false ); + /** + Draw the week (filofax) table of the week containing the date qd. The first + three days of the week will be shown in the first column (using drawDayBox), + the remaining four in the second column, where the last two days of the week + (typically Saturday and Sunday) only get half the height of the other day boxes. + \param p QPainter of the printout + \param qd Arbitrary date within the week to be printed. + */ + void drawWeek( QPainter &p, const QDate &qd, + int x, int y, int width, int height ); + /** + Draw the timetable view of the given time range from fromDate to toDate. + On the left side the time scale is printed (using drawTimeLine), then each + day gets one column (printed using drawAgendaDayBox), + and the events are displayed as boxes (like in korganizer's day/week view). + The first cell of each column contains the all-day events (using + drawAllDayBox with expandable=false). + The given time range cannot be expanded to include all events. + \param p QPainter of the printout + \param fromDate First day to be included in the page + \param toDate Last day to be included in the page + \param fromTime Start time of the displayed time range + \param toTime End time of the displayed time range + */ + void drawTimeTable( QPainter &p, const QDate &fromDate, const QDate &toDate, + QTime &fromTime, QTime &toTime, + int x, int y, int width, int height ); + + /** + Draw the month table of the month containing the date qd. Each day gets one + box (using drawDayBox) that contains a list of all events on that day. They are arranged + in a matrix, with the first column being the first day of the + week (so it might display some days of the previous and the next month). + Above the matrix there is a bar showing the weekdays (drawn using drawDaysOfWeek). + \param p QPainter of the printout + \param qd Arbitrary date within the month to be printed. + \param weeknumbers Whether the week numbers are printed left of each row of the matrix + */ + void drawMonth( QPainter &p, const QDate &qd, bool weeknumbers, + int x, int y, int width, int height ); + + /** + Draws single todo item and its (intented) subitems, optionally connects them by a tree-like line, + and optionally shows due date, summary, description and priority. + \param count The number of the currently printed todo (count will be incremented for each drawn item) + \param item The item to be printed. It's subitems are recursively + drawn, so drawTodo should only be called on the + items of the highest level. + \param p QPainter of the printout + \param connectSubTodos Whether subtodos shall be connected with their parent by a line (tree-like). + \param desc Whether to print the whole description of the item (the summary is always printed). + \param pospriority x-coordinate where the priority is supposed to be printed. If <0, no priority will be printed. + \param possummary x-coordinate where the summary of the item is supposed to be printed. + \param posDueDt x-coordinate where the due date is supposed to the be printed. If <0, no due date will be printed. + \param level Level of the current item in the todo hierarchy (0 means highest + level of printed items, 1 are their subtodos, etc.) + \param x x-coordinate of the upper left coordinate of the first item + \param y y-coordinate of the upper left coordinate of the first item + \param width width of the whole todo list + \param height Space left on the first page of the todo list + \param pageHeight Total height allowed for the todo list on a page. The first page uses height, + but at each line break the current position is reset to 0 and the + height is set to pageHeight. + \param r Internal (used when printing sub items to give information about its parent) + */ + void drawTodo( bool completed, int &count, Todo * item, QPainter &p, bool connectSubTodos, + bool desc, int pospriority, int possummary, int posDueDt, + int level, int x, int &y, int width, int &height, + int pageHeight, TodoParentStart *r = 0 ); + + void drawSplitWeek( QPainter &p, const QDate &fd, const QDate &td ); + void drawSplitHeaderRight( QPainter &p, const QDate &fd, const QDate &td, + const QDate &cd, int width, int height ); + void drawSplitDay( QPainter &p, const QDate &qd, int width, int height, + int offsetLeft ); + void drawSplitTimes( QPainter &p, int width, int timeWidth, int height ); + + /** + Determines the column of the given weekday ( 1=Monday, 7=Sunday ), taking the + start of the week setting into account as given in kcontrol. + \param weekday Index of the weekday + */ + int weekDayColumn( int weekday ); + + KPrinter *mPrinter; + Calendar *mCalendar; + KConfig *mConfig; + //QWidget *mConfigWidget; + + protected: + // TODO_RK: move these to the appropriate subclasses or set them globally. + static int mSubHeaderHeight; + static int mHeaderHeight; + static int mMargin; +}; + +#endif + +#endif diff --git a/korganizer/calprintdayconfig_base.ui b/korganizer/calprintdayconfig_base.ui new file mode 100644 index 0000000..2625593 --- a/dev/null +++ b/korganizer/calprintdayconfig_base.ui @@ -0,0 +1,252 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>CalPrintDayConfig_Base</class> +<comment>Configuration page for the print day mode.</comment> +<author>Reinhold Kainhofer <reinhold@kainhofer.com></author> +<widget class="QWidget"> + <property name="name"> + <cstring>CalPrintDay_Base</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>407</width> + <height>175</height> + </rect> + </property> + <property name="caption"> + <string>CalPrintDay_Base</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>mDateRangeGroup</cstring> + </property> + <property name="title"> + <string>Date && Time Range</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="2"> + <property name="name"> + <cstring>mToDateLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&End date:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>mToDate</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>mFromDateLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Start date:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>mFromDate</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>mFromTimeLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Start &time:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>mFromTime</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="2"> + <property name="name"> + <cstring>mToTimeLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>End ti&me:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>mToTime</cstring> + </property> + </widget> + <widget class="QTimeEdit" row="1" column="1"> + <property name="name"> + <cstring>mFromTime</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>3</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="time"> + <time> + <hour>0</hour> + <minute>8</minute> + <second>0</second> + </time> + </property> + </widget> + <widget class="QTimeEdit" row="1" column="3"> + <property name="name"> + <cstring>mToTime</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>3</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="time"> + <time> + <hour>18</hour> + <minute>0</minute> + <second>0</second> + </time> + </property> + </widget> + <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>mIncludeAllEvents</cstring> + </property> + <property name="text"> + <string>E&xtend time range to include all events</string> + </property> + </widget> + <widget class="KDateEdit" row="0" column="3"> + <property name="name"> + <cstring>mToDate</cstring> + </property> + <property name="focusPolicy"> + <enum>StrongFocus</enum> + </property> + </widget> + <widget class="KDateEdit" row="0" column="1"> + <property name="name"> + <cstring>mFromDate</cstring> + </property> + <property name="focusPolicy"> + <enum>StrongFocus</enum> + </property> + </widget> + </grid> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>mIncludeTodos</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Include to&dos that are due on the printed day(s)</string> + </property> + <property name="accel"> + <string>Alt+D</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>mColors</cstring> + </property> + <property name="text"> + <string>&Use colors</string> + </property> + <property name="accel"> + <string>Alt+U</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>51</height> + </size> + </property> + </spacer> + </vbox> +</widget> +<customwidgets> + <customwidget> + <class>KDateEdit</class> + <header location="local">libkdepim/kdateedit.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="826">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000030149444154789cb59531681b5718c77f0e377c070e3c810a3a70e0041eac51852e0a19e45134830a1d9a4c69a04bc8928e990a693a640e1d0c8642b08742321894c1507991b484c890902bb8701a047760c3bd21701fe4201dde49b6a41a32b8df72dcbbeffdbefffbbfefbd5b1b0c07cce266ebe667ae2006c3c1dada0cdc3be87d6e6c35b0d692a409d9c7ec8b20d65ae29398d19b1114e7e3de4ce98b3f5e10dc0053cf0951b4506496e1b964bf7ce6c585d9054c62d01d617ca48be0596553cf496d8f2c8b01c5f795fc93904e85ec4c01a152857a5d9175d0b2805c872080f18595ccc1499a10a225d4e2fbc2877786fe81253ab6c04c8d106e09db5d43ab0d146e5c64d1a23938fb98a185cea1c33eecfd9eba49eb427dcb201e245365f2b7b2fb5b4a3a31dcb927178afe07d86901df870fefa4842aed6f6b74ba42e52b4014d580e1eb9cbd9d94de7e4aad16d2f9be02d805f0b5e532f927a1ffcacea1777f122a8105b164a7c25faf323a5d9f1f1fd600e1e5bec59e2d4b5c7ef5209d0ad17b8b31864e57c0b3e0815ac3ee33253ab664a770ff5185d1a1cb8d2267d3e58aa1dc7d2508cbe597d0e74fdd269aaaf0f52d414c4ea3e9762c996869e42560d7a72e41c4799a2586e74f95e8d8151481fa86efbe7b3398ac58b1a2b8527589f15451ad303ac2293542ad6648a796278f13a27185e4c4754310facb98c53a79e19a3fdc1426ff28c3d7399d1f7cb25343eb96106cf83c790ce9c4f2eb831855c55485663327992eb6dc8a6259874ed700b0b793323cccb9ffa842b30d6133e3e75fea989ac15a8b16ca76b746b0b92278d919774c5b6d48a78697fb29bbcf52468742a32120909c24e899ce67beed5be2db01e22d1e9485bb620e47f9ee9e606a21bd3f5d3744c7e7c54d55e87443867d8b554515ac5db4620e8e4f62263170fd1cdee90aad7640141992891b0f367c9adfe4049bb07d3b7022bd8c687c0978f46684ee084150b65ac1fcca94591b7a90a496e4c095164fb016a2b192a497795cc0f84817aebe25f7bf70ccc54a575c555c03f78ffa5fc0570d1f0c076bff0232285a0901e2257b0000000049454e44ae426082</data> + </image> +</images> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kdateedit.h</includehint> + <includehint>kdateedit.h</includehint> +</includehints> +</UI> diff --git a/korganizer/calprinter.cpp b/korganizer/calprinter.cpp new file mode 100644 index 0000000..6b5b0fe --- a/dev/null +++ b/korganizer/calprinter.cpp @@ -0,0 +1,299 @@ +/* + This file is part of KOrganizer. + Copyright (c) 1998 Preston Brown + + 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. +*/ + +#include <qvbuttongroup.h> +#include <qwidgetstack.h> +#include <qradiobutton.h> +#include <qlayout.h> +#include <qpushbutton.h> +#include <qcombobox.h> +#include <qlabel.h> +#include <qvbox.h> +#include <qsplitter.h> + +#include <kprinter.h> +#include <kglobal.h> +#include <ksimpleconfig.h> +#include <kmessagebox.h> +#include <kdebug.h> +//#include <kdeversion.h> + +#include "koprefsdialog.h" + +#include "calprinter.h" +#ifndef KORG_NOPRINTER +//#include "calprinter.moc" + +#include "calprintplugins.h" + +CalPrinter::CalPrinter( QWidget *parent, Calendar *calendar ) + : QObject( parent, "CalPrinter" ) +{ + mCalendar = calendar; + mParent = parent; + mPrinter = new KPrinter; + mPrinter->setOrientation( KPrinter::Portrait ); + mConfig = new KConfig(locateLocal("config","korganizer_printing.rc" )); + //KSimpleConfig( "korganizer_printing.rc" ); + + init( mPrinter, calendar ); +} + +CalPrinter::~CalPrinter() +{ + kdDebug() << "~CalPrinter()" << endl; + + CalPrintBase *plug = mPrintPlugins.first(); + while ( plug ) { + plug->doSaveConfig(); + plug = mPrintPlugins.next(); + } + mConfig->sync(); + delete mConfig; + delete mPrintDialog; + delete mPrinter; +} + +void CalPrinter::init( KPrinter *printer, Calendar *calendar ) +{ + mPrintPlugins.setAutoDelete( true ); + mPrintPlugins.append( new CalPrintDay( printer, calendar, mConfig ) ); + mPrintPlugins.append( new CalPrintWeek( printer, calendar, mConfig ) ); + mPrintPlugins.append( new CalPrintMonth( printer, calendar, mConfig ) ); + mPrintPlugins.append( new CalPrintTodos( printer, calendar, mConfig ) ); + + // TODO_RK: Add a plugin interface here + mPrintDialog = new CalPrintDialog( mPrintPlugins, mPrinter, mParent ); + + CalPrintBase *plug = mPrintPlugins.first(); + while ( plug ) { + connect( mPrintDialog, SIGNAL( okClicked() ), + plug, SLOT( readSettingsWidget() ) ); + + plug->doLoadConfig(); + + plug = mPrintPlugins.next(); + } +} + +void CalPrinter::setupPrinter() +{ + KMessageBox::sorry( mParent, i18n("Not implemented.") ); +#if 0 + KOPrefsDialog *optionsDlg = new KOPrefsDialog(mParent); + optionsDlg->readConfig(); + optionsDlg->showPrinterTab(); + connect(optionsDlg, SIGNAL(configChanged()), + mParent, SLOT(updateConfig())); + optionsDlg->show(); +#endif +} + +void CalPrinter::setDateRange( const QDate &fd, const QDate &td ) +{ + CalPrintBase *plug = mPrintPlugins.first(); + while ( plug ) { + plug->setDateRange( fd, td ); + plug = mPrintPlugins.next(); + } +} + +void CalPrinter::preview( PrintType type, const QDate &fd, const QDate &td ) +{ + mPrintDialog->setPreview( true ); + mPrintDialog->setPrintType( int( type ) ); + setDateRange( fd, td ); + + if ( mPrintDialog->exec() == QDialog::Accepted ) { + doPrint( mPrintDialog->selectedPlugin(), true ); + } +} + +void CalPrinter::print( PrintType type, const QDate &fd, const QDate &td ) +{ + mPrintDialog->resize( 640, 380 ); + mPrintDialog->setPreview( false ); + mPrintDialog->setPrintType( int( type ) ); + setDateRange( fd, td ); + + if ( mPrintDialog->exec() == QDialog::Accepted ) { + doPrint( mPrintDialog->selectedPlugin(), false ); + } +} + +void CalPrinter::doPrint( CalPrintBase *selectedStyle, bool preview ) +{ + // FIXME: add a better caption to the Printingdialog + //mPrinter->setPreviewOnly( preview ); + if ( preview || mPrinter->setup( mParent ) ) { + switch ( mPrintDialog->orientation() ) { + case eOrientPlugin: + mPrinter->setOrientation( selectedStyle->orientation()); + break; + case eOrientPortrait: + mPrinter->setOrientation( KPrinter::Portrait ); + break; + case eOrientLandscape: + mPrinter->setOrientation( KPrinter::Landscape ); + break; + case eOrientPrinter: + default: + break; + } + selectedStyle->doPrint(); + } + //mPrinter->setPreviewOnly( false ); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CalPrinter::updateConfig() +{ +} + + +/****************************************************************************/ + +CalPrintDialog::CalPrintDialog( QPtrList<CalPrintBase> plugins, KPrinter *p, + QWidget *parent, const char *name ) + : KDialogBase( parent, name, /*modal*/true, i18n("Print"), Ok | Cancel ), + mPrinter( p ), mPrintPlugins( plugins ) +{ + QVBox *page = new QVBox(this);//makeVBoxMainWidget(); + setMainWidget( page ); + QHBox *printerLayout = new QHBox( page ); + + mPrinterLabel = new QLabel( printerLayout ); + QPushButton *setupButton = new QPushButton( i18n("&Setup Printer..."), + printerLayout ); + setupButton->setSizePolicy( QSizePolicy( + (QSizePolicy::SizeType)4, (QSizePolicy::SizeType)0, + 0, 0, setupButton->sizePolicy().hasHeightForWidth() ) ); + + QSplitter *splitter = new QSplitter( page ); + splitter->setOrientation( QSplitter::Horizontal ); + + mTypeGroup = new QVButtonGroup( i18n("View Type"), splitter, "buttonGroup" ); + // use the minimal width possible = max width of the radio buttons, not extensible +/* mTypeGroup->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)4, + (QSizePolicy::SizeType)5, 0, 0, + mTypeGroup->sizePolicy().hasHeightForWidth() ) );*/ + + QWidget *splitterRight = new QWidget( splitter, "splitterRight" ); + QGridLayout *splitterRightLayout = new QGridLayout( splitterRight ); + splitterRightLayout->setMargin( marginHint() ); + splitterRightLayout->setSpacing( spacingHint() ); + + mConfigArea = new QWidgetStack( splitterRight, "configWidgetStack" ); + splitterRightLayout->addMultiCellWidget( mConfigArea, 0,0, 0,1 ); + + QLabel *orientationLabel = new QLabel( i18n("Page &orientation:"), + splitterRight, "orientationLabel" ); + splitterRightLayout->addWidget( orientationLabel, 1, 0 ); + + mOrientationSelection = new QComboBox( splitterRight, "orientationCombo" ); + mOrientationSelection->insertItem( i18n("Use Default of Selected Style") ); + mOrientationSelection->insertItem( i18n("Use Default Setting of Printer") ); + mOrientationSelection->insertItem( i18n("Portrait") ); + mOrientationSelection->insertItem( i18n("Landscape") ); + splitterRightLayout->addWidget( mOrientationSelection, 1, 1 ); + + // signals and slots connections + connect( setupButton, SIGNAL( clicked() ), SLOT( setupPrinter() ) ); + connect( mTypeGroup, SIGNAL( clicked( int ) ), SLOT( setPrintType( int ) ) ); + + // buddies + orientationLabel->setBuddy( mOrientationSelection ); + + CalPrintBase *plug = mPrintPlugins.first(); + QRadioButton *radioButton; + int id = 0; + while ( plug ) { + radioButton = new QRadioButton( plug->description(), mTypeGroup ); + mTypeGroup->insert( radioButton, id ); + //radioButton->setMinimumHeight( radioButton->sizeHint().height() - 5 ); + + mConfigArea->addWidget( plug->configWidget( mConfigArea ), id ); + + plug = mPrintPlugins.next(); + id++; + } + + // setMinimumSize( minimumSizeHint() ); + //resize( minimumSizeHint() ); +} + +CalPrintDialog::~CalPrintDialog() +{ +} + +void CalPrintDialog::setupPrinter() +{ + if ( mPrinter->setup( this ) ) { + setPrinterLabel(); + } +} + +void CalPrintDialog::setPreview(bool preview) +{ + + setButtonText(KDialogBase::Ok, preview ? i18n("&Preview") : i18n("&Print...") ); + + mPreviewText = preview ? i18n("<qt>Preview for printer <b>%1</b></qt>") + : i18n( "<qt>Printing on printer <b>%1</b></qt>"); + setPrinterLabel(); +} + +void CalPrintDialog::setPrinterLabel() +{ + QString printerName( mPrinter->printerName() ); + if ( printerName.isEmpty() ) + mPrinterLabel->setText( mPreviewText.arg( i18n("[Unconfigured]") ) ); + else + mPrinterLabel->setText( mPreviewText.arg( printerName ) ); +} + +void CalPrintDialog::setPrintType( int i ) +{ + // TODO: Make a safe correlation between type and the radio button + + mTypeGroup->setButton( i ); + mConfigArea->raiseWidget( i ); +} + +CalPrintBase *CalPrintDialog::selectedPlugin() +{ + int pos = mTypeGroup->id( mTypeGroup->selected() ); + if ( pos < 0 ) return 0; + CalPrintBase *retval = mPrintPlugins.at( pos ); + return retval; +} + +void CalPrintDialog::slotOk() +{ + mOrientation = (CalPrinter::ePrintOrientation)mOrientationSelection->currentItem(); + KDialogBase::slotOk(); + emit okClicked(); +} + +#endif diff --git a/korganizer/calprinter.h b/korganizer/calprinter.h new file mode 100644 index 0000000..7b58f4f --- a/dev/null +++ b/korganizer/calprinter.h @@ -0,0 +1,142 @@ +/* + This file is part of KOrganizer. + + Copyright (c) 1998 Preston Brown + + 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 _CALPRINTER_H +#define _CALPRINTER_H + +// #define KORG_NOPRINTER + +#ifndef KORG_NOPRINTER + +#include <qptrlist.h> + +#include <kdialogbase.h> + +#include <korganizer/baseview.h> + +#include "calprintbase.h" + +using namespace KCal; + +class QVButtonGroup; +class QWidgetStack; +class KPrinter; +class CalPrintDialog; +class KConfig; +class QComboBox; +class QLabel; + + +/** + CalPrinter is a class for printing Calendars. It can print in several + different formats (day, week, month). It also provides a way for setting + up the printer and remembering these preferences. +*/ +class CalPrinter : public QObject, public KOrg::CalPrinterBase +{ + Q_OBJECT + + public: + enum ePrintOrientation { + eOrientPlugin=0, + eOrientPrinter, + eOrientPortrait, + eOrientLandscape + }; + public: + /** + \param par parent widget for dialogs + \param cal calendar to be printed + */ + CalPrinter( QWidget *par, Calendar *cal ); + virtual ~CalPrinter(); + + void init( KPrinter *printer, Calendar *calendar ); + + void setupPrinter(); + + /** + Set date range to be printed. + + \param start Start date + \param end End date + */ + void setDateRange( const QDate &start, const QDate &end ); + + public slots: + void updateConfig(); + + private slots: + void doPrint( CalPrintBase *selectedStyle, bool preview ); + + public: + void preview( PrintType type, const QDate &fd, const QDate &td ); + void print( PrintType type, const QDate &fd, const QDate &td ); + + protected: + QPtrList<CalPrintBase> mPrintPlugins; + + private: + KPrinter *mPrinter; + Calendar *mCalendar; + QWidget *mParent; + KConfig *mConfig; + + CalPrintDialog *mPrintDialog; +}; + +class CalPrintDialog : public KDialogBase +{ + Q_OBJECT + public: + CalPrintDialog( QPtrList<CalPrintBase> plugins, KPrinter *p, + QWidget *parent = 0, const char *name = 0 ); + virtual ~CalPrintDialog(); + CalPrintBase *selectedPlugin(); + CalPrinter::ePrintOrientation orientation() { return mOrientation; } + + public slots: + void setPrintType( int ); + void setPreview( bool ); + + protected slots: + void slotOk(); + void setupPrinter(); + void setPrinterLabel(); +signals: + void okClicked(); + private: + KPrinter *mPrinter; + QVButtonGroup *mTypeGroup; + QWidgetStack *mConfigArea; + QPtrList<CalPrintBase> mPrintPlugins; + QLabel *mPrinterLabel; + QString mPreviewText; + QComboBox *mOrientationSelection; + + CalPrinter::ePrintOrientation mOrientation; +}; + +#endif + +#endif diff --git a/korganizer/calprinter.moc b/korganizer/calprinter.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/calprinter.moc diff --git a/korganizer/calprintmonthconfig_base.ui b/korganizer/calprintmonthconfig_base.ui new file mode 100644 index 0000000..734a559 --- a/dev/null +++ b/korganizer/calprintmonthconfig_base.ui @@ -0,0 +1,172 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>CalPrintMonthConfig_Base</class> +<comment>Configuration page for the print day mode.</comment> +<author>Reinhold Kainhofer <reinhold@kainhofer.com></author> +<widget class="QWidget"> + <property name="name"> + <cstring>CalPrintMonth_Base</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>357</width> + <height>112</height> + </rect> + </property> + <property name="caption"> + <string>CalPrintMonth_Base</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer row="4" column="0"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>21</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QGroupBox" row="0" column="0"> + <property name="name"> + <cstring>mDateRangeGroup</cstring> + </property> + <property name="title"> + <string>Date && Time Range</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>mFromDateLabel</cstring> + </property> + <property name="text"> + <string>&Start month:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>mFromDate</cstring> + </property> + </widget> + <widget class="KDateEdit"> + <property name="name"> + <cstring>mFromDate</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>3</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="focusPolicy"> + <enum>StrongFocus</enum> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>mToDateLabel</cstring> + </property> + <property name="text"> + <string>&End month:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>mToDate</cstring> + </property> + </widget> + <widget class="KDateEdit"> + <property name="name"> + <cstring>mToDate</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>3</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="focusPolicy"> + <enum>StrongFocus</enum> + </property> + </widget> + </hbox> + </widget> + <widget class="QCheckBox" row="2" column="0"> + <property name="name"> + <cstring>mIncludeTodos</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Include to&dos that are due on the printed day(s)</string> + </property> + </widget> + <widget class="QCheckBox" row="1" column="0"> + <property name="name"> + <cstring>mWeekNumbers</cstring> + </property> + <property name="text"> + <string>Print week &numbers</string> + </property> + </widget> + </grid> +</widget> +<customwidgets> + <customwidget> + <class>KDateEdit</class> + <header location="local">libkdepim/kdateedit.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="826">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000030149444154789cb59531681b5718c77f0e377c070e3c810a3a70e0041eac51852e0a19e45134830a1d9a4c69a04bc8928e990a693a640e1d0c8642b08742321894c1507991b484c890902bb8701a047760c3bd21701fe4201dde49b6a41a32b8df72dcbbeffdbefffbbfefbd5b1b0c07cce266ebe667ae2006c3c1dada0cdc3be87d6e6c35b0d692a409d9c7ec8b20d65ae29398d19b1114e7e3de4ce98b3f5e10dc0053cf0951b4506496e1b964bf7ce6c585d9054c62d01d617ca48be0596553cf496d8f2c8b01c5f795fc93904e85ec4c01a152857a5d9175d0b2805c872080f18595ccc1499a10a225d4e2fbc2877786fe81253ab6c04c8d106e09db5d43ab0d146e5c64d1a23938fb98a185cea1c33eecfd9eba49eb427dcb201e245365f2b7b2fb5b4a3a31dcb927178afe07d86901df870fefa4842aed6f6b74ba42e52b4014d580e1eb9cbd9d94de7e4aad16d2f9be02d805f0b5e532f927a1ffcacea1777f122a8105b164a7c25faf323a5d9f1f1fd600e1e5bec59e2d4b5c7ef5209d0ad17b8b31864e57c0b3e0815ac3ee33253ab664a770ff5185d1a1cb8d2267d3e58aa1dc7d2508cbe597d0e74fdd269aaaf0f52d414c4ea3e9762c996869e42560d7a72e41c4799a2586e74f95e8d8151481fa86efbe7b3398ac58b1a2b8527589f15451ad303ac2293542ad6648a796278f13a27185e4c4754310facb98c53a79e19a3fdc1426ff28c3d7399d1f7cb25343eb96106cf83c790ce9c4f2eb831855c55485663327992eb6dc8a6259874ed700b0b793323cccb9ffa842b30d6133e3e75fea989ac15a8b16ca76b746b0b92278d919774c5b6d48a78697fb29bbcf52468742a32120909c24e899ce67beed5be2db01e22d1e9485bb620e47f9ee9e606a21bd3f5d3744c7e7c54d55e87443867d8b554515ac5db4620e8e4f62263170fd1cdee90aad7640141992891b0f367c9adfe4049bb07d3b7022bd8c687c0978f46684ee084150b65ac1fcca94591b7a90a496e4c095164fb016a2b192a497795cc0f84817aebe25f7bf70ccc54a575c555c03f78ffa5fc0570d1f0c076bff0232285a0901e2257b0000000049454e44ae426082</data> + </image> +</images> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kdateedit.h</includehint> + <includehint>kdateedit.h</includehint> +</includehints> +</UI> diff --git a/korganizer/calprintplugins.cpp b/korganizer/calprintplugins.cpp new file mode 100644 index 0000000..bc35ca4 --- a/dev/null +++ b/korganizer/calprintplugins.cpp @@ -0,0 +1,669 @@ +/* + This file is part of KOrganizer. + + Copyright (c) 1998 Preston Brown + Copyright (c) 2003 Reinhold Kainhofer <reinhold@kainhofer.com> + Copyright (c) 2003 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. +*/ + +#include <qpainter.h> +#include <qdatetimeedit.h> +#include <qdatetime.h> +#include <qcheckbox.h> +#include <qlineedit.h> +#include <qbuttongroup.h> + +#include <kglobal.h> +#include <klocale.h> +#include <kdebug.h> +#include <kprinter.h> +#include <kconfig.h> +#include <kcalendarsystem.h> + +#include <libkcal/todo.h> +#include <libkcal/calendar.h> + +#include <libkdepim/kdateedit.h> + +#include "koprefs.h" +#include "koglobals.h" +#include "calprintplugins.h" +#ifndef KORG_NOPRINTER + +//#include "calprintplugins.moc" + +#define LEFT_DISTANCE 45 + +/************************************************************** + * Print Day + **************************************************************/ + +CalPrintDay::CalPrintDay( KPrinter *printer, Calendar *cal, KConfig *cfg ) + : CalPrintBase( printer, cal, cfg ) +{ +} + +CalPrintDay::~CalPrintDay() +{ +} + +QWidget *CalPrintDay::configWidget( QWidget *w ) +{ + mConfigWidget = new CalPrintDayConfig_Base( w ); + setSettingsWidget(); + return mConfigWidget; +} + +void CalPrintDay::readSettingsWidget() +{ + CalPrintDayConfig_Base *cfg = mConfigWidget; + if ( cfg ) { + mFromDate = cfg->mFromDate->date(); + mToDate = cfg->mToDate->date(); + + mStartTime = cfg->mFromTime->time(); + mEndTime = cfg->mToTime->time(); + mIncludeAllEvents = cfg->mIncludeAllEvents->isChecked(); + + mIncludeTodos = cfg->mIncludeTodos->isChecked(); + mUseColors = cfg->mColors->isChecked(); + } +} + +void CalPrintDay::setSettingsWidget() +{ + CalPrintDayConfig_Base *cfg =( mConfigWidget ); + if ( cfg ) { + cfg->mFromDate->setDate( mFromDate ); + cfg->mToDate->setDate( mToDate ); + + cfg->mFromTime->setTime( mStartTime ); + cfg->mToTime->setTime( mEndTime ); + cfg->mIncludeAllEvents->setChecked( mIncludeAllEvents ); + + cfg->mIncludeTodos->setChecked( mIncludeTodos ); + cfg->mColors->setChecked( mUseColors ); + } +} + +void CalPrintDay::loadConfig() +{ + if ( mConfig ) { + QDate dt; + QTime tm1 = QTime( KOPrefs::instance()->mDayBegins, 0,0 ); + QDateTime startTm( dt, tm1 ); + QDateTime endTm( dt, tm1.addSecs( 12 * 60 * 60 ) ); + mStartTime = mConfig->readDateTimeEntry( "Start time", &startTm ).time(); + mEndTime = mConfig->readDateTimeEntry( "End time", &endTm ).time(); + mIncludeTodos = mConfig->readBoolEntry( "Include todos", false ); + mIncludeAllEvents = mConfig->readBoolEntry( "Include all events", false ); + } + setSettingsWidget(); +} + +void CalPrintDay::saveConfig() +{ + readSettingsWidget(); + if ( mConfig ) { + mConfig->writeEntry( "Start time", QDateTime( QDate(), mStartTime ) ); + mConfig->writeEntry( "End time", QDateTime( QDate(), mEndTime ) ); + mConfig->writeEntry( "Include todos", mIncludeTodos ); + mConfig->writeEntry( "Include all events", mIncludeAllEvents ); + } +} + +void CalPrintDay::setDateRange( const QDate& from, const QDate& to ) +{ + CalPrintBase::setDateRange( from, to ); + CalPrintDayConfig_Base *cfg = mConfigWidget ; + if ( cfg ) { + cfg->mFromDate->setDate( from ); + cfg->mToDate->setDate( to ); + } +} + +void CalPrintDay::print( QPainter &p, int width, int height ) +{ + QDate curDay( mFromDate ); + int yoffset = 0, xoffset = 0; + if ( width > height ) { + yoffset += LEFT_DISTANCE; + } else { + xoffset += LEFT_DISTANCE; + } + width -= xoffset; + height -= yoffset; + do { + int x = 0; + int y = 0; + + + int currHeight=( height - y ) / 20; + QTime curStartTime( mStartTime ); + QTime curEndTime( mEndTime ); + if ( curStartTime.secsTo( curEndTime ) <= 3600 ) { + if ( curStartTime.hour() == 0 ) { + curStartTime = QTime( 0, 0, 0 ); + curEndTime = curStartTime.addSecs( 3600 ); + } else if ( curEndTime.hour() == 23 ) { + curEndTime=QTime( 23, 59, 59 ); + if ( curStartTime > QTime( 23, 0, 0 ) ) { + curStartTime = QTime( 23, 0, 0 ); + } + } else { + curStartTime = curStartTime.addSecs( -1200 ); + } + curEndTime = curEndTime.addSecs( 1200 ); + } + + KLocale *local = KGlobal::locale(); + drawHeader( p, local->formatDate( curDay, false ), + curDay, QDate(), xoffset, yoffset, width, mHeaderHeight ); + + y += mHeaderHeight + 5; + x = 80; + Event::List eventList; eventList.fill( mCalendar->events( curDay, true )); + + p.setFont( QFont( "helvetica", 10 ) ); + currHeight = p.fontMetrics().lineSpacing()*3/2; + drawAllDayBox( p, eventList, curDay, true, x+xoffset, y+yoffset, width - x, currHeight ); + y += currHeight; + drawAgendaDayBox( p, eventList, curDay, mIncludeAllEvents, + curStartTime, curEndTime, x+xoffset, y+yoffset, width - x, height - y ); + drawTimeLine( p, curStartTime, curEndTime, xoffset, y+yoffset, x - 5, height - y ); + curDay = curDay.addDays( 1 ); + if ( curDay <= mToDate ) mPrinter->newPage(); + } while ( curDay <= mToDate ); +} + + + +/************************************************************** + * Print Week + **************************************************************/ + +CalPrintWeek::CalPrintWeek(KPrinter *printer, Calendar *cal, KConfig *cfg) + :CalPrintBase(printer,cal,cfg) +{ +} + +CalPrintWeek::~CalPrintWeek() +{ +} + +QWidget *CalPrintWeek::configWidget( QWidget *w ) +{ + mConfigWidget = new CalPrintWeekConfig_Base( w ); + setSettingsWidget(); + return mConfigWidget; +} + +void CalPrintWeek::readSettingsWidget() +{ + CalPrintWeekConfig_Base *cfg =( mConfigWidget ); + if ( cfg ) { + mFromDate = cfg->mFromDate->date(); + mToDate = cfg->mToDate->date(); + + mWeekPrintType = (eWeekPrintType)( cfg->mPrintType->id( + cfg->mPrintType->selected() ) ); + + mStartTime = cfg->mFromTime->time(); + mEndTime = cfg->mToTime->time(); + + mIncludeTodos = cfg->mIncludeTodos->isChecked(); + mUseColors = cfg->mColors->isChecked(); + } +} + +void CalPrintWeek::setSettingsWidget() +{ + CalPrintWeekConfig_Base *cfg =( mConfigWidget ); + if ( cfg ) { + cfg->mFromDate->setDate( mFromDate ); + cfg->mToDate->setDate( mToDate ); + + cfg->mPrintType->setButton( mWeekPrintType ); + + cfg->mFromTime->setTime( mStartTime ); + cfg->mToTime->setTime( mEndTime ); + + cfg->mIncludeTodos->setChecked( mIncludeTodos ); + cfg->mColors->setChecked( mUseColors ); + } +} + +void CalPrintWeek::loadConfig() +{ + if ( mConfig ) { + QDate dt; + QTime tm1 = QTime( KOPrefs::instance()->mDayBegins, 0,0); + QDateTime startTm( dt, tm1 ); + QDateTime endTm( dt, tm1.addSecs( 43200 ) ); + mStartTime = mConfig->readDateTimeEntry( "Start time", &startTm ).time(); + mEndTime = mConfig->readDateTimeEntry( "End time", &endTm ).time(); + mIncludeTodos = mConfig->readBoolEntry( "Include todos", false ); + mWeekPrintType =(eWeekPrintType)( mConfig->readNumEntry( "Print type", (int)Filofax ) ); + } + setSettingsWidget(); +} + +void CalPrintWeek::saveConfig() +{ + readSettingsWidget(); + if ( mConfig ) { + mConfig->writeEntry( "Start time", QDateTime( QDate(), mStartTime ) ); + mConfig->writeEntry( "End time", QDateTime( QDate(), mEndTime ) ); + mConfig->writeEntry( "Include todos", mIncludeTodos ); + mConfig->writeEntry( "Print type", int( mWeekPrintType ) ); + } +} + +KPrinter::Orientation CalPrintWeek::orientation() +{ + if ( mWeekPrintType == Filofax || mWeekPrintType == SplitWeek ) return KPrinter::Portrait; + else return KPrinter::Landscape; +} + +void CalPrintWeek::setDateRange( const QDate &from, const QDate &to ) +{ + CalPrintBase::setDateRange( from, to ); + CalPrintWeekConfig_Base *cfg =( mConfigWidget ); + if ( cfg ) { + cfg->mFromDate->setDate( from ); + cfg->mToDate->setDate( to ); + } +} + +void CalPrintWeek::print( QPainter &p, int width, int height ) +{ + QDate curWeek, fromWeek, toWeek; + int yoffset = 0, xoffset = 0; + //width = height -1;//test only + if ( width > height ) { + yoffset += LEFT_DISTANCE; + } else { + xoffset += LEFT_DISTANCE; + } + width -= xoffset; + height -= yoffset; + // correct begin and end to first and last day of week + int weekdayCol = weekdayColumn( mFromDate.dayOfWeek() ); + fromWeek = mFromDate.addDays( -weekdayCol ); + weekdayCol = weekdayColumn( mFromDate.dayOfWeek() ); + toWeek = mToDate.addDays( 6 - weekdayCol ); + + curWeek = fromWeek.addDays( 6 ); + KLocale *local = KGlobal::locale(); + + switch ( mWeekPrintType ) { + case Filofax: + do { + QString line1( local->formatDate( curWeek.addDays( -6 ) ) ); + QString line2( local->formatDate( curWeek ) ); + drawHeader( p, line1 + "\n" + line2, curWeek.addDays( -6 ), QDate(), + 0+xoffset, 0+yoffset, width, mHeaderHeight ); + int top = mHeaderHeight + 10; + drawWeek( p, curWeek, 0+xoffset, top+yoffset, width, height - top ); + curWeek = curWeek.addDays( 7 ); + if ( curWeek <= toWeek ) + mPrinter->newPage(); + } while ( curWeek <= toWeek ); + break; + + case Timetable: + default: + do { + QString line1( local->formatDate( curWeek.addDays( -6 ) ) ); + QString line2( local->formatDate( curWeek ) ); + //int hh = int(mHeaderHeight * 2./3.); + int hh = mHeaderHeight; + if ( yoffset ) + drawHeader( p, i18n("date from - to", "%1 - %2").arg( line1 ).arg( line2 ), + curWeek, QDate(), 0+xoffset, 0+yoffset, width, hh ); + else + drawHeader( p, i18n("date from - to", "%1 -\n%2").arg( line1 ).arg( line2 ), + curWeek, QDate(), 0+xoffset, 0+yoffset, width, hh ); + drawTimeTable( p, fromWeek, curWeek, + mStartTime, mEndTime, 0+xoffset, hh + 5+yoffset, + width, height - hh - 5 ); + fromWeek = fromWeek.addDays( 7 ); + curWeek = fromWeek.addDays( 6 ); + if ( curWeek <= toWeek ) + mPrinter->newPage(); + } while ( curWeek <= toWeek ); + break; + + case SplitWeek: + drawSplitWeek( p, fromWeek, toWeek ); + break; + } +} + + + + +/************************************************************** + * Print Month + **************************************************************/ + +CalPrintMonth::CalPrintMonth( KPrinter *printer, Calendar *cal, KConfig *cfg ) + : CalPrintBase( printer, cal, cfg ) +{ +} + +CalPrintMonth::~CalPrintMonth() +{ +} + +QWidget *CalPrintMonth::configWidget( QWidget *w ) +{ + mConfigWidget = new CalPrintMonthConfig_Base( w ); + return mConfigWidget; +} + +void CalPrintMonth::readSettingsWidget() +{ + CalPrintMonthConfig_Base *cfg =( mConfigWidget ); + if ( cfg ) { + mFromDate = cfg->mFromDate->date(); + mToDate = cfg->mToDate->date(); + + mWeekNumbers = cfg->mWeekNumbers->isChecked(); + + mIncludeTodos = cfg->mIncludeTodos->isChecked(); +// mUseColors = cfg->mColors->isChecked(); + } +} + +void CalPrintMonth::setSettingsWidget() +{ + CalPrintMonthConfig_Base *cfg =( mConfigWidget ); + if ( cfg ) { + cfg->mFromDate->setDate( mFromDate ); + cfg->mToDate->setDate( mToDate ); + + cfg->mWeekNumbers->setChecked( mWeekNumbers ); + + cfg->mIncludeTodos->setChecked( mIncludeTodos ); +// cfg->mColors->setChecked( mUseColors ); + } +} + +void CalPrintMonth::loadConfig() +{ + if ( mConfig ) { + mWeekNumbers = mConfig->readBoolEntry( "Print week numbers", true ); + mIncludeTodos = mConfig->readBoolEntry( "Include todos", false ); + } + setSettingsWidget(); +} + +void CalPrintMonth::saveConfig() +{ + readSettingsWidget(); + if ( mConfig ) { + mConfig->writeEntry( "Print week numbers", mWeekNumbers ); + mConfig->writeEntry( "Include todos", mIncludeTodos ); + } +} + +void CalPrintMonth::setDateRange( const QDate &from, const QDate &to ) +{ + CalPrintBase::setDateRange( from, to ); + CalPrintMonthConfig_Base *cfg =( mConfigWidget ); + if ( cfg ) { + cfg->mFromDate->setDate( from ); + cfg->mToDate->setDate( to ); + } +} + +void CalPrintMonth::print( QPainter &p, int width, int height ) +{ + QDate curMonth, fromMonth, toMonth; + /* + if ( width > height ) { + // for debug only + int te = height; + height = width; + width = te; + } + */ + int yoffset = 0, xoffset = 0; + if ( width > height ) { + yoffset += LEFT_DISTANCE; + } else { + xoffset += LEFT_DISTANCE; + } + width -= xoffset; + height -= yoffset; + fromMonth = mFromDate.addDays( -( mFromDate.day() - 1 ) ); + toMonth = mToDate.addDays( mToDate.daysInMonth() - mToDate.day() ); + + curMonth = fromMonth; + do { + QString title( i18n("monthname year", "%1 %2") ); + title = title.arg( KOGlobals::self()->calendarSystem()->monthName( curMonth ) ) + .arg( curMonth.year() ); + QDate tmp( fromMonth ); + int weekdayCol = weekdayColumn( tmp.dayOfWeek() ); + tmp = tmp.addDays( -weekdayCol ); + + drawHeader( p, title, + curMonth.addMonths( -1 ), curMonth.addMonths( 1 ), + xoffset, yoffset, width, mHeaderHeight ); + drawMonth( p, curMonth, mWeekNumbers, xoffset, mHeaderHeight + 5+yoffset, + width, height - mHeaderHeight - 5 ); + curMonth = curMonth.addDays( curMonth.daysInMonth() ); + if ( curMonth <= toMonth ) mPrinter->newPage(); + } while ( curMonth <= toMonth ); + +} + + + + +/************************************************************** + * Print Todos + **************************************************************/ + +CalPrintTodos::CalPrintTodos( KPrinter *printer, Calendar *cal, KConfig *cfg ) + : CalPrintBase( printer, cal, cfg ) +{ +} + +CalPrintTodos::~CalPrintTodos() +{ +} + +QWidget *CalPrintTodos::configWidget( QWidget *w ) +{ + mConfigWidget = new CalPrintTodoConfig_Base( w ); + return mConfigWidget; +} + +void CalPrintTodos::readSettingsWidget() +{ + CalPrintTodoConfig_Base *cfg =( mConfigWidget ); + if ( cfg ) { + mPageTitle = cfg->mTitle->text(); + + mTodoPrintType = (eTodoPrintType)( cfg->mPrintType->id( + cfg->mPrintType->selected() ) ); + + mFromDate = cfg->mFromDate->date(); + mToDate = cfg->mToDate->date(); + + mIncludeDescription = cfg->mDescription->isChecked(); + mIncludePriority = cfg->mPriority->isChecked(); + mIncludeDueDate = cfg->mDueDate->isChecked(); + mConnectSubTodos = cfg->mConnectSubTodos->isChecked(); + } +} + +void CalPrintTodos::setSettingsWidget() +{ + CalPrintTodoConfig_Base *cfg =( mConfigWidget ); + if ( cfg ) { + cfg->mTitle->setText( mPageTitle ); + + cfg->mPrintType->setButton( mTodoPrintType ); + + cfg->mFromDate->setDate( mFromDate ); + cfg->mToDate->setDate( mToDate ); + + cfg->mDescription->setChecked( mIncludeDescription ); + cfg->mPriority->setChecked( mIncludePriority ); + cfg->mDueDate->setChecked( mIncludeDueDate ); + cfg->mConnectSubTodos->setChecked( mConnectSubTodos ); + } +} + +void CalPrintTodos::loadConfig() +{ + if ( mConfig ) { + mPageTitle = mConfig->readEntry( "Page title", i18n("Todo list") ); + mTodoPrintType = (eTodoPrintType)mConfig->readNumEntry( "Print type", (int)TodosAll ); + mIncludeDescription = mConfig->readBoolEntry( "Include description", true ); + mIncludePriority = mConfig->readBoolEntry( "Include priority", true ); + mIncludeDueDate = mConfig->readBoolEntry( "Include due date", true ); + mConnectSubTodos = mConfig->readBoolEntry( "Connect subtodos", true ); + mTodoPrintType = (eTodoPrintType) mConfig->readNumEntry( "Printing type", 0 ); + } + setSettingsWidget(); +} + +void CalPrintTodos::saveConfig() +{ + readSettingsWidget(); + if ( mConfig ) { + mConfig->writeEntry( "Page title", mPageTitle ); + mConfig->writeEntry( "Print type", int( mTodoPrintType ) ); + mConfig->writeEntry( "Include description", mIncludeDescription ); + mConfig->writeEntry( "Include priority", mIncludePriority ); + mConfig->writeEntry( "Include due date", mIncludeDueDate ); + mConfig->writeEntry( "Connect subtodos", mConnectSubTodos ); + mConfig->writeEntry( "Printing type", mTodoPrintType ); + } +} + +void CalPrintTodos::print( QPainter &p, int width, int height ) +{ + bool printCompleted = true; + if ( mTodoPrintType == 1 ) + printCompleted = false; + int yoffset = 0, xoffset = 0; + //width = height -1;//test only + if ( width > height ) { + yoffset += LEFT_DISTANCE; + } else { + xoffset += LEFT_DISTANCE; + } + width -= xoffset; + height -= yoffset; + + int pospriority = 5+xoffset; + int possummary = 70+xoffset; + int posdue = width - 145; + int lineSpacing = 15; + int fontHeight = 10; + + + drawHeader( p, mPageTitle, mFromDate, QDate(), + 0+xoffset, 0+yoffset, width, mHeaderHeight ); + + int mCurrentLinePos = mHeaderHeight + 5+yoffset; + QString outStr; + + p.setFont( QFont( "helvetica", 10 ) ); + lineSpacing = p.fontMetrics().lineSpacing(); + mCurrentLinePos += lineSpacing; + // draw the headers + p.setFont( QFont("helvetica", 10, QFont::Bold ) ); + if ( mIncludePriority ) { + outStr += i18n("Priority"); + p.drawText( pospriority, mCurrentLinePos - 2, outStr); + } else { + possummary = 10; + pospriority = -1; + } + + outStr.truncate( 0 ); + outStr += i18n("Summary"); + if ( mIncludeDueDate ) + outStr += i18n(" (Due)"); + + p.drawText( possummary, mCurrentLinePos - 2, outStr ); + + if ( mIncludeDueDate ) { + // outStr.truncate( 0 ); +// outStr += i18n("Due"); +// p.drawText( posdue, mCurrentLinePos - 2, outStr ); + } else { + posdue = -1; + } + + p.setFont( QFont( "helvetica", 10 ) ); + + fontHeight = p.fontMetrics().height(); + + Todo::List todoList; +// if (mTodoPrintType==TodosSelected) { +// todoList.append(selectedTodoo); +// } else { + todoList.fill(mCalendar->todos()); +// } + // TODO_RK: filter out todos + + int count = 0; + for( int cprior = 1; cprior <= 6; cprior++ ) { + Todo::List::ConstIterator it; + for( it = todoList.begin(); it != todoList.end(); ++it ) { + Todo *currEvent = *it; + + // Filter out the subitems. + if ( currEvent->relatedTo() ) { + continue; + } + + QDate start = currEvent->dtStart().date(); + // if it is not to start yet, skip. + // if ( ( !start.isValid() ) && ( start >= mToDate ) ) { + // continue; + //} + // priority + int priority = currEvent->priority(); + // 6 is the lowest priority (the unspecified one) + if ( ( priority != cprior ) || + ( ( cprior == 6 ) && ( priority == 0 ) ) ) { + continue; + } + count++; + int todoHeight = height - mCurrentLinePos; + drawTodo( printCompleted, count, currEvent, p, mConnectSubTodos, + mIncludeDescription, pospriority, possummary, posdue, 0, + 0, mCurrentLinePos, width, todoHeight, height ); + } + } +} + + +#endif diff --git a/korganizer/calprintplugins.h b/korganizer/calprintplugins.h new file mode 100644 index 0000000..7c56131 --- a/dev/null +++ b/korganizer/calprintplugins.h @@ -0,0 +1,151 @@ +/* + This file is part of KOrganizer. + + Copyright (c) 1998 Preston Brown + Copyright (c) 2003 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., 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 CALPRINTPLUGINS_H +#define CALPRINTPLUGINS_H + + +#include <klocale.h> +#include "calprintbase.h" +#include "calprintdayconfig_base.h" +#include "calprintweekconfig_base.h" +#include "calprintmonthconfig_base.h" +#include "calprinttodoconfig_base.h" + +#ifndef KORG_NOPRINTER +namespace KCal { +class Calendar; +} + +using namespace KCal; + +class CalPrintDay : public CalPrintBase +{ + Q_OBJECT + public: + CalPrintDay(KPrinter *printer, Calendar *cal, KConfig *cfg); + virtual ~CalPrintDay(); + virtual QString description() { return i18n("Print day"); } + virtual QString longDescription() { return i18n("Prints all events of a single day on one page"); } + virtual QWidget *configWidget( QWidget* ); + + public slots: + void print(QPainter &p, int width, int height); + virtual void readSettingsWidget(); + virtual void setSettingsWidget(); + virtual void loadConfig(); + virtual void saveConfig(); + virtual void setDateRange( const QDate& from, const QDate& to ); + + protected: + QTime mStartTime, mEndTime; + bool mIncludeTodos; + bool mIncludeAllEvents; + CalPrintDayConfig_Base *mConfigWidget; +}; + +class CalPrintWeek : public CalPrintBase +{ + Q_OBJECT + public: + CalPrintWeek(KPrinter *printer, Calendar *cal, KConfig *cfg); + virtual ~CalPrintWeek(); + virtual QString description() { return i18n("Print week"); } + virtual QString longDescription() { return i18n("Prints all events of one week on one page"); } + virtual QWidget *configWidget(QWidget*); + virtual KPrinter::Orientation orientation(); + + public slots: + void print(QPainter &p, int width, int height); + virtual void readSettingsWidget(); + virtual void setSettingsWidget(); + virtual void loadConfig(); + virtual void saveConfig(); + virtual void setDateRange( const QDate& from, const QDate& to ); + + protected: + enum eWeekPrintType { Filofax=0, Timetable, SplitWeek } mWeekPrintType; + QTime mStartTime, mEndTime; + bool mIncludeTodos; + CalPrintWeekConfig_Base *mConfigWidget; +}; + +class CalPrintMonth : public CalPrintBase +{ + Q_OBJECT + public: + CalPrintMonth(KPrinter *printer, Calendar *cal, KConfig *cfg); + virtual ~CalPrintMonth(); + virtual QString description() { return i18n("Print month"); } + virtual QString longDescription() { return i18n("Prints all events of one month on one page"); } + virtual QWidget *configWidget(QWidget*); + virtual KPrinter::Orientation orientation() { return KPrinter::Landscape; } + + public slots: + void print(QPainter &p, int width, int height); + virtual void readSettingsWidget(); + virtual void setSettingsWidget(); + virtual void loadConfig(); + virtual void saveConfig(); + virtual void setDateRange( const QDate& from, const QDate& to ); + + protected: + bool mWeekNumbers; + bool mIncludeTodos; + CalPrintMonthConfig_Base *mConfigWidget; +}; + +class CalPrintTodos : public CalPrintBase +{ + Q_OBJECT + public: + CalPrintTodos(KPrinter *printer, Calendar *cal, KConfig *cfg); + virtual ~CalPrintTodos(); + virtual QString description() { return i18n("Print todos"); } + virtual QString longDescription() { return i18n("Prints all todos in a (tree-like) list"); } + virtual QWidget *configWidget(QWidget*); + + public slots: + void print(QPainter &p, int width, int height); + virtual void readSettingsWidget(); + virtual void setSettingsWidget(); + virtual void loadConfig(); + virtual void saveConfig(); + + protected: + QString mPageTitle; + + enum eTodoPrintType { + TodosAll = 0, TodosUnfinished, TodosDueRange + } mTodoPrintType; + + bool mIncludeDescription; + bool mIncludePriority; + bool mIncludeDueDate; + bool mConnectSubTodos; + CalPrintTodoConfig_Base *mConfigWidget ; +}; + +#endif +#endif diff --git a/korganizer/calprinttodoconfig_base.ui b/korganizer/calprinttodoconfig_base.ui new file mode 100644 index 0000000..010a489 --- a/dev/null +++ b/korganizer/calprinttodoconfig_base.ui @@ -0,0 +1,239 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>CalPrintTodoConfig_Base</class> +<comment>Configuration page for the print day mode.</comment> +<author>Reinhold Kainhofer <reinhold@kainhofer.com></author> +<widget class="QWidget"> + <property name="name"> + <cstring>CalPrintTodoConfig_Base</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>361</width> + <height>271</height> + </rect> + </property> + <property name="caption"> + <string>CalPrintTodoConfig_Base</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>mDescription</cstring> + </property> + <property name="text"> + <string>Include &description of the item</string> + </property> + </widget> + <widget class="QCheckBox" row="4" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>mDueDate</cstring> + </property> + <property name="text"> + <string>Include d&ue date of the item</string> + </property> + </widget> + <widget class="QCheckBox" row="3" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>mPriority</cstring> + </property> + <property name="text"> + <string>Include &priority of the item</string> + </property> + </widget> + <widget class="QButtonGroup" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>mPrintType</cstring> + </property> + <property name="title"> + <string>Items to Print</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="4" column="1"> + <property name="name"> + <cstring>mFromDateLabel</cstring> + </property> + <property name="text"> + <string>&From:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>mFromDate</cstring> + </property> + </widget> + <widget class="QLabel" row="4" column="3"> + <property name="name"> + <cstring>mToDateLabel</cstring> + </property> + <property name="text"> + <string>&To:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>mToDate</cstring> + </property> + </widget> + <spacer row="4" column="5"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>21</height> + </size> + </property> + </spacer> + <spacer row="4" column="0"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QRadioButton" row="0" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>mPrintAll</cstring> + </property> + <property name="text"> + <string>Print &all todo items</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QRadioButton" row="1" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>mPrintUnfinished</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Print only &uncompleted items</string> + </property> + <property name="accel"> + <string>Alt+U</string> + </property> + </widget> + <widget class="QDateEdit" row="4" column="4"> + <property name="name"> + <cstring>mToDate</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="order"> + <enum>DMY</enum> + </property> + </widget> + <widget class="QDateEdit" row="4" column="2"> + <property name="name"> + <cstring>mFromDate</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="order"> + <enum>DMY</enum> + </property> + </widget> + <widget class="QRadioButton" row="3" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>mPrintDueRange</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Only items due in the &range:</string> + </property> + </widget> + </grid> + </widget> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>mTitle</cstring> + </property> + <property name="text"> + <string>Todo List</string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>mTitleLabel</cstring> + </property> + <property name="text"> + <string>&Title:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>mTitle</cstring> + </property> + </widget> + <widget class="QCheckBox" row="5" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>mConnectSubTodos</cstring> + </property> + <property name="text"> + <string>Co&nnect subtodos with its parent</string> + </property> + </widget> + <spacer row="6" column="1"> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>0</height> + </size> + </property> + </spacer> + </grid> +</widget> +<connections> + <connection> + <sender>mPrintDueRange</sender> + <signal>toggled(bool)</signal> + <receiver>mFromDate</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>mPrintDueRange</sender> + <signal>toggled(bool)</signal> + <receiver>mToDate</receiver> + <slot>setEnabled(bool)</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/korganizer/calprintweekconfig_base.ui b/korganizer/calprintweekconfig_base.ui new file mode 100644 index 0000000..c770239 --- a/dev/null +++ b/korganizer/calprintweekconfig_base.ui @@ -0,0 +1,318 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>CalPrintWeekConfig_Base</class> +<comment>Configuration page for the print week mode.</comment> +<author>Reinhold Kainhofer <reinhold@kainhofer.com></author> +<widget class="QWidget"> + <property name="name"> + <cstring>CalPrintWeek_Base</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>374</width> + <height>252</height> + </rect> + </property> + <property name="caption"> + <string>CalPrintWeek_Base</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer row="4" column="0"> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>21</width> + <height>27</height> + </size> + </property> + </spacer> + <widget class="QGroupBox" row="0" column="0"> + <property name="name"> + <cstring>mDateRangeGroup</cstring> + </property> + <property name="title"> + <string>Date && Time Range</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="2"> + <property name="name"> + <cstring>mToDateLabel</cstring> + </property> + <property name="text"> + <string>&End date:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>mToDate</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>mFromDateLabel</cstring> + </property> + <property name="text"> + <string>&Start date:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>mFromDate</cstring> + </property> + </widget> + <widget class="KDateEdit" row="0" column="1"> + <property name="name"> + <cstring>mFromDate</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>3</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="focusPolicy"> + <enum>StrongFocus</enum> + </property> + </widget> + <widget class="KDateEdit" row="0" column="3"> + <property name="name"> + <cstring>mToDate</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>3</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="focusPolicy"> + <enum>StrongFocus</enum> + </property> + </widget> + </grid> + </widget> + <widget class="QCheckBox" row="3" column="0"> + <property name="name"> + <cstring>mColors</cstring> + </property> + <property name="text"> + <string>Use &colors</string> + </property> + </widget> + <widget class="QButtonGroup" row="1" column="0"> + <property name="name"> + <cstring>mPrintType</cstring> + </property> + <property name="title"> + <string>Type of View</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QRadioButton" row="0" column="0" rowspan="1" colspan="6"> + <property name="name"> + <cstring>mPrintTypeButton1</cstring> + </property> + <property name="text"> + <string>Print as &Filofax page</string> + </property> + <property name="accel"> + <string>Alt+F</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QRadioButton" row="1" column="0" rowspan="1" colspan="6"> + <property name="name"> + <cstring>mPrintTypeButton2</cstring> + </property> + <property name="text"> + <string>Print as &timetable view:</string> + </property> + <property name="accel"> + <string>Alt+T</string> + </property> + </widget> + <spacer row="2" column="0"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>21</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="2" column="1"> + <property name="name"> + <cstring>mFromTimeLabel</cstring> + </property> + <property name="text"> + <string>Start &time:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>mFromTime</cstring> + </property> + </widget> + <widget class="QTimeEdit" row="2" column="2"> + <property name="name"> + <cstring>mFromTime</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="time"> + <time> + <hour>0</hour> + <minute>8</minute> + <second>0</second> + </time> + </property> + </widget> + <widget class="QLabel" row="2" column="3"> + <property name="name"> + <cstring>mToTimeLabel</cstring> + </property> + <property name="text"> + <string>End ti&me:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>mToTime</cstring> + </property> + </widget> + <widget class="QTimeEdit" row="2" column="4"> + <property name="name"> + <cstring>mToTime</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="time"> + <time> + <hour>16</hour> + <minute>0</minute> + <second>0</second> + </time> + </property> + </widget> + <spacer row="2" column="5"> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QRadioButton" row="3" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>radioButton3</cstring> + </property> + <property name="text"> + <string>Print as split week view</string> + </property> + </widget> + </grid> + </widget> + <widget class="QCheckBox" row="2" column="0"> + <property name="name"> + <cstring>mIncludeTodos</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Include to&dos that are due on the printed day(s)</string> + </property> + </widget> + </grid> +</widget> +<customwidgets> + <customwidget> + <class>KDateEdit</class> + <header location="local">libkdepim/kdateedit.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="826">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000030149444154789cb59531681b5718c77f0e377c070e3c810a3a70e0041eac51852e0a19e45134830a1d9a4c69a04bc8928e990a693a640e1d0c8642b08742321894c1507991b484c890902bb8701a047760c3bd21701fe4201dde49b6a41a32b8df72dcbbeffdbefffbbfefbd5b1b0c07cce266ebe667ae2006c3c1dada0cdc3be87d6e6c35b0d692a409d9c7ec8b20d65ae29398d19b1114e7e3de4ce98b3f5e10dc0053cf0951b4506496e1b964bf7ce6c585d9054c62d01d617ca48be0596553cf496d8f2c8b01c5f795fc93904e85ec4c01a152857a5d9175d0b2805c872080f18595ccc1499a10a225d4e2fbc2877786fe81253ab6c04c8d106e09db5d43ab0d146e5c64d1a23938fb98a185cea1c33eecfd9eba49eb427dcb201e245365f2b7b2fb5b4a3a31dcb927178afe07d86901df870fefa4842aed6f6b74ba42e52b4014d580e1eb9cbd9d94de7e4aad16d2f9be02d805f0b5e532f927a1ffcacea1777f122a8105b164a7c25faf323a5d9f1f1fd600e1e5bec59e2d4b5c7ef5209d0ad17b8b31864e57c0b3e0815ac3ee33253ab664a770ff5185d1a1cb8d2267d3e58aa1dc7d2508cbe597d0e74fdd269aaaf0f52d414c4ea3e9762c996869e42560d7a72e41c4799a2586e74f95e8d8151481fa86efbe7b3398ac58b1a2b8527589f15451ad303ac2293542ad6648a796278f13a27185e4c4754310facb98c53a79e19a3fdc1426ff28c3d7399d1f7cb25343eb96106cf83c790ce9c4f2eb831855c55485663327992eb6dc8a6259874ed700b0b793323cccb9ffa842b30d6133e3e75fea989ac15a8b16ca76b746b0b92278d919774c5b6d48a78697fb29bbcf52468742a32120909c24e899ce67beed5be2db01e22d1e9485bb620e47f9ee9e606a21bd3f5d3744c7e7c54d55e87443867d8b554515ac5db4620e8e4f62263170fd1cdee90aad7640141992891b0f367c9adfe4049bb07d3b7022bd8c687c0978f46684ee084150b65ac1fcca94591b7a90a496e4c095164fb016a2b192a497795cc0f84817aebe25f7bf70ccc54a575c555c03f78ffa5fc0570d1f0c076bff0232285a0901e2257b0000000049454e44ae426082</data> + </image> +</images> +<connections> + <connection> + <sender>mPrintTypeButton2</sender> + <signal>toggled(bool)</signal> + <receiver>mFromTime</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>mPrintTypeButton2</sender> + <signal>toggled(bool)</signal> + <receiver>mToTime</receiver> + <slot>setEnabled(bool)</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kdateedit.h</includehint> + <includehint>kdateedit.h</includehint> +</includehints> +</UI> diff --git a/korganizer/categoryeditdialog.moc b/korganizer/categoryeditdialog.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/categoryeditdialog.moc diff --git a/korganizer/categoryselectdialog.moc b/korganizer/categoryselectdialog.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/categoryselectdialog.moc diff --git a/korganizer/cellitem.cpp b/korganizer/cellitem.cpp new file mode 100644 index 0000000..61d06ac --- a/dev/null +++ b/korganizer/cellitem.cpp @@ -0,0 +1,98 @@ +/* + This file is part of KOrganizer. + + Copyright (c) 2003 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. +*/ + +#include "cellitem.h" + +#include <klocale.h> +#include <kdebug.h> + +#include <qintdict.h> + +using namespace KOrg; + +QString CellItem::label() const +{ + return i18n("<undefined>"); +} + +QPtrList<CellItem> CellItem::placeItem( QPtrList<CellItem> cells, + CellItem *placeItem ) +{ + kdDebug(5855) << "Placing " << placeItem->label() << endl; + + QPtrList<KOrg::CellItem> conflictItems; + int maxSubCells = 0; + QIntDict<KOrg::CellItem> subCellDict; + + // Find all items which are in same cell + QPtrListIterator<KOrg::CellItem> it2( cells ); + for( it2.toFirst(); it2.current(); ++it2 ) { + KOrg::CellItem *item = it2.current(); + if ( item == placeItem ) continue; + + if ( item->overlaps( placeItem ) ) { + kdDebug(5855) << " Overlaps: " << item->label() << endl; + + conflictItems.append( item ); + if ( item->subCells() > maxSubCells ) maxSubCells = item->subCells(); + subCellDict.insert( item->subCell(), item ); + } + } + + if ( conflictItems.count() > 0 ) { + // Look for unused sub cell and insert item + int i; + for( i = 0; i < maxSubCells; ++i ) { + kdDebug(5855) << " Trying subcell " << i << endl; + if ( !subCellDict.find( i ) ) { + kdDebug(5855) << " Use subcell " << i << endl; + placeItem->setSubCell( i ); + break; + } + } + if ( i == maxSubCells ) { + kdDebug(5855) << " New subcell " << i << endl; + placeItem->setSubCell( maxSubCells ); + maxSubCells++; // add new item to number of sub cells + } + + kdDebug(5855) << " Sub cells: " << maxSubCells << endl; + + // Write results to item to be placed + conflictItems.append( placeItem ); + placeItem->setSubCells( maxSubCells ); + + QPtrListIterator<KOrg::CellItem> it3( conflictItems ); + for( it3.toFirst(); it3.current(); ++it3 ) { + (*it3)->setSubCells( maxSubCells ); + } + // Todo: Adapt subCells of items conflicting with conflicting items + } else { + kdDebug(5855) << " no conflicts" << endl; + placeItem->setSubCell( 0 ); + placeItem->setSubCells( 1 ); + } + + return conflictItems; +} diff --git a/korganizer/cellitem.h b/korganizer/cellitem.h new file mode 100644 index 0000000..72773d0 --- a/dev/null +++ b/korganizer/cellitem.h @@ -0,0 +1,66 @@ +/* + This file is part of KOrganizer. + + Copyright (c) 2003 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 KORG_CELLITEM_H +#define KORG_CELLITEM_H + +#include <qstring.h> +#include <qptrlist.h> + +namespace KOrg { + +class CellItem +{ + public: + CellItem() + : mSubCells( 0 ), mSubCell( -1 ) + { + } + + void setSubCells( int v ) { mSubCells = v; } + int subCells() const { return mSubCells; } + + void setSubCell( int v ) { mSubCell = v; } + int subCell() const { return mSubCell; } + + virtual bool overlaps( CellItem *other ) const = 0; + + virtual QString label() const; + + /** + Place item \arg placeItem into stripe containing items \arg cells in a + way that items don't overlap. + + \return Placed items + */ + static QPtrList<CellItem> placeItem( QPtrList<CellItem> cells, + CellItem *placeItem ); + + private: + int mSubCells; + int mSubCell; +}; + +} + +#endif diff --git a/korganizer/customlistviewitem.h b/korganizer/customlistviewitem.h new file mode 100644 index 0000000..94e5bce --- a/dev/null +++ b/korganizer/customlistviewitem.h @@ -0,0 +1,38 @@ +#ifndef CUSTOMLISTVIEWITEM_H +#define CUSTOMLISTVIEWITEM_H + +#include <qmap.h> +#include <qstring.h> +#include <klistview.h> + +template<class T> +class CustomListViewItem : public KListViewItem +{ + public: + CustomListViewItem( T data, KListView *parent ) : + KListViewItem( parent ), mData( data ) { updateItem(); }; + ~CustomListViewItem() {}; + + void updateItem() {}; + + T data() const { return mData; } + + QString key(int column, bool) const + { + QMap<int,QString>::ConstIterator it = mKeyMap.find(column); + if (it == mKeyMap.end()) return text(column); + else return *it; + } + + void setSortKey(int column,const QString &key) + { + mKeyMap.insert(column,key); + } + + private: + T mData; + + QMap<int,QString> mKeyMap; +}; + +#endif diff --git a/korganizer/datenavigator.cpp b/korganizer/datenavigator.cpp new file mode 100644 index 0000000..8d35c42 --- a/dev/null +++ b/korganizer/datenavigator.cpp @@ -0,0 +1,287 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2002 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. +*/ + +#include "datenavigator.h" + +#include "koglobals.h" + +#include <kcalendarsystem.h> + +#include <kdebug.h> +#include <kglobal.h> +#include <klocale.h> + +using namespace KCal; + +DateNavigator::DateNavigator( QObject *parent, const char *name , KOViewManager * v) + : QObject( parent, name ) +{ + mViewManager = v; + mSelectedDates.append( QDate::currentDate() ); +} + +DateNavigator::~DateNavigator() +{ +} + +void DateNavigator::slotMonthSelect( int m ) +{ + QDate firstSelected = mSelectedDates.first(); + int weekDay = firstSelected.dayOfWeek(); + int diff = m - firstSelected.month() ; + firstSelected = KOGlobals::self()->calendarSystem()->addMonths( firstSelected, diff ); + + if ( mSelectedDates.first().day() == 1 && mSelectedDates.count() > 27 ) + selectMonthByDate( firstSelected ); + else + selectWeekByDay( weekDay, firstSelected ); + +} + +void DateNavigator::slotDaySelect( QDate d ) +{ + QDate firstSelected = mSelectedDates.first(); + int weekDay = firstSelected.dayOfWeek(); + //int diff = firstSelected.daysTo( d ) ; + firstSelected = firstSelected.addDays( firstSelected .daysTo( d ) ); + + selectWeekByDay( weekDay, firstSelected ); + +} + +void DateNavigator::selectMonthByDate( const QDate & firstSelected ) +{ + + int monthDay = firstSelected.day(); + QDate date = firstSelected.addDays( 1-monthDay ); + selectDates( date , date.daysInMonth ()); + +} +void DateNavigator::selectMonth() +{ + + QDate date =mSelectedDates.first(); + selectMonthByDate( date ); +} + +DateList DateNavigator::selectedDates() +{ + return mSelectedDates; +} + +int DateNavigator::datesCount() const +{ + return mSelectedDates.count(); +} + +void DateNavigator::selectDates( const DateList& dateList ) +{ + if (dateList.count() > 0) { + mSelectedDates = dateList; + emitSelected(); + } +} + +void DateNavigator::selectDate( const QDate &date ) +{ + QDate d = date; + + if ( !d.isValid() ) { + d = QDate::currentDate(); + } + + mSelectedDates.clear(); + mSelectedDates.append( d ); + + emitSelected(); +} + +void DateNavigator::selectDates( int count ) +{ + + QDate d = mSelectedDates.first(); + selectDates( d, count ); +} + +void DateNavigator::selectDates( const QDate &d, int count ) +{ + DateList dates; + + int i; + for( i = 0; i < count; ++i ) { + dates.append( d.addDays( i ) ); + } + + mSelectedDates = dates; + + emitSelected(); +} + +void DateNavigator::selectWeekByDay( int weekDay, const QDate &d ) +{ + // qDebug("selectWeekByDay( %d %s ", weekDay, d.toString().latin1()); + int dateCount = mSelectedDates.count(); + bool weekStart = ( weekDay == KGlobal::locale()->weekStartDay() ); + if ( weekDay == 1 && dateCount == 5 ) selectWorkWeek( d ); + else if ( weekStart && dateCount == 7 ) selectWeek( d ); + else selectDates( d, dateCount ); +} + +void DateNavigator::selectWeek() +{ + QDate d = mSelectedDates.first(); + selectWeek( d ); +} +void DateNavigator::selectWeek( int num ) +{ + int year = mSelectedDates.first().year(); + if ( mSelectedDates.first().dayOfYear() > 300 && num < 10 ) + ++year; + if ( mSelectedDates.first().dayOfYear() < 70 && num > 40 ) + --year; + QDate d = QDate ( year, 1,1); + while ( d.dayOfWeek() != 4 ) + d = d.addDays( 1 ); + selectWeek( d.addDays ( (num-1) *7 ) ); +} +void DateNavigator::selectWeek( const QDate &d ) +{ + int dayOfWeek = KOGlobals::self()->calendarSystem()->dayOfWeek( d ); + + int weekStart = KGlobal::locale()->weekStartDay(); + QDate firstDate = d.addDays( weekStart - dayOfWeek ); + + if ( weekStart != 1 && dayOfWeek < weekStart ) { + firstDate = firstDate.addDays(-7 ); + } + + + selectDates( firstDate, 7 ); +} + +void DateNavigator::selectWorkWeek() +{ + QDate d = mSelectedDates.first(); + selectWorkWeek( d ); +} + +void DateNavigator::selectWorkWeek( const QDate &d ) +{ + int dayOfWeek = KOGlobals::self()->calendarSystem()->dayOfWeek( d ); + + QDate firstDate = d.addDays( 1 - dayOfWeek ); + + int weekStart = KGlobal::locale()->weekStartDay(); + if ( weekStart != 1 && dayOfWeek >= weekStart ) { + firstDate = firstDate.addDays( 7 ); + } + + selectDates( firstDate, 5 ); +} + +void DateNavigator::selectToday() +{ + QDate d = QDate::currentDate(); + + int dateCount = mSelectedDates.count(); + + if ( dateCount == 5 ) selectWorkWeek( d ); + else if ( dateCount == 7 ) selectWeek( d ); + else selectDates( d, dateCount ); +} + +void DateNavigator::selectPreviousYear() +{ + QDate firstSelected = mSelectedDates.first(); + int weekDay = firstSelected.dayOfWeek(); + firstSelected = KOGlobals::self()->calendarSystem()->addYears( firstSelected, -1 ); + + selectWeekByDay( weekDay, firstSelected ); +} + +void DateNavigator::selectPreviousMonth() +{ + QDate firstSelected = mSelectedDates.first(); + int weekDay = firstSelected.dayOfWeek(); + firstSelected = KOGlobals::self()->calendarSystem()->addMonths( firstSelected, -1 ); + + + if ( mSelectedDates.first().day() == 1 && mSelectedDates.count() > 27 ) + selectMonthByDate( firstSelected ); + else + selectWeekByDay( weekDay, firstSelected ); +} + +void DateNavigator::selectNextMonth() +{ + QDate firstSelected = mSelectedDates.first(); + int weekDay = firstSelected.dayOfWeek(); + + firstSelected = KOGlobals::self()->calendarSystem()->addMonths( firstSelected, 1 ); + + if ( mSelectedDates.first().day() == 1 && mSelectedDates.count() > 27 ) + selectMonthByDate( firstSelected ); + else + selectWeekByDay( weekDay, firstSelected ); + +} + +void DateNavigator::selectNextYear() +{ + QDate firstSelected = mSelectedDates.first(); + int weekDay = firstSelected.dayOfWeek(); + firstSelected = KOGlobals::self()->calendarSystem()->addYears( firstSelected, 1 ); + + selectWeekByDay( weekDay, firstSelected ); +} + +void DateNavigator::selectPrevious() +{ + int offset = -7; + if ( datesCount() == 1 ) { + offset = -1; + } + if ( mViewManager ) + if ( mViewManager->showsNextDays() ) + offset = -datesCount(); + selectDates( mSelectedDates.first().addDays( offset ), datesCount() ); +} + +void DateNavigator::selectNext() +{ + int offset = 7; + if ( datesCount() == 1 ) { + offset = 1; + } + if ( mViewManager ) + if ( mViewManager->showsNextDays() ) + offset = datesCount(); + selectDates( mSelectedDates.first().addDays( offset ), datesCount() ); +} + +void DateNavigator::emitSelected() +{ + emit datesSelected( mSelectedDates ); +} + +#include "datenavigator.moc" diff --git a/korganizer/datenavigator.h b/korganizer/datenavigator.h new file mode 100644 index 0000000..747e3d3 --- a/dev/null +++ b/korganizer/datenavigator.h @@ -0,0 +1,89 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2002 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 DATENAVIGATOR_H +#define DATENAVIGATOR_H + +#include <libkcal/incidencebase.h> + +#include <qobject.h> +#include "koviewmanager.h" + +/** + This class controls date navigation. All requests to move the views to another + date are sent to the DateNavigator. The DateNavigator processes the new + selection of dates and emits the required signals for the views. +*/ +class DateNavigator : public QObject +{ + Q_OBJECT + public: + DateNavigator( QObject *parent = 0, const char *name = 0 , KOViewManager * v = 0); + ~DateNavigator(); + + KCal::DateList selectedDates(); + + int datesCount() const; + + public slots: + void selectDates( const KCal::DateList & ); + void selectDate( const QDate & ); + + void selectDates( int count ); + void selectDates( const QDate &, int count ); + + void selectWeek(); + void selectWeek( int weeknum ); + void selectWeek( const QDate & ); + + void selectWorkWeek(); + void selectWorkWeek( const QDate & ); + + void selectWeekByDay( int weekDay, const QDate & ); + + void selectToday(); + + void selectPreviousYear(); + void selectPreviousMonth(); + void selectNextMonth(); + void selectNextYear(); + + void selectMonth(); + void selectMonthByDate( const QDate & ); + + void selectPrevious(); + void selectNext(); + void slotMonthSelect( int ); + void slotDaySelect( QDate d ); + + signals: + void datesSelected( const KCal::DateList & ); + + protected: + void emitSelected(); + + private: + KOViewManager * mViewManager; + KCal::DateList mSelectedDates; +}; + +#endif diff --git a/korganizer/datenavigator.moc b/korganizer/datenavigator.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/datenavigator.moc diff --git a/korganizer/docprefs.cpp b/korganizer/docprefs.cpp new file mode 100644 index 0000000..f849aaa --- a/dev/null +++ b/korganizer/docprefs.cpp @@ -0,0 +1,64 @@ +/* + 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. +*/ + +#include <ksimpleconfig.h> +#include <kstandarddirs.h> +#include <kdebug.h> +#include <stdlib.h> + +#include "docprefs.h" + +KSimpleConfig *DocPrefs::mConfig = 0; + +DocPrefs::DocPrefs( const QString &type ) +{ + if ( !mConfig ) { + mConfig = new KSimpleConfig( locateLocal( "config", "docprefs." + type ) ); + } +} + +DocPrefs::~DocPrefs() +{ + mConfig->sync(); +} + +void DocPrefs::setDoc( const QString &identifier ) +{ + mDocId = identifier; +} + +QString DocPrefs::doc() const +{ + return mDocId; +} + +bool DocPrefs::readBoolEntry( const QString &id ) const +{ + mConfig->setGroup( mDocId ); + bool result = mConfig->readBoolEntry( id, false ); +// kdDebug() << "DocPrefs::readEntry(): " << id << " : " << (result ? "True" : "False" ) << endl; + return result; +} + +void DocPrefs::writeEntry( const QString &id, bool value ) +{ +// kdDebug() << "DocPrefs::writeEntry(): " << id << " : " << (value ? "True" : "False" ) << endl; + mConfig->setGroup( mDocId ); + mConfig->writeEntry( id, value ); +} diff --git a/korganizer/docprefs.h b/korganizer/docprefs.h new file mode 100644 index 0000000..88751fe --- a/dev/null +++ b/korganizer/docprefs.h @@ -0,0 +1,44 @@ +/* + 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. +*/ +#ifndef DOCPREFS_H +#define DOCPREFS_H + +#include <qstring.h> + +class KSimpleConfig; + +class DocPrefs +{ + public: + DocPrefs( const QString &type="general" ); + ~DocPrefs(); + + void setDoc( const QString &identifier ); + QString doc() const; + + bool readBoolEntry( const QString &identifier ) const; + void writeEntry( const QString &identifier, bool value ); + + private: + static KSimpleConfig *mConfig; + + QString mDocId; +}; + +#endif diff --git a/korganizer/filteredit_base.cpp b/korganizer/filteredit_base.cpp new file mode 100644 index 0000000..21a0954 --- a/dev/null +++ b/korganizer/filteredit_base.cpp @@ -0,0 +1,128 @@ +/**************************************************************************** +** Form implementation generated from reading ui file 'filteredit_base.ui' +** +** Created: Di Mai 4 15:30:31 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#include "filteredit_base.h" + +#include <qvariant.h> +#include <qpushbutton.h> +#include <qframe.h> +#include <qbuttongroup.h> +#include <qradiobutton.h> +#include <qlistbox.h> +#include <qlabel.h> +#include <qcheckbox.h> +#include <qlayout.h> +#include <qtooltip.h> +#include <qwhatsthis.h> + +/* + * Constructs a FilterEdit_base as a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + */ +FilterEdit_base::FilterEdit_base( QWidget* parent, const char* name, WFlags fl ) + : QWidget( parent, name, fl ) +{ + if ( !name ) + setName( "FilterEdit_base" ); + FilterEdit_baseLayout = new QVBoxLayout( this, 0, 0, "FilterEdit_baseLayout"); + + mCriteriaFrame = new QFrame( this, "mCriteriaFrame" ); + mCriteriaFrame->setFrameShape( QFrame::StyledPanel ); + mCriteriaFrame->setFrameShadow( QFrame::Raised ); + mCriteriaFrameLayout = new QGridLayout( mCriteriaFrame, 1, 1, 3, 2, "mCriteriaFrameLayout"); + + ButtonGroup1 = new QButtonGroup( mCriteriaFrame, "ButtonGroup1" ); + ButtonGroup1->setColumnLayout(0, Qt::Vertical ); + ButtonGroup1->layout()->setSpacing( 6 ); + ButtonGroup1->layout()->setMargin( 11 ); + ButtonGroup1Layout = new QVBoxLayout( ButtonGroup1->layout() ); + ButtonGroup1Layout->setAlignment( Qt::AlignTop ); + + mCatShowCheck = new QRadioButton( ButtonGroup1, "mCatShowCheck" ); + ButtonGroup1Layout->addWidget( mCatShowCheck ); + + mCatHideCheck = new QRadioButton( ButtonGroup1, "mCatHideCheck" ); + ButtonGroup1Layout->addWidget( mCatHideCheck ); + + mCatList = new QListBox( ButtonGroup1, "mCatList" ); + ButtonGroup1Layout->addWidget( mCatList ); + + mCatEditButton = new QPushButton( ButtonGroup1, "mCatEditButton" ); + ButtonGroup1Layout->addWidget( mCatEditButton ); + + mCriteriaFrameLayout->addWidget( ButtonGroup1, 0, 0 ); + + layout1 = new QHBoxLayout( 0, 0, 0, "layout1"); + + textLabel1 = new QLabel( mCriteriaFrame, "textLabel1" ); + layout1->addWidget( textLabel1 ); + + mRecurringCheck = new QCheckBox( mCriteriaFrame, "mRecurringCheck" ); + layout1->addWidget( mRecurringCheck ); + + mCompletedCheck = new QCheckBox( mCriteriaFrame, "mCompletedCheck" ); + layout1->addWidget( mCompletedCheck ); + + mCriteriaFrameLayout->addLayout( layout1, 1, 0 ); + + layout2 = new QHBoxLayout( 0, 0, 0, "layout2"); + + textLabel2 = new QLabel( mCriteriaFrame, "textLabel2" ); + layout2->addWidget( textLabel2 ); + + mPublicCheck = new QCheckBox( mCriteriaFrame, "mPublicCheck" ); + layout2->addWidget( mPublicCheck ); + + mPrivateCheck = new QCheckBox( mCriteriaFrame, "mPrivateCheck" ); + layout2->addWidget( mPrivateCheck ); + + mConfidentialCheck = new QCheckBox( mCriteriaFrame, "mConfidentialCheck" ); + mConfidentialCheck->setChecked( FALSE ); + layout2->addWidget( mConfidentialCheck ); + + mCriteriaFrameLayout->addLayout( layout2, 2, 0 ); + FilterEdit_baseLayout->addWidget( mCriteriaFrame ); + languageChange(); + resize( QSize(284, 241).expandedTo(minimumSizeHint()) ); + clearWState( WState_Polished ); +} + +/* + * Destroys the object and frees any allocated resources + */ +FilterEdit_base::~FilterEdit_base() +{ + // no need to delete child widgets, Qt does it all for us +} + +/* + * Sets the strings of the subwidgets using the current + * language. + */ +void FilterEdit_base::languageChange() +{ + setCaption( tr( "FilterEditor" ) ); + ButtonGroup1->setTitle( tr( "Categories" ) ); + mCatShowCheck->setText( tr( "Show only selected" ) ); + mCatHideCheck->setText( tr( "Show all but selected" ) ); + mCatEditButton->setText( tr( "Edit Selection..." ) ); + textLabel1->setText( tr( "Hide" ) ); + mRecurringCheck->setText( tr( "recurring events" ) ); + mCompletedCheck->setText( tr( "completed to-dos" ) ); + textLabel2->setText( tr( "Show" ) ); + mPublicCheck->setText( tr( "public" ) ); + mPrivateCheck->setText( tr( "private" ) ); + mConfidentialCheck->setText( tr( "confidential" ) ); +} + +void FilterEdit_base::updateFilter() +{ + qWarning( "FilterEdit_base::updateFilter(): Not implemented yet" ); +} + diff --git a/korganizer/filteredit_base.cpp.emb b/korganizer/filteredit_base.cpp.emb new file mode 100644 index 0000000..9e32851 --- a/dev/null +++ b/korganizer/filteredit_base.cpp.emb @@ -0,0 +1,97 @@ +/**************************************************************************** +** Form implementation generated from reading ui file 'filteredit_base.ui' +** +** Created: Do Jan 22 23:56:40 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#include "filteredit_base.h" + +#include <qvariant.h> +#include <qpushbutton.h> +#include <qframe.h> +#include <qbuttongroup.h> +#include <qradiobutton.h> +#include <qlistbox.h> +#include <qcheckbox.h> +#include <qlayout.h> +#include <qtooltip.h> +#include <qwhatsthis.h> + +/* + * Constructs a FilterEdit_base as a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + */ +FilterEdit_base::FilterEdit_base( QWidget* parent, const char* name, WFlags fl ) + : QWidget( parent, name, fl ) +{ + if ( !name ) + setName( "FilterEdit_base" ); + FilterEdit_baseLayout = new QVBoxLayout( this, 0, 0, "FilterEdit_baseLayout"); + + mCriteriaFrame = new QFrame( this, "mCriteriaFrame" ); + mCriteriaFrame->setFrameShape( QFrame::StyledPanel ); + mCriteriaFrame->setFrameShadow( QFrame::Raised ); + mCriteriaFrameLayout = new QVBoxLayout( mCriteriaFrame, 11, 6, "mCriteriaFrameLayout"); + + ButtonGroup1 = new QButtonGroup( mCriteriaFrame, "ButtonGroup1" ); + ButtonGroup1->setColumnLayout(0, Qt::Vertical ); + ButtonGroup1->layout()->setSpacing( 6 ); + ButtonGroup1->layout()->setMargin( 11 ); + ButtonGroup1Layout = new QVBoxLayout( ButtonGroup1->layout() ); + ButtonGroup1Layout->setAlignment( Qt::AlignTop ); + + mCatShowCheck = new QRadioButton( ButtonGroup1, "mCatShowCheck" ); + ButtonGroup1Layout->addWidget( mCatShowCheck ); + + mCatHideCheck = new QRadioButton( ButtonGroup1, "mCatHideCheck" ); + ButtonGroup1Layout->addWidget( mCatHideCheck ); + + mCatList = new QListBox( ButtonGroup1, "mCatList" ); + ButtonGroup1Layout->addWidget( mCatList ); + + mCatEditButton = new QPushButton( ButtonGroup1, "mCatEditButton" ); + ButtonGroup1Layout->addWidget( mCatEditButton ); + mCriteriaFrameLayout->addWidget( ButtonGroup1 ); + + mRecurringCheck = new QCheckBox( mCriteriaFrame, "mRecurringCheck" ); + mCriteriaFrameLayout->addWidget( mRecurringCheck ); + + mCompletedCheck = new QCheckBox( mCriteriaFrame, "mCompletedCheck" ); + mCriteriaFrameLayout->addWidget( mCompletedCheck ); + FilterEdit_baseLayout->addWidget( mCriteriaFrame ); + languageChange(); + resize( QSize(196, 257).expandedTo(minimumSizeHint()) ); + clearWState( WState_Polished ); +} + +/* + * Destroys the object and frees any allocated resources + */ +FilterEdit_base::~FilterEdit_base() +{ + // no need to delete child widgets, Qt does it all for us +} + +/* + * Sets the strings of the subwidgets using the current + * language. + */ +void FilterEdit_base::languageChange() +{ + setCaption( tr( "FilterEditor" ) ); + ButtonGroup1->setTitle( tr( "Categories" ) ); + mCatShowCheck->setText( tr( "Show only selected" ) ); + mCatHideCheck->setText( tr( "Show all but selected" ) ); + mCatEditButton->setText( tr( "Edit Selection..." ) ); + mRecurringCheck->setText( tr( "Hide recurring events" ) ); + mCompletedCheck->setText( tr( "Hide completed to-dos" ) ); +} + +void FilterEdit_base::updateFilter() +{ + qWarning( "FilterEdit_base::updateFilter(): Not implemented yet" ); +} + diff --git a/korganizer/filteredit_base.h b/korganizer/filteredit_base.h new file mode 100644 index 0000000..664598a --- a/dev/null +++ b/korganizer/filteredit_base.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** Form interface generated from reading ui file 'filteredit_base.ui' +** +** Created: Di Mai 4 15:24:50 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#ifndef FILTEREDIT_BASE_H +#define FILTEREDIT_BASE_H + +#include <qvariant.h> +#include <qwidget.h> + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QSpacerItem; +class QFrame; +class QButtonGroup; +class QRadioButton; +class QListBox; +class QListBoxItem; +class QPushButton; +class QLabel; +class QCheckBox; + +class FilterEdit_base : public QWidget +{ + Q_OBJECT + +public: + FilterEdit_base( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~FilterEdit_base(); + + QFrame* mCriteriaFrame; + QButtonGroup* ButtonGroup1; + QRadioButton* mCatShowCheck; + QRadioButton* mCatHideCheck; + QListBox* mCatList; + QPushButton* mCatEditButton; + QLabel* textLabel1; + QCheckBox* mRecurringCheck; + QCheckBox* mCompletedCheck; + QLabel* textLabel2; + QCheckBox* mPublicCheck; + QCheckBox* mPrivateCheck; + QCheckBox* mConfidentialCheck; + +public slots: + virtual void updateFilter(); + +protected: + QVBoxLayout* FilterEdit_baseLayout; + QGridLayout* mCriteriaFrameLayout; + QVBoxLayout* ButtonGroup1Layout; + QHBoxLayout* layout1; + QHBoxLayout* layout2; + +protected slots: + virtual void languageChange(); + +}; + +#endif // FILTEREDIT_BASE_H diff --git a/korganizer/filteredit_base.h.emb b/korganizer/filteredit_base.h.emb new file mode 100644 index 0000000..8befd6b --- a/dev/null +++ b/korganizer/filteredit_base.h.emb @@ -0,0 +1,57 @@ +/**************************************************************************** +** Form interface generated from reading ui file 'filteredit_base.ui' +** +** Created: Do Jan 22 23:56:38 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#ifndef FILTEREDIT_BASE_H +#define FILTEREDIT_BASE_H + +#include <qvariant.h> +#include <qwidget.h> + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QFrame; +class QButtonGroup; +class QRadioButton; +class QListBox; +class QListBoxItem; +class QPushButton; +class QCheckBox; + +class FilterEdit_base : public QWidget +{ + Q_OBJECT + +public: + FilterEdit_base( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~FilterEdit_base(); + + QFrame* mCriteriaFrame; + QButtonGroup* ButtonGroup1; + QRadioButton* mCatShowCheck; + QRadioButton* mCatHideCheck; + QListBox* mCatList; + QPushButton* mCatEditButton; + QCheckBox* mRecurringCheck; + QCheckBox* mCompletedCheck; + +public slots: + virtual void updateFilter(); + +protected: + QVBoxLayout* FilterEdit_baseLayout; + QVBoxLayout* mCriteriaFrameLayout; + QVBoxLayout* ButtonGroup1Layout; + +protected slots: + virtual void languageChange(); + +}; + +#endif // FILTEREDIT_BASE_H diff --git a/korganizer/filteredit_base.ui b/korganizer/filteredit_base.ui new file mode 100644 index 0000000..b7cbb59 --- a/dev/null +++ b/korganizer/filteredit_base.ui @@ -0,0 +1,201 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>FilterEdit_base</class> +<widget class="QWidget"> + <property name="name"> + <cstring>FilterEdit_base</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>284</width> + <height>241</height> + </rect> + </property> + <property name="caption"> + <string>FilterEditor</string> + </property> + <property name="layoutMargin" stdset="0"> + </property> + <property name="layoutSpacing" stdset="0"> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="QFrame"> + <property name="name"> + <cstring>mCriteriaFrame</cstring> + </property> + <property name="frameShape"> + <enum>StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>Raised</enum> + </property> + <property name="layoutMargin" stdset="0"> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>3</number> + </property> + <property name="spacing"> + <number>2</number> + </property> + <widget class="QButtonGroup" row="0" column="0"> + <property name="name"> + <cstring>ButtonGroup1</cstring> + </property> + <property name="title"> + <string>Categories</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QRadioButton"> + <property name="name"> + <cstring>mCatShowCheck</cstring> + </property> + <property name="text"> + <string>Show only selected</string> + </property> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>mCatHideCheck</cstring> + </property> + <property name="text"> + <string>Show all but selected</string> + </property> + </widget> + <widget class="QListBox"> + <property name="name"> + <cstring>mCatList</cstring> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>mCatEditButton</cstring> + </property> + <property name="text"> + <string>Edit Selection...</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Hide</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>mRecurringCheck</cstring> + </property> + <property name="text"> + <string>recurring events</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>mCompletedCheck</cstring> + </property> + <property name="text"> + <string>completed to-dos</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="2" column="0"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Show</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>mPublicCheck</cstring> + </property> + <property name="text"> + <string>public</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>mPrivateCheck</cstring> + </property> + <property name="text"> + <string>private</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>mConfidentialCheck</cstring> + </property> + <property name="text"> + <string>confidential</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </hbox> + </widget> + </grid> + </widget> + </vbox> +</widget> +<slots> + <slot>updateFilter()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/korganizer/filtereditdialog.cpp b/korganizer/filtereditdialog.cpp new file mode 100644 index 0000000..2943e41 --- a/dev/null +++ b/korganizer/filtereditdialog.cpp @@ -0,0 +1,270 @@ +/* + 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. +*/ + +#include <qlayout.h> +#include <qpushbutton.h> +#include <qcombobox.h> +#include <qcheckbox.h> +#include <qradiobutton.h> +#include <qlistbox.h> +#include <qapplication.h> + +#include <kdebug.h> +#include <klocale.h> +#include <klineeditdlg.h> +#include <kmessagebox.h> + +#include <libkdepim/categoryselectdialog.h> + +#include "koprefs.h" +#include "filteredit_base.h" + +#include "filtereditdialog.h" +#include "filtereditdialog.moc" + +// TODO: Make dialog work on a copy of the filters objects. + +class ComboFilterBox: public QComboBox +{ +public: + ComboFilterBox( QWidget *parent=0, const char *name=0) : + QComboBox( parent,name ) { } + void popupBox() { popup(); } + +}; + +FilterEditDialog::FilterEditDialog(QPtrList<CalFilter> *filters,QWidget *parent, + const char *name) : + KDialogBase(parent,name,true,i18n("Edit Calendar Filters"), + Ok|Apply|Cancel) +{ + mFilters = filters; + + QWidget *mainWidget = new QWidget(this); + setMainWidget(mainWidget); + + mSelectionCombo = new ComboFilterBox(mainWidget); + connect(mSelectionCombo,SIGNAL(activated(int)),SLOT(filterSelected())); + // mSelectionCombo->setEditable ( true ); + QPushButton *addButton = new QPushButton(i18n("Add Filter"),mainWidget); + connect(addButton,SIGNAL(clicked()),SLOT(slotAdd())); + addButton->setMaximumSize( addButton->sizeHint()); + mRemoveButton = new QPushButton( i18n("Remove"), mainWidget ); + connect( mRemoveButton, SIGNAL( clicked() ), SLOT( slotRemove() ) ); + mRemoveButton->setMaximumSize( mRemoveButton->sizeHint()); + + QPushButton *upButton = new QPushButton(i18n("Up"),mainWidget); + upButton->setMaximumSize( upButton->sizeHint()); + connect(upButton,SIGNAL(clicked()),SLOT(slotUp())); + + + mEditor = new FilterEdit_base(mainWidget); + + QGridLayout *topLayout = new QGridLayout(mainWidget,2,2); + topLayout->setSpacing(spacingHint()); + topLayout->addWidget(mSelectionCombo,0,0); + topLayout->addWidget(upButton,0,1); + topLayout->addWidget(addButton,0,2); + topLayout->addWidget(mRemoveButton,0,3); + topLayout->addMultiCellWidget(mEditor,1,1,0,3); + mSelectionCombo->setMaximumWidth ( QApplication::desktop()->width() - + addButton->maximumWidth() - + mRemoveButton->maximumWidth() - + upButton->maximumWidth() - + spacingHint() * 5 ); + connect(mEditor->mCatEditButton,SIGNAL(clicked()), + SLOT(editCategorySelection())); + + // Clicking cancel exits the dialog without saving + connect(this,SIGNAL(cancelClicked()),SLOT(reject())); + updateFilterList(); +} + +FilterEditDialog::~FilterEditDialog() +{ +} +void FilterEditDialog::slotUp() +{ + + if ( mFilters->count() <= 1 ) return; + if ( mSelectionCombo->currentItem() == 0 ) return; + int num = mSelectionCombo->currentItem(); + CalFilter* f = new CalFilter( ); + *f = *(mFilters->at( num )); + mFilters->remove( num ); + mFilters->insert( num-1, f ); + updateFilterList(); + mSelectionCombo->setCurrentItem( num-1 ); + readFilter(f); + //qApp->processEvents(); + //mSelectionCombo->popupBox(); +} +void FilterEditDialog::updateFilterList() +{ + mSelectionCombo->clear(); + + CalFilter *filter = mFilters->first(); + + if (!filter) { + enableButtonOK(false); + enableButtonApply(false); + } else { + while(filter) { + mSelectionCombo->insertItem(filter->name()); + filter = mFilters->next(); + } + CalFilter *f = mFilters->at(mSelectionCombo->currentItem()); + if (f) readFilter(f); + + enableButtonOK(true); + enableButtonApply(true); + } + + mRemoveButton->setEnabled( mFilters->count() > 1 ); +} + +void FilterEditDialog::slotDefault() +{ +} + +void FilterEditDialog::slotApply() +{ + CalFilter *f = mFilters->at(mSelectionCombo->currentItem()); + writeFilter(f); + emit filterChanged(); +} +void FilterEditDialog::accept() +{ + slotOk(); +} +void FilterEditDialog::slotOk() +{ + CalFilter *f = mFilters->at(mSelectionCombo->currentItem()); + writeFilter(f); + emit filterChanged(); + QDialog::accept(); +} + +void FilterEditDialog::slotAdd() +{ + KLineEditDlg dlg(i18n("Enter filter name:"), "New Filter", this); + dlg.setCaption(i18n("Add Filter")); + if (dlg.exec()) { + if ( dlg.text().length() > 0 ) { + mFilters->append(new CalFilter(dlg.text())); + updateFilterList(); + int num = mSelectionCombo->count() -1 ; + mSelectionCombo->setCurrentItem( num ); + readFilter(mFilters->at( num ) ); + } + } +} + +void FilterEditDialog::slotRemove() +{ + int currentItem = mSelectionCombo->currentItem(); + if ( currentItem < 0 ) return; + + // We need at least a default filter object. + if ( mFilters->count() <= 1 ) return; + + int result = KMessageBox::questionYesNo( this, + i18n("This item will be\npermanently deleted.") ); + + if ( result != KMessageBox::Yes ) { + return; + } + + mFilters->remove( currentItem ); + updateFilterList(); + emit filterChanged(); +} + +void FilterEditDialog::editCategorySelection() +{ + KPIM::CategorySelectDialog *dlg = new KPIM::CategorySelectDialog( + KOPrefs::instance(), this, "filterCatSelect", true ); + dlg->setSelected(mCategories); + + connect(dlg,SIGNAL(categoriesSelected(const QStringList &)), + SLOT(updateCategorySelection(const QStringList &))); + + dlg->exec(); +} + +void FilterEditDialog::updateCategorySelection(const QStringList &categories) +{ + mCategories = categories; + + mEditor->mCatList->clear(); + mEditor->mCatList->insertStringList(mCategories); +} + +void FilterEditDialog::filterSelected() +{ + CalFilter *f = mFilters->at(mSelectionCombo->currentItem()); + if (f) readFilter(f); +} + +void FilterEditDialog::readFilter(CalFilter *filter) +{ + int c = filter->criteria(); + + mEditor->mCompletedCheck->setChecked(c & CalFilter::HideCompleted); + mEditor->mRecurringCheck->setChecked(c & CalFilter::HideRecurring); + mEditor->mPublicCheck->setChecked(c & CalFilter::ShowPublic); + mEditor->mPrivateCheck->setChecked(c & CalFilter::ShowPrivate); + mEditor->mConfidentialCheck->setChecked(c & CalFilter::ShowConfidential); + + if (c & CalFilter::ShowCategories) { + mEditor->mCatShowCheck->setChecked(true); + } else { + mEditor->mCatHideCheck->setChecked(true); + } + + mEditor->mCatList->clear(); + mEditor->mCatList->insertStringList(filter->categoryList()); + mCategories = filter->categoryList(); + + setCaption( i18n("Filter position: ") + QString::number ( mSelectionCombo->currentItem()+1 )); +} + +void FilterEditDialog::writeFilter(CalFilter *filter) +{ + int c = 0; + + if (mEditor->mCompletedCheck->isChecked()) c |= CalFilter::HideCompleted; + if (mEditor->mRecurringCheck->isChecked()) c |= CalFilter::HideRecurring; + if (mEditor->mCatShowCheck->isChecked()) c |= CalFilter::ShowCategories; + if (mEditor->mPublicCheck->isChecked()) c |= CalFilter::ShowPublic; + if (mEditor->mPrivateCheck->isChecked()) c |= CalFilter::ShowPrivate; + if (mEditor->mConfidentialCheck->isChecked()) c |= CalFilter::ShowConfidential; + + filter->setCriteria(c); + + QStringList categoryList; + for(uint i=0;i<mEditor->mCatList->count();++i) { + categoryList.append(mEditor->mCatList->text(i)); + } + filter->setCategoryList(categoryList); +} diff --git a/korganizer/filtereditdialog.h b/korganizer/filtereditdialog.h new file mode 100644 index 0000000..42aa3da --- a/dev/null +++ b/korganizer/filtereditdialog.h @@ -0,0 +1,86 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2001, 2002 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 _FILTEREDITDIALOG_H +#define _FILTEREDITDIALOG_H + +#include <qptrlist.h> + +#include <kdialogbase.h> + +#include <libkcal/calfilter.h> + +class QComboBox; +class ComboFilterBox; +class QPushButton; +class FilterEdit_base; + +using namespace KCal; + +/** + This is the class to add/edit a calendar filter. + + @short Creates a dialog box to create/edit a calendar filter + @author Cornelius Schumacher +*/ +class FilterEditDialog : public KDialogBase +{ + Q_OBJECT + public: + FilterEditDialog(QPtrList<CalFilter> *,QWidget *parent=0, const char *name=0); + virtual ~FilterEditDialog(); + + public slots: + void updateFilterList(); + + signals: + void filterChanged(); + + protected slots: + void slotDefault(); + void slotApply(); + void slotOk(); + void accept(); + + void slotAdd(); + void slotUp(); + void slotRemove(); + + void filterSelected(); + void editCategorySelection(); + void updateCategorySelection(const QStringList &categories); + + protected: + void readFilter(CalFilter *); + void writeFilter(CalFilter *); + + private: + QPtrList<CalFilter> *mFilters; + + ComboFilterBox *mSelectionCombo; + QPushButton *mRemoveButton; + FilterEdit_base *mEditor; + + QStringList mCategories; +}; + +#endif diff --git a/korganizer/filtereditdialog.moc b/korganizer/filtereditdialog.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/filtereditdialog.moc diff --git a/korganizer/incomingdialog.cpp b/korganizer/incomingdialog.cpp new file mode 100644 index 0000000..490d21e --- a/dev/null +++ b/korganizer/incomingdialog.cpp @@ -0,0 +1,527 @@ +/* + 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. +*/ + +#include <qlistview.h> +#include <qfile.h> +#include <qdir.h> +#include <qmap.h> + +#include <kglobal.h> +#include <klocale.h> +#include <kdebug.h> +#include <kstandarddirs.h> +#include <kmessagebox.h> + +#include <libkcal/incidence.h> +#include <libkcal/event.h> +#include <libkcal/calendar.h> +#include <libkcal/freebusy.h> +#include <libkcal/attendee.h> +#include <libkcal/calendarresources.h> +#include <libkcal/resourcecalendar.h> +#include <kresources/resourceselectdialog.h> + +#ifndef KORG_NOMAIL +#include "mailscheduler.h" +#else +#include <libkcal/dummyscheduler.h> +#endif + + +#include "incomingdialog.h" +#include "koeventviewerdialog.h" +#include "kocounterdialog.h" +#include "koprefs.h" + +#ifndef KORG_NOKABC +#include <kabc/stdaddressbook.h> +#define size count +#endif + + +ScheduleItemIn::ScheduleItemIn(QListView *parent,IncidenceBase *ev, + Scheduler::Method method,ScheduleMessage::Status status) + : QListViewItem(parent) +{ + mIncidence = ev; + mMethod = method; + mStatus = status; + setText(6,Scheduler::translatedMethodName(mMethod)+" "); + setText(7,ScheduleMessage::statusName(status)); +} + + +/* Visitor */ +ScheduleItemVisitor::ScheduleItemVisitor(ScheduleItemIn *item) +{ + mItem = item; +} + +ScheduleItemVisitor::~ScheduleItemVisitor() +{ +} + +bool ScheduleItemVisitor::visit(Event *e) +{ + mItem->setText(0,e->summary()); + mItem->setText(1,e->dtStartDateStr()); + if (e->doesFloat()) { + mItem->setText(2,i18n("no time ")); + mItem->setText(4,i18n("no time ")); + } + else { + mItem->setText(2,e->dtStartTimeStr()); + mItem->setText(4,e->dtEndTimeStr()); + } + if (e->hasEndDate()) { + mItem->setText(3,e->dtEndDateStr()); + } + else { + mItem->setText(3,""); + } + mItem->setText(5,e->organizer()+" "); + + return true; +} + +bool ScheduleItemVisitor::visit(Todo *e) +{ + mItem->setText(0,e->summary()); + if (e->hasStartDate()) { + mItem->setText(1,e->dtStartDateStr()); + if (!e->doesFloat()) { + mItem->setText(2,e->dtStartTimeStr()); + } + } + if (e->hasDueDate()) { + mItem->setText(1,e->dtDueDateStr()); + if (!e->doesFloat()) { + mItem->setText(2,e->dtDueTimeStr()); + } + } + mItem->setText(5,e->organizer()+" "); + + return true; +} + +bool ScheduleItemVisitor::visit(Journal *) +{ + return false; +} + + +/* + * Constructs a IncomingDialog which is a child of 'parent', with the + * name 'name' and widget flags set to 'f' + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +IncomingDialog::IncomingDialog(Calendar *calendar,OutgoingDialog *outgoing, + QWidget* parent,const char* name,bool modal,WFlags fl) : + IncomingDialog_base(parent,name,modal,fl) +{ + mCalendar = calendar; + mOutgoing = outgoing; +#ifndef KORG_NOMAIL + mScheduler = new MailScheduler(mCalendar); +#else + mScheduler = new DummyScheduler(mCalendar); +#endif + mMessageListView->setColumnAlignment(1,AlignHCenter); + mMessageListView->setColumnAlignment(2,AlignHCenter); + mMessageListView->setColumnAlignment(3,AlignHCenter); + mMessageListView->setColumnAlignment(4,AlignHCenter); + QObject::connect(mMessageListView,SIGNAL(doubleClicked(QListViewItem *)), + this,SLOT(showEvent(QListViewItem *))); + retrieve(); +} + +/* + * Destroys the object and frees any allocated resources + */ +IncomingDialog::~IncomingDialog() +{ + // no need to delete child widgets, Qt does it all for us +} + +void IncomingDialog::setOutgoingDialog(OutgoingDialog *outgoing) +{ + mOutgoing = outgoing; +} + +void IncomingDialog::retrieve() +{ + QPtrList <ScheduleMessage> messages = mScheduler->retrieveTransactions(); + + ScheduleMessage *message; + for(message = messages.first();message;message = messages.next()) { + IncidenceBase *inc = message->event(); + Scheduler::Method method = (Scheduler::Method)message->method(); + ScheduleMessage::Status status = message->status(); + + ScheduleItemIn *item = new ScheduleItemIn(mMessageListView,inc,method,status); + if(inc->type()!="FreeBusy") { + Incidence *incidence = static_cast<Incidence *>(inc); + ScheduleItemVisitor v(item); + if (!incidence->accept(v)) delete item; + } else { + FreeBusy *fb = static_cast<FreeBusy *>(item->event()); + item->setText(0, "FreeBusy"); + item->setText(1, KGlobal::locale()->formatDate( fb->dtStart().date() ) ); + item->setText(2, KGlobal::locale()->formatTime( fb->dtStart().time() ) ); + item->setText(3, KGlobal::locale()->formatDate( fb->dtEnd().date() ) ); + item->setText(4, KGlobal::locale()->formatTime( fb->dtEnd().time() ) ); + item->setText(5, fb->organizer()); + } + automaticAction(item); + } + emit numMessagesChanged(mMessageListView->childCount()); +} + +void IncomingDialog::acceptAllMessages() +{ + bool success = false; + + ScheduleItemIn *item = (ScheduleItemIn *)mMessageListView->firstChild(); + while(item) { + ScheduleItemIn *nextitem = (ScheduleItemIn *)(item->nextSibling()); + if (acceptMessage(item)) success = true; + item = nextitem; + } + + if (success) emit calendarUpdated(); +} + +void IncomingDialog::acceptMessage() +{ + ScheduleItemIn *item = (ScheduleItemIn *)mMessageListView->selectedItem(); + if (item) { + if (acceptMessage(item)) emit calendarUpdated(); + } +} + +bool IncomingDialog::acceptMessage(ScheduleItemIn *item) +{ + switch (item->method()) { + case Scheduler::Refresh: + return incomeRefresh(item); + break; + case Scheduler::Counter: + return incomeCounter(item); + break; + case Scheduler::Declinecounter: + return incomeDeclineCounter(item); + break; + case Scheduler::Add: + return incomeAdd(item); + break; + case Scheduler::Request: + return incomeRequest(item); + break; + default: + return incomeDefault(item); + } + return false; +} + +void IncomingDialog::rejectMessage() +{ + ScheduleItemIn *item = (ScheduleItemIn *)mMessageListView->selectedItem(); + if (item) { + mScheduler->deleteTransaction(item->event()); + delete item; + emit numMessagesChanged(mMessageListView->childCount()); + } +} + +void IncomingDialog::showEvent(QListViewItem *item) +{ + IncidenceBase *incidence = ((ScheduleItemIn *)item)->event(); + if( incidence && incidence->type() == "Event" ) { + Event *event = static_cast<Event *>(incidence); + KOEventViewerDialog *eventViewer = new KOEventViewerDialog(this); + eventViewer->setEvent(event); + eventViewer->show(); + } +} + +bool IncomingDialog::incomeRefresh(ScheduleItemIn *item) +{ + Event *ev = mCalendar->event(item->event()->uid()); + if (ev) { + //user interaction before?? + Attendee *att; + QPtrList<Attendee> attlist = ev->attendees(); + for (att=attlist.first(); att; att=attlist.next()) { + Event *event = new Event(*ev); + mOutgoing->addMessage(event,Scheduler::Request,att->email()); + delete(event); + } + mScheduler->deleteTransaction(item->event()); + delete item; + emit numMessagesChanged(mMessageListView->childCount()); + return true; + } + mScheduler->deleteTransaction(item->event()); + delete item; + emit numMessagesChanged(mMessageListView->childCount()); + return false; +} + +bool IncomingDialog::incomeCounter(ScheduleItemIn *item) +{ + IncidenceBase *incidence = ((ScheduleItemIn *)item)->event(); + // currently only events supportet - attetion at insertion below! + if ( incidence->type() != "Event" ) return false; + + Event *counterEvent = static_cast<Event *>( incidence ); + + Event *even = mCalendar->event(counterEvent->uid()); + + KOCounterDialog *eventViewer = new KOCounterDialog(this); + eventViewer->addText(i18n("counter proposal event","<b>Counter-event:</b><p>")); + eventViewer->addEvent(counterEvent); + eventViewer->addText("<hr>"); + eventViewer->addText(i18n("<b>Original event:</b><p>")); + if (even) eventViewer->addEvent(even); + else eventViewer->addText(i18n("A corresponding event is missing in your calendar!")); + eventViewer->addText("<hr>"); + eventViewer->addText(i18n("If this counter-event is a good proposal for your event, press 'Accept'. All Attendees will then get the new version of this event")); + eventViewer->show(); + + eventViewer->exec(); + if (eventViewer->result()) { + kdDebug() << "IncomingDialog::Counter:Accept" << endl; + int revision = 0; + if (even) { + revision = even->revision(); + mCalendar->deleteEvent(even); + } + mCalendar->addIncidence(counterEvent); + + even = mCalendar->event(item->event()->uid()); + if (even) { + if (revision < even->revision()) + even->setRevision(even->revision()+1); + else + even->setRevision(revision+1); + Event *ev = new Event(*even); + mOutgoing->addMessage(ev,Scheduler::Request); + delete(ev); + } + mScheduler->deleteTransaction(item->event()); + delete item; + emit numMessagesChanged(mMessageListView->childCount()); + return true; + } else { + kdDebug() << "IncomingDialog::Counter:Decline" << endl; + //the counter-sender's email is missing... + //now every attendee gets an declinecounter :-( + mOutgoing->addMessage(counterEvent,Scheduler::Declinecounter); + delete item; + emit numMessagesChanged(mMessageListView->childCount()); + mScheduler->deleteTransaction(item->event()); + delete item; + emit numMessagesChanged(mMessageListView->childCount()); + return true; + } + //mScheduler->deleteTransaction(item->event()); + delete item; + emit numMessagesChanged(mMessageListView->childCount()); + return false; +} + +bool IncomingDialog::incomeDeclineCounter(ScheduleItemIn *item) +{ + Event *even = mCalendar->event(item->event()->uid()); + if (even) { + mOutgoing->addMessage(even,Scheduler::Refresh); + mScheduler->deleteTransaction(item->event()); + delete item; + emit numMessagesChanged(mMessageListView->childCount()); + return true; + } + mScheduler->deleteTransaction(item->event()); + delete item; + emit numMessagesChanged(mMessageListView->childCount()); + return false; +} + +bool IncomingDialog::incomeAdd(ScheduleItemIn *item) +{ + IncidenceBase *incidence = ((ScheduleItemIn *)item)->event(); + if (incidence->type() == "Event" ) { + Event *refr = static_cast<Event *>( incidence ); + mOutgoing->addMessage(refr,Scheduler::Refresh); + mScheduler->deleteTransaction( incidence ); + delete item; + emit numMessagesChanged(mMessageListView->childCount()); + return true; + } + else { + kdDebug() << "IncomingDialog::incomeAdd - only Events are supportet yet" << endl; + mScheduler->deleteTransaction( incidence ); + delete item; + emit numMessagesChanged(mMessageListView->childCount()); + return false; + } +} + +bool IncomingDialog::incomeDefault(ScheduleItemIn *item) +{ + if (mScheduler->acceptTransaction(item->event(),item->method(),item->status())) { + delete item; + emit numMessagesChanged(mMessageListView->childCount()); + return true; + } + else { + KMessageBox::error(this,i18n("Unable to accept the IMIP-message. It may be a problem with the email addresses.")); + kdDebug() << "IncomingDialog::acceptMessage(): Error!" << endl; + return false; + } + return false; +} + +bool IncomingDialog::incomeRequest(ScheduleItemIn *item) +{ + if (item->event()->type()=="FreeBusy") { + //handel freebusy request + IncidenceBase *inc = item->event(); + QDateTime start = inc->dtStart(); + QDateTime end = start.addDays(inc->duration()/86400); + + FreeBusy *freebusy = new FreeBusy(mCalendar, start, end); + freebusy->setOrganizer(inc->organizer()); + Attendee *att = new Attendee(KOPrefs::instance()->fullName(), + KOPrefs::instance()->email()); + freebusy->addAttendee(att); + + kdDebug() << "calendarview: schedule_publish_freebusy: startDate: " + << KGlobal::locale()->formatDateTime( start ) << " End Date: " + << KGlobal::locale()->formatDateTime( end ) << endl; + + if (mOutgoing->addMessage(freebusy,Scheduler::Reply)) { + delete item; + emit numMessagesChanged(mMessageListView->childCount()); + delete(freebusy); + return true; + } + return false; + } else { + return incomeDefault(item); + } + return false; +} + +bool IncomingDialog::automaticAction(ScheduleItemIn *item) +{ + bool autoAction = false; + IncidenceBase *inc = item->event(); + Scheduler::Method method = item->method(); + + if( inc->type()=="FreeBusy" ) { + if ( method==Scheduler::Request ) { + if ( KOPrefs::instance()->mIMIPAutoFreeBusy==KOPrefs::addressbookAuto ) { + // reply freebusy information + if ( checkOrganizerInAddressbook(inc->organizer()) ) { + incomeRequest(item); + } + } else return false; + } else { + + if ( method==Scheduler::Reply ) { + if ( KOPrefs::instance()->mIMIPAutoFreeBusy==KOPrefs::addressbookAuto ) { + // insert freebusy information + //if ( checkAttendeesInAddressbook(inc) ) + + } else return false; + } else { + if ( method==Scheduler::Publish) { + if ( KOPrefs::instance()->mIMIPAutoFreeBusy==KOPrefs::addressbookAuto ) { + // insert freebusy information + //if ( checkOrganizerInAddressbook(inc->organizer()) ) + + } + } else return false; + } + } + } + + if ( inc->type()=="Event" ) { + if ( method==Scheduler::Request || method==Scheduler::Publish ) { + if ( KOPrefs::instance()->mIMIPAutoInsertRequest==KOPrefs::addressbookAuto ) { + // insert event + if ( checkOrganizerInAddressbook(inc->organizer()) ) + autoAction = acceptMessage(item); + } else return false; + } else { + + if ( method==Scheduler::Reply ) { + if ( KOPrefs::instance()->mIMIPAutoInsertReply==KOPrefs::addressbookAuto ) { + // update event information + if ( checkAttendeesInAddressbook(inc) ) + autoAction = acceptMessage(item); + } else return false; + } else { + + if ( method==Scheduler::Refresh ) { + if ( KOPrefs::instance()->mIMIPAutoRefresh==KOPrefs::addressbookAuto ) { + // send refresh-information + if ( checkAttendeesInAddressbook(inc) ) + autoAction = acceptMessage(item); + else return false; + } else return false; + } else return false; + } + } + } + return autoAction; +} + +bool IncomingDialog::checkOrganizerInAddressbook(QString organizer) +{ + bool inBook = false; +#ifndef KORG_NOKABC + KABC::AddressBook *add_book = KABC::StdAddressBook::self(); + KABC::Addressee::List addressList; + addressList = add_book->findByEmail(organizer); + if ( addressList.size()>0 ) inBook = true; +#endif + return inBook; +} + +bool IncomingDialog::checkAttendeesInAddressbook(IncidenceBase *inc) +{ + bool inBook = false; +#ifndef KORG_NOKABC + KABC::AddressBook *add_book = KABC::StdAddressBook::self(); + KABC::Addressee::List addressList; + QPtrList <Attendee> attendees; + Attendee *att; + attendees = inc->attendees(); + for (att=attendees.first();att;att=attendees.next()) { + addressList = add_book->findByEmail(att->email()); + if (addressList.size()>0 ) inBook = true; + } +#endif + return inBook; +} + +#include "incomingdialog.moc" diff --git a/korganizer/incomingdialog.h b/korganizer/incomingdialog.h new file mode 100644 index 0000000..413ce6a --- a/dev/null +++ b/korganizer/incomingdialog.h @@ -0,0 +1,110 @@ +/* + 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. +*/ +#ifndef INCOMINGDIALOG_H +#define INCOMINGDIALOG_H + +#include <qlistview.h> + +#include <libkcal/calendar.h> +#include <libkcal/scheduler.h> + +#include "incomingdialog_base.h" +#include "outgoingdialog.h" + +using namespace KCal; + +class ScheduleItemIn : public QListViewItem +{ + public: + ScheduleItemIn(QListView *parent,IncidenceBase *ev,Scheduler::Method method, + ScheduleMessage::Status status); + virtual ~ScheduleItemIn() {} + + IncidenceBase *event() { return mIncidence; } + Scheduler::Method method() { return mMethod; } + ScheduleMessage::Status status() { return mStatus; } + + private: + IncidenceBase *mIncidence; + Scheduler::Method mMethod; + ScheduleMessage::Status mStatus; +}; + + +/** + This class provides the initialisation of a ScheduleItemIn for calendar + components using the Incidence::Visitor. +*/ +class ScheduleItemVisitor : public Incidence::Visitor +{ + public: + ScheduleItemVisitor(ScheduleItemIn *); + ~ScheduleItemVisitor(); + + bool visit(Event *); + bool visit(Todo *); + bool visit(Journal *); + + private: + ScheduleItemIn *mItem; +}; + + + +class IncomingDialog : public IncomingDialog_base +{ + Q_OBJECT + public: + IncomingDialog(Calendar *calendar,OutgoingDialog *outgoing, + QWidget* parent=0,const char* name=0,bool modal=false,WFlags fl=0); + ~IncomingDialog(); + + void setOutgoingDialog(OutgoingDialog *outgoing); + + signals: + void calendarUpdated(); + void numMessagesChanged(int); + public slots: + void retrieve(); + + protected slots: + void acceptAllMessages(); + void acceptMessage(); + void rejectMessage(); + void showEvent(QListViewItem *); + + protected: + bool acceptMessage(ScheduleItemIn *item); + bool incomeRefresh(ScheduleItemIn *item); + bool incomeCounter(ScheduleItemIn *item); + bool incomeDeclineCounter(ScheduleItemIn *item); + bool incomeAdd(ScheduleItemIn *item); + bool incomeRequest(ScheduleItemIn *item); + bool incomeDefault(ScheduleItemIn *item); + bool automaticAction(ScheduleItemIn *item); + + private: + bool checkAttendeesInAddressbook(IncidenceBase *inc); + bool checkOrganizerInAddressbook(QString organizer); + Calendar *mCalendar; + Scheduler *mScheduler; + OutgoingDialog *mOutgoing; +}; + +#endif // INCOMINGDIALOG_H diff --git a/korganizer/incomingdialog.moc b/korganizer/incomingdialog.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/incomingdialog.moc diff --git a/korganizer/incomingdialog_base.cpp b/korganizer/incomingdialog_base.cpp new file mode 100644 index 0000000..91740a4 --- a/dev/null +++ b/korganizer/incomingdialog_base.cpp @@ -0,0 +1,137 @@ +#include <klocale.h> +/**************************************************************************** +** Form implementation generated from reading ui file '/build/kde/cvs/korge/kdepim/korganizer/incomingdialog_base.ui' +** +** Created: Sat Mar 29 22:31:27 2003 +** by: The User Interface Compiler () +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#include "incomingdialog_base.h" + +#include <qvariant.h> +#include <qheader.h> +#include <qlistview.h> +#include <qpushbutton.h> +#include <qlayout.h> +#include <qtooltip.h> +#include <qwhatsthis.h> + +/* + * Constructs a IncomingDialog_base as a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +IncomingDialog_base::IncomingDialog_base( QWidget* parent, const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, fl ) + +{ + if ( !name ) + setName( "IncomingDialog_base" ); + IncomingDialog_baseLayout = new QGridLayout( this, 1, 1, 11, 6, "IncomingDialog_baseLayout"); + + PushButton4 = new QPushButton( this, "PushButton4" ); + + IncomingDialog_baseLayout->addWidget( PushButton4, 0, 1 ); + + PushButton7 = new QPushButton( this, "PushButton7" ); + PushButton7->setDefault( TRUE ); + + IncomingDialog_baseLayout->addWidget( PushButton7, 5, 1 ); + + mMessageListView = new QListView( this, "mMessageListView" ); + mMessageListView->addColumn( tr2i18n( "Summary" ) ); + mMessageListView->addColumn( tr2i18n( "Start Date" ) ); + mMessageListView->addColumn( tr2i18n( "Start Time" ) ); + mMessageListView->addColumn( tr2i18n( "End Date" ) ); + mMessageListView->addColumn( tr2i18n( "End Time" ) ); + mMessageListView->addColumn( tr2i18n( "Organizer" ) ); + mMessageListView->addColumn( tr2i18n( "Method" ) ); + mMessageListView->addColumn( tr2i18n( "Status" ) ); + mMessageListView->setAllColumnsShowFocus( FALSE ); + + IncomingDialog_baseLayout->addMultiCellWidget( mMessageListView, 0, 5, 0, 0 ); + + PushButton7_2 = new QPushButton( this, "PushButton7_2" ); + + IncomingDialog_baseLayout->addWidget( PushButton7_2, 3, 1 ); + + PushButton8 = new QPushButton( this, "PushButton8" ); + + IncomingDialog_baseLayout->addWidget( PushButton8, 1, 1 ); + + PushButton9 = new QPushButton( this, "PushButton9" ); + + IncomingDialog_baseLayout->addWidget( PushButton9, 2, 1 ); + QSpacerItem* spacer = new QSpacerItem( 20, 70, QSizePolicy::Minimum, QSizePolicy::Expanding ); + IncomingDialog_baseLayout->addItem( spacer, 4, 1 ); + languageChange(); + resize( QSize(525, 262).expandedTo(minimumSizeHint()) ); + + // signals and slots connections + connect( PushButton7, SIGNAL( clicked() ), this, SLOT( accept() ) ); + connect( PushButton4, SIGNAL( clicked() ), this, SLOT( retrieve() ) ); + connect( PushButton7_2, SIGNAL( clicked() ), this, SLOT( acceptAllMessages() ) ); + + // tab order + setTabOrder( PushButton7, PushButton4 ); + setTabOrder( PushButton4, PushButton7_2 ); + setTabOrder( PushButton7_2, mMessageListView ); + setTabOrder( mMessageListView, PushButton8 ); + setTabOrder( PushButton8, PushButton9 ); +} + +/* + * Destroys the object and frees any allocated resources + */ +IncomingDialog_base::~IncomingDialog_base() +{ + // no need to delete child widgets, Qt does it all for us +} + +/* + * Sets the strings of the subwidgets using the current + * language. + */ +void IncomingDialog_base::languageChange() +{ + setCaption( tr2i18n( "Scheduler - Incoming Messages" ) ); + PushButton4->setText( tr2i18n( "Retrieve &Messages" ) ); + PushButton7->setText( tr2i18n( "&Close" ) ); + mMessageListView->header()->setLabel( 0, tr2i18n( "Summary" ) ); + mMessageListView->header()->setLabel( 1, tr2i18n( "Start Date" ) ); + mMessageListView->header()->setLabel( 2, tr2i18n( "Start Time" ) ); + mMessageListView->header()->setLabel( 3, tr2i18n( "End Date" ) ); + mMessageListView->header()->setLabel( 4, tr2i18n( "End Time" ) ); + mMessageListView->header()->setLabel( 5, tr2i18n( "Organizer" ) ); + mMessageListView->header()->setLabel( 6, tr2i18n( "Method" ) ); + mMessageListView->header()->setLabel( 7, tr2i18n( "Status" ) ); + PushButton7_2->setText( tr2i18n( "Accept A&ll" ) ); + PushButton8->setText( tr2i18n( "&Accept" ) ); + PushButton9->setText( tr2i18n( "&Reject" ) ); +} + +void IncomingDialog_base::acceptAllMessages() +{ + qWarning( "IncomingDialog_base::acceptAllMessages(): Not implemented yet" ); +} + +void IncomingDialog_base::acceptMessage() +{ + qWarning( "IncomingDialog_base::acceptMessage(): Not implemented yet" ); +} + +void IncomingDialog_base::rejectMessage() +{ + qWarning( "IncomingDialog_base::rejectMessage(): Not implemented yet" ); +} + +void IncomingDialog_base::retrieve() +{ + qWarning( "IncomingDialog_base::retrieve(): Not implemented yet" ); +} + +#include "incomingdialog_base.moc" diff --git a/korganizer/incomingdialog_base.h b/korganizer/incomingdialog_base.h new file mode 100644 index 0000000..7732384 --- a/dev/null +++ b/korganizer/incomingdialog_base.h @@ -0,0 +1,51 @@ +/**************************************************************************** +** Form interface generated from reading ui file '/build/kde/cvs/korge/kdepim/korganizer/incomingdialog_base.ui' +** +** Created: Sat Mar 29 22:24:26 2003 +** by: The User Interface Compiler () +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#ifndef INCOMINGDIALOG_BASE_H +#define INCOMINGDIALOG_BASE_H + +#include <qvariant.h> +#include <qdialog.h> + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QListView; +class QListViewItem; +class QPushButton; + +class IncomingDialog_base : public QDialog +{ + Q_OBJECT + +public: + IncomingDialog_base( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~IncomingDialog_base(); + + QPushButton* PushButton4; + QPushButton* PushButton7; + QListView* mMessageListView; + QPushButton* PushButton7_2; + QPushButton* PushButton8; + QPushButton* PushButton9; + +protected: + QGridLayout* IncomingDialog_baseLayout; + +protected slots: + virtual void languageChange(); + + virtual void acceptAllMessages(); + virtual void acceptMessage(); + virtual void rejectMessage(); + virtual void retrieve(); + +}; + +#endif // INCOMINGDIALOG_BASE_H diff --git a/korganizer/incomingdialog_base.moc b/korganizer/incomingdialog_base.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/incomingdialog_base.moc diff --git a/korganizer/interfaces/korganizer/baseview.h b/korganizer/interfaces/korganizer/baseview.h new file mode 100644 index 0000000..09f8ba3 --- a/dev/null +++ b/korganizer/interfaces/korganizer/baseview.h @@ -0,0 +1,192 @@ +/* + This file is part of the KOrganizer interfaces. + Copyright (c) 1999 Cornelius Schumacher <schumacher@kde.org> + Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#ifndef KORG_BASEVIEW_H +#define KORG_BASEVIEW_H +// $Id$ +// KOBaseView is the abstract base class of all calendar views. + +#include <qwidget.h> +#include <qptrlist.h> +#include <qvaluelist.h> + +#include <klocale.h> +#include <kdebug.h> +#include <kmessagebox.h> + +#include <libkcal/event.h> +#include <libkcal/calendar.h> + +using namespace KCal; + +class CalPrinter; + +namespace KOrg { + +class CalPrinterBase +{ + public: + enum PrintType { Day, Week, Month, Todolist }; +}; + + +/** + This class provides an interface for all views being displayed within the main + calendar view. It has functions to update the view, to specify date range and + other display parameter and to return selected objects. An important class, + which inherits KOBaseView is KOEventView, which provides the interface for all + views of event data like the agenda or the month view. + + @short Base class for calendar views + @author Preston Brown, Cornelius Schumacher + @see KOTodoView, KOEventView, KOListView, KOAgendaView, KOMonthView +*/ +class BaseView : public QWidget +{ + Q_OBJECT + public: + /** + Constructs a view. + + @param cal Pointer to the calendar object from which events + will be retrieved for display. + @param parent parent widget. + @param name name of this widget. + */ + BaseView(Calendar *cal, QWidget *parent = 0, const char *name = 0) : + QWidget(parent, name), mCalendar(cal) {} + + /** + Destructor. Views will do view-specific cleanups here. + */ + virtual ~BaseView() {} + + /** + Return calendar object of this view. + */ + Calendar *calendar() { return mCalendar; } + + /** + @return a list of selected events. Most views can probably only + select a single event at a time, but some may be able to select + more than one. + */ + virtual QPtrList<Incidence> selectedIncidences() = 0; + + /** + @return a list of the dates of selected events. Most views can probably only + select a single event at a time, but some may be able to select + more than one. + */ + virtual DateList selectedDates() = 0; + + /** + Generate a print preview of this event view. + + @param calPrinter Calendar printer object used for printing + @param fd from date + @param td to date + */ +/* + The date parameters should be determined by the view itself and not given as + parameters. At the moment I just move the code from the topwidget to the + individual views. +*/ + virtual void printPreview(CalPrinter *, + const QDate &, const QDate &) + { + KMessageBox::sorry(this, i18n("Unfortunately, we don't handle printing for\n" + "that view yet.\n")); + } + + /** + Print this view. + + @param calPrinter Calendar printer object used for printing + */ + virtual void print(CalPrinter *) + { + KMessageBox::sorry(this, i18n("Unfortunately, we don't handle printing for\n" + "that view yet.\n")); + } + + /** + Return number of currently shown dates. A return value of 0 means no idea. + */ + virtual int currentDateCount() = 0; + + /** Return if this view is a view for displaying events. */ + virtual bool isEventView() { return false; } + + public slots: + /** + Show incidences for the given date range. The date range actually shown may be + different from the requested range, depending on the particular requirements + of the view. + + @param start Start of date range. + @param end End of date range. + */ + virtual void showDates( const QDate &start, const QDate &end ) = 0; + + /** + Show given events. Depending on the actual view it might not be possible to + show all given events. + + @param eventList a list of events to show. + */ + virtual void showEvents(QPtrList<Event> eventList) = 0; + + /** + Updates the current display to reflect changes that may have happened + in the calendar since the last display refresh. + */ + virtual void updateView() = 0; + + /** + Write all unsaved data back to calendar store. + */ + virtual void flushView() {} + + /** + Updates the current display to reflect the changes to one particular event. + */ + virtual void changeEventDisplay(Event *, int) = 0; + + /** + Re-reads the KOrganizer configuration and picks up relevant + changes which are applicable to the view. + */ + virtual void updateConfig() {} + + /** + Clear selection. The incidenceSelected signal is not emitted. + */ + virtual void clearSelection() {} + + signals: + void incidenceSelected( Incidence * ); + + protected: + Calendar *mCalendar; +}; + +} +#endif diff --git a/korganizer/interfaces/korganizer/calendarviewbase.h b/korganizer/interfaces/korganizer/calendarviewbase.h new file mode 100644 index 0000000..3c715b1 --- a/dev/null +++ b/korganizer/interfaces/korganizer/calendarviewbase.h @@ -0,0 +1,65 @@ +/* + This file is part of the KOrganizer interfaces. + Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#ifndef KORG_CALENDARVIEWBASE_H +#define KORG_CALENDARVIEWBASE_H +// $Id$ + +#include <qwidget.h> +#include <qlayout.h> + + +#include <libkcal/calendar.h> + +#include <korganizer/baseview.h> + +namespace KOrg { + +/** + @short interface for main calendar view widget + @author Cornelius Schumacher +*/ +class CalendarViewBase : public QWidget +{ + Q_OBJECT + public: + CalendarViewBase(QWidget *parent, const char *name) : + QWidget(parent,name) {new QVBoxLayout(this);} + virtual ~CalendarViewBase() {}; + + virtual KCal::Calendar *calendar() = 0; + + virtual QDate startDate() = 0; + virtual QDate endDate() = 0; + + virtual Incidence *currentSelection() = 0; + + virtual void addView(KOrg::BaseView *) = 0; + + /** changes the view to be the currently selected view */ + virtual void showView(KOrg::BaseView *) = 0; + + public slots: + virtual void updateView() = 0; + +}; + +} + +#endif diff --git a/korganizer/journalentry.cpp b/korganizer/journalentry.cpp new file mode 100644 index 0000000..d1d7946 --- a/dev/null +++ b/korganizer/journalentry.cpp @@ -0,0 +1,170 @@ +/* + 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 <kdebug.h> +#include <kglobal.h> +#include <klocale.h> +#include <ktextedit.h> +#include "koprefs.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) +{ + mCalendar = calendar; + mJournal = 0; + mDirty = false; + + mTitleLabel = new QLabel(i18n("Title"),this); + mTitleLabel->setMargin(2); + mTitleLabel->setAlignment(AlignCenter); + + mEditor = new KTextEdit(this); + connect(mEditor,SIGNAL(textChanged()),SLOT(setDirty())); +#ifndef DESKTOP_VERSION + QPEApplication::setStylusOperation( mEditor, QPEApplication::RightOnHold ); +#endif + mEditor->setWordWrap( KTextEdit::WidgetWidth ); + QBoxLayout *topLayout = new QVBoxLayout(this); + topLayout->addWidget(mTitleLabel); + topLayout->addWidget(mEditor); + mEditor->installEventFilter(this); +} + +JournalEntry::~JournalEntry() +{ +} + +void JournalEntry::setDate(const QDate &date) +{ + writeJournal(); + + mTitleLabel->setText(KGlobal::locale()->formatDate(date)); + + + mDate = date; +} + +void JournalEntry::setJournal(Journal *journal) +{ + writeJournal(); + + mJournal = journal; + + mEditor->setText(mJournal->description()); + + mDirty = false; +} + +Journal *JournalEntry::journal() const +{ + return mJournal; +} + +void JournalEntry::setDirty() +{ + mDirty = true; + +// kdDebug() << "JournalEntry::setDirty()" << endl; +} + +void JournalEntry::clear() +{ + mJournal = 0; + mEditor->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() +{ +// kdDebug() << "JournalEntry::writeJournal()" << endl; + if (!mDirty) return; + + if (mEditor->text().isEmpty()) { + if ( mJournal ) { + mDirty = false; + bool conf = KOPrefs::instance()->mConfirm; + KOPrefs::instance()->mConfirm = false; + emit deleteJournal(mJournal); + KOPrefs::instance()->mConfirm = conf; + mJournal = 0; + } + return; + } + +// kdDebug() << "JournalEntry::writeJournal()..." << endl; + + if (!mJournal) { + mJournal = new Journal; + mJournal->setDtStart(QDateTime(mDate,QTime(0,0,0))); + mCalendar->addJournal(mJournal); + } + + mJournal->setDescription(mEditor->text()); + + mDirty = false; +} + +void JournalEntry::flushEntry() +{ + if (!mDirty) return; + + writeJournal(); +} +void JournalEntry::keyPressEvent ( QKeyEvent * e ) +{ + e->ignore(); + +} diff --git a/korganizer/journalentry.h b/korganizer/journalentry.h new file mode 100644 index 0000000..1f784f4 --- a/dev/null +++ b/korganizer/journalentry.h @@ -0,0 +1,73 @@ +/* + 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 JOURNALENTRY_H +#define JOURNALENTRY_H +// +// Widget showing one Journal entry + +#include <qframe.h> + +#include <libkcal/calendar.h> + +class QLabel; +class KTextEdit; + +using namespace KCal; + +class JournalEntry : public QFrame { + Q_OBJECT + public: + JournalEntry(Calendar *,QWidget *parent); + virtual ~JournalEntry(); + + void setJournal(Journal *); + Journal *journal() const; + + void setDate(const QDate &); + + void clear(); + + void flushEntry(); + + protected slots: + void setDirty(); + signals: + void deleteJournal(Journal *); + + protected: + bool eventFilter( QObject *o, QEvent *e ); + + void writeJournal(); + + private: + Calendar *mCalendar; + Journal *mJournal; + QDate mDate; + void keyPressEvent ( QKeyEvent * ) ; + QLabel *mTitleLabel; + KTextEdit *mEditor; + + bool mDirty; +}; + +#endif diff --git a/korganizer/journalentry.moc b/korganizer/journalentry.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/journalentry.moc diff --git a/korganizer/kdatenavigator.cpp b/korganizer/kdatenavigator.cpp new file mode 100644 index 0000000..12e983b --- a/dev/null +++ b/korganizer/kdatenavigator.cpp @@ -0,0 +1,364 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2001,2002 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. +*/ + +#include <qstring.h> +#include <qkeycode.h> +#include <qlayout.h> +#include <qtimer.h> +#include <qframe.h> +#include <qlabel.h> +#include <qapplication.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kglobal.h> + +#include "koglobals.h" +#include "koprefs.h" +#ifndef KORG_NOPLUGINS +#include "kocore.h" +#endif + +#include <kcalendarsystem.h> + +#include "navigatorbar.h" + +#include "kdatenavigator.h" + +KDateNavigator::KDateNavigator( QWidget *parent, Calendar *calendar, + bool show_week_nums, const char *name, + QDate startDate ) + : QFrame(parent, name), + updateTimer(0L) +{ + mCalendar = calendar; + + setFrameStyle(QFrame::NoFrame); + + QGridLayout *topLayout = new QGridLayout(this,8,8); + + if (! startDate.isValid()) { + kdDebug() << "KDateNavigator::KDateNavigator(): an invalid date was passed as a parameter!" << endl; + startDate = QDate::currentDate(); + } + + mSelectedDates.append(startDate); + m_MthYr = startDate; + m_bShowWeekNums = show_week_nums; + + setFont( KOPrefs::instance()->mDateNavigatorFont ); + mNavigatorBar = new NavigatorBar( startDate, this ); + topLayout->addMultiCellWidget( mNavigatorBar, 0, 0, 0, 7 ); + //mNavigatorBar->resize( 1,1); + connect( mNavigatorBar, SIGNAL( goPrevYear() ), SIGNAL( goPrevYear() ) ); + connect( mNavigatorBar, SIGNAL( goPrevMonth() ), SIGNAL( goPrevMonth() ) ); + connect( mNavigatorBar, SIGNAL( goNextMonth() ), SIGNAL( goNextMonth() ) ); + connect( mNavigatorBar, SIGNAL( goNextYear() ), SIGNAL( goNextYear() ) ); + connect( mNavigatorBar, SIGNAL( monthSelected( int ) ), SIGNAL( monthSelected( int ) ) ); + + // get the day of the week on the first day + QDate dayone(m_MthYr.year(), m_MthYr.month(), 1); + m_fstDayOfWk = dayone.dayOfWeek(); + + int i; + + // Set up the heading fields. + for( i = 0; i < 7; i++ ) { + headings[i] = new QLabel("",this); + //headings[i]->setFont(QFont("Arial", 10, QFont::Bold)); + headings[i]->setAlignment(AlignCenter); + + topLayout->addWidget(headings[i],1,i+1); + } + + // Create the weeknumber labels + for( i = 0; i < 6; i++ ) { + weeknos[i] = new QLabel(this); + weeknos[i]->setAlignment(AlignCenter); + //weeknos[i]->setFont(QFont("Arial", 10)); + if(!show_week_nums) { + weeknos[i]->hide(); + } + weeknos[i]->installEventFilter(this); + + topLayout->addWidget(weeknos[i],i+2,0); + } + + daymatrix = new KODayMatrix( this, mCalendar, dayone, + "KDateNavigator::DayMatrix"); + daymatrix->setFrameStyle(QFrame::Panel|QFrame::Sunken); + daymatrix->setLineWidth(1); + + connect( daymatrix, SIGNAL( selected( const KCal::DateList & ) ), + SIGNAL( datesSelected( const KCal::DateList & ) ) ); + + connect( daymatrix, SIGNAL( eventDropped( Event * ) ), + SIGNAL( eventDropped( Event * ) ) ); + + topLayout->addMultiCellWidget(daymatrix,2,7,1,7); + + // read settings from configuration file. + updateConfig(); + enableRollover(FollowMonth); + setFixedSize ( sizeHint() ); +} + +void KDateNavigator::enableRollover(RolloverType r) +{ + switch(r) + { + case None : + if (updateTimer) + { + updateTimer->stop(); + delete updateTimer; + updateTimer=0L; + } + break; + case FollowDay : + case FollowMonth : + if (!updateTimer) + { + updateTimer = new QTimer(this); + QObject::connect(updateTimer,SIGNAL(timeout()), + this,SLOT(possiblyPastMidnight())); + } + updateTimer->start(0,true); + lastDayChecked = QDate::currentDate(); + } + updateRollover=r; +} + + +KDateNavigator::~KDateNavigator() +{ +} + + +void KDateNavigator::passedMidnight() +{ + QDate today = QDate::currentDate(); + bool emitMonth = false; + + if (today.month() != lastDayChecked.month()) + { + if (updateRollover==FollowMonth && + daymatrix->isEndOfMonth()) { + goNextMonth(); + emitMonth=true; + } + } + daymatrix->recalculateToday(); + daymatrix->repaint(); + emit dayPassed(today); + if (emitMonth) { emit monthPassed(today); } +} + +/* slot */ void KDateNavigator::possiblyPastMidnight() +{ + if (lastDayChecked!=QDate::currentDate()) + { + passedMidnight(); + lastDayChecked=QDate::currentDate(); + } + // Set the timer to go off 1 second after midnight + // or after 8 minutes, whichever comes first. + if (updateTimer) + { + QTime now = QTime::currentTime(); + QTime midnight = QTime(23,59,59); + int msecsWait = QMIN(480000,now.msecsTo(midnight)+2000); + + // qDebug(QString("Waiting %1 msec from %2 to %3.").arg(msecsWait)) + // .arg(now.toString()).arg(midnight.toString())); + + updateTimer->stop(); + updateTimer->start(msecsWait,true); + } +} + +void KDateNavigator::updateDates() +{ + // Find the first day of the week of the current month. + //int d1 = KOGlobals::self()->calendarSystem()->day( m_MthYr ); + QDate dayone( m_MthYr.year(), m_MthYr.month(), m_MthYr.day() ); + int d2 = KOGlobals::self()->calendarSystem()->day( dayone ); + //int di = d1 - d2 + 1; + dayone = dayone.addDays( -d2 + 1 ); + + int m_fstDayOfWkCalsys = KOGlobals::self()->calendarSystem()->dayOfWeek( dayone ); + + // If month begins on Monday and Monday is first day of week, + // month should begin on second line. Sunday doesn't have this problem. + int nextLine = ( ( m_fstDayOfWkCalsys == 1) && + ( KGlobal::locale()->weekStartsMonday() == 1 ) ) ? 7 : 0; + + // update the matrix dates + int index = (KGlobal::locale()->weekStartsMonday() ? 1 : 0) - m_fstDayOfWkCalsys - nextLine; + + + daymatrix->updateView(dayone.addDays(index)); +//each updateDates is followed by an updateView -> repaint is issued there ! +// daymatrix->repaint(); +} + +void KDateNavigator::updateDayMatrix() +{ + daymatrix->updateView(); + daymatrix->repaint(); +} + + +void KDateNavigator::updateView() +{ + + setUpdatesEnabled( false ); + + int i; + +// kdDebug() << "updateView() -> daymatrix->updateView()" << endl; + daymatrix->updateView(); + + // set the week numbers. + for(i = 0; i < 6; i++) { + QString weeknum; + // remember, according to ISO 8601, the first week of the year is the + // first week that contains a thursday. Thus we must subtract off 4, + // not just 1. + + //ET int dayOfYear = buttons[(i + 1) * 7 - 4]->date().dayOfYear(); + int dayOfYear = KOGlobals::self()->calendarSystem()->dayOfYear((daymatrix->getDate((i+1)*7-4))); + + if (dayOfYear % 7 != 0) + weeknum.setNum(dayOfYear / 7 + 1); + else + weeknum.setNum(dayOfYear / 7); + weeknos[i]->setText(weeknum); + } + + setUpdatesEnabled( true ); +// kdDebug() << "updateView() -> repaint()" << endl; + repaint(); + daymatrix->repaint(); +} + +void KDateNavigator::updateConfig() +{ + int day; + for(int i=0; i<7; i++) { + // take the first letter of the day name to be the abbreviation + if (KGlobal::locale()->weekStartsMonday()) { + day = i+1; + } else { + if (i==0) day = 7; + else day = i; + } + QString dayName = KOGlobals::self()->calendarSystem()->weekDayName( day, + true ); + if ( KOPrefs::instance()->mCompactDialogs ) dayName = dayName.left( 1 ); + headings[i]->setText( dayName ); + } + updateDates(); + updateView(); +} + +void KDateNavigator::setShowWeekNums(bool enabled) +{ + m_bShowWeekNums = enabled; + for(int i=0; i<6; i++) { + if(enabled) + weeknos[i]->show(); + else + weeknos[i]->hide(); + } + resize(size()); +} + +void KDateNavigator::selectDates(const DateList& dateList) +{ + + if (dateList.count() > 0) { + mNavigatorBar->selectDates( dateList ); + mSelectedDates = dateList; + + // set our record of the month and year that this datetbl is + // displaying. + m_MthYr = mSelectedDates.first(); + + + // set our record of the first day of the week of the current + // month. This needs to be done before calling dayToIndex, since it + // relies on this information being up to date. + QDate dayone(m_MthYr.year(), m_MthYr.month(), 1); + m_fstDayOfWk = dayone.dayOfWeek(); + + updateDates(); + + daymatrix->setSelectedDaysFrom(*(dateList.begin()), *(--dateList.end())); + + updateView(); + } +} + +int KDateNavigator::dayNum(int row, int col) +{ + return 7 * (row - 1) + (col + 1) - m_fstDayOfWk; +} + +int KDateNavigator::dayToIndex(int dayNum) +{ + int row, col; + + row = (dayNum+m_fstDayOfWk-1-(KGlobal::locale()->weekStartsMonday() ? 1 : 0)) / 7; + if (KGlobal::locale()->weekStartsMonday() && (m_fstDayOfWk == 1)) + row++; + col = (dayNum+m_fstDayOfWk-1-(KGlobal::locale()->weekStartsMonday() ? 1 : 0)) % 7; + return row * 7 + col; +} + +void KDateNavigator::wheelEvent (QWheelEvent *e) +{ + if(e->delta()>0) emit goPrevious(); + else emit goNext(); + + e->accept(); +} + +bool KDateNavigator::eventFilter (QObject *o,QEvent *e) +{ + if (e->type() == QEvent::MouseButtonPress) { + int i; + for(i=0;i<6;++i) { + if (o == weeknos[i]) { + QDate weekstart = daymatrix->getDate(i*7); + emit weekClicked(weekstart); + break; + } + } + return true; + } else { + return false; + } +} + +#include "kdatenavigator.moc" diff --git a/korganizer/kdatenavigator.h b/korganizer/kdatenavigator.h new file mode 100644 index 0000000..3ae1648 --- a/dev/null +++ b/korganizer/kdatenavigator.h @@ -0,0 +1,148 @@ +/* + 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 KDATENAVIGATOR_H +#define KDATENAVIGATOR_H + +#include <qframe.h> +#include <qdatetime.h> +#include <qlabel.h> + +#include <libkcal/calendar.h> + +#include "kodaymatrix.h" + +class QPushButton; +class QTimer; + +class KCalendarSystem; + +class NavigatorBar; + +class KDateNavigator: public QFrame +{ + Q_OBJECT + public: + KDateNavigator( QWidget *parent = 0, Calendar *calendar = 0, + bool show_week_numbers = false, const char *name = 0, + QDate date = QDate::currentDate() ); + ~KDateNavigator(); + + /** The DateNavigator automatically checks for + * the passage of midnight. If rollover type is + * set to None, no signals are emitted and no + * processing is done. With rollover set to + * FollowDay, the day highlighter changes at + * midnight and dayPassed() is emitted. + * With FollowMonth, it has the same effect + * as FollowDay but also adjusts the month that is + * visible and emits monthPassed() when the month changes. + */ + enum RolloverType { None, FollowDay, FollowMonth } ; + void enableRollover( RolloverType ); + + void setShowWeekNums( bool enabled ); + + public slots: + void selectDates( const KCal::DateList & ); + void updateView(); + void updateConfig(); + void updateDayMatrix(); + + signals: + void datesSelected( const KCal::DateList & ); + void eventDropped( Event * ); + void weekClicked( const QDate &); + + void goPrevious(); + void goNext(); + + void goNextMonth(); + void goPrevMonth(); + void goNextYear(); + void goPrevYear(); + void monthSelected( int ); + + // Signals emitted at midnight carrying the new date. + void dayPassed( QDate ); + void monthPassed( QDate ); + + protected slots: + + /** + * Called regularly to see if we need to update the view + * wrt. the today box and the month box. Only important + * if you leave KOrganizer idle for long periods of time. + * + * Until we have a reliable way of setting QTimers to go + * off at a particular wall-clock time, we need this, + * which calls passedMidnight() at the right moments. + */ + void possiblyPastMidnight(); + + /** handles updating the view when midnight has come by due to idle time. + * + */ + void passedMidnight(); + + protected: + void updateDates(); + + void wheelEvent (QWheelEvent *); + + bool eventFilter (QObject *,QEvent *); + + private: + NavigatorBar *mNavigatorBar; + + QFrame *headingSep; + QFrame *weeknumSep; + QLabel *headings[7]; + QLabel *weeknos[7]; + KODayMatrix *daymatrix; + + KCal::DateList mSelectedDates; + QDate m_MthYr; + int m_fstDayOfWk; + bool m_bShowWeekNums; + + int dayNum(int row, int col); + int dayToIndex(int dayNum); + + Calendar *mCalendar; + KCalendarSystem *mCalendarSystem; + + const QString *curHeaders; + + /** used to update the day view periodically, in particular every + * midnight to move the "today" rectangle. + */ + QTimer *updateTimer; + QDate lastDayChecked; + RolloverType updateRollover; + + // Disabling copy constructor and assignment operator + KDateNavigator(const KDateNavigator & ); + KDateNavigator &operator=(const KDateNavigator &); +}; + +#endif diff --git a/korganizer/kdatenavigator.moc b/korganizer/kdatenavigator.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/kdatenavigator.moc diff --git a/korganizer/koagenda.cpp b/korganizer/koagenda.cpp new file mode 100644 index 0000000..607c250 --- a/dev/null +++ b/korganizer/koagenda.cpp @@ -0,0 +1,1932 @@ +/* + 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 "koagenda.moc" + +#include <libkcal/event.h> +#include <libkcal/todo.h> + +#ifndef DESKTOP_VERSION +#include <qpe/qpeapplication.h> +#endif + +//extern bool globalFlagBlockPainting; +extern int globalFlagBlockAgenda; +extern int globalFlagBlockAgendaItemPaint; +extern int globalFlagBlockAgendaItemUpdate; +extern int globalFlagBlockStartup; + +//////////////////////////////////////////////////////////////////////////// +MarcusBains::MarcusBains(KOAgenda *_agenda,const char *name) + : QFrame(_agenda->viewport(),name), agenda(_agenda) +{ + setLineWidth(0); + setMargin(0); + setBackgroundColor(Qt::red); + minutes = new QTimer(this); + connect(minutes, SIGNAL(timeout()), this, SLOT(updateLoc())); + minutes->start(0, true); + + mTimeBox = new QLabel(this); + mTimeBox->setAlignment(Qt::AlignRight | Qt::AlignBottom); + QPalette pal = mTimeBox->palette(); + pal.setColor(QColorGroup::Foreground, Qt::red); + mTimeBox->setPalette(pal); + //mTimeBox->setAutoMask(true); + + agenda->addChild(mTimeBox); + + oldToday = -1; +} + +MarcusBains::~MarcusBains() +{ + delete minutes; +} + +int MarcusBains::todayColumn() +{ + QDate currentDate = QDate::currentDate(); + + DateList dateList = agenda->dateList(); + DateList::ConstIterator it; + int col = 0; + for(it = dateList.begin(); it != dateList.end(); ++it) { + if((*it) == currentDate) + return KOGlobals::self()->reverseLayout() ? + agenda->columns() - 1 - col : col; + ++col; + } + + return -1; +} +void MarcusBains::updateLoc() +{ + updateLocation(); +} +void MarcusBains::updateLocation(bool recalculate) +{ + + QTime tim = QTime::currentTime(); + //qDebug(" MarcusBains::updateLocation %s ", tim.toString().latin1()); + if((tim.hour() == 0) && (oldTime.hour()==23)) + recalculate = true; + + int mins = tim.hour()*60 + tim.minute(); + int minutesPerCell = 24 * 60 / agenda->rows(); + int y = mins*agenda->gridSpacingY()/minutesPerCell; + int today = recalculate ? todayColumn() : oldToday; + int x = agenda->gridSpacingX()*today; + bool disabled = !(KOPrefs::instance()->mMarcusBainsEnabled); + + oldTime = tim; + oldToday = today; + + if(disabled || (today<0)) { + hide(); mTimeBox->hide(); + return; + } else { + show(); mTimeBox->show(); + } + + if(recalculate) + setFixedSize(agenda->gridSpacingX(),1); + agenda->moveChild(this, x, y); + raise(); + + if(recalculate) + //mTimeBox->setFont(QFont("helvetica",10)); + mTimeBox->setFont(KOPrefs::instance()->mMarcusBainsFont); + + mTimeBox->setText(KGlobal::locale()->formatTime(tim, KOPrefs::instance()->mMarcusBainsShowSeconds)); + mTimeBox->adjustSize(); + // the -2 below is there because there is a bug in this program + // somewhere, where the last column of this widget is a few pixels + // narrower than the other columns. + int offs = (today==agenda->columns()-1) ? -4 : 0; + agenda->moveChild(mTimeBox, + x+agenda->gridSpacingX()-mTimeBox->width()+offs-1, + y-mTimeBox->height()); + + mTimeBox->raise(); + //mTimeBox->setAutoMask(true); + minutes->start(5000,true); +} + + +//////////////////////////////////////////////////////////////////////////// + + +/* + Create an agenda widget with rows rows and columns columns. +*/ +KOAgenda::KOAgenda(int columns,int rows,int rowSize,QWidget *parent, + const char *name,WFlags f) : + QScrollView(parent,name,f) +{ + + mColumns = columns; + mRows = rows; + mGridSpacingY = rowSize; + mAllDayMode = false; +#ifndef DESKTOP_VERSION + QPEApplication::setStylusOperation( viewport(), QPEApplication::RightOnHold ); +#endif + mHolidayMask = 0; + init(); +} + +/* + Create an agenda widget with columns columns and one row. This is used for + all-day events. +*/ +KOAgenda::KOAgenda(int columns,QWidget *parent,const char *name,WFlags f) : + QScrollView(parent,name,f) +{ + + blockResize = false; + mColumns = columns; + mRows = 1; + //qDebug("aaaaaaaaaaaaaaaaaaldays %d ", KOPrefs::instance()->mAllDaySize); + mGridSpacingY = KOPrefs::instance()->mAllDaySize; + mAllDayMode = true; +#ifndef DESKTOP_VERSION + QPEApplication::setStylusOperation( viewport(), QPEApplication::RightOnHold ); +#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() +{ +#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); + } +} + +void KOAgenda::clear() +{ + KOAgendaItem *item; + for ( item=mItems.first(); item != 0; item=mItems.next() ) { + mUnusedItems.append( item ); + //item->hide(); + } + mItems.clear(); + mSelectedItem = 0; + clearSelection(); +} + +void KOAgenda::clearSelection() +{ + mSelectionCellX = 0; + mSelectionYTop = 0; + mSelectionHeight = 0; +} + +void KOAgenda::marcus_bains() +{ + if(mMarcusBains) mMarcusBains->updateLocation(true); +} + + +void KOAgenda::changeColumns(int columns) +{ + if (columns == 0) { + kdDebug() << "KOAgenda::changeColumns() called with argument 0" << endl; + return; + } + + clear(); + + mColumns = columns; +// setMinimumSize(mColumns * 10, mGridSpacingY + 1); +// init(); +// update(); + //qDebug("KOAgenda::changeColumns "); + computeSizes(); + // QResizeEvent event( size(), size() ); + + //QApplication::sendEvent( this, &event ); +} + +/* + This is the eventFilter function, which gets all events from the KOAgendaItems + contained in the agenda. It has to handle moving and resizing for all items. +*/ +bool KOAgenda::eventFilter ( QObject *object, QEvent *event ) +{ +// kdDebug() << "KOAgenda::eventFilter" << endl; + switch(event->type()) { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonDblClick: + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: + return eventFilter_mouse(object, static_cast<QMouseEvent *>(event)); + + case (QEvent::Leave): + if (!mActionItem) + setCursor(arrowCursor); + return true; + + default: + return QScrollView::eventFilter(object,event); + } +} + + +bool KOAgenda::eventFilter_mouse(QObject *object, QMouseEvent *me) +{ + //qDebug("KOAgenda::eventFilter_mous "); + QPoint viewportPos; + if (object != viewport()) { + viewportPos = ((QWidget *)object)->mapToParent(me->pos()); + } else { + viewportPos = me->pos(); + } + static int startX = 0; + static int startY = 0; + static bool block = true; + switch (me->type()) { + case QEvent::MouseButtonPress: + //qDebug("QEvent::MouseButtonPress: "); + // kdDebug() << "koagenda: filtered button press" << endl; + if (object != viewport()) { + if (me->button() == RightButton) { + + mClickedItem = (KOAgendaItem *)object; + if (mClickedItem) { + selectItem(mClickedItem); + // emit showIncidencePopupSignal(mClickedItem->incidence()); + } + //mItemPopup->popup(QCursor::pos()); + } else { + mActionItem = (KOAgendaItem *)object; + if (mActionItem) { + if ( mSelectionHeight > 0 ) { + int selectionCellX = mSelectionCellX * mGridSpacingX; + int selectionYTop = mSelectionYTop; + int gridSpacingX = mGridSpacingX; + int selectionHeight = mSelectionHeight; + clearSelection(); + repaintContents( selectionCellX, selectionYTop, + gridSpacingX, selectionHeight,false ); + } + selectItem(mActionItem); + Incidence *incidence = mActionItem->incidence(); + if ( incidence->isReadOnly() /*|| incidence->recurrence()->doesRecur() */) { + mActionItem = 0; + } else { + startItemAction(viewportPos); + startX = viewportPos.x(); + startY = viewportPos.y(); + block = true; + } + } + } + } else { + selectItem(0); + mActionItem = 0; + setCursor(arrowCursor); + startSelectAction(viewportPos); + } + break; + + case QEvent::MouseButtonRelease: + //qDebug("QEvent::MouseButtonRelease: "); + if (me->button() == RightButton && block ) { + if (object != viewport()) { + mClickedItem = (KOAgendaItem *)object; + if (mActionItem ) { + endItemAction(); + } + if (mClickedItem) { + selectItem(mClickedItem); + emit showIncidencePopupSignal(mClickedItem->incidence()); + } + } + break; + } + block = true; + 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; + return true; + } + endItemAction(); + } else if ( mActionType == SELECT ) { + endSelectAction(); + } + break; + + case QEvent::MouseMove: + if (object != viewport()) { + KOAgendaItem *moveItem = (KOAgendaItem *)object; + //qDebug("moveItem %d ",moveItem ); + if (!moveItem->incidence()->isReadOnly() /*&& + !moveItem->incidence()->recurrence()->doesRecur()*/ ) + if (!mActionItem) + setNoActionCursor(moveItem,viewportPos); + else { + if ( block ) { + int dX, dY; + dX = startX - viewportPos.x(); + if ( dX < 0 ) + dX = -dX; + dY = viewportPos.y() - startY; + if ( dY < 0 ) + dY = -dY; + int diff = 30; + if ( QApplication::desktop()->width() < 480 ) + diff = 15; + // qDebug(" %d %d ",dX, dY ); + if ( dX > diff || dY > diff ) { + block = false; + } + } + if ( !block ) + performItemAction(viewportPos); + } + } else { + if ( mActionType == SELECT ) { + performSelectAction( viewportPos ); + } + } + break; + + case QEvent::MouseButtonDblClick: + 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::startSelectAction(QPoint viewportPos) +{ + //emit newStartSelectSignal(); + + mActionType = SELECT; + + int x,y; + viewportToContents(viewportPos.x(),viewportPos.y(),x,y); + int gx,gy; + contentsToGrid(x,y,gx,gy); + + mStartCellX = gx; + mStartCellY = gy; + mCurrentCellX = gx; + mCurrentCellY = gy; + + // Store coordinates of old selection + int selectionX = mSelectionCellX * mGridSpacingX; + int selectionYTop = mSelectionYTop; + int selectionHeight = mSelectionHeight; + + // Store new selection + mSelectionCellX = gx; + mSelectionYTop = gy * mGridSpacingY; + mSelectionHeight = mGridSpacingY; + + // Clear old selection + repaintContents( selectionX, selectionYTop, + mGridSpacingX, selectionHeight,false ); + + // Paint new selection + // repaintContents( mSelectionCellX * mGridSpacingX, mSelectionYTop, + // mGridSpacingX, mSelectionHeight ); +} + +void KOAgenda::performSelectAction(QPoint viewportPos) +{ + int x,y; + viewportToContents(viewportPos.x(),viewportPos.y(),x,y); + int gx,gy; + contentsToGrid(x,y,gx,gy); + + QPoint clipperPos = clipper()-> + mapFromGlobal(viewport()->mapToGlobal(viewportPos)); + + // Scroll if cursor was moved to upper or lower end of agenda. + if (clipperPos.y() < mScrollBorderWidth) { + mScrollUpTimer.start(mScrollDelay); + } else if (visibleHeight() - clipperPos.y() < + mScrollBorderWidth) { + mScrollDownTimer.start(mScrollDelay); + } else { + mScrollUpTimer.stop(); + mScrollDownTimer.stop(); + } + + if ( gy > mCurrentCellY ) { + mSelectionHeight = ( gy + 1 ) * mGridSpacingY - mSelectionYTop; + +#if 0 + // FIXME: Repaint only the newly selected region + repaintContents( mSelectionCellX * mGridSpacingX, + mCurrentCellY + mGridSpacingY, + mGridSpacingX, + mSelectionHeight - ( gy - mCurrentCellY - 1 ) * mGridSpacingY ); +#else + repaintContents( (KOGlobals::self()->reverseLayout() ? + mColumns - 1 - mSelectionCellX : mSelectionCellX) * + mGridSpacingX, mSelectionYTop, + mGridSpacingX, mSelectionHeight , false); +#endif + + mCurrentCellY = gy; + } else if ( gy < mCurrentCellY ) { + if ( gy >= mStartCellY ) { + int selectionHeight = mSelectionHeight; + mSelectionHeight = ( gy + 1 ) * mGridSpacingY - mSelectionYTop; + + repaintContents( (KOGlobals::self()->reverseLayout() ? + mColumns - 1 - mSelectionCellX : mSelectionCellX) * + mGridSpacingX, mSelectionYTop, + mGridSpacingX, selectionHeight,false ); + + mCurrentCellY = gy; + } else { + } + } +} + +void KOAgenda::endSelectAction() +{ + mActionType = NOP; + mScrollUpTimer.stop(); + mScrollDownTimer.stop(); + + emit newTimeSpanSignal(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()->type() != "Todo" ); + 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()); + 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()->recurrence()->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()->type() == "Todo" ) { + mSelectedItem = 0; + //qDebug("todo %d %d %d ", mCurrentCellX, modifiedItem->cellX() ,modifiedItem->cellXWidth()); + modifiedItem->mLastMoveXPos = mCurrentCellX; + emit itemModified( modifiedItem, mActionType ); + } + else { +#if 0 + for ( item=oldconflictItems.first(); item != 0; + item=oldconflictItems.next() ) { + placeSubCells(item); + } + while ( placeItem ) { + //qDebug("placeItem %s ", placeItem->incidence()->summary().latin1()); + placeSubCells( placeItem ); + placeItem = placeItem->nextMultiItem(); + } +#endif + + 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); + } + */ + + + } + + } + + 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 && + moveItem->cellYBottom() == gy && + !moveItem->lastMultiItem()) { + setCursor(sizeVerCursor); + } else { + setCursor(arrowCursor); + } + } +} + + +/* + Place item in cell and take care that multiple items using the same cell do + not overlap. This method is not yet optimal. It doesn�t use the maximum space + it can get in all cases. + At the moment the method has a bug: When an item is placed only the sub cell + widths of the items are changed, which are within the Y region the item to + place spans. When the sub cell width change of one of this items affects a + cell, where other items are, which do not overlap in Y with the item to place, + the display gets corrupted, although the corruption looks quite nice. +*/ +void KOAgenda::placeSubCells(KOAgendaItem *placeItem) +{ + + QPtrList<KOAgendaItem> conflictItems; + int maxSubCells = 0; + QIntDict<KOAgendaItem> subCellDict(5); + + KOAgendaItem *item; + for ( item=mItems.first(); item != 0; item=mItems.next() ) { + if (item != placeItem) { + if (placeItem->cellX() <= item->cellXWidth() && + placeItem->cellXWidth() >= item->cellX()) { + if ((placeItem->cellYTop() <= item->cellYBottom()) && + (placeItem->cellYBottom() >= item->cellYTop())) { + conflictItems.append(item); + if (item->subCells() > maxSubCells) + maxSubCells = item->subCells(); + subCellDict.insert(item->subCell(),item); + } + } + } + } + + if (conflictItems.count() > 0) { + // Look for unused sub cell and insert item + int i; + for(i=0;i<maxSubCells;++i) { + if (!subCellDict.find(i)) { + placeItem->setSubCell(i); + break; + } + } + if (i == maxSubCells) { + placeItem->setSubCell(maxSubCells); + maxSubCells++; // add new item to number of sub cells + } + + // Prepare for sub cell geometry adjustment + int newSubCellWidth; + if (mAllDayMode) newSubCellWidth = mGridSpacingY / maxSubCells; + else newSubCellWidth = mGridSpacingX / maxSubCells; + conflictItems.append(placeItem); + + + // Adjust sub cell geometry of all items + for ( item=conflictItems.first(); item != 0; + item=conflictItems.next() ) { + item->setSubCells(maxSubCells); + if (mAllDayMode) { + item->resize(item->cellWidth() * mGridSpacingX, newSubCellWidth); + } else { + item->resize(newSubCellWidth, item->cellHeight() * mGridSpacingY); + } + int x,y; + gridToContents(item->cellX(),item->cellYTop(),x,y); + if (mAllDayMode) { + y += item->subCell() * newSubCellWidth; + } else { + x += item->subCell() * newSubCellWidth; + } + moveChild(item,x,y); + // qDebug("moveChild %s %d %d ", item->incidence()->summary().latin1() ,x,y); + //item->updateItem(); + } + + } else { + placeItem->setSubCell(0); + placeItem->setSubCells(1); + if (mAllDayMode) placeItem->resize(placeItem->width(),mGridSpacingY); + else placeItem->resize(mGridSpacingX,placeItem->height()); + int x,y; + gridToContents(placeItem->cellX(),placeItem->cellYTop(),x,y); + moveChild(placeItem,x,y); + } + placeItem->setConflictItems(conflictItems); + // for ( item=conflictItems.first(); item != 0; +// item=conflictItems.next() ) { +// //item->updateItem(); +// //qDebug("xxx item->updateItem() %s %d %d", item->incidence()->summary().latin1(),item->x(), item->y() ); +// } +// placeItem->updateItem(); +} + +void KOAgenda::drawContents(QPainter* p, int cx, int cy, int cw, int ch) +{ + if ( globalFlagBlockAgenda ) + return; + //qDebug("KOAgenda::drawContents "); + if ( mCurPixWid != contentsWidth() || mCurPixHei != contentsHeight() ) + ;//drawContentsToPainter(); + + QPaintDevice* pd = p->device(); + p->end(); + int vx, vy; + int selectionX = KOGlobals::self()->reverseLayout() ? + (mColumns - 1 - mSelectionCellX) * mGridSpacingX : + mSelectionCellX * mGridSpacingX; + contentsToViewport ( cx, cy, vx,vy); + // qDebug(" %d %d %d %d ", cx, cy, cw,ch) ; + if ( !(selectionX == cx && cy == mSelectionYTop && cw ==mGridSpacingX && ch == mSelectionHeight ) ) + bitBlt ( pd, vx, vy, &mPaintPixmap, cx, cy, cw, ch ,CopyROP); + + if ( mSelectionHeight > 0 ) { + //qDebug("---- %d %d %d %d ", selectionX, mSelectionYTop, mGridSpacingX, mSelectionHeight ); + if ( ( cx + cw ) >= selectionX && cx <= ( selectionX + mGridSpacingX ) && + ( cy + ch ) >= mSelectionYTop && cy <= ( mSelectionYTop + mSelectionHeight ) ) { + contentsToViewport ( selectionX, mSelectionYTop, vx,vy); + bitBlt ( pd, vx+1, vy, &mHighlightPixmap, 0, mSelectionYTop, mGridSpacingX-1, mSelectionHeight ,CopyROP); + } + } + //qDebug("btbl "); + p->begin( pd ); + //qDebug("end "); +} + +void KOAgenda::finishUpdate() +{ + + KOAgendaItem *item; + globalFlagBlockAgendaItemPaint = 1; + for ( item=mItems.first(); item != 0; item=mItems.next() ) { + if ( !item->isVisible() ) + item->show(); + + } + globalFlagBlockAgendaItemUpdate = 0; + for ( item=mItems.first(); item != 0; item=mItems.next() ) { + item->repaintMe( ); + } + globalFlagBlockAgendaItemUpdate = 1; + qApp->processEvents(); + globalFlagBlockAgendaItemPaint = 0; + for ( item=mItems.first(); item != 0; item=mItems.next() ) { + item->repaint( false ); + } + +} + +/* + Draw grid in the background of the agenda. +*/ +void KOAgenda::drawContentsToPainter( QPainter* paint, bool backgroundOnly )// int cx, int cy, int cw, int ch) +{ + + + if ( ! mGridSpacingX || ! mGridSpacingY ||! mHolidayMask ) + return; + if ( globalFlagBlockAgenda > 1 && globalFlagBlockAgenda < 4 ) + return; + int cx = 0, cy = 0, cw = contentsWidth(), ch = contentsHeight(); + if ( ch < 1 ) + ch = 1; + if ( mPaintPixmap.width() < contentsWidth()+42 || mPaintPixmap.height() < ch ) { + mPaintPixmap.resize( contentsWidth()+42, ch ); + } + mCurPixWid = contentsWidth(); + mCurPixHei = ch; + if ( mHighlightPixmap.width() < mGridSpacingX-1 || mHighlightPixmap.height() < ch ) { + mHighlightPixmap.resize( mGridSpacingX-1, ch ); + mHighlightPixmap.fill ( KOPrefs::instance()->mHighlightColor ); + } + mPixPainter.begin( &mPaintPixmap) ; + //qDebug("wid %d hei %d ",mPaintPixmap.width(),mPaintPixmap.height() ); + QPainter * p ; + if (paint == 0) { + mPaintPixmap.fill(KOPrefs::instance()->mAgendaBgColor); + p = &mPixPainter; + } + else + p = paint ; + // qDebug("++++++KOAgenda::drawContentsTo Painter %d %d %d %d ", cx, cy, cw, ch); + + //--cx;++cw; + int lGridSpacingY = mGridSpacingY*2; + int selDay; + if ( !backgroundOnly ) + for ( selDay = 0; selDay < mSelectedDates.count(); ++selDay) + { + if ( mSelectedDates[selDay] == QDateTime::currentDateTime ().date() && KOPrefs::instance()->mHighlightCurrentDay) { + int x1 = cx; + int y1 = 0; + if (y1 < cy) y1 = cy; + int x2 = cx+cw-1; + int y2 = contentsHeight(); + if (y2 > cy+ch-1) y2=cy+ch-1; + if (x2 >= x1 && y2 >= y1) { + int gxStart = selDay; + int gxEnd = gxStart ; + int xStart = KOGlobals::self()->reverseLayout() ? + (mColumns - 1 - gxStart)*mGridSpacingX : + gxStart*mGridSpacingX; + if (xStart < x1) xStart = x1; + int xEnd = KOGlobals::self()->reverseLayout() ? + (mColumns - gxStart)*mGridSpacingX-1 : + (gxStart+1)*mGridSpacingX-1; + if (xEnd > x2) xEnd = x2; + if ( KOPrefs::instance()->mUseHighlightLightColor ) + p->fillRect(xStart,y1,xEnd-xStart+1,y2-y1+1, + KOPrefs::instance()->mAgendaBgColor.light()); + else + p->fillRect(xStart,y1,xEnd-xStart+1,y2-y1+1, + KOPrefs::instance()->mAgendaBgColor.dark()); + + } + } + } + // Highlight working hours + + if ( !backgroundOnly ) + if (mWorkingHoursEnable) { + int x1 = cx; + int y1 = mWorkingHoursYTop; + if (y1 < cy) y1 = cy; + int x2 = cx+cw-1; + // int x2 = mGridSpacingX * 5 - 1; + // if (x2 > cx+cw-1) x2 = cx + cw - 1; + int y2 = mWorkingHoursYBottom; + if (y2 > cy+ch-1) y2=cy+ch-1; + + if (x2 >= x1 && y2 >= y1) { + // qDebug("x1 %d mGridSpacingX %d ", x1, mGridSpacingX ); + int gxStart = x1/mGridSpacingX; + int gxEnd = x2/mGridSpacingX; + while(gxStart <= gxEnd) { + if (gxStart < int(mHolidayMask->count()) && + !mHolidayMask->at(gxStart)) { + int xStart = KOGlobals::self()->reverseLayout() ? + (mColumns - 1 - gxStart)*mGridSpacingX : + gxStart*mGridSpacingX; + if (xStart < x1) xStart = x1; + int xEnd = KOGlobals::self()->reverseLayout() ? + (mColumns - gxStart)*mGridSpacingX-1 : + (gxStart+1)*mGridSpacingX-1; + if (xEnd > x2) xEnd = x2; + if ( mSelectedDates[gxStart] == QDateTime::currentDateTime ().date()&& KOPrefs::instance()->mHighlightCurrentDay ) { + if ( KOPrefs::instance()->mUseHighlightLightColor ) + p->fillRect(xStart,y1,xEnd-xStart+1,y2-y1+1, + KOPrefs::instance()->mWorkingHoursColor.light()); + else + p->fillRect(xStart,y1,xEnd-xStart+1,y2-y1+1, + KOPrefs::instance()->mWorkingHoursColor.dark()); + } else { + p->fillRect(xStart,y1,xEnd-xStart+1,y2-y1+1, + KOPrefs::instance()->mWorkingHoursColor); + } + } + ++gxStart; + } + } + } + /* + int selectionX = KOGlobals::self()->reverseLayout() ? + (mColumns - 1 - mSelectionCellX) * mGridSpacingX : + mSelectionCellX * mGridSpacingX; + + // Draw selection + if ( ( cx + cw ) >= selectionX && cx <= ( selectionX + mGridSpacingX ) && + ( cy + ch ) >= mSelectionYTop && cy <= ( mSelectionYTop + mSelectionHeight ) ) { + // TODO: paint only part within cx,cy,cw,ch + p->fillRect( selectionX, mSelectionYTop, mGridSpacingX, + mSelectionHeight, KOPrefs::instance()->mHighlightColor ); + } + */ + // Draw vertical lines of grid + + int x = ((int)(cx/mGridSpacingX))*mGridSpacingX; + if ( mGridSpacingX > 0 ) { + while (x < cx + cw) { + p->drawLine(x,cy,x,cy+ch); + x+=mGridSpacingX; + } + } + // Draw horizontal lines of grid + int y = ((int)(cy/lGridSpacingY))*lGridSpacingY; + if ( lGridSpacingY > 0 ) { + while (y < cy + ch) { + p->drawLine(cx,y,cx+cw,y); + y+=lGridSpacingY; + } + } + mPixPainter.end() ; +} + +/* + Convert srcollview contents coordinates to agenda grid coordinates. +*/ +void KOAgenda::contentsToGrid (int x, int y, int& gx, int& gy) +{ + gx = KOGlobals::self()->reverseLayout() ? mColumns - 1 - x/mGridSpacingX : + x/mGridSpacingX; + gy = y/mGridSpacingY; +} + +/* + Convert agenda grid coordinates to scrollview contents coordinates. +*/ +void KOAgenda::gridToContents (int gx, int gy, int& x, int& y) +{ + x = KOGlobals::self()->reverseLayout() ? (mColumns - 1 - gx)*mGridSpacingX: + gx*mGridSpacingX; + y = gy*mGridSpacingY; +} + + +/* + Return Y coordinate corresponding to time. Coordinates are rounded to fit into + the grid. +*/ +int KOAgenda::timeToY(const QTime &time) +{ + int minutesPerCell = 24 * 60 / mRows; + int timeMinutes = time.hour() * 60 + time.minute(); + int Y = (timeMinutes + (minutesPerCell / 2)) / minutesPerCell; + return Y; +} + + +/* + Return time corresponding to cell y coordinate. Coordinates are rounded to + fit into the grid. +*/ +QTime KOAgenda::gyToTime(int gy) +{ + + int secondsPerCell = 24 * 60 * 60/ mRows; + + int timeSeconds = secondsPerCell * gy; + + QTime time( 0, 0, 0 ); + if ( timeSeconds < 24 * 60 * 60 ) { + time = time.addSecs(timeSeconds); + } else { + time.setHMS( 23, 59, 59 ); + } + + return time; +} + +void KOAgenda::setStartHour(int startHour) +{ + int startCell = startHour * mRows / 24; + setContentsPos(0,startCell * gridSpacingY()); +} +void KOAgenda::hideUnused() +{ + // experimental only + // return; + KOAgendaItem *item; + for ( item=mUnusedItems.first(); item != 0; item=mUnusedItems.next() ) { + item->hide(); + } +} + + +KOAgendaItem *KOAgenda::getNewItem(Incidence * event,QDate qd, QWidget* view) +{ + + KOAgendaItem *fi; + for ( fi=mUnusedItems.first(); fi != 0; fi=mUnusedItems.next() ) { + if ( fi->incidence() == event ) { + mUnusedItems.remove(); + fi->init( event, qd ); + return fi; + } + } + fi=mUnusedItems.first(); + if ( fi ) { + mUnusedItems.remove(); + fi->init( event, qd ); + return fi; + } + // qDebug("new KOAgendaItem "); + + KOAgendaItem* agendaItem = new KOAgendaItem( event, qd, view, mAllDayMode ); + agendaItem->installEventFilter(this); + addChild(agendaItem,0,0); + return agendaItem; +} +KOAgendaItem * KOAgenda::getItemForTodo ( Todo * todo ) +{ + KOAgendaItem *item; + for ( item=mItems.first(); item != 0; item=mItems.next() ) { + if ( item->incidence() == todo ) { + mItems.remove(); + return item; + } + } + return 0; +} + + +void KOAgenda::updateTodo( Todo * todo, int days, bool remove) +{ + + KOAgendaItem *item; + item = getItemForTodo ( todo ); + //qDebug("KOAgenda::updateTodo %d %d %d %d", this, todo, days, remove); + if ( item ) { + blockSignals( true ); + //qDebug("item found "); + item->hide(); + item->setCellX(-2, -1 ); + item->select(false); + mUnusedItems.append( item ); + mItems.remove( item ); + QPtrList<KOAgendaItem> oldconflictItems = item->conflictItems(); + KOAgendaItem *itemit; + //globalFlagBlockAgendaItemPaint = 1; + for ( itemit=oldconflictItems.first(); itemit != 0; + itemit=oldconflictItems.next() ) { + if ( itemit != item ) + placeSubCells(itemit); + } + qApp->processEvents(); + //globalFlagBlockAgendaItemPaint = 0; + for ( itemit=oldconflictItems.first(); itemit != 0; + itemit=oldconflictItems.next() ) { + globalFlagBlockAgendaItemUpdate = 0; + if ( itemit != item ) + itemit->repaintMe(); + globalFlagBlockAgendaItemUpdate = 1; + itemit->repaint(); + } + blockSignals( false ); + } + if ( remove ) { + //qDebug("remove****************************************** "); + return; + } + //qDebug("updateTodo+++++++++++++++++++++++++++++++++++++ "); + bool overdue = (!todo->isCompleted()) && (todo->dtDue() < QDate::currentDate())&& ( KOPrefs::instance()->mShowTodoInAgenda ); + QDate currentDate; + if ( overdue ) { + currentDate = QDate::currentDate(); + days += todo->dtDue().date().daysTo( currentDate ); + } + else + currentDate = todo->dtDue().date(); + + if ( todo->doesFloat() || overdue ) { + if ( ! mAllDayMode ) return; + // aldayagenda + globalFlagBlockAgendaItemPaint = 1; + item = insertAllDayItem(todo, currentDate,days, days); + item->show(); + + } + else { + if ( mAllDayMode ) return; + // mAgenda + globalFlagBlockAgendaItemPaint = 1; + int endY = timeToY(todo->dtDue().time()) - 1; + int hi = 12/KOPrefs::instance()->mHourSize; + int startY = endY - 1-hi; + item = insertItem(todo,currentDate,days,startY,endY); + item->show(); + } + qApp->processEvents(); + globalFlagBlockAgendaItemPaint = 0; + QPtrList<KOAgendaItem> oldconflictItems = item->conflictItems(); + KOAgendaItem *itemit; + for ( itemit=oldconflictItems.first(); itemit != 0; + itemit=oldconflictItems.next() ) { + globalFlagBlockAgendaItemUpdate = 0; + itemit->repaintMe(); + globalFlagBlockAgendaItemUpdate = 1; + itemit->repaint(); + } + globalFlagBlockAgendaItemUpdate = 0; + item->repaintMe(); + globalFlagBlockAgendaItemUpdate = 1; + item->repaint(); +} +/* + Insert KOAgendaItem into agenda. +*/ +KOAgendaItem *KOAgenda::insertItem (Incidence *event,QDate qd,int X,int YTop,int YBottom) +{ + //kdDebug() << "KOAgenda::insertItem:" << event->summary() << "-" << qd.toString() << " ;top, bottom:" << YTop << "," << YBottom << endl; + + if (mAllDayMode) { + kdDebug() << "KOAgenda: calling insertItem in all-day mode is illegal." << endl; + return 0; + } + + KOAgendaItem *agendaItem = getNewItem(event,qd,viewport()); + //agendaItem->setFrameStyle(WinPanel|Raised); + + int YSize = YBottom - YTop + 1; + if (YSize < 0) { + kdDebug() << "KOAgenda::insertItem(): Text: " << agendaItem->text() << " YSize<0" << endl; + YSize = 1; + } + int iheight = mGridSpacingY * YSize; + + agendaItem->resize(mGridSpacingX,iheight ); + agendaItem->setCellXY(X,YTop,YBottom); + agendaItem->setCellXWidth(X); + + //addChild(agendaItem,X*mGridSpacingX,YTop*mGridSpacingY); + mItems.append(agendaItem); + + placeSubCells(agendaItem); + + //agendaItem->show(); + + marcus_bains(); + + return agendaItem; +} + + +/* + Insert all-day KOAgendaItem into agenda. +*/ +KOAgendaItem *KOAgenda::insertAllDayItem (Incidence *event,QDate qd,int XBegin,int XEnd) +{ + if (!mAllDayMode) { + return 0; + } + + KOAgendaItem *agendaItem = getNewItem(event,qd,viewport()); + + agendaItem->setCellXY(XBegin,0,0); + agendaItem->setCellXWidth(XEnd); + agendaItem->resize(mGridSpacingX * agendaItem->cellWidth(),mGridSpacingY); + + //addChild(agendaItem,XBegin*mGridSpacingX,0); + mItems.append(agendaItem); + + placeSubCells(agendaItem); + + //agendaItem->show(); + + return agendaItem; +} + + +void KOAgenda::insertMultiItem (Event *event,QDate qd,int XBegin,int XEnd, + int YTop,int YBottom) +{ + if (mAllDayMode) { + ; + return; + } + + int cellX,cellYTop,cellYBottom; + QString newtext; + int width = XEnd - XBegin + 1; + int count = 0; + KOAgendaItem *current = 0; + QPtrList<KOAgendaItem> multiItems; + for (cellX = XBegin;cellX <= XEnd;++cellX) { + if (cellX == XBegin) cellYTop = YTop; + else cellYTop = 0; + if (cellX == XEnd) cellYBottom = YBottom; + else cellYBottom = rows() - 1; + newtext = QString("(%1/%2): ").arg(++count).arg(width); + newtext.append(event->summary()); + current = insertItem(event,qd,cellX,cellYTop,cellYBottom); + current->setText(newtext); + multiItems.append(current); + } + + KOAgendaItem *next = 0; + KOAgendaItem *last = multiItems.last(); + KOAgendaItem *first = multiItems.first(); + KOAgendaItem *setFirst,*setLast; + current = first; + while (current) { + next = multiItems.next(); + if (current == first) setFirst = 0; + else setFirst = first; + if (current == last) setLast = 0; + else setLast = last; + + current->setMultiItem(setFirst,next,setLast); + current = next; + } + + marcus_bains(); +} + + +//QSizePolicy KOAgenda::sizePolicy() const +//{ + // Thought this would make the all-day event agenda minimum size and the + // normal agenda take the remaining space. But it doesn�t work. The QSplitter + // don�t seem to think that an Expanding widget needs more space than a + // Preferred one. + // But it doesn�t hurt, so it stays. +// if (mAllDayMode) { +// return QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred); +// } else { +// return QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); +// } +//} +void KOAgenda::finishResize ( ) +{ + //qDebug("finishResize+++++++++++++++++++++++++++++++ ( ) "); + if ( globalFlagBlockAgenda == 0 ) { + finishUpdate(); + //qDebug("finishUpdate() called "); + } +} +/* + Overridden from QScrollView to provide proper resizing of KOAgendaItems. +*/ +void KOAgenda::resizeEvent ( QResizeEvent *ev ) +{ + + mResizeTimer.start( 150 , true ); + computeSizes(); + return; + +} +void KOAgenda::computeSizes() +{ + if ( globalFlagBlockStartup ) + return; + + if (mAllDayMode) { + mGridSpacingX = (width()-3) / mColumns; + mGridSpacingY = height() - 2 * frameWidth() - 1; + resizeContents( mGridSpacingX * mColumns + 1 , mGridSpacingY + 1); +// mGridSpacingY = height(); +// resizeContents( mGridSpacingX * mColumns + 1 , mGridSpacingY * mRows + 1 ); + + KOAgendaItem *item; + int subCellWidth; + for ( item=mItems.first(); item != 0; item=mItems.next() ) { + subCellWidth = mGridSpacingY / item->subCells(); + item->resize(mGridSpacingX * item->cellWidth(),subCellWidth); + moveChild(item,KOGlobals::self()->reverseLayout() ? + (mColumns - 1 - item->cellX()) * mGridSpacingX : + item->cellX() * mGridSpacingX, + item->subCell() * subCellWidth); + } + KOPrefs::instance()->mAllDaySize = mGridSpacingY; + } else { + mGridSpacingX = (width() - verticalScrollBar()->width()-3)/mColumns; + if (height() > mGridSpacingY * mRows + 1 ) { + KOPrefs::instance()->mHourSize = ((height())/mRows)+1; + mGridSpacingY = KOPrefs::instance()->mHourSize ; + resizeContents( mGridSpacingX * mColumns + 1 , mGridSpacingY * mRows + 1 ); + emit resizedSignal(); + } else + resizeContents( mGridSpacingX * mColumns + 1 , mGridSpacingY * mRows + 1 ); + KOAgendaItem *item; + int subCellWidth; + + for ( item=mItems.first(); item != 0; item=mItems.next() ) { + subCellWidth = mGridSpacingX / item->subCells(); + item->resize(subCellWidth,item->height()); + moveChild(item,(KOGlobals::self()->reverseLayout() ? + (mColumns - 1 - item->cellX()) * mGridSpacingX : + item->cellX() * mGridSpacingX) + + item->subCell() * subCellWidth,childY(item)); + } + } + int cw = contentsWidth(); + int ch = contentsHeight(); + if ( mAllDayMode ) { + QPixmap* paintPixAll = KOAgendaItem::paintPixAllday(); + if ( paintPixAll->width() < cw || paintPixAll->height() < ch ) + paintPixAll->resize( cw, ch ); + } else { + QPixmap* paintPix = KOAgendaItem::paintPix(); + if ( paintPix->width() < cw || paintPix->height() < ch ) + KOAgendaItem::resizePixmap( cw , ch ); + } + + checkScrollBoundaries(); + marcus_bains(); + drawContentsToPainter(); + viewport()->repaint(false); +} + +void KOAgenda::scrollUp() +{ + scrollBy(0,-mScrollOffset); +} + + +void KOAgenda::scrollDown() +{ + scrollBy(0,mScrollOffset); +} + +void KOAgenda::popupAlarm() +{ + if (!mClickedItem) { + kdDebug() << "KOAgenda::popupAlarm() called without having a clicked item" << endl; + return; + } +// TODO: deal correctly with multiple alarms + Alarm* alarm; + QPtrList<Alarm> list(mClickedItem->incidence()->alarms()); + for(alarm=list.first();alarm;alarm=list.next()) { + alarm->toggleAlarm(); + } + emit itemModified( mClickedItem , KOGlobals::EVENTEDITED ); + mClickedItem->paintMe( true ); + mClickedItem->repaint( false ); +} + +/* + Calculates the minimum width +*/ +int KOAgenda::minimumWidth() const +{ + // TODO:: develop a way to dynamically determine the minimum width + int min = 100; + + return min; +} + +void KOAgenda::updateConfig() +{ + if ( viewport()->backgroundColor() != KOPrefs::instance()->mAgendaBgColor) + viewport()->setBackgroundColor(KOPrefs::instance()->mAgendaBgColor); + if ( mAllDayMode ) { + mGridSpacingY = height() - 1 ;// KOPrefs::instance()->mAllDaySize; + //mGridSpacingY = KOPrefs::instance()->mAllDaySize; + resizeContents( mGridSpacingX * mColumns + 1 , mGridSpacingY+1 ); + // setMaximumHeight( mGridSpacingY+1 ); + viewport()->repaint( false ); + //setFixedHeight( mGridSpacingY+1 ); + //qDebug("KOPrefs:aaaaa:instance()->mAllDaySize %d ", KOPrefs::instance()->mAllDaySize); + } + else { + mGridSpacingY = KOPrefs::instance()->mHourSize; + calculateWorkingHours(); + marcus_bains(); + } +} + +void KOAgenda::checkScrollBoundaries() +{ + // Invalidate old values to force update + mOldLowerScrollValue = -1; + mOldUpperScrollValue = -1; + + checkScrollBoundaries(verticalScrollBar()->value()); +} + +void KOAgenda::checkScrollBoundaries(int v) +{ + if ( mGridSpacingY == 0 ) + return; + int yMin = v/mGridSpacingY; + int yMax = (v+visibleHeight())/mGridSpacingY; + +// kdDebug() << "--- yMin: " << yMin << " yMax: " << yMax << endl; + + if (yMin != mOldLowerScrollValue) { + mOldLowerScrollValue = yMin; + emit lowerYChanged(yMin); + } + if (yMax != mOldUpperScrollValue) { + mOldUpperScrollValue = yMax; + emit upperYChanged(yMax); + } +} + +void KOAgenda::deselectItem() +{ + if (mSelectedItem.isNull()) return; + mSelectedItem->select(false); + mSelectedItem = 0; +} + +void KOAgenda::selectItem(KOAgendaItem *item) +{ + if ((KOAgendaItem *)mSelectedItem == item) return; + deselectItem(); + if (item == 0) { + emit incidenceSelected( 0 ); + return; + } + mSelectedItem = item; + mSelectedItem->select(); + emit incidenceSelected( mSelectedItem->incidence() ); +} + +// This function seems never be called. +void KOAgenda::keyPressEvent( QKeyEvent *kev ) +{ + switch(kev->key()) { + case Key_PageDown: + verticalScrollBar()->addPage(); + break; + case Key_PageUp: + verticalScrollBar()->subtractPage(); + break; + case Key_Down: + verticalScrollBar()->addLine(); + break; + case Key_Up: + verticalScrollBar()->subtractLine(); + break; + default: + ; + } +} + +void KOAgenda::calculateWorkingHours() +{ +// mWorkingHoursEnable = KOPrefs::instance()->mEnableWorkingHours; + mWorkingHoursEnable = !mAllDayMode; + + mWorkingHoursYTop = mGridSpacingY * + KOPrefs::instance()->mWorkingHoursStart * 4; + mWorkingHoursYBottom = mGridSpacingY * + KOPrefs::instance()->mWorkingHoursEnd * 4 - 1; +} + + +DateList KOAgenda::dateList() const +{ + return mSelectedDates; +} + +void KOAgenda::setDateList(const DateList &selectedDates) +{ + mSelectedDates = selectedDates; + marcus_bains(); +} + +void KOAgenda::setHolidayMask(QMemArray<bool> *mask) +{ + mHolidayMask = mask; + +/* + kdDebug() << "HolidayMask: "; + for(uint i=0;i<mask->count();++i) { + kdDebug() << (mask->at(i) ? "*" : "o"); + } + kdDebug() << endl; +*/ +} + +void KOAgenda::contentsMousePressEvent ( QMouseEvent *event ) +{ + + QScrollView::contentsMousePressEvent(event); +} + +void KOAgenda::storePosition() +{ + //mContentPosition + int max = mGridSpacingY*4*24; + if ( contentsY() < 5 && max > viewport()->height()*3/2 ) + mContentPosition = 0; + else if ( contentsY() + viewport()->height() > max - 5 && max > viewport()->height()*3/2) + mContentPosition = -1.0; + else + mContentPosition = ((float) max)/ ((float)(contentsY()+ ( viewport()->height()/2))); + //qDebug("mContentPosition %f %d %d %d",mContentPosition , max, contentsY() ,viewport()->height()); + +} +void KOAgenda::restorePosition() +{ + int posY; + int max = mGridSpacingY*4*24; + if ( mContentPosition < 0 ) + posY = max-viewport()->height(); + else + if ( mContentPosition == 0 ) + posY = 0; + else + posY = (max/mContentPosition)-(viewport()->height()/2); + setContentsPos (0, posY ); + //qDebug("posY %d hei %d", posY, max); + +} +void KOAgenda::moveChild( QWidget *w, int x , int y ) +{ + ++x; + QScrollView::moveChild( w, x , y ); +} +#include <qmessagebox.h> +#ifdef DESKTOP_VERSION +#include <qprinter.h> +#include <qpainter.h> +#include <qpaintdevicemetrics.h> + +#endif +void KOAgenda::printSelection() +{ +#ifdef DESKTOP_VERSION + if ( mStartCellY == mCurrentCellY ) { + int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"), + i18n("Nothing selected!\n\nThis prints the full width of the Agenda view as you see it!\n\nTo determine the vertical range of the printing, please select\na vertical range (with the left mouse button down) in one column. "), + i18n("OK"), 0, 0, + 0, 1 ); + return; + } + + float dx, dy; + int x,y,w,h; + x= 0; + w= contentsWidth()+2; + // h= contentsHeight(); + y = mGridSpacingY*mStartCellY; + h = mGridSpacingY*(mCurrentCellY+1)-y+2; + + //return; + QPrinter* printer = new QPrinter(); + if ( !printer->setup()) { + delete printer; + return; + } + QPainter p( printer ); + QPaintDeviceMetrics m = QPaintDeviceMetrics ( printer ); + QString date = i18n("Date range: ")+KGlobal::locale()->formatDate( mSelectedDates.first() )+" - "+KGlobal::locale()->formatDate( mSelectedDates.last() ); + date += " --- printing time: " + KGlobal::locale()->formatDateTime(QDateTime::currentDateTime(), true ); + int hei = p.boundingRect(0,0, 5, 5, Qt::AlignLeft, date ).height(); + // p.drawText( 0, 0, date ); + int offset = m.width()/8; + // compute the scale + dx = ((float) m.width()-offset) / (float)w; + dy = (float)(m.height() - ( 2 * hei )-offset ) / (float)h; + float scale; + // scale to fit the width or height of the paper + if ( dx < dy ) + scale = dx; + else + scale = dy; + // set the scale + p.drawText( offset* scale, offset* scale*3/4, date ); + + int selDay; + float widOffset = ((float) m.width()-offset) / ((float)(mSelectedDates.count())); + float startX = 1; + for ( selDay = 0; selDay < mSelectedDates.count(); ++selDay) + { + QString text = KGlobal::locale()->formatDate( mSelectedDates[selDay],true ); + p.setClipRect(offset* scale+startX , 0, widOffset-4, offset* scale+(2*hei* scale) ); + p.drawText( offset* scale+startX, (offset+hei)* scale, text ); + startX += widOffset; + + } + p.translate( offset* scale,offset* scale+ (-y * scale)+(2*hei* scale)); + p.scale( scale, scale ); + p.setClipRect( offset* scale, offset* scale+(2*hei* scale), w*scale, h*scale ); + // now printing with y offset: 2 hei + // p.translate( 0, -y*scale); + + drawContentsToPainter(&p, true ); + globalFlagBlockAgendaItemUpdate = false; + KOAgendaItem *item; + for ( item=mItems.first(); item != 0; item=mItems.next() ) { + item->select(false); + item->paintMe( false, &p ); + } + globalFlagBlockAgendaItemUpdate = true; + p.end(); + delete printer; +#else + int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"), + i18n("Not supported \non PDA!\n"), + i18n("OK"), 0, 0, + 0, 1 ); +#endif +} diff --git a/korganizer/koagenda.h b/korganizer/koagenda.h new file mode 100644 index 0000000..111242f --- a/dev/null +++ b/korganizer/koagenda.h @@ -0,0 +1,286 @@ +/* + 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" + +class QPopupMenu; +class QTime; +class KConfig; +class QFrame; +class KOAgenda; +class KCal::Event; +class KCal::Todo; + +using namespace KCal; + +class MarcusBains : public QFrame { + Q_OBJECT + public: + MarcusBains(KOAgenda *agenda=0,const char *name=0); + virtual ~MarcusBains(); + + public slots: + void updateLocation(bool recalculate=false); + void updateLoc(); + + private: + int todayColumn(); + QTimer *minutes; + QLabel *mTimeBox; + KOAgenda *agenda; + QTime oldTime; + int oldToday; +}; + + +class KOAgenda : public QScrollView +{ + Q_OBJECT + public: + enum MouseActionType { NOP, MOVE, SELECT, + RESIZETOP, RESIZEBOTTOM, RESIZELEFT, RESIZERIGHT }; + + KOAgenda ( int columns, int rows, int columnSize, QWidget * parent=0, + const char * name=0, WFlags f=0 ); + KOAgenda ( int columns, QWidget * parent=0, + const char * name=0, WFlags f=0 ); + virtual ~KOAgenda(); + + Incidence *selectedIncidence() const; + QDate selectedIncidenceDate() const; + + virtual bool eventFilter ( QObject *, QEvent * ); + + void contentsToGrid (int x, int y, int& gx, int& gy); + void gridToContents (int gx, int gy, int& x, int& y); + + int timeToY (const QTime &time); + QTime gyToTime (int y); + + void setStartHour(int startHour); + + KOAgendaItem *insertItem (Incidence *event,QDate qd,int X,int YTop,int YBottom); + KOAgendaItem *insertAllDayItem (Incidence *event,QDate qd,int XBegin,int XEnd); + void insertMultiItem (Event *event,QDate qd,int XBegin,int XEnd, + int YTop,int YBottom); + + void changeColumns(int columns); + + int columns() { return mColumns; } + int rows() { return mRows; } + + int gridSpacingX() const { return mGridSpacingX; } + int gridSpacingY() const { return mGridSpacingY; } + +// virtual QSizePolicy sizePolicy() const; + + void clear(); + + void clearSelection(); + void hideUnused(); + + /** Calculates the minimum width */ + virtual int minimumWidth() const; + /** Update configuration from preference settings */ + void updateConfig(); + + void checkScrollBoundaries(); + + void setHolidayMask(QMemArray<bool> *); + void setDateList(const DateList &selectedDates); + DateList dateList() const; + void drawContentsToPainter( QPainter* paint = 0, bool backgroundOnly = false); + void finishUpdate(); + void printSelection(); + void storePosition(); + void restorePosition(); + + + public slots: + void 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 newEventSignal(); + void newEventSignal(int gx,int gy); + void newEventSignal(int gxStart, int gyStart, int gxEnd, int gyEnd); + void newTimeSpanSignal(int gxStart, int gyStart, int gxEnd, int gyEnd); + void newStartSelectSignal(); + void showIncidenceSignal(Incidence *); + void editIncidenceSignal(Incidence *); + void deleteIncidenceSignal(Incidence *); + void showIncidencePopupSignal(Incidence *); + + void itemModified(KOAgendaItem *item, int ); + void incidenceSelected(Incidence *); + + void lowerYChanged(int); + void upperYChanged(int); + + void startDragSignal(Incidence *); + void addToCalSignal(Incidence *, Incidence *); + void resizedSignal(); + + protected: + QPainter mPixPainter; + QPixmap mPaintPixmap; + QPixmap mHighlightPixmap; + void drawContents(QPainter *p,int cx, int cy, int cw, int ch); + virtual void resizeEvent ( QResizeEvent * ); + + /** Handles mouse events. Called from eventFilter */ + virtual bool eventFilter_mouse ( QObject *, QMouseEvent * ); + + /** Start selecting time span. */ + void startSelectAction(QPoint viewportPos); + + /** Select time span. */ + void performSelectAction(QPoint viewportPos); + + /** Emd selecting time span. */ + void endSelectAction(); + + /** 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; + 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 + + int mOldLowerScrollValue; + int mOldUpperScrollValue; + KOAgendaItem * getItemForTodo ( Todo * todo ); + QMemArray<bool> *mHolidayMask; + int mCurPixWid; + int mCurPixHei; +}; + +#endif // KOAGENDA_H diff --git a/korganizer/koagenda.moc b/korganizer/koagenda.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/koagenda.moc diff --git a/korganizer/koagendaitem.cpp b/korganizer/koagendaitem.cpp new file mode 100644 index 0000000..02fd33b --- a/dev/null +++ b/korganizer/koagendaitem.cpp @@ -0,0 +1,720 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include <qlabel.h> +#include <qlayout.h> +#include <qhbox.h> +#include <qvbox.h> +#include <qtooltip.h> +#include <qwhatsthis.h> +#include <qdragobject.h> +#include <qdrawutil.h> +#include <qpainter.h> + +#include <kiconloader.h> +#include <kdebug.h> +#include <kglobal.h> +#include <klocale.h> +#ifndef DESKTOP_VERSION +#include <qpe/qpeapplication.h> +#define AGENDA_ICON_SIZE 5 +#else +#define AGENDA_ICON_SIZE 7 +#endif +#include <libkcal/icaldrag.h> +#include <libkcal/vcaldrag.h> +#include <libkdepim/kincidenceformatter.h> +extern int globalFlagBlockAgenda; +extern int globalFlagBlockAgendaItemPaint; +extern int globalFlagBlockAgendaItemUpdate; + +#include "koprefs.h" + +#include "koagendaitem.h" +#include "koagendaitem.moc" + + +//-------------------------------------------------------------------------- + +QToolTipGroup *KOAgendaItem::mToolTipGroup = 0; + +//-------------------------------------------------------------------------- + +KOAgendaItem::KOAgendaItem(Incidence *incidence, QDate qd, QWidget *parent,bool allday, + const char *name,WFlags) : + QWidget(parent, name), mIncidence(incidence), mDate(qd) +{ +#ifndef DESKTOP_VERSION + QPEApplication::setStylusOperation( this, QPEApplication::RightOnHold ); +#endif + int wflags = getWFlags() |WRepaintNoErase;// WResizeNoErase + setWFlags ( wflags); + mAllDay = allday; + init ( incidence, qd ); + setMouseTracking(true); + //setAcceptDrops(true); + xPaintCoord = -1; + yPaintCoord = -1; +} + +void KOAgendaItem::init ( Incidence *incidence, QDate qd ) +{ + mIncidence = incidence; + mDate = qd; + mFirstMultiItem = 0; + mNextMultiItem = 0; + mLastMultiItem = 0; + computeText(); + + if ( (incidence->type() == "Todo") && + ( !((static_cast<Todo*>(incidence))->isCompleted()) && + ((static_cast<Todo*>(incidence))->dtDue().date() <= QDate::currentDate()) ) ) { + if ( (static_cast<Todo*>(incidence))->dtDue() < QDateTime::currentDateTime().date()) + mBackgroundColor = KOPrefs::instance()->mTodoOverdueColor ; + else + mBackgroundColor = KOPrefs::instance()->mTodoDueTodayColor; + } + else { + QStringList categories = mIncidence->categories(); + QString cat = categories.first(); + if (cat.isEmpty()) { + mBackgroundColor =KOPrefs::instance()->mEventColor; + } else { + mBackgroundColor = *KOPrefs::instance()->categoryColor(cat); + } + } + mColorGroup = QColorGroup( mBackgroundColor.light(), + mBackgroundColor.dark(),mBackgroundColor.light(), + mBackgroundColor.dark(),mBackgroundColor, black, mBackgroundColor) ; + setBackgroundColor( mBackgroundColor ); + + setCellXY(0,0,1); + setCellXWidth(0); + setSubCell(0); + setSubCells(1); + setMultiItem(0,0,0); + startMove(); + mSelected = true; + select(false); + QString tipText = mIncidence->summary(); + // QToolTip::add(this,tipText); + QWhatsThis::add(this,KIncidenceFormatter::instance()->getFormattedText( mIncidence )); + if ( !mIncidence->doesFloat() ) + if ( mIncidence->type() == "Event" ) { + if ( (static_cast<Event*>(mIncidence))->isMultiDay() ) { + tipText += "\n"+i18n("From: ")+mIncidence->dtStartStr(); + tipText += "\n"+i18n("To: ")+(static_cast<Event*>(mIncidence))->dtEndStr(); + } + else { + tipText += "\n"+i18n("Time: ")+mIncidence->dtStartTimeStr(); + tipText += " - "+(static_cast<Event*>(mIncidence))->dtEndTimeStr(); + } + } + else if ( mIncidence->type() == "Todo" ) { + tipText += "\n"+i18n("Due: ")+ (static_cast<Todo*>(mIncidence))->dtDueTimeStr(); + } + + if (!mIncidence->location().isEmpty()) { + tipText += "\n"+i18n("Location: ")+mIncidence->location(); + } + QToolTip::add(this,tipText,toolTipGroup(),""); + QFontMetrics fontinf(KOPrefs::instance()->mAgendaViewFont); + mFontPixelSize = fontinf.height();; + hide(); + xPaintCoord = -1; + yPaintCoord = -1; +} + + +KOAgendaItem::~KOAgendaItem() +{ + // qDebug("deleteKOAgendaItem::~KOAgendaItem( "); + +} + +void KOAgendaItem::recreateIncidence() +{ + Incidence* newInc = mIncidence->clone(); + newInc->recreate(); + if ( mIncidence->doesRecur() ) { + mIncidence->addExDate( mDate ); + newInc->recurrence()->unsetRecurs(); + int len = mIncidence->dtStart().secsTo( ((Event*)mIncidence)->dtEnd()); + QTime tim = mIncidence->dtStart().time(); + newInc->setDtStart( QDateTime(mDate, tim) ); + ((Event*)newInc)->setDtEnd( newInc->dtStart().addSecs( len ) ); + } + mIncidence = newInc; +} +bool KOAgendaItem::updateIcons(QPainter * p, bool horLayout) +{ + int size = AGENDA_ICON_SIZE; + + int yOff = 0; + int xOff = 0; + int x = pos().x() +3; + int y; + if ( mAllDay ) + y = pos().y()+3; + else + y = mCellYTop * ( height() / cellHeight() ) +3; + if (mIncidence->cancelled()) { + int xpos = xOff*( 1 +AGENDA_ICON_SIZE )+x; + int ypos = yOff*( 1 +AGENDA_ICON_SIZE)+y; + p->drawLine( xpos, ypos, xpos+AGENDA_ICON_SIZE-1, ypos+AGENDA_ICON_SIZE-1 ); + p->drawLine( xpos, ypos+AGENDA_ICON_SIZE-1, xpos+AGENDA_ICON_SIZE-1, ypos ); + if ( horLayout ) + ++xOff; + else + ++yOff; + } + if (mIncidence->isAlarmEnabled()) { + p->fillRect ( xOff*( 1 +AGENDA_ICON_SIZE )+x, yOff*( 1 +AGENDA_ICON_SIZE)+y, AGENDA_ICON_SIZE, AGENDA_ICON_SIZE, red ); + if ( horLayout ) + ++xOff; + else + ++yOff; + } + if (mIncidence->recurrence()->doesRecur()) { + p->fillRect ( xOff*( 1 +AGENDA_ICON_SIZE )+x, yOff*( 1 +AGENDA_ICON_SIZE)+y, AGENDA_ICON_SIZE, AGENDA_ICON_SIZE, blue ); + if ( horLayout ) + ++xOff; + else + ++yOff; + } + if (mIncidence->description().length() > 0) { + p->fillRect ( xOff*( 1 +AGENDA_ICON_SIZE )+x, yOff*( 1 +AGENDA_ICON_SIZE)+y, AGENDA_ICON_SIZE, AGENDA_ICON_SIZE, darkGreen ); + if ( horLayout ) + ++xOff; + else + ++yOff; + } + if (mIncidence->isReadOnly()) { + p->fillRect ( xOff*( 1 +AGENDA_ICON_SIZE )+x, yOff*( 1 +AGENDA_ICON_SIZE)+y, AGENDA_ICON_SIZE, AGENDA_ICON_SIZE, white ); + if ( horLayout ) + ++xOff; + else + ++yOff; + } + + if (mIncidence->attendeeCount()>0) { + + if (mIncidence->organizer() == KOPrefs::instance()->email()) { + p->fillRect ( xOff*( 1 +AGENDA_ICON_SIZE )+x, yOff*( 1 +AGENDA_ICON_SIZE)+y, AGENDA_ICON_SIZE, AGENDA_ICON_SIZE, black ); + if ( horLayout ) + ++xOff; + else + ++yOff; + } else { + Attendee *me = mIncidence->attendeeByMails(KOPrefs::instance()->mAdditionalMails,KOPrefs::instance()->email()); + if (me!=0) { + + + } else { + p->fillRect ( xOff*( 1 +AGENDA_ICON_SIZE )+x, yOff*( 1 +AGENDA_ICON_SIZE)+y, AGENDA_ICON_SIZE, AGENDA_ICON_SIZE, yellow ); + if ( horLayout ) + ++xOff; + else + ++yOff; + + } + p->fillRect ( xOff*( 1 +AGENDA_ICON_SIZE )+x, yOff*( 1 +AGENDA_ICON_SIZE)+y, AGENDA_ICON_SIZE, AGENDA_ICON_SIZE, darkYellow ); + if ( horLayout ) + ++xOff; + else + ++yOff; + + } + + } + return ( yOff || xOff ); +} + + +void KOAgendaItem::select(bool selected) +{ + //qDebug("select %d %d",firstMultiItem(), nextMultiItem() ); + if (mSelected == selected) return; + mSelected = selected; + if ( ! isVisible() ) + return; + if ( firstMultiItem() ) + firstMultiItem()->select( selected ); + if ( !firstMultiItem() && nextMultiItem() ) { + KOAgendaItem * placeItem = nextMultiItem(); + while ( placeItem ) { + placeItem->select( selected ); + placeItem = placeItem->nextMultiItem(); + } + } + globalFlagBlockAgendaItemUpdate = 0; + paintMe( selected ); + globalFlagBlockAgendaItemUpdate = 1; + repaint( false ); +} + + +/* + The eventFilter has to filter the mouse events of the agenda item childs. The + events are fed into the event handling method of KOAgendaItem. This allows the + KOAgenda to handle the KOAgendaItems by using an eventFilter. +*/ +bool KOAgendaItem::eventFilter ( QObject *object, QEvent *e ) +{ + if (e->type() == QEvent::MouseButtonPress || + e->type() == QEvent::MouseButtonDblClick || + e->type() == QEvent::MouseButtonRelease || + e->type() == QEvent::MouseMove) { + QMouseEvent *me = (QMouseEvent *)e; + QPoint itemPos = this->mapFromGlobal(((QWidget *)object)-> + mapToGlobal(me->pos())); + QMouseEvent returnEvent (e->type(),itemPos,me->button(),me->state()); + return event(&returnEvent); + } else { + return false; + } +} +void KOAgendaItem::repaintMe( ) +{ + paintMe ( mSelected ); +} +void KOAgendaItem::paintMe( bool selected, QPainter* paint ) +{ + if ( globalFlagBlockAgendaItemUpdate && ! selected) + return; + QPainter pa; + + if ( mSelected ) { + pa.begin( paintPixSel() ); + } else { + if ( mAllDay ) + pa.begin( paintPixAllday() ); + else + pa.begin( paintPix() ); + } + int x, yy, w, h; + float nfh; + x = pos().x(); w = width(); h = height (); + if ( mAllDay ) + yy = y(); + else + yy = mCellYTop * ( height() / cellHeight() ); + xPaintCoord= x; + yPaintCoord = yy; + wPaintCoord = width(); + hPaintCoord = height(); + //qDebug("paintMe %s %d %d %d %d",incidence()->summary().latin1(), x, yy, width(), height()); + if ( paint == 0 ) + paint = &pa; + bool horLayout = ( w < h ); + int maxhei = mFontPixelSize+4; + if ( horLayout ) + maxhei += AGENDA_ICON_SIZE -4; + bool small = ( h < maxhei ); + if ( ! small ) + paint->setFont(KOPrefs::instance()->mAgendaViewFont); + else { + QFont f = KOPrefs::instance()->mAgendaViewFont; + f.setBold( false ); + int fh = f.pointSize(); + nfh = (((float)height())/(float)(mFontPixelSize+4))*fh; + if ( nfh < 6 ) + nfh = 6; + f.setPointSize( nfh ); + paint->setFont(f); + } + paint->fillRect ( x, yy, w, h, mBackgroundColor ); + static const QPixmap completedPxmp = SmallIcon("greenhook16"); + static const QPixmap overduePxmp = SmallIcon("redcross16"); + if ( mIncidence->type() == "Todo" ) { + Todo* tempTodo = static_cast<Todo*>(mIncidence); + int xx = pos().x()+(width()-completedPxmp.width()-3 ); + int yyy = yy+3; + if ( tempTodo->isCompleted() ) + paint->drawPixmap ( xx, yyy, completedPxmp ); + else { + paint->drawPixmap ( xx, yyy, overduePxmp ); + + } + } + bool addIcon = false; + if ( ! small || w > 3 * h || h > 3* w ) + addIcon = updateIcons( paint, horLayout ); + + qDrawShadePanel (paint, x, yy, w, h, mColorGroup, selected , 2, 0); + //qDebug("draw rect %d %d %d %d ",x, yy, w, h ); + if ( ! small ) { + x += 3; yy += 3;w -= 6; h-= 5; + } else { + x += 2; yy += 1;w -= 4; h-= 4; + if ( nfh < 6.01 ) { + yy -= 2; + h += 4; + } + else + if ( nfh < h -2 ) + ++yy; + } + int align; +#ifndef DESKTOP_VERSION + align = ( AlignLeft|WordBreak|AlignTop); +#else + align = ( AlignLeft|BreakAnywhere|WordBreak|AlignTop); +#endif + if ( addIcon ) { + if ( ! horLayout ) { + x += AGENDA_ICON_SIZE+3; + w -= (AGENDA_ICON_SIZE+3); + } + else { + yy+= AGENDA_ICON_SIZE+2; + h -=(AGENDA_ICON_SIZE+3); + } + } + int colsum = mBackgroundColor.red() + mBackgroundColor.green() + mBackgroundColor.blue(); + if ( colsum < 250 ) + paint->setPen ( white); + if ( x < 0 ) { + w = w+x-3; + x = 3; + if ( w > parentWidget()->width() ){ + w = parentWidget()->width() - 6; +#ifndef DESKTOP_VERSION + align = ( AlignCenter|WordBreak); +#else + align = ( AlignCenter|BreakAnywhere|WordBreak); +#endif + + } + } + QRect dr; + paint->drawText ( x, yy, w, h, align, mDisplayedText, -1, &dr ); + if ( mIncidence->cancelled() ){ + if ( ! small ) { + QFontMetrics fm ( paint->font() ); + paint->drawLine(dr.left(), yy+fm.height()/2, dr.right()-2, yy+fm.height()/2); + } + + } + pa.end(); + +} +void KOAgendaItem::resizePixmap( int w , int h ) +{ + paintPix()->resize( w, h ); + paintPixSel()->resize( w, h ); + +} +QPixmap * KOAgendaItem::paintPix() +{ + static QPixmap* mPaintPix = 0; + if ( ! mPaintPix ) + mPaintPix = new QPixmap(); + return mPaintPix ; +} +QPixmap * KOAgendaItem::paintPixAllday() +{ + static QPixmap* mPaintPixA = 0; + if ( ! mPaintPixA ) + mPaintPixA = new QPixmap(); + return mPaintPixA ; +} +QPixmap * KOAgendaItem::paintPixSel() +{ + static QPixmap* mPaintPixSel = 0; + if ( ! mPaintPixSel ) + mPaintPixSel = new QPixmap(); + return mPaintPixSel ; +} +void KOAgendaItem::paintEvent ( QPaintEvent *e ) +{ + + if ( globalFlagBlockAgendaItemPaint ) + return; + if ( globalFlagBlockAgenda > 0 && globalFlagBlockAgenda < 5 ) + return; + int yy; + if ( mAllDay ) + yy = y(); + else + yy = mCellYTop * ( height() / cellHeight() ); + int xx = x(); + if ( xPaintCoord != xx || yPaintCoord != yy || + wPaintCoord != width() || hPaintCoord != height()) { + xPaintCoord= xx; + yPaintCoord = yy; + wPaintCoord = width(); + hPaintCoord = height(); + globalFlagBlockAgendaItemUpdate = 0; + paintMe( mSelected ); + //qDebug("calling paintMe "); + globalFlagBlockAgendaItemUpdate = 1; + } + int rx, ry, rw, rh; + rx = e->rect().x(); + ry = e->rect().y(); + rw = e->rect().width(); + rh = e->rect().height(); + //qDebug(" paintevent %s %d %d %d %d", mIncidence->summary().latin1(), x(), yy, width(), height()); + + QPixmap* paintFrom ; + if ( mSelected ) { + paintFrom = paintPixSel(); + } else { + if ( mAllDay ) + paintFrom = paintPixAllday(); + else + paintFrom = paintPix(); + } + bitBlt (this, rx, ry, paintFrom, x()+rx ,yPaintCoord+ry, rw, rh ,CopyROP); +} +void KOAgendaItem::computeText() +{ + mDisplayedText = mIncidence->summary(); + if ( (mIncidence->type() == "Todo") ) { + if ( static_cast<Todo*>(mIncidence)->dtDue().date() < QDate::currentDate() ) + mDisplayedText += i18n(" (") +KGlobal::locale()->formatDate((static_cast<Todo*>(mIncidence))->dtDue().date(), true)+")"; + else if ( !(mIncidence->doesFloat())) + mDisplayedText += i18n(" (") +KGlobal::locale()->formatTime((static_cast<Todo*>(mIncidence))->dtDue().time())+")"; + + + + } else { + if ( !(mIncidence->doesFloat())) + mDisplayedText += ": " +KGlobal::locale()->formatTime((static_cast<Event*>(mIncidence))->dtStart().time()) + "-" + KGlobal::locale()->formatTime((static_cast<Event*>(mIncidence))->dtEnd().time()) ; + + if ( mAllDay ) { + if ( mIncidence->dtStart().date().addDays(3) < mIncidence->dtEnd().date() ) { + mDisplayedText += ": " +KGlobal::locale()->formatDate((static_cast<Event*>(mIncidence))->dtStart().date(), true) + " - " + KGlobal::locale()->formatDate((static_cast<Event*>(mIncidence))->dtEnd().date(), true) ; + } + } + + } + + if ( !mIncidence->location().isEmpty() ) { + if ( mAllDay ) + mDisplayedText += " ("; + else + mDisplayedText += "\n("; + mDisplayedText += mIncidence->location() +")"; + } +} +void KOAgendaItem::updateItem() +{ + computeText(); + + //qDebug("KOAgendaItem:: updateItem() %s %d %d ",incidence()->summary().latin1(), x(), y()); + paintMe( mSelected ); + repaint( false); +} + +void KOAgendaItem::resizeEvent ( QResizeEvent *ev ) +{ + //qDebug("KOAgendaItem::resizeEvent %s ", mIncidence->summary().latin1()); + paintMe( mSelected ); + repaint( false ); +} + +/* + Return height of item in units of agenda cells +*/ +int KOAgendaItem::cellHeight() +{ + int ret = mCellYBottom - mCellYTop + 1; + if ( ret <= 0 ) { + ret = 1; + mCellYBottom = 0; + mCellYTop = 0; + } + return ret; +} + +/* + Return height of item in units of agenda cells +*/ +int KOAgendaItem::cellWidth() +{ + return mCellXWidth - mCellX + 1; +} + +void KOAgendaItem::setItemDate(QDate qd) +{ + mDate = qd; +} + +void KOAgendaItem::setCellXY(int X, int YTop, int YBottom) +{ + mCellX = X; + mCellYTop = YTop; + mCellYBottom = YBottom; +} + +void KOAgendaItem::setCellXWidth(int xwidth) +{ + mCellXWidth = xwidth; +} + +void KOAgendaItem::setCellX(int XLeft, int XRight) +{ + mCellX = XLeft; + mCellXWidth = XRight; +} + +void KOAgendaItem::setCellY(int YTop, int YBottom) +{ + mCellYTop = YTop; + mCellYBottom = YBottom; +} + +void KOAgendaItem::setSubCell(int subCell) +{ + mSubCell = subCell; +} + +void KOAgendaItem::setSubCells(int subCells) +{ + mSubCells = subCells; +} + +void KOAgendaItem::setMultiItem(KOAgendaItem *first,KOAgendaItem *next, + KOAgendaItem *last) +{ + mFirstMultiItem = first; + mNextMultiItem = next; + mLastMultiItem = last; +} + +void KOAgendaItem::startMove() +{ + mStartCellX = mCellX; + mStartCellXWidth = mCellXWidth; + mStartCellYTop = mCellYTop; + mStartCellYBottom = mCellYBottom; +} + +void KOAgendaItem::resetMove() +{ + mCellX = mStartCellX; + mCellXWidth = mStartCellXWidth; + mCellYTop = mStartCellYTop; + mCellYBottom = mStartCellYBottom; +} + +void KOAgendaItem::moveRelative(int dx, int dy) +{ + int newX = cellX() + dx; + int newXWidth = cellXWidth() + dx; + int newYTop = cellYTop() + dy; + int newYBottom = cellYBottom() + dy; + setCellXY(newX,newYTop,newYBottom); + setCellXWidth(newXWidth); +} + +void KOAgendaItem::expandTop(int dy) +{ + int newYTop = cellYTop() + dy; + int newYBottom = cellYBottom(); + if (newYTop > newYBottom) newYTop = newYBottom; + setCellY(newYTop, newYBottom); +} + +void KOAgendaItem::expandBottom(int dy) +{ + int newYTop = cellYTop(); + int newYBottom = cellYBottom() + dy; + if (newYBottom < newYTop) newYBottom = newYTop; + setCellY(newYTop, newYBottom); +} + +void KOAgendaItem::expandLeft(int dx) +{ + int newX = cellX() + dx; + int newXWidth = cellXWidth(); + if (newX > newXWidth) newX = newXWidth; + setCellX(newX,newXWidth); +} + +void KOAgendaItem::expandRight(int dx) +{ + int newX = cellX(); + int newXWidth = cellXWidth() + dx; + if (newXWidth < newX) newXWidth = newX; + setCellX(newX,newXWidth); +} + +QToolTipGroup *KOAgendaItem::toolTipGroup() +{ + if (!mToolTipGroup) mToolTipGroup = new QToolTipGroup(0); + return mToolTipGroup; +} + +void KOAgendaItem::dragEnterEvent( QDragEnterEvent *e ) +{ +#ifndef KORG_NODND + if ( ICalDrag::canDecode( e ) || VCalDrag::canDecode( e ) || + !QTextDrag::canDecode( e ) ) { + e->ignore(); + return; + } + e->accept(); +#endif +} + +void KOAgendaItem::dropEvent( QDropEvent *e ) +{ +#ifndef KORG_NODND + QString text; + if(QTextDrag::decode(e,text)) + { + kdDebug() << "Dropped : " << text << endl; + QStringList emails = QStringList::split(",",text); + for(QStringList::ConstIterator it = emails.begin();it!=emails.end();++it) { + kdDebug() << " Email: " << (*it) << endl; + int pos = (*it).find("<"); + QString name = (*it).left(pos); + QString email = (*it).mid(pos); + if (!email.isEmpty()) { + mIncidence->addAttendee(new Attendee(name,email)); + } + } + } +#endif +} + + +QPtrList<KOAgendaItem> KOAgendaItem::conflictItems() +{ + return mConflictItems; +} + +void KOAgendaItem::setConflictItems(QPtrList<KOAgendaItem> ci) +{ + mConflictItems = ci; + KOAgendaItem *item; + for ( item=mConflictItems.first(); item != 0; + item=mConflictItems.next() ) { + item->addConflictItem(this); + } +} + +void KOAgendaItem::addConflictItem(KOAgendaItem *ci) +{ + if (mConflictItems.find(ci)<0) + mConflictItems.append(ci); +} diff --git a/korganizer/koagendaitem.h b/korganizer/koagendaitem.h new file mode 100644 index 0000000..7321af2 --- a/dev/null +++ b/korganizer/koagendaitem.h @@ -0,0 +1,160 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef KOAGENDAITEM_H +#define KOAGENDAITEM_H + +#include <qframe.h> +#include <qlabel.h> +#include <qpixmap.h> +#include <qdatetime.h> +#include <qpalette.h> + +#include <libkcal/incidence.h> + +class QToolTipGroup; +class QDragEnterEvent; +class QDropEvent; + +using namespace KCal; + +/* + The KOAgendaItem has to make sure that it receives all mouse events, which are + to be used for dragging and resizing. That means it has to be installed as + eventfiler for its children, if it has children, and it has to pass mouse + events from the cildren to itself. See eventFilter(). +*/ +class KOAgendaItem : public QWidget +{ + Q_OBJECT + public: + KOAgendaItem(Incidence *incidence, QDate qd, QWidget *parent, bool allday, const char *name=0, + WFlags f=0 ); + ~KOAgendaItem(); + void init ( Incidence *incidence, QDate qd ); + int cellX() { return mCellX; } + int cellXWidth() { return mCellXWidth; } + int cellYTop() { return mCellYTop; } + int cellYBottom() { return mCellYBottom; } + int cellHeight(); + int cellWidth(); + int subCell() { return mSubCell; } + int subCells() { return mSubCells; } + + void setCellXY(int X, int YTop, int YBottom); + void setCellY(int YTop, int YBottom); + void setCellX(int XLeft, int XRight); + void setCellXWidth(int xwidth); + void setSubCell(int subCell); + void setSubCells(int subCells); + + /** Start movement */ + void startMove(); + /** Reset to original values */ + void resetMove(); + + void moveRelative(int dx,int dy); + void expandTop(int dy); + void expandBottom(int dy); + void expandLeft(int dx); + void expandRight(int dx); + int mLastMoveXPos; + + void setMultiItem(KOAgendaItem *first,KOAgendaItem *next, + KOAgendaItem *last); + KOAgendaItem *firstMultiItem() { return mFirstMultiItem; } + KOAgendaItem *nextMultiItem() { return mNextMultiItem; } + KOAgendaItem *lastMultiItem() { return mLastMultiItem; } + + Incidence *incidence() const { return mIncidence; } + QDate itemDate() { return mDate; } + + /** Update the date of this item's occurence (not in the event) */ + void setItemDate(QDate qd); + + void setText ( const QString & text ) { mDisplayedText = text; } + QString text () { return mDisplayedText; } + + virtual bool eventFilter ( QObject *, QEvent * ); + + static QToolTipGroup *toolTipGroup(); + + QPtrList<KOAgendaItem> conflictItems(); + void setConflictItems(QPtrList<KOAgendaItem>); + void addConflictItem(KOAgendaItem *ci); + void paintMe( bool, QPainter* painter = 0 ); + void repaintMe(); + static void resizePixmap( int, int ); + static QPixmap * paintPix(); + static QPixmap * paintPixSel(); + static QPixmap * paintPixAllday(); + void updateItem(); + void computeText(); + void recreateIncidence(); + public slots: + bool updateIcons( QPainter *, bool ); + void select(bool=true); + + protected: + void dragEnterEvent(QDragEnterEvent *e); + void dropEvent(QDropEvent *e); + void paintEvent ( QPaintEvent * ); + void resizeEvent ( QResizeEvent *ev ); + + private: + bool mAllDay; + int mCellX; + int mCellXWidth; + int mCellYTop,mCellYBottom; + int mSubCell; // subcell number of this item + int mSubCells; // Total number of subcells in cell of this item + int xPaintCoord; + int yPaintCoord; + int wPaintCoord; + int hPaintCoord; + // Variables to remember start position + int mStartCellX; + int mStartCellXWidth; + int mStartCellYTop,mStartCellYBottom; + int mLastMovePos; + + // Multi item pointers + KOAgendaItem *mFirstMultiItem; + KOAgendaItem *mNextMultiItem; + KOAgendaItem *mLastMultiItem; + + int mFontPixelSize; + Incidence *mIncidence; // corresponding event or todo + QDate mDate; //date this events occurs (for recurrence) + //void showIcon( QLabel*, int ); + //QLabel *mTodoIconLabel; + //QLabel *mItemLabel; + //QWidget *mIconBox; + //QLabel *mIconAlarm,*mIconRecur,*mIconReadonly; + //QLabel *mIconReply,*mIconGroup,*mIconOrganizer; + //QLabel *mIconMoreInfo; + static QToolTipGroup *mToolTipGroup; + + QColor mBackgroundColor; + QColorGroup mColorGroup; + QString mDisplayedText; + bool mSelected; + QPtrList<KOAgendaItem> mConflictItems; +}; + +#endif // KOAGENDAITEM_H diff --git a/korganizer/koagendaitem.moc b/korganizer/koagendaitem.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/koagendaitem.moc diff --git a/korganizer/koagendaview.cpp b/korganizer/koagendaview.cpp new file mode 100644 index 0000000..9e057e4 --- a/dev/null +++ b/korganizer/koagendaview.cpp @@ -0,0 +1,1436 @@ +/* + 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. +*/ + +#include <qhbox.h> +#include <qvbox.h> +#include <qlabel.h> +#include <qframe.h> +#include <qlayout.h> +#ifndef KORG_NOSPLITTER +#include <qsplitter.h> +#endif +#include <qfont.h> +#include <qfontmetrics.h> +#include <qpopupmenu.h> +#include <qtooltip.h> +#include <qpainter.h> +#include <qpushbutton.h> +#include <qapplication.h> + +#include <kapplication.h> +#include <KDGanttMinimizeSplitter.h> +#include <kdebug.h> +#include <kstandarddirs.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kconfig.h> +#include <kglobal.h> +#include "calendarview.h" +#include "koviewmanager.h" + +#include <libkcal/calendar.h> +#include <libkcal/icaldrag.h> +#include <libkcal/dndfactory.h> + +#include <kcalendarsystem.h> + +#include "koglobals.h" +#ifndef KORG_NOPLUGINS +#include "kocore.h" +#endif +#include "koprefs.h" +#include "koagenda.h" +#include "koagendaitem.h" +#ifndef KORG_NOPRINTER +#include "calprinter.h" +#endif + +#include "koagendaview.h" +#include "koagendaview.moc" + +//extern bool globalFlagBlockPainting; +extern int globalFlagBlockAgenda; +extern int globalFlagBlockStartup; +extern int globalFlagBlockAgendaItemPaint; +extern int globalFlagBlockAgendaItemUpdate; +extern int globalFlagBlockLabel; +using namespace KOrg; + +TimeLabels::TimeLabels(int rows,QWidget *parent,const char *name,WFlags f) : + QScrollView(parent,name,f) +{ + mRows = rows; + + setMinimumHeight( 20 ); + mCellHeight = KOPrefs::instance()->mHourSize*4; + + enableClipper(true); + + setHScrollBarMode(AlwaysOff); + setVScrollBarMode(AlwaysOff); + + resizeContents(50,mRows * mCellHeight); + + viewport()->setBackgroundMode( PaletteBackground ); +} + +void TimeLabels::setCellHeight(int height) +{ + mCellHeight = height; +} + +/* + Optimization so that only the "dirty" portion of the scroll view + is redrawn. Unfortunately, this is not called by default paintEvent() method. +*/ +void TimeLabels::drawContents(QPainter *p,int cx, int cy, int cw, int ch) +{ + + // if ( globalFlagBlockAgenda ) + // return; + // bug: the parameters cx, cy, cw, ch are the areas that need to be + // redrawn, not the area of the widget. unfortunately, this + // code assumes the latter... + + // now, for a workaround... + // these two assignments fix the weird redraw bug + cx = contentsX() + 2; + cw = contentsWidth() - 2; + // end of workaround + + int cell = ((int)(cy/mCellHeight)); + int y = cell * mCellHeight; + QFontMetrics fm = fontMetrics(); + QString hour; + QString suffix; + QString fullTime; + int tW = fm.width("24:00i"); + + while (y < cy + ch) { + p->drawLine(cx,y,cx+tW,y); + hour.setNum(cell); + suffix = "am"; + + // handle 24h and am/pm time formats + if (KGlobal::locale()->use12Clock()) { + if (cell > 11) suffix = "pm"; + if (cell == 0) hour.setNum(12); + if (cell > 12) hour.setNum(cell - 12); + } else { + suffix = ":00"; + } + + // create string in format of "XX:XX" or "XXpm/am" + fullTime = hour + suffix; + + // center and draw the time label + int timeWidth = fm.width(fullTime+"i"); + int offset = this->width() - timeWidth; + int borderWidth = 5; + int timeHeight = fm.height(); + timeHeight = timeHeight + 2 - ( timeHeight / 4 ); + p->drawText(cx -borderWidth + offset, y+ timeHeight, fullTime); + + // increment indices + y += mCellHeight; + cell++; + } +} + +/** + Calculates the minimum width. +*/ +int TimeLabels::minimumWidth() const +{ + QFontMetrics fm = fontMetrics(); + + //TODO: calculate this value + int borderWidth = 4; + + // the maximum width possible + int width = fm.width("88:88x") + borderWidth; + + return width; +} + +/** updates widget's internal state */ +void TimeLabels::updateConfig() +{ + // set the font + // config->setGroup("Fonts"); + // QFont font = config->readFontEntry("TimeBar Font"); + setFont(KOPrefs::instance()->mTimeBarFont); + + // update geometry restrictions based on new settings + setFixedWidth(minimumWidth()); + + // update HourSize + mCellHeight = KOPrefs::instance()->mHourSize*4; + resizeContents(50,mRows * mCellHeight); +} + +/** update time label positions */ +void TimeLabels::positionChanged() +{ + int adjustment = mAgenda->contentsY(); + setContentsPos(0, adjustment); +} + +/** */ +void TimeLabels::setAgenda(KOAgenda* agenda) +{ + mAgenda = agenda; +} + + +/** This is called in response to repaint() */ +void TimeLabels::paintEvent(QPaintEvent*) +{ + + // kdDebug() << "paintevent..." << endl; + // this is another hack! + // QPainter painter(this); + //QString c + repaintContents(contentsX(), contentsY(), visibleWidth(), visibleHeight()); +} + +//////////////////////////////////////////////////////////////////////////// + +EventIndicator::EventIndicator(Location loc,QWidget *parent,const char *name) + : QFrame(parent,name) +{ + mColumns = 1; + mTopBox = 0; + mLocation = loc; + mTopLayout = 0; + mPaintWidget = 0; + mXOffset = 0; + if (mLocation == Top) mPixmap = SmallIcon("1uparrow"); + else mPixmap = SmallIcon("1downarrow"); + mEnabled.resize(mColumns); + if (mLocation == Top) + setMaximumHeight(0); + else + setMinimumHeight(mPixmap.height()); +} + +EventIndicator::~EventIndicator() +{ +} + +void EventIndicator::drawContents(QPainter *p) +{ + + // kdDebug() << "======== top: " << contentsRect().top() << " bottom " << // contentsRect().bottom() << " left " << contentsRect().left() << " right " << contentsRect().right() << endl; + KDGanttSplitterHandle* han = 0; + if ( mPaintWidget ) + han = mPaintWidget->firstHandle(); + if ( ! han ) { + int i; + for(i=0;i<mColumns;++i) { + if (mEnabled[i]) { + int cellWidth = contentsRect().right()/mColumns; + int xOffset = KOGlobals::self()->reverseLayout() ? + (mColumns - 1 - i)*cellWidth + cellWidth/2 -mPixmap.width()/2 : + i*cellWidth + cellWidth/2 -mPixmap.width()/2; + p->drawPixmap(QPoint(xOffset,0),mPixmap); + } + } + } else { + han->repaint(); + //mPaintWidget->setBackgroundColor( red ); + + QPainter pa( han ); + int i; + bool setColor = false; + for(i=0;i<mColumns;++i) { + if (mEnabled[i]) { + setColor = true; + + int cellWidth = contentsRect().right()/mColumns; + int xOffset = KOGlobals::self()->reverseLayout() ? + (mColumns - 1 - i)*cellWidth + cellWidth/2 -mPixmap.width()/2 : + i*cellWidth + cellWidth/2 -mPixmap.width()/2; + pa.drawPixmap(QPoint(mXOffset + xOffset,0),mPixmap); + //qDebug("222draw pix %d ",xOffset ); + + } + + } + pa.end(); + + } +} + +void EventIndicator::setXOffset( int x ) +{ + mXOffset = x; +} +void EventIndicator::setPaintWidget( KDGanttMinimizeSplitter * w ) +{ + mPaintWidget = w; +} +void EventIndicator::changeColumns(int columns) +{ + mColumns = columns; + mEnabled.resize(mColumns); + + update(); +} + +void EventIndicator::enableColumn(int column, bool enable) +{ + mEnabled[column] = enable; +} + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + +KOAgendaView::KOAgendaView(Calendar *cal,QWidget *parent,const char *name) : + KOEventView (cal,parent,name) +{ + mBlockUpdating = true; + mStartHour = 8; + mSelectedDates.append(QDate::currentDate()); + + mLayoutDayLabels = 0; + mDayLabelsFrame = 0; + mDayLabels = 0; + bool isRTL = KOGlobals::self()->reverseLayout(); + + if ( KOPrefs::instance()->mVerticalScreen ) { + mExpandedPixmap = SmallIcon( "1downarrow" ); + mNotExpandedPixmap = SmallIcon( "1uparrow" ); + } else { + mExpandedPixmap = SmallIcon( isRTL ? "1leftarrow" : "1rightarrow" ); + mNotExpandedPixmap = SmallIcon( isRTL ? "1rightarrow" : "1leftarrow" ); + } + + QBoxLayout *topLayout = new QVBoxLayout(this); + + // Create day name labels for agenda columns + mDayLabelsFrame = new QHBox(this); + topLayout->addWidget(mDayLabelsFrame); + mDayLabels = new QFrame (mDayLabelsFrame); + mLayoutDayLabels = new QHBoxLayout(mDayLabels); + // Create agenda splitter +#ifndef KORG_NOSPLITTER + mSplitterAgenda = new QSplitter(Vertical,this); + topLayout->addWidget(mSplitterAgenda); + mSplitterAgenda->setOpaqueResize(); + + mAllDayFrame = new QHBox(mSplitterAgenda); + + QWidget *agendaFrame = new QWidget(mSplitterAgenda); +#else +#if 0 + QWidget *mainBox = new QWidget( this ); + topLayout->addWidget( mainBox ); + QBoxLayout *mainLayout = new QVBoxLayout(mainBox); + mAllDayFrame = new QHBox(mainBox); + mainLayout->addWidget(mAllDayFrame); + mainLayout->setStretchFactor( mAllDayFrame, 0 ); + mAllDayFrame->setFocusPolicy(NoFocus); + QWidget *agendaFrame = new QWidget(mainBox); + mainLayout->addWidget(agendaFrame); + mainLayout->setStretchFactor( agendaFrame, 10 ); + + agendaFrame->setFocusPolicy(NoFocus); +#endif + mSplitterAgenda = new KDGanttMinimizeSplitter( Qt::Vertical, this); + mSplitterAgenda->setMinimizeDirection ( KDGanttMinimizeSplitter::Up ); + topLayout->addWidget( mSplitterAgenda ); + mAllDayFrame = new QHBox(mSplitterAgenda); + mAllDayFrame->setFocusPolicy(NoFocus); + QWidget *agendaFrame = new QWidget(mSplitterAgenda); + agendaFrame->setFocusPolicy(NoFocus); + +#endif + + // Create all-day agenda widget + mDummyAllDayLeft = new QVBox( mAllDayFrame ); + + mExpandButton = new QPushButton(mDummyAllDayLeft); + mExpandButton->setPixmap( mNotExpandedPixmap ); + mExpandButton->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, + QSizePolicy::Fixed ) ); + connect( mExpandButton, SIGNAL( clicked() ), SIGNAL( toggleExpand() ) ); + mExpandButton->setFocusPolicy(NoFocus); + mAllDayAgenda = new KOAgenda(1,mAllDayFrame); + mAllDayAgenda->setFocusPolicy(NoFocus); + QWidget *dummyAllDayRight = new QWidget(mAllDayFrame); + + // Create event context menu for all day agenda + mAllDayAgendaPopup = eventPopup(); + connect(mAllDayAgenda,SIGNAL(showIncidencePopupSignal(Incidence *)), + mAllDayAgendaPopup,SLOT(showIncidencePopup(Incidence *))); + + // Create agenda frame + QGridLayout *agendaLayout = new QGridLayout(agendaFrame,3,3); + // QHBox *agendaFrame = new QHBox(splitterAgenda); + + // create event indicator bars + mEventIndicatorTop = new EventIndicator(EventIndicator::Top,agendaFrame); + agendaLayout->addWidget(mEventIndicatorTop,0,1); + mEventIndicatorTop->setPaintWidget( mSplitterAgenda ); + mEventIndicatorBottom = new EventIndicator(EventIndicator::Bottom, + agendaFrame); + agendaLayout->addWidget(mEventIndicatorBottom,2,1); + QWidget *dummyAgendaRight = new QWidget(agendaFrame); + agendaLayout->addWidget(dummyAgendaRight,0,2); + + // Create time labels + mTimeLabels = new TimeLabels(24,agendaFrame); + agendaLayout->addWidget(mTimeLabels,1,0); + + // Create agenda + mAgenda = new KOAgenda(1,96,KOPrefs::instance()->mHourSize,agendaFrame); + agendaLayout->addMultiCellWidget(mAgenda,1,1,1,2); + agendaLayout->setColStretch(1,1); + mAgenda->setFocusPolicy(NoFocus); + // Create event context menu for agenda + mAgendaPopup = eventPopup(); + + mAgendaPopup->addAdditionalItem(QIconSet(SmallIcon("bell")), + i18n("Toggle Alarm"),mAgenda, + SLOT(popupAlarm()),true); + + + connect(mAgenda,SIGNAL(showIncidencePopupSignal(Incidence *)), + mAgendaPopup,SLOT(showIncidencePopup(Incidence *))); + + // make connections between dependent widgets + mTimeLabels->setAgenda(mAgenda); + + // Update widgets to reflect user preferences + // updateConfig(); + + // createDayLabels(); + + // these blank widgets make the All Day Event box line up with the agenda + dummyAllDayRight->setFixedWidth(mAgenda->verticalScrollBar()->width()); + dummyAgendaRight->setFixedWidth(mAgenda->verticalScrollBar()->width()); + mDummyAllDayLeft->setFixedWidth(mTimeLabels->width()); + + // Scrolling + connect(mAgenda->verticalScrollBar(),SIGNAL(valueChanged(int)), + mTimeLabels, SLOT(positionChanged())); + connect(mTimeLabels->verticalScrollBar(),SIGNAL(valueChanged(int)), + SLOT(setContentsPos(int))); + + // Create/Show/Edit/Delete Event + connect(mAgenda,SIGNAL(newEventSignal(int,int)), + SLOT(newEvent(int,int))); + connect(mAgenda,SIGNAL(newEventSignal(int,int,int,int)), + SLOT(newEvent(int,int,int,int))); + connect(mAllDayAgenda,SIGNAL(newEventSignal(int,int)), + SLOT(newEventAllDay(int,int))); + connect(mAllDayAgenda,SIGNAL(newEventSignal(int,int,int,int)), + SLOT(newEventAllDay(int,int))); + connect(mAgenda,SIGNAL(newTimeSpanSignal(int,int,int,int)), + SLOT(newTimeSpanSelected(int,int,int,int))); + connect(mAllDayAgenda,SIGNAL(newTimeSpanSignal(int,int,int,int)), + SLOT(newTimeSpanSelectedAllDay(int,int,int,int))); + connect(mAgenda,SIGNAL(newStartSelectSignal()),SLOT(updateView())); + connect(mAllDayAgenda,SIGNAL(newStartSelectSignal()),SLOT(updateView())); + + connect(mAgenda,SIGNAL(editIncidenceSignal(Incidence *)), + SIGNAL(editIncidenceSignal(Incidence *))); + connect(mAllDayAgenda,SIGNAL(editIncidenceSignal(Incidence *)), + SIGNAL(editIncidenceSignal(Incidence *))); + connect(mAgenda,SIGNAL(showIncidenceSignal(Incidence *)), + SIGNAL(showIncidenceSignal(Incidence *))); + connect(mAllDayAgenda,SIGNAL(showIncidenceSignal(Incidence *)), + SIGNAL(showIncidenceSignal(Incidence *))); + connect(mAgenda,SIGNAL(deleteIncidenceSignal(Incidence *)), + SIGNAL(deleteIncidenceSignal(Incidence *))); + connect(mAllDayAgenda,SIGNAL(deleteIncidenceSignal(Incidence *)), + SIGNAL(deleteIncidenceSignal(Incidence *))); + + connect(mAgenda,SIGNAL(itemModified(KOAgendaItem *, int )), + SLOT(updateEventDates(KOAgendaItem *, int ))); + connect(mAllDayAgenda,SIGNAL(itemModified(KOAgendaItem *, int )), + SLOT(updateEventDates(KOAgendaItem *, int))); + + // event indicator update + connect(mAgenda,SIGNAL(lowerYChanged(int)), + SLOT(updateEventIndicatorTop(int))); + connect(mAgenda,SIGNAL(upperYChanged(int)), + SLOT(updateEventIndicatorBottom(int))); + // drag signals + /* + connect(mAgenda,SIGNAL(startDragSignal(Event *)), + SLOT(startDrag(Event *))); + connect(mAllDayAgenda,SIGNAL(startDragSignal(Event *)), + SLOT(startDrag(Event *))); + */ + // synchronize selections + connect( mAgenda, SIGNAL( incidenceSelected( Incidence * ) ), + mAllDayAgenda, SLOT( deselectItem() ) ); + connect( mAllDayAgenda, SIGNAL( incidenceSelected( Incidence * ) ), + mAgenda, SLOT( deselectItem() ) ); + connect( mAgenda, SIGNAL( incidenceSelected( Incidence * ) ), + SIGNAL( incidenceSelected( Incidence * ) ) ); + connect( mAllDayAgenda, SIGNAL( incidenceSelected( Incidence * ) ), + SIGNAL( incidenceSelected( Incidence * ) ) ); + connect( mAgenda, SIGNAL( resizedSignal() ), + SLOT( updateConfig( ) ) ); + connect( mAgenda, SIGNAL( addToCalSignal(Incidence *, Incidence *) ), + SLOT( addToCalSlot(Incidence *, Incidence * ) ) ); + connect( mAllDayAgenda, SIGNAL( addToCalSignal(Incidence * ,Incidence *) ), + SLOT( addToCalSlot(Incidence * , Incidence *) ) ); + // connect( mAgenda, SIGNAL( cloneIncidenceSignal(Incidence *) ), SIGNAL( cloneIncidenceSignal(Incidence *) ) ); + //connect( mAllDayAgenda, SIGNAL( cloneIncidenceSignal(Incidence *) ), SIGNAL( cloneIncidenceSignal(Incidence *) ) ); + + +} + +void KOAgendaView::toggleAllDay() +{ + if ( mSplitterAgenda->firstHandle() ) + mSplitterAgenda->firstHandle()->toggle(); +} +void KOAgendaView::addToCalSlot(Incidence * inc, Incidence * incOld ) +{ + calendar()->addIncidence( inc ); + + if ( incOld ) { + if ( incOld->type() == "Todo" ) + emit todoMoved((Todo*)incOld, KOGlobals::EVENTEDITED ); + else + emit incidenceChanged(incOld, KOGlobals::EVENTEDITED); + } + +} + +KOAgendaView::~KOAgendaView() +{ + delete mAgendaPopup; + delete mAllDayAgendaPopup; + delete KOAgendaItem::paintPix(); + delete KOAgendaItem::paintPixSel(); +} +void KOAgendaView::resizeEvent( QResizeEvent* e ) +{ + //qDebug("KOAgendaView::resizeEvent( QResizeEvent* e ) %d ", e->size().width()); + bool uc = false; + int ow = e->oldSize().width(); + int oh = e->oldSize().height(); + int w = e->size().width(); + int h = e->size().height(); + if ( (ow > oh && w< h ) || (ow < oh && w > h ) ) { + if ( ! mBlockUpdating && !globalFlagBlockStartup && !globalFlagBlockAgenda ) + uc = true; + //qDebug("view changed %d %d %d %d ", ow, oh , w , h); + } + mUpcomingWidth = e->size().width() ; + if ( mBlockUpdating || uc ) { + mBlockUpdating = false; + //mAgenda->setMinimumSize(800 , 600 ); + //qDebug("mAgenda->resize+++++++++++++++ "); + updateConfig(); + //qDebug("KOAgendaView::Updating now possible "); + } else + createDayLabels(); + //qDebug("resizeEvent end "); + +} +void KOAgendaView::createDayLabels() +{ + + if ( mBlockUpdating || globalFlagBlockLabel == 1) { + // qDebug(" KOAgendaView::createDayLabels() blocked "); + return; + + } + int newHight; + + // ### Before deleting and recreating we could check if mSelectedDates changed... + // It would remove some flickering and gain speed (since this is called by + // each updateView() call) + + int maxWid = mUpcomingWidth - mTimeLabels->width()- mAgenda->verticalScrollBar()->width() - 2; + mDayLabelsFrame->setMaximumWidth( mUpcomingWidth ); + if ( maxWid < 0 ) + maxWid = 20; + + QFont dlf = KOPrefs::instance()->mTimeLabelsFont; + QFontMetrics fm ( dlf ); + int selCount = mSelectedDates.count(); + QString dayTest = "Mon 20"; + int wid = fm.width( dayTest ); + maxWid -= ( selCount * 3 ); + if ( maxWid < 0 ) + maxWid = 20; + int needWid = wid * selCount; + //qDebug("++++++++Needed : %d MaxWidth: %d", needWid, maxWid ); + //if ( needWid > maxWid ) + // qDebug("DAYLABELS TOOOOOOO BIG "); + while ( needWid > maxWid ) { + dayTest = dayTest.left( dayTest.length() - 1 ); + wid = fm.width( dayTest ); + needWid = wid * selCount; + } + int maxLen = dayTest.length(); + int fontPoint = dlf.pointSize(); + if ( maxLen < 2 ) { + int fontPoint = dlf.pointSize(); + while ( fontPoint > 4 ) { + --fontPoint; + dlf.setPointSize( fontPoint ); + QFontMetrics f( dlf ); + wid = f.width( "20" ); + needWid = wid * selCount; + if ( needWid < maxWid ) + break; + } + maxLen = 2; + } + //qDebug("Max len %d ", dayTest.length() ); + + QFontMetrics tempF( dlf ); + newHight = tempF.height(); + mDayLabels->setFont( dlf ); + // mLayoutDayLabels = new QHBoxLayout(mDayLabels);; + // mLayoutDayLabels->addSpacing(mTimeLabels->width()); + //mLayoutDayLabels->addSpacing( 2 ); + // QFont lFont = dlf; + bool appendLabels = false; + QLabel *dayLabel; + dayLabel = mDayLabelsList.first(); + if ( !dayLabel ) { + appendLabels = true; + dayLabel = new QLabel(mDayLabels); + mDayLabelsList.append( dayLabel ); + mLayoutDayLabels->addWidget(dayLabel); + } + dayLabel->setFixedWidth( mTimeLabels->width()+2 ); + dayLabel->setFont( dlf ); + dayLabel->setAlignment(QLabel::AlignHCenter); + dayLabel->setText( KOGlobals::self()->calendarSystem()->monthName( mSelectedDates.first(), true ) ); + dayLabel->show(); + DateList::ConstIterator dit; + for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) { + QDate date = *dit; + // QBoxLayout *dayLayout = new QVBoxLayout(mLayoutDayLabels); + if ( ! appendLabels ) { + dayLabel = mDayLabelsList.next(); + if ( !dayLabel ) + appendLabels = true; + } + if ( appendLabels ) { + dayLabel = new QLabel(mDayLabels); + mDayLabelsList.append( dayLabel ); + mLayoutDayLabels->addWidget(dayLabel); + } + dayLabel->setMinimumWidth( 1 ); + dayLabel->setMaximumWidth( 2048 ); + dayLabel->setFont( dlf ); + dayLabel->show(); + QString str; + int dW = KOGlobals::self()->calendarSystem()->dayOfWeek(date); + QString dayName = KOGlobals::self()->calendarSystem()->weekDayName( dW, true ); + switch ( maxLen ) { + case 2: + str = QString::number( date.day() ); + break; + + case 3: + str = dayName.left( 1 ) +QString::number( date.day()); + + break; + case 4: + str = dayName.left( 1 ) + " " +QString::number( date.day()); + + break; + case 5: + str = dayName.left( 2 ) + " " +QString::number( date.day()); + + break; + case 6: + str = dayName.left( 3 ) + " " +QString::number( date.day()); + break; + + default: + break; + } + + dayLabel->setText(str); + dayLabel->setAlignment(QLabel::AlignHCenter); + if (date == QDate::currentDate()) { + QFont bFont = dlf; + bFont.setBold( true ); + dayLabel->setFont(bFont); + } + //dayLayout->addWidget(dayLabel); + +#ifndef KORG_NOPLUGINS + CalendarDecoration::List cds = KOCore::self()->calendarDecorations(); + CalendarDecoration *it; + for(it = cds.first(); it; it = cds.next()) { + QString text = it->shortText( date ); + if ( !text.isEmpty() ) { + QLabel *label = new QLabel(text,mDayLabels); + label->setAlignment(AlignCenter); + dayLayout->addWidget(label); + } + } + + for(it = cds.first(); it; it = cds.next()) { + QWidget *wid = it->smallWidget(mDayLabels,date); + if ( wid ) { + // wid->setHeight(20); + dayLayout->addWidget(wid); + } + } +#endif + } + if ( ! appendLabels ) { + dayLabel = mDayLabelsList.next(); + if ( !dayLabel ) + appendLabels = true; + } + if ( appendLabels ) { + dayLabel = new QLabel(mDayLabels); + mDayLabelsList.append( dayLabel ); + mLayoutDayLabels->addWidget(dayLabel); + } + //dayLabel->hide();//test only + + int offset = (mAgenda->width() - mAgenda->verticalScrollBar()->width()-3 ) % mSelectedDates.count() ; + if ( offset < 0 ) offset = 0; + //qDebug("mLayoutDayLabels->addSpacing %d ", mAgenda->verticalScrollBar()->width()+offset+2 ); + dayLabel->setText("");//QString::number ( mSelectedDates.first().month() ) ); + dayLabel->show(); + dayLabel->setFixedWidth( mAgenda->verticalScrollBar()->width()+ offset ); + //qDebug("setToFixed %d ", mAgenda->verticalScrollBar()->width()+ offset+2); + //mLayoutDayLabels->addSpacing(mAgenda->verticalScrollBar()->width()+ offset+2); + if ( !appendLabels ) { + dayLabel = mDayLabelsList.next(); + while ( dayLabel ) { + //qDebug("!dayLabel %d",dayLabel ); + dayLabel->hide(); + dayLabel = mDayLabelsList.next(); + } + } + //mDayLabelsFrame->show(); + //mDayLabels->show(); + //qDebug("heigt %d %d %d ",mDayLabelsFrame->height(), mDayLabelsFrame->sizeHint().height(), newHight); + //mDayLabelsFrame->resize( mAgenda->visibleWidth(), newHight ); + mDayLabelsFrame->setFixedHeight( newHight ); +} + +int KOAgendaView::maxDatesHint() +{ + // Not sure about the max number of events, so return 0 for now. + return 0; +} + +int KOAgendaView::currentDateCount() +{ + return mSelectedDates.count(); +} + +QPtrList<Incidence> KOAgendaView::selectedIncidences() +{ + QPtrList<Incidence> selected; + Incidence *incidence; + + incidence = mAgenda->selectedIncidence(); + if (incidence) selected.append(incidence); + + incidence = mAllDayAgenda->selectedIncidence(); + if (incidence) selected.append(incidence); + + return selected; +} + +DateList KOAgendaView::selectedDates() +{ + DateList selected; + QDate qd; + + qd = mAgenda->selectedIncidenceDate(); + if (qd.isValid()) selected.append(qd); + + qd = mAllDayAgenda->selectedIncidenceDate(); + if (qd.isValid()) selected.append(qd); + + return selected; +} + + +void KOAgendaView::updateView() +{ + if ( mBlockUpdating ) + return; + // kdDebug() << "KOAgendaView::updateView()" << endl; + fillAgenda(); + +} + + +/* + Update configuration settings for the agenda view. This method is not + complete. +*/ +void KOAgendaView::updateConfig() +{ + if ( mBlockUpdating ) + return; + // kdDebug() << "KOAgendaView::updateConfig()" << endl; + + // update config for children + mTimeLabels->updateConfig(); + mAgenda->storePosition(); + mAgenda->updateConfig(); + mAllDayAgenda->updateConfig(); + // widget synchronization + //TODO: find a better way, maybe signal/slot + mTimeLabels->positionChanged(); + + // for some reason, this needs to be called explicitly + mTimeLabels->repaint(); + + mDummyAllDayLeft->setFixedWidth(mTimeLabels->width()); + + // ToolTips displaying summary of events + KOAgendaItem::toolTipGroup()->setEnabled(KOPrefs::instance() + ->mEnableToolTips); + + //setHolidayMasks(); + + //createDayLabels(); called by via updateView(); + mEventIndicatorTop->setXOffset(mTimeLabels->width() + mAgenda->frameWidth()); + updateView(); + mAgenda->restorePosition(); +} + + +void KOAgendaView::updateEventDates(KOAgendaItem *item, int type) +{ + // kdDebug() << "KOAgendaView::updateEventDates(): " << item->text() << endl; + //qDebug("KOAgendaView::updateEventDates "); + QDateTime startDt,endDt; + QDate startDate; + int lenInSecs; + // if ( type == KOAgenda::RESIZETOP ) + // qDebug("RESIZETOP "); + // if ( type == KOAgenda::RESIZEBOTTOM ) + // qDebug("RESIZEBOTTOM "); + // if ( type == KOAgenda::MOVE ) + // qDebug("MOVE "); + if ( item->incidence()->type() == "Event" ) { + startDt =item->incidence()->dtStart(); + endDt = item->incidence()->dtEnd(); + lenInSecs = startDt.secsTo( endDt ); + } + + // emit incidenceItemChanged( item->incidence(), KOGlobals::EVENTEDITED ); + + if ( item->incidence()->type()=="Todo" && item->mLastMoveXPos > 0 ) { + startDate = mSelectedDates[item->mLastMoveXPos]; + } else { + if (item->cellX() < 0) { + startDate = (mSelectedDates.first()).addDays(item->cellX()); + } else { + startDate = mSelectedDates[item->cellX()]; + } + } + startDt.setDate(startDate); + + if (item->incidence()->doesFloat()) { + endDt.setDate(startDate.addDays(item->cellWidth() - 1)); + } else { + if ( type == KOAgenda::RESIZETOP || type == KOAgenda::MOVE ) + startDt.setTime(mAgenda->gyToTime(item->cellYTop())); + if ( item->incidence()->type() == "Event" ) { + if ( type == KOAgenda::MOVE ) { + endDt = startDt.addSecs(lenInSecs); + + } else if ( type == KOAgenda::RESIZEBOTTOM ) { + if (item->lastMultiItem()) { + endDt.setTime(mAgenda->gyToTime(item->lastMultiItem()->cellYBottom()+1)); + endDt.setDate(startDate. + addDays(item->lastMultiItem()->cellX() - item->cellX())); + } else { + endDt.setTime(mAgenda->gyToTime(item->cellYBottom()+1)); + endDt.setDate(startDate); + } + } + } else { + // todo + if (item->lastMultiItem()) { + endDt.setTime(mAgenda->gyToTime(item->lastMultiItem()->cellYBottom()+1)); + endDt.setDate(startDate. + addDays(item->lastMultiItem()->cellX() - item->cellX())); + } else { + //qDebug("tem->cellYBottom() %d",item->cellYBottom() ); + if ( item->cellYBottom() > 0 ) + endDt.setTime(mAgenda->gyToTime(item->cellYBottom()+1)); + else + endDt.setTime((static_cast<Todo*>(item->incidence()))->dtDue().time()); + endDt.setDate(startDate); + } + } + } + + + if ( item->incidence()->type() == "Event" ) { + item->incidence()->setDtStart(startDt); + (static_cast<Event*>(item->incidence()))->setDtEnd(endDt); + } else if ( item->incidence()->type() == "Todo" ) { + (static_cast<Todo*>(item->incidence()))->setDtDue(endDt); + } + //qDebug("KOAgendaView::updateEventDates stsart %s end %s ", startDt.toString().latin1(), endDt.toString().latin1() ); + item->incidence()->setRevision(item->incidence()->revision()+1); + item->setItemDate(startDt.date()); + //item->updateItem(); + if ( item->incidence()->type() == "Todo" ) { + emit todoMoved((Todo*)item->incidence(), KOGlobals::EVENTEDITED ); + + } + else + emit incidenceChanged(item->incidence(), KOGlobals::EVENTEDITED); + item->updateItem(); +} + +void KOAgendaView::showDates( const QDate &start, const QDate &end ) +{ + // kdDebug() << "KOAgendaView::selectDates" << endl; + + mSelectedDates.clear(); + // qDebug("KOAgendaView::showDates "); + QDate d = start; + while (d <= end) { + mSelectedDates.append(d); + d = d.addDays( 1 ); + } + + // and update the view + fillAgenda(); +} + + +void KOAgendaView::showEvents(QPtrList<Event>) +{ + kdDebug() << "KOAgendaView::showEvents() is not yet implemented" << endl; +} + +void KOAgendaView::changeEventDisplay(Event *, int) +{ + // qDebug("KOAgendaView::changeEventDisplay "); + // kdDebug() << "KOAgendaView::changeEventDisplay" << endl; + // this should be re-written to be MUCH smarter. Right now we + // are just playing dumb. + fillAgenda(); +} + +void KOAgendaView::fillAgenda(const QDate &) +{ + // qDebug("KOAgendaView::fillAgenda "); + fillAgenda(); +} + +void KOAgendaView::fillAgenda() +{ + if ( globalFlagBlockStartup ) + return; + if ( globalFlagBlockAgenda == 1 ) + return; + //if ( globalFlagBlockAgenda == 2 ) + //globalFlagBlockAgenda = 0; + // globalFlagBlockPainting = false; + if ( globalFlagBlockAgenda == 0 ) + globalFlagBlockAgenda = 1; + // clearView(); + //qDebug("fillAgenda()++++ "); + globalFlagBlockAgendaItemPaint = 1; + mAllDayAgenda->changeColumns(mSelectedDates.count()); + mAgenda->changeColumns(mSelectedDates.count()); + qApp->processEvents(); + mEventIndicatorTop->changeColumns(mSelectedDates.count()); + mEventIndicatorBottom->changeColumns(mSelectedDates.count()); + setHolidayMasks(); + + //mAgenda->hideUnused(); + //mAllDayAgenda->hideUnused(); + + // mAgenda->blockNextRepaint( false ); + // mAgenda->viewport()->repaint(); + // mAgenda->blockNextRepaint( true ); + mMinY.resize(mSelectedDates.count()); + mMaxY.resize(mSelectedDates.count()); + + QPtrList<Event> dayEvents; + + // ToDo items shall be displayed for the day they are due, but only showed today if they are already overdue. + // Therefore, get all of them. + QPtrList<Todo> todos = calendar()->todos(); + + mAgenda->setDateList(mSelectedDates); + + QDate today = QDate::currentDate(); + + DateList::ConstIterator dit; + int curCol = 0; + for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) { + QDate currentDate = *dit; + // kdDebug() << "KOAgendaView::fillAgenda(): " << currentDate.toString() + // << endl; + + dayEvents = calendar()->events(currentDate,true); + + // Default values, which can never be reached + mMinY[curCol] = mAgenda->timeToY(QTime(23,59)) + 1; + mMaxY[curCol] = mAgenda->timeToY(QTime(0,0)) - 1; + + unsigned int numEvent; + for(numEvent=0;numEvent<dayEvents.count();++numEvent) { + Event *event = dayEvents.at(numEvent); + if ( !KOPrefs::instance()->mShowSyncEvents && event->uid().left(21) == QString("last-syncEvent-device") ) + continue; + // kdDebug() << " Event: " << event->summary() << endl; + + int beginX = currentDate.daysTo(event->dtStart().date()) + curCol; + int endX = currentDate.daysTo(event->dtEnd().date()) + curCol; + + // kdDebug() << " beginX: " << beginX << " endX: " << endX << endl; + + if (event->doesFloat()) { + if (event->recurrence()->doesRecur()) { + mAllDayAgenda->insertAllDayItem(event,currentDate,curCol,curCol); + } else { + if (beginX <= 0 && curCol == 0) { + mAllDayAgenda->insertAllDayItem(event,currentDate,beginX,endX); + } else if (beginX == curCol) { + mAllDayAgenda->insertAllDayItem(event,currentDate,beginX,endX); + } + } + } else if (event->isMultiDay()) { + if ( event->doesRecur () ) { + QDate dateit = currentDate; + int count = 0; + int max = event->dtStart().daysTo( event->dtEnd() ) +2; + while (! event->recursOn( dateit ) && count <= max ) { + ++count; + dateit = dateit.addDays( -1 ); + } + bool ok; + QDateTime nextOcstart = event->getNextOccurence( QDateTime(dateit) ,&ok ); + if ( ok ) + { + int secs = event->dtStart().secsTo( event->dtEnd() ); + QDateTime nextOcend =nextOcstart.addSecs( secs ); ; + beginX = currentDate.daysTo(nextOcstart.date()) + curCol; + endX = currentDate.daysTo(nextOcend.date()) + curCol; + + } + } + int startY = mAgenda->timeToY(event->dtStart().time()); + int endY = mAgenda->timeToY(event->dtEnd().time()) - 1; + //qDebug("insert %d %d %d %d %d ",beginX,endX,startY,endY , curCol ); + if ((beginX <= 0 && curCol == 0) || beginX == curCol) { + //qDebug("insert!!! "); + mAgenda->insertMultiItem(event,currentDate,beginX,endX,startY,endY); + } + if (beginX == curCol) { + mMaxY[curCol] = mAgenda->timeToY(QTime(23,59)); + if (startY < mMinY[curCol]) mMinY[curCol] = startY; + } else if (endX == curCol) { + mMinY[curCol] = mAgenda->timeToY(QTime(0,0)); + if (endY > mMaxY[curCol]) mMaxY[curCol] = endY; + } else { + mMinY[curCol] = mAgenda->timeToY(QTime(0,0)); + mMaxY[curCol] = mAgenda->timeToY(QTime(23,59)); + } + } else { + int startY = mAgenda->timeToY(event->dtStart().time()); + int endY = mAgenda->timeToY(event->dtEnd().time()) - 1; + if (endY < startY) endY = startY; + mAgenda->insertItem(event,currentDate,curCol,startY,endY); + if (startY < mMinY[curCol]) mMinY[curCol] = startY; + if (endY > mMaxY[curCol]) mMaxY[curCol] = endY; + } + } + // ---------- [display Todos -------------- + unsigned int numTodo; + for (numTodo = 0; numTodo < todos.count(); ++numTodo) { + Todo *todo = todos.at(numTodo); + + if ( ! todo->hasDueDate() ) continue; // todo shall not be displayed if it has no date + + // ToDo items shall be displayed for the day they are due, but only showed today if they are already overdue. + // Already completed items can be displayed on their original due date + //if not KOPrefs::instance()->mShowTodoInAgenda, show overdue in agenda + bool overdue = (!todo->isCompleted()) && (todo->dtDue() < today) && KOPrefs::instance()->mShowTodoInAgenda; + + if ( ((todo->dtDue().date() == currentDate) && !overdue) || + ((currentDate == today) && overdue) ) { + if ( todo->doesFloat() || overdue ) { // Todo has no due-time set or is already overdue + if ( KOPrefs::instance()->mShowTodoInAgenda ) + mAllDayAgenda->insertAllDayItem(todo, currentDate, curCol, curCol); + } + else { + + int endY = mAgenda->timeToY(todo->dtDue().time()) - 1; + int hi = (18/KOPrefs::instance()->mHourSize); + //qDebug("hei %d ",KOPrefs::instance()->mHourSize); + int startY = endY -hi; + + mAgenda->insertItem(todo,currentDate,curCol,startY,endY); + + if (startY < mMinY[curCol]) mMinY[curCol] = startY; + if (endY > mMaxY[curCol]) mMaxY[curCol] = endY; + } + } + } + // ---------- display Todos] -------------- + + ++curCol; + } + mAgenda->hideUnused(); + mAllDayAgenda->hideUnused(); + mAgenda->checkScrollBoundaries(); + + deleteSelectedDateTime(); + + createDayLabels(); + emit incidenceSelected( 0 ); + + if ( globalFlagBlockAgenda == 2 ) { + if ( KOPrefs::instance()->mSetTimeToDayStartAt ) + setStartHour( KOPrefs::instance()->mDayBegins ); + else if ( KOPrefs::instance()->mCenterOnCurrentTime ) + setStartHour( QTime::currentTime ().hour() ); + // qApp->processEvents(); + } + qApp->processEvents(); + //qDebug("qApp->processEvents(); END "); + globalFlagBlockAgenda = 0; + + // mAgenda->hideUnused(); + //mAllDayAgenda->hideUnused(); + mAllDayAgenda->drawContentsToPainter(); + mAgenda->drawContentsToPainter(); + repaintAgenda(); + // mAgenda->finishUpdate(); + //mAllDayAgenda->finishUpdate(); + + // repaintAgenda(); + //qApp->processEvents(); + // globalFlagBlockAgenda = 0; +} +void KOAgendaView::repaintAgenda() +{ + // mAllDayAgenda->drawContentsToPainter(); +// mAllDayAgenda->viewport()->repaint( false ); +// mAgenda->drawContentsToPainter(); +// mAgenda->viewport()->repaint( false ); +// qApp->processEvents(); + + //qDebug("KOAgendaView::repaintAgenda() "); + //qApp->processEvents(); + mAgenda->viewport()->repaint( false ); + mAllDayAgenda->viewport()->repaint( false ); + mAgenda->finishUpdate(); + mAllDayAgenda->finishUpdate(); +} + + +void KOAgendaView::clearView() +{ + // kdDebug() << "ClearView" << endl; + mAllDayAgenda->clear(); + mAgenda->clear(); +} + +void KOAgendaView::printPreview(CalPrinter *calPrinter, const QDate &fd, + const QDate &td) +{ +#ifndef KORG_NOPRINTER + if (fd == td) + calPrinter->preview(CalPrinter::Day, fd, td); + else + calPrinter->preview(CalPrinter::Week, fd, td); +#endif +} + +// void KOAgendaView::updateMovedTodo() +// { +// // updateConfig(); +// // emit updateTodoViews(); +// } + +void KOAgendaView::newEvent(int gx, int gy) +{ + if (!mSelectedDates.count()) return; + + QDate day = mSelectedDates[gx]; + + QTime time = mAgenda->gyToTime(gy); + QDateTime dt(day,time); + // if ( dt < QDateTime::currentDateTime () ) + // dt = QDateTime::currentDateTime ().addSecs( 3600 ); + emit newEventSignal(dt); +} + +void KOAgendaView::newEvent(int gxStart, int gyStart, int gxEnd, int gyEnd) +{ + if (!mSelectedDates.count()) return; + + QDate dayStart = mSelectedDates[gxStart]; + QDate dayEnd = mSelectedDates[gxEnd]; + + QTime timeStart = mAgenda->gyToTime(gyStart); + QTime timeEnd = mAgenda->gyToTime( gyEnd + 1 ); + + QDateTime dtStart(dayStart,timeStart); + QDateTime dtEnd(dayEnd,timeEnd); + + emit newEventSignal(dtStart,dtEnd); +} + +void KOAgendaView::newEventAllDay(int gx, int ) +{ + if (!mSelectedDates.count()) return; + + QDate day = mSelectedDates[gx]; + + emit newEventSignal(day); +} + +void KOAgendaView::updateEventIndicatorTop(int newY) +{ + uint i; + for(i=0;i<mMinY.size();++i) { + if (newY >= mMinY.at(i)) mEventIndicatorTop->enableColumn(i,true); + else mEventIndicatorTop->enableColumn(i,false); + } + + mEventIndicatorTop->update(); +} + +void KOAgendaView::updateEventIndicatorBottom(int newY) +{ + uint i; + for(i=0;i<mMaxY.size();++i) { + if (newY <= mMaxY.at(i)) mEventIndicatorBottom->enableColumn(i,true); + else mEventIndicatorBottom->enableColumn(i,false); + } + + mEventIndicatorBottom->update(); +} + +void KOAgendaView::startDrag(Event *event) +{ +#ifndef KORG_NODND + DndFactory factory( calendar() ); + ICalDrag *vd = factory.createDrag(event,this); + if (vd->drag()) { + kdDebug() << "KOAgendaView::startDrag(): Delete drag source" << endl; + } +#endif +} + +void KOAgendaView::readSettings() +{ + readSettings(KOGlobals::config()); +} + +void KOAgendaView::readSettings(KConfig *config) +{ + // kdDebug() << "KOAgendaView::readSettings()" << endl; + + config->setGroup("Views"); + + //#ifndef KORG_NOSPLITTER + QValueList<int> sizes = config->readIntListEntry("Separator AgendaView"); + if (sizes.count() == 2) { + if ( sizes[0] < 20 ) { + sizes[1] = sizes[1] +20 - sizes[0]; + sizes[0] = 20; + } + mSplitterAgenda->setSizes(sizes); + // qDebug("read %d %d ",sizes[0],sizes[1] ); + } + //#endif + + // updateConfig(); +} + +void KOAgendaView::writeSettings(KConfig *config) +{ + // kdDebug() << "KOAgendaView::writeSettings()" << endl; + + config->setGroup("Views"); + + //#ifndef KORG_NOSPLITTER + QValueList<int> list = mSplitterAgenda->sizes(); + config->writeEntry("Separator AgendaView",list); + //qDebug("write %d %d ", list[0],list[1] ); + //#endif +} + +void KOAgendaView::setHolidayMasks() +{ + mHolidayMask.resize(mSelectedDates.count()); + + uint i; + for(i=0;i<mSelectedDates.count();++i) { + QDate date = mSelectedDates[i]; + bool showSaturday = KOPrefs::instance()->mExcludeSaturdays && (date.dayOfWeek() == 6); + bool showSunday = KOPrefs::instance()->mExcludeHolidays && (date.dayOfWeek() == 7); +#ifndef KORG_NOPLUGINS + bool showHoliday = KOPrefs::instance()->mExcludeHolidays && + !KOCore::self()->holiday(date).isEmpty(); + bool showDay = showSaturday || showSunday || showHoliday; +#else + bool showDay = showSaturday || showSunday; +#endif + if (showDay) { + mHolidayMask.at(i) = true; + } else { + mHolidayMask.at(i) = false; + } + } + + mAgenda->setHolidayMask(&mHolidayMask); + mAllDayAgenda->setHolidayMask(&mHolidayMask); +} + +void KOAgendaView::setContentsPos(int y) +{ + mAgenda->setContentsPos(0,y); +} + +void KOAgendaView::setExpandedButton( bool expanded ) +{ + if ( expanded ) { + mExpandButton->setPixmap( mExpandedPixmap ); + } else { + mExpandButton->setPixmap( mNotExpandedPixmap ); + } +} + +void KOAgendaView::clearSelection() +{ + mAgenda->deselectItem(); + mAllDayAgenda->deselectItem(); +} + +void KOAgendaView::newTimeSpanSelectedAllDay(int gxStart, int gyStart, + int gxEnd, int gyEnd) +{ + mTimeSpanInAllDay = true; + newTimeSpanSelected(gxStart,gyStart,gxEnd,gyEnd); +} + + + + +void KOAgendaView::newTimeSpanSelected(int gxStart, int gyStart, + int gxEnd, int gyEnd) +{ + if (!mSelectedDates.count()) return; + + QDate dayStart = mSelectedDates[gxStart]; + QDate dayEnd = mSelectedDates[gxEnd]; + + QTime timeStart = mAgenda->gyToTime(gyStart); + QTime timeEnd = mAgenda->gyToTime( gyEnd + 1 ); + + QDateTime dtStart(dayStart,timeStart); + QDateTime dtEnd(dayEnd,timeEnd); + + mTimeSpanBegin = dtStart; + mTimeSpanEnd = dtEnd; + +} + +void KOAgendaView::deleteSelectedDateTime() +{ + mTimeSpanBegin.setDate(QDate()); + mTimeSpanEnd.setDate(QDate()); + mTimeSpanInAllDay = false; +} + +void KOAgendaView::keyPressEvent ( QKeyEvent * e ) +{ + e->ignore(); +} + +void KOAgendaView::scrollOneHourUp() +{ + + mAgenda->scrollBy ( 0, -mAgenda->contentsHeight () / 24 ); +} +void KOAgendaView::scrollOneHourDown() +{ + mAgenda->scrollBy ( 0, mAgenda->contentsHeight () / 24 ); +} + +void KOAgendaView::setStartHour( int h ) +{ + mAgenda->setStartHour( h ); + +} + +void KOAgendaView::updateTodo( Todo * t, int ) +{ + + bool remove = false; + bool removeAD = false; + if ( ! t->hasDueDate() ) { + remove = true; + removeAD = true; + } + else { + bool overdue = (!t->isCompleted()) && (t->dtDue() < QDate::currentDate()) && KOPrefs::instance()->mShowTodoInAgenda ; + if ( overdue && + QDate::currentDate() >= mSelectedDates.first() && + QDate::currentDate() <= mSelectedDates.last()) { + removeAD = false; + remove = true; + } + else { + if ( t->dtDue().date() < mSelectedDates.first() || + t->dtDue().date() > mSelectedDates.last() ) { + remove = true; + removeAD = true; + } else { + remove = t->doesFloat(); + removeAD = !remove; + } + } + } + int days = mSelectedDates.first().daysTo( t->dtDue().date() ); + // qDebug("daysto %d ", days ); + mAgenda->updateTodo( t , days, remove); + if ( KOPrefs::instance()->mShowTodoInAgenda ) + mAllDayAgenda->updateTodo( t , days, removeAD); + //qDebug("KOAgendaView::updateTodo( Todo *, int ) "); + +} diff --git a/korganizer/koagendaview.h b/korganizer/koagendaview.h new file mode 100644 index 0000000..0079253 --- a/dev/null +++ b/korganizer/koagendaview.h @@ -0,0 +1,252 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ +#ifndef KOAGENDAVIEW_H +#define KOAGENDAVIEW_H + +#include <qscrollview.h> +#include <qdatetime.h> +#include <qlayout.h> +#ifndef DESKTOP_VERSION +#include <qksplitter.h> +#else +#include <qsplitter.h> +#endif +#include <qmemarray.h> + +#include "koeventview.h" + + +class QHBox; +class QFrame; +class QLabel; +class QPushButton; +class CalendarView; +class KOAgenda; +class KOAgendaItem; +class KConfig; +class KDGanttMinimizeSplitter; +class TimeLabels : public QScrollView { + Q_OBJECT + public: + TimeLabels(int rows,QWidget *parent=0,const char *name=0,WFlags f=0); + + void setCellHeight(int height); + + /** Calculates the minimum width */ + virtual int minimumWidth() const; + + /** updates widget's internal state */ + void updateConfig(); + + /** */ + void setAgenda(KOAgenda* agenda); + + /** */ + virtual void paintEvent(QPaintEvent* e); + + public slots: + /** update time label positions */ + void positionChanged(); + + protected: + void drawContents(QPainter *p,int cx, int cy, int cw, int ch); + + private: + int mRows; + int mCellHeight; + + /** */ + KOAgenda* mAgenda; +}; + +class EventIndicator : public QFrame { + Q_OBJECT + public: + enum Location { Top, Bottom }; + EventIndicator(Location loc=Top,QWidget *parent=0,const char *name=0); + virtual ~EventIndicator(); + + void changeColumns(int columns); + void setPaintWidget( KDGanttMinimizeSplitter* ); + void setXOffset( int ); + void enableColumn(int column, bool enable); + + protected: + void drawContents(QPainter *); + + private: + int mXOffset; + KDGanttMinimizeSplitter* mPaintWidget; + int mColumns; + QHBox *mTopBox; + QBoxLayout *mTopLayout; + Location mLocation; + QPixmap mPixmap; + QMemArray<bool> mEnabled; +}; + +/** + KOAgendaView is the agenda-like view used to display events in an one or + multi-day view. +*/ +class KOAgendaView : public KOEventView { + Q_OBJECT + public: + KOAgendaView(Calendar *cal,QWidget *parent = 0,const char *name = 0 ); + virtual ~KOAgendaView(); + void setStartHour( int ); + void toggleAllDay(); + + + /** Returns maximum number of days supported by the koagendaview */ + virtual int maxDatesHint(); + + /** Returns number of currently shown dates. */ + virtual int currentDateCount(); + + /** returns the currently selected events */ + virtual QPtrList<Incidence> selectedIncidences(); + + /** returns the currently selected events */ + virtual DateList selectedDates(); + + /** Remove all events from view */ + void clearView(); + KOAgenda *agenda() { return mAgenda;} + virtual void printPreview(CalPrinter *calPrinter, + const QDate &, const QDate &); + + /** start-datetime of selection */ + QDateTime selectionStart() {return mTimeSpanBegin;} + /** end-datetime of selection */ + QDateTime selectionEnd() {return mTimeSpanEnd;} + /** returns true if selection is for whole day */ + bool selectedIsAllDay() {return mTimeSpanInAllDay;} + /** make selected start/end invalid */ + void deleteSelectedDateTime(); + void repaintAgenda(); + public slots: + virtual void updateView(); + virtual void updateConfig(); + virtual void showDates(const QDate &start, const QDate &end); + virtual void showEvents(QPtrList<Event> eventList); + + void updateTodo( Todo *, int ); + void changeEventDisplay(Event *, int); + + void clearSelection(); + + void newEvent(int gx,int gy); + void newEvent(int gxStart, int gyStart, int gxEnd, int gyEnd); + void newEventAllDay(int gx, int gy); + + void startDrag(Event *); + + void readSettings(); + void readSettings(KConfig *); + void writeSettings(KConfig *); + + void setContentsPos(int y); + + void setExpandedButton( bool expanded ); + void scrollOneHourUp(); + void scrollOneHourDown(); + void addToCalSlot(Incidence *, Incidence *); + + signals: + void toggleExpand(); + void todoMoved( Todo *, int ); + void incidenceChanged(Incidence * , int ); + // void cloneIncidenceSignal(Incidence *); + + protected: + bool mBlockUpdating; + int mUpcomingWidth; + /** Fill agenda beginning with date startDate */ + void fillAgenda(const QDate &startDate); + void resizeEvent( QResizeEvent* e ); + /** Fill agenda using the current set value for the start date */ + void fillAgenda(); + + /** Create labels for the selected dates. */ + void createDayLabels(); + + /** + Set the masks on the agenda widgets indicating, which days are holidays. + */ + void setHolidayMasks(); + + protected slots: + /** Update event belonging to agenda item */ + void updateEventDates(KOAgendaItem *item, int mode = -1); + //void updateMovedTodo(); + + void updateEventIndicatorTop(int newY); + void updateEventIndicatorBottom(int newY); + + /** Updates data for selected timespan */ + void newTimeSpanSelected(int gxStart, int gyStart, int gxEnd, int gyEnd); + /** Updates data for selected timespan for all day event*/ + void newTimeSpanSelectedAllDay(int gxStart, int gyStart, int gxEnd, int gyEnd); + + private: + // view widgets + QFrame *mDayLabels; + QHBox *mDayLabelsFrame; + QBoxLayout *mLayoutDayLabels; + QFrame *mAllDayFrame; + KOAgenda *mAllDayAgenda; + KOAgenda *mAgenda; + TimeLabels *mTimeLabels; + QWidget *mDummyAllDayLeft; + + KDGanttMinimizeSplitter* mSplitterAgenda; + QPushButton *mExpandButton; + + DateList mSelectedDates; // List of dates to be displayed + int mViewType; + + bool mWeekStartsMonday; + int mStartHour; + + KOEventPopupMenu *mAgendaPopup; + KOEventPopupMenu *mAllDayAgendaPopup; + + EventIndicator *mEventIndicatorTop; + EventIndicator *mEventIndicatorBottom; + + QMemArray<int> mMinY; + QMemArray<int> mMaxY; + + QMemArray<bool> mHolidayMask; + + QPixmap mExpandedPixmap; + QPixmap mNotExpandedPixmap; + QPtrList<QLabel> mDayLabelsList; + QDateTime mTimeSpanBegin; + QDateTime mTimeSpanEnd; + bool mTimeSpanInAllDay; + void keyPressEvent ( QKeyEvent * e ); +}; + +#endif // KOAGENDAVIEW_H diff --git a/korganizer/koagendaview.moc b/korganizer/koagendaview.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/koagendaview.moc diff --git a/korganizer/kocounterdialog.cpp b/korganizer/kocounterdialog.cpp new file mode 100644 index 0000000..8a9ae44 --- a/dev/null +++ b/korganizer/kocounterdialog.cpp @@ -0,0 +1,66 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +#include <klocale.h> + +#include <libkcal/event.h> +#include "koeventviewer.h" + +#include "kocounterdialog.h" +#include "kocounterdialog.moc" + +KOCounterDialog::KOCounterDialog(QWidget *parent,const char *name) + : KDialogBase(parent,name,false,i18n("Counter-event Viewer"),User1|User2,User1, + false,i18n("Decline"),i18n("Accept")) +{ + mEventViewer = new KOEventViewer(this); + setMainWidget(mEventViewer); + + connect(this,SIGNAL(user1Clicked()),this,SLOT(slotCancel())); + connect(this,SIGNAL(user2Clicked()),this,SLOT(slotOk())); + + // TODO: Set a sensible size (based on the content?). + setMinimumSize(300,200); + resize(320,300); +} + +KOCounterDialog::~KOCounterDialog() +{ +} + +void KOCounterDialog::setEvent(Event *event) +{ + mEventViewer->setEvent(event); +} + +void KOCounterDialog::addEvent(Event *event) +{ + mEventViewer->addEvent(event); +} + +void KOCounterDialog::setTodo(Todo *event) +{ + mEventViewer->setTodo(event); +} + +void KOCounterDialog::addText(QString text) +{ + mEventViewer->addText(text); +} diff --git a/korganizer/kocounterdialog.h b/korganizer/kocounterdialog.h new file mode 100644 index 0000000..c8dcf45 --- a/dev/null +++ b/korganizer/kocounterdialog.h @@ -0,0 +1,50 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000, 2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef KOCOUNTERDIALOG_H +#define KOCOUNTERDIALOG_H +// +// Viewer dialog for counter events. +// + +#include <qtextview.h> + +#include <kdialogbase.h> + +#include <libkcal/event.h> + +using namespace KCal; + +class KOEventViewer; + +class KOCounterDialog : public KDialogBase { + Q_OBJECT + public: + KOCounterDialog(QWidget *parent=0,const char *name=0); + virtual ~KOCounterDialog(); + + void setEvent(Event *event); + void addEvent(Event *event); + void setTodo(Todo *event); + void addText(QString text); + + private: + KOEventViewer *mEventViewer; +}; + +#endif diff --git a/korganizer/kocounterdialog.moc b/korganizer/kocounterdialog.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/kocounterdialog.moc diff --git a/korganizer/kodaymatrix.cpp b/korganizer/kodaymatrix.cpp new file mode 100644 index 0000000..779d67c --- a/dev/null +++ b/korganizer/kodaymatrix.cpp @@ -0,0 +1,597 @@ +/* + 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 + + 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. +*/ + +#include <qevent.h> +#include <qpainter.h> +#include <qptrlist.h> + +#include <kglobal.h> +#include <kdebug.h> +#include <klocale.h> + +#include <libkcal/vcaldrag.h> +#include <libkcal/icaldrag.h> +#include <libkcal/dndfactory.h> +#include <libkcal/calendarresources.h> +#include <libkcal/resourcecalendar.h> +#include <kresources/resourceselectdialog.h> + +#include <kcalendarsystem.h> + +#ifndef KORG_NOPLUGINS +#include "kocore.h" +#endif +#include "koprefs.h" +#include "koglobals.h" + +#include "kodaymatrix.h" +#include "kodaymatrix.moc" + +// ============================================================================ +// D Y N A M I C T I P +// ============================================================================ + +DynamicTip::DynamicTip( QWidget * parent ) + : QToolTip( parent ) +{ + matrix = (KODayMatrix*)parent; +} + + +void DynamicTip::maybeTip( const QPoint &pos ) +{ + //calculate which cell of the matrix the mouse is in + QRect sz = matrix->frameRect(); + int dheight = sz.height()*7 / 42; + int dwidth = sz.width() / 7; + int row = pos.y()/dheight; + int col = pos.x()/dwidth; + + QRect rct(col*dwidth, row*dheight, dwidth, dheight); + +// kdDebug() << "DynamicTip::maybeTip matrix cell index [" << +// col << "][" << row << "] => " <<(col+row*7) << endl; + + //show holiday names only + QString str = matrix->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(QWidget *parent, Calendar* calendar, QDate date, const char *name) : + QFrame(parent, name) +{ + mCalendar = calendar; + + // initialize dynamic arrays + days = new QDate[NUMDAYS]; + daylbls = new QString[NUMDAYS]; + events = new int[NUMDAYS]; + mToolTip = new DynamicTip(this); + + // set default values used for drawing the matrix + mDefaultBackColor = palette().active().base(); + mDefaultTextColor = palette().active().foreground(); + mDefaultTextColorShaded = getShadedColor(mDefaultTextColor); + mHolidayColorShaded = getShadedColor(KOPrefs::instance()->mHolidayColor); + mSelectedDaysColor = QColor("white"); + mTodayMarginWidth = 2; + mSelEnd = mSelStart = NOSELECTION; + + setAcceptDrops(true); + //setFont( QFont("Arial", 10) ); + updateView(date); +} + +QColor KODayMatrix::getShadedColor(QColor color) +{ + QColor 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() +{ + delete [] days; + delete [] daylbls; + delete [] events; + delete mToolTip; +} + +/* +void KODayMatrix::setStartDate(QDate start) +{ + updateView(start); +} +*/ + +void KODayMatrix::addSelectedDaysTo(DateList& selDays) +{ + kdDebug() << "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(days[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(days[i]); + } + for (int i = NUMDAYS; i < mSelEnd; i++) { + selDays.append(days[0].addDays(i)); + } + + // apply normal routine to selection being entirely within matrix limits + } else { + for (int i = i0; i <= mSelEnd; i++) { + selDays.append(days[i]); + } + } +} + +void KODayMatrix::setSelectedDaysFrom(const QDate& start, const QDate& end) +{ + mSelStart = startdate.daysTo(start); + mSelEnd = startdate.daysTo(end); +} + + +void KODayMatrix::recalculateToday() +{ + today = -1; + for (int i=0; i<NUMDAYS; i++) { + days[i] = startdate.addDays(i); + daylbls[i] = QString::number( KOGlobals::self()->calendarSystem()->day( days[i] )); + + // if today is in the currently displayed month, hilight today + if (days[i].year() == QDate::currentDate().year() && + days[i].month() == QDate::currentDate().month() && + days[i].day() == QDate::currentDate().day()) { + today = i; + } + } + // qDebug(QString("Today is visible at %1.").arg(today)); +} + +void KODayMatrix::updateView() +{ + updateView(startdate); +} + +void KODayMatrix::updateView(QDate actdate) +{ + +// kdDebug() << "KODayMatrix::updateView() " << actdate.toString() << endl; + + //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 != startdate) { + // reset index of selection according to shift of starting date from startdate to actdate + if (mSelStart != NOSELECTION) { + int tmp = actdate.daysTo(startdate); + //kdDebug() << "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; + } + } + + startdate = actdate; + daychanged = true; + } + + if (daychanged) { + recalculateToday(); + } + + for(int i = 0; i < NUMDAYS; i++) { + + // if events are set for the day then remember to draw it bold + QPtrList<Event> eventlist = mCalendar->events(days[i]); + Event *event; + int numEvents = eventlist.count(); + + for(event=eventlist.first();event != 0;event=eventlist.next()) { + ushort recurType = event->recurrence()->doesRecur(); + + if ((recurType == Recurrence::rDaily && !KOPrefs::instance()->mDailyRecur) || + (recurType == Recurrence::rWeekly && !KOPrefs::instance()->mWeeklyRecur)) { + numEvents--; + } + } + events[i] = numEvents; + + //if it is a holy day then draw it red. Sundays are consider holidays, too +#ifndef KORG_NOPLUGINS + QString holiStr = KOCore::self()->holiday(days[i]); +#else + QString holiStr = QString::null; +#endif + if ( (KOGlobals::self()->calendarSystem()->dayOfWeek(days[i]) == KOGlobals::self()->calendarSystem()->weekDayOfPray()) || + !holiStr.isEmpty()) { + if (holiStr.isNull()) holiStr = ""; + mHolidays[i] = holiStr; + + } else { + mHolidays[i] = QString::null; + } + } +} + +const QDate& KODayMatrix::getDate(int offset) +{ + if (offset < 0 || offset > NUMDAYS-1) { + kdDebug() << "Wrong offset (" << offset << ") in KODayMatrix::getDate(int)" << endl; + return days[0]; + } + return days[offset]; +} + +QString KODayMatrix::getHolidayLabel(int offset) +{ + if (offset < 0 || offset > NUMDAYS-1) { + kdDebug() << "Wrong offset (" << offset << ") in KODayMatrix::getHolidayLabel(int)" << endl; + return 0; + } + return mHolidays[offset]; +} + +int KODayMatrix::getDayIndexFrom(int x, int y) +{ + return 7*(y/daysize.height()) + (KOGlobals::self()->reverseLayout() ? + 6 - x/daysize.width() : x/daysize.width()); +} + +// ---------------------------------------------------------------------------- +// M O U S E E V E N T H A N D L I N G +// ---------------------------------------------------------------------------- + +void KODayMatrix::mousePressEvent (QMouseEvent* e) +{ + mSelStart = getDayIndexFrom(e->x(), e->y()); + if (mSelStart > NUMDAYS-1) mSelStart=NUMDAYS-1; + mSelInit = mSelStart; +} + +void KODayMatrix::mouseReleaseEvent (QMouseEvent* 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(days[i]); + } + emit selected((const DateList)daylist); + +} + +void KODayMatrix::mouseMoveEvent (QMouseEvent* 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 +// ---------------------------------------------------------------------------- + +void KODayMatrix::dragEnterEvent(QDragEnterEvent *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(QDragMoveEvent *e) +{ +#ifndef KORG_NODND + if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) { + e->ignore(); + return; + } + + e->accept(); +#endif +} + +void KODayMatrix::dragLeaveEvent(QDragLeaveEvent */*dl*/) +{ +#ifndef KORG_NODND +// setPalette(oldPalette); +// update(); +#endif +} + +void KODayMatrix::dropEvent(QDropEvent *e) +{ +#ifndef KORG_NODND +// kdDebug() << "KODayMatrix::dropEvent(e) begin" << endl; + + if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) { + e->ignore(); + return; + } + + DndFactory factory( mCalendar ); + Event *event = factory.createDrop(e); + + if (event) { + e->acceptAction(); + + Event *existingEvent = mCalendar->event(event->uid()); + + if(existingEvent) { + // uniquify event + event->recreate(); +/* + KMessageBox::sorry(this, + i18n("Event already exists in this calendar."), + i18n("Drop Event")); + delete event; + return; +*/ + } +// kdDebug() << "Drop new Event" << endl; + // Adjust date + QDateTime start = event->dtStart(); + QDateTime end = event->dtEnd(); + int duration = start.daysTo(end); + int idx = getDayIndexFrom(e->pos().x(), e->pos().y()); + + start.setDate(days[idx]); + end.setDate(days[idx].addDays(duration)); + + event->setDtStart(start); + event->setDtEnd(end); + mCalendar->addEvent(event); + + emit eventDropped(event); + } else { +// kdDebug() << "KODayMatrix::dropEvent(): Event from drop not decodable" << endl; + e->ignore(); + } +#endif +} + +// ---------------------------------------------------------------------------- +// P A I N T E V E N T H A N D L I N G +// ---------------------------------------------------------------------------- + +void KODayMatrix::paintEvent(QPaintEvent * pevent) +{ +//kdDebug() << "KODayMatrix::paintEvent() BEGIN" << endl; + + QPainter p(this); + + QRect sz = frameRect(); + int dheight = daysize.height(); + int dwidth = daysize.width(); + int row,col; + int selw, selh; + bool isRTL = KOGlobals::self()->reverseLayout(); + + // draw background and topleft frame + p.fillRect(pevent->rect(), mDefaultBackColor); + p.setPen(mDefaultTextColor); + p.drawRect(0, 0, sz.width()+1, sz.height()+1); + + // draw selected days with highlighted background color + if (mSelStart != NOSELECTION) { + + row = mSelStart/7; + col = mSelStart -row*7; + QColor selcol = KOPrefs::instance()->mHighlightColor; + + 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 > 1) { + p.fillRect(0, (row+1)*dheight, 7*dwidth, (selh-1)*dheight,selcol); + } + // draw last block from left to mSelEnd + 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 + QColor actcol = mDefaultTextColorShaded; + p.setPen(actcol); + QPen 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( days[i] ) == 1) { + if (actcol == mDefaultTextColorShaded) { + actcol = mDefaultTextColor; + } else { + actcol = mDefaultTextColorShaded; + } + p.setPen(actcol); + } + + //Reset pen color after selected days block + if (i == mSelEnd+1) { + p.setPen(actcol); + } + + // if today then draw rectangle around day + if (today == i) { + tmppen = p.pen(); + QPen mTodayPen(p.pen()); + + mTodayPen.setWidth(mTodayMarginWidth); + //draw red rectangle for holidays + if (!mHolidays[i].isNull()) { + if (actcol == mDefaultTextColor) { + mTodayPen.setColor(KOPrefs::instance()->mHolidayColor); + } else { + mTodayPen.setColor(mHolidayColorShaded); + } + } + //draw gray rectangle for today if in selection + if (i >= mSelStart && i <= mSelEnd) { + QColor 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 (events[i] > 0) { + QFont myFont = font(); + myFont.setBold(true); + p.setFont(myFont); + } + + // if it is a holiday then use the default holiday color + if (!mHolidays[i].isNull()) { + if (actcol == mDefaultTextColor) { + p.setPen(KOPrefs::instance()->mHolidayColor); + } else { + p.setPen(mHolidayColorShaded); + } + } + + // draw selected days with special color + // DO NOT specially highlight holidays in selection ! + if (i >= mSelStart && i <= mSelEnd) { + p.setPen(mSelectedDaysColor); + } + + p.drawText(col*dwidth, row*dheight, dwidth, dheight, + Qt::AlignHCenter | Qt::AlignVCenter, daylbls[i]); + + // reset color to actual color + if (!mHolidays[i].isNull()) { + p.setPen(actcol); + } + // reset bold font to plain font + if (events[i] > 0) { + QFont myFont = font(); + myFont.setBold(false); + p.setFont(myFont); + } + } +} + +// ---------------------------------------------------------------------------- +// R E SI Z E E V E N T H A N D L I N G +// ---------------------------------------------------------------------------- + +void KODayMatrix::resizeEvent(QResizeEvent *) +{ + QRect sz = frameRect(); + daysize.setHeight(sz.height()*7 / NUMDAYS); + daysize.setWidth(sz.width() / 7); +} diff --git a/korganizer/kodaymatrix.h b/korganizer/kodaymatrix.h new file mode 100644 index 0000000..b4eb2a8 --- a/dev/null +++ b/korganizer/kodaymatrix.h @@ -0,0 +1,308 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2001 Eitzenberger Thomas <thomas.eitzenberger@siemens.at> + + 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 _KODAYMAT_H +#define _KODAYMAT_H + +#include <libkcal/calendar.h> + +#include <qstring.h> +#include <qframe.h> +#include <qcolor.h> +#include <qpen.h> +#include <qdatetime.h> +#include <qtooltip.h> + +#include <qmap.h> + +class QDragEnterEvent; +class QDragMoveEvent; +class QDragLeaveEvent; +class QDropEvent; + +class KODayMatrix; + +using namespace KCal; + + +/** + * small helper class to dynamically show tooltips inside the day matrix. + * This class asks the day matrix object for a appropriate label which + * is in our special case the name of the holiday or null if this day is no holiday. + */ +class DynamicTip : public QToolTip +{ +public: + + /** + * Constructor that expects a KODayMatrix object as parent. + * + * @param parent the parent KODayMatrix control. + */ + DynamicTip(QWidget* parent ); + +protected: + + /** + * Qt's callback to ask the object to provide an approrpiate text for the + * tooltip to be shown. + * + * @param pos coordinates of the mouse. + */ + void maybeTip( const QPoint & pos); + +private: + + /** the parent control this tooltip is designed for. */ + KODayMatrix* matrix; +}; + +/** + * replacement for kdpdatebuton.cpp that used 42 widgets for the day matrix to be displayed. + * Cornelius thought this was a waste of memory and a lot of overhead. + * In addition the selection was not very intuitive so I decided to rewrite it using a QFrame + * that draws the labels and allows for dragging selection while maintaining nearly full + * compatibility in behaviour with its predecessor. + * + * The following functionality has been changed: + * + * o when shifting events in the agenda view from one day to another the day matrix is updated now + * o TODO ET dragging an event to the matrix will MOVE not COPY the event to the new date. + * o no support for Ctrl+click to create groups of dates + * (This has not really been supported in the predecessor. It was not very intuitive nor was it + * user friendly.) + * This feature has been replaced with dragging a selection on the matrix. The matrix will + * automatically choose the appropriate selection (e.g. you are not any longer able to select + * two distinct groups of date selections as in the old class) + * o now that you can select more then a week it can happen that not all selected days are + * displayed in the matrix. However this is preferred to the alternative which would mean to + * adjust the selection and leave some days undisplayed while scrolling through the months + * + * @short day matrix widget of the KDateNavigator + * + * @author Eitzenberger Thomas + */ +class KODayMatrix: public QFrame { + + Q_OBJECT + +public: + + /** constructor to create a day matrix widget. + * + * @param parent widget that is the parent of the day matrix. Normally this should + * be a KDateNavigator + * @param calendar instance of a calendar on which all calculations are based + * @param date start date of the matrix (is expected to be already fixed). It is + * assumed that this date is the first week day to be shown in the matrix. + * @param name name of the widget + */ + KODayMatrix(QWidget *parent, Calendar* calendar, QDate date, const char *name ); + + /** destructor that deallocates all dynamically allocated private members. + */ + ~KODayMatrix(); + + /** updates the day matrix to start with the given date. Does all the necessary + * checks for holidays or events on a day and stores them for display later on. + * Does NOT update the view visually. Call repaint() for this. + * + * @param actdate recalculates the day matrix to show NUMDAYS starting from this + * date. + */ + void updateView(QDate actdate); + + /** returns the QDate object associated with day indexed by the + * supplied offset. + */ + const QDate& getDate(int offset); + + /** returns the official name of this holy day or 0 if there is no label + * for this day. + */ + QString getHolidayLabel(int offset); + + /** adds all actual selected days from mSelStart to mSelEnd to the supplied + * DateList. + */ + void addSelectedDaysTo(DateList&); + + /** sets the actual to be displayed selection in the day matrix starting from + * start and ending with end. Theview must be manually updated by calling + * repaint. (?) + */ + void setSelectedDaysFrom(const QDate& start, const QDate& end); + + + /** Is today visible in the view? Keep this in sync with + * the values today (below) can take. + */ + bool isTodayVisible() const { return today>=0; } ; + + /** If today is visible, then we can find out if today is + * near the beginning or the end of the month. + * This is dependent on today remaining the index + * in the array of visible dates and going from + * top left (0) to bottom right (41). + */ + bool isBeginningOfMonth() const { return today<=8; } ; + bool isEndOfMonth() const { return today>=27; } ; + +public slots: + /** Recalculates all the flags of the days in the matrix like holidays or events + * on a day (Actually calls above method with the actual startdate). + */ + void updateView(); + + /** + * Calculate which square in the matrix should be + * hilighted to indicate it's today. + */ + void recalculateToday(); + +/* + void setStartDate(QDate); +*/ + +signals: + + /** emitted if the user selects a block of days with the mouse by dragging a rectangle + * inside the matrix + * + * @param daylist list of days that have been selected by the user + */ + void selected( const KCal::DateList &daylist ); + + /** emitted if the user has dropped an event inside the matrix + * + * @param event the dropped calendar event + */ + void eventDropped(Event *event); + +protected: + + void paintEvent(QPaintEvent *ev); + + void mousePressEvent (QMouseEvent* e); + + void mouseReleaseEvent (QMouseEvent* e); + + void mouseMoveEvent (QMouseEvent* e); + + void dragEnterEvent(QDragEnterEvent *); + + void dragMoveEvent(QDragMoveEvent *); + + void dragLeaveEvent(QDragLeaveEvent *); + + void dropEvent(QDropEvent *); + + void resizeEvent(QResizeEvent *); + +private: + + /** returns the index of the day located at the matrix's widget (x,y) position. + * + * @param x horizontal coordinate + * @param y vertical coordinate + */ + int getDayIndexFrom(int x, int y); + + /** calculates a "shaded" color from the supplied color object. + * (Copied from Cornelius's kdpdatebutton.cpp) + * + * @param color source based on which a shaded color should be calculated. + */ + QColor getShadedColor(QColor color); + + /** number of days to be displayed. For now there is no support for any other number then 42. + so change it at your own risk :o) */ + static const int NUMDAYS; + + /** calendar instance to be queried for holidays, events, ... */ + Calendar *mCalendar; + + /** starting date of the matrix */ + QDate startdate; + + /** array of day labels to optimeize drawing performance. */ + QString *daylbls; + + /** array of days displayed to reduce memory consumption by + subsequently calling QDate::addDays(). */ + QDate *days; + + /** array of storing the number of events on a given day. + * used for drawing a bold font if there is at least one event on that day. + */ + int *events; + + /** stores holiday names of the days shown in the matrix. */ + QMap<int,QString> mHolidays; + + /** indey of today or -1 if today is not visible in the matrix. */ + int today; + + /** index of day where dragged selection was initiated. + used to detect "negative" timely selections */ + int mSelInit; + + /** if mSelStart has this value it indicates that there is no + actual selection in the matrix. */ + static const int NOSELECTION; + + /** index of first selected day. */ + int mSelStart; + + /** index of last selected day. */ + int mSelEnd; + + /** dynamic tooltip to handle mouse dependent tips for each day in the matrix. */ + DynamicTip* mToolTip; + + + /** default background colour of the matrix. */ + QColor mDefaultBackColor; + + /** default text color of the matrix. */ + QColor mDefaultTextColor; + + /** default text color for days not in the actual month. */ + QColor mDefaultTextColorShaded; + + /** default text color for holidays not in the actual month. */ + QColor mHolidayColorShaded; + + /** text color for selected days. */ + QColor mSelectedDaysColor; + + /** default width of the frame drawn around today if it is visible in the matrix. */ + int mTodayMarginWidth; + + /** stores actual size of each day in the widget so that I dont need to ask this data + * on every repaint. + */ + QRect daysize; + +}; + +#endif diff --git a/korganizer/kodaymatrix.moc b/korganizer/kodaymatrix.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/kodaymatrix.moc diff --git a/korganizer/kodialogmanager.cpp b/korganizer/kodialogmanager.cpp new file mode 100644 index 0000000..caf7599 --- a/dev/null +++ b/korganizer/kodialogmanager.cpp @@ -0,0 +1,343 @@ +/* + 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. +*/ + +#include <libkdepim/categoryeditdialog.h> + +#include "calendarview.h" +#include "incomingdialog.h" +#include "outgoingdialog.h" +#include "koprefsdialog.h" +#include "koeventeditor.h" +#include "koprefs.h" +#include "datenavigator.h" +#include "kotodoeditor.h" +#include "searchdialog.h" +#include "filtereditdialog.h" +#ifndef KORG_NOPLUGINS +#include "plugindialog.h" +#endif +#ifndef KORG_NOARCHIVE +#include "archivedialog.h" +#endif + +#include "kconfig.h" +#include "kodialogmanager.h" +#include "kodialogmanager.moc" + +KODialogManager::KODialogManager( CalendarView *mainView ) : + QObject(), mMainView( mainView ) +{ + mOutgoingDialog = 0; + mIncomingDialog = 0; + mOptionsDialog = 0; + mSearchDialog = 0; + mArchiveDialog = 0; + mFilterEditDialog = 0; + mPluginDialog = 0; + + // mCategoryEditDialog = new KPIM::CategoryEditDialog(KOPrefs::instance(),mMainView); + //KOGlobals::fitDialogToScreen( mCategoryEditDialog ); +} + +KODialogManager::~KODialogManager() +{ + delete mOutgoingDialog; + delete mIncomingDialog; + delete mOptionsDialog; + delete mSearchDialog; +#ifndef KORG_NOARCHIVE + delete mArchiveDialog; +#endif + delete mFilterEditDialog; +#ifndef KORG_NOPLUGINS + delete mPluginDialog; +#endif +} + +OutgoingDialog *KODialogManager::outgoingDialog() +{ + createOutgoingDialog(); + return mOutgoingDialog; +} + +void KODialogManager::createOutgoingDialog() +{ + if (!mOutgoingDialog) { + mOutgoingDialog = new OutgoingDialog(mMainView->calendar(),mMainView); + if (mIncomingDialog) mIncomingDialog->setOutgoingDialog(mOutgoingDialog); + connect(mOutgoingDialog,SIGNAL(numMessagesChanged(int)), + mMainView,SIGNAL(numOutgoingChanged(int))); + } +} + +void KODialogManager::showOptionsDialog( bool showSync ) +{ + int curLanguage = KOPrefs::instance()->mPreferredLanguage; + if (!mOptionsDialog) { + mOptionsDialog = new KOPrefsDialog(mMainView); + //mOptionsDialog->readConfig(); + connect(mOptionsDialog,SIGNAL(configChanged()), + mMainView,SLOT(updateConfig())); + //connect(mCategoryEditDialog,SIGNAL(categoryConfigChanged()), + // mOptionsDialog,SLOT(updateCategories())); + + } + mOptionsDialog->readConfig(); +#ifndef DESKTOP_VERSION + mOptionsDialog->showMaximized(); +#else + mOptionsDialog->show(); +#endif + if ( showSync ) + mOptionsDialog->showSyncPage(); + mOptionsDialog->exec(); + if ( curLanguage != KOPrefs::instance()->mPreferredLanguage ) + KOPrefs::instance()->mLanguageChanged = true; +} +void KODialogManager::showSyncOptions() +{ + showOptionsDialog( true ); + +} +void KODialogManager::showOutgoingDialog() +{ + createOutgoingDialog(); + mOutgoingDialog->show(); + mOutgoingDialog->raise(); +} + +IncomingDialog *KODialogManager::incomingDialog() +{ + createOutgoingDialog(); + if (!mIncomingDialog) { + mIncomingDialog = new IncomingDialog(mMainView->calendar(),mOutgoingDialog,mMainView); + connect(mIncomingDialog,SIGNAL(numMessagesChanged(int)), + mMainView,SIGNAL(numIncomingChanged(int))); + connect(mIncomingDialog,SIGNAL(calendarUpdated()), + mMainView,SLOT(updateView())); + } + return mIncomingDialog; +} + +void KODialogManager::createIncomingDialog() +{ + createOutgoingDialog(); + if (!mIncomingDialog) { + mIncomingDialog = new IncomingDialog(mMainView->calendar(),mOutgoingDialog,mMainView); + connect(mIncomingDialog,SIGNAL(numMessagesChanged(int)), + mMainView,SIGNAL(numIncomingChanged(int))); + connect(mIncomingDialog,SIGNAL(calendarUpdated()), + mMainView,SLOT(updateView())); + } +} + +void KODialogManager::showIncomingDialog() +{ + createIncomingDialog(); + mIncomingDialog->show(); + mIncomingDialog->raise(); +} +/* +void KODialogManager::showCategoryEditDialog() +{ + mCategoryEditDialog->show(); +} +*/ +void KODialogManager::hideSearchDialog() +{ + if (mSearchDialog) + mSearchDialog->hide(); +} + +void KODialogManager::showSearchDialog() +{ + if (!mSearchDialog) { + mSearchDialog = new SearchDialog(mMainView->calendar(),mMainView); + KOListView * lview = mSearchDialog->listview(); + + connect(lview, SIGNAL(showIncidenceSignal(Incidence *)), + mMainView, SLOT(showIncidence(Incidence *))); + connect(lview, SIGNAL(editIncidenceSignal(Incidence *)), + mMainView, SLOT(editIncidence(Incidence *))); + connect(lview, SIGNAL(deleteIncidenceSignal(Incidence *)), + mMainView, SLOT(deleteIncidence(Incidence *))); + connect(lview, SIGNAL(cloneIncidenceSignal(Incidence *)), + mMainView, SLOT(cloneIncidence(Incidence *))); + connect(lview, SIGNAL(beamIncidenceSignal(Incidence *)), + mMainView, SLOT(beamIncidence(Incidence *))); + connect(lview, SIGNAL(moveIncidenceSignal(Incidence *)), + mMainView, SLOT(moveIncidence(Incidence *))); + connect(lview, SIGNAL(beamIncidenceList(QPtrList<Incidence> )), + mMainView, SLOT(beamIncidenceList(QPtrList<Incidence> ))); + + connect(mMainView, SIGNAL(configChanged()), mSearchDialog, SLOT(updateConfig())); + connect(mMainView, SIGNAL(updateSearchDialog()), mSearchDialog, SLOT(updateList())); + // connect( lview, SIGNAL( incidenceSelected( Incidence * ) ), + // mMainView, SLOT( processMainViewSelection( Incidence * ) ) ); +#ifndef DESKTOP_VERSION + mSearchDialog->setMaximumSize( 640, 480 ); + //mSearchDialog->setGeometry( 40,40, 400, 300); + mSearchDialog->showMaximized(); +#else + KConfig *config = KOGlobals::config(); + config->setGroup("WidgetLayout"); + QStringList list; + list = config->readListEntry("SearchLayout"); + int x,y,w,h; + if ( ! list.isEmpty() ) { + x = list[0].toInt(); + y = list[1].toInt(); + w = list[2].toInt(); + h = list[3].toInt(); + mSearchDialog->setGeometry(x,y,w,h); + + } + +#endif + } + // make sure the widget is on top again + mSearchDialog->show(); + mSearchDialog->raise(); +} + +SearchDialog * KODialogManager::getSearchDialog() +{ + return mSearchDialog; +} +void KODialogManager::showArchiveDialog() +{ +#ifndef KORG_NOARCHIVE + if (!mArchiveDialog) { + mArchiveDialog = new ArchiveDialog(mMainView->calendar(),mMainView); + connect(mArchiveDialog,SIGNAL(eventsDeleted()), + mMainView,SLOT(updateView())); + } + mArchiveDialog->show(); + mArchiveDialog->raise(); + + // Workaround. + QApplication::restoreOverrideCursor(); +#endif +} + +void KODialogManager::showFilterEditDialog(QPtrList<CalFilter> *filters) +{ + if (!mFilterEditDialog) { + mFilterEditDialog = new FilterEditDialog(filters,mMainView); + connect(mFilterEditDialog,SIGNAL(filterChanged()), + mMainView,SLOT(filterEdited())); + + } + +#ifndef DESKTOP_VERSION + mFilterEditDialog->showMaximized(); +#else + mFilterEditDialog->show(); +#endif + mFilterEditDialog->raise(); +} + +void KODialogManager::showPluginDialog() +{ +#ifndef KORG_NOPLUGINS + if (!mPluginDialog) { + mPluginDialog = new PluginDialog(mMainView); + connect(mPluginDialog,SIGNAL(configChanged()), + mMainView,SLOT(updateConfig())); + } + mPluginDialog->show(); + mPluginDialog->raise(); +#endif +} + +KOEventEditor *KODialogManager::getEventEditor() +{ + KOEventEditor *eventEditor = new KOEventEditor( mMainView->calendar(), + mMainView ); + + connect(eventEditor,SIGNAL(eventAdded(Event *)), + mMainView,SLOT(eventAdded(Event *))); + connect(eventEditor,SIGNAL(eventChanged(Event *)), + mMainView,SLOT(eventChanged(Event *))); + connect(eventEditor,SIGNAL(eventDeleted()), + mMainView,SLOT(eventDeleted())); + connect(eventEditor,SIGNAL(deleteAttendee(Incidence *)), + mMainView,SLOT(schedule_cancel(Incidence *))); + connect( eventEditor, SIGNAL(jumpToTime( const QDate &)), + mMainView->dateNavigator(), SLOT( selectWeek( const QDate & ) ) ); + connect( eventEditor, SIGNAL( showAgendaView( bool)), + mMainView->viewManager(), SLOT( showAgendaView( bool) ) ); + + // connect(mCategoryEditDialog,SIGNAL(categoryConfigChanged()), + // eventEditor,SLOT(updateCategoryConfig())); + // connect(eventEditor,SIGNAL(editCategories()), + // mCategoryEditDialog,SLOT(show())); + connect(eventEditor,SIGNAL(dialogClose(Incidence*)), + mMainView,SLOT(dialogClosing(Incidence*))); + + //connect(mMainView,SIGNAL(closingDown()),eventEditor,SLOT(reject())); + + return eventEditor; +} + +KOTodoEditor *KODialogManager::getTodoEditor() +{ + KOTodoEditor *todoEditor = new KOTodoEditor( mMainView->calendar(), + mMainView ); + + // connect(mCategoryEditDialog,SIGNAL(categoryConfigChanged()), + // todoEditor,SLOT(updateCategoryConfig())); + // connect(todoEditor,SIGNAL(editCategories()),mCategoryEditDialog,SLOT(show())); + + connect(todoEditor,SIGNAL(todoAdded(Todo *)), + mMainView,SLOT(todoAdded(Todo *))); + connect(todoEditor,SIGNAL(todoChanged(Todo *)), + mMainView,SLOT(todoChanged(Todo *))); + connect(todoEditor,SIGNAL(todoDeleted()), + mMainView,SLOT(todoDeleted())); + connect(todoEditor,SIGNAL(dialogClose(Incidence*)), + mMainView,SLOT(dialogClosing(Incidence*))); + connect( todoEditor, SIGNAL(jumpToTime( const QDate &)), + mMainView->dateNavigator(), SLOT( selectWeek( const QDate & ) ) ); + connect( todoEditor, SIGNAL( showAgendaView( bool)), + mMainView->viewManager(), SLOT( showAgendaView( bool) ) ); + // connect(todoEditor,SIGNAL(deleteAttendee(Incidence *)), + // mMainView,SLOT(schedule_cancel(Incidence *))); + //connect(mMainView,SIGNAL(closingDown()),todoEditor,SLOT(reject())); + + return todoEditor; +} + +void KODialogManager::updateSearchDialog() +{ + if (mSearchDialog) mSearchDialog->updateView(); +} + +void KODialogManager::setDocumentId( const QString &id ) +{ + if (mOutgoingDialog) mOutgoingDialog->setDocumentId( id ); +} + +void KODialogManager::writeSettings( KConfig *config ) +{ + if (mSearchDialog) + mSearchDialog->listview()->writeSettings(config,"SearchListView Layout"); +} diff --git a/korganizer/kodialogmanager.h b/korganizer/kodialogmanager.h new file mode 100644 index 0000000..a6cc621 --- a/dev/null +++ b/korganizer/kodialogmanager.h @@ -0,0 +1,100 @@ +/* + 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 KODIALOGMANAGER_H +#define KODIALOGMANAGER_H + +#include <qobject.h> +#include <qptrlist.h> + +#include <libkcal/calfilter.h> + +class CalendarView; +class OutgoingDialog; +class IncomingDialog; +class KOPrefsDialog; +//namespace KPIM { class CategoryEditDialog; } +class KOEventEditor; +class KOTodoEditor; +class SearchDialog; +class ArchiveDialog; +class PluginDialog; +class KConfig; +class FilterEditDialog; + +using namespace KCal; + +/** + This class manages the dialogs used by the calendar view. It owns the objects + and handles creation and selection. +*/ +class KODialogManager : public QObject +{ + Q_OBJECT + public: + KODialogManager( CalendarView * ); + virtual ~KODialogManager(); + + /** Get an editor dialog for an Event. */ + KOEventEditor *getEventEditor(); + + /** Get an editor dialog for a Todo. */ + KOTodoEditor *getTodoEditor(); + + OutgoingDialog *outgoingDialog(); + + IncomingDialog *incomingDialog(); + void writeSettings( KConfig *config); + void updateSearchDialog(); + SearchDialog * getSearchDialog(); + void setDocumentId( const QString &id ); + + public slots: + void showOptionsDialog( bool showSync = false); + void showSyncOptions(); + void showIncomingDialog(); + void showOutgoingDialog(); + // void showCategoryEditDialog(); + void showSearchDialog(); + void showArchiveDialog(); + void showFilterEditDialog(QPtrList<CalFilter> *filters); + void showPluginDialog(); + void hideSearchDialog(); + + private: + void createOutgoingDialog(); + void createIncomingDialog(); + + CalendarView *mMainView; + + OutgoingDialog *mOutgoingDialog; + IncomingDialog *mIncomingDialog; + KOPrefsDialog *mOptionsDialog; + // KPIM::CategoryEditDialog *mCategoryEditDialog; + SearchDialog *mSearchDialog; + ArchiveDialog *mArchiveDialog; + FilterEditDialog *mFilterEditDialog; + PluginDialog *mPluginDialog; +}; + +#endif diff --git a/korganizer/kodialogmanager.moc b/korganizer/kodialogmanager.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/kodialogmanager.moc diff --git a/korganizer/koeditordetails.cpp b/korganizer/koeditordetails.cpp new file mode 100644 index 0000000..7c4c382 --- a/dev/null +++ b/korganizer/koeditordetails.cpp @@ -0,0 +1,398 @@ +/* + 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 thse 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. +*/ + +#include <qtooltip.h> +#include <qfiledialog.h> +#include <qlayout.h> +#include <qvbox.h> +#include <qbuttongroup.h> +#include <qvgroupbox.h> +#include <qwidgetstack.h> +#include <qdatetime.h> +#include <qapp.h> + +#include <klocale.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <kstandarddirs.h> +#include <kmessagebox.h> +#ifndef KORG_NOKABC +#include <kabc/addresseedialog.h> +#endif + +#include <libkcal/incidence.h> + +#include "koprefs.h" + +#include "koeditordetails.h" +#include "koeditordetails.moc" + +template <> +CustomListViewItem<class Attendee *>::~CustomListViewItem() +{ + delete mData; +} + +template <> +void CustomListViewItem<class Attendee *>::updateItem() +{ + setText(0,mData->name()); + setText(1,mData->email()); + setText(2,mData->roleStr()); + setText(3,mData->statusStr()); + if (mData->RSVP() && !mData->email().isEmpty()) + setPixmap(4,SmallIcon("mailappt")); + else + setPixmap(4,SmallIcon("nomailappt")); +} + + +KOEditorDetails::KOEditorDetails (int spacing,QWidget* parent,const char* name) + : QWidget( parent, name), mDisableItemUpdate( false ) +{ + QGridLayout *topLayout = new QGridLayout(this); + topLayout->setSpacing(spacing); + + QString organizer = KOPrefs::instance()->email(); + mOrganizerLabel = new QLabel(i18n("Organizer: %1").arg(organizer),this); + + mListView = new KListView(this,"mListView"); + mListView->addColumn(i18n("Name"),180); + mListView->addColumn(i18n("Email"),180); + mListView->addColumn(i18n("Role"),60); + mListView->addColumn(i18n("Status"),100); + mListView->addColumn(i18n("RSVP"),35); + if ( KOPrefs::instance()->mCompactDialogs ) { + //mListView->setFixedHeight(78); + } + + connect(mListView,SIGNAL(selectionChanged(QListViewItem *)), + SLOT(updateAttendeeInput())); + + QLabel *attendeeLabel = new QLabel(this); + attendeeLabel->setText(i18n("Name:")); + attendeeLabel->setFixedSize( attendeeLabel->sizeHint() ); + mNameEdit = new QLineEdit(this); + connect(mNameEdit,SIGNAL(textChanged(const QString &)), + SLOT(updateAttendeeItem())); + + mUidEdit = new QLineEdit(0); + mUidEdit->setText(""); + + QLabel *emailLabel = new QLabel(this); + emailLabel->setText(i18n("Email:")); + mEmailEdit = new QLineEdit(this); + connect(mEmailEdit,SIGNAL(textChanged(const QString &)), + SLOT(updateAttendeeItem())); + + QLabel *attendeeRoleLabel = new QLabel(this); + attendeeRoleLabel->setText(i18n("Role:")); + mRoleCombo = new QComboBox(false,this); + mRoleCombo->insertStringList(Attendee::roleList()); + connect(mRoleCombo,SIGNAL(activated(int)),SLOT(updateAttendeeItem())); + + QLabel *statusLabel = new QLabel(this); + statusLabel->setText( i18n("Status:") ); + + mStatusCombo = new QComboBox(false,this); + mStatusCombo->insertStringList(Attendee::statusList()); + connect(mStatusCombo,SIGNAL(activated(int)),SLOT(updateAttendeeItem())); + + mRsvpButton = new QCheckBox(this); + mRsvpButton->setText(i18n("Request response")); + connect(mRsvpButton,SIGNAL(clicked()),SLOT(updateAttendeeItem())); + QWidget *buttonBox = new QWidget(this); + QVBoxLayout *buttonLayout = new QVBoxLayout(buttonBox); + + QPushButton *newButton = new QPushButton(i18n("&New"),buttonBox); + buttonLayout->addWidget(newButton); + connect(newButton,SIGNAL(clicked()),SLOT(addNewAttendee())); + + mRemoveButton = new QPushButton(i18n("&Remove"),buttonBox); + buttonLayout->addWidget(mRemoveButton); + connect(mRemoveButton, SIGNAL(clicked()),SLOT(removeAttendee())); + + mAddressBookButton = new QPushButton(i18n("Address &Book..."),this); + // buttonLayout->addWidget(mAddressBookButton); + connect(mAddressBookButton,SIGNAL(clicked()),SLOT(openAddressBook())); + //mRoleCombo->setFixedSize( mRoleCombo->sizeHint () ); + + if (qApp->desktop()->width() < 300 ) { + mListView->setFixedHeight(80); + topLayout->addMultiCellWidget(mOrganizerLabel,0,0,0,3); + topLayout->addMultiCellWidget(mListView,1,1,0,3); + topLayout->addWidget(attendeeLabel,3,0); + topLayout->addMultiCellWidget(mNameEdit,3,3,1,2); + topLayout->addWidget(emailLabel,4,0); + topLayout->addMultiCellWidget(mEmailEdit,4,4,1,2); + topLayout->addWidget(attendeeRoleLabel,5,0); + topLayout->addMultiCellWidget(mRoleCombo,5,5,1,2); + topLayout->addWidget(statusLabel,6,0); + topLayout->addMultiCellWidget(mStatusCombo,6,6,1,2); + topLayout->addMultiCellWidget(mAddressBookButton,2,2,2,3); + topLayout->addMultiCellWidget(mRsvpButton,2,2,0,1); + topLayout->addMultiCellWidget(buttonBox,3,4,3,3); + topLayout->setRowStretch(1,2); + topLayout->setColStretch(0,0); + topLayout->setColStretch(1,2); + topLayout->setColStretch(2,1); + topLayout->setColStretch(3,1); + + } else { + topLayout->addMultiCellWidget(mOrganizerLabel,0,0,0,5); + topLayout->addMultiCellWidget(mListView,1,1,0,5); + topLayout->addWidget(attendeeLabel,3,0); + topLayout->addMultiCellWidget(mNameEdit,3,3,1,4); + topLayout->addWidget(emailLabel,4,0); + topLayout->addMultiCellWidget(mEmailEdit,4,4,1,4); + topLayout->addWidget(attendeeRoleLabel,5,0); + topLayout->addMultiCellWidget(mRoleCombo,5,5,1,2); + topLayout->addWidget(statusLabel,5,3); + topLayout->addMultiCellWidget(mStatusCombo,5,5,4,5); + topLayout->addMultiCellWidget(mAddressBookButton,2,2,4,5); + topLayout->addMultiCellWidget(mRsvpButton,2,2,0,1); + topLayout->addMultiCellWidget(buttonBox,3,4,5,5); + topLayout->setRowStretch(1,5); + topLayout->setColStretch(0,0); + } +// #if 0 +// topLayout->setColStretch(2,1); +// topLayout->addWidget(statusLabel,3,3); +// topLayout->addWidget(mStatusCombo,3,4); +// #else +// topLayout->addWidget(statusLabel,4,3); +// // topLayout->addWidget(mStatusCombo,4,3); +// topLayout->addMultiCellWidget(mStatusCombo,4,4,4,5); + +// #endif +// // topLayout->setRowStretch(5,1); +// topLayout->addMultiCellWidget(mRsvpButton,5,5,0,1); +// topLayout->addMultiCellWidget(buttonBox,2,3,5,5); +// topLayout->setRowStretch(1,5); +// topLayout->setColStretch(0,0); + +#ifdef KORG_NOKABC + mAddressBookButton->hide(); +#endif + + updateAttendeeInput(); +} + +KOEditorDetails::~KOEditorDetails() +{ +} + +void KOEditorDetails::removeAttendee() +{ + AttendeeListItem *aItem = (AttendeeListItem *)mListView->selectedItem(); + if (!aItem) return; + + Attendee *delA = new Attendee(aItem->data()->name(),aItem->data()->email(), + aItem->data()->RSVP(),aItem->data()->status(),aItem->data()->role(), + aItem->data()->uid()); + mdelAttendees.append(delA); + + delete aItem; + + updateAttendeeInput(); +} + + +void KOEditorDetails::openAddressBook() +{ +#ifndef KORG_NOKABC + + KABC::Addressee::List list = KABC::AddresseeDialog::getAddressees(this); + uint i=0; + for (i=0; i < list.count(); i++) { + insertAttendee( new Attendee( list[i].realName(), list[i].preferredEmail(),false,KCal::Attendee::NeedsAction,KCal::Attendee::ReqParticipant,list[i].uid()) ); + } + +#if 0 + KABC::Addressee a = KABC::AddresseeDialog::getAddressee(this); + if (!a.isEmpty()) { + insertAttendee( new Attendee( a.realName(), a.preferredEmail(),false,KCal::Attendee::NeedsAction,KCal::Attendee::ReqParticipant,a.uid()) ); + } +#endif +#endif +} + + +void KOEditorDetails::addNewAttendee() +{ +#if 0 + // this is cool. If they didn't enter an email address, + // try to look it up in the address book and fill it in for them. + if (QString(mEmailEdit->text()).stripWhiteSpace().isEmpty()) { + KabAPI addrBook; + QString name; + std::list<AddressBook::Entry> entries; + name = mNameEdit->text(); + if (addrBook.init() == AddressBook::NoError) { + if (addrBook.getEntryByName(name, entries, 1) == AddressBook::NoError) { + kdDebug() << "positive match" << endl; + // take first email address + if (!entries.front().emails.isEmpty() && + entries.front().emails.first().length()>0) + mEmailEdit->setText(entries.front().emails.first()); + } + } + } +#endif + + Attendee *a = new Attendee(i18n("(EmptyName)"),i18n("(EmptyEmail)")); + insertAttendee(a); +} + + +void KOEditorDetails::insertAttendee(Attendee *a) +{ + AttendeeListItem *item = new AttendeeListItem(a,mListView); + mListView->setSelected( item, true ); +} + +void KOEditorDetails::setDefaults() +{ + mRsvpButton->setChecked(true); + mListView->clear(); + mdelAttendees.clear(); + clearAttendeeInput(); + mOrganizerLabel->setText(i18n("Organizer: %1").arg(KOPrefs::instance()->email())); + + mNameEdit->setText(""); + mUidEdit->setText(""); + mEmailEdit->setText(""); + mRoleCombo->setCurrentItem( 0 ); + mStatusCombo->setCurrentItem( 0 ); + +} + +void KOEditorDetails::readEvent(Incidence *event) +{ + setDefaults(); + //mListView->clear(); + //mdelAttendees.clear(); + QPtrList<Attendee> tmpAList = event->attendees(); + Attendee *a; + for (a = tmpAList.first(); a; a = tmpAList.next()) + insertAttendee(new Attendee(*a)); + + mListView->setSelected( mListView->firstChild(), true ); + mOrganizerLabel->setText(i18n("Organizer: %1").arg(event->organizer())); +} + +void KOEditorDetails::writeEvent(Incidence *event) +{ + event->clearAttendees(); + QListViewItem *item; + AttendeeListItem *a; + for (item = mListView->firstChild(); item; + item = item->nextSibling()) { + a = (AttendeeListItem *)item; + event->addAttendee(new Attendee(*(a->data()))); + } + event->setOrganizer(KOPrefs::instance()->email()); +} + +void KOEditorDetails::cancelAttendeeEvent(Incidence *event) +{ + event->clearAttendees(); + Attendee * att; + for (att=mdelAttendees.first();att;att=mdelAttendees.next()) { + event->addAttendee(new Attendee(*att)); + } + mdelAttendees.clear(); +} + +bool KOEditorDetails::validateInput() +{ + return true; +} + +void KOEditorDetails::updateAttendeeInput() +{ + QListViewItem *item = mListView->selectedItem(); + AttendeeListItem *aItem = static_cast<AttendeeListItem *>( item ); + if (aItem) { + fillAttendeeInput( aItem ); + } else { + clearAttendeeInput(); + } +} + +void KOEditorDetails::clearAttendeeInput() +{ + mNameEdit->setText(""); + mUidEdit->setText(""); + mEmailEdit->setText(""); + mRoleCombo->setCurrentItem(0); + mStatusCombo->setCurrentItem(0); + mRsvpButton->setChecked(true); + setEnabledAttendeeInput( false ); +} + +void KOEditorDetails::fillAttendeeInput( AttendeeListItem *aItem ) +{ + Attendee *a = aItem->data(); + mDisableItemUpdate = true; + mNameEdit->setText(a->name()); + mUidEdit->setText(a->uid()); + mEmailEdit->setText(a->email()); + mRoleCombo->setCurrentItem(a->role()); + mStatusCombo->setCurrentItem(a->status()); + mRsvpButton->setChecked(a->RSVP()); + + mDisableItemUpdate = false; + + setEnabledAttendeeInput( true ); +} + +void KOEditorDetails::setEnabledAttendeeInput( bool enabled ) +{ + mNameEdit->setEnabled( enabled ); + mEmailEdit->setEnabled( enabled ); + mRoleCombo->setEnabled( enabled ); + mStatusCombo->setEnabled( enabled ); + mRsvpButton->setEnabled( enabled ); + + mRemoveButton->setEnabled( enabled ); +} + +void KOEditorDetails::updateAttendeeItem() +{ + if (mDisableItemUpdate) return; + + QListViewItem *item = mListView->selectedItem(); + AttendeeListItem *aItem = static_cast<AttendeeListItem *>( item ); + if ( !aItem ) return; + + Attendee *a = aItem->data(); + + a->setName( mNameEdit->text() ); + a->setUid( mUidEdit->text() ); + a->setEmail( mEmailEdit->text() ); + a->setRole( Attendee::Role( mRoleCombo->currentItem() ) ); + a->setStatus( Attendee::PartStat( mStatusCombo->currentItem() ) ); + a->setRSVP( mRsvpButton->isChecked() ); + aItem->updateItem(); +} diff --git a/korganizer/koeditordetails.h b/korganizer/koeditordetails.h new file mode 100644 index 0000000..930b296 --- a/dev/null +++ b/korganizer/koeditordetails.h @@ -0,0 +1,103 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + 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 _KOEDITORDETAILS_H +#define _KOEDITORDETAILS_H + +#include <qframe.h> +#include <qlabel.h> +#include <qcheckbox.h> +#include <qpushbutton.h> +#include <qgroupbox.h> +#include <qlineedit.h> +#include <qcombobox.h> +#include <qmultilineedit.h> +#include <klistview.h> +#include <qradiobutton.h> +#include <qptrlist.h> + +#include <kapplication.h> + +#include <libkcal/event.h> + +#include "ktimeedit.h" +#include "customlistviewitem.h" + +class KDateEdit; + +using namespace KCal; + +typedef CustomListViewItem<Attendee *> AttendeeListItem; + + +class KOEditorDetails : public QWidget +{ + Q_OBJECT + public: + KOEditorDetails (int spacing = 8,QWidget* parent = 0, const char* name = 0); + virtual ~KOEditorDetails(); + + /** Set widgets to default values */ + void setDefaults(); + /** Read event object and setup widgets accordingly */ + void readEvent(Incidence *); + /** Write event settings to event object */ + void writeEvent(Incidence *); + + /** return a clone of the event with attendees to be canceld*/ + void cancelAttendeeEvent(Incidence *); + /** Check if the input is valid. */ + bool validateInput(); + + public slots: + void insertAttendee(Attendee *); + + protected slots: + void addNewAttendee(); + void removeAttendee(); + void openAddressBook(); + void updateAttendeeInput(); + void clearAttendeeInput(); + void fillAttendeeInput(AttendeeListItem *); + void updateAttendeeItem(); + void setEnabledAttendeeInput(bool); + + private: + bool mDisableItemUpdate; + + QLineEdit *mNameEdit; + QLineEdit *mUidEdit; + QLineEdit *mEmailEdit; + KListView *mListView; + QComboBox* mRoleCombo; + QCheckBox* mRsvpButton; + QComboBox* mStatusCombo; + QLabel *mOrganizerLabel; + + QPushButton* mAddButton; + QPushButton* mRemoveButton; + QPushButton* mAddressBookButton; + + QPtrList<Attendee> mdelAttendees; +}; + +#endif diff --git a/korganizer/koeditordetails.moc b/korganizer/koeditordetails.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/koeditordetails.moc diff --git a/korganizer/koeditorgeneral.cpp b/korganizer/koeditorgeneral.cpp new file mode 100644 index 0000000..ad1389f --- a/dev/null +++ b/korganizer/koeditorgeneral.cpp @@ -0,0 +1,505 @@ +/* + 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. +*/ + +#include <qwidget.h> +#include <qtooltip.h> +#include <qlayout.h> +#include <qvbox.h> +#include <qbuttongroup.h> +#include <qvgroupbox.h> +#include <qwidgetstack.h> +#include <qdatetime.h> +#include <qfile.h> + + +#include <kglobal.h> +#include <kdebug.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <kfiledialog.h> +#include <kstandarddirs.h> + +#include <libkcal/todo.h> +#include <libkcal/event.h> +#include <libkdepim/categoryselectdialog.h> +#include <libkdepim/kdateedit.h> + +#include "koprefs.h" +#include "koglobals.h" + +#include "koeditorgeneral.h" +#include "kolocationbox.h" +#include "koeditorgeneral.moc" +#ifndef DESKTOP_VERSION +#include <qpe/qpeapplication.h> +#else +#include <qapplication.h> +#endif + +KOEditorGeneral::KOEditorGeneral(QObject* parent, const char* name) : + QObject( parent, name) +{ +} + +KOEditorGeneral::~KOEditorGeneral() +{ +} + +void KOEditorGeneral::initHeader(QWidget *parent,QBoxLayout *topLayout) +{ + QGridLayout *headerLayout = new QGridLayout(topLayout); + +#if 0 + mOwnerLabel = new QLabel(i18n("Owner:"),parent); + headerLayout->addMultiCellWidget(mOwnerLabel,0,0,0,1); +#endif + + QLabel *summaryLabel = new QLabel(i18n("Summary:"),parent); + headerLayout->addWidget(summaryLabel,1,0); + + mSummaryEdit = new KOLocationBox(TRUE,parent, 10); + mSummaryEdit->setSizePolicy( QSizePolicy( QSizePolicy::Preferred ,QSizePolicy::MinimumExpanding ,FALSE) ); + //mSummaryEdit->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)5 ,(QSizePolicy::SizeType)3 ,FALSE) ); + //qDebug("h %d %d ", summaryLabel->sizeHint().height(),mSummaryEdit->sizeHint().height() ); + int hei = (summaryLabel->sizeHint().height() + mSummaryEdit->sizeHint().height())/2; + if ( QApplication::desktop()->width() > 320 ) + mSummaryEdit->setMaximumHeight( hei +6 ); + //qDebug("%d %d %d %d %d %d ", QSizePolicy::Fixed , QSizePolicy::Minimum , QSizePolicy:: Maximum , QSizePolicy:: Preferred , QSizePolicy:: MinimumExpanding , QSizePolicy::Expanding ); + // SizeType { Fixed = 0, Minimum = MayGrow, Maximum = MayShrink, Preferred = MayGrow|MayShrink, MinimumExpanding = Minimum|ExpMask, Expanding = MinimumExpanding|MayShrink } + // mSummaryEdit = new QLineEdit(parent); + headerLayout->addWidget(mSummaryEdit,1,1); + connect ( mSummaryEdit->lineEdit(), SIGNAL ( returnPressed() ), this, SIGNAL (allAccepted () ) ); + + QLabel *locationLabel = new QLabel(i18n("Location:"),parent); + headerLayout->addWidget(locationLabel,2,0); + + mLocationEdit = new KOLocationBox(TRUE,parent,10); + mLocationEdit->setSizePolicy( QSizePolicy( QSizePolicy::Preferred ,QSizePolicy::MinimumExpanding ,FALSE) ); + if ( QApplication::desktop()->width() > 320 ) + mLocationEdit->setMaximumHeight( hei + 6); + + // mLocationEdit = new QLineEdit(parent); + connect ( mLocationEdit->lineEdit(), SIGNAL ( returnPressed() ), this, SIGNAL (allAccepted () ) ); + headerLayout->addWidget(mLocationEdit,2,1); + headerLayout->setColStretch( 1, 10); +} +void KOEditorGeneral::setFocusOn( int i ) +{ + qApp->processEvents(); + if ( i == 1 ) { + mDescriptionEdit->setFocus(); + mDescriptionEdit->setCursorPosition( mDescriptionEdit->numLines (), 333); + } + if ( i == 2 ) { + mSummaryEdit->setFocus(); + } + +} +void KOEditorGeneral::editCategories() +{ + // qDebug("KOEditorGeneral::editCategories() "); + KPIM::CategorySelectDialog* csd = new KPIM::CategorySelectDialog( KOPrefs::instance(), 0 ); + connect(csd,SIGNAL(categoriesSelected(const QString &)), this ,SLOT(setCategories(const QString &))); + //KOGlobals::fitDialogToScreen( csd ); + csd->setSelected( QStringList::split (",", mCategoriesLabel->text()) ); + csd->exec(); + delete csd; +} +void KOEditorGeneral::initCategories(QWidget *parent, QBoxLayout *topLayout) +{ + QBoxLayout *categoriesLayout = new QHBoxLayout( topLayout ); + + mCategoriesButton = new QPushButton(parent); + mCategoriesButton->setText(i18n("Categories...")); + connect(mCategoriesButton,SIGNAL(clicked()),this, SLOT(editCategories() )); + categoriesLayout->addWidget(mCategoriesButton); + + mCategoriesLabel = new QLabel(parent); + mCategoriesLabel->setFrameStyle(QFrame::Panel|QFrame::Sunken); + categoriesLayout->addWidget(mCategoriesLabel,1); +} + +void KOEditorGeneral::initSecrecy(QWidget *parent, QBoxLayout *topLayout) +{ + QBoxLayout *secrecyLayout = new QHBoxLayout( topLayout ); + + QLabel *secrecyLabel = new QLabel(i18n("Access:"),parent); + mCancelBox = new QCheckBox ( i18n("Cancelled"), parent); + secrecyLayout->addWidget(mCancelBox); + secrecyLayout->addWidget(secrecyLabel); + + mSecrecyCombo = new QComboBox(parent); + mSecrecyCombo->insertStringList(Incidence::secrecyList()); + secrecyLayout->addWidget(mSecrecyCombo); +} + +void KOEditorGeneral::initDescription(QWidget *parent,QBoxLayout *topLayout) +{ + mDescriptionEdit = new KTextEdit(parent); + mDescriptionEdit->setFont(KOPrefs::instance()->mEditBoxFont ); + mDescriptionEdit->append(""); + mDescriptionEdit->setReadOnly(false); + mDescriptionEdit->setOverwriteMode(false); + mDescriptionEdit->setWordWrap( KTextEdit::WidgetWidth ); + topLayout->addWidget(mDescriptionEdit); +#ifndef DESKTOP_VERSION + QPEApplication::setStylusOperation( mDescriptionEdit, QPEApplication::RightOnHold ); +#endif + +} + +void KOEditorGeneral::initAlarm(QWidget *parent,QBoxLayout *topLayout) +{ + QBoxLayout *alarmLayout = new QHBoxLayout(topLayout); + + //mAlarmBell = new QLabel(parent); + //mAlarmBell->setPixmap(SmallIcon("bell")); + //alarmLayout->addWidget(mAlarmBell); + if ( QApplication::desktop()->width() < 320 ) + mAlarmButton = new QCheckBox(i18n("Rem."),parent); + else + mAlarmButton = new QCheckBox(i18n("Reminder:"),parent); + + connect(mAlarmButton, SIGNAL(toggled(bool)), SLOT(enableAlarmEdit(bool))); + alarmLayout->addWidget(mAlarmButton); + + mAlarmTimeEdit = new QSpinBox ( 0, 9999, 1, parent, "mAlarmTimeEdit " ) ; + alarmLayout->addWidget(mAlarmTimeEdit); + mAlarmIncrCombo = new QComboBox(false, parent); + if ( QApplication::desktop()->width() < 320 ) { + mAlarmIncrCombo->insertItem(i18n("min")); + mAlarmIncrCombo->insertItem(i18n("hou")); + mAlarmIncrCombo->insertItem(i18n("day")); + mAlarmTimeEdit->setMaximumWidth( mAlarmTimeEdit->sizeHint().width() ); + mAlarmIncrCombo->setMaximumWidth( mAlarmIncrCombo->sizeHint().width() ); + } else { + mAlarmIncrCombo->insertItem(i18n("minute(s)")); + mAlarmIncrCombo->insertItem(i18n("hour(s)")); + mAlarmIncrCombo->insertItem(i18n("day(s)")); + } + + // mAlarmIncrCombo->setMinimumHeight(20); + alarmLayout->addWidget(mAlarmIncrCombo); + mAlarmSoundButton = new QPushButton(parent); + mAlarmSoundButton->setPixmap(SmallIcon("playsound")); + mAlarmSoundButton->setToggleButton(true); + QToolTip::add(mAlarmSoundButton, i18n("No sound set")); + connect(mAlarmSoundButton, SIGNAL(clicked()), SLOT(pickAlarmSound())); + alarmLayout->addWidget(mAlarmSoundButton); + + mAlarmProgramButton = new QPushButton(parent); + mAlarmProgramButton->setPixmap(SmallIcon("run")); + mAlarmProgramButton->setToggleButton(true); + QToolTip::add(mAlarmProgramButton, i18n("No program set")); + connect(mAlarmProgramButton, SIGNAL(clicked()), SLOT(pickAlarmProgram())); + alarmLayout->addWidget(mAlarmProgramButton); + mAlarmSoundButton->setMaximumWidth( mAlarmSoundButton->sizeHint().width() + 4 ); + mAlarmProgramButton->setMaximumWidth(mAlarmProgramButton->sizeHint().width() + 4 ); + // if ( KOPrefs::instance()->mCompactDialogs ) { + // mAlarmSoundButton->hide(); + // mAlarmProgramButton->hide(); + // } +} + +void KOEditorGeneral::pickAlarmSound() +{ + + //QString prefix = mAlarmSound; + if (!mAlarmSoundButton->isOn()) { + //mAlarmSound = ""; + QToolTip::remove(mAlarmSoundButton); + QToolTip::add(mAlarmSoundButton, i18n("No sound set")); + mAlarmProgramButton->setOn(true); + mAlarmSoundButton->setOn(false); + } else { + QString fileName(KFileDialog::getOpenFileName(mAlarmSound, + i18n("*.wav|Wav Files"), 0)); + if (!fileName.isEmpty()) { + mAlarmSound = fileName; + QToolTip::remove(mAlarmSoundButton); + QString dispStr = i18n("Playing '%1'").arg(fileName); + QToolTip::add(mAlarmSoundButton, dispStr); + mAlarmProgramButton->setOn(false); + mAlarmSoundButton->setOn(true); + } else { + mAlarmProgramButton->setOn(true); + mAlarmSoundButton->setOn(false); + + } + } + + if (mAlarmProgramButton->isOn()) + ((QWidget*)parent())->topLevelWidget()->setCaption(i18n("Proc.Al.: ") + mAlarmProgram ); + if ( mAlarmSoundButton->isOn()) + ((QWidget*)parent())->topLevelWidget()->setCaption(i18n("Audio.Al.: ") + mAlarmSound ); +} + +void KOEditorGeneral::pickAlarmProgram() +{ + if (!mAlarmProgramButton->isOn()) { + //mAlarmProgram = ""; + QToolTip::remove(mAlarmProgramButton); + QToolTip::add(mAlarmProgramButton, i18n("No program set")); + mAlarmProgramButton->setOn(false); + mAlarmSoundButton->setOn(true); + } else { + QString fileName(KFileDialog::getOpenFileName(mAlarmProgram,i18n("Procedure Alarm.: ") , 0)); + if (!fileName.isEmpty()) { + mAlarmProgram = fileName; + QToolTip::remove(mAlarmProgramButton); + QString dispStr = i18n("Running '%1'").arg(fileName); + QToolTip::add(mAlarmProgramButton, dispStr); + mAlarmSoundButton->setOn(false); + mAlarmProgramButton->setOn(true); + } else { + mAlarmProgramButton->setOn(false); + mAlarmSoundButton->setOn(true); + } + } + if (mAlarmProgramButton->isOn()) + ((QWidget*)parent())->topLevelWidget()->setCaption(i18n("Proc.Al.: ") + mAlarmProgram ); + if ( mAlarmSoundButton->isOn()) + ((QWidget*)parent())->topLevelWidget()->setCaption(i18n("Sound.Al.: ") + mAlarmSound ); +} + + + +void KOEditorGeneral::enableAlarmEdit(bool enable) +{ + if ( enable ) { + if (!mAlarmProgramButton->isOn() && !mAlarmSoundButton->isOn()) { + mAlarmSoundButton->setOn( true ); + if ( mAlarmSound.isEmpty() ) + mAlarmSound = KOPrefs::instance()->mDefaultAlarmFile; + else { + if ( ! QFile::exists( mAlarmSound ) ) + mAlarmSound = KOPrefs::instance()->mDefaultAlarmFile; + } + } + if (mAlarmProgramButton->isOn()) + ((QWidget*)parent())->topLevelWidget()->setCaption(i18n("Proc.Al.: ") + mAlarmProgram ); + if (!mAlarmSound.isEmpty() && mAlarmSoundButton->isOn()) + ((QWidget*)parent())->topLevelWidget()->setCaption(i18n("Sound.Al.: ") + mAlarmSound ); + } + else { + ((QWidget*)parent())->topLevelWidget()->setCaption(i18n("Alarm disabled")); + + } + mAlarmTimeEdit->setEnabled(enable); + mAlarmSoundButton->setEnabled(enable); + mAlarmProgramButton->setEnabled(enable); + mAlarmIncrCombo->setEnabled(enable); +} + +void KOEditorGeneral::disableAlarmEdit(bool disable) +{ + enableAlarmEdit( !disable ); +} + +void KOEditorGeneral::enableAlarm( bool enable ) +{ + enableAlarmEdit( enable ); +} + +void KOEditorGeneral::alarmDisable(bool disable) +{ + if (!disable) { + //mAlarmBell->setEnabled(true); + mAlarmButton->setEnabled(true); + } else { + //mAlarmBell->setEnabled(false); + mAlarmButton->setEnabled(false); + mAlarmButton->setChecked(false); + mAlarmTimeEdit->setEnabled(false); + mAlarmSoundButton->setEnabled(false); + mAlarmProgramButton->setEnabled(false); + mAlarmIncrCombo->setEnabled(false); + } +} + +void KOEditorGeneral::setCategories(const QString &str) +{ + mCategoriesLabel->setText(str); +} + +void KOEditorGeneral::setDefaults(bool allDay) +{ +#if 0 + mOwnerLabel->setText(i18n("Owner: ") + KOPrefs::instance()->fullName()); +#endif + + enableAlarmEdit( !allDay ); + + // TODO: Implement a KPrefsComboItem to solve this in a clean way. + int alarmTime; + int a[] = { 1,5,10,15,30,60,180, 1440 }; + int index = KOPrefs::instance()->mAlarmTime; + if (index < 0 || index > 7) { + alarmTime = 15; + } else { + alarmTime = a[index]; + } + mAlarmButton ->setChecked( false ); + mAlarmTimeEdit->setValue(alarmTime); + mAlarmIncrCombo->setCurrentItem(0); + enableAlarmEdit( false ); + //alarmDisable (false); + mSecrecyCombo->setCurrentItem(Incidence::SecrecyPublic); + mCancelBox->setChecked( false ); + mSummaryEdit->setEditText(""); + mLocationEdit->setEditText(""); + mDescriptionEdit->setText(""); + mAlarmSound = KOPrefs::instance()->mDefaultAlarmFile; + setCategories(""); +} +void KOEditorGeneral::setSecrecy( int num ) +{ + mSecrecyCombo->setCurrentItem(num); +} +void KOEditorGeneral::readIncidence(Incidence *event) +{ + + mAlarmIncrCombo->setCurrentItem(0); + mSummaryEdit->setEditText(event->summary()); + mLocationEdit->setEditText(event->location()); + mDescriptionEdit->setText(event->description()); + +#if 0 + // organizer information + mOwnerLabel->setText(i18n("Owner: ") + event->organizer()); +#endif + + enableAlarmEdit( event->isAlarmEnabled() ); + //qDebug("KOEditorGeneral::readIncidence(Incidence *event) "); + if(!event->isAlarmEnabled()) { + // TODO: Implement a KPrefsComboItem to solve this in a clean way. + int alarmTime; + int a[] = { 1,5,10,15,30,60,180, 1440 }; + int index = KOPrefs::instance()->mAlarmTime; + if (index < 0 || index > 7) { + alarmTime = 15; + } else { + alarmTime = a[index]; + } + mAlarmTimeEdit->setValue(alarmTime); + } + mAlarmButton->setChecked( event->isAlarmEnabled() ); + mSecrecyCombo->setCurrentItem(event->secrecy()); + mCancelBox->setChecked( event->cancelled() ); + mAlarmProgramButton->setOn(false); + mAlarmSoundButton->setOn(false); + + // set up alarm stuff + QPtrList<Alarm> alarms = event->alarms(); + Alarm* alarm; + mAlarmIncrCombo->setCurrentItem(0); + for ( alarm = alarms.first(); alarm; alarm = alarms.next() ) { + int offset; + if ( alarm->hasTime() ) { + QDateTime t = alarm->time(); + offset = event->dtStart().secsTo( t ); + } else { + offset = alarm->startOffset().asSeconds(); + } + if ( offset != 0 ) { + offset = offset / -60; // make minutes + if (offset % 60 == 0) { // divides evenly into hours? + offset = offset / 60; + mAlarmIncrCombo->setCurrentItem(1); + if (offset % 24 == 0) { // divides evenly into days? + offset = offset / 24; + mAlarmIncrCombo->setCurrentItem(2); + } + } + } + mAlarmTimeEdit->setValue( offset ); + if (alarm->type() == Alarm::Procedure) { + + mAlarmProgram = alarm->programFile(); + mAlarmProgramButton->setOn(true); + QString dispStr = i18n("Running '%1'").arg(mAlarmProgram); + QToolTip::add(mAlarmProgramButton, dispStr); + } + else if (alarm->type() == Alarm::Audio) { + mAlarmSound = alarm->audioFile(); + if ( ! QFile::exists( mAlarmSound ) ) + mAlarmSound = KOPrefs::instance()->mDefaultAlarmFile; + mAlarmSoundButton->setOn(true); + QString dispStr = i18n("Playing '%1'").arg(mAlarmSound); + QToolTip::add(mAlarmSoundButton, dispStr); + } + mAlarmButton->setChecked(alarm->enabled()); + enableAlarmEdit( alarm->enabled() ); + //qDebug("nableAlarmEdit( alarm->enabled() )********* "); + // TODO: Deal with multiple alarms + break; // For now, stop after the first alarm + } + + setCategories(event->categoriesStr()); +} + +void KOEditorGeneral::writeIncidence(Incidence *event) +{ + // kdDebug() << "KOEditorGeneral::writeEvent()" << endl; + mLocationEdit->save(KOLocationBox::LOCATION); + event->setSummary(mSummaryEdit->currentText()); + event->setLocation(mLocationEdit->currentText()); + event->setDescription(mDescriptionEdit->text()); + event->setCategories(mCategoriesLabel->text()); + event->setSecrecy(mSecrecyCombo->currentItem()); + event->setCancelled(mCancelBox->isChecked() );; + // alarm stuff + if (mAlarmButton->isChecked()) { + if (event->alarms().count() == 0) + event->newAlarm(); + QPtrList<Alarm> alarms = event->alarms(); + Alarm *alarm; + for (alarm = alarms.first(); alarm; alarm = alarms.next() ) { + alarm->setEnabled(true); + int j = mAlarmTimeEdit->value()* -60; + if (mAlarmIncrCombo->currentItem() == 1) + j = j * 60; + else if (mAlarmIncrCombo->currentItem() == 2) + j = j * (60 * 24); + alarm->setStartOffset( j ); + + if (!mAlarmProgram.isEmpty() && mAlarmProgramButton->isOn()) { + alarm->setProcedureAlarm(mAlarmProgram); + } + else if (!mAlarmSound.isEmpty() && mAlarmSoundButton->isOn()) + alarm->setAudioAlarm(mAlarmSound); + else + alarm->setType(Alarm::Invalid); + //alarm->setAudioAlarm("default"); + // TODO: Deal with multiple alarms + break; // For now, stop after the first alarm + } + } else { + Alarm* alarm = event->alarms().first(); + if ( alarm ) { + alarm->setEnabled(false); + alarm->setType(Alarm::Invalid); + } + } +} diff --git a/korganizer/koeditorgeneral.h b/korganizer/koeditorgeneral.h new file mode 100644 index 0000000..c58335e --- a/dev/null +++ b/korganizer/koeditorgeneral.h @@ -0,0 +1,112 @@ +/* + 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 KOEDITORGENERAL_H +#define KOEDITORGENERAL_H + +#include <qframe.h> +#include <qlabel.h> +#include <qcheckbox.h> +#include <qpushbutton.h> +#include <qgroupbox.h> +#include <qlineedit.h> +#include <qcombobox.h> +#include <qlistview.h> +#include <qradiobutton.h> +#include <qlayout.h> +#include <qspinbox.h> + +#include <ktextedit.h> +#include <krestrictedline.h> + +#include <libkcal/incidence.h> + +#include "ktimeedit.h" + +class KDateEdit; +class KOLocationBox; +using namespace KCal; + +class KOEditorGeneral : public QObject +{ + Q_OBJECT + public: + KOEditorGeneral (QObject* parent=0,const char* name=0); + virtual ~KOEditorGeneral(); + void setFocusOn( int i ); + void initHeader(QWidget *,QBoxLayout *); + void initDescription(QWidget *,QBoxLayout *); + void initSecrecy(QWidget *,QBoxLayout *); + void initCategories(QWidget *,QBoxLayout *); + void initAlarm(QWidget *,QBoxLayout *); + + /** Set widgets to default values */ + void setDefaults(bool allDay); + /** Read event object and setup widgets accordingly */ + void readIncidence(Incidence *); + /** Write event settings to event object */ + void writeIncidence(Incidence *); + + /** Check if the input is valid. */ + bool validateInput() { return true; } + + void enableAlarm( bool enable ); + void setSecrecy( int num ); + public slots: + void setCategories(const QString &); + void editCategories(); + + protected slots: + void enableAlarmEdit( bool enable ); + void disableAlarmEdit( bool disable ); + void alarmDisable( bool disable ); + void pickAlarmSound(); + void pickAlarmProgram(); + + signals: + void openCategoryDialog(); + void allAccepted(); + + protected: + //QLineEdit *mSummaryEdit; + //QLineEdit *mLocationEdit; + KOLocationBox *mSummaryEdit; + KOLocationBox *mLocationEdit; + QLabel *mAlarmBell; + QCheckBox *mAlarmButton; + QSpinBox *mAlarmTimeEdit; + QPushButton *mAlarmSoundButton; + QPushButton *mAlarmProgramButton; + QComboBox *mAlarmIncrCombo; + KTextEdit *mDescriptionEdit; + QLabel *mOwnerLabel; + QComboBox *mSecrecyCombo; + QCheckBox *mCancelBox; + QPushButton *mCategoriesButton; + QLabel *mCategoriesLabel; + + private: + QString mAlarmSound; + QString mAlarmProgram; +}; + +#endif diff --git a/korganizer/koeditorgeneral.moc b/korganizer/koeditorgeneral.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/koeditorgeneral.moc diff --git a/korganizer/koeditorgeneralevent.cpp b/korganizer/koeditorgeneralevent.cpp new file mode 100644 index 0000000..9b93e7e --- a/dev/null +++ b/korganizer/koeditorgeneralevent.cpp @@ -0,0 +1,443 @@ +/* + 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. +*/ + +#include <qtooltip.h> +#include <qlayout.h> +#include <qvbox.h> +#include <qbuttongroup.h> +#include <qvgroupbox.h> +#include <qwidgetstack.h> +#include <qdatetime.h> + +#include <kdebug.h> +#include <kglobal.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <kfiledialog.h> +#include <kstandarddirs.h> + +#include <libkcal/event.h> + +#include <libkdepim/kdateedit.h> + +#include "koprefs.h" + +#include "koeditorgeneralevent.h" +#include "kolocationbox.h" +#include "koeditorgeneralevent.moc" + +KOEditorGeneralEvent::KOEditorGeneralEvent(QObject* parent, + const char* name) : + KOEditorGeneral( parent, name) +{ + connect(this,SIGNAL(dateTimesChanged(QDateTime,QDateTime)), + SLOT(setDuration())); + connect(this,SIGNAL(dateTimesChanged(QDateTime,QDateTime)), + SLOT(emitDateTimeStr())); +} + +KOEditorGeneralEvent::~KOEditorGeneralEvent() +{ +} + +void KOEditorGeneralEvent::finishSetup() +{ + + //disabled +// QWidget::setTabOrder( mSummaryEdit, mLocationEdit ); +// QWidget::setTabOrder( mLocationEdit, mStartDateEdit ); +// QWidget::setTabOrder( mStartDateEdit, mStartTimeEdit ); +// QWidget::setTabOrder( mStartTimeEdit, mEndDateEdit ); +// QWidget::setTabOrder( mEndDateEdit, mEndTimeEdit ); +// QWidget::setTabOrder( mEndTimeEdit, mNoTimeButton ); +// QWidget::setTabOrder( mNoTimeButton, mAlarmButton ); +// QWidget::setTabOrder( mAlarmButton, mAlarmTimeEdit ); +// QWidget::setTabOrder( mFreeTimeCombo, mCategoriesButton ); +// QWidget::setTabOrder( mCategoriesButton, mSecrecyCombo ); +// QWidget::setTabOrder( mSecrecyCombo, mDescriptionEdit ); + + + + mSummaryEdit->load(KOLocationBox::SUMMARYEVENT); + mSummaryEdit->setFocus(); +} + +void KOEditorGeneralEvent::initTime(QWidget *parent,QBoxLayout *topLayout) +{ + QBoxLayout *timeLayout = new QVBoxLayout(topLayout); + + QGroupBox *timeGroupBox = new QGroupBox(1,QGroupBox::Horizontal, + i18n("Date && Time"),parent); + timeLayout->addWidget(timeGroupBox); + + timeGroupBox->layout()->setSpacing( 0 ); + timeGroupBox->layout()->setMargin( 5 ); + QFrame *timeBoxFrame = new QFrame(timeGroupBox); + + QGridLayout *layoutTimeBox = new QGridLayout(timeBoxFrame,2,3); + layoutTimeBox->setSpacing(topLayout->spacing()); + + mStartDateLabel = new QLabel(i18n("Start:"),timeBoxFrame); + layoutTimeBox->addWidget(mStartDateLabel,0,0); + + mStartDateEdit = new KDateEdit(timeBoxFrame); + layoutTimeBox->addWidget(mStartDateEdit,0,1); + + mStartTimeEdit = new KOTimeEdit(timeBoxFrame); + layoutTimeBox->addWidget(mStartTimeEdit,0,2); + + + mEndDateLabel = new QLabel(i18n("End:"),timeBoxFrame); + layoutTimeBox->addWidget(mEndDateLabel,1,0); + + mEndDateEdit = new KDateEdit(timeBoxFrame); + layoutTimeBox->addWidget(mEndDateEdit,1,1); + + mEndTimeEdit = new KOTimeEdit(timeBoxFrame); + layoutTimeBox->addWidget(mEndTimeEdit,1,2); + QWidget* duration = new QWidget( timeBoxFrame ); + QHBoxLayout *flagsBox = new QHBoxLayout( duration ); + mNoTimeButton = new QCheckBox(i18n("Allday"),duration); + flagsBox->addWidget(mNoTimeButton); + connect(mNoTimeButton, SIGNAL(toggled(bool)),SLOT(dontAssociateTime(bool))); + mDurationLabel = new QLabel( duration ); + // if ( KOPrefs::instance()->mCompactDialogs ) { + //layoutTimeBox->addMultiCellWidget( mDurationLabel, 3, 3, 0, 3 ); + //} else { + flagsBox->addWidget( mDurationLabel ); + //} + flagsBox->setStretchFactor(mDurationLabel, 10 ); + mDurationLabel->setAlignment( AlignRight | AlignVCenter); + layoutTimeBox->addMultiCellWidget( duration, 2, 2, 0, 3 ); + + // time widgets are checked if they contain a valid time + connect(mStartTimeEdit, SIGNAL(timeChanged(QTime)), + this, SLOT(startTimeChanged(QTime))); + connect(mEndTimeEdit, SIGNAL(timeChanged(QTime)), + this, SLOT(endTimeChanged(QTime))); + + // date widgets are checked if they contain a valid date + connect(mStartDateEdit, SIGNAL(dateChanged(QDate)), + this, SLOT(startDateChanged(QDate))); + connect(mEndDateEdit, SIGNAL(dateChanged(QDate)), + this, SLOT(endDateChanged(QDate))); +} + +void KOEditorGeneralEvent::initClass(QWidget *parent,QBoxLayout *topLayout) +{ + QBoxLayout *classLayout = new QHBoxLayout(topLayout); + + QLabel *freeTimeLabel = new QLabel(i18n("Show time as:"),parent); + classLayout->addWidget(freeTimeLabel); + + mFreeTimeCombo = new QComboBox(false, parent); + mFreeTimeCombo->insertItem(i18n("Busy")); + mFreeTimeCombo->insertItem(i18n("Free")); + classLayout->addWidget(mFreeTimeCombo); +} + +void KOEditorGeneralEvent::timeStuffDisable(bool disable) +{ + mStartTimeEdit->setEnabled( !disable ); + mEndTimeEdit->setEnabled( !disable ); + + setDuration(); + emitDateTimeStr(); +} + +void KOEditorGeneralEvent::dontAssociateTime(bool noTime) +{ + timeStuffDisable(noTime); + //if(alarmButton->isChecked()) alarmStuffDisable(noTime); + allDayChanged(noTime); +} + +void KOEditorGeneralEvent::setDateTimes(QDateTime start, QDateTime end) +{ +// kdDebug() << "KOEditorGeneralEvent::setDateTimes(): Start DateTime: " << start.toString() << endl; + + mStartDateEdit->setDate(start.date()); + // KTimeEdit seems to emit some signals when setTime() is called. + mStartTimeEdit->blockSignals( true ); + mStartTimeEdit->setTime(start.time()); + mStartTimeEdit->blockSignals( false ); + mEndDateEdit->setDate(end.date()); + mEndTimeEdit->setTime(end.time()); + + mCurrStartDateTime = start; + mCurrEndDateTime = end; + + setDuration(); + emitDateTimeStr(); +} + +void KOEditorGeneralEvent::startTimeChanged(QTime newtime) +{ + kdDebug() << "KOEditorGeneralEvent::startTimeChanged() " << newtime.toString() << endl; + + int secsep = mCurrStartDateTime.secsTo(mCurrEndDateTime); + + mCurrStartDateTime.setTime(newtime); + + // adjust end time so that the event has the same duration as before. + mCurrEndDateTime = mCurrStartDateTime.addSecs(secsep); + mEndTimeEdit->setTime(mCurrEndDateTime.time()); + mEndDateEdit->setDate(mCurrEndDateTime.date()); + + emit dateTimesChanged(mCurrStartDateTime,mCurrEndDateTime); +} + +void KOEditorGeneralEvent::endTimeChanged(QTime newtime) +{ +// kdDebug() << "KOEditorGeneralEvent::endTimeChanged " << newtime.toString() << endl; + + QDateTime newdt(mCurrEndDateTime.date(), newtime); + mCurrEndDateTime = newdt; + + emit dateTimesChanged(mCurrStartDateTime,mCurrEndDateTime); +} + +void KOEditorGeneralEvent::startDateChanged(QDate newdate) +{ + int daysep = mCurrStartDateTime.daysTo(mCurrEndDateTime); + + mCurrStartDateTime.setDate(newdate); + + // adjust end date so that the event has the same duration as before + mCurrEndDateTime.setDate(mCurrStartDateTime.date().addDays(daysep)); + mEndDateEdit->setDate(mCurrEndDateTime.date()); + + emit dateTimesChanged(mCurrStartDateTime,mCurrEndDateTime); +} + +void KOEditorGeneralEvent::endDateChanged(QDate newdate) +{ + QDateTime newdt(newdate, mCurrEndDateTime.time()); + + if(newdt < mCurrStartDateTime) { + // oops, we can't let that happen. + newdt = mCurrStartDateTime; + mEndDateEdit->setDate(newdt.date()); + mEndTimeEdit->setTime(newdt.time()); + } + mCurrEndDateTime = newdt; + + emit dateTimesChanged(mCurrStartDateTime,mCurrEndDateTime); +} + +void KOEditorGeneralEvent::setDefaults(QDateTime from,QDateTime to,bool allDay) +{ + mSummaryEdit->load(KOLocationBox::SUMMARYEVENT); + mLocationEdit->load(KOLocationBox::LOCATION); + KOEditorGeneral::setDefaults(allDay); + + mNoTimeButton->setChecked(allDay); + timeStuffDisable(allDay); + mFreeTimeCombo->setCurrentItem( 0 ); + setDateTimes(from,to); +} + +void KOEditorGeneralEvent::readEvent( Event *event, bool tmpl ) +{ + QString tmpStr; + + if ( !tmpl ) { + // the rest is for the events only + mNoTimeButton->setChecked(event->doesFloat()); + timeStuffDisable(event->doesFloat()); + + setDateTimes(event->dtStart(),event->dtEnd()); + } + + switch( event->transparency() ) { + case Event::Transparent: + mFreeTimeCombo->setCurrentItem(1); + break; + case Event::Opaque: + mFreeTimeCombo->setCurrentItem(0); + break; + } + + mSummaryEdit->load(KOLocationBox::SUMMARYEVENT); + mLocationEdit->load(KOLocationBox::LOCATION); + readIncidence(event); +} + +void KOEditorGeneralEvent::writeEvent(Event *event) +{ +// kdDebug() << "KOEditorGeneralEvent::writeEvent()" << endl; + + writeIncidence(event); + + QDate tmpDate; + QTime tmpTime; + QDateTime tmpDT; + + // temp. until something better happens. + QString tmpStr; + + if (mNoTimeButton->isChecked()) { + event->setFloats(true); + // need to change this. + tmpDate = mStartDateEdit->date(); + tmpTime.setHMS(0,0,0); + tmpDT.setDate(tmpDate); + tmpDT.setTime(tmpTime); + event->setDtStart(tmpDT); + + tmpDate = mEndDateEdit->date(); + tmpTime.setHMS(0,0,0); + tmpDT.setDate(tmpDate); + tmpDT.setTime(tmpTime); + event->setDtEnd(tmpDT); + } else { + event->setFloats(false); + + // set date/time end + tmpDate = mEndDateEdit->date(); + tmpTime = mEndTimeEdit->getTime(); + tmpDT.setDate(tmpDate); + tmpDT.setTime(tmpTime); + event->setDtEnd(tmpDT); + + // set date/time start + tmpDate = mStartDateEdit->date(); + tmpTime = mStartTimeEdit->getTime(); + tmpDT.setDate(tmpDate); + tmpDT.setTime(tmpTime); + event->setDtStart(tmpDT); + } // check for float + mSummaryEdit->save(KOLocationBox::SUMMARYEVENT); + + event->setTransparency(mFreeTimeCombo->currentItem() > 0 + ? KCal::Event::Transparent + : KCal::Event::Opaque); + +// kdDebug() << "KOEditorGeneralEvent::writeEvent() done" << endl; +} + +void KOEditorGeneralEvent::setDuration() +{ + QString tmpStr = "", catStr; + int hourdiff, minutediff; + // end<date is an accepted temporary state while typing, but don't show + // any duration if this happens + if(mCurrEndDateTime >= mCurrStartDateTime) { + + if (mNoTimeButton->isChecked()) { + int daydiff = mCurrStartDateTime.date().daysTo(mCurrEndDateTime.date()) + 1; + tmpStr = i18n("Duration: "); + tmpStr.append(i18n("1 Day","%n Days",daydiff)); + } else { + int secto = mCurrStartDateTime.secsTo( mCurrEndDateTime ); + hourdiff = secto / 3600; + minutediff = (secto/60 ) % 60; + if (hourdiff || minutediff){ + tmpStr = i18n("Duration: "); + if (hourdiff){ + catStr = i18n("1 h","%n h",hourdiff); + tmpStr.append(catStr); + } + if (hourdiff && minutediff){ + tmpStr += i18n(", "); + } + if (minutediff){ + catStr = i18n("1 min","%n min",minutediff); + tmpStr += catStr; + } + } else tmpStr = ""; + } + } + mDurationLabel->setText(tmpStr); +} + +void KOEditorGeneralEvent::emitDateTimeStr() +{ + KLocale *l = KGlobal::locale(); + + QString from,to; + if (mNoTimeButton->isChecked()) { + from = l->formatDate(mCurrStartDateTime.date()); + to = l->formatDate(mCurrEndDateTime.date()); + } else { + from = l->formatDateTime(mCurrStartDateTime); + to = l->formatDateTime(mCurrEndDateTime); + } + + QString str = i18n("From: %1 To: %2 %3").arg(from).arg(to) + .arg(mDurationLabel->text()); + + emit dateTimeStrChanged(str); +} + +bool KOEditorGeneralEvent::validateInput() +{ +// kdDebug() << "KOEditorGeneralEvent::validateInput()" << endl; + + if (!mNoTimeButton->isChecked()) { + if (!mStartTimeEdit->inputIsValid()) { + KMessageBox::sorry( 0, + i18n("Please specify a valid start time, for example '%1'.") + .arg( KGlobal::locale()->formatTime( QTime::currentTime() ) ) ); + return false; + } + + if (!mEndTimeEdit->inputIsValid()) { + KMessageBox::sorry( 0, + i18n("Please specify a valid end time, for example '%1'.") + .arg( KGlobal::locale()->formatTime( QTime::currentTime() ) ) ); + return false; + } + } + + if (!mStartDateEdit->inputIsValid()) { + KMessageBox::sorry( 0, + i18n("Please specify a valid start date, for example '%1'.") + .arg( KGlobal::locale()->formatDate( QDate::currentDate() ) ) ); + return false; + } + + if (!mEndDateEdit->inputIsValid()) { + KMessageBox::sorry( 0, + i18n("Please specify a valid end date, for example '%1'.") + .arg( KGlobal::locale()->formatDate( QDate::currentDate() ) ) ); + return false; + } + + QDateTime startDt,endDt; + startDt.setDate(mStartDateEdit->date()); + endDt.setDate(mEndDateEdit->date()); + if (!mNoTimeButton->isChecked()) { + startDt.setTime(mStartTimeEdit->getTime()); + endDt.setTime(mEndTimeEdit->getTime()); + } + + if (startDt > endDt) { + KMessageBox::sorry(0,i18n("The event ends before it starts.\n" + "Please correct dates and times.")); + return false; + } + + return KOEditorGeneral::validateInput(); +} diff --git a/korganizer/koeditorgeneralevent.h b/korganizer/koeditorgeneralevent.h new file mode 100644 index 0000000..188dc93 --- a/dev/null +++ b/korganizer/koeditorgeneralevent.h @@ -0,0 +1,108 @@ +/* + 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 _KOEDITORGENERALEVENT_H +#define _KOEDITORGENERALEVENT_H + +#include <qframe.h> +#include <qlabel.h> +#include <qcheckbox.h> +#include <qpushbutton.h> +#include <qgroupbox.h> +#include <qlineedit.h> +#include <qcombobox.h> +#include <qmultilineedit.h> +#include <qlistview.h> +#include <qradiobutton.h> + +#include <krestrictedline.h> + +#include "koeditorgeneral.h" + +#include "ktimeedit.h" + +class KDateEdit; + +using namespace KCal; + +class KOEditorGeneralEvent : public KOEditorGeneral +{ + Q_OBJECT + public: + KOEditorGeneralEvent (QObject* parent=0,const char* name=0); + virtual ~KOEditorGeneralEvent(); + + void initTime(QWidget *,QBoxLayout *); + void initClass(QWidget *,QBoxLayout *); + + void finishSetup(); + + /** Set widgets to default values */ + void setDefaults(QDateTime from,QDateTime to,bool allDay); + /** + Read event object and setup widgets accordingly. If templ is true, the + event is read as template, i.e. the time and date information isn't set. + */ + void readEvent( Event *, bool tmpl = false ); + /** Write event settings to event object */ + void writeEvent(Event *); + + /** Check if the input is valid. */ + bool validateInput(); + + public slots: + void setDateTimes(QDateTime start, QDateTime end); + void setDuration(); + + protected slots: + void timeStuffDisable(bool disable); + void dontAssociateTime(bool noTime); + + void startTimeChanged(QTime); + void startDateChanged(QDate); + void endTimeChanged(QTime); + void endDateChanged(QDate); + + void emitDateTimeStr(); + + signals: + void dateTimesChanged(QDateTime start,QDateTime end); + void allDayChanged(bool); + void dateTimeStrChanged(const QString &); + + private: + QLabel *mStartDateLabel; + QLabel *mEndDateLabel; + KDateEdit *mStartDateEdit; + KDateEdit *mEndDateEdit; + KOTimeEdit *mStartTimeEdit; + KOTimeEdit *mEndTimeEdit; + QLabel *mDurationLabel; + QCheckBox *mNoTimeButton; + QComboBox *mFreeTimeCombo; + + // current start and end date and time + QDateTime mCurrStartDateTime; + QDateTime mCurrEndDateTime; +}; + +#endif diff --git a/korganizer/koeditorgeneralevent.moc b/korganizer/koeditorgeneralevent.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/koeditorgeneralevent.moc diff --git a/korganizer/koeditorgeneraltodo.cpp b/korganizer/koeditorgeneraltodo.cpp new file mode 100644 index 0000000..57837bb --- a/dev/null +++ b/korganizer/koeditorgeneraltodo.cpp @@ -0,0 +1,467 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + 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. +*/ + +#include <qtooltip.h> +#include <qfiledialog.h> +#include <qlayout.h> +#include <qvbox.h> +#include <qbuttongroup.h> +#include <qvgroupbox.h> +#include <qwidgetstack.h> +#include <qdatetime.h> + +#include <kglobal.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <kdebug.h> +#include <krestrictedline.h> +#include <kstandarddirs.h> +#include <kfiledialog.h> + +#include <libkcal/todo.h> + +#include <libkdepim/kdateedit.h> + +#include "koprefs.h" +#include "ktimeedit.h" + +#include "koeditorgeneraltodo.h" +#include "kolocationbox.h" +#include "koeditorgeneraltodo.moc" + +KOEditorGeneralTodo::KOEditorGeneralTodo(QObject* parent, + const char* name) + : KOEditorGeneral( parent, name) +{ +} + +KOEditorGeneralTodo::~KOEditorGeneralTodo() +{ +} + +void KOEditorGeneralTodo::finishSetup() +{ + +// QWidget::setTabOrder(mSummaryEdit, mLocationEdit); +// QWidget::setTabOrder(mLocationEdit, mDueCheck); +// QWidget::setTabOrder(mDueCheck, mDueDateEdit); +// QWidget::setTabOrder(mDueDateEdit, mDueTimeEdit); +// QWidget::setTabOrder(mDueTimeEdit, mStartCheck); +// QWidget::setTabOrder(mStartCheck, mStartDateEdit); +// QWidget::setTabOrder(mStartDateEdit, mStartTimeEdit); +// QWidget::setTabOrder(mStartTimeEdit, mTimeButton); +// QWidget::setTabOrder(mTimeButton, mCompletedCombo); +// QWidget::setTabOrder(mCompletedCombo, mPriorityCombo); +// QWidget::setTabOrder(mPriorityCombo, mAlarmButton); +// QWidget::setTabOrder(mAlarmButton, mCategoriesButton); +// QWidget::setTabOrder(mCategoriesButton, mSecrecyCombo); +// QWidget::setTabOrder(mSecrecyCombo, mDescriptionEdit); + mSummaryEdit->load(KOLocationBox::SUMMARYTODO); + mSummaryEdit->setFocus(); +} + +void KOEditorGeneralTodo::initTime(QWidget *parent,QBoxLayout *topLayout) +{ + QBoxLayout *timeLayout = new QVBoxLayout(topLayout); + + QGroupBox *timeGroupBox = new QGroupBox(1,QGroupBox::Horizontal, + i18n("Date && Time"),parent); + timeLayout->addWidget(timeGroupBox); + timeGroupBox->layout()->setSpacing( 0 ); + timeGroupBox->layout()->setMargin( 5 ); + QFrame *timeBoxFrame = new QFrame(timeGroupBox); + + QGridLayout *layoutTimeBox = new QGridLayout(timeBoxFrame,3,3); + layoutTimeBox->setSpacing(topLayout->spacing()); + layoutTimeBox->setColStretch( 1, 1 ); + + mDueCheck = new QCheckBox(i18n("Due:"),timeBoxFrame); + layoutTimeBox->addWidget(mDueCheck,0,0); + connect(mDueCheck,SIGNAL(toggled(bool)),SLOT(enableDueEdit(bool))); + connect(mDueCheck,SIGNAL(toggled(bool)),SLOT(showAlarm())); + + + mDueDateEdit = new KDateEdit(timeBoxFrame); + layoutTimeBox->addWidget(mDueDateEdit,0,1); + + mDueTimeEdit = new KOTimeEdit(timeBoxFrame); + layoutTimeBox->addWidget(mDueTimeEdit,0,2); + + + mStartCheck = new QCheckBox(i18n("Start:"),timeBoxFrame); + layoutTimeBox->addWidget(mStartCheck,1,0); + connect(mStartCheck,SIGNAL(toggled(bool)),SLOT(enableStartEdit(bool))); + + mStartDateEdit = new KDateEdit(timeBoxFrame); + layoutTimeBox->addWidget(mStartDateEdit,1,1); + + mStartTimeEdit = new KOTimeEdit(timeBoxFrame); + layoutTimeBox->addWidget(mStartTimeEdit,1,2); + + + mTimeButton = new QCheckBox(i18n("Time associated"),timeBoxFrame); + layoutTimeBox->addMultiCellWidget(mTimeButton,2,2,0,1); + + connect(mTimeButton,SIGNAL(toggled(bool)),SLOT(enableTimeEdits(bool))); + + // some more layouting + //layoutTimeBox->setColStretch(3,1); +} + + +void KOEditorGeneralTodo::initCompletion(QWidget *parent, QBoxLayout *topLayout) +{ + mCompletedCombo = new QComboBox(parent); + // xgettext:no-c-format + mCompletedCombo->insertItem(i18n(" 0 %")); + // xgettext:no-c-format + mCompletedCombo->insertItem(i18n(" 20 %")); + // xgettext:no-c-format + mCompletedCombo->insertItem(i18n(" 40 %")); + // xgettext:no-c-format + mCompletedCombo->insertItem(i18n(" 60 %")); + // xgettext:no-c-format + mCompletedCombo->insertItem(i18n(" 80 %")); + // xgettext:no-c-format + mCompletedCombo->insertItem(i18n("100 %")); + connect(mCompletedCombo,SIGNAL(activated(int)),SLOT(completedChanged(int))); + topLayout->addWidget(mCompletedCombo); + + mCompletedLabel = new QLabel(i18n("completed"),parent); + topLayout->addWidget(mCompletedLabel); +} + +void KOEditorGeneralTodo::initPriority(QWidget *parent, QBoxLayout *topLayout) +{ + + QHBox* h = new QHBox ( parent ); + topLayout->addWidget( h ); + QLabel *priorityLabel = new QLabel(i18n("Priority:"), h); + // topLayout->addWidget(priorityLabel); + + mPriorityCombo = new QComboBox( h ); + mPriorityCombo->insertItem(i18n("1 (high)")); + mPriorityCombo->insertItem(i18n("2")); + mPriorityCombo->insertItem(i18n("3")); + mPriorityCombo->insertItem(i18n("4")); + mPriorityCombo->insertItem(i18n("5 (low)")); + //topLayout->addWidget(mPriorityCombo); +} + +void KOEditorGeneralTodo::initStatus(QWidget *parent,QBoxLayout *topLayout) +{ + QBoxLayout *statusLayout = new QHBoxLayout(topLayout); + + initCompletion( parent, statusLayout ); + + statusLayout->addStretch( 1 ); + + initPriority( parent, statusLayout ); +} + +void KOEditorGeneralTodo::setDefaults(QDateTime due,bool allDay) +{ + + mSummaryEdit->load(KOLocationBox::SUMMARYTODO); + mLocationEdit->load(KOLocationBox::LOCATION); + KOEditorGeneral::setDefaults(allDay); + + mTimeButton->setChecked( !allDay ); + if(mTimeButton->isChecked()) { + mTimeButton->setEnabled(true); + } + else { + mTimeButton->setEnabled(false); + } + + enableTimeEdits( !allDay ); + + mDueCheck->setChecked(false); + enableDueEdit(false); + + alarmDisable(true); + + mStartCheck->setChecked(false); + enableStartEdit(false); + + mDueDateEdit->setDate(due.date()); + mDueTimeEdit->setTime(due.time()); + + mStartDateEdit->setDate(QDate::currentDate()); + mStartTimeEdit->setTime(QTime::currentTime()); + + mPriorityCombo->setCurrentItem(2); + mCompletedLabel->setText(i18n("completed"));; + mCompletedCombo->setCurrentItem(0); +} + +void KOEditorGeneralTodo::readTodo(Todo *todo) +{ + + mSummaryEdit->load(KOLocationBox::SUMMARYTODO); + mLocationEdit->load(KOLocationBox::LOCATION); + KOEditorGeneral::readIncidence(todo); + + QDateTime dueDT; + + if (todo->hasDueDate()) { + enableAlarmEdit(true); + dueDT = todo->dtDue(); + mDueDateEdit->setDate(todo->dtDue().date()); + mDueTimeEdit->setTime(todo->dtDue().time()); + mDueCheck->setChecked(true); + } else { + alarmDisable(true); + mDueDateEdit->setEnabled(false); + mDueTimeEdit->setEnabled(false); + mDueDateEdit->setDate(QDate::currentDate()); + mDueTimeEdit->setTime(QTime::currentTime()); + mDueCheck->setChecked(false); + } + + if (todo->hasStartDate()) { + mStartDateEdit->setDate(todo->dtStart().date()); + mStartTimeEdit->setTime(todo->dtStart().time()); + mStartCheck->setChecked(true); + } else { + mStartDateEdit->setEnabled(false); + mStartTimeEdit->setEnabled(false); + mStartDateEdit->setDate(QDate::currentDate()); + mStartTimeEdit->setTime(QTime::currentTime()); + mStartCheck->setChecked(false); + } + + mTimeButton->setChecked( !todo->doesFloat() ); + + mCompletedCombo->setCurrentItem(todo->percentComplete() / 20); + if (todo->isCompleted() && todo->hasCompletedDate()) { + mCompleted = todo->completed(); + } + setCompletedDate(); + + mPriorityCombo->setCurrentItem(todo->priority()-1); +} + +void KOEditorGeneralTodo::writeTodo(Todo *todo) +{ + KOEditorGeneral::writeIncidence(todo); + + // temp. until something better happens. + QString tmpStr; + + todo->setHasDueDate(mDueCheck->isChecked()); + todo->setHasStartDate(mStartCheck->isChecked()); + + QDate tmpDate; + QTime tmpTime; + QDateTime tmpDT; + if ( mTimeButton->isChecked() ) { + todo->setFloats(false); + + // set due date/time + tmpDate = mDueDateEdit->date(); + tmpTime = mDueTimeEdit->getTime(); + tmpDT.setDate(tmpDate); + tmpDT.setTime(tmpTime); + todo->setDtDue(tmpDT); + + // set start date/time + tmpDate = mStartDateEdit->date(); + tmpTime = mStartTimeEdit->getTime(); + tmpDT.setDate(tmpDate); + tmpDT.setTime(tmpTime); + todo->setDtStart(tmpDT); + } else { + todo->setFloats(true); + + // need to change this. + tmpDate = mDueDateEdit->date(); + tmpTime.setHMS(0,0,0); + tmpDT.setDate(tmpDate); + tmpDT.setTime(tmpTime); + todo->setDtDue(tmpDT); + + tmpDate = mStartDateEdit->date(); + tmpTime.setHMS(0,0,0); + tmpDT.setDate(tmpDate); + tmpDT.setTime(tmpTime); + todo->setDtStart(tmpDT); + } + + todo->setPriority(mPriorityCombo->currentItem()+1); + + // set completion state + todo->setPercentComplete(mCompletedCombo->currentItem() * 20); + + if (mCompletedCombo->currentItem() == 5 && mCompleted.isValid()) { + todo->setCompleted(mCompleted); + } + mSummaryEdit->save(KOLocationBox::SUMMARYTODO); +} + +void KOEditorGeneralTodo::enableDueEdit(bool enable) +{ + mDueDateEdit->setEnabled( enable ); + + if(mDueCheck->isChecked() || mStartCheck->isChecked()) { + mTimeButton->setEnabled(true); + } + else { + mTimeButton->setEnabled(false); + mTimeButton->setChecked(false); + } + + if (enable) { + mDueTimeEdit->setEnabled( mTimeButton->isChecked() ); + } else { + mDueTimeEdit->setEnabled( false ); + } +} + +void KOEditorGeneralTodo::enableStartEdit( bool enable ) +{ + mStartDateEdit->setEnabled( enable ); + + if(mDueCheck->isChecked() || mStartCheck->isChecked()) { + mTimeButton->setEnabled(true); + } + else { + mTimeButton->setEnabled(false); + mTimeButton->setChecked(false); + } + + if (enable) { + mStartTimeEdit->setEnabled( mTimeButton->isChecked() ); + } else { + mStartTimeEdit->setEnabled( false ); + } +} + +void KOEditorGeneralTodo::enableTimeEdits(bool enable) +{ + if(mStartCheck->isChecked()) { + mStartTimeEdit->setEnabled( enable ); + } + if(mDueCheck->isChecked()) { + mDueTimeEdit->setEnabled( enable ); + } +} + +void KOEditorGeneralTodo::showAlarm() +{ + if ( mDueCheck->isChecked() ) { + alarmDisable(false); + } + else { + alarmDisable(true); + } +} + +bool KOEditorGeneralTodo::validateInput() +{ + if (mDueCheck->isChecked()) { + if (!mDueDateEdit->inputIsValid()) { + KMessageBox::sorry(0,i18n("Please specify a valid due date.")); + return false; + } + if (mTimeButton->isChecked()) { + if (!mDueTimeEdit->inputIsValid()) { + KMessageBox::sorry(0,i18n("Please specify a valid due time.")); + return false; + } + } + } + + if (mStartCheck->isChecked()) { + if (!mStartDateEdit->inputIsValid()) { + KMessageBox::sorry(0,i18n("Please specify a valid start date.")); + return false; + } + if (mTimeButton->isChecked()) { + if (!mStartTimeEdit->inputIsValid()) { + KMessageBox::sorry(0,i18n("Please specify a valid start time.")); + return false; + } + } + } + + if (mStartCheck->isChecked() && mDueCheck->isChecked()) { + QDateTime startDate; + QDateTime dueDate; + startDate.setDate(mStartDateEdit->date()); + dueDate.setDate(mDueDateEdit->date()); + if (mTimeButton->isChecked()) { + startDate.setTime(mStartTimeEdit->getTime()); + dueDate.setTime(mDueTimeEdit->getTime()); + } + if (startDate > dueDate) { + KMessageBox::sorry(0, + i18n("The start date cannot be after the due date.")); + return false; + } + } + + return KOEditorGeneral::validateInput(); +} + +void KOEditorGeneralTodo::completedChanged(int index) +{ + if (index == 5) { + mCompleted = QDateTime::currentDateTime(); + } + setCompletedDate(); +} + +void KOEditorGeneralTodo::setCompletedDate() +{ + if (mCompletedCombo->currentItem() == 5 && mCompleted.isValid()) { + mCompletedLabel->setText(i18n("completed on %1") + .arg(KGlobal::locale()->formatDateTime(mCompleted))); + } else { + mCompletedLabel->setText(i18n("completed")); + } +} + +void KOEditorGeneralTodo::modified (Todo* todo, int modification) +{ + switch (modification) { + case KOGlobals::PRIORITY_MODIFIED: + mPriorityCombo->setCurrentItem(todo->priority()-1); + break; + case KOGlobals::COMPLETION_MODIFIED: + mCompletedCombo->setCurrentItem(todo->percentComplete() / 20); + if (todo->isCompleted() && todo->hasCompletedDate()) { + mCompleted = todo->completed(); + } + setCompletedDate(); + break; + case KOGlobals::CATEGORY_MODIFIED: + setCategories (todo->categoriesStr ()); + break; + case KOGlobals::UNKNOWN_MODIFIED: // fall through + default: + readTodo( todo ); + break; + } +} diff --git a/korganizer/koeditorgeneraltodo.h b/korganizer/koeditorgeneraltodo.h new file mode 100644 index 0000000..f6c30f8 --- a/dev/null +++ b/korganizer/koeditorgeneraltodo.h @@ -0,0 +1,105 @@ +/* + 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 _KOEDITORGENERALTODO_H +#define _KOEDITORGENERALTODO_H + +#include <qframe.h> +#include <qlabel.h> +#include <qcheckbox.h> +#include <qpushbutton.h> +#include <qgroupbox.h> +#include <qlineedit.h> +#include <qcombobox.h> +#include <qmultilineedit.h> +#include <qlistview.h> +#include <qradiobutton.h> + +#include "koeditorgeneral.h" +#include "koglobals.h" + +class KRestrictedLine; + +class KDateEdit; + +using namespace KCal; + +class KOEditorGeneralTodo : public KOEditorGeneral +{ + Q_OBJECT + public: + KOEditorGeneralTodo (QObject* parent=0,const char* name=0); + virtual ~KOEditorGeneralTodo(); + + void initTime(QWidget *, QBoxLayout *); + void initStatus(QWidget *, QBoxLayout *); + void initCompletion(QWidget *, QBoxLayout *); + void initPriority(QWidget *, QBoxLayout *); + + void finishSetup(); + + /** Set widgets to default values */ + void setDefaults(QDateTime due,bool allDay); + /** Read todo object and setup widgets accordingly */ + void readTodo(Todo *); + /** Write todo settings to event object */ + void writeTodo(Todo *); + + /** Check if the input is valid. */ + bool validateInput(); + + /** The todo has been modified externally */ + void modified (Todo*, int); + + signals: + void openCategoryDialog(); + + protected slots: + void completedChanged(int); + + void enableDueEdit( bool enable ); + void enableStartEdit( bool enable ); + void enableTimeEdits( bool enable ); + void showAlarm(); + + protected: + void setCompletedDate(); + + private: + KDateEdit *mStartDateEdit; + KOTimeEdit *mStartTimeEdit; + QCheckBox *mTimeButton; + QCheckBox *mDueCheck; + KDateEdit *mDueDateEdit; + KOTimeEdit *mDueTimeEdit; + QComboBox *mCompletedCombo; + QLabel *mCompletedLabel; + QLabel *mPriorityLabel; + QComboBox *mPriorityCombo; + + QCheckBox *mStartCheck; + + QDateTime mCompleted; +}; + + +#endif diff --git a/korganizer/koeditorgeneraltodo.moc b/korganizer/koeditorgeneraltodo.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/koeditorgeneraltodo.moc diff --git a/korganizer/koeditorrecurrence.cpp b/korganizer/koeditorrecurrence.cpp new file mode 100644 index 0000000..d82172f --- a/dev/null +++ b/korganizer/koeditorrecurrence.cpp @@ -0,0 +1,1117 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000-2003 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. +*/ + +#include <qtooltip.h> +#include <qfiledialog.h> +#include <qlayout.h> +#include <qvbox.h> +#include <qbuttongroup.h> +#include <qvgroupbox.h> +#include <qwidgetstack.h> +#include <qdatetime.h> +#include <qlistbox.h> +#include <qspinbox.h> +#include <qcheckbox.h> +#include <qapplication.h> + +#include <kdialog.h> +#include <kglobal.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kdebug.h> +#include <knumvalidator.h> + +#include <libkcal/event.h> + +#include <libkdepim/kdateedit.h> + +#include "koprefs.h" + +#include "koeditorrecurrence.h" +#include "koeditorrecurrence.moc" + +/////////////////////////// RecurBase /////////////////////////////// + +RecurBase::RecurBase( QWidget *parent, const char *name ) : + QWidget( parent, name ) +{ + mFrequencyEdit = new QSpinBox( 1, 9999, 1, this ); + mFrequencyEdit->setValue( 1 ); +} + +QWidget *RecurBase::frequencyEdit() +{ + return mFrequencyEdit; +} + +void RecurBase::setFrequency( int f ) +{ + if ( f < 1 ) f = 1; + + mFrequencyEdit->setValue( f ); +} + +int RecurBase::frequency() +{ + return mFrequencyEdit->value(); +} + +/////////////////////////// RecurDaily /////////////////////////////// + +RecurDaily::RecurDaily( QWidget *parent, const char *name ) : + RecurBase( parent, name ) +{ + QBoxLayout *topLayout = new QHBoxLayout( this ); + topLayout->setSpacing( KDialog::spacingHint() ); + + QLabel *preLabel = new QLabel( i18n("Recur every"), this ); + topLayout->addWidget( preLabel ); + + topLayout->addWidget( frequencyEdit() ); + + QLabel *postLabel = new QLabel( i18n("day(s)"), this ); + topLayout->addWidget( postLabel ); +} + + +/////////////////////////// RecurWeekly /////////////////////////////// + +RecurWeekly::RecurWeekly( QWidget *parent, const char *name ) : + RecurBase( parent, name ) +{ + QBoxLayout *topLayout = new QVBoxLayout( this ); + topLayout->setSpacing( KDialog::spacingHint() ); + + topLayout->addStretch( 1 ); + + QBoxLayout *weeksLayout = new QHBoxLayout( topLayout ); + + QLabel *preLabel = new QLabel( i18n("Recur every"), this ); + weeksLayout->addWidget( preLabel ); + + weeksLayout->addWidget( frequencyEdit() ); + + QLabel *postLabel = new QLabel( i18n("week(s) on:"), this ); + weeksLayout->addWidget( postLabel ); + + QHBox *dayBox = new QHBox( this ); + topLayout->addWidget( dayBox, 1, AlignVCenter ); + // TODO: Respect start of week setting + for ( int i = 0; i < 7; ++i ) { + QString weekDayName = KGlobal::locale()->weekDayName( i + 1, true ); + if ( KOPrefs::instance()->mCompactDialogs ) { + weekDayName = weekDayName.left( 1 ); + } + mDayBoxes[ i ] = new QCheckBox( weekDayName, dayBox ); + } + + topLayout->addStretch( 1 ); +} + +void RecurWeekly::setDays( const QBitArray &days ) +{ + for ( int i = 0; i < 7; ++i ) { + mDayBoxes[ i ]->setChecked( days.testBit( i ) ); + } +} + +QBitArray RecurWeekly::days() +{ + QBitArray days( 7 ); + + for ( int i = 0; i < 7; ++i ) { + days.setBit( i, mDayBoxes[ i ]->isChecked() ); + } + + return days; +} + +/////////////////////////// RecurMonthly /////////////////////////////// + +RecurMonthly::RecurMonthly( QWidget *parent, const char *name ) : + RecurBase( parent, name ) +{ + QBoxLayout *topLayout = new QVBoxLayout( this ); + topLayout->setSpacing( KDialog::spacingHint() ); + + + QBoxLayout *freqLayout = new QHBoxLayout( topLayout ); + + QLabel *preLabel = new QLabel( i18n("every"), this ); + freqLayout->addWidget( preLabel ); + + freqLayout->addWidget( frequencyEdit() ); + + QLabel *postLabel = new QLabel( i18n("month(s)"), this ); + freqLayout->addWidget( postLabel ); + + + QButtonGroup *buttonGroup = new QButtonGroup( this ); + buttonGroup->setFrameStyle( QFrame::NoFrame ); + topLayout->addWidget( buttonGroup, 1, AlignVCenter ); + + QGridLayout *buttonLayout = new QGridLayout( buttonGroup, 3, 2 ); + buttonLayout->setSpacing( KDialog::spacingHint() ); + + + QString recurOnText; + if ( !KOPrefs::instance()->mCompactDialogs ) { + recurOnText = i18n("Recur on the"); + } + + mByDayRadio = new QRadioButton( recurOnText, buttonGroup ); + buttonLayout->addWidget( mByDayRadio, 0, 0 ); + + mByDayCombo = new QComboBox( buttonGroup ); + mByDayCombo->setSizeLimit( 7 ); + mByDayCombo->insertItem( i18n("1st") ); + mByDayCombo->insertItem( i18n("2nd") ); + mByDayCombo->insertItem( i18n("3rd") ); + mByDayCombo->insertItem( i18n("4th") ); + mByDayCombo->insertItem( i18n("5th") ); + mByDayCombo->insertItem( i18n("6th") ); + mByDayCombo->insertItem( i18n("7th") ); + mByDayCombo->insertItem( i18n("8th") ); + mByDayCombo->insertItem( i18n("9th") ); + mByDayCombo->insertItem( i18n("10th") ); + mByDayCombo->insertItem( i18n("11th") ); + mByDayCombo->insertItem( i18n("12th") ); + mByDayCombo->insertItem( i18n("13th") ); + mByDayCombo->insertItem( i18n("14th") ); + mByDayCombo->insertItem( i18n("15th") ); + mByDayCombo->insertItem( i18n("16th") ); + mByDayCombo->insertItem( i18n("17th") ); + mByDayCombo->insertItem( i18n("18th") ); + mByDayCombo->insertItem( i18n("19th") ); + mByDayCombo->insertItem( i18n("20th") ); + mByDayCombo->insertItem( i18n("21st") ); + mByDayCombo->insertItem( i18n("22nd") ); + mByDayCombo->insertItem( i18n("23rd") ); + mByDayCombo->insertItem( i18n("24th") ); + mByDayCombo->insertItem( i18n("25th") ); + mByDayCombo->insertItem( i18n("26th") ); + mByDayCombo->insertItem( i18n("27th") ); + mByDayCombo->insertItem( i18n("28th") ); + mByDayCombo->insertItem( i18n("29th") ); + mByDayCombo->insertItem( i18n("30th") ); + mByDayCombo->insertItem( i18n("31st") ); + buttonLayout->addWidget( mByDayCombo, 0, 1 ); + + QLabel *byDayLabel = new QLabel( i18n("day"), buttonGroup ); + buttonLayout->addWidget( byDayLabel, 0, 2 ); + + + mByPosRadio = new QRadioButton( recurOnText, buttonGroup); + buttonLayout->addWidget( mByPosRadio, 1, 0 ); + + mByPosCountCombo = new QComboBox( buttonGroup ); + mByPosCountCombo->insertItem( i18n("1st") ); + mByPosCountCombo->insertItem( i18n("2nd") ); + mByPosCountCombo->insertItem( i18n("3rd") ); + mByPosCountCombo->insertItem( i18n("4th") ); + mByPosCountCombo->insertItem( i18n("5th") ); + buttonLayout->addWidget( mByPosCountCombo, 1, 1 ); + + mByPosWeekdayCombo = new QComboBox( buttonGroup ); + mByPosWeekdayCombo->insertItem( i18n("Monday") ); + mByPosWeekdayCombo->insertItem( i18n("Tuesday") ); + mByPosWeekdayCombo->insertItem( i18n("Wednesday") ); + mByPosWeekdayCombo->insertItem( i18n("Thursday") ); + mByPosWeekdayCombo->insertItem( i18n("Friday") ); + mByPosWeekdayCombo->insertItem( i18n("Saturday") ); + mByPosWeekdayCombo->insertItem( i18n("Sunday") ); + buttonLayout->addWidget( mByPosWeekdayCombo, 1, 2 ); +} + +void RecurMonthly::setByDay( int day ) +{ + mByDayRadio->setChecked( true ); + mByDayCombo->setCurrentItem( day ); +} + +void RecurMonthly::setByPos( int count, int weekday ) +{ + mByPosRadio->setChecked( true ); + mByPosCountCombo->setCurrentItem( count ); + mByPosWeekdayCombo->setCurrentItem( weekday ); +} + +bool RecurMonthly::byDay() +{ + return mByDayRadio->isChecked(); +} + +bool RecurMonthly::byPos() +{ + return mByPosRadio->isChecked(); +} + +int RecurMonthly::day() +{ + return mByDayCombo->currentItem() + 1; +} + +int RecurMonthly::count() +{ + return mByPosCountCombo->currentItem() + 1; +} + +int RecurMonthly::weekday() +{ + return mByPosWeekdayCombo->currentItem(); +} + +/////////////////////////// RecurYearly /////////////////////////////// + +RecurYearly::RecurYearly( QWidget *parent, const char *name ) : + RecurBase( parent, name ) +{ + QBoxLayout *topLayout = new QVBoxLayout( this ); + topLayout->setSpacing( KDialog::spacingHint() ); + + + QBoxLayout *freqLayout = new QHBoxLayout( topLayout ); + + QLabel *preLabel = new QLabel( i18n("every"), this ); + freqLayout->addWidget( preLabel ); + + freqLayout->addWidget( frequencyEdit() ); + + QLabel *postLabel = new QLabel( i18n("year(s)"), this ); + freqLayout->addWidget( postLabel ); + + + QButtonGroup *buttonGroup = new QButtonGroup( this ); + buttonGroup->setFrameStyle( QFrame::NoFrame ); + topLayout->addWidget( buttonGroup, 1, AlignVCenter ); + + QGridLayout *buttonLayout = new QGridLayout( buttonGroup, 3, 2 ); + + QString recurInMonthText; + if ( !KOPrefs::instance()->mCompactDialogs ) { + recurInMonthText = i18n("Recur in the month of"); + } + + mByMonthRadio = new QRadioButton( recurInMonthText, buttonGroup); + buttonLayout->addWidget( mByMonthRadio, 0, 0 ); + + mByMonthCombo = new QComboBox( buttonGroup ); + mByMonthCombo->insertItem( i18n("January") ); + mByMonthCombo->insertItem( i18n("February") ); + mByMonthCombo->insertItem( i18n("March") ); + mByMonthCombo->insertItem( i18n("April") ); + mByMonthCombo->insertItem( i18n("May") ); + mByMonthCombo->insertItem( i18n("June") ); + mByMonthCombo->insertItem( i18n("July") ); + mByMonthCombo->insertItem( i18n("August") ); + mByMonthCombo->insertItem( i18n("September") ); + mByMonthCombo->insertItem( i18n("October") ); + mByMonthCombo->insertItem( i18n("November") ); + mByMonthCombo->insertItem( i18n("December") ); + buttonLayout->addWidget( mByMonthCombo, 0, 1 ); + + mByMonthCombo->setSizeLimit( 6 ); + + buttonLayout->setRowStretch( 1, 1 ); + + QString recurOnDayText; + if ( KOPrefs::instance()->mCompactDialogs ) { + recurOnDayText = i18n("This day"); + } else { + recurOnDayText = i18n("Recur on this day"); + } + + mByDayRadio = new QRadioButton( recurOnDayText, buttonGroup); + buttonLayout->addMultiCellWidget( mByDayRadio, 2, 2, 0, 1 ); +} + +void RecurYearly::setByDay() +{ + mByDayRadio->setChecked( true ); +} + +void RecurYearly::setByMonth( int month ) +{ + mByMonthRadio->setChecked( true ); + mByMonthCombo->setCurrentItem( month - 1 ); +} + +bool RecurYearly::byMonth() +{ + return mByMonthRadio->isChecked(); +} + +bool RecurYearly::byDay() +{ + return mByDayRadio->isChecked(); +} + +int RecurYearly::month() +{ + return mByMonthCombo->currentItem() + 1; +} + +//////////////////////////// ExceptionsWidget ////////////////////////// + +ExceptionsWidget::ExceptionsWidget( QWidget *parent, const char *name ) : + QWidget( parent, name ) +{ + QBoxLayout *topLayout = new QVBoxLayout( this ); + + QGroupBox *groupBox = new QGroupBox( 1, Horizontal, i18n("Exceptions"), + this ); + topLayout->addWidget( groupBox ); + + QWidget *box = new QWidget( groupBox ); + + QGridLayout *boxLayout = new QGridLayout( box ); + + mExceptionDateEdit = new KDateEdit( box ); + boxLayout->addWidget( mExceptionDateEdit, 0, 0 ); + + QPushButton *addExceptionButton = new QPushButton( i18n("Add"), box ); + boxLayout->addWidget( addExceptionButton, 1, 0 ); + QPushButton *changeExceptionButton = new QPushButton( i18n("Change"), box ); + boxLayout->addWidget( changeExceptionButton, 2, 0 ); + QPushButton *deleteExceptionButton = new QPushButton( i18n("Delete"), box ); + boxLayout->addWidget( deleteExceptionButton, 3, 0 ); + + mExceptionList = new QListBox( box ); + boxLayout->addMultiCellWidget( mExceptionList, 0, 3, 1, 1 ); + + boxLayout->setRowStretch( 4, 1 ); + boxLayout->setColStretch( 1, 3 ); + + connect( addExceptionButton, SIGNAL( clicked() ), + SLOT( addException() ) ); + connect( changeExceptionButton, SIGNAL( clicked() ), + SLOT( changeException() ) ); + connect( deleteExceptionButton, SIGNAL( clicked() ), + SLOT( deleteException() ) ); + if ( QApplication::desktop()->width() < 480 ) { + setMinimumWidth( 220 ); + } else { + setMinimumWidth( 440 ); + mExceptionDateEdit->setMinimumWidth( 200 ); + } +} + +void ExceptionsWidget::setDefaults( const QDateTime &from ) +{ + mExceptionDateEdit->setDate( from.date() ); +} + +void ExceptionsWidget::addException() +{ + QDate date = mExceptionDateEdit->date(); + QString dateStr = KGlobal::locale()->formatDate( date ); + if( !mExceptionList->findItem( dateStr ) ) { + mExceptionDates.append( date ); + mExceptionList->insertItem( dateStr ); + } +} + +void ExceptionsWidget::changeException() +{ + int pos = mExceptionList->currentItem(); + if ( pos < 0 ) return; + + QDate date = mExceptionDateEdit->date(); + mExceptionDates[ pos ] = date; + mExceptionList->changeItem( KGlobal::locale()->formatDate( date ), pos ); +} + +void ExceptionsWidget::deleteException() +{ + int pos = mExceptionList->currentItem(); + if ( pos < 0 ) return; + + mExceptionDates.remove( mExceptionDates.at( pos ) ); + mExceptionList->removeItem( pos ); +} + +void ExceptionsWidget::setDates( const DateList &dates ) +{ + mExceptionList->clear(); + mExceptionDates.clear(); + DateList::ConstIterator dit; + for ( dit = dates.begin(); dit != dates.end(); ++dit ) { + mExceptionList->insertItem( KGlobal::locale()->formatDate(* dit ) ); + mExceptionDates.append( *dit ); + } +} + +DateList ExceptionsWidget::dates() +{ + return mExceptionDates; +} + +///////////////////////// ExceptionsDialog /////////////////////////// + +ExceptionsDialog::ExceptionsDialog( QWidget *parent, const char *name ) : + KDialogBase( parent, name, true, i18n("Edit exceptions"), Ok|Cancel ) +{ + mExceptions = new ExceptionsWidget( this ); + setMainWidget( mExceptions ); + resize(220,10); +} + +void ExceptionsDialog::setDefaults( const QDateTime &from ) +{ + mExceptions->setDefaults( from ); +} + +void ExceptionsDialog::setDates( const DateList &dates ) +{ + mExceptions->setDates( dates ); +} + +DateList ExceptionsDialog::dates() +{ + return mExceptions->dates(); +} + +///////////////////////// RecurrenceRangeWidget /////////////////////////// + +RecurrenceRangeWidget::RecurrenceRangeWidget( QWidget *parent, + const char *name ) + : QWidget( parent, name ) +{ + QBoxLayout *topLayout = new QVBoxLayout( this ); + + mRangeGroupBox = new QGroupBox( 1, Horizontal, i18n("Recurrence Range"), + this ); + topLayout->addWidget( mRangeGroupBox ); + + QWidget *rangeBox = new QWidget( mRangeGroupBox ); + QVBoxLayout *rangeLayout = new QVBoxLayout( rangeBox ); + rangeLayout->setSpacing( KDialog::spacingHint() ); + + mStartDateLabel = new QLabel( i18n("Begin on:"), rangeBox ); + rangeLayout->addWidget( mStartDateLabel ); + + QButtonGroup *rangeButtonGroup = new QButtonGroup; + + mNoEndDateButton = new QRadioButton( i18n("No ending date"), rangeBox ); + rangeButtonGroup->insert( mNoEndDateButton ); + rangeLayout->addWidget( mNoEndDateButton ); + + QBoxLayout *durationLayout = new QHBoxLayout( rangeLayout ); + durationLayout->setSpacing( KDialog::spacingHint() ); + + mEndDurationButton = new QRadioButton( i18n("End after"), rangeBox ); + rangeButtonGroup->insert( mEndDurationButton ); + durationLayout->addWidget( mEndDurationButton ); + + mEndDurationEdit = new QSpinBox( 1, 9999, 1, rangeBox ); + durationLayout->addWidget( mEndDurationEdit ); + + QLabel *endDurationLabel = new QLabel( i18n("occurrence(s)"), rangeBox ); + durationLayout ->addWidget( endDurationLabel ); + + QBoxLayout *endDateLayout = new QHBoxLayout( rangeLayout ); + endDateLayout->setSpacing( KDialog::spacingHint() ); + + mEndDateButton = new QRadioButton( i18n("End by:"), rangeBox ); + rangeButtonGroup->insert( mEndDateButton ); + endDateLayout->addWidget( mEndDateButton ); + + mEndDateEdit = new KDateEdit( rangeBox ); + endDateLayout->addWidget( mEndDateEdit ); + + endDateLayout->addStretch( 1 ); + + connect( mNoEndDateButton, SIGNAL( toggled( bool ) ), + SLOT( showCurrentRange() ) ); + connect( mEndDurationButton, SIGNAL( toggled( bool ) ), + SLOT( showCurrentRange() ) ); + connect( mEndDateButton, SIGNAL( toggled( bool ) ), + SLOT( showCurrentRange() ) ); +} + +void RecurrenceRangeWidget::setDefaults( const QDateTime &from ) +{ + mNoEndDateButton->setChecked( true ); + + setDateTimes( from ); + mEndDateEdit->setDate( from.date() ); +} + +void RecurrenceRangeWidget::setDuration( int duration ) +{ + if ( duration == -1 ) { + mNoEndDateButton->setChecked( true ); + } else if ( duration == 0 ) { + mEndDateButton->setChecked( true ); + } else { + mEndDurationButton->setChecked( true ); + mEndDurationEdit->setValue( duration ); + } +} + +int RecurrenceRangeWidget::duration() +{ + if ( mNoEndDateButton->isChecked() ) { + return -1; + } else if ( mEndDurationButton->isChecked() ) { + return mEndDurationEdit->value(); + } else { + return 0; + } +} + +void RecurrenceRangeWidget::setEndDate( const QDate &date ) +{ + mEndDateEdit->setDate( date ); +} + +QDate RecurrenceRangeWidget::endDate() +{ + return mEndDateEdit->date(); +} + +void RecurrenceRangeWidget::showCurrentRange() +{ + mEndDurationEdit->setEnabled( mEndDurationButton->isChecked() ); + mEndDateEdit->setEnabled( mEndDateButton->isChecked() ); +} + +void RecurrenceRangeWidget::setDateTimes( const QDateTime &start, + const QDateTime & ) +{ + mStartDateLabel->setText( i18n("Start date: %1") + .arg( KGlobal::locale()->formatDate( start.date() ) ) ); + + if(!mEndDateButton->isChecked()) + mEndDateEdit->setDate( start.date() ); +} + +///////////////////////// RecurrenceRangeDialog /////////////////////////// + +RecurrenceRangeDialog::RecurrenceRangeDialog( QWidget *parent, + const char *name ) : + KDialogBase( parent, name, true, i18n("Edit Recurrence Range"), Ok|Cancel ) +{ + mRecurrenceRangeWidget = new RecurrenceRangeWidget( this ); + setMainWidget( mRecurrenceRangeWidget ); +} + +void RecurrenceRangeDialog::setDefaults( const QDateTime &from ) +{ + mRecurrenceRangeWidget->setDefaults( from ); +} + +void RecurrenceRangeDialog::setDuration( int duration ) +{ + mRecurrenceRangeWidget->setDuration( duration ); +} + +int RecurrenceRangeDialog::duration() +{ + return mRecurrenceRangeWidget->duration(); +} + +void RecurrenceRangeDialog::setEndDate( const QDate &date ) +{ + mRecurrenceRangeWidget->setEndDate( date ); +} + +QDate RecurrenceRangeDialog::endDate() +{ + return mRecurrenceRangeWidget->endDate(); +} + +void RecurrenceRangeDialog::setDateTimes( const QDateTime &start, + const QDateTime &end ) +{ + mRecurrenceRangeWidget->setDateTimes( start, end ); +} + +//////////////////////////// RecurrenceChooser //////////////////////// + +RecurrenceChooser::RecurrenceChooser( QWidget *parent, const char *name ) : + QWidget( parent, name ) +{ + QBoxLayout *topLayout = new QVBoxLayout( this ); + + if ( KOPrefs::instance()->mCompactDialogs ) { + mTypeCombo = new QComboBox( this ); + mTypeCombo->insertItem( i18n("Daily") ); + mTypeCombo->insertItem( i18n("Weekly") ); + mTypeCombo->insertItem( i18n("Monthly") ); + mTypeCombo->insertItem( i18n("Yearly") ); + + topLayout->addWidget( mTypeCombo ); + + connect( mTypeCombo, SIGNAL( activated( int ) ), SLOT( emitChoice() ) ); + } else { + mTypeCombo = 0; + + QButtonGroup *ruleButtonGroup = new QButtonGroup( 1, Horizontal, this ); + ruleButtonGroup->setFrameStyle( QFrame::NoFrame ); + topLayout->addWidget( ruleButtonGroup ); + + mDailyButton = new QRadioButton( i18n("Daily"), ruleButtonGroup ); + mWeeklyButton = new QRadioButton( i18n("Weekly"), ruleButtonGroup ); + mMonthlyButton = new QRadioButton( i18n("Monthly"), ruleButtonGroup ); + mYearlyButton = new QRadioButton( i18n("Yearly"), ruleButtonGroup ); + + connect( mDailyButton, SIGNAL( toggled( bool ) ), + SLOT( emitChoice() ) ); + connect( mWeeklyButton, SIGNAL( toggled( bool ) ), + SLOT( emitChoice() ) ); + connect( mMonthlyButton, SIGNAL( toggled( bool ) ), + SLOT( emitChoice() ) ); + connect( mYearlyButton, SIGNAL( toggled( bool ) ), + SLOT( emitChoice() ) ); + } +} + +int RecurrenceChooser::type() +{ + if ( mTypeCombo ) { + return mTypeCombo->currentItem(); + } else { + if ( mDailyButton->isChecked() ) return Daily; + else if ( mWeeklyButton->isChecked() ) return Weekly; + else if ( mMonthlyButton->isChecked() ) return Monthly; + else return Yearly; + } +} + +void RecurrenceChooser::setType( int type ) +{ + if ( mTypeCombo ) { + mTypeCombo->setCurrentItem( type ); + } else { + switch ( type ) { + case Daily: + mDailyButton->setChecked( true ); + break; + case Weekly: + mWeeklyButton->setChecked( true ); + break; + case Monthly: + mMonthlyButton->setChecked( true ); + break; + case Yearly: + default: + mYearlyButton->setChecked( true ); + break; + } + } +} + +void RecurrenceChooser::emitChoice() +{ + emit chosen ( type() ); +} + +/////////////////////////////// Main Widget ///////////////////////////// + +KOEditorRecurrence::KOEditorRecurrence( QWidget* parent, const char *name ) : + QWidget( parent, name ) +{ + QGridLayout *topLayout = new QGridLayout( this, 2,2 ); + topLayout->setSpacing( KDialog::spacingHint() ); + + mEnabledCheck = new QCheckBox( i18n("Enable Recurrence"), this ); + connect( mEnabledCheck, SIGNAL( toggled( bool ) ), + SLOT( setEnabled( bool ) ) ); + topLayout->addMultiCellWidget( mEnabledCheck, 0, 0, 0, 1 ); + + + mTimeGroupBox = new QGroupBox( 1, Horizontal, i18n("Appointment Time "), + this ); + topLayout->addMultiCellWidget( mTimeGroupBox, 1, 1 , 0 , 1 ); + + if ( KOPrefs::instance()->mCompactDialogs ) { + mTimeGroupBox->hide(); + } + +// QFrame *timeFrame = new QFrame( mTimeGroupBox ); +// QBoxLayout *layoutTimeFrame = new QHBoxLayout( timeFrame ); +// layoutTimeFrame->setSpacing( KDialog::spacingHint() ); + + mDateTimeLabel = new QLabel( mTimeGroupBox ); +// mDateTimeLabel = new QLabel( timeFrame ); +// layoutTimeFrame->addWidget( mDateTimeLabel ); + + Qt::Orientation orientation; + if ( KOPrefs::instance()->mCompactDialogs ) orientation = Horizontal; + else orientation = Vertical; + + mRuleBox = new QGroupBox( 1, orientation, i18n("Recurrence Rule"), this ); + if ( KOPrefs::instance()->mCompactDialogs ) { + topLayout->addMultiCellWidget( mRuleBox, 2, 2, 0, 1 ); + } else { + topLayout->addMultiCellWidget( mRuleBox, 2, 2, 0, 1 ); + } + + mRecurrenceChooser = new RecurrenceChooser( mRuleBox ); + connect( mRecurrenceChooser, SIGNAL( chosen( int ) ), + SLOT( showCurrentRule( int ) ) ); + + if ( !KOPrefs::instance()->mCompactDialogs ) { + QFrame *ruleSepFrame = new QFrame( mRuleBox ); + ruleSepFrame->setFrameStyle( QFrame::VLine | QFrame::Sunken ); + } + + mRuleStack = new QWidgetStack( mRuleBox ); + + mDaily = new RecurDaily( mRuleStack ); + mRuleStack->addWidget( mDaily, 0 ); + + mWeekly = new RecurWeekly( mRuleStack ); + mRuleStack->addWidget( mWeekly, 0 ); + + mMonthly = new RecurMonthly( mRuleStack ); + mRuleStack->addWidget( mMonthly, 0 ); + + mYearly = new RecurYearly( mRuleStack ); + mRuleStack->addWidget( mYearly, 0 ); + + showCurrentRule( mRecurrenceChooser->type() ); + + if ( KOPrefs::instance()->mCompactDialogs ) { + mRecurrenceRangeWidget = 0; + mRecurrenceRangeDialog = new RecurrenceRangeDialog( this ); + mRecurrenceRange = mRecurrenceRangeDialog; + mRecurrenceRangeButton = new QPushButton( i18n("Recurrence Range..."), + this ); + + connect( mRecurrenceRangeButton, SIGNAL( clicked() ), + SLOT( showRecurrenceRangeDialog() ) ); + + mExceptionsWidget = 0; + mExceptionsDialog = new ExceptionsDialog( this ); + mExceptions = mExceptionsDialog; + mExceptionsButton = new QPushButton( i18n("Exceptions..."), this ); + if ( QApplication::desktop()->width() < 320 ) { + topLayout->addMultiCellWidget( mRecurrenceRangeButton, 3, 3, 0, 1 ); + topLayout->addMultiCellWidget( mExceptionsButton, 4, 4, 0, 1 ); + } else { + topLayout->addWidget( mRecurrenceRangeButton, 3, 0 ); + topLayout->addWidget( mExceptionsButton, 3, 1 ); + } + connect( mExceptionsButton, SIGNAL( clicked() ), + SLOT( showExceptionsDialog() ) ); + + } else { + mRecurrenceRangeWidget = new RecurrenceRangeWidget( this ); + mRecurrenceRangeDialog = 0; + mRecurrenceRange = mRecurrenceRangeWidget; + mRecurrenceRangeButton = 0; + topLayout->addWidget( mRecurrenceRangeWidget, 3, 0 ); + + mExceptionsWidget = new ExceptionsWidget( this ); + mExceptionsDialog = 0; + mExceptions = mExceptionsWidget; + mExceptionsButton = 0; + topLayout->addWidget( mExceptionsWidget, 3, 1 ); + } +} + +KOEditorRecurrence::~KOEditorRecurrence() +{ +} + +void KOEditorRecurrence::setEnabled( bool enabled ) +{ +// kdDebug() << "KOEditorRecurrence::setEnabled(): " << (enabled ? "on" : "off") << endl; + + mTimeGroupBox->setEnabled( enabled ); + if ( mRecurrenceRangeWidget ) mRecurrenceRangeWidget->setEnabled( enabled ); + if ( mRecurrenceRangeButton ) mRecurrenceRangeButton->setEnabled( enabled ); + if ( mExceptionsWidget ) mExceptionsWidget->setEnabled( enabled ); + if ( mExceptionsButton ) mExceptionsButton->setEnabled( enabled ); +} + +void KOEditorRecurrence::showCurrentRule( int current ) +{ + switch ( current ) { + case Daily: + mRuleStack->raiseWidget( mDaily ); + break; + case Weekly: + mRuleStack->raiseWidget( mWeekly ); + break; + case Monthly: + mRuleStack->raiseWidget( mMonthly ); + break; + default: + case Yearly: + mRuleStack->raiseWidget( mYearly ); + break; + } +} + +void KOEditorRecurrence::setDateTimes( QDateTime start, QDateTime end ) +{ +// kdDebug() << "KOEditorRecurrence::setDateTimes" << endl; + + mRecurrenceRange->setDateTimes( start, end ); + mExceptions->setDefaults( end ); + +} + +void KOEditorRecurrence::setDefaults( QDateTime from, QDateTime to, bool ) +{ + + // qDebug("KOEditorRecurrence::setDefaults %s %s ",from.toString().latin1(),to.toString().latin1() ); + setDateTimes( from, to ); + + bool enabled = false; + mEnabledCheck->setChecked( enabled ); + setEnabled( enabled ); + + mExceptions->setDefaults( to ); + mRecurrenceRange->setDefaults( to ); + + mRecurrenceChooser->setType( RecurrenceChooser::Weekly ); + showCurrentRule( mRecurrenceChooser->type() ); + + mDaily->setFrequency( 1 ); + + mWeekly->setFrequency( 1 ); + QBitArray days( 7 ); + days.fill( 0 ); + mWeekly->setDays( days ); + + mMonthly->setFrequency( 1 ); + mMonthly->setByDay( from.date().day()-1 ); + + mYearly->setFrequency( 1 ); + mYearly->setByDay(); +} + +void KOEditorRecurrence::readEvent(Event *event) +{ + QBitArray rDays( 7 ); + QPtrList<Recurrence::rMonthPos> rmp; + QPtrList<int> rmd; + int day = 0; + int count = 0; + int month = 0; + setDateTimes( event->dtStart(), event->dtEnd() ); + + Recurrence *r = event->recurrence(); + int f = r->frequency(); + + int recurs = r->doesRecur(); + + mEnabledCheck->setChecked( recurs ); + setEnabled( recurs ); + + int recurrenceType = RecurrenceChooser::Weekly; + + switch ( recurs ) { + case Recurrence::rNone: + setDefaults( event->dtStart(), event->dtEnd(), true ); + break; + case Recurrence::rDaily: + recurrenceType = RecurrenceChooser::Daily; + mDaily->setFrequency( f ); + break; + case Recurrence::rWeekly: + recurrenceType = RecurrenceChooser::Weekly; + mWeekly->setFrequency( f ); + mWeekly->setDays( r->days() ); + break; + case Recurrence::rMonthlyPos: + // we only handle one possibility in the list right now, + // so I have hardcoded calls with first(). If we make the GUI + // more extended, this can be changed. + recurrenceType = RecurrenceChooser::Monthly; + + rmp = r->monthPositions(); + if ( rmp.first()->negative ) + count = 5 - rmp.first()->rPos - 1; + else + count = rmp.first()->rPos - 1; + day = 0; + while ( !rmp.first()->rDays.testBit( day ) ) ++day; + mMonthly->setByPos( count, day ); + + mMonthly->setFrequency( f ); + + break; + case Recurrence::rMonthlyDay: + recurrenceType = RecurrenceChooser::Monthly; + + rmd = r->monthDays(); + day = *rmd.first() - 1; + mMonthly->setByDay( day ); + + mMonthly->setFrequency( f ); + + break; + case Recurrence::rYearlyMonth: + case Recurrence::rYearlyDay: + recurrenceType = RecurrenceChooser::Yearly; + + rmd = r->yearNums(); + month = *rmd.first(); + if ( month == event->dtStart().date().month() ) { + mYearly->setByDay(); + } else { + mYearly->setByMonth( month ); + } + + mYearly->setFrequency( f ); + break; + default: + setDefaults( event->dtStart(), event->dtEnd(), true ); + break; + } + + mRecurrenceChooser->setType( recurrenceType ); + showCurrentRule( recurrenceType ); + + mRecurrenceRange->setDateTimes( event->dtStart() ); + + if ( r->doesRecur() ) { + mRecurrenceRange->setDuration( r->duration() ); + if ( r->duration() == 0 ) + { + if ( r->endDate() < event->dtStart().date() ) + mRecurrenceRange->setEndDate( event->dtStart().date() ); + else + mRecurrenceRange->setEndDate( r->endDate() ); + } else + mRecurrenceRange->setEndDate( event->dtStart().date() ); + } + + mExceptions->setDates( event->exDates() ); +} + +void KOEditorRecurrence::writeEvent( Event *event ) +{ + Recurrence *r = event->recurrence(); + + // clear out any old settings; + r->unsetRecurs(); + + if ( mEnabledCheck->isChecked() ) { + int duration = mRecurrenceRange->duration(); + QDate endDate; + if ( duration == 0 ) endDate = mRecurrenceRange->endDate(); + + int recurrenceType = mRecurrenceChooser->type(); + + if ( recurrenceType == RecurrenceChooser::Daily ) { + int freq = mDaily->frequency(); + if ( duration != 0 ) r->setDaily( freq, duration ); + else r->setDaily( freq, endDate ); + } else if ( recurrenceType == RecurrenceChooser::Weekly ) { + int freq = mWeekly->frequency(); + QBitArray days = mWeekly->days(); + int j; + bool found = false; + for (j = 0; j < 7 ; ++j ) { + found |=days.at(j); + } + if ( !found ) { + days.setBit( event->dtStart().date().dayOfWeek()-1); + qDebug("bit set %d "); + } + if ( duration != 0 ) r->setWeekly( freq, days, duration ); + else r->setWeekly( freq, days, endDate ); + } else if ( recurrenceType == RecurrenceChooser::Monthly ) { + int freq = mMonthly->frequency(); + if ( mMonthly->byPos() ) { + int pos = mMonthly->count(); + + QBitArray days( 7 ); + days.fill( false ); + + days.setBit( mMonthly->weekday() ); + if ( duration != 0 ) + r->setMonthly( Recurrence::rMonthlyPos, freq, duration ); + else + r->setMonthly( Recurrence::rMonthlyPos, freq, endDate ); + r->addMonthlyPos( pos, days ); + } else { + // it's by day + int day = mMonthly->day(); + + if ( duration != 0 ) { + r->setMonthly( Recurrence::rMonthlyDay, freq, duration ); + } else { + r->setMonthly( Recurrence::rMonthlyDay, freq, endDate ); + } + r->addMonthlyDay( day ); + } + } else if ( recurrenceType == RecurrenceChooser::Yearly ) { + int freq = mYearly->frequency(); + + int month; + if ( mYearly->byMonth() ) { + month = mYearly->month(); + } else { + month = event->dtStart().date().month(); + } + if ( duration != 0 ) { + r->setYearly( Recurrence::rYearlyMonth, freq, duration ); + } else { + r->setYearly( Recurrence::rYearlyMonth, freq, endDate ); + } + + r->addYearlyNum( month ); + } + + event->setExDates( mExceptions->dates() ); + } +} + +void KOEditorRecurrence::setDateTimeStr( const QString &str ) +{ + mDateTimeLabel->setText( str ); +} + +bool KOEditorRecurrence::validateInput() +{ + // Check input here + + return true; +} + +void KOEditorRecurrence::showExceptionsDialog() +{ + DateList dates = mExceptions->dates(); + int result = mExceptionsDialog->exec(); + if ( result == QDialog::Rejected ) mExceptions->setDates( dates ); +} + +void KOEditorRecurrence::showRecurrenceRangeDialog() +{ + int duration = mRecurrenceRange->duration(); + QDate endDate = mRecurrenceRange->endDate(); + + int result = mRecurrenceRangeDialog->exec(); + if ( result == QDialog::Rejected ) { + mRecurrenceRange->setDuration( duration ); + mRecurrenceRange->setEndDate( endDate ); + } + +} diff --git a/korganizer/koeditorrecurrence.h b/korganizer/koeditorrecurrence.h new file mode 100644 index 0000000..4f0f0b2 --- a/dev/null +++ b/korganizer/koeditorrecurrence.h @@ -0,0 +1,321 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000-2003 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 _KOEDITORRECURRENCE_H +#define _KOEDITORRECURRENCE_H + +#include <qframe.h> +#include <qlabel.h> +#include <qcheckbox.h> +#include <qpushbutton.h> +#include <qgroupbox.h> +#include <qlineedit.h> +#include <qcombobox.h> +#include <qmultilineedit.h> +#include <qlistview.h> +#include <qradiobutton.h> + +#include <kdialogbase.h> + +#include <libkcal/event.h> + +#include "ktimeedit.h" + +class QWidgetStack; +class QSpinBox; + +class KDateEdit; + +using namespace KCal; + +class RecurBase : public QWidget +{ + public: + RecurBase( QWidget *parent = 0, const char *name = 0 ); + + void setFrequency( int ); + int frequency(); + + QWidget *frequencyEdit(); + + private: + QSpinBox *mFrequencyEdit; +}; + +class RecurDaily : public RecurBase +{ + public: + RecurDaily( QWidget *parent = 0, const char *name = 0 ); +}; + +class RecurWeekly : public RecurBase +{ + public: + RecurWeekly( QWidget *parent = 0, const char *name = 0 ); + + void setDays( const QBitArray & ); + QBitArray days(); + + private: + QCheckBox *mDayBoxes[7]; +}; + +class RecurMonthly : public RecurBase +{ + public: + RecurMonthly( QWidget *parent = 0, const char *name = 0 ); + + void setByDay( int day ); + void setByPos( int count, int weekday ); + + bool byDay(); + bool byPos(); + + int day(); + + int count(); + int weekday(); + + private: + QRadioButton *mByDayRadio; + QComboBox *mByDayCombo; + + QRadioButton *mByPosRadio; + QComboBox *mByPosCountCombo; + QComboBox *mByPosWeekdayCombo; +}; + +class RecurYearly : public RecurBase +{ + public: + RecurYearly( QWidget *parent = 0, const char *name = 0 ); + + void setByDay(); + void setByMonth( int month ); + + bool byMonth(); + bool byDay(); + + int month(); + + private: + QRadioButton *mByMonthRadio; + QComboBox *mByMonthCombo; + + QRadioButton *mByDayRadio; +}; + +class RecurrenceChooser : public QWidget +{ + Q_OBJECT + public: + RecurrenceChooser( QWidget *parent = 0, const char *name = 0 ); + + enum { Daily, Weekly, Monthly, Yearly }; + + void setType( int ); + int type(); + + signals: + void chosen( int ); + + protected slots: + void emitChoice(); + + private: + QComboBox *mTypeCombo; + + QRadioButton *mDailyButton; + QRadioButton *mWeeklyButton; + QRadioButton *mMonthlyButton; + QRadioButton *mYearlyButton; +}; + +class ExceptionsBase +{ + public: + virtual void setDefaults( const QDateTime &from ) = 0; + virtual void setDates( const DateList & ) = 0; + virtual DateList dates() = 0; +}; + +class ExceptionsWidget : public QWidget, public ExceptionsBase +{ + Q_OBJECT + public: + ExceptionsWidget( QWidget *parent = 0, const char *name = 0 ); + + void setDefaults( const QDateTime &from ); + + void setDates( const DateList & ); + DateList dates(); + + protected slots: + void addException(); + void changeException(); + void deleteException(); + + private: + KDateEdit *mExceptionDateEdit; + QListBox *mExceptionList; + DateList mExceptionDates; +}; + +class ExceptionsDialog : public KDialogBase, public ExceptionsBase +{ + public: + ExceptionsDialog( QWidget *parent, const char *name = 0 ); + + void setDefaults( const QDateTime &from ); + + void setDates( const DateList & ); + DateList dates(); + + private: + ExceptionsWidget *mExceptions; +}; + +class RecurrenceRangeBase +{ + public: + virtual void setDefaults( const QDateTime &from ) = 0; + + virtual void setDuration( int ) = 0; + virtual int duration() = 0; + + virtual void setEndDate( const QDate & ) = 0; + virtual QDate endDate() = 0; + + virtual void setDateTimes( const QDateTime &start, + const QDateTime &end = QDateTime() ) = 0; +}; + +class RecurrenceRangeWidget : public QWidget, public RecurrenceRangeBase +{ + Q_OBJECT + public: + RecurrenceRangeWidget( QWidget *parent = 0, const char *name = 0 ); + + void setDefaults( const QDateTime &from ); + + void setDuration( int ); + int duration(); + + void setEndDate( const QDate & ); + QDate endDate(); + + void setDateTimes( const QDateTime &start, + const QDateTime &end = QDateTime() ); + + protected slots: + void showCurrentRange(); + + private: + QGroupBox *mRangeGroupBox; + QLabel *mStartDateLabel; + QRadioButton *mNoEndDateButton; + QRadioButton *mEndDurationButton; + QSpinBox *mEndDurationEdit; + QRadioButton *mEndDateButton; + KDateEdit *mEndDateEdit; +}; + +class RecurrenceRangeDialog : public KDialogBase, public RecurrenceRangeBase +{ + public: + RecurrenceRangeDialog( QWidget *parent = 0, const char *name = 0 ); + + void setDefaults( const QDateTime &from ); + + void setDuration( int ); + int duration(); + + void setEndDate( const QDate & ); + QDate endDate(); + + void setDateTimes( const QDateTime &start, + const QDateTime &end = QDateTime() ); + + private: + RecurrenceRangeWidget *mRecurrenceRangeWidget; +}; + +class KOEditorRecurrence : public QWidget +{ + Q_OBJECT + public: + KOEditorRecurrence ( QWidget *parent = 0, const char *name = 0 ); + virtual ~KOEditorRecurrence(); + + enum { Daily, Weekly, Monthly, Yearly }; + + /** Set widgets to default values */ + void setDefaults( QDateTime from, QDateTime to, bool allday ); + /** Read event object and setup widgets accordingly */ + void readEvent( Event * ); + /** Write event settings to event object */ + void writeEvent( Event * ); + + /** Check if the input is valid. */ + bool validateInput(); + + public slots: + void setEnabled( bool ); + void setDateTimes( QDateTime start, QDateTime end ); + void setDateTimeStr( const QString & ); + + signals: + void dateTimesChanged( QDateTime start, QDateTime end ); + + protected slots: + void showCurrentRule( int ); + void showExceptionsDialog(); + void showRecurrenceRangeDialog(); + + private: + QCheckBox *mEnabledCheck; + + QGroupBox *mTimeGroupBox; + QLabel *mDateTimeLabel; + + QGroupBox *mRuleBox; + QWidgetStack *mRuleStack; + RecurrenceChooser *mRecurrenceChooser; + + RecurDaily *mDaily; + RecurWeekly *mWeekly; + RecurMonthly *mMonthly; + RecurYearly *mYearly; + + RecurrenceRangeBase *mRecurrenceRange; + RecurrenceRangeWidget *mRecurrenceRangeWidget; + RecurrenceRangeDialog *mRecurrenceRangeDialog; + QPushButton *mRecurrenceRangeButton; + + ExceptionsBase *mExceptions; + ExceptionsDialog *mExceptionsDialog; + ExceptionsWidget *mExceptionsWidget; + QPushButton *mExceptionsButton; + +}; + +#endif diff --git a/korganizer/koeditorrecurrence.moc b/korganizer/koeditorrecurrence.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/koeditorrecurrence.moc diff --git a/korganizer/koeventeditor.cpp b/korganizer/koeventeditor.cpp new file mode 100644 index 0000000..b3edec6 --- a/dev/null +++ b/korganizer/koeventeditor.cpp @@ -0,0 +1,378 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2001,2002 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. +*/ + +#include <qtooltip.h> +#include <qframe.h> +#include <qpixmap.h> +#include <qhbox.h> +#include <qdir.h> +#include <qlayout.h> +#include <qwidgetstack.h> +#include <qapplication.h> + +#include <kiconloader.h> +#include <kstandarddirs.h> +#include <kdebug.h> +#include <klocale.h> +#include <kfiledialog.h> +#include <kmessagebox.h> +#include <libkcal/calendarresources.h> +#include <libkcal/resourcecalendar.h> +#include <kresources/resourceselectdialog.h> + +#include <libkdepim/categoryselectdialog.h> +#include <libkcal/calendarlocal.h> +#include <libkcal/icalformat.h> + +#include "koprefs.h" + +#include "koeventeditor.h" +#include "koeventeditor.moc" +extern int globalFlagBlockAgenda; + +KOEventEditor::KOEventEditor( Calendar *calendar, QWidget *parent ) : + KOIncidenceEditor( i18n("Edit Event"), calendar, parent ) +{ + mEvent = 0; + init(); +} + +KOEventEditor::~KOEventEditor() +{ + //emit dialogClose( mEvent ); +} + +void KOEventEditor::init() +{ + + setupGeneral(); + setupAttendeesTab(); + setupRecurrence(); + + // Propagate date time settings to recurrence tab + connect(mGeneral,SIGNAL(dateTimesChanged(QDateTime,QDateTime)), + mRecurrence,SLOT(setDateTimes(QDateTime,QDateTime))); + connect(mGeneral,SIGNAL(dateTimeStrChanged(const QString &)), + mRecurrence,SLOT(setDateTimeStr(const QString &))); + + // Category dialog + // connect(mGeneral,SIGNAL(openCategoryDialog()),mCategoryDialog,SLOT(show())); + //connect(mCategoryDialog,SIGNAL(categoriesSelected(const QString &)), + // mGeneral,SLOT(setCategories(const QString &))); + + +} + +void KOEventEditor::reload() +{ + if ( mEvent ) readEvent( mEvent ); +} + +void KOEventEditor::setSecrecy( int sec ) +{ + mGeneral->setSecrecy( sec ); +} +void KOEventEditor::setCategories( QString s ) +{ + mGeneral->setCategories(s); + +} +void KOEventEditor::setupGeneral() +{ + mGeneral = new KOEditorGeneralEvent( this, "KOEditorGeneralEvent" ); + connect ( mGeneral, SIGNAL ( allAccepted() ), this, SLOT ( slotOk () ) ); + + if( KOPrefs::instance()->mCompactDialogs ) { + QFrame *topFrame = addPage(i18n("General")); + QBoxLayout *topLayout = new QVBoxLayout(topFrame); + topLayout->setSpacing(spacingHint()-1); + topLayout->setMargin(marginHint()-1); + mGeneral->initHeader(topFrame,topLayout); + mGeneral->initTime(topFrame,topLayout); +// QBoxLayout *alarmLineLayout = new QHBoxLayout(topLayout); + mGeneral->initAlarm(topFrame,topLayout); + mGeneral->enableAlarm( false ); + + QBoxLayout *buttonLayout; + if ( QApplication::desktop()->width() < 500 ) + buttonLayout = new QVBoxLayout( topLayout ); + else + buttonLayout = new QHBoxLayout( topLayout ); + QHBox* buttonWidget = new QHBox (topFrame); + QIconSet icon; + if ( QApplication::desktop()->width() < 321 ) + icon = SmallIcon("fileexport16"); + else + icon = SmallIcon("fileexport"); + QPushButton * loadTemplate = new QPushButton( buttonWidget); + QPushButton * saveTemplate = new QPushButton( buttonWidget); + saveTemplate->setIconSet (icon ) ; + int size = saveTemplate->sizeHint().height(); + saveTemplate->setFixedSize( size, size ); + if ( QApplication::desktop()->width() < 321 ) + icon = SmallIcon("fileimport16"); + else + icon = SmallIcon("fileimport"); + loadTemplate->setIconSet (icon ) ; + loadTemplate->setFixedSize( size, size ); + buttonLayout->addWidget( buttonWidget ); + mGeneral->initCategories( topFrame, buttonLayout ); + + topLayout->addStretch( 1 ); + + QFrame *topFrame2 = addPage(i18n("Details")); + + QBoxLayout *topLayout2 = new QVBoxLayout(topFrame2); + topLayout2->setSpacing(spacingHint()); + + mGeneral->initClass(topFrame2,topLayout2); + mGeneral->initSecrecy( topFrame2, topLayout2 ); + mGeneral->initDescription(topFrame2,topLayout2); + + connect( saveTemplate, SIGNAL( clicked() ), this , SLOT( slotSaveTemplate() ) ); + connect( loadTemplate, SIGNAL( clicked() ), this , SLOT( slotLoadTemplate() ) ); + } else { + QFrame *topFrame = addPage(i18n("General")); + + QBoxLayout *topLayout = new QVBoxLayout(topFrame); + topLayout->setSpacing(spacingHint()); + + mGeneral->initHeader(topFrame,topLayout); + mGeneral->initTime(topFrame,topLayout); + QBoxLayout *alarmLineLayout = new QHBoxLayout(topLayout); + mGeneral->initAlarm(topFrame,alarmLineLayout); + mGeneral->initClass(topFrame,alarmLineLayout); + mGeneral->initDescription(topFrame,topLayout); + QBoxLayout *detailsLayout = new QHBoxLayout(topLayout); + mGeneral->initCategories( topFrame, detailsLayout ); + mGeneral->initSecrecy( topFrame, detailsLayout ); + } + + mGeneral->finishSetup(); + +} + +void KOEventEditor::setupRecurrence() +{ + QFrame *topFrame = addPage( i18n("Recurrence") ); + QBoxLayout *topLayout = new QVBoxLayout( topFrame ); + + mRecurrence = new KOEditorRecurrence( topFrame ); + topLayout->addWidget( mRecurrence ); +} + +void KOEventEditor::editEvent(Event *event, bool showDescription) +{ + // init(); + + mEvent = event; + readEvent(mEvent); + qApp->processEvents(); + if ( showDescription ) { + showPage( 1 ); + mGeneral->setFocusOn( 1 ); + } else { + showPage( 0 ); + mGeneral->setFocusOn( 2 ); + } +} + +void KOEventEditor::newEvent( QDateTime from, QDateTime to, bool allDay ) +{ + // init(); + + mEvent = 0; + setDefaults(from,to,allDay); +} + +void KOEventEditor::loadDefaults() +{ + int fmt = KOPrefs::instance()->mStartTime; + + QDateTime from(QDate::currentDate(), QTime(fmt,0,0)); + QDateTime to(QDate::currentDate(), + QTime(fmt+KOPrefs::instance()->mDefaultDuration,0,0)); + + setDefaults(from,to,false); +} + +bool KOEventEditor::processInput( bool emitTime ) +{ + if (!validateInput()) return false; + + Event *event = 0; + + if (mEvent) event = mEvent; + else { + event = new Event; + event->setOrganizer(KOPrefs::instance()->email()); + } + + writeEvent(event); + if ( emitTime ) { + globalFlagBlockAgenda = 1; + emit showAgendaView( false ); + emit jumpToTime( event->dtStart().date() ); + globalFlagBlockAgenda = 2; + + } + if (mEvent) { + event->setRevision(event->revision()+1); + emit eventChanged(event); + } else { + mCalendar->addEvent(event); + mEvent = event; + emit eventAdded(event); + } + + return true; +} + +void KOEventEditor::deleteEvent() +{ + kdDebug() << "Delete event" << endl; + + if (mEvent) { + if (KOPrefs::instance()->mConfirm) { + switch (msgItemDelete()) { + case KMessageBox::Continue: // OK + emit eventToBeDeleted(mEvent); + emit dialogClose(mEvent); + mCalendar->deleteEvent(mEvent); + emit eventDeleted(); + reject(); + break; + } + } + else { + emit eventToBeDeleted(mEvent); + emit dialogClose(mEvent); + mCalendar->deleteEvent(mEvent); + emit eventDeleted(); + reject(); + } + } else { + reject(); + } +} + +void KOEventEditor::setDefaults(QDateTime from, QDateTime to, bool allDay) +{ + mGeneral->setDefaults(from,to,allDay); + mDetails->setDefaults(); + mRecurrence->setDefaults(from,to,allDay); + showPage( 0 ); + mGeneral->setFocusOn( 2 ); +} + +void KOEventEditor::readEvent( Event *event, bool tmpl ) +{ + mGeneral->readEvent( event, tmpl ); + mDetails->readEvent( event ); + mRecurrence->readEvent( event ); + + // categories + //mCategoryDialog->setSelected( event->categories() ); +} + +void KOEventEditor::writeEvent(Event *event) +{ + mGeneral->writeEvent( event ); + mDetails->writeEvent( event ); + + if ( event->organizer() == KOPrefs::instance()->email() ) { + Event *ev = new Event( *event ); + ev->registerObserver(0); + mDetails->cancelAttendeeEvent( ev ); + if ( ev->attendeeCount() > 0 ) { + emit deleteAttendee( ev ); + } + delete(ev); + } + + mRecurrence->writeEvent(event); +} + +bool KOEventEditor::validateInput() +{ + if (!mGeneral->validateInput()) return false; + if (!mDetails->validateInput()) return false; + if (!mRecurrence->validateInput()) return false; + return true; +} + +int KOEventEditor::msgItemDelete() +{ + return KMessageBox::warningContinueCancel(this, + i18n("This item will be permanently deleted."), + i18n("KOrganizer Confirmation"),i18n("Delete")); +} + +void KOEventEditor::slotLoadTemplate() +{ + + QString fileName =locateLocal( "templates", "events" ); + QDir t_dir; + if ( !t_dir.exists(fileName) ) + t_dir.mkdir ( fileName ); + fileName += "/event"; + fileName = KFileDialog::getSaveFileName( fileName , "Load Event template", this ); + if ( fileName.length() == 0 ) + return; + CalendarLocal cal; + ICalFormat format; + if ( !format.load( &cal, fileName ) ) { + KMessageBox::error( this, i18n("Error loading template file\n '%1'.") + .arg( fileName ) ); + return ; + } + QPtrList<Event> events = cal.events(); + Event* event = events.first(); + if ( !event ) { + KMessageBox::error( this, + i18n("Template does not contain\na valid Event.")); + } else { + kdDebug() << "KOEventEditor::slotLoadTemplate(): readTemplate" << endl; + readEvent( event, true ); + } +} + + +void KOEventEditor::slotSaveTemplate() +{ + QString fileName =locateLocal( "templates", "events" ); + QDir t_dir; + if ( !t_dir.exists(fileName) ) + t_dir.mkdir ( fileName ); + fileName += "/event"; + fileName = KFileDialog::getSaveFileName( fileName , "Save as Event template", this ); + if ( fileName.length() > 0 ) + saveTemplate( fileName ); +} + +void KOEventEditor::saveTemplate( const QString &templateName ) +{ + Event *event = new Event; + writeEvent( event ); + saveAsTemplate( event, templateName ); +} diff --git a/korganizer/koeventeditor.h b/korganizer/koeventeditor.h new file mode 100644 index 0000000..5303c27 --- a/dev/null +++ b/korganizer/koeventeditor.h @@ -0,0 +1,118 @@ +/* + 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 _KOEVENTEDITOR_H +#define _KOEVENTEDITOR_H + +#include <kdialogbase.h> + +#include <qdatetime.h> + +#include <libkcal/calendar.h> + +#include "koeditorgeneralevent.h" +#include "koeditordetails.h" +#include "koeditorrecurrence.h" +#include "koincidenceeditor.h" + +class SaveTemplateDialog; + +using namespace KCal; + +/** + This class provides a dialog for editing an event. +*/ +class KOEventEditor : public KOIncidenceEditor +{ + Q_OBJECT + public: + /** + Construct new event editor. + */ + KOEventEditor( Calendar *calendar, QWidget *parent ); + virtual ~KOEventEditor(void); + + void init(); + + void reload(); + + /** + Clear eventwin for new event, and preset the dates and times with hint + */ + void newEvent( QDateTime from, QDateTime to, bool allDay = false ); + /** + Edit an existing event. + */ + void editEvent( Event * , bool showDescription = false); + + /** + Set widgets to default values + */ + void setDefaults( QDateTime from, QDateTime to, bool allDay ); + + /** + Read event object and setup widgets accordingly. If tmpl is true, the + event is read as template, i.e. the time and date information isn't set. + */ + void readEvent( Event *, bool tmpl = false ); + /** + Write event settings to event object + */ + void writeEvent( Event * ); + + void setCategories( QString s ); + void setSecrecy( int ); + signals: + void eventAdded(Event *); + void eventChanged(Event *); + void eventToBeDeleted(Event *); + void eventDeleted(); + void deleteAttendee(Incidence *); + + protected slots: + void loadDefaults(); + void deleteEvent(); + + void slotLoadTemplate(); + void slotSaveTemplate(); + + void saveTemplate( const QString & ); + + protected: + void setupGeneral(); + void setupRecurrence(); + + /** Check if the input is valid. */ + bool validateInput(); + /** Process user input and create or update event. Returns false if input + * is not valid */ + bool processInput( bool ); + int msgItemDelete(); + + private: + Event *mEvent; + + KOEditorGeneralEvent *mGeneral; + KOEditorRecurrence *mRecurrence; +}; + +#endif diff --git a/korganizer/koeventeditor.moc b/korganizer/koeventeditor.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/koeventeditor.moc diff --git a/korganizer/koeventpopupmenu.cpp b/korganizer/koeventpopupmenu.cpp new file mode 100644 index 0000000..410bceb --- a/dev/null +++ b/korganizer/koeventpopupmenu.cpp @@ -0,0 +1,114 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + 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. +*/ + +#include <qcursor.h> + +#include <klocale.h> +#include <kdebug.h> +#include <kiconloader.h> + +#include <libkcal/event.h> + +#include "koeventpopupmenu.h" +#include "koeventpopupmenu.moc" + +KOEventPopupMenu::KOEventPopupMenu() +{ + mCurrentIncidence = 0; + mHasAdditionalItems = false; + + insertItem (i18n("&Show"),this,SLOT(popupShow())); + mEditOnlyItems.append(insertItem (i18n("&Edit..."),this,SLOT(popupEdit()))); + mEditOnlyItems.append(insertItem (i18n("&Delete"), + this,SLOT(popupDelete()))); + mEditOnlyItems.append(insertItem (i18n("&Clone..."), + this,SLOT(popupClone()))); + mEditOnlyItems.append(insertItem (i18n("&Move..."), + this,SLOT(popupMove()))); +#ifndef DESKTOP_VERSION + mEditOnlyItems.append(insertItem (i18n("&Beam..."), + this,SLOT(popupBeam()))); +#endif + mEditOnlyItems.append(insertItem (i18n("&Toggle Cancel"), + this,SLOT(popupCancel()))); +} + +void KOEventPopupMenu::showIncidencePopup(Incidence *incidence) +{ + mCurrentIncidence = incidence; + + if (mCurrentIncidence) { + // Enable/Disabled menu items only valid for editable events. + QValueList<int>::Iterator it; + for( it = mEditOnlyItems.begin(); it != mEditOnlyItems.end(); ++it ) { + setItemEnabled(*it,!mCurrentIncidence->isReadOnly()); + } + popup(QCursor::pos()); + } else { + kdDebug() << "KOEventPopupMenu::showEventPopup(): No event selected" << endl; + } +} + +void KOEventPopupMenu::addAdditionalItem(const QIconSet &icon,const QString &text, + const QObject *receiver, const char *member, + bool editOnly) +{ + if (!mHasAdditionalItems) { + mHasAdditionalItems = true; + insertSeparator(); + } + int id = insertItem(icon,text,receiver,member); + if (editOnly) mEditOnlyItems.append(id); +} + +void KOEventPopupMenu::popupShow() +{ + if (mCurrentIncidence) emit showIncidenceSignal(mCurrentIncidence); +} + +void KOEventPopupMenu::popupEdit() +{ + if (mCurrentIncidence) emit editIncidenceSignal(mCurrentIncidence); +} + +void KOEventPopupMenu::popupDelete() +{ + if (mCurrentIncidence) emit deleteIncidenceSignal(mCurrentIncidence); +} +void KOEventPopupMenu::popupClone() +{ + if (mCurrentIncidence) emit cloneIncidenceSignal(mCurrentIncidence); +} +void KOEventPopupMenu::popupCancel() +{ + if (mCurrentIncidence) emit cancelIncidenceSignal(mCurrentIncidence); +} +void KOEventPopupMenu::popupMove() +{ + if (mCurrentIncidence) emit moveIncidenceSignal(mCurrentIncidence); +} + +void KOEventPopupMenu::popupBeam() +{ + if (mCurrentIncidence) emit beamIncidenceSignal(mCurrentIncidence); +} diff --git a/korganizer/koeventpopupmenu.h b/korganizer/koeventpopupmenu.h new file mode 100644 index 0000000..6993899 --- a/dev/null +++ b/korganizer/koeventpopupmenu.h @@ -0,0 +1,73 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + 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 KOEVENTPOPUPMENU_H +#define KOEVENTPOPUPMENU_H +// +// Context menu for event views with standard event actions +// + +#include <qpopupmenu.h> + +#include <libkcal/incidence.h> + +using namespace KCal; + +class KOEventPopupMenu : public QPopupMenu { + Q_OBJECT + public: + KOEventPopupMenu(); + + void addAdditionalItem(const QIconSet &icon,const QString &text, + const QObject *receiver, const char *member, + bool editOnly=false); + + + public slots: + void showIncidencePopup(Incidence *); + + protected slots: + void popupShow(); + void popupEdit(); + void popupDelete(); + void popupClone(); + void popupCancel(); + void popupMove(); + void popupBeam(); + + signals: + void editIncidenceSignal(Incidence *); + void showIncidenceSignal(Incidence *); + void deleteIncidenceSignal(Incidence *); + void cloneIncidenceSignal(Incidence *); + void cancelIncidenceSignal(Incidence *); + void moveIncidenceSignal(Incidence *); + void beamIncidenceSignal(Incidence *); + + private: + Incidence *mCurrentIncidence; + + bool mHasAdditionalItems; + QValueList<int> mEditOnlyItems; +}; + +#endif diff --git a/korganizer/koeventpopupmenu.moc b/korganizer/koeventpopupmenu.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/koeventpopupmenu.moc diff --git a/korganizer/koeventview.cpp b/korganizer/koeventview.cpp new file mode 100644 index 0000000..4553b0b --- a/dev/null +++ b/korganizer/koeventview.cpp @@ -0,0 +1,133 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000, 2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + 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. +*/ + +#include <qpopupmenu.h> +#include <qcursor.h> + +#include <klocale.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <kmessagebox.h> + +#include <libkcal/calendar.h> +#include "koprefs.h" +#include "koeventview.h" +using namespace KOrg; +#include "koeventview.moc" + +//--------------------------------------------------------------------------- + +KOEventView::KOEventView(Calendar *cal,QWidget *parent,const char *name) + : KOrg::BaseView(cal,parent,name) +{ +} + +//--------------------------------------------------------------------------- + +KOEventView::~KOEventView() +{ +} + +//--------------------------------------------------------------------------- + +KOEventPopupMenu *KOEventView::eventPopup() +{ + KOEventPopupMenu *eventPopup = new KOEventPopupMenu; + + connect(eventPopup,SIGNAL(editIncidenceSignal(Incidence *)), + SIGNAL(editIncidenceSignal(Incidence *))); + connect(eventPopup,SIGNAL(showIncidenceSignal(Incidence *)), + SIGNAL(showIncidenceSignal(Incidence *))); + connect(eventPopup,SIGNAL(deleteIncidenceSignal(Incidence *)), + SIGNAL(deleteIncidenceSignal(Incidence *))); + connect(eventPopup,SIGNAL(cancelIncidenceSignal(Incidence *)), + SIGNAL(cancelIncidenceSignal(Incidence *))); + connect(eventPopup,SIGNAL(cloneIncidenceSignal(Incidence *)), + SIGNAL(cloneIncidenceSignal(Incidence *))); + connect(eventPopup,SIGNAL(beamIncidenceSignal(Incidence *)), + SIGNAL(beamIncidenceSignal(Incidence *))); + connect(eventPopup,SIGNAL(moveIncidenceSignal(Incidence *)), + SIGNAL(moveIncidenceSignal(Incidence *))); + + return eventPopup; +} + +//--------------------------------------------------------------------------- + +void KOEventView::showIncidencePopup(QPopupMenu *popup,Incidence *event) +{ + mCurrentIncidence = event; + if (event) popup->popup(QCursor::pos()); + else kdDebug() << "KOEventView::showEventPopup(): No event selected" << endl; +} + +//--------------------------------------------------------------------------- + +void KOEventView::popupShow() +{ + emit showIncidenceSignal(mCurrentIncidence); +} + +//--------------------------------------------------------------------------- + +void KOEventView::popupEdit() +{ + emit editIncidenceSignal(mCurrentIncidence); +} + +//--------------------------------------------------------------------------- + +void KOEventView::popupDelete() +{ + emit deleteIncidenceSignal(mCurrentIncidence); +} +void KOEventView::popupClone() +{ + emit cloneIncidenceSignal(mCurrentIncidence); +} +void KOEventView::popupCancel() +{ + emit cancelIncidenceSignal(mCurrentIncidence); +} + +//--------------------------------------------------------------------------- + +void KOEventView::defaultAction( Incidence *incidence ) +{ + + if ( !incidence ) return; + + if ( incidence->isReadOnly() ) + emit showIncidenceSignal(incidence); + else { + if ( KOPrefs::instance()->mEditOnDoubleClick ) + emit editIncidenceSignal(incidence); + else + emit showIncidenceSignal(incidence); + } +} + +//--------------------------------------------------------------------------- + +#include "baseview.moc" + diff --git a/korganizer/koeventview.h b/korganizer/koeventview.h new file mode 100644 index 0000000..77ec111 --- a/dev/null +++ b/korganizer/koeventview.h @@ -0,0 +1,172 @@ +/* + This file is part of KOrganizer. + Copyright (c) 1999 Preston Brown <pbrown@kde.org> + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ +#ifndef _KOEVENTVIEW_H +#define _KOEVENTVIEW_H + +#include <libkcal/calendar.h> +#include <libkcal/event.h> + +#include <korganizer/baseview.h> + +#include "koeventpopupmenu.h" + +using namespace KCal; + +class CalPrinter; + +/** + KOEventView is the abstract base class from which all other + calendar views for event data are derived. It provides methods for + displaying + appointments and events on one or more days. The actual number of + days that a view actually supports is not defined by this abstract class; + that is up to the classes that inherit from it. It also provides + methods for updating the display, retrieving the currently selected + event (or events), and the like. + + @short Abstract class from which all event views are derived. + @author Preston Brown <pbrown@kde.org> + @see KOListView, KOAgendaView, KOWeekView, KOMonthView +*/ +class KOEventView : public KOrg::BaseView +{ + Q_OBJECT + + public: + /** + * Constructs a view. + * @param cal is a pointer to the calendar object from which events + * will be retrieved for display. + */ + KOEventView(Calendar *cal,QWidget *parent=0,const char *name=0); + + /** + * Destructor. Views will do view-specific cleanups here. + */ + virtual ~KOEventView(); + + /** + * provides a hint back to the caller on the maximum number of dates + * that the view supports. A return value of 0 means no maximum. + */ + virtual int maxDatesHint() = 0; + + /** + * Construct a standard context menu for an event. + */ + KOEventPopupMenu *eventPopup(); + + /** This view is an view for displaying events. */ + bool isEventView() { return true; } + + public slots: + + /** + * Show context menu for event. + * @param event event, which is to be manipulated by the menu actions + * @param popup a popop menu created with eventPopup() + */ + void showIncidencePopup(QPopupMenu *popup, Incidence *event); + + /** + Perform the default action for an incidence, e.g. open the event editor, + when double-clicking an event in the agenda view. + */ + void defaultAction( Incidence * ); + + signals: + /** + * when the view changes the dates that are selected in one way or + * another, this signal is emitted. It should be connected back to + * the @see KDateNavigator object so that it changes appropriately, + * and any other objects that need to be aware that the list of + * selected dates has changed. + */ + void datesSelected(const DateList); + + /** + * instructs the receiver to show the incidence in read-only mode. + */ + void showIncidenceSignal(Incidence *); + + /** + * instructs the receiver to begin editing the incidence specified in + * some manner. Doesn't make sense to connect to more than one + * receiver. + */ + void editIncidenceSignal(Incidence *); + void cloneIncidenceSignal(Incidence *); + void cancelIncidenceSignal(Incidence *); + void beamIncidenceSignal(Incidence *); + void moveIncidenceSignal(Incidence *); + + /** + * instructs the receiver to delete the Incidence in some manner; some + * possibilities include automatically, with a confirmation dialog + * box, etc. Doesn't make sense to connect to more than one receiver. + */ + void deleteIncidenceSignal(Incidence *); + + /** + * instructs the receiver to create a new event. Doesn't make + * sense to connect to more than one receiver. + */ + void newEventSignal(); + /** + * instructs the receiver to create a new event with the specified beginning + * time. Doesn't make sense to connect to more than one receiver. + */ + void newEventSignal(QDate); + /** + * instructs the receiver to create a new event with the specified beginning + * time. Doesn't make sense to connect to more than one receiver. + */ + void newEventSignal(QDateTime); + /** + * instructs the receiver to create a new event, with the specified + * beginning end ending times. Doesn't make sense to connect to more + * than one receiver. + */ + void newEventSignal(QDateTime, QDateTime); + + //ET CVS MERGE ! + /** + * Emitted when an event is moved using the mouse in an agenda + * view (week / month). + */ + void shiftedEvent(const QDate& olddate, const QDate& newdate); + + + protected slots: + void popupShow(); + void popupEdit(); + void popupDelete(); + void popupClone(); + void popupCancel(); + + protected: + Incidence *mCurrentIncidence; // Incidence selected e.g. for a context menu +}; + +#endif diff --git a/korganizer/koeventview.moc b/korganizer/koeventview.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/koeventview.moc diff --git a/korganizer/koeventviewer.cpp b/korganizer/koeventviewer.cpp new file mode 100644 index 0000000..9f8bd9b --- a/dev/null +++ b/korganizer/koeventviewer.cpp @@ -0,0 +1,510 @@ +/* + 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. +*/ + +#include <qcstring.h> +#include <qwhatsthis.h> +#include <qdialog.h> +#include <qapplication.h> +#include <qlabel.h> +#include <qlayout.h> + +#include <klocale.h> +#include <kapplication.h> +#include <libkcal/event.h> +#include <libkcal/todo.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <krun.h> +#include <kglobal.h> +#include <kprocess.h> +#include "koprefs.h" + +#include <libkdepim/addresseeview.h> +#include <kabc/stdaddressbook.h> + +#ifndef KORG_NODCOP +#include <dcopclient.h> +#include "korganizer.h" +#include "koprefs.h" +#include "actionmanager.h" +#endif + +#include "koeventviewer.h" +#include "koeventviewer.moc" +#ifndef KORG_NOKABC +#include <kabc/stdaddressbook.h> +#define size count +#endif +KOEventViewer::KOEventViewer(QWidget *parent,const char *name) + : QTextBrowser(parent,name) +{ + mSyncMode = false; + mColorMode = 0; +} + +KOEventViewer::~KOEventViewer() +{ +} + +void KOEventViewer::setSource(const QString& n) +{ + KABC::StdAddressBook* AddressBook = KABC::StdAddressBook::self( true ); + KABC::AddressBook::Iterator it; + for( it = AddressBook->begin(); it != AddressBook->end(); ++it ) { + // LR I do not understand, why the uid string is different on zaurus and desktop +#ifdef DESKTOP_VERSION + QString uid = "uid://"+(*it).uid(); +#else + QString uid = "uid:"+(*it).uid(); +#endif + //qDebug("for *%s* +%s+ ", n.latin1(), uid.latin1()); + if (n == uid ) { + //qDebug("found %s ",(*it).mobileHomePhone().latin1() ); + QDialog dia( this,"dia123", true ); + dia.setCaption( i18n("Details of attendee") ); + QVBoxLayout lay ( &dia ); + KPIM::AddresseeView av ( &dia ); + av.setAddressee( (*it) ); + lay.addWidget( &av ); + if ( QApplication::desktop()->width() < 480 ) + dia.resize( 220, 240); + else { + dia.resize( 400,400); + + } + dia.exec(); + break; + } + } + + +#ifndef KORG_NODCOP + kdDebug() << "KOEventViewer::setSource(): " << n << endl; + QString tmpStr; + if (n.startsWith("mailto:")) { + KApplication::kApplication()->invokeMailer(n.mid(7),QString::null); + //emit showIncidence(n); + return; + } else if (n.startsWith("uid:")) { + DCOPClient *client = KApplication::kApplication()->dcopClient(); + const QByteArray noParamData; + const QByteArray paramData; + QByteArray replyData; + QCString replyTypeStr; +#define PING_ABBROWSER (client->call("kaddressbook", "KAddressBookIface", "interfaces()", noParamData, replyTypeStr, replyData)) + bool foundAbbrowser = PING_ABBROWSER; + + if (foundAbbrowser) { + //KAddressbook is already running, so just DCOP to it to bring up the contact editor + //client->send("kaddressbook","KAddressBookIface", + QDataStream arg(paramData, IO_WriteOnly); + arg << n.mid(6); + client->send("kaddressbook", "KAddressBookIface", "showContactEditor( QString )", paramData); + return; + } else { + /* + KaddressBook is not already running. Pass it the UID of the contact via the command line while starting it - its neater. + We start it without its main interface + */ + KIconLoader* iconLoader = new KIconLoader(); + QString iconPath = iconLoader->iconPath("go",KIcon::Small); + ActionManager::setStartedKAddressBook(true); + tmpStr = "kaddressbook --editor-only --uid "; + tmpStr += KProcess::quote(n.mid(6)); + KRun::runCommand(tmpStr,"KAddressBook",iconPath); + return; + } + } else { + //QTextBrowser::setSource(n); + } +#endif +} + +void KOEventViewer::addTag(const QString & tag,const QString & text) +{ + int number=text.contains("\n"); + QString str = "<" + tag + ">"; + QString tmpText=text; + QString tmpStr=str; + if(number !=-1) + { + if (number > 0) { + int pos=0; + QString tmp; + for(int i=0;i<=number;i++) { + pos=tmpText.find("\n"); + tmp=tmpText.left(pos); + tmpText=tmpText.right(tmpText.length()-pos-1); + tmpStr+=tmp+"<br>"; + } + } + else tmpStr += tmpText; + tmpStr+="</" + tag + ">"; + mText.append(tmpStr); + } + else + { + str += text + "</" + tag + ">"; + mText.append(str); + } +} + +void KOEventViewer::setColorMode( int m ) +{ + mColorMode = m; +} +void KOEventViewer::appendEvent(Event *event, int mode ) +{ + mCurrentIncidence = event; + bool shortDate = KOPrefs::instance()->mShortDateInViewer; + topLevelWidget()->setCaption(i18n("Event Viewer")); + if ( mode == 0 ) { + addTag("h2",event->summary()); + } + else { + if ( mColorMode == 1 ) { + mText +="<font color=\"#00A000\">"; + } + if ( mColorMode == 2 ) { + mText +="<font color=\"#C00000\">"; + } + // mText +="<font color=\"#F00000\">" + i18n("O-due!") + "</font>"; + if ( mode == 1 ) { + addTag("h2",i18n( "Local: " ) +event->summary()); + } else { + addTag("h2",i18n( "Remote: " ) +event->summary()); + } + addTag("h3",i18n( "Last modified: " ) + KGlobal::locale()->formatDateTime(event->lastModified(),shortDate, true ) ); + if ( mColorMode ) + mText += "</font>"; + } + if (event->cancelled ()) { + mText +="<font color=\"#B00000\">"; + addTag("i",i18n("This event has been cancelled!")); + mText.append("<br>"); + mText += "</font>"; + } + if (!event->location().isEmpty()) { + addTag("b",i18n("Location: ")); + mText.append(event->location()+"<br>"); + } + if (event->doesFloat()) { + if (event->isMultiDay()) { + mText.append(i18n("<p><b>From:</b> %1 </p><p><b>To:</b> %2</p>") + .arg(event->dtStartDateStr(shortDate)) + .arg(event->dtEndDateStr(shortDate))); + } else { + mText.append(i18n("<p><b>On:</b> %1</p>").arg(event->dtStartDateStr( shortDate ))); + } + } else { + if (event->isMultiDay()) { + mText.append(i18n("<p><b>From:</b> %1</p> ") + .arg(event->dtStartStr( shortDate))); + mText.append(i18n("<p><b>To:</b> %1</p>") + .arg(event->dtEndStr(shortDate))); + } else { + mText.append(i18n("<p><b>On:</b> %1</p> ") + .arg(event->dtStartDateStr( shortDate ))); + mText.append(i18n("<p><b>From:</b> %1 <b>To:</b> %2</p>") + .arg(event->dtStartTimeStr()) + .arg(event->dtEndTimeStr())); + } + } + + if (event->recurrence()->doesRecur()) { + + QString recurText = event->recurrence()->recurrenceText(); + addTag("p","<em>" + i18n("This is a %1 recurring event.").arg(recurText ) + "</em>"); + bool last; + QDate start = QDate::currentDate(); + QDate next; + next = event->recurrence()->getPreviousDate( start , &last ); + if ( !last ) { + next = event->recurrence()->getNextDate( start.addDays( - 1 ) ); + addTag("p",i18n("<b>Next recurrence is on:</b>") ); + addTag("p", KGlobal::locale()->formatDate( next, shortDate )); + } else { + addTag("p",i18n("<b>Last recurrence was on:</b>") ); + addTag("p", KGlobal::locale()->formatDate( next, shortDate )); + } + } + + + if (event->isAlarmEnabled()) { + Alarm *alarm =event->alarms().first() ; + QDateTime t = alarm->time(); + int min = t.secsTo( event->dtStart() )/60; + QString s =i18n("( %1 min before )").arg( min ); + addTag("p",i18n("<b>Alarm on: ") + s +" </b>"); + addTag("p", KGlobal::locale()->formatDateTime( t, shortDate )); + //addTag("p",s); + } + + addTag("b",i18n("Access: ")); + mText.append(event->secrecyStr()+"<br>"); + if (!event->description().isEmpty()) { + addTag("p",i18n("<b>Details: </b>")); + addTag("p",event->description()); + } + + formatCategories(event); + + formatReadOnly(event); + formatAttendees(event); + + setText(mText); + //QWhatsThis::add(this,mText); + +} + +void KOEventViewer::appendTodo(Todo *event, int mode ) +{ + mCurrentIncidence = event; + topLevelWidget()->setCaption(i18n("Todo Viewer")); + bool shortDate = KOPrefs::instance()->mShortDateInViewer; + if (mode == 0 ) + addTag("h2",event->summary()); + else { + if ( mColorMode == 1 ) { + mText +="<font color=\"#00A000\">"; + } + if ( mColorMode == 2 ) { + mText +="<font color=\"#B00000\">"; + } + if ( mode == 1 ) { + addTag("h2",i18n( "Local: " ) +event->summary()); + } else { + addTag("h2",i18n( "Remote: " ) +event->summary()); + } + addTag("h3",i18n( "Last modified: " ) + KGlobal::locale()->formatDateTime(event->lastModified(),shortDate, true ) ); + if ( mColorMode ) + mText += "</font>"; + } + if (event->cancelled ()) { + mText +="<font color=\"#B00000\">"; + addTag("i",i18n("This todo has been cancelled!")); + mText.append("<br>"); + mText += "</font>"; + } + + if (!event->location().isEmpty()) { + addTag("b",i18n("Location: ")); + mText.append(event->location()+"<br>"); + } + if (event->hasDueDate()) { + mText.append(i18n("<p><b>Due on:</b> %1</p>").arg(event->dtDueStr(KOPrefs::instance()->mShortDateInViewer))); + } + addTag("b",i18n("Access: ")); + mText.append(event->secrecyStr()+"<br>"); + if (!event->description().isEmpty()) { + addTag("p",i18n("<b>Details: </b>")); + addTag("p",event->description()); + } + + formatCategories(event); + + mText.append(i18n("<p><b>Priority:</b> %2</p>") + .arg(QString::number(event->priority()))); + + mText.append(i18n("<p><i>%1 % completed</i></p>") + .arg(event->percentComplete())); + + formatReadOnly(event); + formatAttendees(event); + + setText(mText); +} + +void KOEventViewer::formatCategories(Incidence *event) +{ + if (!event->categoriesStr().isEmpty()) { + if (event->categories().count() == 1) { + addTag("h3",i18n("Category")); + } else { + addTag("h3",i18n("Categories")); + } + addTag("p",event->categoriesStr()); + } +} +void KOEventViewer::formatAttendees(Incidence *event) +{ + QPtrList<Attendee> attendees = event->attendees(); + if (attendees.count()) { + + + QString iconPath = KGlobal::iconLoader()->iconPath("mailappt",KIcon::Small); + addTag("h3",i18n("Organizer")); + mText.append("<ul><li>"); +#ifndef KORG_NOKABC + + KABC::AddressBook *add_book = KABC::StdAddressBook::self(); + KABC::Addressee::List addressList; + addressList = add_book->findByEmail(event->organizer()); + KABC::Addressee o = addressList.first(); + if (!o.isEmpty() && addressList.size()<2) { + mText += "<a href=\"uid:" + o.uid() + "\">"; + mText += o.formattedName(); + mText += "</a>\n"; + } else { + mText.append(event->organizer()); + } +#else + mText.append(event->organizer()); +#endif + + if (iconPath) { + mText += " <a href=\"mailto:" + event->organizer() + "\">"; + mText += "<IMG src=\"" + iconPath + "\">"; + mText += "</a>\n"; + } + mText.append("</li></ul>"); + + addTag("h3",i18n("Attendees")); + Attendee *a; + mText.append("<ul>"); + for(a=attendees.first();a;a=attendees.next()) { +#ifndef KORG_NOKABC + if (a->name().isEmpty()) { + addressList = add_book->findByEmail(a->email()); + KABC::Addressee o = addressList.first(); + if (!o.isEmpty() && addressList.size()<2) { + mText += "<a href=\"uid:" + o.uid() + "\">"; + mText += o.formattedName(); + mText += "</a>\n"; + } else { + mText += "<li>"; + mText.append(a->email()); + mText += "\n"; + } + } else { + mText += "<li><a href=\"uid:" + a->uid() + "\">"; + if (!a->name().isEmpty()) mText += a->name(); + else mText += a->email(); + mText += "</a>\n"; + } +#else + //qDebug("nokabc "); + mText += "<li><a href=\"uid:" + a->uid() + "\">"; + if (!a->name().isEmpty()) mText += a->name(); + else mText += a->email(); + mText += "</a>\n"; +#endif + + if (!a->email().isEmpty()) { + if (iconPath) { + mText += "<a href=\"mailto:" + a->name() +" "+ "<" + a->email() + ">" + "\">"; + mText += "<IMG src=\"" + iconPath + "\">"; + mText += "</a>\n"; + } + } + if (a->status() != Attendee::NeedsAction ) + mText +="[" + a->statusStr() + "] "; + if (a->role() == Attendee::Chair ) + mText +="(" + a->roleStr().left(1) + ".)"; + } + mText.append("</li></ul>"); + } + +} +void KOEventViewer::appendJournal(Journal *jour, int mode ) +{ + bool shortDate = KOPrefs::instance()->mShortDateInViewer; + if (mode == 0 ) + addTag("h2",i18n("Journal from: ")); + else { + if ( mode == 1 ) { + addTag("h2",i18n( "Local: " ) +i18n("Journal from: ")); + } else { + addTag("h2",i18n( "Remote: " ) +i18n("Journal from: ")); + } + addTag("h3",i18n( "Last modified " ) + KGlobal::locale()->formatDateTime(jour->lastModified(),shortDate ) ); + } + topLevelWidget()->setCaption("Journal Viewer"); + mText.append(i18n("<h3> %1 </h3> ").arg(jour->dtStartDateStr(KOPrefs::instance()->mShortDateInViewer))); + if (!jour->description().isEmpty()) { + addTag("p",jour->description()); + } + setText(mText); +} + +void KOEventViewer::formatReadOnly(Incidence *event) +{ + if (event->isReadOnly()) { + addTag("p","<em>(" + i18n("read-only") + ")</em>"); + } +} +void KOEventViewer::setSyncMode( bool b ) +{ + mSyncMode = b; +} + + +void KOEventViewer::setTodo(Todo *event, bool clearV ) +{ + if ( clearV ) + clearEvents(); + if ( mSyncMode ) { + if ( clearV ) + appendTodo(event,1 ); + else + appendTodo(event,2); + } else + appendTodo(event); +} +void KOEventViewer::setJournal(Journal *event, bool clearV ) +{ + if ( clearV ) + clearEvents(); + if ( mSyncMode ) { + if ( clearV ) + appendJournal(event, 1); + else + appendJournal(event, 2); + } else + appendJournal(event); +} + +void KOEventViewer::setEvent(Event *event) +{ + clearEvents(); + if ( mSyncMode ) + appendEvent(event, 1); + else + appendEvent(event); +} + +void KOEventViewer::addEvent(Event *event) +{ + if ( mSyncMode ) + appendEvent(event, 2); + else + appendEvent(event); +} + +void KOEventViewer::clearEvents(bool now) +{ + mText = ""; + if (now) setText(mText); +} + +void KOEventViewer::addText(QString text) +{ + mText.append(text); + setText(mText); +} diff --git a/korganizer/koeventviewer.h b/korganizer/koeventviewer.h new file mode 100644 index 0000000..74f1135 --- a/dev/null +++ b/korganizer/koeventviewer.h @@ -0,0 +1,73 @@ +/* + 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. +*/ +#ifndef KOEVENTVIEWER_H +#define KOEVENTVIEWER_H +// +// Viewer widget for events. +// + +#include <qtextbrowser.h> + +#include <libkcal/event.h> +#include <libkcal/journal.h> + + +using namespace KCal; + +class KOEventViewer : public QTextBrowser { + Q_OBJECT + public: + KOEventViewer(QWidget *parent=0,const char *name=0); + virtual ~KOEventViewer(); + + void setSource(const QString &); + void setEvent(Event *event); + void addEvent(Event *event); + void setTodo(Todo *event, bool clearV = true ); + void setJournal(Journal *jour, bool clearV = true ); + + void appendEvent(Event *event, int mode = 0 ); + void appendTodo(Todo *event, int mode = 0 ); + void appendJournal(Journal *jour, int mode = 0 ); + + void clearEvents(bool now=false); + + void addText(QString text); + void setSyncMode( bool ); + void setColorMode( int ); + + protected: + int mColorMode; + void addTag(const QString & tag,const QString & text); + + void formatCategories(Incidence *event); + void formatAttendees(Incidence *event); + void formatReadOnly(Incidence *event); + + private: + QTextBrowser *mEventTextView; + bool mSyncMode; + + QString mText; + Incidence* mCurrentIncidence; + signals: + void launchaddressbook(QString uid); +}; + +#endif diff --git a/korganizer/koeventviewer.moc b/korganizer/koeventviewer.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/koeventviewer.moc diff --git a/korganizer/koeventviewerdialog.cpp b/korganizer/koeventviewerdialog.cpp new file mode 100644 index 0000000..64ab94d --- a/dev/null +++ b/korganizer/koeventviewerdialog.cpp @@ -0,0 +1,240 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include <klocale.h> + +#include <libkcal/event.h> +#include <qpushbutton.h> + +#include "koeventviewer.h" +#include "koprefs.h" +#include <libkcal/todo.h> +#include "qapp.h" + +#include "koeventviewerdialog.h" +#include "koeventviewerdialog.moc" +extern int globalFlagBlockAgenda; + +KOEventViewerDialog::KOEventViewerDialog(QWidget *parent,const char *name) + : KDialogBase(parent,name, +#ifndef DESKTOP_VERSION + true , +#else + false, +#endif + i18n("Event Viewer"),Ok|User1|Close,Close, false, i18n("Agenda")) +{ + + mEventViewer = new KOEventViewer(this); + mEventViewer->setFont( KOPrefs::instance()->mEventViewFont ); + setMainWidget(mEventViewer); + setButtonText(Ok, i18n("Edit") ); + + QObject::connect(findButton( Ok ),SIGNAL(clicked()), + SLOT(editIncidence())); + QObject::connect(this,SIGNAL(user1Clicked()), + SLOT(showIncidence())); + mIncidence = 0; + // TODO: Set a sensible size (based on the content?). + //showMaximized(); + //qDebug("++++++++++++KOEventViewerDialog() "); + // if ( KOPrefs::instance()->mCompactDialogs ) { +// setFixedSize( 240,284 ); +// move( 0, 15 ); +// } else { +// setMinimumSize(300,200); +// resize(320,300); +// } + mSyncMode = false; + mSyncResult = 0; + +} + +KOEventViewerDialog::~KOEventViewerDialog() +{ + //qDebug("-------~KOEventViewerDialog() "); +} +void KOEventViewerDialog::showMe() +{ + +#ifdef DESKTOP_VERSION + show(); +#else + showMaximized(); +#endif + setFocus(); + setActiveWindow(); + +} +void KOEventViewerDialog::setSyncMode( bool b ) +{ + mSyncMode = b; + //qDebug("KOEventViewerDialog::setSyncMode %d ",mSyncMode ); + if ( mSyncMode ) { + findButton( Close )->setText( i18n("Cancel Sync")); + findButton( Ok )->setText( i18n("Remote")); + findButton( User1 )->setText( i18n("Local")); + } else { + findButton( Close )->setText( i18n("Close")); + findButton( Ok )->setText( i18n("Edit")); + findButton( User1 )->setText( i18n("Agenda")); + } + mEventViewer->setSyncMode( b ); +} +void KOEventViewerDialog::setColorMode( int m ) +{ + mEventViewer->setColorMode( m ); +} +int KOEventViewerDialog::executeS( bool local ) +{ + mSyncResult = 3; + if ( local ) + findButton( User1 )->setFocus(); + else + findButton( Ok )->setFocus(); + exec(); + return mSyncResult; +} + +void KOEventViewerDialog::updateConfig() +{ + mEventViewer->setFont( KOPrefs::instance()->mEventViewFont ); + +} +void KOEventViewerDialog::setEvent(Event *event) +{ + mEventViewer->setEvent(event); + mIncidence = event; + findButton( Close )->setFocus(); +} +void KOEventViewerDialog::setIncidence(Incidence *in ) +{ + if ( in->type() == "Event" ) + setEvent( (Event*) in ); + else if ( in->type() =="Todo" ) + setTodo( (Todo*) in ); + else if ( in->type() =="Journal" ) + setJournal( (Journal*) in ); +} +void KOEventViewerDialog::addIncidence(Incidence *in) +{ + if ( in->type() == "Event" ) + addEvent( (Event*) in ); + else if ( in->type() =="Todo" ) + mEventViewer->setTodo( (Todo*) in, false ); + else if ( in->type() =="Journal" ) + mEventViewer->setJournal( (Journal*) in, false ); + if ( mSyncMode ) { + findButton( User1 )->setFocus(); + setCaption(i18n("Conflict! Please choose entry")); + } +} + +void KOEventViewerDialog::addEvent(Event *event) +{ + mEventViewer->addEvent(event); + mIncidence = event; + findButton( Close )->setFocus(); +} + +void KOEventViewerDialog::setTodo(Todo *event) +{ + mEventViewer->setTodo(event); + mIncidence = (Incidence*)event; + findButton( Close )->setFocus(); +} +void KOEventViewerDialog::setJournal(Journal *j) +{ + mEventViewer->setJournal(j); + mIncidence = (Incidence*)j; + findButton( Close )->setFocus(); +} + +void KOEventViewerDialog::addText(QString text) +{ + mEventViewer->addText(text); + findButton( Close )->setFocus(); +} +void KOEventViewerDialog::editIncidence() +{ + if ( mSyncMode ) { + mSyncResult = 2; + accept(); + return; + } + if ( mIncidence ){ +#ifndef DESKTOP_VERSION + hide(); +#endif + emit editIncidence( mIncidence ); + } +} +void KOEventViewerDialog::showIncidence() +{ + + if ( mSyncMode ) { + mSyncResult = 1; + accept(); + return; + } + + if ( mIncidence ){ +#ifndef DESKTOP_VERSION + hide(); +#endif + QDate date; + if ( mIncidence->type() == "Todo" ) { + if ( ((Todo*)mIncidence)->hasDueDate() ) + date = ((Todo*)mIncidence)->dtDue().date(); + else { + globalFlagBlockAgenda = 2; + emit showAgendaView( false ); + return; + } + } else + date = mIncidence->dtStart().date(); + globalFlagBlockAgenda = 1; + emit showAgendaView( false ); + globalFlagBlockAgenda = 2; + emit jumpToTime( date ); + } +} +void KOEventViewerDialog::keyPressEvent ( QKeyEvent * e ) +{ + switch ( e->key() ) { + + case Qt::Key_A : + case Qt::Key_L : + showIncidence(); + break; + case Qt::Key_E : + case Qt::Key_R : + editIncidence(); + break; + case Qt::Key_C: + close(); + break; + case Qt::Key_I: + accept(); + break; + default: + break; + } + +} diff --git a/korganizer/koeventviewerdialog.h b/korganizer/koeventviewerdialog.h new file mode 100644 index 0000000..21cb3ee --- a/dev/null +++ b/korganizer/koeventviewerdialog.h @@ -0,0 +1,70 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000, 2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef KOEVENTVIEWERDIALOG_H +#define KOEVENTVIEWERDIALOG_H +// +// Viewer dialog for events. +// + +#include <qtextview.h> + +#include <kdialogbase.h> + +#include <libkcal/event.h> + +using namespace KCal; + +class KOEventViewer; + +class KOEventViewerDialog : public KDialogBase { + Q_OBJECT + public: + KOEventViewerDialog(QWidget *parent=0,const char *name=0); + virtual ~KOEventViewerDialog(); + + void setEvent(Event *event); + void addEvent(Event *event); + void setTodo(Todo *event); + void setJournal(Journal *journal); + void setIncidence(Incidence *inc); + void addIncidence(Incidence *inc); + void addText(QString text); + void showMe(); + void setSyncMode( bool ); + void setColorMode( int m ); + int executeS( bool ); + public slots: + void updateConfig(); + signals: + void editIncidence( Incidence* ); + void jumpToTime( const QDate &); + void showAgendaView( bool ); +private slots: + void editIncidence(); + void showIncidence(); + + private: + bool mSyncMode; + int mSyncResult; + KOEventViewer *mEventViewer; + Incidence* mIncidence; + void keyPressEvent ( QKeyEvent * e ); +}; + +#endif diff --git a/korganizer/koeventviewerdialog.moc b/korganizer/koeventviewerdialog.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/koeventviewerdialog.moc diff --git a/korganizer/kofilterview.cpp b/korganizer/kofilterview.cpp new file mode 100644 index 0000000..b22bc54 --- a/dev/null +++ b/korganizer/kofilterview.cpp @@ -0,0 +1,96 @@ +/* + 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. +*/ + +#include <qcheckbox.h> +#include <qcombobox.h> +#include <qpushbutton.h> + +#include <libkcal/calfilter.h> + +#include "kofilterview.h" +#include "kofilterview.moc" + +KOFilterView::KOFilterView(QPtrList<CalFilter> *filterList,QWidget* parent, + const char* name,WFlags fl ) + : KOFilterView_base(parent,name,fl) +{ + mFilters = filterList; + + connect(mSelectionCombo,SIGNAL(activated(int)),SIGNAL(filterChanged())); + connect(mEnabledCheck,SIGNAL(clicked()),SIGNAL(filterChanged())); + connect(mEditButton,SIGNAL(clicked()),SIGNAL(editFilters())); +} + +KOFilterView::~KOFilterView() +{ + // no need to delete child widgets, Qt does it all for us +} + +bool KOFilterView::filtersEnabled() +{ + return mEnabledCheck->isChecked(); +} + +void KOFilterView::setFiltersEnabled(bool set) +{ + mEnabledCheck->setChecked(set); + emit filterChanged(); +} + + +void KOFilterView::updateFilters() +{ + mSelectionCombo->clear(); + + CalFilter *filter = mFilters->first(); + while(filter) { + mSelectionCombo->insertItem(filter->name()); + filter = mFilters->next(); + } +} + +CalFilter *KOFilterView::selectedFilter() +{ + CalFilter *f = mFilters->at(mSelectionCombo->currentItem()); + return f; +} + +void KOFilterView::setSelectedFilter(QString filterName) +{ + int filter_num = mSelectionCombo->count(); + int i; + for (i=0;i<filter_num;i++) { + if (mSelectionCombo->text(i)==filterName) + mSelectionCombo->setCurrentItem(i); + } + emit filterChanged(); +} +void KOFilterView::setSelectedFilter( int fil ) +{ + if ( fil >= mSelectionCombo->count() ) + return; + mSelectionCombo->setCurrentItem( fil ); + emit filterChanged(); +} + + diff --git a/korganizer/kofilterview.h b/korganizer/kofilterview.h new file mode 100644 index 0000000..9ba2673 --- a/dev/null +++ b/korganizer/kofilterview.h @@ -0,0 +1,57 @@ +/* + 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 KOFILTERVIEW_H +#define KOFILTERVIEW_H + +#include <qstring.h> + +#include "kofilterview_base.h" + +#include <libkcal/calfilter.h> + +using namespace KCal; + +class KOFilterView : public KOFilterView_base +{ + Q_OBJECT + public: + KOFilterView(QPtrList<CalFilter> *filterList,QWidget* parent=0,const char* name=0, WFlags fl=0); + ~KOFilterView(); + + void updateFilters(); + + bool filtersEnabled(); + void setFiltersEnabled(bool); + CalFilter *selectedFilter(); + void setSelectedFilter(QString); + void setSelectedFilter( int ); + + signals: + void filterChanged(); + void editFilters(); + + private: + QPtrList<CalFilter> *mFilters; +}; + +#endif // KOFILTERVIEW_H diff --git a/korganizer/kofilterview.moc b/korganizer/kofilterview.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/kofilterview.moc diff --git a/korganizer/kofilterview_base.cpp b/korganizer/kofilterview_base.cpp new file mode 100644 index 0000000..6709630 --- a/dev/null +++ b/korganizer/kofilterview_base.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** Form implementation generated from reading ui file 'kofilterview_base.ui' +** +** Created: Sat Jun 26 17:24:07 2004 +** by: The User Interface Compiler (uic) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ +#include "kofilterview_base.h" + +#include <qcheckbox.h> +#include <qcombobox.h> +#include <qframe.h> +#include <qpushbutton.h> +#include <qlayout.h> +#include <qvariant.h> +#include <qtooltip.h> +#include <qwhatsthis.h> + +/* + * Constructs a KOFilterView_base which is a child of 'parent', with the + * name 'name' and widget flags set to 'f' + */ +KOFilterView_base::KOFilterView_base( QWidget* parent, const char* name, WFlags fl ) + : QWidget( parent, name, fl ) +{ + if ( !name ) + setName( "KOFilterView_base" ); + resize( 100, 100 ); + setCaption( tr( "Form2" ) ); + KOFilterView_baseLayout = new QVBoxLayout( this ); + KOFilterView_baseLayout->setSpacing( 2 ); + KOFilterView_baseLayout->setMargin( 2 ); + + Frame11 = new QFrame( this, "Frame11" ); + Frame11->setFrameShadow( QFrame::Raised ); + Frame11->setFrameShape( QFrame::StyledPanel ); + Frame11Layout = new QVBoxLayout( Frame11 ); + Frame11Layout->setSpacing( 1 ); + Frame11Layout->setMargin( 2 ); + + mEnabledCheck = new QCheckBox( Frame11, "mEnabledCheck" ); + mEnabledCheck->setText( tr( "Filter enabled" ) ); + Frame11Layout->addWidget( mEnabledCheck ); + + mSelectionCombo = new QComboBox( FALSE, Frame11, "mSelectionCombo" ); + Frame11Layout->addWidget( mSelectionCombo ); + KOFilterView_baseLayout->addWidget( Frame11 ); + + mEditButton = new QPushButton( this, "mEditButton" ); + mEditButton->setText( tr( "Edit Filters" ) ); + KOFilterView_baseLayout->addWidget( mEditButton ); +} + +/* + * Destroys the object and frees any allocated resources + */ +KOFilterView_base::~KOFilterView_base() +{ + // no need to delete child widgets, Qt does it all for us +} + diff --git a/korganizer/kofilterview_base.h b/korganizer/kofilterview_base.h new file mode 100644 index 0000000..ed084ce --- a/dev/null +++ b/korganizer/kofilterview_base.h @@ -0,0 +1,40 @@ +/**************************************************************************** +** Form interface generated from reading ui file 'kofilterview_base.ui' +** +** Created: Sat Jun 26 17:22:53 2004 +** by: The User Interface Compiler (uic) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ +#ifndef KOFILTERVIEW_BASE_H +#define KOFILTERVIEW_BASE_H + +#include <qvariant.h> +#include <qwidget.h> +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QCheckBox; +class QComboBox; +class QFrame; +class QPushButton; + +class KOFilterView_base : public QWidget +{ + Q_OBJECT + +public: + KOFilterView_base( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~KOFilterView_base(); + + QFrame* Frame11; + QCheckBox* mEnabledCheck; + QComboBox* mSelectionCombo; + QPushButton* mEditButton; + +protected: + QVBoxLayout* KOFilterView_baseLayout; + QVBoxLayout* Frame11Layout; +}; + +#endif // KOFILTERVIEW_BASE_H diff --git a/korganizer/kofilterview_base.ui b/korganizer/kofilterview_base.ui new file mode 100644 index 0000000..b1b7c61 --- a/dev/null +++ b/korganizer/kofilterview_base.ui @@ -0,0 +1,96 @@ +<!DOCTYPE UI><UI> +<class>KOFilterView_base</class> +<widget> + <class>QWidget</class> + <property stdset="1"> + <name>name</name> + <cstring>KOFilterView_base</cstring> + </property> + <property stdset="1"> + <name>geometry</name> + <rect> + <x>0</x> + <y>0</y> + <width>100</width> + <height>100</height> + </rect> + </property> + <property stdset="1"> + <name>caption</name> + <string>Form2</string> + </property> + <property> + <name>layoutMargin</name> + </property> + <property> + <name>layoutSpacing</name> + </property> + <vbox> + <property stdset="1"> + <name>margin</name> + <number>2</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>2</number> + </property> + <widget> + <class>QFrame</class> + <property stdset="1"> + <name>name</name> + <cstring>Frame11</cstring> + </property> + <property stdset="1"> + <name>frameShadow</name> + <enum>Raised</enum> + </property> + <property stdset="1"> + <name>frameShape</name> + <enum>StyledPanel</enum> + </property> + <property> + <name>layoutMargin</name> + </property> + <vbox> + <property stdset="1"> + <name>margin</name> + <number>2</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>1</number> + </property> + <widget> + <class>QCheckBox</class> + <property stdset="1"> + <name>name</name> + <cstring>mEnabledCheck</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Filter enabled</string> + </property> + </widget> + <widget> + <class>QComboBox</class> + <property stdset="1"> + <name>name</name> + <cstring>mSelectionCombo</cstring> + </property> + </widget> + </vbox> + </widget> + <widget> + <class>QPushButton</class> + <property stdset="1"> + <name>name</name> + <cstring>mEditButton</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Edit Filters</string> + </property> + </widget> + </vbox> +</widget> +</UI> diff --git a/korganizer/koglobals.cpp b/korganizer/koglobals.cpp new file mode 100644 index 0000000..8016034 --- a/dev/null +++ b/korganizer/koglobals.cpp @@ -0,0 +1,143 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2002 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. +*/ + +#include <qapplication.h> + +#include <kdebug.h> +#include <kglobal.h> +#include <kconfig.h> +#include <kstandarddirs.h> +#include <kglobalsettings.h> +#include <klocale.h> + +#include <kcalendarsystem.h> + +#ifndef KORG_NOKALARMD +#include "kalarmdclient.h" +#endif +#include "simplealarmclient.h" + +#include "koglobals.h" +#include "koprefs.h" + +class NopAlarmClient : public AlarmClient +{ + public: + void startDaemon() {} + bool setCalendars( const QStringList & ) { return false; } + bool addCalendar( const QString & ) { return false; } + bool removeCalendar( const QString & ) { return false; } + bool reloadCalendar( const QString & ) { return false; } +}; + +KOGlobals *KOGlobals::mSelf = 0; + +KOGlobals *KOGlobals::self() +{ + if (!mSelf) { + mSelf = new KOGlobals; + } + + return mSelf; +} + +KOGlobals::KOGlobals() +{ + KConfig *cfg = KOGlobals::config(); + + cfg->setGroup("General"); + mCalendarSystem = KGlobal::locale()->calendar(); + + cfg->setGroup("AlarmDaemon"); + QString alarmClient = cfg->readEntry( "Daemon", "kalarmd" ); + if ( alarmClient == "simple" ) { + mAlarmClient = new SimpleAlarmClient; +#ifndef KORG_NOKALARMD + } else if ( alarmClient == "kalarmd" ) { + mAlarmClient = new KalarmdClient; +#endif + } else { + mAlarmClient = new NopAlarmClient; + } +} + +KConfig* KOGlobals::config() +{ + static KConfig *mConfig = 0; + if (!mConfig) { + KOPrefs *p = KOPrefs::instance(); + mConfig = p->getConfig(); + //mConfig = new KConfig( locateLocal( "config", "korganizerrc" ) ); + } + return mConfig; +} + +KOGlobals::~KOGlobals() +{ + delete mAlarmClient; +} + +const KCalendarSystem *KOGlobals::calendarSystem() const +{ + return mCalendarSystem; +} + +AlarmClient *KOGlobals::alarmClient() const +{ + return mAlarmClient; +} + +void KOGlobals::fitDialogToScreen( QWidget *wid, bool force ) +{ + bool resized = false; + + int w = wid->frameSize().width(); + int h = wid->frameSize().height(); + + QRect desk = KGlobalSettings::desktopGeometry(wid); + if ( w > desk.width() ) { + w = desk.width(); + resized = true; + } + // Yuck this hack is ugly. Is the -30 really to circumvent the size of + // kicker?! + if ( h > desk.height() - 30 ) { + h = desk.height() - 30; + resized = true; + } + + if ( resized || force ) { + wid->resize( w, h ); + wid->move( desk.x(), desk.y()+15 ); + if ( force ) wid->setFixedSize( w, h ); + } +} + +bool KOGlobals::reverseLayout() +{ +#if QT_VERSION >= 0x030000 + return QApplication::reverseLayout(); +#else + return false; +#endif +} diff --git a/korganizer/koglobals.h b/korganizer/koglobals.h new file mode 100644 index 0000000..357ff5f --- a/dev/null +++ b/korganizer/koglobals.h @@ -0,0 +1,59 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2002 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 KORG_GLOBALS_H +#define KORG_GLOBALS_H + +class KCalendarSystem; +class AlarmClient; + +class KConfig; + +class KOGlobals +{ + public: + static KOGlobals *self(); + + enum { EVENTADDED, EVENTEDITED, EVENTDELETED }; + enum { PRIORITY_MODIFIED, COMPLETION_MODIFIED, CATEGORY_MODIFIED, UNKNOWN_MODIFIED }; + + static void fitDialogToScreen( QWidget *widget, bool force=false ); + static KConfig *config(); + + static bool reverseLayout(); + + const KCalendarSystem *calendarSystem() const; + + AlarmClient *alarmClient() const; + + protected: + KOGlobals(); + ~KOGlobals(); + + private: + static KOGlobals *mSelf; + + const KCalendarSystem *mCalendarSystem; + AlarmClient *mAlarmClient; +}; + +#endif diff --git a/korganizer/koincidenceeditor.cpp b/korganizer/koincidenceeditor.cpp new file mode 100644 index 0000000..e10a188 --- a/dev/null +++ b/korganizer/koincidenceeditor.cpp @@ -0,0 +1,187 @@ +/* + 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. +*/ + +#include <qtooltip.h> +#include <qframe.h> +#include <qpixmap.h> +#include <qlayout.h> +#include <qwidgetstack.h> +#include <qdatetime.h> +#include <qdir.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kmessagebox.h> +#include <kfiledialog.h> + +#include <libkdepim/categoryselectdialog.h> +#include <libkdepim/kinputdialog.h> + +#include <libkcal/calendarlocal.h> +#include <libkcal/icalformat.h> + +#include "koprefs.h" +#include "koglobals.h" + +#include "koincidenceeditor.h" +#include "koincidenceeditor.moc" + +KOIncidenceEditor::KOIncidenceEditor( const QString &caption, + Calendar *calendar, QWidget *parent ) : + KDialogBase( Tabbed, caption, Ok | Apply | Cancel |/* Default | */User1, Ok, + parent, caption, true, false ), + mSaveTemplateDialog( 0 ) +{ + mCalendar = calendar; + + setButtonText( Default, i18n("Template...") ); + + QString saveTemplateText; + // if ( KOPrefs::instance()->mCompactDialogs ) { +// showButton( User1, false ); +// showButton( Apply, false ); +// } else { + showButton( Apply, false ); + saveTemplateText = i18n("Ok+Agenda"); + // } + setButtonText( User1, saveTemplateText ); + + //mCategoryDialog = new KPIM::CategorySelectDialog( KOPrefs::instance(), this ); + // KOGlobals::fitDialogToScreen( mCategoryDialog ); + + //connect(mCategoryDialog,SIGNAL(editCategories()),SIGNAL(editCategories())); + + //connect( this, SIGNAL( defaultClicked() ), SLOT( slotLoadTemplate() ) ); + // connect( this, SIGNAL( user1Clicked() ), SLOT( slotSaveTemplate() ) ); + connect( this, SIGNAL( user1Clicked() ), SLOT( slotShowIncidence() ) ); +} + +KOIncidenceEditor::~KOIncidenceEditor() +{ + //delete mCategoryDialog; +} + +void KOIncidenceEditor::setupAttendeesTab() +{ + QFrame *topFrame = addPage(i18n("Attendees")); + + QBoxLayout *topLayout = new QVBoxLayout(topFrame); + + mDetails = new KOEditorDetails(spacingHint(),topFrame); + topLayout->addWidget(mDetails); +} + + +void KOIncidenceEditor::slotApply() +{ + processInput( false ); +} +void KOIncidenceEditor::accept() +{ + slotOk(); +} +void KOIncidenceEditor::slotOk() +{ + if ( processInput( false ) ) QDialog::accept(); +} + +void KOIncidenceEditor::updateCategoryConfig() +{ + qDebug("KOIncidenceEditor::updateCategoryConfig() is dead! "); + //mCategoryDialog->updateCategoryConfig(); +} + +void KOIncidenceEditor::slotCancel() +{ + reject(); +} + +void KOIncidenceEditor::slotLoadTemplate() +{ + kdDebug() << "KOIncidenceEditor::loadTemplate()" << endl; +} +void KOIncidenceEditor::slotShowIncidence() +{ + + if ( processInput(true ) ) { + accept(); + } +} + +void KOIncidenceEditor::slotSaveTemplate() +{ + kdDebug() << "KOIncidenceEditor::saveTemplate()" << endl; +} + +void KOIncidenceEditor::createSaveTemplateDialog( SaveTemplateDialog::IncidenceType type ) +{ + if ( !mSaveTemplateDialog ) { + mSaveTemplateDialog = new SaveTemplateDialog( type, this ); + connect( mSaveTemplateDialog, SIGNAL( templateSelected( const QString & ) ), + SLOT( saveTemplate( const QString & ) ) ); + } + mSaveTemplateDialog->show(); + mSaveTemplateDialog->raise(); +} + +void KOIncidenceEditor::saveAsTemplate( Incidence *incidence, + const QString &templateName ) +{ + CalendarLocal cal; + cal.addIncidence( incidence ); + ICalFormat format; + format.save( &cal, templateName ); +} + +QString KOIncidenceEditor::loadTemplate( Calendar *cal, const QString &type, + const QStringList &templates ) +{ + // bool ok = false; +// QString templateName = KInputDialog::getItem( i18n("Load Template"), +// i18n("Select a template to load:"), templates, 0, &ok ); +// if ( !ok || templateName.isEmpty() ) return QString::null; + +// QString fileName = locateLocal( "data", "korganizer/templates/" + type + "/" + +// templateName ); +// fn =KFileDialog:: getOpenFileName( fn, "Import filename(*.ics/*.vcs)", this ); + + // QString fileName;// =locateLocal( "templates", incidence->type() ); +// fileName=KFileDialog:: getOpenFileName( fileName, "Load "+incidence()->type(), this ); +// if ( fileNamelength() == 0) +// return QString::null; +// if ( fileName.isEmpty() ) { +// KMessageBox::error( this, i18n("Unable to find template '%1'.") +// .arg( fileName ) ); +// return QString::null; +// } else { +// ICalFormat format; +// if ( !format.load( cal, fileName ) ) { +// KMessageBox::error( this, i18n("Error loading template file '%1'.") +// .arg( fileName ) ); +// return QString::null; +// } +// } + + return ""; +} diff --git a/korganizer/koincidenceeditor.h b/korganizer/koincidenceeditor.h new file mode 100644 index 0000000..bfd6cc6 --- a/dev/null +++ b/korganizer/koincidenceeditor.h @@ -0,0 +1,105 @@ +/* + 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 KOINCIDENCEEDITOR_H +#define KOINCIDENCEEDITOR_H + +#include <kdialogbase.h> + +#include <libkcal/calendar.h> + +#include "koeditordetails.h" +#include "savetemplatedialog.h" + +class QDateTime; +namespace KPIM { class CategorySelectDialog; } + +using namespace KCal; + +/** + This is the base class for the calendar component editors. +*/ +class KOIncidenceEditor : public KDialogBase +{ + Q_OBJECT + public: + /** + Construct new IncidenceEditor. + */ + KOIncidenceEditor( const QString &caption, Calendar *calendar, + QWidget *parent ); + virtual ~KOIncidenceEditor(); + + /** Initialize editor. This function creates the tab widgets. */ + virtual void init() = 0; + void accept(); + virtual void setCategories( QString )= 0; + + virtual void reload() = 0; + + public slots: + void updateCategoryConfig(); + + signals: + void editCategories(); + void showAgendaView( bool ); + void dialogClose( Incidence * ); + void jumpToTime( const QDate & ); + + protected slots: + void slotApply(); + void slotOk(); + void slotCancel(); + void slotShowIncidence(); + + virtual void slotLoadTemplate(); + virtual void slotSaveTemplate(); + + virtual void saveTemplate( const QString & ) = 0; + + protected: + void setupAttendeesTab(); + + void createSaveTemplateDialog( SaveTemplateDialog::IncidenceType ); + + QString loadTemplate( Calendar *cal, const QString &type, + const QStringList &templates ); + void saveAsTemplate( Incidence *, const QString &name ); + + /** + Process user input and create or update event. Returns false if input is invalid. + */ + virtual bool processInput( bool emitTime ) { return false; } + + Calendar *mCalendar; + + //KPIM::CategorySelectDialog *mCategoryDialog; + + KOEditorDetails *mDetails; + + private: + SaveTemplateDialog *mSaveTemplateDialog; +}; + +#endif + + diff --git a/korganizer/koincidenceeditor.moc b/korganizer/koincidenceeditor.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/koincidenceeditor.moc diff --git a/korganizer/kojournalview.cpp b/korganizer/kojournalview.cpp new file mode 100644 index 0000000..579f24d --- a/dev/null +++ b/korganizer/kojournalview.cpp @@ -0,0 +1,113 @@ +/* + 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. +*/ + +// +// View of Journal entries + +#include <qlayout.h> +#include <qpopupmenu.h> + +#include <klocale.h> +#include <kdebug.h> +#include "koprefs.h" + +#include <libkcal/calendar.h> + +#include "journalentry.h" + +#include "kojournalview.h" +using namespace KOrg; +#include "kojournalview.moc" + +KOJournalView::KOJournalView(Calendar *calendar, QWidget *parent, + const char *name) + : KOrg::BaseView(calendar, parent, name) +{ + mEntry = new JournalEntry(calendar,this); + mEntry->setFont ( KOPrefs::instance()->mJornalViewFont ); + QBoxLayout *topLayout = new QVBoxLayout(this); + topLayout->addWidget(mEntry); + connect ( mEntry,SIGNAL(deleteJournal(Journal *) ),this ,SIGNAL(deleteJournal(Journal *) ) ) ; +} + +KOJournalView::~KOJournalView() +{ +} + +int KOJournalView::currentDateCount() +{ + return 0; +} + +QPtrList<Incidence> KOJournalView::selectedIncidences() +{ + QPtrList<Incidence> eventList; + + return eventList; +} +void KOJournalView::updateConfig() +{ + mEntry->setFont ( KOPrefs::instance()->mJornalViewFont ); +} +void KOJournalView::updateView() +{ + mEntry->setFont ( KOPrefs::instance()->mJornalViewFont ); +} + +void KOJournalView::flushView() +{ + mEntry->flushEntry(); +} + +void KOJournalView::showDates(const QDate &start, const QDate &) +{ +// kdDebug() << "KOJournalView::selectDates()" << endl; + + mEntry->setDate(start); + + Journal *j = calendar()->journal(start); + if (j) mEntry->setJournal(j); + else mEntry->clear(); + +// emit incidenceSelected( 0 ); +} + +void KOJournalView::showEvents(QPtrList<Event>) +{ + // After new creation of list view no events are selected. +// emit incidenceSelected( 0 ); +} + +void KOJournalView::changeEventDisplay(Event *, int /*action*/) +{ + updateView(); +} + +void KOJournalView::keyPressEvent ( QKeyEvent * e ) +{ + //qDebug("keyPressEven "); + if ( e->state() == Qt::ControlButton ) { + if ( e->key () == Qt::Key_Right || e->key () == Qt::Key_Left ) + e->ignore(); + } +} diff --git a/korganizer/kojournalview.h b/korganizer/kojournalview.h new file mode 100644 index 0000000..1c0be82 --- a/dev/null +++ b/korganizer/kojournalview.h @@ -0,0 +1,67 @@ +/* + 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 _KOJOURNALVIEW_H +#define _KOJOURNALVIEW_H + +#include <korganizer/baseview.h> + +class JournalEntry; + +/** + * This class provides a journal view. + + * @short View for Journal components. + * @author Cornelius Schumacher <schumacher@kde.org> + * @see KOBaseView + */ +class KOJournalView : public KOrg::BaseView +{ + Q_OBJECT + public: + KOJournalView(Calendar *calendar, QWidget *parent = 0, + const char *name = 0); + ~KOJournalView(); + + virtual int currentDateCount(); + virtual QPtrList<Incidence> selectedIncidences(); + DateList selectedDates() + {DateList q; + return q;}; + signals: + void deleteJournal(Journal *); + public slots: + void updateView(); + void flushView(); + void updateConfig(); + void showDates( const QDate &start, const QDate &end ); + void showEvents(QPtrList<Event> eventList); + + void changeEventDisplay(Event *, int); + + private: + JournalEntry *mEntry; + void keyPressEvent ( QKeyEvent * ) ; + +}; + +#endif diff --git a/korganizer/kojournalview.moc b/korganizer/kojournalview.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/kojournalview.moc diff --git a/korganizer/kolistview.cpp b/korganizer/kolistview.cpp new file mode 100644 index 0000000..b6061d0 --- a/dev/null +++ b/korganizer/kolistview.cpp @@ -0,0 +1,1062 @@ +/* + This file is part of KOrganizer. + Copyright (c) 1999 Preston Brown + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qlistview.h> +#include <qlayout.h> +#include <qlabel.h> +#include <qpopupmenu.h> +#include <qprogressbar.h> +#include <qfileinfo.h> +#include <qmessagebox.h> +#include <qdialog.h> +#include <qtextstream.h> +#include <qdir.h> + +#include <klocale.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <kglobal.h> + +#include <libkcal/calendar.h> +#include <libkcal/calendarlocal.h> +#include <libkcal/icalformat.h> +#include <libkcal/vcalformat.h> +#include <libkcal/recurrence.h> +#include <libkcal/filestorage.h> +#include <libkdepim/categoryselectdialog.h> +#ifndef DESKTOP_VERSION +#include <qpe/qpeapplication.h> +#else +#include <qapplication.h> +#endif + +#ifndef KORG_NOPRINTER +#include "calprinter.h" +#endif +#include "koglobals.h" +#include "koprefs.h" +#include "kfiledialog.h" + +#include "kolistview.h" +#include "kolistview.moc" + +ListItemVisitor::ListItemVisitor(KOListViewItem *item, QDate date ) +{ + mItem = item; + mDate = date; +} + +ListItemVisitor::~ListItemVisitor() +{ +} + +bool ListItemVisitor::visit(Event *e) +{ + + bool ok = false; + QString start, end; + if ( e->doesRecur() ) { + QDate d = e->getNextOccurence( QDateTime( mDate, QTime(0,0,0)), &ok ).date(); + if ( ok ) { + int days = e->dtStart().date().daysTo(e->dtEnd().date() ); + start = KGlobal::locale()->formatDate(d,true); + end = KGlobal::locale()->formatDate(d.addDays( days),true); + } + + } + if ( ! ok ) { + start =e->dtStartDateStr(); + end = e->dtEndDateStr(); + } + mItem->setText(0,e->summary()); + mItem->setText(1,start); + mItem->setText(2,e->dtStartTimeStr()); + mItem->setText(3,end); + mItem->setText(4,e->dtEndTimeStr()); + mItem->setText(5,e->isAlarmEnabled() ? i18n("Yes") : i18n("No")); + mItem->setText(6, e->recurrence()->recurrenceText()); + mItem->setText(7,"---"); + mItem->setText(8,"---"); + mItem->setText(9, e->cancelled() ? i18n("Yes") : i18n("No")); + mItem->setText(10,e->categoriesStr()); + + QString key; + QDate d = e->dtStart().date(); + QTime t = e->doesFloat() ? QTime(0,0) : e->dtStart().time(); + key.sprintf("%04d%02d%02d%02d%02d",d.year(),d.month(),d.day(),t.hour(),t.minute()); + mItem->setSortKey(1,key); + + d = e->dtEnd().date(); + t = e->doesFloat() ? QTime(0,0) : e->dtEnd().time(); + key.sprintf("%04d%02d%02d%02d%02d",d.year(),d.month(),d.day(),t.hour(),t.minute()); + mItem->setSortKey(3,key); + + return true; +} + +bool ListItemVisitor::visit(Todo *t) +{ + mItem->setText(0,i18n("To-Do: %1").arg(t->summary())); + if (t->hasStartDate()) { + mItem->setText(1,t->dtStartDateStr()); + if (t->doesFloat()) { + mItem->setText(2,"---"); + } else { + mItem->setText(2,t->dtStartTimeStr()); + } + } else { + mItem->setText(1,"---"); + mItem->setText(2,"---"); + } + mItem->setText(3,"---"); + mItem->setText(4,"---"); + mItem->setText(5,"---"); + mItem->setText(6,"---"); + if (t->hasDueDate()) { + mItem->setText(7,t->dtDueDateStr()); + if (t->doesFloat()) { + mItem->setText(8,"---"); + } else { + mItem->setText(8,t->dtDueTimeStr()); + } + } else { + mItem->setText(7,"---"); + mItem->setText(8,"---"); + } + mItem->setText(9, t->cancelled() ? i18n("Yes") : i18n("No")); + mItem->setText(10,t->categoriesStr()); + + QString key; + QDate d; + if (t->hasDueDate()) { + d = t->dtDue().date(); + QTime tm = t->doesFloat() ? QTime(0,0) : t->dtDue().time(); + key.sprintf("%04d%02d%02d%02d%02d",d.year(),d.month(),d.day(),tm.hour(),tm.minute()); + mItem->setSortKey(7,key); + } + if ( t->hasStartDate() ) { + d = t->dtStart().date(); + QTime tm = t->doesFloat() ? QTime(0,0) : t->dtStart().time(); + key.sprintf("%04d%02d%02d%02d%02d",d.year(),d.month(),d.day(),tm.hour(),tm.minute()); + mItem->setSortKey(1,key); + } + return true; +} + +bool ListItemVisitor::visit(Journal * j) +{ + mItem->setText(0,i18n("Journal")); + mItem->setText(1,j->dtStartDateStr()); + mItem->setText(2,"---"); + mItem->setText(3,"---"); + mItem->setText(4,"---"); + mItem->setText(5,"---"); + mItem->setText(6,"---"); + mItem->setText(7,j->dtStartDateStr()); + mItem->setText(8,"---"); + mItem->setText(9,"---"); + + QString key; + QDate d = j->dtStart().date(); + key.sprintf("%04d%02d%02d",d.year(),d.month(),d.day()); + mItem->setSortKey(1,key); + mItem->setSortKey(7,key); + + return true; +} + +KOListView::KOListView(Calendar *calendar, QWidget *parent, + const char *name) + : KOEventView(calendar, parent, name) +{ + mActiveItem = 0; + mListView = new KOListViewListView(this); + mListView->addColumn(i18n("Summary")); + mListView->addColumn(i18n("Start Date")); + mListView->addColumn(i18n("Start Time")); + mListView->addColumn(i18n("End Date")); + mListView->addColumn(i18n("End Time")); + mListView->addColumn(i18n("Alarm")); // alarm set? + mListView->addColumn(i18n("Recurs")); // recurs? + mListView->addColumn(i18n("Due Date")); + mListView->addColumn(i18n("Due Time")); + mListView->addColumn(i18n("Cancelled")); + mListView->addColumn(i18n("Categories")); + + mListView->setColumnAlignment(0,AlignLeft); + mListView->setColumnAlignment(1,AlignLeft); + mListView->setColumnAlignment(2,AlignHCenter); + mListView->setColumnAlignment(3,AlignLeft); + mListView->setColumnAlignment(4,AlignHCenter); + mListView->setColumnAlignment(5,AlignLeft); + mListView->setColumnAlignment(6,AlignLeft); + mListView->setColumnAlignment(7,AlignLeft); + mListView->setColumnAlignment(8,AlignLeft); + mListView->setColumnAlignment(9,AlignLeft); + mListView->setColumnAlignment(10,AlignLeft); + + int iii = 0; + for ( iii = 0; iii< 10 ; ++iii ) + mListView->setColumnWidthMode( iii, QListView::Manual ); + + QBoxLayout *layoutTop = new QVBoxLayout(this); + layoutTop->addWidget(mListView); + mListView->setFont ( KOPrefs::instance()->mListViewFont ); + mPopupMenu = eventPopup(); + mPopupMenu->addAdditionalItem(QIconSet(QPixmap()), + i18n("Select all"),this, + SLOT(allSelection()),true); + mPopupMenu->addAdditionalItem(QIconSet(QPixmap()), + i18n("Deselect All"),this, + SLOT(clearSelection()),true); + mPopupMenu->addAdditionalItem(QIconSet(QPixmap()), + i18n("Delete all selected"),this, + SLOT(deleteAll()),true); + mPopupMenu->insertSeparator(); + mPopupMenu->addAdditionalItem(QIconSet(QPixmap()), + i18n("Save selected to file..."),this, + SLOT(saveToFile()),true); + mPopupMenu->addAdditionalItem(QIconSet(QPixmap()), + i18n("Save Journal/Description..."),this, + SLOT(saveDescriptionToFile()),true); + mPopupMenu->insertSeparator(); + mPopupMenu->addAdditionalItem(QIconSet(QPixmap()), + i18n("Add Categ. to selected..."),this, + SLOT(addCat()),true); + mPopupMenu->addAdditionalItem(QIconSet(QPixmap()), + i18n("Set Categ. for selected..."),this, + SLOT(setCat()),true); + mPopupMenu->insertSeparator(); + + +#ifndef DESKTOP_VERSION + mPopupMenu->addAdditionalItem(QIconSet(QPixmap()), + i18n("Beam selected via IR"),this, + SLOT(beamSelected()),true); +#endif + /* + mPopupMenu = new QPopupMenu; + mPopupMenu->insertItem(i18n("Edit Event"), this, + SLOT (editEvent())); + mPopupMenu->insertItem(SmallIcon("delete"), i18n("Delete Event"), this, + SLOT (deleteEvent())); + mPopupMenu->insertSeparator(); + mPopupMenu->insertItem(i18n("Show Dates"), this, + SLOT(showDates())); + mPopupMenu->insertItem(i18n("Hide Dates"), this, + SLOT(hideDates())); + */ + QObject::connect(mListView,SIGNAL( newEvent()), + this,SIGNAL(signalNewEvent())); + QObject::connect(mListView,SIGNAL(doubleClicked(QListViewItem *)), + this,SLOT(defaultItemAction(QListViewItem *))); + QObject::connect(mListView,SIGNAL(rightButtonClicked ( QListViewItem *, + const QPoint &, int )), + this,SLOT(popupMenu(QListViewItem *,const QPoint &,int))); + QObject::connect(mListView,SIGNAL(currentChanged(QListViewItem *)), + SLOT(processSelectionChange(QListViewItem *))); + QObject::connect(mListView,SIGNAL(showIncidence(Incidence *)), + SIGNAL(showIncidenceSignal(Incidence *)) ); + + readSettings(KOGlobals::config(),"KOListView Layout"); +} + +KOListView::~KOListView() +{ + delete mPopupMenu; +} + +void KOListView::updateList() +{ + // qDebug(" KOListView::updateList() "); + +} + +void KOListView::addCat( ) +{ + setCategories( false ); +} +void KOListView::setCat() +{ + setCategories( true ); +} +void KOListView::setCategories( bool removeOld ) +{ + + KPIM::CategorySelectDialog* csd = new KPIM::CategorySelectDialog( KOPrefs::instance(), 0 ); + if (! csd->exec()) { + delete csd; + return; + } + QStringList catList = csd->selectedCategories(); + delete csd; + // if ( catList.count() == 0 ) + // return; + catList.sort(); + QString categoriesStr = catList.join(","); + int i; + QStringList itemList; + QPtrList<KOListViewItem> sel ; + QListViewItem *qitem = mListView->firstChild (); + while ( qitem ) { + if ( qitem->isSelected() ) { + sel.append(((KOListViewItem *)qitem)); + } + qitem = qitem->nextSibling(); + } + KOListViewItem * item, *temp; + item = sel.first(); + Incidence* inc; + while ( item ) { + inc = item->data(); + if ( removeOld ) { + inc->setCategories( categoriesStr ); + } else { + itemList = QStringList::split (",", inc->categoriesStr() ); + for( i = 0; i< catList.count(); ++i ) { + if ( !itemList.contains (catList[i])) + itemList.append( catList[i] ); + } + itemList.sort(); + inc->setCategories( itemList.join(",") ); + } + temp = item; + item = sel.next(); + mUidDict.remove( inc->uid() ); + delete temp;; + addIncidence( inc ); + } +} + +void KOListView::beamSelected() +{ + int icount = 0; + QPtrList<Incidence> delSel ; + QListViewItem *item = mListView->firstChild (); + while ( item ) { + if ( item->isSelected() ) { + delSel.append(((KOListViewItem *)item)->data()); + ++icount; + } + + item = item->nextSibling(); + } + if ( icount ) { + emit beamIncidenceList( delSel ); + return; + QString fn ; + fn = QDir::homeDirPath()+"/kopitempbeamfile.vcs"; + QString mes; + bool createbup = true; + if ( createbup ) { + QString description = "\n"; + CalendarLocal* cal = new CalendarLocal(); + cal->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); + Incidence *incidence = delSel.first(); + while ( incidence ) { + Incidence *in = incidence->clone(); + description += in->summary() + "\n"; + cal->addIncidence( in ); + incidence = delSel.next(); + } + FileStorage storage( cal, fn, new VCalFormat ); + storage.save(); + delete cal; + mes = i18n("KO/Pi: Ready for beaming"); + topLevelWidget()->setCaption(mes); + +#ifndef DESKTOP_VERSION + Ir *ir = new Ir( this ); + connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) ); + ir->send( fn, description, "text/x-vCalendar" ); +#endif + } + } +} +void KOListView::beamDone( Ir *ir ) +{ +#ifndef DESKTOP_VERSION + delete ir; +#endif + topLevelWidget()->setCaption(i18n("KO/Pi:Beaming done")); +} + +void KOListView::saveDescriptionToFile() +{ + + int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"), + i18n("This saves the text/details of selected\nJournals and Events/Todos\nto a text file."), + i18n("Continue"), i18n("Cancel"), 0, + 0, 1 ); + if ( result != 0 ) { + return; + } + int icount = 0; + QPtrList<Incidence> delSel ; + QListViewItem *item = mListView->firstChild (); + while ( item ) { + if ( item->isSelected() ) { + delSel.append(((KOListViewItem *)item)->data()); + ++icount; + } + + item = item->nextSibling(); + } + if ( icount ) { + QString fn = KOPrefs::instance()->mLastSaveFile; + fn = KFileDialog::getSaveFileName( fn, i18n("Save filename"), this ); + + if ( fn == "" ) + return; + QFileInfo info; + info.setFile( fn ); + QString mes; + bool createbup = true; + if ( info. exists() ) { + mes = i18n("File already exists!\nOld file from:\n%1\nOverwrite?\n").arg (KGlobal::locale()->formatDateTime(info.lastModified (), true, false ) ); + int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"),mes, + i18n("Overwrite!"), i18n("Cancel"), 0, + 0, 1 ); + if ( result != 0 ) { + createbup = false; + } + } + if ( createbup ) { + QString text = i18n("KO/Pi Description/Journal save file.\nSave date: ") + + KGlobal::locale()->formatDateTime(QDateTime::currentDateTime(), false); + Incidence *incidence = delSel.first(); + icount = 0; + while ( incidence ) { + if ( incidence->type() == "Journal" ) { + text += "\n************************************\n"; + text += i18n("Journal from: ") +incidence->dtStartDateStr( false ); + text +="\n" + i18n("Last modified: ") +KGlobal::locale()->formatDateTime(incidence->lastModified(), false); + text +="\n" + i18n("Description: ") + "\n"+ incidence->description(); + ++icount; + + } else { + if ( !incidence->description().isEmpty() ) { + text += "\n************************************\n"; + if ( incidence->type() == "Todo" ) + text += i18n("To-Do: "); + text += incidence->summary(); + if ( incidence->hasStartDate() ) + text +="\n"+ i18n("Start Date: ") + incidence->dtStartStr( false ); + text +="\n"+ i18n("Last modified: ") +KGlobal::locale()->formatDateTime(incidence->lastModified(), false); + if ( !incidence->location().isEmpty() ) + text += "\n" +i18n("Location: ") + incidence->location(); + text += "\n" + i18n("Description: ") + "\n" + incidence->description(); + ++icount; + + } + } + incidence = delSel.next(); + } + QFile file( fn ); + if (!file.open( IO_WriteOnly ) ) { + topLevelWidget()->setCaption(i18n("File open error - nothing saved!") ); + return; + } + QTextStream ts( &file ); + ts << text; + file.close(); + //qDebug("%s ", text.latin1()); + mes = i18n("KO/Pi:Saved %1 descriptions/journals").arg(icount ); + KOPrefs::instance()->mLastSaveFile = fn; + topLevelWidget()->setCaption(mes); + } + } +} +void KOListView::saveToFile() +{ + + int icount = 0; + QPtrList<Incidence> delSel ; + QListViewItem *item = mListView->firstChild (); + while ( item ) { + if ( item->isSelected() ) { + delSel.append(((KOListViewItem *)item)->data()); + ++icount; + } + + item = item->nextSibling(); + } + if ( icount ) { + QString fn = KOPrefs::instance()->mLastSaveFile; + fn = KFileDialog::getSaveFileName( fn, i18n("Save filename"), this ); + + if ( fn == "" ) + return; + QFileInfo info; + info.setFile( fn ); + QString mes; + bool createbup = true; + if ( info. exists() ) { + mes = i18n("File already exists!\nOld file from:\n%1\nOverwrite?\n").arg (KGlobal::locale()->formatDateTime(info.lastModified (), true, false ) ); + int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"),mes, + i18n("Overwrite!"), i18n("Cancel"), 0, + 0, 1 ); + if ( result != 0 ) { + createbup = false; + } + } + if ( createbup ) { + CalendarLocal cal; + cal.setTimeZoneId(KOPrefs::instance()->mTimeZoneId); + Incidence *incidence = delSel.first(); + while ( incidence ) { + cal.addIncidence( incidence->clone() ); + incidence = delSel.next(); + } + ICalFormat format; + format.save( &cal, fn ); + mes = i18n("KO/Pi:Saved %1").arg(fn ); + KOPrefs::instance()->mLastSaveFile = fn; + topLevelWidget()->setCaption(mes); + } + } +} +void KOListView::deleteAll() +{ + int icount = 0; + QPtrList<Incidence> delSel ; + QListViewItem *item = mListView->firstChild (); + while ( item ) { + if ( item->isSelected() ) { + delSel.append(((KOListViewItem *)item)->data()); + ++icount; + } + + item = item->nextSibling(); + } + if ( icount ) { + Incidence *incidence = delSel.first(); + Incidence *toDelete; + KOPrefs *p = KOPrefs::instance(); + bool confirm = p->mConfirm; + QString mess; + mess = mess.sprintf( i18n("You have %d item(s) selected.\n"), icount ); + if ( KMessageBox::Continue == KMessageBox::warningContinueCancel(this, mess + i18n("All selected items will be\npermanently deleted.\n(Deleting items will take\nsome time on a PDA)\n"), i18n("KO/Pi Confirmation"),i18n("Delete")) ) { + p->mConfirm = false; + int delCounter = 0; + QDialog dia ( this, "p-dialog", true ); + QLabel lab (i18n("Close dialog to abort deletion!"), &dia ); + QVBoxLayout lay( &dia ); + lay.setMargin(7); + lay.setSpacing(7); + lay.addWidget( &lab); + QProgressBar bar( icount, &dia ); + lay.addWidget( &bar); + int w = 220; + int h = 50; + int dw = QApplication::desktop()->width(); + int dh = QApplication::desktop()->height(); + dia.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); + //dia.resize( 240,50 ); + dia.show(); + + while ( incidence ) { + bar.setProgress( delCounter ); + mess = mess.sprintf( i18n("Deleting item %d ..."), ++delCounter ); + dia.setCaption( mess ); + qApp->processEvents(); + toDelete = (incidence); + incidence = delSel.next(); + emit deleteIncidenceSignal(toDelete ); + if ( dia.result() != 0 ) + break; + + } + mess = mess.sprintf( i18n("%d items remaining in list."), count() ); + topLevelWidget ()->setCaption( mess ); + p->mConfirm = confirm; + } + } + + +} +int KOListView::maxDatesHint() +{ + return 0; +} + +int KOListView::currentDateCount() +{ + return 0; +} + +QPtrList<Incidence> KOListView::selectedIncidences() +{ + QPtrList<Incidence> eventList; + QListViewItem *item = mListView->firstChild (); + while ( item ) { + if ( item->isSelected() ) { + eventList.append(((KOListViewItem *)item)->data()); + } + + item = item->nextSibling(); + } + + // // QListViewItem *item = mListView->selectedItem(); + //if (item) eventList.append(((KOListViewItem *)item)->data()); + + return eventList; +} + +DateList KOListView::selectedDates() +{ + DateList eventList; + return eventList; +} + +void KOListView::showDates(bool show) +{ + // Shouldn't we set it to a value greater 0? When showDates is called with + // show == true at first, then the columnwidths are set to zero. + static int oldColWidth1 = 0; + static int oldColWidth3 = 0; + + if (!show) { + oldColWidth1 = mListView->columnWidth(1); + oldColWidth3 = mListView->columnWidth(3); + mListView->setColumnWidth(1, 0); + mListView->setColumnWidth(3, 0); + } else { + mListView->setColumnWidth(1, oldColWidth1); + mListView->setColumnWidth(3, oldColWidth3); + } + mListView->repaint(); +} + +void KOListView::printPreview(CalPrinter *calPrinter, const QDate &fd, + const QDate &td) +{ +#ifndef KORG_NOPRINTER + calPrinter->preview(CalPrinter::Day, fd, td); +#endif +} + +void KOListView::showDates() +{ + showDates(true); +} + +void KOListView::hideDates() +{ + showDates(false); +} + +void KOListView::updateView() +{ + mListView->setFocus(); + if ( mListView->firstChild () ) + mListView->setCurrentItem( mListView->firstChild () ); +} +void KOListView::updateConfig() +{ + + mListView->setFont ( KOPrefs::instance()->mListViewFont ); + updateView(); + +} +void KOListView::setStartDate(const QDate &start) +{ + mStartDate = start; +} + +void KOListView::showDates(const QDate &start, const QDate &end) +{ + clear(); + mStartDate = start; + QDate date = start; + while( date <= end ) { + addEvents(calendar()->events(date)); + addTodos(calendar()->todos(date)); + date = date.addDays( 1 ); + } + emit incidenceSelected( 0 ); + updateView(); + +} + +void KOListView::addEvents(QPtrList<Event> eventList) +{ + Event *ev; + for(ev = eventList.first(); ev; ev = eventList.next()) { + addIncidence(ev); + } + if ( !mListView->currentItem() ){ + updateView(); + } +} + +void KOListView::addTodos(QPtrList<Todo> eventList) +{ + Todo *ev; + for(ev = eventList.first(); ev; ev = eventList.next()) { + addIncidence(ev); + } + if ( !mListView->currentItem() ){ + updateView(); + } +} +void KOListView::addJournals(QPtrList<Journal> eventList) +{ + Journal *ev; + for(ev = eventList.first(); ev; ev = eventList.next()) { + addIncidence(ev); + } + if ( !mListView->currentItem() ){ + updateView(); + } +} + +void KOListView::addIncidence(Incidence *incidence) +{ + if ( mUidDict.find( incidence->uid() ) ) return; + + // mListView->setFont ( KOPrefs::instance()->mListViewFont ); + mUidDict.insert( incidence->uid(), incidence ); + + KOListViewItem *item = new KOListViewItem( incidence, mListView ); + ListItemVisitor v(item, mStartDate ); + if (incidence->accept(v)) return; + else delete item; + //qDebug("delete item "); +} + +void KOListView::showEvents(QPtrList<Event> eventList) +{ + clear(); + + addEvents(eventList); + + // After new creation of list view no events are selected. + emit incidenceSelected( 0 ); +} +int KOListView::count() +{ + return mListView->childCount(); +} + +void KOListView::changeEventDisplay(Event *event, int action) +{ + KOListViewItem *item; + + switch(action) { + case KOGlobals::EVENTADDED: + addIncidence( event ); + break; + case KOGlobals::EVENTEDITED: + item = getItemForEvent(event); + if (item) { + mUidDict.remove( event->uid() ); + delete item; + addIncidence( event ); + } + break; + case KOGlobals::EVENTDELETED: + item = getItemForEvent(event); + if (item) { + mUidDict.remove( event->uid() ); + delete item; + } + break; + default: + ; + } +} + +KOListViewItem *KOListView::getItemForEvent(Event *event) +{ + KOListViewItem *item = (KOListViewItem *)mListView->firstChild(); + while (item) { + if (item->data() == event) return item; + item = (KOListViewItem *)item->nextSibling(); + } + return 0; +} + +void KOListView::defaultItemAction(QListViewItem *i) +{ + KOListViewItem *item = static_cast<KOListViewItem *>( i ); + if ( item ) defaultAction( item->data() ); + +} + +void KOListView::popupMenu(QListViewItem *item,const QPoint &,int) +{ + mActiveItem = (KOListViewItem *)item; + if (mActiveItem) { + Incidence *incidence = mActiveItem->data(); + mPopupMenu->showIncidencePopup(incidence); + + /* + if ( incidence && incidence->type() == "Event" ) { + Event *event = static_cast<Event *>( incidence ); + mPopupMenu->showEventPopup(event); + } + */ + } +} + +void KOListView::readSettings(KConfig *config, QString setting) +{ + // qDebug("KOListView::readSettings "); + mListView->restoreLayout(config,setting); +} + +void KOListView::writeSettings(KConfig *config, QString setting) +{ + // qDebug("KOListView::writeSettings "); + mListView->saveLayout(config, setting); +} + +void KOListView::processSelectionChange(QListViewItem *) +{ + + KOListViewItem *item = + static_cast<KOListViewItem *>( mListView->currentItem() ); + + if ( !item ) { + emit incidenceSelected( 0 ); + } else { + emit incidenceSelected( item->data() ); + } +} + +void KOListView::clearSelection() +{ + mListView->selectAll( false ); +} +void KOListView::allSelection() +{ + mListView->selectAll( true ); +} + +void KOListView::clear() +{ + mListView->clear(); + mUidDict.clear(); +} + +Incidence* KOListView::currentItem() +{ + if ( mListView->currentItem() ) + return ((KOListViewItem*) mListView->currentItem())->data(); + return 0; +} +void KOListView::keyPressEvent ( QKeyEvent *e) +{ + + if ( e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace ) { + deleteAll(); + return; + } + + e->ignore(); +} +void KOListViewListView::keyPressEvent ( QKeyEvent *e) +{ + + switch ( e->key() ) { + case Qt::Key_Down: + if ( e->state() == ShiftButton ) { + QListViewItem* cn = currentItem(); + if ( !cn ) + cn = firstChild(); + if ( !cn ) + return; + while ( cn->nextSibling() ) + cn = cn->nextSibling(); + setCurrentItem ( cn ); + ensureItemVisible ( cn ); + + e->accept(); + return; + } + if ( e->state() == ControlButton ) { + int count = childCount (); + int jump = count / 5; + QListViewItem* cn; + cn = currentItem(); + if ( ! cn ) + return; + if ( jump == 0 ) + jump = 1; + while ( jump && cn->nextSibling() ) { + cn = cn->nextSibling(); + --jump; + } + setCurrentItem ( cn ); + ensureItemVisible ( cn ); + + } else + QListView::keyPressEvent ( e ) ; + e->accept(); + break; + + case Qt::Key_Up: + if ( e->state() == ShiftButton ) { + QListViewItem* cn = firstChild(); + if ( cn ) { + setCurrentItem ( cn ); + ensureItemVisible ( cn ); + } + e->accept(); + return; + } + if ( e->state() == ControlButton ) { + int count = childCount (); + int jump = count / 5; + QListViewItem* cn; + cn = currentItem(); + if ( ! cn ) + return; + if ( jump == 0 ) + jump = 1; + while ( jump && cn->itemAbove ()) { + cn = cn->itemAbove (); + --jump; + } + setCurrentItem ( cn ); + ensureItemVisible ( cn ); + } else + QListView::keyPressEvent ( e ) ; + e->accept(); + break; + case Qt::Key_I: { + QListViewItem* cn; + cn = currentItem(); + if ( cn ) { + KOListViewItem* ci = (KOListViewItem*)( cn ); + if ( ci ){ + emit showIncidence( ci->data()); + cn = cn->nextSibling(); + if ( cn ) { + setCurrentItem ( cn ); + ensureItemVisible ( cn ); + } + } + } + e->accept(); + } + break; + case Qt::Key_Return: + case Qt::Key_Enter: + { + QListViewItem* cn; + cn = currentItem(); + if ( cn ) { + KOListViewItem* ci = (KOListViewItem*)( cn ); + if ( ci ){ + if ( e->state() == ShiftButton ) + ci->setSelected( false ); + else + ci->setSelected( true ); + cn = cn->nextSibling(); + if ( cn ) { + setCurrentItem ( cn ); + ensureItemVisible ( cn ); + } + } + } + e->accept(); + } + break; + default: + e->ignore(); + } +} +KOListViewListView::KOListViewListView(KOListView * lv ) + : KListView( lv ) +{ +#ifndef DESKTOP_VERSION + QPEApplication::setStylusOperation(viewport(), QPEApplication::RightOnHold ); +#endif + setSelectionMode( QListView::Multi ); + setMultiSelection( true); + mAllowPopupMenu = true; + mMouseDown = false; + +} +void KOListViewListView::contentsMouseDoubleClickEvent(QMouseEvent *e) +{ + if (!e) return; + QPoint vp = contentsToViewport(e->pos()); + QListViewItem *item = itemAt(vp); + if (!item) { + emit newEvent(); + return; + } + KListView::contentsMouseDoubleClickEvent(e); +} + + +void KOListViewListView::contentsMousePressEvent(QMouseEvent *e) +{ + //qDebug("contentsMousePressEvent++++ "); + if (! mMouseDown ) { + mAllowPopupMenu = true; + mYMousePos = mapToGlobal( (e->pos())).y(); + } + if ( e->button() == RightButton && mMouseDown ) + return; + if ( e->button() == LeftButton ) + mMouseDown = true; + KListView::contentsMousePressEvent( e ); +} +void KOListViewListView::contentsMouseReleaseEvent(QMouseEvent *e) +{ + //qDebug("contentsMouseReleaseEv---- "); + if ( ! mMouseDown ) { + if ( e->button() == RightButton && ! mAllowPopupMenu ) + return; + QListViewItem* ci = currentItem(); + if ( ci ) + ci->setSelected( true ); + KListView::contentsMouseReleaseEvent(e); + return; + } + if ( e->button() == LeftButton ) + mMouseDown = false; + if ( e->button() == RightButton && ! mAllowPopupMenu ) + return; + if ( e->button() == RightButton ) { + QListViewItem* ci = currentItem(); + if ( ci ) + ci->setSelected( true ); + } + KListView::contentsMouseReleaseEvent(e); +} +void KOListViewListView::contentsMouseMoveEvent(QMouseEvent *e) +{ + // qDebug("contentsMouseMoveEv....... "); + // qDebug("start: %d current %d ",mYMousePos , mapToGlobal( (e->pos())).y() ); + int diff = mYMousePos - mapToGlobal( (e->pos())).y(); + if ( diff < 0 ) diff = -diff; + if ( diff > 20 ) + mAllowPopupMenu = false; + KListView::contentsMouseMoveEvent(e); +} diff --git a/korganizer/kolistview.h b/korganizer/kolistview.h new file mode 100644 index 0000000..23afdb1 --- a/dev/null +++ b/korganizer/kolistview.h @@ -0,0 +1,167 @@ +/* + This file is part of KOrganizer. + Copyright (c) 1999 Preston Brown + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ +#ifndef _KOLISTVIEW_H +#define _KOLISTVIEW_H + +#include <qlistview.h> +#include <qmap.h> +#include <qdict.h> + +#include <klistview.h> + +#ifndef DESKTOP_VERSION +#include <qtopia/ir.h> +#else +#define Ir char +#endif +#include <libkcal/incidence.h> + +#include "koeventview.h" +#include "customlistviewitem.h" + +using namespace KCal; + +typedef CustomListViewItem<Incidence *> KOListViewItem; + +/** + This class provides the initialisation of a KOListViewItem for calendar + components using the Incidence::Visitor. +*/ +class ListItemVisitor : public Incidence::Visitor +{ + public: + ListItemVisitor(KOListViewItem *, QDate d); + ~ListItemVisitor(); + + bool visit(Event *); + bool visit(Todo *); + bool visit(Journal *); + + private: + KOListViewItem *mItem; + QDate mDate; +}; + +/** + This class provides a multi-column list view of events. It can + display events from one particular day or several days, it doesn't + matter. To use a view that only handles one day at a time, use + KODayListView. + + @short multi-column list view of various events. + @author Preston Brown <pbrown@kde.org> + @see KOBaseView, KODayListView +*/ +class KOListView; + +class KOListViewListView : public KListView +{ + Q_OBJECT + public: + KOListViewListView(KOListView * lv ); + signals: + void newEvent(); + void showIncidence( Incidence* ); + private: + void keyPressEvent ( QKeyEvent * ) ; + void contentsMouseDoubleClickEvent(QMouseEvent *e); + void contentsMousePressEvent(QMouseEvent *e); + void contentsMouseReleaseEvent(QMouseEvent *e); + void contentsMouseMoveEvent(QMouseEvent *e); + bool mAllowPopupMenu; + bool mMouseDown; + int mYMousePos; +}; + +class KOListView : public KOEventView +{ + Q_OBJECT + public: + KOListView(Calendar *calendar, QWidget *parent = 0, + const char *name = 0); + ~KOListView(); + + virtual int maxDatesHint(); + virtual int currentDateCount(); + virtual QPtrList<Incidence> selectedIncidences(); + virtual DateList selectedDates(); + + void showDates(bool show); + Incidence* currentItem(); + void addTodos(QPtrList<Todo> eventList); + void addJournals(QPtrList<Journal> eventList); + virtual void printPreview(CalPrinter *calPrinter, + const QDate &, const QDate &); + + void readSettings(KConfig *config, QString setting = "KOListView Layout"); + void writeSettings(KConfig *config, QString setting = "KOListView Layout"); + void updateList(); + void setStartDate(const QDate &start); + int count(); + signals: + void signalNewEvent(); + void beamIncidenceList(QPtrList<Incidence>); + + public slots: + virtual void updateView(); + virtual void showDates(const QDate &start, const QDate &end); + virtual void showEvents(QPtrList<Event> eventList); + void clearSelection(); + void allSelection(); + + void clear(); + void beamDone( Ir *ir ); + void showDates(); + void hideDates(); + void deleteAll(); + void saveToFile(); + void saveDescriptionToFile(); + void beamSelected(); + void updateConfig(); + void addCat(); + void setCat(); + void setCategories( bool removeOld ); + void changeEventDisplay(Event *, int); + + void defaultItemAction(QListViewItem *item); + void popupMenu(QListViewItem *item,const QPoint &,int); + + protected slots: + void processSelectionChange(QListViewItem *); + + protected: + void addEvents(QPtrList<Event> eventList); + void addIncidence(Incidence *); + KOListViewItem *getItemForEvent(Event *event); + + private: + KOListViewListView *mListView; + KOEventPopupMenu *mPopupMenu; + KOListViewItem *mActiveItem; + QDict<Incidence> mUidDict; + QDate mStartDate; + void keyPressEvent ( QKeyEvent * ) ; +}; + +#endif diff --git a/korganizer/kolistview.moc b/korganizer/kolistview.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/kolistview.moc diff --git a/korganizer/kolocationbox.cpp b/korganizer/kolocationbox.cpp new file mode 100644 index 0000000..f8fee2e --- a/dev/null +++ b/korganizer/kolocationbox.cpp @@ -0,0 +1,96 @@ +/* + Copyright (c) 2004 Dirk Loesche <dirk.loesche@bigfoot.de> + + This file is part of KOrganizer/PI + KOrganizer Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> + KOrganizer/PI Copyright (c) 2004 Lutz Rogowski <lutz@pi-sync.net> + + 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. +*/ + +#include "kolocationbox.h" +#include <qstring.h> +#include <qlineedit.h> +#include <qapplication.h> + + +KOLocationBox::KOLocationBox( bool rw , QWidget *parent , int _maxItems) : + QComboBox( rw , parent ) +{ + maxItems = _maxItems; + maxItems = 50; // sorry - hack from me to set maxitems globally to 30 + setInsertionPolicy(AtTop); + setDuplicatesEnabled( FALSE ); + setMaxCount( maxItems ); + setAutoCompletion( TRUE ); + +} + +KOLocationBox::~KOLocationBox() +{ +} + +void KOLocationBox::load(int what) +{ + clear(); + // qDebug("load %d ",what ); + switch(what) { + case LOCATION: + insertStringList( KOPrefs::instance()->mLocationDefaults, 0 ); +// insertStringList( KOPrefs::instance()->mLocationUserDefaults, 0 ); + break; // don't disable + case SUMMARYEVENT: + insertStringList( KOPrefs::instance()->mEventSummaryUser, 0 ); + break; // don't disable + case SUMMARYTODO: + insertStringList( KOPrefs::instance()->mTodoSummaryUser, 0 ); + break; // don't disable + } +} + +void KOLocationBox::save(int what) +{ + strlist.clear(); + for( int l = 0; l < count() ; l++ ) { + strlist << text( l ); + } + // strlist.sort(); + QString currentLine = lineEdit()->text(); + if ( !strlist.contains( currentLine ) ) + strlist.prepend( currentLine ); + // qDebug("save %d ", what); + switch(what) { + case LOCATION: + KOPrefs::instance()->mLocationDefaults = strlist; +// KOPrefs::instance()->mLocationUserDefaults = strlist; + break; // don't disable + case SUMMARYEVENT: + KOPrefs::instance()->mEventSummaryUser = strlist; + break; // don't disable + case SUMMARYTODO: + KOPrefs::instance()->mTodoSummaryUser = strlist; + break; // don't disable + } +} + +void KOLocationBox::clearItems(int what) +{ + clear(); + save(what); +} diff --git a/korganizer/kolocationbox.h b/korganizer/kolocationbox.h new file mode 100644 index 0000000..be8ea86 --- a/dev/null +++ b/korganizer/kolocationbox.h @@ -0,0 +1,55 @@ +/* + File Copyright (c) 2004 Dirk Loesche <dirk.loesche@bigfoot.de> + + This file is part of KOrganizer/PI + KOrganizer Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> + KOrganizer/PI Copyright (c) 2004 Lutz Rogowski <lutz@pi-sync.net> + + 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 KOLOCATIONBOX_H +#define KOLOCATIONBOX_H + +#include <qcombobox.h> +#include "koprefs.h" + +class KOLocationBox : public QComboBox +{ + public: + KOLocationBox( bool rw , QWidget *parent , int _maxItems ); + virtual ~KOLocationBox(); + + enum {LOCATION, SUMMARYEVENT, SUMMARYTODO}; + + public slots: + void load(int); + void save(int); + void clearItems(int); // clear listbox and config rc items + + protected: +// void focusOutEvent( QFocusEvent * ); +// void timerEvent( QTimerEvent * ); + + private: + int maxItems; // maximal listbox items + QStringList strlist; // temporary stringlist +}; + +#endif diff --git a/korganizer/komonthview.cpp b/korganizer/komonthview.cpp new file mode 100644 index 0000000..c4bc51b --- a/dev/null +++ b/korganizer/komonthview.cpp @@ -0,0 +1,1057 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include <qpopupmenu.h> +#include <qfont.h> +#include <qfontmetrics.h> +#include <qkeycode.h> +#include <qhbox.h> +#include <qvbox.h> +#include <qpushbutton.h> +#include <qtooltip.h> +#include <qpainter.h> +#include <qwhatsthis.h> +#ifndef DESKTOP_VERSION +#include <qpe/qpeapplication.h> +#else +#include <qapplication.h> +#endif + +#include <kdebug.h> +#include <klocale.h> +#include <kglobal.h> +#include <kconfig.h> +#include <kiconloader.h> + +#include <kcalendarsystem.h> + +#ifndef KORG_NOPRINTER +#include "calprinter.h" +#endif +#include "koprefs.h" +#ifndef KORG_NOPLUGINS +#include "kocore.h" +#endif +#include "koglobals.h" +#include <libkdepim/kincidenceformatter.h> + +#include "komonthview.h" +#include "komonthview.moc" + +#define PIXMAP_SIZE 5 + +class KNOWhatsThis :public QWhatsThis +{ +public: + KNOWhatsThis( KNoScrollListBox* sbox ) : QWhatsThis( sbox ), _wid( sbox) { }; + +protected: + virtual QString text( const QPoint& p) + { + return _wid->getWhatsThisText(p) ; + }; +private: + KNoScrollListBox* _wid; + +}; + + +KNoScrollListBox::KNoScrollListBox(QWidget *parent,const char *name) + : QListBox(parent, name) +{ +#ifndef DESKTOP_VERSION + QPEApplication::setStylusOperation( viewport(), QPEApplication::RightOnHold ); +#endif + new KNOWhatsThis(this); +} + +QString KNoScrollListBox::getWhatsThisText(QPoint p) +{ + QListBoxItem* item = itemAt ( p ); + if ( ! item ) { + return i18n("Click in the cell or\non the date label\nto add an event!"); + } + return KIncidenceFormatter::instance()->getFormattedText(((MonthViewItem*) item)->incidence()); +} +void KNoScrollListBox::keyPressEvent(QKeyEvent *e) +{ + + switch(e->key()) { + case Key_Right: + // if ( e->state() == Qt::ControlButton ) + { + e->ignore(); + return; + } + scrollBy(4,0); + break; + case Key_Left: + // if ( e->state() == Qt::ControlButton ) + { + e->ignore(); + return; + } + scrollBy(-4,0); + break; + case Key_Up: + if(!count()) break; + setCurrentItem((currentItem()+count()-1)%count()); + if(!itemVisible(currentItem())) { + if((unsigned int) currentItem() == (count()-1)) { + setTopItem(currentItem()-numItemsVisible()+1); + } else { + setTopItem(topItem()-1); + } + } + break; + case Key_Down: + if(!count()) break; + setCurrentItem((currentItem()+1)%count()); + if(!itemVisible(currentItem())) { + if(currentItem() == 0) { + setTopItem(0); + } else { + setTopItem(topItem()+1); + } + } + break; + case Key_Shift: + emit shiftDown(); + break; + default: + e->ignore(); + break; + } +} + +void KNoScrollListBox::keyReleaseEvent(QKeyEvent *e) +{ + switch(e->key()) { + case Key_Shift: + emit shiftUp(); + break; + default: + break; + } +} + +void KNoScrollListBox::mousePressEvent(QMouseEvent *e) +{ + QListBox::mousePressEvent(e); + + if(e->button() == RightButton) { + emit rightClick(); + } +} + +MonthViewItem::MonthViewItem( Incidence *incidence, QDate qd, const QString & s) + : QListBoxItem() +{ + setText( s ); + + mIncidence = incidence; + mDate = qd; + // QWhatsThis::add(this,KIncidenceFormatter::instance()->getFormattedText( mIncidence )); + mRecur = false; + mAlarm = false; + mReply = false; + mInfo = false; +} + +void MonthViewItem::paint(QPainter *p) +{ +#if QT_VERSION >= 0x030000 + bool sel = isSelected(); +#else + bool sel = selected(); +#endif + + + if (KOPrefs::instance()->mMonthViewUsesCategoryColor) + { + p->setBackgroundColor( palette().color( QPalette::Normal, \ + sel ? QColorGroup::Highlight : QColorGroup::Background ) ); + p->eraseRect( 0, 0, listBox()->maxItemWidth(), height( listBox() ) ); + } + int x = 1; + int y = 3;//(height() - mRecurPixmap.height()) /2; + int size = PIXMAP_SIZE; + if ( QApplication::desktop()->width() < 300 ) + size = 3; + if ( KOPrefs::instance()->mMonthShowIcons ) { + if ( mInfo ) { + p->fillRect ( x, y,size,size, Qt::darkGreen ); + x += size + 1; + } + if ( mRecur ) { + p->fillRect ( x, y,size,size, Qt::blue ); + x += size + 1; + } + if ( mAlarm ) { + p->fillRect ( x, y,size,size, Qt::red ); + x += size + 1; + } + if ( mReply ) { + p->fillRect ( x, y,size,size, Qt::yellow ); + x += size + 1; + } + } + QFontMetrics fm = p->fontMetrics(); + int yPos; + int pmheight = size; + if( pmheight < fm.height() ) + yPos = fm.ascent() + fm.leading()/2; + else + yPos = pmheight/2 - fm.height()/2 + fm.ascent(); + p->setPen( palette().color( QPalette::Normal, sel ? \ + QColorGroup::HighlightedText : QColorGroup::Foreground ) ); + p->drawText( x, yPos, text() ); + if ( mIncidence->cancelled() ) { + int wid = fm.width( text() ); + p->drawLine( x, yPos- fm.height()/2+2,x+wid, yPos- fm.height()/2 +2); + } + +} + +int MonthViewItem::height(const QListBox *lb) const +{ + return lb->fontMetrics().lineSpacing()+1; +} + +int MonthViewItem::width(const QListBox *lb) const +{ + int size = PIXMAP_SIZE; + if ( QApplication::desktop()->width() < 300 ) + size = 3; + int x = 1; + if ( mInfo ) { + x += size + 1; + } + if( mRecur ) { + x += size+1; + } + if( mAlarm ) { + x += size+1; + } + if( mReply ) { + x += size+1; + } + + return( x + lb->fontMetrics().width( text() ) + 1 ); +} + + +MonthViewCell::MonthViewCell( KOMonthView *parent) + : QWidget( parent ), + mMonthView( parent ) +{ + + QVBoxLayout *topLayout = new QVBoxLayout( this ); + + // mLabel = new QLabel( this );QPushButton + mLabel = new QPushButton( this ); + //mLabel->setFrameStyle( QFrame::Panel | QFrame::Plain ); + //mLabel->setLineWidth( 1 ); + //mLabel->setAlignment( AlignCenter ); + mLabel->setFlat( true ); + mItemList = new KNoScrollListBox( this ); + mItemList->setMinimumSize( 10, 10 ); + mItemList->setFrameStyle( QFrame::Panel | QFrame::Plain ); + mItemList->setLineWidth( 1 ); + topLayout->addWidget( mItemList ); + mLabel->raise(); + // QColor( 0,0,255 ) QColor( 160,1600,255 ) + mStandardPalette = palette(); + mStandardPalette.setColor(QColorGroup::Base, mStandardPalette.color( QPalette::Normal, QColorGroup::Background ) ); + + enableScrollBars( false ); + updateConfig(); + connect( mLabel, SIGNAL( clicked( )), + SLOT( newEvent() )); + connect( mItemList, SIGNAL( doubleClicked( QListBoxItem *) ), + SLOT( defaultAction( QListBoxItem * ) ) ); + connect( mItemList, SIGNAL( rightButtonPressed( QListBoxItem *, + const QPoint &) ), + SLOT( contextMenu( QListBoxItem * ) ) ); + connect( mItemList, SIGNAL( highlighted( QListBoxItem *) ), + SLOT( selection( QListBoxItem * ) ) ); + connect( mItemList, SIGNAL( clicked( QListBoxItem * ) ), + SLOT( cellClicked( QListBoxItem * ) ) ); + connect( mItemList, SIGNAL( clicked( QListBoxItem * ) ), + SLOT( selection( QListBoxItem * ) ) ); +} + +void MonthViewCell::setDate( const QDate &date ) +{ +// kdDebug() << "MonthViewCell::setDate(): " << date.toString() << endl; + + mDate = date; + + QString text; + bool smallDisplay = QApplication::desktop()->width() < 320 && KOPrefs::instance()->mMonthViewSatSunTog; + if ( KOGlobals::self()->calendarSystem()->day( date ) == 1 || (date.dayOfWeek() == 7 && !smallDisplay ) || KOPrefs::instance()->mMonthShowShort) { + text = KOGlobals::self()->calendarSystem()->monthName( date, true ) + " "; + mLabel->resize( mLabelBigSize ); + text += QString::number( KOGlobals::self()->calendarSystem()->day(mDate) ); + } else { + mLabel->resize( mLabelSize ); + text += QString::number( KOGlobals::self()->calendarSystem()->day(mDate) ); + } + mLabel->setText( text ); + + //resizeEvent( 0 ); +} + +QDate MonthViewCell::date() const +{ + return mDate; +} + +void MonthViewCell::setPrimary( bool primary ) +{ + mPrimary = primary; + //setMyPalette(); +} +void MonthViewCell::setMyPalette() +{ + + if ( mHoliday) { + setPalette( mHolidayPalette ); + } else { + if ( mPrimary ) { + setPalette( mPrimaryPalette ); + } else { + setPalette( mNonPrimaryPalette ); + } + } + QPalette pal = palette(); + + mLabel->setPalette( QPalette ( pal.color( QPalette::Normal,QColorGroup::Base),pal.color(QPalette::Normal,QColorGroup::Base ) )); +} +QPalette MonthViewCell::getPalette () +{ + if ( !KOPrefs::instance()->mMonthViewUsesDayColors ) + return mStandardPalette; + if ( mHoliday) { + return mHolidayPalette ; + } else { + if ( mPrimary ) { + return mPrimaryPalette ; + } + } + return mNonPrimaryPalette; +} +bool MonthViewCell::isPrimary() const +{ + return mPrimary; +} + +void MonthViewCell::setHoliday( bool holiday ) +{ + mHoliday = holiday; + //setMyPalette(); +} + +void MonthViewCell::setHoliday( const QString &holiday ) +{ + mHolidayString = holiday; + + if ( !holiday.isEmpty() ) { + setHoliday( true ); + } +} +void MonthViewCell::keyPressEvent ( QKeyEvent * e ) +{ + + e->ignore(); + +} +void MonthViewCell::updateCell() +{ + + setPrimary( mDate.month()%2 ); + setHoliday( KOGlobals::self()->calendarSystem()->dayOfWeek(mDate) == KOGlobals::self()->calendarSystem()->weekDayOfPray() ); + if ( mDate == QDate::currentDate() ) { + mItemList->setLineWidth( 3 ); + } else { + mItemList->setLineWidth( 1 ); + } + mItemList->clear(); + //qApp->processEvents(); + if ( !mHolidayString.isEmpty() ) { + MonthViewItem *item = new MonthViewItem( 0, mDate, mHolidayString ); + item->setPalette( mHolidayPalette ); + mItemList->insertItem( item ); + } + //mLabel->setMaximumWidth( width() - mItemList->lineWidth()*2); + QPtrList<Event> events = mMonthView->calendar()->events( mDate, true ); + Event *event; + for( event = events.first(); event; event = events.next() ) { + if ( event->categories().contains("Holiday") || + event->categories().contains(i18n("Holiday"))) { + setHoliday( true ); + if ( mDate.dayOfWeek() == 7 ) + mItemList->setLineWidth( 3 ); + } + QString text; + if (event->isMultiDay()) { + QString prefix = "<->"; + if ( event->doesRecur() ) { + if ( event->recursOn( mDate) ) + prefix ="->" ; + else { + int days = event->dtStart().date().daysTo ( event->dtEnd().date() ); + if ( event->recursOn( mDate.addDays( -days)) ) + prefix ="<-" ; + } + + } else { + if (mDate == event->dtStart().date()) { + prefix ="->" ; + } else if (mDate == event->dtEnd().date()) { + prefix ="<-" ; + } + } + text = prefix + event->summary(); + } else { + if (event->doesFloat()) + text = event->summary(); + else { + text = KGlobal::locale()->formatTime(event->dtStart().time()); + text += " " + event->summary(); + } + } + + MonthViewItem *item = new MonthViewItem( event, mDate, text ); + QPalette pal; + if (KOPrefs::instance()->mMonthViewUsesCategoryColor) { + QStringList categories = event->categories(); + QString cat = categories.first(); + if ( KOPrefs::instance()->mMonthViewUsesForegroundColor ) { + pal = getPalette(); + if (cat.isEmpty()) { + pal.setColor(QColorGroup::Foreground,KOPrefs::instance()->mEventColor); + } else { + pal.setColor(QColorGroup::Foreground, *(KOPrefs::instance()->categoryColor(cat))); + } + + } else { + if (cat.isEmpty()) { + pal = QPalette(KOPrefs::instance()->mEventColor, KOPrefs::instance()->mEventColor); + } else { + pal = QPalette(*(KOPrefs::instance()->categoryColor(cat)), *(KOPrefs::instance()->categoryColor(cat))); + } + } + + } else { + pal = mStandardPalette ; + } + item->setPalette( pal ); + item->setRecur( event->recurrence()->doesRecur() ); + item->setAlarm( event->isAlarmEnabled() ); + item->setMoreInfo( event->description().length() > 0 ); + Attendee *me = event->attendeeByMails(KOPrefs::instance()->mAdditionalMails, + KOPrefs::instance()->email()); + if ( me != 0 ) { + if ( me->status() == Attendee::NeedsAction && me->RSVP()) + item->setReply(true); + else + item->setReply(false); + } else + item->setReply(false); + bool insert = true; + if ( !(event->doesRecur() == Recurrence::rNone) ) { + if ( !KOPrefs::instance()->mMonthDailyRecur && event->doesRecur() == Recurrence::rDaily ) + insert = false; + else + if ( !KOPrefs::instance()->mMonthWeeklyRecur && event->doesRecur() == Recurrence::rWeekly ) + insert = false; + + } + if ( insert ) + mItemList->insertItem( item ); + } + + // insert due todos + QPtrList<Todo> todos = mMonthView->calendar()->todos( mDate ); + Todo *todo; + for(todo = todos.first(); todo; todo = todos.next()) { + QString text; + if (todo->hasDueDate()) { + if (!todo->doesFloat()) { + text += KGlobal::locale()->formatTime(todo->dtDue().time()); + text += " "; + } + } + text += i18n("To-Do: %1").arg(todo->summary()); + + MonthViewItem *item = new MonthViewItem( todo, mDate, text ); + //item->setPalette( mStandardPalette ); + QPalette pal; + if (KOPrefs::instance()->mMonthViewUsesCategoryColor) { + QStringList categories = todo->categories(); + QString cat = categories.first(); + if ( KOPrefs::instance()->mMonthViewUsesForegroundColor ) { + pal = getPalette(); + if (cat.isEmpty()) { + pal.setColor(QColorGroup::Foreground,KOPrefs::instance()->mEventColor); + } else { + pal.setColor(QColorGroup::Foreground, *(KOPrefs::instance()->categoryColor(cat))); + } + + } else { + if (cat.isEmpty()) { + pal = QPalette(KOPrefs::instance()->mEventColor, KOPrefs::instance()->mEventColor); + } else { + pal = QPalette(*(KOPrefs::instance()->categoryColor(cat)), *(KOPrefs::instance()->categoryColor(cat))); + } + } + + } else { + pal = mStandardPalette ; + } + item->setPalette( pal ); + mItemList->insertItem( item ); + } + //setMyPalette(); + setMyPalette(); + resizeEvent( 0 ); + // if ( isVisible()) + // qApp->processEvents(); +} + +void MonthViewCell::updateConfig() +{ + + setFont( KOPrefs::instance()->mMonthViewFont ); + + QFontMetrics fm( font() ); + mLabelSize = fm.size( 0, "30" ) + QSize( 4, 2 ); + mLabelBigSize = fm.size( 0, "Mag 30" ) + QSize( 2, 2 ); + mHolidayPalette = mStandardPalette; + mPrimaryPalette = mStandardPalette; + mNonPrimaryPalette = mStandardPalette; + if ( KOPrefs::instance()->mMonthViewUsesDayColors ) { + mHolidayPalette.setColor(QColorGroup::Base, KOPrefs::instance()->mMonthViewHolidayColor ); + mHolidayPalette.setColor(QColorGroup::Background, KOPrefs::instance()->mMonthViewHolidayColor ); + mHolidayPalette.setColor(QColorGroup::Foreground, KOPrefs::instance()->mMonthViewHolidayColor.dark()); + mPrimaryPalette.setColor(QColorGroup::Foreground,KOPrefs::instance()->mMonthViewOddColor.dark()); + mPrimaryPalette.setColor(QColorGroup::Base,KOPrefs::instance()->mMonthViewOddColor); + mPrimaryPalette.setColor(QColorGroup::Background,KOPrefs::instance()->mMonthViewOddColor); + mNonPrimaryPalette.setColor(QColorGroup::Foreground,KOPrefs::instance()->mMonthViewEvenColor.dark()); + mNonPrimaryPalette.setColor(QColorGroup::Base,KOPrefs::instance()->mMonthViewEvenColor); + mNonPrimaryPalette.setColor(QColorGroup::Background,KOPrefs::instance()->mMonthViewEvenColor); + } + updateCell(); +} + +void MonthViewCell::enableScrollBars( bool enabled ) +{ + if ( enabled ) { + mItemList->setVScrollBarMode(QScrollView::Auto); + mItemList->setHScrollBarMode(QScrollView::Auto); + } else { + mItemList->setVScrollBarMode(QScrollView::AlwaysOff); + mItemList->setHScrollBarMode(QScrollView::AlwaysOff); + } +} + +Incidence *MonthViewCell::selectedIncidence() +{ + int index = mItemList->currentItem(); + if ( index < 0 ) return 0; + + MonthViewItem *item = + static_cast<MonthViewItem *>( mItemList->item( index ) ); + + if ( !item ) return 0; + + return item->incidence(); +} + +QDate MonthViewCell::selectedIncidenceDate() +{ + QDate qd; + int index = mItemList->currentItem(); + if ( index < 0 ) return qd; + + MonthViewItem *item = + static_cast<MonthViewItem *>( mItemList->item( index ) ); + + if ( !item ) return qd; + + return item->incidenceDate(); +} + +void MonthViewCell::deselect() +{ + mItemList->clearSelection(); + enableScrollBars( false ); + // updateCell(); +} +void MonthViewCell::select() +{ + ;// updateCell(); +} + +void MonthViewCell::resizeEvent ( QResizeEvent * ) +{ + int size = height() - mLabel->height(); + if ( size > 0 ) + mItemList->verticalScrollBar()->setMaximumHeight( size ); + size = width() - mLabel->width(); + if ( size > 0 ) + mItemList->horizontalScrollBar()->setMaximumWidth( size ); + mLabel->move( width()-mItemList->lineWidth() - mLabel->width(), height()-mItemList->lineWidth() - mLabel->height() ); + //mLabel->setMaximumWidth( width() - mItemList->lineWidth()*2); +} + +void MonthViewCell::defaultAction( QListBoxItem *item ) +{ + if ( !item ) return; + + MonthViewItem *eventItem = static_cast<MonthViewItem *>( item ); + Incidence *incidence = eventItem->incidence(); + if ( incidence ) mMonthView->defaultAction( incidence ); +} +void MonthViewCell::newEvent() +{ + QDateTime dt( date(), QTime( KOPrefs::instance()->mStartTime, 0 ) ); + emit newEventSignal( dt ); +} +void MonthViewCell::cellClicked( QListBoxItem *item ) +{ + static QListBoxItem * lastClicked = 0; + if ( item == 0 ) { + QDateTime dt( date(), QTime( KOPrefs::instance()->mStartTime, 0 ) ); + emit newEventSignal( dt ); + return; + } + /* + if ( lastClicked ) + if ( ! item ) { + if ( lastClicked->listBox() != item->listBox() ) + lastClicked->listBox()->clearSelection(); + } + */ + + mMonthView->setSelectedCell( this ); + if( KOPrefs::instance()->mEnableMonthScroll ) enableScrollBars( true ); + select(); +} + +void MonthViewCell::contextMenu( QListBoxItem *item ) +{ + if ( !item ) return; + + MonthViewItem *eventItem = static_cast<MonthViewItem *>( item ); + Incidence *incidence = eventItem->incidence(); + if ( incidence ) mMonthView->showContextMenu( incidence ); +} + +void MonthViewCell::selection( QListBoxItem *item ) +{ + if ( !item ) return; + + mMonthView->setSelectedCell( this ); +} + + +// ******************************************************************************* +// ******************************************************************************* +// ******************************************************************************* + + +KOMonthView::KOMonthView(Calendar *calendar, QWidget *parent, const char *name) + : KOEventView( calendar, parent, name ), + mDaysPerWeek( 7 ), mNumWeeks( 6 ), mNumCells( mDaysPerWeek * mNumWeeks ), + mShortDayLabels( false ), mWidthLongDayLabel( 0 ), mSelectedCell( 0 ) +{ + mCells.setAutoDelete( true ); + mShowSatSunComp = KOPrefs::instance()->mMonthViewSatSunTog ; + // mDayLayout = new QGridLayout( this ); + // create the day of the week labels (Sun, Mon, etc) and add them to + // the layout. + mDayLabels.resize( mDaysPerWeek ); + QFont bfont = font(); + if ( QApplication::desktop()->width() < 650 ) { + bfont.setPointSize( bfont.pointSize() - 2 ); + } + bfont.setBold( true ); + int i; + + for( i = 0; i < mDaysPerWeek; i++ ) { + QLabel *label = new QLabel( this ); + label->setFont(bfont); + label->setFrameStyle(QFrame::Panel|QFrame::Raised); + label->setLineWidth(1); + label->setAlignment(AlignCenter); + mDayLabels.insert( i, label ); + } + + bfont.setBold( false ); + mWeekLabels.resize( mNumWeeks+1 ); + for( i = 0; i < mNumWeeks+1; i++ ) { + KOWeekButton *label = new KOWeekButton( this ); + label->setFont(bfont); + connect( label, SIGNAL( selectWeekNum ( int )),this, SIGNAL( selectWeekNum ( int )) ); + label->setFlat(true); + QWhatsThis::add(label,i18n("Click on the week number to\nshow week in agenda view")); + //label->setFrameStyle(QFrame::Panel|QFrame::Raised); + //label->setLineWidth(1); + //label->setAlignment(AlignCenter); + mWeekLabels.insert( i, label ); + } + mWeekLabels[mNumWeeks]->setText( i18n("W")); + int row, col; + mCells.resize( mNumCells ); + for( row = 0; row < mNumWeeks; ++row ) { + for( col = 0; col < mDaysPerWeek; ++col ) { + MonthViewCell *cell = new MonthViewCell( this ); + mCells.insert( row * mDaysPerWeek + col, cell ); + + connect( cell, SIGNAL( defaultAction( Incidence * ) ), + SLOT( defaultAction( Incidence * ) ) ); + connect( cell, SIGNAL( newEventSignal( QDateTime ) ), + SIGNAL( newEventSignal( QDateTime ) ) ); + } + } + + mContextMenu = eventPopup(); + // updateConfig(); //useless here + + emit incidenceSelected( 0 ); +} + +KOMonthView::~KOMonthView() +{ + delete mContextMenu; +} + +int KOMonthView::maxDatesHint() +{ + return mNumCells; +} + +int KOMonthView::currentDateCount() +{ + return mNumCells; +} + +QPtrList<Incidence> KOMonthView::selectedIncidences() +{ + QPtrList<Incidence> selected; + + if ( mSelectedCell ) { + Incidence *incidence = mSelectedCell->selectedIncidence(); + if ( incidence ) selected.append( incidence ); + } + + return selected; +} + +DateList KOMonthView::selectedDates() +{ + DateList selected; + + if ( mSelectedCell ) { + QDate qd = mSelectedCell->selectedIncidenceDate(); + if ( qd.isValid() ) selected.append( qd ); + } + + return selected; +} + +void KOMonthView::printPreview(CalPrinter *calPrinter, const QDate &fd, + const QDate &td) +{ +#ifndef KORG_NOPRINTER + calPrinter->preview(CalPrinter::Month, fd, td); +#endif +} + +void KOMonthView::updateConfig() +{ + + mWeekStartsMonday = KGlobal::locale()->weekStartsMonday(); + + QFontMetrics fontmetric(mDayLabels[0]->font()); + mWidthLongDayLabel = 0; + + for (int i = 0; i < 7; i++) { + int width = fontmetric.width(KOGlobals::self()->calendarSystem()->weekDayName(i+1)); + if ( width > mWidthLongDayLabel ) mWidthLongDayLabel = width; + } + bool temp = mShowSatSunComp ; + mShowSatSunComp = KOPrefs::instance()->mMonthViewSatSunTog ; + if ( temp != KOPrefs::instance()->mMonthViewSatSunTog ) + computeLayout(); + updateDayLabels(); + //qDebug("KOMonthView::updateConfig() %d %d %d ",height(), mDayLabels[0]->sizeHint().height() ,mNumWeeks); + int cellHeight = (height() - mDayLabels[0]->sizeHint().height()) /mNumWeeks; + //resizeEvent( 0 ); + for (uint i = 0; i < mCells.count(); ++i) { + mCells[i]->updateConfig(); + } +} + +void KOMonthView::updateDayLabels() +{ + + for (int i = 0; i < 7; i++) { + if (mWeekStartsMonday) { + bool show = mShortDayLabels; + if ( i > 4 && mShowSatSunComp && mWidthLongDayLabel > mDayLabels[i]->width() ) + show = true; + mDayLabels[i]->setText(KOGlobals::self()->calendarSystem()->weekDayName(i+1,show)); + } else { + if (i==0) mDayLabels[i]->setText(KOGlobals::self()->calendarSystem()->weekDayName(7,mShortDayLabels)); + else mDayLabels[i]->setText(KOGlobals::self()->calendarSystem()->weekDayName(i,mShortDayLabels)); + + } + } +} + +void KOMonthView::showDates(const QDate &start, const QDate &) +{ +// kdDebug() << "KOMonthView::showDates(): " << start.toString() << endl; + + + mStartDate = start; + + int startWeekDay = mWeekStartsMonday ? 1 : 7; + + while( KOGlobals::self()->calendarSystem()->dayOfWeek(mStartDate) != startWeekDay ) { + mStartDate = mStartDate.addDays( -1 ); + } + + bool primary = false; + uint i; + for( i = 0; i < mCells.size(); ++i ) { + QDate date = mStartDate.addDays( i ); + mCells[i]->setDate( date ); + +#ifndef KORG_NOPLUGINS + // add holiday, if present + QString hstring(KOCore::self()->holiday(date)); + mCells[i]->setHoliday( hstring ); +#endif + + } + QDate date = mStartDate.addDays( mWeekStartsMonday ? 3 : 4 ); + for( i = 0; i < 6; ++i ) { + int wno; + // remember, according to ISO 8601, the first week of the year is the + // first week that contains a thursday. Thus we must subtract off 4, + // not just 1. + int dayOfYear = date.dayOfYear(); + if (dayOfYear % 7 != 0) + wno = dayOfYear / 7 + 1; + else + wno =dayOfYear / 7; + mWeekLabels[i]->setWeekNum( wno ); + date = date.addDays( 7 ); + } + updateView(); +} + +void KOMonthView::showEvents(QPtrList<Event>) +{ + qDebug("KOMonthView::selectEvents is not implemented yet. "); +} + +void KOMonthView::changeEventDisplay(Event *, int) +{ + // this should be re-written to be much more efficient, but this + // quick-and-dirty-hack gets the job done for right now. + updateView(); +} + +void KOMonthView::updateView() +{ + + uint i; + for( i = 0; i < mCells.count(); ++i ) { + mCells[i]->updateCell(); + } + //qDebug("KOMonthView::updateView() "); + processSelectionChange(); +} + +void KOMonthView::resizeEvent(QResizeEvent * e) +{ + computeLayout(); +} +void KOMonthView::computeLayout() +{ + // select the appropriate heading string size. E.g. "Wednesday" or "Wed". + // note this only changes the text if the requested size crosses the + // threshold between big enough to support the full name and not big + // enough. + + int daysToShow = 7; + bool combinedSatSun = false; + if (mShowSatSunComp = KOPrefs::instance()->mMonthViewSatSunTog ) { + daysToShow = 6; + combinedSatSun = true; + } + int tWid = topLevelWidget()->size().width(); + int tHei = topLevelWidget()->size().height(); + + int wid = size().width();//e + int hei = size().height()-1; + + if ( ((wid *3)/2) < tWid && (( hei *3) /2) < tHei ) + return; + + QFontMetrics fm ( mWeekLabels[0]->font() ); + int weeklabelwid = fm.width( "888" ); + wid -= weeklabelwid; + + int colWid = wid / daysToShow; + int lastCol = wid - ( colWid*6 ); + int dayLabelHei = mDayLabels[0]->sizeHint().height(); + int cellHei = (hei - dayLabelHei) /6; + int colModulo = wid % daysToShow; + int rowModulo = (hei- dayLabelHei) % 6; + //qDebug("rowmod %d ", rowModulo); + int i; + int x,y,w,h; + x= 0; + y= 0; + w = colWid; + h = dayLabelHei ; + for ( i = 0; i < 7; i++) { + if ( i == daysToShow-colModulo ) + ++w; + if ( combinedSatSun ) { + if ( i >= daysToShow-1 ) { + mDayLabels[i]->setGeometry( x+weeklabelwid,y,w/2,h); + x -= w/2 ; + } + else + mDayLabels[i]->setGeometry( x+weeklabelwid,y,w,h); + } else + mDayLabels[i]->setGeometry( x+weeklabelwid,y,w,h); + x += w; + } + x= 0; + y= dayLabelHei; + w = colWid; + h = cellHei ; + for ( i = 0; i < mCells.count(); ++i) { + + w = colWid; + if ( ((i) % 7) >= 7-colModulo ) { + ++w; + } + if ( i == (6-rowModulo)*7) + ++h; + if ( combinedSatSun ) { + if ( (i)%7 >= daysToShow-1 ) { + if ( (i)%7 == daysToShow-1 ) { + mCells[i]->setGeometry ( x+weeklabelwid,y,w,h/2 ); + x -= w ;y += h/2; + } else { + mCells[i]->setGeometry ( x+weeklabelwid,y,w,h-h/2 ); + y -= h/2; + } + } else + mCells[i]->setGeometry ( x+weeklabelwid,y,w,h ); + + } + else + mCells[i]->setGeometry ( x+weeklabelwid,y,w,h ); + x += w; + if ( x + w/2 > wid ) { + x = 0; + y += h; + } + } + y= dayLabelHei; + h = cellHei ; + for ( i = 0; i < 6; i++) { + if ( i == (6-rowModulo)) + ++h; + mWeekLabels[i]->setGeometry( 0,y,weeklabelwid,h); + y += h; + } + mWeekLabels[6]->setGeometry( 0,0,weeklabelwid,dayLabelHei); + // qDebug("RRRRRRRRRRRRR %d %d old %d %d", e->size().width(),e->size().height() , e->oldSize().width(),e->oldSize().height()); + //qDebug("parent %d %d ", topLevelWidget()->size().width(), topLevelWidget()->size().height()); + mShortDayLabels = mDayLabels[0]->width() < mWidthLongDayLabel ; + updateDayLabels(); +} + +void KOMonthView::showContextMenu( Incidence *incidence ) +{ + mContextMenu->showIncidencePopup(incidence); + /* + if( incidence && incidence->type() == "Event" ) { + Event *event = static_cast<Event *>(incidence); + mContextMenu->showEventPopup(event); + } else { + kdDebug() << "MonthView::showContextMenu(): cast failed." << endl; + } + */ +} +MonthViewCell * KOMonthView::selectedCell( ) +{ + return mSelectedCell; +} +void KOMonthView::setSelectedCell( MonthViewCell *cell ) +{ + // qDebug("KOMonthView::setSelectedCell "); + if ( mSelectedCell && mSelectedCell != cell ) { + MonthViewCell * mvc = mSelectedCell; + mSelectedCell = cell; + mvc->deselect(); + } else + mSelectedCell = cell; + // if ( mSelectedCell ) +// mSelectedCell->select(); + if ( !mSelectedCell ) + emit incidenceSelected( 0 ); + else + emit incidenceSelected( mSelectedCell->selectedIncidence() ); +} + +void KOMonthView::processSelectionChange() +{ + QPtrList<Incidence> incidences = selectedIncidences(); + if (incidences.count() > 0) { + emit incidenceSelected( incidences.first() ); + } else { + emit incidenceSelected( 0 ); + } +} + +void KOMonthView::clearSelection() +{ + if ( mSelectedCell ) { + mSelectedCell->deselect(); + mSelectedCell = 0; + } +} +void KOMonthView::keyPressEvent ( QKeyEvent * e ) +{ + + e->ignore(); + +} diff --git a/korganizer/komonthview.h b/korganizer/komonthview.h new file mode 100644 index 0000000..d976246 --- a/dev/null +++ b/korganizer/komonthview.h @@ -0,0 +1,252 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef _KOMONTHVIEW_H +#define _KOMONTHVIEW_H + +#include <qlabel.h> +#include <qframe.h> +#include <qdatetime.h> +#include <qlistbox.h> +#include <qpoint.h> +#include <qlayout.h> +#include <qintdict.h> +#include <qpushbutton.h> +#include <qvaluelist.h> +#include <qptrvector.h> + +#include <libkcal/calendar.h> +#include <libkcal/event.h> + +#include "koeventview.h" + +class KOWeekButton : public QPushButton +{ + Q_OBJECT + public: + KOWeekButton( QWidget *parent=0, const char *name=0 ) : + QPushButton( parent, name) + { + connect( this, SIGNAL( clicked() ), + SLOT( bottonClicked() )); + mNumber = -1; + } + void setWeekNum ( int num ) {mNumber = num; setText( QString::number ( num ));} + signals: + void selectWeekNum ( int ); +private: + int mNumber; +private slots : + void bottonClicked() { if ( mNumber > 0 ) emit selectWeekNum ( mNumber ); } +}; + +class KNoScrollListBox: public QListBox +{ + Q_OBJECT + public: + KNoScrollListBox(QWidget *parent=0, const char *name=0); + ~KNoScrollListBox() {} + QString getWhatsThisText(QPoint p) ; + + signals: + void shiftDown(); + void shiftUp(); + void rightClick(); + + protected slots: + void keyPressEvent(QKeyEvent *); + void keyReleaseEvent(QKeyEvent *); + void mousePressEvent(QMouseEvent *); +}; + + +class MonthViewItem: public QListBoxItem +{ + public: + MonthViewItem( Incidence *, QDate qd, const QString & title ); + + void setRecur(bool on) { mRecur = on; } + void setAlarm(bool on) { mAlarm = on; } + void setReply(bool on) { mReply = on; } + void setMoreInfo(bool on) { mInfo = on; } + + + void setPalette(const QPalette &p) { mPalette = p; } + QPalette palette() const { return mPalette; } + + Incidence *incidence() const { return mIncidence; } + QDate incidenceDate() { return mDate; } + + protected: + virtual void paint(QPainter *); + virtual int height(const QListBox *) const; + virtual int width(const QListBox *) const; + + private: + bool mRecur; + bool mAlarm; + bool mReply; + bool mInfo; + + QPalette mPalette; + QDate mDate; + + Incidence *mIncidence; +}; + + +class KOMonthView; + +class MonthViewCell : public QWidget +{ + Q_OBJECT + public: + MonthViewCell( KOMonthView * ); + + void setDate( const QDate & ); + QDate date() const; + + void setPrimary( bool ); + bool isPrimary() const; + + void setHoliday( bool ); + void setHoliday( const QString & ); + + void updateCell(); + + void updateConfig(); + + void enableScrollBars( bool ); + + Incidence *selectedIncidence(); + QDate selectedIncidenceDate(); + + void deselect(); + void select(); + + signals: + void defaultAction( Incidence * ); + void newEventSignal( QDateTime ); + + protected: + void resizeEvent( QResizeEvent * ); + + protected slots: + void defaultAction( QListBoxItem * ); + void contextMenu( QListBoxItem * ); + void selection( QListBoxItem * ); + void cellClicked( QListBoxItem * ); + void newEvent(); + + private: + KOMonthView *mMonthView; + + QDate mDate; + bool mPrimary; + bool mHoliday; + QString mHolidayString; + + //QLabel *mLabel; + QPushButton *mLabel; + QListBox *mItemList; + + QSize mLabelSize; + QSize mLabelBigSize; + QPalette mHolidayPalette; + QPalette mStandardPalette; + QPalette mPrimaryPalette; + QPalette mNonPrimaryPalette; + void setMyPalette(); + QPalette getPalette (); + void keyPressEvent ( QKeyEvent * ) ; + +}; + + +class KOMonthView: public KOEventView +{ + Q_OBJECT + public: + KOMonthView(Calendar *cal, QWidget *parent = 0, const char *name = 0 ); + ~KOMonthView(); + + /** Returns maximum number of days supported by the komonthview */ + virtual int maxDatesHint(); + + /** Returns number of currently shown dates. */ + virtual int currentDateCount(); + + /** returns the currently selected events */ + virtual QPtrList<Incidence> selectedIncidences(); + + /** returns dates of the currently selected events */ + virtual DateList selectedDates(); + + virtual void printPreview(CalPrinter *calPrinter, + const QDate &, const QDate &); + + MonthViewCell * selectedCell(); + public slots: + virtual void updateView(); + virtual void updateConfig(); + virtual void showDates(const QDate &start, const QDate &end); + virtual void showEvents(QPtrList<Event> eventList); + + void changeEventDisplay(Event *, int); + + void clearSelection(); + + void showContextMenu( Incidence * ); + + void setSelectedCell( MonthViewCell * ); + + protected slots: + void processSelectionChange(); + signals: + void selectWeekNum ( int ); + protected: + void resizeEvent(QResizeEvent *); + void viewChanged(); + void updateDayLabels(); + + private: + int mDaysPerWeek; + int mNumWeeks; + int mNumCells; + bool mWeekStartsMonday; + bool mShowSatSunComp; + void computeLayout(); + + QPtrVector<MonthViewCell> mCells; + QPtrVector<QLabel> mDayLabels; + QPtrVector<KOWeekButton> mWeekLabels; + + bool mShortDayLabels; + int mWidthLongDayLabel; + + QDate mStartDate; + + MonthViewCell *mSelectedCell; + + KOEventPopupMenu *mContextMenu; + void keyPressEvent ( QKeyEvent * ) ; + +}; + +#endif diff --git a/korganizer/komonthview.moc b/korganizer/komonthview.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/komonthview.moc diff --git a/korganizer/koprefs.cpp b/korganizer/koprefs.cpp new file mode 100644 index 0000000..2900a40 --- a/dev/null +++ b/korganizer/koprefs.cpp @@ -0,0 +1,555 @@ +/* + 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. +*/ + +#include <time.h> +#ifndef _WIN32_ +#include <unistd.h> +#endif +#include <qdir.h> +#include <qtextstream.h> +#include <qtextcodec.h> +#include <qstring.h> +#include <qfont.h> +#include <qcolor.h> +#include <qstringlist.h> +#include <stdlib.h> + +#include <kglobal.h> +#include <kconfig.h> +#include <klocale.h> +#include <kdebug.h> +#include <kemailsettings.h> +#include <kstaticdeleter.h> + +#include "koprefs.h" +#include "mainwindow.h" + +const char *germanwords[][2] = { +#include "wordsgerman.h" + "", "" +}; + +KOPrefs *KOPrefs::mInstance = 0; +static KStaticDeleter<KOPrefs> insd; + +KOPrefs::KOPrefs() : + KPimPrefs("korganizerrc") +{ + mCategoryColors.setAutoDelete(true); + mLocaleDict = 0; + fillMailDefaults(); + mDefaultCategoryColor = QColor(175,210,255);//196,196,196); + QColor defaultHolidayColor = QColor(255,0,0); + QColor defaultHighlightColor = QColor(129,112,255);//64,64,255); + QColor defaultAgendaBgColor = QColor(239,241,169);//128,128,128); + QColor defaultWorkingHoursColor = QColor(170,223,150);//160,160,160); + QColor defaultTodoDueTodayColor = QColor(255,220,100); + QColor defaultTodoOverdueColor = QColor(255,153,125); + + mTimeBarFont = QFont("helvetica",10);//,QFont::Bold); + mDefaultViewFont = QFont("helvetica",10); + mDefaultMonthViewFont = QFont("helvetica",8); + mMarcusBainsFont= QFont("helvetica",10); + mDateNavigatorFont= QFont("helvetica",10, QFont::Bold); + mEditBoxFont = QFont("helvetica",12); + mJornalViewFont = QFont("helvetica",12); + + KPrefs::setCurrentGroup("General"); + addItemBool("Enable Group Scheduling",&mEnableGroupScheduling,false); + + addItemBool("ShowIconNewTodo",&mShowIconNewTodo,true); + addItemBool("ShowIconNewEvent",&mShowIconNewEvent,true); + addItemBool("ShowIconSearch",&mShowIconSearch,true); + addItemBool("ShowIconList",&mShowIconList,true); + addItemBool("ShowIconDay1",&mShowIconDay1,true); + addItemBool("ShowIconDay5",&mShowIconDay5,true); + addItemBool("ShowIconDay7",&mShowIconDay7,true); + addItemBool("ShowIconMonth",&mShowIconMonth,true); + addItemBool("ShowIconTodoview",&mShowIconTodoview,true); + addItemBool("ShowIconBackFast",&mShowIconBackFast,true); + addItemBool("ShowIconBack",&mShowIconBack,true); + addItemBool("ShowIconToday",&mShowIconToday,true); + addItemBool("ShowIconForward",&mShowIconForward,true); + addItemBool("ShowIconForwardFast",&mShowIconForwardFast,true); + addItemBool("ShowIconWhatsThis",&mShowIconWhatsThis,false); + addItemBool("ShowIconNextDays",&mShowIconNextDays,true); + addItemBool("ShowIconNext",&mShowIconNext,true); + addItemBool("ShowIconJournal",&mShowIconJournal,true); + addItemBool("ShowIconStretch",&mShowIconStretch,true); + addItemBool("LanguageChanged",&mLanguageChanged,false); + + addItemBool("AskForQuit",&mAskForQuit,false); + +#ifndef DESKTOP_VERSION + addItemBool("ShowFullMenu",&mShowFullMenu,false); +#else + addItemBool("ShowFullMenu",&mShowFullMenu,true); +#endif + addItemBool("ToolBarHor",&mToolBarHor, true ); + addItemBool("ToolBarUp",&mToolBarUp, false ); + addItemBool("ToolBarMiniIcons",&mToolBarMiniIcons, false ); + addItemInt("Whats Next Days",&mWhatsNextDays,3); + addItemInt("Whats Next Prios",&mWhatsNextPrios,1); + + addItemBool("ShowTodoInAgenda",&mShowTodoInAgenda,true); + addItemBool("ShowCompletedTodo",&mShowCompletedTodo,true); + addItemInt("AllDay Size",&mAllDaySize,28); + QString defAlarm = KGlobal::iconLoader()->iconPath()+"koalarm.wav"; + addItemString("DefaultAlarmFile",&mDefaultAlarmFile,defAlarm ); + + addItemStringList("LocationDefaults",&mLocationDefaults ); + addItemStringList("EventSummary User",&mEventSummaryUser); + addItemStringList("TodoSummary User",&mTodoSummaryUser); + + addItemBool("Enable Group Scheduling",&mEnableGroupScheduling,false); + addItemBool("Enable Project View",&mEnableProjectView,false); + addItemBool("Auto Save",&mAutoSave,false); + addItemInt("Auto Save Interval",&mAutoSaveInterval,3); + addItemBool("Confirm Deletes",&mConfirm,true); + addItemString("Archive File",&mArchiveFile); + addItemString("Html Export File",&mHtmlExportFile, + QDir::homeDirPath() + "/" + i18n("Default export file", "calendar.html")); + addItemBool("Html With Save",&mHtmlWithSave,false); + + KPrefs::setCurrentGroup("Personal Settings"); + + addItemInt("Mail Client",&mMailClient,MailClientKMail); + addItemBool("Use Control Center Email",&mEmailControlCenter,false); + addItemBool("Bcc",&mBcc,false); + + KPrefs::setCurrentGroup("Time & Date"); + + // addItemString("Time Zone",&mTimeZone,"+0100"); + addItemString("TimeZoneName",&mTimeZoneId,i18n ("+01:00 Europe/Oslo(CET)") ); + // addItemInt("TimeZoneOffset",&mTimeZoneOffset,60); + addItemBool("UseDaylightsaving",&mUseDaylightsaving,true); + addItemInt("DaylightsavingStart",&mDaylightsavingStart,90); + addItemInt("DaylightsavingEnd",&mDaylightsavingEnd,304); + + + addItemInt("Default Start Time",&mStartTime,10); + addItemInt("Default Duration",&mDefaultDuration,2); + addItemInt("Default Alarm Time",&mAlarmTime,3); + addItemInt("Daylight Savings",&mDaylightSavings,0); + KPrefs::setCurrentGroup("AlarmSettings"); + addItemInt("AlarmPlayBeeps",&mAlarmPlayBeeps,20); + addItemInt("AlarmSuspendTime",&mAlarmSuspendTime,7); + addItemInt("AlarmSuspendCount",&mAlarmSuspendCount,5); + addItemInt("AlarmBeepInterval",&mAlarmBeepInterval,3); + + + KPrefs::setCurrentGroup("Calendar"); + + addItemInt("Default Calendar Format",&mDefaultFormat,FormatICalendar); + + KPrefs::setCurrentGroup("Fonts"); + // qDebug(" KPrefs::setCurrentGroup(Fonts); "); + addItemFont("TimeBar Font",&mTimeBarFont); + addItemFont("MonthView Font",&mMonthViewFont); + addItemFont("AgendaView Font",&mAgendaViewFont); + addItemFont("MarcusBains Font",&mMarcusBainsFont); + addItemFont("TimeLabels Font",&mTimeLabelsFont); + addItemFont("TodoView Font",&mTodoViewFont); + addItemFont("ListView Font",&mListViewFont); + addItemFont("DateNavigator Font",&mDateNavigatorFont); + addItemFont("EditBox Font",&mEditBoxFont); + addItemFont("JournalView Font",&mJornalViewFont); + addItemFont("WhatsNextView Font",&mWhatsNextFont); + addItemFont("EventView Font",&mEventViewFont); + + KPrefs::setCurrentGroup("SyncProfiles"); + addItemString("LocalMachineName",&mLocalMachineName, "undefined"); + addItemStringList("SyncProfileNames",&mSyncProfileNames); + + KPrefs::setCurrentGroup("RemoteSyncing"); + addItemBool("UsePasswd",&mUsePassWd,false); + addItemBool("WriteBackFile",&mWriteBackFile,true); + addItemBool("WriteBackExistingOnly",&mWriteBackExistingOnly,false); + addItemBool("AskForPreferences",&mAskForPreferences,true); + addItemBool("ShowSyncSummary",&mShowSyncSummary,true); + addItemBool("ShowSyncEvents",&mShowSyncEvents,false); + addItemInt("LastSyncTime",&mLastSyncTime,0); + addItemInt("SyncAlgoPrefs",&mSyncAlgoPrefs,3); + addItemInt("RingSyncAlgoPrefs",&mRingSyncAlgoPrefs,3); + +#ifdef _WIN32_ + QString hdp= locateLocal("data","korganizer")+"\\\\"; +#else + QString hdp= locateLocal("data","korganizer")+"/"; +#endif + addItemString("RemoteIP",&mRemoteIP, "192.168.0.65"); + addItemString("RemoteUser",&mRemoteUser, "zaurus"); + addItemString("RemotePassWd",&mRemotePassWd, ""); + addItemString("RemoteFile", &mRemoteFile, hdp+"mycalendar.ics"); + addItemString("LocalTempFile",&mLocalTempFile, "/tmp/tempsyncfile.ics" ); + + + KPrefs::setCurrentGroup("LoadSaveFileNames"); + + addItemString("LastImportFile", &mLastImportFile ,hdp +"import.ics" ); + addItemString("LastVcalFile", &mLastVcalFile ,hdp +"export.vcs" ); + addItemString("LastSaveFile", &mLastSaveFile ,hdp +"mybackup.ics" ); + addItemString("LastLoadFile", &mLastLoadFile ,hdp +"mybackup.ics" ); + addItemString("LastSyncedLocalFile", &mLastSyncedLocalFile ,hdp +"lastsync.ics" ); + + + KPrefs::setCurrentGroup("Locale"); + addItemInt("PreferredLanguage",&mPreferredLanguage,0); + addItemInt("PreferredTime",&mPreferredTime,0); + addItemInt("PreferredDate",&mPreferredDate,0); + addItemBool("WeekStartsOnSunday",&mWeekStartsOnSunday,false); + addItemBool("QuickSavingWOUnicode",&mUseQuicksave,false); + addItemBool("ShortDateInViewer",&mShortDateInViewer,false); + addItemString("UserDateFormatLong", &mUserDateFormatLong, "%A %d %b %y"); + addItemString("UserDateFormatShort", &mUserDateFormatShort, "%aK %d.%m.%y"); + + + KPrefs::setCurrentGroup("Colors"); + addItemColor("Holiday Color",&mHolidayColor,defaultHolidayColor); + addItemColor("Highlight Color",&mHighlightColor,defaultHighlightColor); + addItemColor("Event Color",&mEventColor,mDefaultCategoryColor); + addItemColor("Agenda Background Color",&mAgendaBgColor,defaultAgendaBgColor); + addItemColor("WorkingHours Color",&mWorkingHoursColor,defaultWorkingHoursColor); + addItemColor("Todo due today Color",&mTodoDueTodayColor,defaultTodoDueTodayColor); + addItemColor("Todo overdue Color",&mTodoOverdueColor,defaultTodoOverdueColor); + addItemColor("MonthViewEvenColor",&mMonthViewEvenColor,QColor( 160,160,255 )); + addItemColor("MonthViewOddColor",&mMonthViewOddColor,QColor( 160,255,160 )); + addItemColor("MonthViewHolidayColor",&mMonthViewHolidayColor,QColor( 255,160,160 )); + addItemBool("MonthViewUsesDayColors",&mMonthViewUsesDayColors,true); + addItemBool("MonthViewSatSunTog",&mMonthViewSatSunTog,true); + addItemBool("HightlightDateTimeEdit",&mHightlightDateTimeEdit,false); + addItemColor("AppColor1",&mAppColor1,QColor( 130,170,255 )); + addItemColor("AppColor2",&mAppColor2,QColor( 174,216,255 )); + addItemBool("UseAppColors",&mUseAppColors,false); + + + + KPrefs::setCurrentGroup("Views"); + addItemInt("Hour Size",&mHourSize,8); + addItemBool("Show Daily Recurrences",&mDailyRecur,true); + addItemBool("Show Weekly Recurrences",&mWeeklyRecur,true); + addItemBool("Show Month Daily Recurrences",&mMonthDailyRecur,true); + addItemBool("Show Month Weekly Recurrences",&mMonthWeeklyRecur,true); + addItemBool("ShowShortMonthName",&mMonthShowShort,false); + addItemBool("ShowIconsInMonthCell",&mMonthShowIcons,true); + addItemBool("Enable ToolTips",&mEnableToolTips,false); + addItemBool("Enable MonthView ScrollBars",&mEnableMonthScroll,false); + addItemBool("Marcus Bains shows seconds",&mMarcusBainsShowSeconds,false); + addItemBool("Show Marcus Bains",&mMarcusBainsEnabled,true); + addItemBool("EditOnDoubleClick",&mEditOnDoubleClick,true); + addItemBool("ViewChangeHoldFullscreen",&mViewChangeHoldFullscreen,false); + addItemBool("ViewChangeHoldNonFullscreen",&mViewChangeHoldNonFullscreen,false); + addItemBool("CenterOnCurrentTime",&mCenterOnCurrentTime,false); + addItemBool("SetTimeToDayStartAt",&mSetTimeToDayStartAt,true); + addItemBool("HighlightCurrentDay",&mHighlightCurrentDay,true); + addItemBool("WNViewShowsParents",&mWNViewShowsParents,true); + addItemBool("WNViewShowLocation",&mWNViewShowLocation,false); + addItemBool("UseHighlightLightColor",&mUseHighlightLightColor,false); + addItemBool("ListViewMonthTimespan",&mListViewMonthTimespan,true); + addItemBool("TodoViewUsesCatColors",&mTodoViewUsesCatColors,false); + addItemBool("TodoViewShowsPercentage",&mTodoViewShowsPercentage,false); + addItemBool("TodoViewUsesSmallFont",&mTodoViewUsesSmallFont,false); + addItemBool("TodoViewUsesForegroundColor",&mTodoViewUsesForegroundColor,false); + addItemBool("MonthViewUsesForegroundColor",&mMonthViewUsesForegroundColor,false); + addItemBool("UseInternalAlarmNotification",&mUseInternalAlarmNotification,false); + addItemInt("Day Begins",&mDayBegins,7); + addItemInt("Working Hours Start",&mWorkingHoursStart,8); + addItemInt("Working Hours End",&mWorkingHoursEnd,17); + addItemBool("Exclude Holidays",&mExcludeHolidays,true); + addItemBool("Exclude Saturdays",&mExcludeSaturdays,true); + + addItemBool("Month View Uses Category Color",&mMonthViewUsesCategoryColor,false); + addItemBool("Full View Month",&mFullViewMonth,true); + addItemBool("Full View Todo",&mFullViewTodo,true); + addItemBool("Quick Todo",&mEnableQuickTodo,false); + + addItemInt("Next X Days",&mNextXDays,3); + + KPrefs::setCurrentGroup("Printer"); + + KPrefs::setCurrentGroup("Layout"); + + addItemBool("CompactDialogs",&mCompactDialogs,false); + addItemBool("VerticalScreen",&mVerticalScreen,true); + + KPrefs::setCurrentGroup("KOrganizer Plugins"); + + addItemStringList("SelectedPlugins",&mSelectedPlugins,"holidays"); + + KPrefs::setCurrentGroup("Group Scheduling"); + + addItemInt("IMIPScheduler",&mIMIPScheduler,IMIPKMail); + addItemInt("IMIPSend",&mIMIPSend,IMIPdirectsend); + addItemStringList("AdditionalMails",&mAdditionalMails,""); + addItemInt("IMIP auto refresh",&mIMIPAutoRefresh,neverAuto); + addItemInt("IMIP auto insert request",&mIMIPAutoInsertRequest,neverAuto); + addItemInt("IMIP auto insert reply",&mIMIPAutoInsertReply,neverAuto); + addItemInt("IMIP auto FreeBusy",&mIMIPAutoFreeBusy,neverAuto); + addItemInt("IMIP auto save FreeBusy",&mIMIPAutoFreeBusyReply,neverAuto); + + KPrefs::setCurrentGroup( "Editors" ); + + addItemStringList( "EventTemplates", &mEventTemplates ); + addItemStringList( "TodoTemplates", &mTodoTemplates ); + + addItemInt("DestinationPolicy",&mDestination,standardDestination); + + + +} + + +KOPrefs::~KOPrefs() +{ + if (mInstance == this) + mInstance = insd.setObject(0); + setLocaleDict( 0 ); + if ( mLocaleDict ) + delete mLocaleDict; + //qDebug("KOPrefs::~KOPrefs() "); +} + + +KOPrefs *KOPrefs::instance() +{ + if (!mInstance) { + mInstance = insd.setObject(new KOPrefs()); + mInstance->readConfig(); + } + + return mInstance; +} + +void KOPrefs::usrSetDefaults() +{ + +} + +void KOPrefs::fillMailDefaults() +{ + if (mName.isEmpty()) mName = i18n("Anonymous"); + if (mEmail.isEmpty()) mEmail = i18n("nobody@nowhere"); +} + +void KOPrefs::setTimeZoneIdDefault() +{ + mTimeZoneId = i18n("+01:00 Europe/Oslo(CET)"); +} + +void KOPrefs::setCategoryDefaults() +{ + mCustomCategories.clear(); + mCustomCategories = getDefaultList(); + + QStringList::Iterator it; + for (it = mCustomCategories.begin();it != mCustomCategories.end();++it ) { + setCategoryColor(*it,mDefaultCategoryColor); + } +} + +QStringList KOPrefs::getDefaultList() +{ + QStringList retval ; + retval << i18n("Anniversary") << i18n("Appointment") << i18n("Birthday") << i18n("Business") << i18n("Business Travel") << i18n("Cinema") << i18n("Customer") + << i18n("Break")<< i18n("Breakfast")<< i18n("Competition")<< i18n("Dinner") + << i18n("Education")<< i18n("Family") << i18n("Favorites") << i18n("Festival")<< i18n("Fishing")<< i18n("Flight") << i18n("Gifts") + << i18n("Holiday") << i18n("Holiday Cards")<< i18n("Hot Contacts") << i18n("Hiking") << i18n("Hunting") << i18n("Key Customer") << i18n("Kids") + << i18n("Lunch") << i18n("Meeting") << i18n("Miscellaneous") << i18n("Partner")<< i18n("Party") << i18n("Personal") << i18n("Personal Travel") + << i18n("PHB") << i18n("Phone Calls") << i18n("Projects") << i18n("Recurring") << i18n("School") << i18n("Shopping") + << i18n("Speach") << i18n("Special Occasion") << i18n("Sports") << i18n("Talk") << i18n("Travel") << i18n("TV")<< i18n("University") + << i18n("Vacation") << i18n("VIP") << i18n("SyncEvent") ; + retval.sort(); + return retval; +} + +void KOPrefs::usrReadConfig() +{ + mLocaleDict = 0; + // pending LR fix translation + // qDebug("KOPrefs::usrReadConfig() fix translation "); + if ( mPreferredLanguage == 1 ) { + mLocaleDict = new QDict<QString>; + int i = 0; + QString fw ( germanwords[i] [0]); + while ( !fw.isEmpty() ) { + mLocaleDict->insert( fw, new QString (germanwords[i] [1] )); + ++i; + fw = germanwords[i] [0]; + } + + setLocaleDict( mLocaleDict ); + } + if ( mPreferredLanguage == 3 ) { + QString fileName = MainWindow::resourcePath()+"usertranslation.txt"; + QFile file( fileName ); + if (file.open( IO_ReadOnly ) ) { + QTextStream ts( &file ); + ts.setCodec( QTextCodec::codecForLocale() ); + QString text = ts.read(); + file.close(); + + QString line; + QString we; + QString wt; + int br = 0; + int nbr; + nbr = text.find ( "},", br ); + line = text.mid( br, nbr - br ); + br = nbr+1; + int se, ee, st, et; + mLocaleDict = new QDict<QString>; + QString end = "{ \"\",\"\" }"; + while ( (line != end) && (br > 1) ) { + //qDebug("%d *%s* ", br, line.latin1()); + se = line.find("\"")+1; + et = line.findRev("\"",-1); + ee = line.find("\",\""); + st = ee+3; + we = line.mid( se, ee-se ); + wt = line.mid( st, et-st ); + //qDebug("*%s* *%s* ", we.latin1(), wt.latin1()); + mLocaleDict->insert( we, new QString (wt) ); + nbr = text.find ( "}", br ); + line = text.mid( br, nbr - br ); + br = nbr+1; + } + //qDebug("end *%s* ", end.latin1()); + + setLocaleDict( mLocaleDict ); + } else { + qDebug("KO: Cannot find translation file usertranslation.txt"); + } + } + config()->setGroup("General"); + + mCustomCategories = config()->readListEntry("Custom Categories"); + if ( KOPrefs::instance()->mLanguageChanged ) { + mLocationDefaults.clear(); + mEventSummaryUser.clear(); + mTodoSummaryUser.clear(); + } + if (mLocationDefaults.isEmpty()) { + mLocationDefaults << i18n("Home") << i18n("Office") << i18n("Libary") << i18n("School") << i18n("Doctor") << i18n("Beach") + << i18n("University") << i18n("Restaurant") << i18n("Bar") << i18n("Conference room") << i18n("Cinema") << i18n("Lake") << i18n("Kindergarden") + << i18n("Germany") << i18n("Sweden") << i18n("Forest") << i18n("Desert") << i18n("Kitchen") ; + // << i18n("") << i18n("") << i18n("") << i18n("") << i18n("") << i18n("") << i18n("") << i18n("") + mLocationDefaults.sort(); + } + + if (mEventSummaryUser.isEmpty()) { + mEventSummaryUser = getDefaultList() ; + } + if (mTodoSummaryUser.isEmpty()) { + mTodoSummaryUser = getDefaultList() ; + } + + if (mCustomCategories.isEmpty()) setCategoryDefaults(); + + config()->setGroup("Personal Settings"); + mName = config()->readEntry("user_name",""); + mEmail = config()->readEntry("user_email",""); + fillMailDefaults(); + + config()->setGroup("Category Colors"); + QStringList::Iterator it; + for (it = mCustomCategories.begin();it != mCustomCategories.end();++it ) { + setCategoryColor(*it,config()->readColorEntry(*it,&mDefaultCategoryColor)); + + } + + if (mTimeZoneId.isEmpty()) { + setTimeZoneIdDefault(); + } + KPimPrefs::usrReadConfig(); +} + + +void KOPrefs::usrWriteConfig() +{ + config()->setGroup("General"); + config()->writeEntry("Custom Categories",mCustomCategories); + + config()->setGroup("Personal Settings"); + config()->writeEntry("user_name",mName); + config()->writeEntry("user_email",mEmail); + + config()->setGroup("Category Colors"); + QDictIterator<QColor> it(mCategoryColors); + while (it.current()) { + config()->writeEntry(it.currentKey(),*(it.current())); + ++it; + } + + + KPimPrefs::usrWriteConfig(); +} + +void KOPrefs::setCategoryColor(QString cat,const QColor & color) +{ + mCategoryColors.replace(cat,new QColor(color)); +} + +QColor *KOPrefs::categoryColor(QString cat) +{ + QColor *color = 0; + + if (!cat.isEmpty()) color = mCategoryColors[cat]; + + if (color) return color; + else return &mDefaultCategoryColor; +} + +void KOPrefs::setFullName(const QString &name) +{ + mName = name; +} + +void KOPrefs::setEmail(const QString &email) +{ + //qDebug(" KOPrefs::setEmai*********** %s",email.latin1() ); + mEmail = email; +} + +QString KOPrefs::fullName() +{ + if (mEmailControlCenter) { + KEMailSettings settings; + return settings.getSetting(KEMailSettings::RealName); + } else { + return mName; + } +} + +QString KOPrefs::email() +{ + if (mEmailControlCenter) { + KEMailSettings settings; + return settings.getSetting(KEMailSettings::EmailAddress); + } else { + return mEmail; + } +} +KConfig* KOPrefs::getConfig() +{ + return config(); +} diff --git a/korganizer/koprefs.h b/korganizer/koprefs.h new file mode 100644 index 0000000..fe044e6 --- a/dev/null +++ b/korganizer/koprefs.h @@ -0,0 +1,299 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + 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 KOPREFS_H +#define KOPREFS_H + +#include <qdict.h> + +#include <libkdepim/kpimprefs.h> + +class KConfig; +class QFont; +class QColor; +class QStringList; + +class KOPrefs : public KPimPrefs +{ + public: + enum { FormatVCalendar, FormatICalendar }; + enum { MailClientKMail, MailClientSendmail }; + enum { IMIPDummy, IMIPKMail }; + enum { IMIPOutbox, IMIPdirectsend }; + enum { neverAuto, addressbookAuto, selectedAuto }; + enum { standardDestination, askDestination }; + + virtual ~KOPrefs(); + + /** Get instance of KOPrefs. It is made sure that there is only one + instance. */ + static KOPrefs *instance(); + + /** Set preferences to default values */ + void usrSetDefaults(); + + /** Read preferences from config file */ + void usrReadConfig(); + + /** Write preferences to config file */ + void usrWriteConfig(); + void setCategoryDefaults(); + + protected: + void setTimeZoneIdDefault(); + + /** Fill empty mail fields with default values. */ + void fillMailDefaults(); + + private: + /** Constructor disabled for public. Use instance() to create a KOPrefs + object. */ + KOPrefs(); + + static KOPrefs *mInstance; + QDict<QString> *mLocaleDict; + QStringList getDefaultList(); + public: + // preferences data + KConfig* getConfig(); + void setFullName(const QString &); + QString fullName(); + void setEmail(const QString &); + QString email(); + + QString mAdditional; + + bool mEmailControlCenter; + + bool mBcc; + bool mAutoSave; + int mAutoSaveInterval; + bool mConfirm; + + bool mEnableGroupScheduling; + bool mEnableProjectView; + + int mDefaultFormat; + int mMailClient; + + QString mTimeZone; + QString mTimeZoneId; + //QString mTimeZoneName; // e.g. +00:04:00 Indian/Mauritius + //int mTimeZoneOffset; // e.g. -240 min + bool mUseDaylightsaving; + int mDaylightsavingStart; + int mDaylightsavingEnd; + int mStartTime; + int mDefaultDuration; + int mAlarmTime; + int mDaylightSavings; + + int mWorkingHoursStart; + int mWorkingHoursEnd; + bool mExcludeHolidays; + bool mExcludeSaturdays; + bool mMarcusBainsShowSeconds; + + QFont mTimeBarFont; + QFont mMonthViewFont; + QFont mAgendaViewFont; + QFont mMarcusBainsFont; + QFont mTimeLabelsFont; + QFont mTodoViewFont; + QFont mListViewFont; + QFont mDateNavigatorFont; + QFont mEditBoxFont; + QFont mJornalViewFont; + QFont mWhatsNextFont; + QFont mEventViewFont; + + + + + QColor mHolidayColor; + QColor mHighlightColor; + QColor mEventColor; + QColor mAgendaBgColor; + QColor mWorkingHoursColor; + QColor mTodoDueTodayColor; + QColor mTodoOverdueColor; + QColor mMonthViewEvenColor; + QColor mMonthViewOddColor; + QColor mMonthViewHolidayColor; + bool mMonthViewUsesDayColors; + bool mMonthViewSatSunTog; + QColor mAppColor1; + QColor mAppColor2; + bool mUseAppColors; + + int mDayBegins; + int mHourSize; + int mAllDaySize; + bool mShowFullMenu; + bool mDailyRecur; + bool mWeeklyRecur; + bool mMonthDailyRecur; + bool mMonthWeeklyRecur; + bool mMonthShowIcons; + bool mMonthShowShort; + bool mEnableToolTips; + bool mEnableMonthScroll; + bool mFullViewMonth; + bool mMonthViewUsesCategoryColor; + bool mFullViewTodo; + bool mShowCompletedTodo; + bool mMarcusBainsEnabled; + int mNextXDays; + int mWhatsNextDays; + int mWhatsNextPrios; + bool mEnableQuickTodo; + bool mLanguageChanged; + + bool mCompactDialogs; + bool mVerticalScreen; + + bool mShowIconNewTodo; + bool mShowIconNewEvent; + bool mShowIconSearch; + bool mShowIconList; + bool mShowIconDay1; + bool mShowIconDay5; + bool mShowIconDay7; + bool mShowIconMonth; + bool mShowIconTodoview; + bool mShowIconBackFast; + bool mShowIconBack; + bool mShowIconToday; + bool mShowIconForward; + bool mShowIconForwardFast; + bool mShowIconWhatsThis; + bool mShowIconNextDays; + bool mShowIconNext; + bool mShowIconJournal; + + bool mShowIconStretch; + + bool mToolBarHor; + bool mToolBarUp; + bool mToolBarMiniIcons; + + bool mAskForQuit; + bool mUsePassWd; + bool mWriteBackFile; + bool mAskForPreferences; + bool mShowSyncSummary; + bool mShowSyncEvents; + bool mShowTodoInAgenda; + bool mWriteBackExistingOnly; + + QString mRemoteIP; + QString mRemoteUser; + QString mRemotePassWd; + QString mRemoteFile; + QString mLocalTempFile; + + int mLastSyncTime; + int mSyncAlgoPrefs; + int mRingSyncAlgoPrefs; + QStringList mSyncProfileNames; + QString mLocalMachineName; + void setCategoryColor(QString cat,const QColor & color); + QColor *categoryColor(QString cat); + + QString mArchiveFile; + QString mHtmlExportFile; + bool mHtmlWithSave; + + QStringList mSelectedPlugins; + + QString mLastImportFile; + QString mLastVcalFile; + QString mLastSaveFile; + QString mLastLoadFile; + QString mLastSyncedLocalFile; + + + QString mDefaultAlarmFile; + int mIMIPScheduler; + int mIMIPSend; + QStringList mAdditionalMails; + int mIMIPAutoRefresh; + int mIMIPAutoInsertReply; + int mIMIPAutoInsertRequest; + int mIMIPAutoFreeBusy; + int mIMIPAutoFreeBusyReply; + + QStringList mTodoTemplates; + QStringList mEventTemplates; + + int mDestination; + + + bool mEditOnDoubleClick; + bool mViewChangeHoldFullscreen; + bool mViewChangeHoldNonFullscreen; + bool mCenterOnCurrentTime; + bool mSetTimeToDayStartAt; + bool mHighlightCurrentDay; + bool mUseHighlightLightColor; + bool mListViewMonthTimespan; + bool mWNViewShowsParents; + bool mWNViewShowLocation; + bool mTodoViewShowsPercentage; + bool mTodoViewUsesCatColors; + bool mTodoViewUsesSmallFont; + bool mTodoViewUsesForegroundColor; + bool mMonthViewUsesForegroundColor; + + bool mHightlightDateTimeEdit; + int mPreferredLanguage; + bool mUseQuicksave; + int mPreferredTime; + int mPreferredDate; + bool mWeekStartsOnSunday; + bool mShortDateInViewer; + QString mUserDateFormatLong; + QString mUserDateFormatShort; + + QStringList mLocationDefaults; + QStringList mEventSummaryUser; + QStringList mTodoSummaryUser; + + bool mUseInternalAlarmNotification; + int mAlarmPlayBeeps; + int mAlarmSuspendTime; + int mAlarmSuspendCount; + int mAlarmBeepInterval; + + private: + QDict<QColor> mCategoryColors; + QColor mDefaultCategoryColor; + + QFont mDefaultTimeBarFont; + QFont mDefaultViewFont; + QFont mDefaultMonthViewFont; + + QString mName; + QString mEmail; +}; + +#endif diff --git a/korganizer/koprefsdialog.cpp b/korganizer/koprefsdialog.cpp new file mode 100644 index 0000000..04fffe2 --- a/dev/null +++ b/korganizer/koprefsdialog.cpp @@ -0,0 +1,1610 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + 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. +*/ + +#include <qlayout.h> +#include <qlabel.h> +#include <qgroupbox.h> +#include <qbuttongroup.h> +#include <qlineedit.h> +#include <qfont.h> +#include <qslider.h> +#include <qfile.h> +#include <qtextstream.h> +#include <qcombobox.h> +#include <qvbox.h> +#include <qhbox.h> +#include <qregexp.h> +#include <qspinbox.h> +#include <qdatetime.h> +#include <qcheckbox.h> +#include <qradiobutton.h> +#include <qpushbutton.h> +#include <qstrlist.h> +#include <qapplication.h> + +#include <kcolorbutton.h> +#include <kdebug.h> +#include <klocale.h> +#include <kglobal.h> +#include <kfontdialog.h> +#include <kfiledialog.h> +#include <kmessagebox.h> +#include <kcolordialog.h> +#include <kiconloader.h> +#include <kemailsettings.h> +#include <kstandarddirs.h> + +#include <kurlrequester.h> +#include <klineedit.h> + +#if defined(USE_SOLARIS) +#include <sys/param.h> + +#define ZONEINFODIR "/usr/share/lib/zoneinfo" +#define INITFILE "/etc/default/init" +#endif + +#include "koprefs.h" + +#include "koprefsdialog.h" +#include "koprefsdialog.moc" + + +KOPrefsDialog::KOPrefsDialog(QWidget *parent, char *name, bool modal) : + KPrefsDialog(KOPrefs::instance(),parent,name,true) +{ + + setCaption( i18n("Preferences - some settings need a restart (nr)")); + mCategoryDict.setAutoDelete(true); + + KGlobal::locale()->insertCatalogue("timezones"); + + setupMainTab(); + setupLocaleTab(); + setupTimeZoneTab(); + setupTimeTab(); + setupLocaleDateTab(); + setupFontsTab(); + setupColorsTab(); + setupViewsTab(); + //setupSyncTab(); + //setupSyncAlgTab(); + //setupPrinterTab(); + //setupGroupSchedulingTab(); + //setupGroupAutomationTab(); +} + + +KOPrefsDialog::~KOPrefsDialog() +{ +} + +void KOPrefsDialog::setupLocaleDateTab() +{ +QFrame *topFrame = addPage(i18n("Date Format"),0,0); + QGridLayout *topLayout = new QGridLayout(topFrame,3,2); + topLayout->setSpacing(spacingHint()); + topLayout->setMargin(marginHint()); + int iii = 0; + + + KPrefsWidRadios *syncPrefsGroup = + addWidRadios(i18n("Date Format:"),&(KOPrefs::instance()->mPreferredDate),topFrame); + QString format; + if ( QApplication::desktop()->width() < 480 ) + format = "(%d.%m.%Y)"; + else + format = "(%d.%m.%Y|%A %d %B %Y)"; + syncPrefsGroup->addRadio(i18n("24.03.2004 "+format)); + if ( QApplication::desktop()->width() < 480 ) + format = "(%m.%d.%Y)"; + else + format = "(%m.%d.%Y|%A %B %d %Y)"; + syncPrefsGroup->addRadio(i18n("03.24.2004 "+format)); + if ( QApplication::desktop()->width() < 480 ) + format = "(%Y-%m-%d)"; + else + format = "(%Y-%m-%d|%A %Y %B %d)"; + syncPrefsGroup->addRadio(i18n("2004-03-24 "+format)); + syncPrefsGroup->addRadio(i18n("User defined")); + topLayout->addMultiCellWidget( syncPrefsGroup->groupBox(),iii,iii,0,1); + ++iii; + ++iii; + QLabel * lab; + mUserDateFormatLong = new QLineEdit(topFrame); + lab = new QLabel(mUserDateFormatLong, i18n("User long date:"), topFrame); + topLayout->addWidget(lab ,iii,0); + topLayout->addWidget(mUserDateFormatLong,iii,1); + ++iii; + mUserDateFormatShort = new QLineEdit(topFrame); + lab = new QLabel(mUserDateFormatShort, i18n("User short date:"), topFrame); + topLayout->addWidget(lab ,iii,0); + topLayout->addWidget(mUserDateFormatShort,iii,1); + ++iii; + lab = new QLabel( i18n("Monday 19 April 2004: %A %d %B %Y"), topFrame); + topLayout->addMultiCellWidget(lab ,iii,iii,0,1); + ++iii; + lab = new QLabel( i18n("Mon 19.04.04: %a %d.%m.%y"), topFrame); + topLayout->addMultiCellWidget(lab ,iii,iii,0,1); + ++iii; + lab = new QLabel( i18n("Mon, 19.Apr.04: %a, %d.%b.%y"), topFrame); + topLayout->addMultiCellWidget(lab ,iii,iii,0,1); + ++iii; + +} + +void KOPrefsDialog::setupLocaleTab() +{ + QFrame *topFrame = addPage(i18n("Locale"),0,0); + QGridLayout *topLayout = new QGridLayout(topFrame,4,2); + topLayout->setSpacing(spacingHint()); + topLayout->setMargin(marginHint()); + int iii = 0; + KPrefsWidRadios *syncPrefsGroup = + addWidRadios(i18n("Language:(needs restart)"),&(KOPrefs::instance()->mPreferredLanguage),topFrame); + syncPrefsGroup->addRadio(i18n("English")); + syncPrefsGroup->addRadio(i18n("German")); + syncPrefsGroup->addRadio(i18n("French(nyi)")); + syncPrefsGroup->addRadio(i18n("User defined (usertranslation.txt)")); + if ( QApplication::desktop()->width() < 300 ) + ;// syncPrefsGroup->groupBox()-> setOrientation (Qt::Vertical); + topLayout->addMultiCellWidget( syncPrefsGroup->groupBox(),iii,iii,0,1); + ++iii; + + syncPrefsGroup = + addWidRadios(i18n("Time Format(nr):"),&(KOPrefs::instance()->mPreferredTime),topFrame); + if ( QApplication::desktop()->width() > 300 ) + syncPrefsGroup->groupBox()-> setOrientation (Qt::Vertical); + syncPrefsGroup->addRadio(i18n("24:00")); + syncPrefsGroup->addRadio(i18n("12:00am")); + syncPrefsGroup->groupBox()-> setOrientation (Qt::Vertical); + topLayout->addMultiCellWidget( syncPrefsGroup->groupBox(),iii,iii,0,1); + ++iii; + KPrefsWidBool *sb; + if ( QApplication::desktop()->width() < 300 ) { + sb = + addWidBool(i18n("Week starts on Sunday"), + &(KOPrefs::instance()->mWeekStartsOnSunday),topFrame); + topLayout->addMultiCellWidget(sb->checkBox(), iii,iii,0,1); + ++iii; + sb = + addWidBool(i18n("Use short date in (WN/E) view"), + &(KOPrefs::instance()->mShortDateInViewer),topFrame); + topLayout->addMultiCellWidget(sb->checkBox(), iii,iii,0,1); + } + else { + QWidget * hb = new QWidget( topFrame ); + QHBoxLayout *hbLayout = new QHBoxLayout(hb); + sb = + addWidBool(i18n("Week starts on Sunday"), + &(KOPrefs::instance()->mWeekStartsOnSunday),hb); + hbLayout->addWidget(sb->checkBox() ); + sb = + addWidBool(i18n("Use short date in (WN/E) view"), + &(KOPrefs::instance()->mShortDateInViewer),hb); + hbLayout->addWidget(sb->checkBox() ); + topLayout->addMultiCellWidget(hb, iii,iii,0,1); + + } + //#ifndef DESKTOP_VERSION +#if 0 + ++iii; + sb = + addWidBool(i18n("Quick load/save (w/o Unicode)"), + &(KOPrefs::instance()->mUseQuicksave),topFrame); + topLayout->addMultiCellWidget(sb->checkBox(), iii,iii,0,1); +#endif +} +void KOPrefsDialog::showSyncPage() +{ + showPage ( 2 ) ; + +} +void KOPrefsDialog::setupSyncAlgTab() +{ +#if 0 + QLabel * lab; + QFrame *topFrame = addPage(i18n("Sync Prefs"),0,0); + mSetupSyncAlgTab = topFrame; + QGridLayout *topLayout = new QGridLayout(topFrame,6,2); + topLayout->setSpacing(spacingHint()); + topLayout->setMargin(marginHint()); + int iii = 0; + + KPrefsWidBool *sb = + addWidBool(i18n("Ask for preferences before syncing"), + &(KOPrefs::instance()->mAskForPreferences),topFrame); + topLayout->addMultiCellWidget(sb->checkBox(), iii,iii,0,1); + + ++iii; + + KPrefsWidRadios *syncPrefsGroup = + addWidRadios(i18n("Sync preferences:"),&(KOPrefs::instance()->mSyncAlgoPrefs), + topFrame); + syncPrefsGroup->addRadio(i18n("Take local entry on conflict")); + syncPrefsGroup->addRadio(i18n("Take remote entry on conflict")); + syncPrefsGroup->addRadio(i18n("Take newest entry on conflict")); + syncPrefsGroup->addRadio(i18n("Ask for every entry on conflict")); + syncPrefsGroup->addRadio(i18n("Force take local entry always")); + syncPrefsGroup->addRadio(i18n("Force take remote entry always")); + topLayout->addMultiCellWidget( syncPrefsGroup->groupBox(),iii,iii,0,1); + ++iii; + sb = + addWidBool(i18n("Show summary after syncing"), + &(KOPrefs::instance()->mShowSyncSummary),topFrame); + topLayout->addMultiCellWidget(sb->checkBox(), iii,iii,0,1); + + ++iii; +#endif + + + +} + + +void KOPrefsDialog::setupSyncTab() +{ +#if 0 + QLabel * lab; + QFrame *topFrame = addPage(i18n("Sync Network"),0,0); + QGridLayout *topLayout = new QGridLayout(topFrame,6,2); + topLayout->setSpacing(spacingHint()); + topLayout->setMargin(marginHint()); + lab = new QLabel(i18n("Remote syncing (via ssh/scp)\nnetwork settings "), topFrame); + int iii = 0; + topLayout->addMultiCellWidget(lab , iii,iii,0,1); + ++iii; + + mRemoteIPEdit = new QLineEdit(topFrame); + lab = new QLabel(mRemoteIPEdit, i18n("Remote IP:"), topFrame); + topLayout->addWidget(lab ,iii,0); + topLayout->addWidget(mRemoteIPEdit,iii,1); + ++iii; + mRemoteUser = new QLineEdit(topFrame); + lab = new QLabel(mRemoteUser, i18n("Remote user:"), topFrame); + topLayout->addWidget(lab ,iii,0); + topLayout->addWidget(mRemoteUser, iii,1); + ++iii; + + mRemoteFile = new QLineEdit(topFrame); + lab = new QLabel(mRemoteFile, i18n("Remote file:"), topFrame); + topLayout->addWidget(lab ,iii,0); + topLayout->addWidget(mRemoteFile,iii,1); + ++iii; + + mLocalTempFile = new QLineEdit(topFrame); + lab = new QLabel(mLocalTempFile, i18n("Local temp file:"), topFrame); + topLayout->addWidget(lab ,iii,0); + topLayout->addWidget(mLocalTempFile,iii,1); + ++iii; + + KPrefsWidBool *wb = + addWidBool(i18n("Write back synced file"), + &(KOPrefs::instance()->mWriteBackFile),topFrame); + topLayout->addMultiCellWidget(wb->checkBox(), iii,iii,0,1); + ++iii; + wb = + addWidBool(i18n("Write back existing entries only"), + &(KOPrefs::instance()->mWriteBackExistingOnly),topFrame); + topLayout->addMultiCellWidget(wb->checkBox(), iii,iii,0,1); + ++iii; + +#endif +} + +void KOPrefsDialog::setupMainTab() +{ + QFrame *topFrame = addPage(i18n("General"),0,0); + // DesktopIcon("identity",KIcon::SizeMedium)); + + QGridLayout *topLayout = new QGridLayout(topFrame,6,2); + topLayout->setSpacing(spacingHint()); + topLayout->setMargin(marginHint()); + + // KPrefsWidBool *emailControlCenter = +// addWidBool(i18n("&Use email settings from Control Center"), +// &(KOPrefs::instance()->mEmailControlCenter),topFrame); +// topLayout->addMultiCellWidget(emailControlCenter->checkBox(),0,0,0,1); + // connect(emailControlCenter->checkBox(),SIGNAL(toggled(bool)), + // SLOT(toggleEmailSettings(bool))); + + mNameEdit = new QLineEdit(topFrame); + mNameLabel = new QLabel(mNameEdit, i18n("Full &name:"), topFrame); + topLayout->addWidget(mNameLabel,0,0); + topLayout->addWidget(mNameEdit,0,1); + + mEmailEdit = new QLineEdit(topFrame); + mEmailLabel = new QLabel(mEmailEdit, i18n("E&mail address:"),topFrame); + topLayout->addWidget(mEmailLabel,1,0); + topLayout->addWidget(mEmailEdit,1,1); + KPrefsWidBool *wb; + QHBox *dummy; + if ( QApplication::desktop()->width() > 480 ) { + dummy = new QHBox(topFrame); + } else { + dummy = new QVBox(topFrame); + } + + topLayout->addMultiCellWidget(dummy, 2,2,0,1); + addWidBool(i18n("Full menu bar(nr)"), + &(KOPrefs::instance()->mShowFullMenu),dummy); + + + addWidBool(i18n("Mini icons in toolbar(nr)"), + &(KOPrefs::instance()->mToolBarMiniIcons),dummy); + + + dummy = new QHBox(topFrame); + new QLabel(i18n("Days in What's Next:"),dummy); + mWhatsNextSpin = new QSpinBox(1,14,1,dummy); + + topLayout->addMultiCellWidget(dummy,3,3,0,1); + + + + dummy = new QHBox(topFrame); + new QLabel(i18n("Days in Next-X-Days:"),dummy); + mNextXDaysSpin = new QSpinBox(2,14,1,dummy); + + topLayout->addMultiCellWidget(dummy,4,4,0,1); + + QHBox *prioBox = new QHBox(topFrame); + // intervalBox->setSpacing(spacingHint()); + topLayout->addMultiCellWidget(prioBox,5,5,0,1); + QString messa = i18n("Show topmost todo prios in What's Next:"); + + if ( QApplication::desktop()->width() < 300 ) + messa = i18n("Show topmost todo prios in What's N.:"); + QLabel *prioLabel = new QLabel(messa, prioBox); + mPrioSpin = new QSpinBox(0,5,1,prioBox); + if ( QApplication::desktop()->width() < 300 ) + mPrioSpin->setFixedWidth( 40 ); + + // KPrefsWidBool *bcc = +// addWidBool(i18n("Send copy to owner when mailing events"), +// &(KOPrefs::instance()->mBcc),topFrame); +// topLayout->addMultiCellWidget(bcc->checkBox(),4,4,0,1); + + + // QGroupBox *autoSaveGroup = new QGroupBox(1,Horizontal,i18n("Auto-Save"), topFrame); + //topLayout->addMultiCellWidget(autoSaveGroup,6,6,0,1); + + // addWidBool(i18n("Enable automatic saving of calendar"), + // &(KOPrefs::instance()->mAutoSave),autoSaveGroup); + + QHBox *intervalBox = new QHBox(topFrame); + // intervalBox->setSpacing(spacingHint()); + topLayout->addMultiCellWidget(intervalBox,6,6,0,1); + QLabel *autoSaveIntervalLabel = new QLabel(i18n("Auto save delay in minutes:"),intervalBox); + mAutoSaveIntervalSpin = new QSpinBox(0,500,1,intervalBox); + autoSaveIntervalLabel->setBuddy(mAutoSaveIntervalSpin); + /* + QHBox * agendasize = new QHBox ( topFrame ); + + new QLabel (i18n("AllDayAgenda Height:"), agendasize ); + + + mHourSizeSlider = new QSlider(24,47,1,24,Horizontal,agendasize); + topLayout->addMultiCellWidget(agendasize,7,7,0,1); + */ + KPrefsWidBool *verticalScreen = + addWidBool(i18n("Show vertical screen (Needs restart)"), + &(KOPrefs::instance()->mVerticalScreen),topFrame); + //topLayout->addWidget(verticalScreen->checkBox(),ii++,0); + topLayout->addMultiCellWidget(verticalScreen->checkBox(),7,7,0,1); + + KPrefsWidBool *ask = + addWidBool(i18n("Ask for quit when closing KO/Pi"), + &(KOPrefs::instance()->mAskForQuit),topFrame); + topLayout->addMultiCellWidget(ask->checkBox(),8,8,0,1); + + + /* + KPrefsWidBool *confirmCheck = + addWidBool(i18n("Confirm &deletes"),&(KOPrefs::instance()->mConfirm), + topFrame); + topLayout->addMultiCellWidget(confirmCheck->checkBox(),7,7,0,1); + + + mEnableGroupScheduling = + addWidBool(i18n("Enable group scheduling"), + &(KOPrefs::instance()->mEnableGroupScheduling),topFrame); + topLayout->addWidget(mEnableGroupScheduling->checkBox(),8,0); + connect(mEnableGroupScheduling->checkBox(),SIGNAL(clicked()), + SLOT(warningGroupScheduling())); + + mEnableProjectView = + addWidBool(i18n("Enable project view"), + &(KOPrefs::instance()->mEnableProjectView),topFrame); + topLayout->addWidget(mEnableProjectView->checkBox(),9,0); + connect(mEnableProjectView->checkBox(),SIGNAL(clicked()), + SLOT(warningProjectView())); + + // Can't be disabled anymore + mEnableGroupScheduling->checkBox()->hide(); + + // Disable setting, because this feature now becomes stable + mEnableProjectView->checkBox()->hide(); + + KPrefsWidRadios *defaultFormatGroup = + addWidRadios(i18n("Default Calendar Format"), + &(KOPrefs::instance()->mDefaultFormat),topFrame); + defaultFormatGroup->addRadio(i18n("vCalendar")); + defaultFormatGroup->addRadio(i18n("iCalendar")); + + topLayout->addMultiCellWidget(defaultFormatGroup->groupBox(),10,10,0,1); + + // Default format unconditionally is iCalendar + defaultFormatGroup->groupBox()->hide(); + + KPrefsWidRadios *mailClientGroup = + addWidRadios(i18n("Mail Client"),&(KOPrefs::instance()->mMailClient), + topFrame); + mailClientGroup->addRadio(i18n("KMail")); + mailClientGroup->addRadio(i18n("Sendmail")); + topLayout->addMultiCellWidget(mailClientGroup->groupBox(),11,11,0,1); + + KPrefsWidBool *htmlsave = + addWidBool(i18n("Export to HTML with every save"),&(KOPrefs::instance()->mHtmlWithSave), + topFrame); + topLayout->addMultiCellWidget(htmlsave->checkBox(),12,12,0,1); + + KPrefsWidRadios *destinationGroup = + addWidRadios(i18n("New Events/Todos should"),&(KOPrefs::instance()->mDestination), + topFrame); + destinationGroup->addRadio(i18n("be added to the standard resource")); + destinationGroup->addRadio(i18n("be asked which resource to use")); + topLayout->addMultiCellWidget(destinationGroup->groupBox(),13,13,0,1); + + topLayout->setRowStretch(14,1); + */ +} + + +void KOPrefsDialog::setupTimeTab() +{ + QFrame *topFrame = addPage(i18n("Time"),0,0); + // DesktopIcon("clock",KIcon::SizeMedium)); + + QGridLayout *topLayout = new QGridLayout(topFrame,4,2); + topLayout->setSpacing(spacingHint()); + topLayout->setMargin(marginHint()); + + QHBox *dummy = new QHBox(topFrame); + KPrefsWidTime *dayBegins = + addWidTime(i18n("Day begins at:"),&(KOPrefs::instance()->mDayBegins), + dummy); + //topLayout->addWidget(dayBegins->label(),2,0); + + //topLayout->addWidget(dayBegins->spinBox(),2,1); + topLayout->addMultiCellWidget(dummy,0,0,0,1); + + topLayout->addWidget(new QLabel(i18n("Default appointment time:"), + topFrame),1,0); + mStartTimeSpin = new QSpinBox(0,23,1,topFrame); + mStartTimeSpin->setSuffix(":00"); + topLayout->addWidget(mStartTimeSpin,1,1); + + topLayout->addWidget(new QLabel(i18n("Def. duration of new app.:"), + topFrame),2,0); + mDefaultDurationSpin = new QSpinBox(0,23,1,topFrame); + mDefaultDurationSpin->setSuffix(":00"); + topLayout->addWidget(mDefaultDurationSpin,2,1); + + QStringList alarmList; + alarmList << i18n("1 minute") << i18n("5 minutes") << i18n("10 minutes") + << i18n("15 minutes") << i18n("30 minutes")<< i18n("1 hour")<< i18n("3 hours") << i18n("24 hours") ; + topLayout->addWidget(new QLabel(i18n("Default alarm time:"),topFrame), + 3,0); + mAlarmTimeCombo = new QComboBox(topFrame); + mAlarmTimeCombo->insertStringList(alarmList); + topLayout->addWidget(mAlarmTimeCombo,3,1); + + + QGroupBox *workingHoursGroup = new QGroupBox(1,Horizontal, + i18n("Working Hours"), + topFrame); + topLayout->addMultiCellWidget(workingHoursGroup,4,4,0,1); + workingHoursGroup->layout()->setSpacing( 0 ); + workingHoursGroup->layout()->setMargin( 4 ); + QHBox *workStartBox = new QHBox(workingHoursGroup); + // workStartBox->setMargin( 0 ); + addWidTime(i18n("Daily starting hour:"), + &(KOPrefs::instance()->mWorkingHoursStart),workStartBox); + + QHBox *workEndBox = new QHBox(workingHoursGroup); + //workEndBox->setMargin( 0 ); + addWidTime(i18n("Daily ending hour:"), + &(KOPrefs::instance()->mWorkingHoursEnd),workEndBox); + QVBox *excludeBox = new QVBox(workingHoursGroup); + //excludeBox->setMargin( 0 ); + addWidBool(i18n("Exclude holidays"), + &(KOPrefs::instance()->mExcludeHolidays),excludeBox); + + addWidBool(i18n("Exclude Saturdays"), + &(KOPrefs::instance()->mExcludeSaturdays),excludeBox); + +// KPrefsWidBool *marcusBainsShowSeconds = addWidBool(i18n("Show seconds on Marcus Bains line"), +// &(KOPrefs::instance()->mMarcusBainsShowSeconds), +// topFrame); +// topLayout->addWidget(marcusBainsShowSeconds->checkBox(),5,0); + + // topLayout->setRowStretch(6,1); +} + + +void KOPrefsDialog::setupViewsTab() +{ + + QFrame *topFrame = addPage(i18n("Views"),0,0); + // DesktopIcon("viewmag",KIcon::SizeMedium)); + + QGridLayout *topLayout = new QGridLayout(topFrame,6,1); + topLayout->setSpacing(spacingHint()); + topLayout->setMargin(marginHint()); + +// QBoxLayout *dayBeginsLayout = new QHBoxLayout; +// topLayout->addLayout(dayBeginsLayout,0,0); + +// KPrefsWidTime *dayBegins = +// addWidTime(i18n("Day begins at:"),&(KOPrefs::instance()->mDayBegins), +// topFrame); +// dayBeginsLayout->addWidget(dayBegins->label()); +// dayBeginsLayout->addStretch(1); +// dayBeginsLayout->addWidget(dayBegins->spinBox()); + +// QBoxLayout *nextDaysLayout = new QHBoxLayout; +// topLayout->addLayout(nextDaysLayout,1,0); +// nextDaysLayout->addWidget(new QLabel(i18n("Days to show in Next-X-Days view:"),topFrame)); +// mNextXDaysSpin = new QSpinBox(2,14,1,topFrame); +// nextDaysLayout->addStretch(1); +// nextDaysLayout->addWidget(mNextXDaysSpin); + + + int ii = 0; + KPrefsWidBool *dummy = + addWidBool(i18n("Edit item on doubleclick (if not, show)"), + &(KOPrefs::instance()->mEditOnDoubleClick),topFrame); + topLayout->addWidget(dummy->checkBox(),ii++,0); + + dummy = + addWidBool(i18n("Highlight current day in agenda"), + &(KOPrefs::instance()->mHighlightCurrentDay),topFrame); + topLayout->addWidget(dummy->checkBox(),ii++,0); + + dummy = + addWidBool(i18n("Use light color for highlight current day"), + &(KOPrefs::instance()->mUseHighlightLightColor),topFrame); + topLayout->addWidget(dummy->checkBox(),ii++,0); + + KPrefsWidBool *dailyRecur = + addWidBool(i18n("Show events that recur daily in date nav."), + &(KOPrefs::instance()->mDailyRecur),topFrame); + topLayout->addWidget(dailyRecur->checkBox(),ii++,0); + + KPrefsWidBool *weeklyRecur = + addWidBool(i18n("Show ev. that recur weekly in date nav."), + &(KOPrefs::instance()->mWeeklyRecur),topFrame); + topLayout->addWidget(weeklyRecur->checkBox(),ii++,0); + if ( QApplication::desktop()->width() > 640 ) { + + KPrefsWidBool *enableToolTips = + addWidBool(i18n("Enable tooltips displaying summary of ev."), + &(KOPrefs::instance()->mEnableToolTips),topFrame); + topLayout->addWidget(enableToolTips->checkBox(),ii++,0); + + } + KPrefsWidBool *passwdk = + addWidBool(i18n("Show parent To-Do's in What's Next view"), + &(KOPrefs::instance()->mWNViewShowsParents),topFrame); + topLayout->addWidget(passwdk->checkBox(), ii++,0); + + passwdk = + addWidBool(i18n("Show location in What's Next view"), + &(KOPrefs::instance()->mWNViewShowLocation),topFrame); + topLayout->addWidget(passwdk->checkBox(), ii++,0); + + passwdk = + addWidBool(i18n("Show Sync Events in WN/Agenda view"), + &(KOPrefs::instance()->mShowSyncEvents),topFrame); + topLayout->addWidget(passwdk->checkBox(), ii++,0); + + + KPrefsWidBool *marcusBainsEnabled = + addWidBool(i18n("Show Marcus Bains line"), + &(KOPrefs::instance()->mMarcusBainsEnabled),topFrame); + topLayout->addWidget(marcusBainsEnabled->checkBox(),ii++,0); + + + // topLayout->addWidget(hourSizeGroup,ii++,0); + // topLayout->addMultiCellWidget(hourSizeGroup,ii,ii,0,0); + //topLayout->setRowStretch(11,1); + + + + + + + topFrame = addPage(i18n("ViewChange"),0,0); + // DesktopIcon("viewmag",KIcon::SizeMedium)); + + topLayout = new QGridLayout(topFrame,6,1); + topLayout->setSpacing(spacingHint()); + topLayout->setMargin(marginHint()); + ii = 0; + + + dummy = + addWidBool(i18n("Hold fullscreen on view change"), + &(KOPrefs::instance()->mViewChangeHoldFullscreen),topFrame); + topLayout->addWidget(dummy->checkBox(),ii++,0); + + dummy = + addWidBool(i18n("Hold non-fullscreen on view change"), + &(KOPrefs::instance()->mViewChangeHoldNonFullscreen),topFrame); + topLayout->addWidget(dummy->checkBox(),ii++,0); + + + KPrefsWidBool *fullViewTodo = + addWidBool(i18n("Event list view uses full window"), + &(KOPrefs::instance()->mFullViewTodo),topFrame); + topLayout->addWidget(fullViewTodo->checkBox(),ii++,0); + + KPrefsWidBool *fullViewMonth = + addWidBool(i18n("Next days view uses full window"), + &(KOPrefs::instance()->mFullViewMonth),topFrame); + topLayout->addWidget(fullViewMonth->checkBox(),ii++,0); + + dummy = + addWidBool(i18n("Set agenda to DayBeginsAt on change"), + &(KOPrefs::instance()->mSetTimeToDayStartAt),topFrame); + topLayout->addWidget(dummy->checkBox(),ii++,0); + + dummy = + addWidBool(i18n("Set agenda to current time on change"), + &(KOPrefs::instance()->mCenterOnCurrentTime),topFrame); + topLayout->addWidget(dummy->checkBox(),ii++,0); + + dummy = + addWidBool(i18n("Listview uses monthly timespan"), + &(KOPrefs::instance()->mListViewMonthTimespan),topFrame); + topLayout->addWidget(dummy->checkBox(),ii++,0); + dummy = + addWidBool(i18n("Highlight selection in Time Edit"), + &(KOPrefs::instance()->mHightlightDateTimeEdit),topFrame); + topLayout->addWidget( dummy->checkBox(), ii++,0); + + + + + + topFrame = addPage(i18n("Month View"),0,0); + // DesktopIcon("viewmag",KIcon::SizeMedium)); + + topLayout = new QGridLayout(topFrame,5,1); + topLayout->setSpacing(spacingHint()); + topLayout->setMargin(marginHint()); + ii = 0; + QLabel *lab; + QHBox *habo = new QHBox( topFrame ); + if ( QApplication::desktop()->width() < 320 ) { + lab = new QLabel ( i18n("Show events that recur "), topFrame ); + topLayout->addMultiCellWidget(lab,ii, ii,0,1); + ii++; + + } else { + new QLabel ( i18n("Show events that recur "), habo ); + + } + dailyRecur = + addWidBool(i18n("daily"), + &(KOPrefs::instance()->mMonthDailyRecur),habo); + // topLayout->addWidget(dailyRecur->checkBox(),ii++,0); + + weeklyRecur = + addWidBool(i18n("weekly"), + &(KOPrefs::instance()->mMonthWeeklyRecur),habo); + topLayout->addMultiCellWidget(habo,ii, ii,0,1); + ii++; + + + habo = new QHBox( topFrame ); + if ( QApplication::desktop()->width() < 320 ) { + lab = new QLabel (i18n("Show in every cell ") , topFrame ); + topLayout->addMultiCellWidget(lab,ii, ii,0,1); + ii++; + + } else { + new QLabel ( i18n("Show in every cell "), habo ); + } + weeklyRecur = + addWidBool(i18n("short month"), + &(KOPrefs::instance()->mMonthShowShort),habo); + weeklyRecur = + addWidBool(i18n("icons"), + &(KOPrefs::instance()->mMonthShowIcons),habo); + + topLayout->addMultiCellWidget(habo,ii, ii,0,1); + ii++; +#ifdef DESKTOP_VERSION + KPrefsWidBool *enableMonthScroll = + addWidBool(i18n("Enable scrollbars in month view cells"), + &(KOPrefs::instance()->mEnableMonthScroll),topFrame); + topLayout->addWidget(enableMonthScroll->checkBox(),ii++,0); +#endif + + dummy = + addWidBool(i18n("Show Sat/Sun together"), + &(KOPrefs::instance()->mMonthViewSatSunTog),topFrame); + topLayout->addWidget(dummy->checkBox(),ii++,0); + + KPrefsWidBool *coloredCategoriesInMonthView = + addWidBool(i18n("Month view uses category colors"), + &(KOPrefs::instance()->mMonthViewUsesCategoryColor),topFrame); + topLayout->addWidget(coloredCategoriesInMonthView->checkBox(),ii++,0); + + dummy = + addWidBool(i18n("Categorie colors are applied to text"), + &(KOPrefs::instance()->mMonthViewUsesForegroundColor),topFrame); + topLayout->addWidget(dummy->checkBox(),ii++,0); + coloredCategoriesInMonthView = + addWidBool(i18n("Month view uses day colors"), + &(KOPrefs::instance()->mMonthViewUsesDayColors),topFrame); + topLayout->addWidget(coloredCategoriesInMonthView->checkBox(),ii++,0); + + KPrefsWidColor *holidayColor = + addWidColor(i18n("Day color odd months"), + &(KOPrefs::instance()->mMonthViewOddColor),topFrame); + topLayout->addWidget(holidayColor->label(),ii,0); + topLayout->addWidget(holidayColor->button(),ii++,1); + + holidayColor = + addWidColor(i18n("Day color even months"), + &(KOPrefs::instance()->mMonthViewEvenColor),topFrame); + topLayout->addWidget(holidayColor->label(),ii,0); + topLayout->addWidget(holidayColor->button(),ii++,1); + + + holidayColor = + addWidColor(i18n("Color for Sundays + category \"Holiday\""), + &(KOPrefs::instance()->mMonthViewHolidayColor),topFrame); + topLayout->addWidget(holidayColor->label(),ii,0); + topLayout->addWidget(holidayColor->button(),ii++,1); + + // *********************** Todo View + + topFrame = addPage(i18n("Todo View"),0,0); + // DesktopIcon("viewmag",KIcon::SizeMedium)); + + topLayout = new QGridLayout(topFrame,4,1); + topLayout->setSpacing(spacingHint()); + topLayout->setMargin(marginHint()); + ii = 0; + + KPrefsWidBool *showCompletedTodo = + addWidBool(i18n("To-do view shows completed Todos"), + &(KOPrefs::instance()->mShowCompletedTodo),topFrame); + topLayout->addWidget(showCompletedTodo->checkBox(),ii++,0); + dummy = + addWidBool(i18n("To-do view shows complete as 'xx %'"), + &(KOPrefs::instance()->mTodoViewShowsPercentage),topFrame); + topLayout->addWidget(dummy->checkBox(),ii++,0); + + dummy = + addWidBool(i18n("Small To-do view uses smaller font"), + &(KOPrefs::instance()->mTodoViewUsesSmallFont),topFrame); + topLayout->addWidget(dummy->checkBox(),ii++,0); + + + + dummy = + addWidBool(i18n("Todo view uses category colors"), + &(KOPrefs::instance()->mTodoViewUsesCatColors),topFrame); + topLayout->addWidget(dummy->checkBox(),ii++,0); + + + QWidget* wid = new QWidget( topFrame ); + // Todo due today color + KPrefsWidColor *todoDueTodayColor = + addWidColor(i18n("Todo due today color:"), + &(KOPrefs::instance()->mTodoDueTodayColor),wid); + QHBoxLayout *widLayout = new QHBoxLayout(wid); + widLayout->addWidget( todoDueTodayColor->label() ); + widLayout->addWidget( todoDueTodayColor->button() ); + topLayout->addWidget(wid,ii++,0); + //topLayout->addWidget(todoDueTodayColor->button(),ii++,1); + + // Todo overdue color + wid = new QWidget( topFrame ); + widLayout = new QHBoxLayout(wid); + KPrefsWidColor *todoOverdueColor = + addWidColor(i18n("Todo overdue color:"), + &(KOPrefs::instance()->mTodoOverdueColor),wid); + widLayout->addWidget(todoOverdueColor->label()); + widLayout->addWidget(todoOverdueColor->button()); + topLayout->addWidget(wid,ii++,0); + + dummy = + addWidBool(i18n("Colors are applied to text"), + &(KOPrefs::instance()->mTodoViewUsesForegroundColor),topFrame); + topLayout->addWidget(dummy->checkBox(),ii++,0); + + dummy = + addWidBool(i18n("Allday Agenda view shows todos"), + &(KOPrefs::instance()->mShowTodoInAgenda),topFrame); + topLayout->addWidget(dummy->checkBox(),ii++,0); + + + + + topFrame = addPage(i18n("Alarm"),0,0); + // DesktopIcon("viewmag",KIcon::SizeMedium)); + + topLayout = new QGridLayout(topFrame,2,1); + topLayout->setSpacing(spacingHint()); + topLayout->setMargin(marginHint()); + int iii = 0; + + dummy = + addWidBool(i18n("Use internal alarm notification"), + &(KOPrefs::instance()->mUseInternalAlarmNotification),topFrame); + topLayout->addWidget(dummy->checkBox(),iii++,0); + lab = new QLabel( i18n("Note: KO/Pi must be running to notify you about an alarm. Recommended for use on Zaurus: Disable this option and install KO/Pi alarm applet.\n"), topFrame); + + topLayout->addWidget(lab ,iii++,0); +#ifndef DESKTOP_VERSION + lab->setAlignment( AlignLeft|WordBreak|AlignTop); +#else + lab->setAlignment( AlignLeft|BreakAnywhere|WordBreak|AlignTop); + lab->setSizePolicy( QSizePolicy( QSizePolicy::Ignored , QSizePolicy::Ignored,true) ); +#endif + + QHBox* dummyBox = new QHBox(topFrame); + new QLabel(i18n("Play beeps count:"),dummyBox); + mAlarmPlayBeeps = new QSpinBox(0,500,1,dummyBox); + topLayout->addWidget(dummyBox,iii++,0); + + dummyBox = new QHBox(topFrame); + new QLabel(i18n("Beeps interval in sec:"),dummyBox); + mAlarmBeepInterval = new QSpinBox(1,600,1,dummyBox); + topLayout->addWidget(dummyBox,iii++,0); + + dummyBox = new QHBox(topFrame); + new QLabel(i18n("Default suspend time in min:"),dummyBox); + mAlarmSuspendTime = new QSpinBox(1,600,1,dummyBox); + topLayout->addWidget(dummyBox,iii++,0); + + dummyBox = new QHBox(topFrame); + new QLabel(i18n("Auto suspend count:"),dummyBox); + mAlarmSuspendCount = new QSpinBox(0,60,1,dummyBox); + topLayout->addWidget(dummyBox,iii++,0); + + + + + + + + QHBox* hbo = new QHBox ( topFrame ); + mDefaultAlarmFile = new QLineEdit(hbo); + QPushButton * loadTemplate = new QPushButton(hbo); + QPixmap icon; + if ( QApplication::desktop()->width() < 321 ) + icon = SmallIcon("fileimport16"); + else + icon = SmallIcon("fileimport"); + loadTemplate->setIconSet (icon ) ; + connect( loadTemplate, SIGNAL( clicked() ), this , SLOT( selectSoundFile() ) ); + int size = loadTemplate->sizeHint().height(); + loadTemplate->setFixedSize( size, size ); + //lab = new QLabel( i18n("This setting is useless for 5500 user!"), topFrame); + // topLayout->addWidget(lab ,iii++,0); + lab = new QLabel( i18n("Alarm *.wav file for newly created alarm:"), topFrame); + topLayout->addWidget(lab ,iii++,0); + topLayout->addWidget(hbo,iii++,0); + // lab = new QLabel( i18n("Note: This does not mean, that for every alarm this file is replayed. This file here is associated with a newly created alarm."), topFrame); + +// topLayout->addWidget(lab ,iii++,0); +// #ifndef DESKTOP_VERSION +// lab->setAlignment( AlignLeft|WordBreak|AlignTop); +// #else +// lab->setAlignment( AlignLeft|BreakAnywhere|WordBreak|AlignTop); +// lab->setSizePolicy( QSizePolicy( QSizePolicy::Ignored , QSizePolicy::Ignored,true) ); +// #endif + + +} + +void KOPrefsDialog::selectSoundFile() +{ + QString fileName = mDefaultAlarmFile->text(); + fileName = KFileDialog::getSaveFileName( mDefaultAlarmFile->text() , "Choose default alarm file", this ); + if ( fileName.length() > 0 ) + mDefaultAlarmFile->setText( fileName ); +} +void KOPrefsDialog::setupFontsTab() +{ + + QFrame *topFrame = addPage(i18n("Fonts"),0,0); + // DesktopIcon("fonts",KIcon::SizeMedium)); + + QGridLayout *topLayout = new QGridLayout(topFrame,7,3); + topLayout->setSpacing(1); + topLayout->setMargin(3); + KPrefsWidFont * tVFont; + int i = 0; + KPrefsWidFont *timeLabelsFont = + addWidFont(i18n("23"),i18n("DateNavigator:(nr)"), + &(KOPrefs::instance()->mDateNavigatorFont),topFrame); + topLayout->addWidget(timeLabelsFont->label(),i,0); + topLayout->addWidget(timeLabelsFont->preview(),i,1); + topLayout->addWidget(timeLabelsFont->button(),i,2); + ++i; + + + timeLabelsFont = + addWidFont(i18n("Mon 15"),i18n("Date Labels:"), + &(KOPrefs::instance()->mTimeLabelsFont),topFrame); + topLayout->addWidget(timeLabelsFont->label(),i,0); + topLayout->addWidget(timeLabelsFont->preview(),i,1); + topLayout->addWidget(timeLabelsFont->button(),i,2); + ++i; + + KPrefsWidFont *timeBarFont = + addWidFont(KGlobal::locale()->formatTime(QTime(12,34)),i18n("Time bar:"), + &(KOPrefs::instance()->mTimeBarFont),topFrame); + topLayout->addWidget(timeBarFont->label(),i,0); + topLayout->addWidget(timeBarFont->preview(),i,1); + topLayout->addWidget(timeBarFont->button(),i,2); + ++i; + + + KPrefsWidFont *marcusBainsFont = + addWidFont(KGlobal::locale()->formatTime(QTime(12,34,23)),i18n("M. Bains line:"), + &(KOPrefs::instance()->mMarcusBainsFont),topFrame); + topLayout->addWidget(marcusBainsFont->label(),i,0); + topLayout->addWidget(marcusBainsFont->preview(),i,1); + topLayout->addWidget(marcusBainsFont->button(),i,2); + ++i; + + tVFont = + addWidFont(i18n("Summary"),i18n("Event Viewer:"), + &(KOPrefs::instance()->mEventViewFont),topFrame); + topLayout->addWidget(tVFont->label(),i,0); + topLayout->addWidget(tVFont->preview(),i,1); + topLayout->addWidget(tVFont->button(),i,2); + ++i; + + + + tVFont = + addWidFont(i18n("Details"),i18n("EditorBox:"), + &(KOPrefs::instance()->mEditBoxFont),topFrame); + topLayout->addWidget(tVFont->label(),i,0); + topLayout->addWidget(tVFont->preview(),i,1); + topLayout->addWidget(tVFont->button(),i,2); + ++i; + + + + topLayout->setColStretch(1,1); + topLayout->setRowStretch(4,1); + + + i = 0; + topFrame = addPage(i18n("View Fonts"),0, + DesktopIcon("fonts",KIcon::SizeMedium)); + + topLayout = new QGridLayout(topFrame,7,3); + topLayout->setSpacing(1); + topLayout->setMargin(3); + + tVFont = + addWidFont(i18n("Configure KO"),i18n("What's Next View:"), + &(KOPrefs::instance()->mWhatsNextFont),topFrame); + topLayout->addWidget(tVFont->label(),i,0); + topLayout->addWidget(tVFont->preview(),i,1); + topLayout->addWidget(tVFont->button(),i,2); + ++i; + KPrefsWidFont *agendaViewFont = + addWidFont(i18n("Event text"),i18n("Agenda view:"), + &(KOPrefs::instance()->mAgendaViewFont),topFrame); + topLayout->addWidget(agendaViewFont->label(),i,0); + topLayout->addWidget(agendaViewFont->preview(),i,1); + topLayout->addWidget(agendaViewFont->button(),i,2); + ++i; + + + KPrefsWidFont *monthViewFont = + addWidFont(KGlobal::locale()->formatTime(QTime(12,34)) + " " + i18n("Event"), + i18n("Month view:"),&(KOPrefs::instance()->mMonthViewFont),topFrame); + topLayout->addWidget(monthViewFont->label(),i,0); + topLayout->addWidget(monthViewFont->preview(),i,1); + topLayout->addWidget(monthViewFont->button(),i,2); + ++i; + + + KPrefsWidFont *lVFont = + addWidFont(i18n("Event"),i18n("List View:"), + &(KOPrefs::instance()->mListViewFont),topFrame); + topLayout->addWidget(lVFont->label(),i,0); + topLayout->addWidget(lVFont->preview(),i,1); + topLayout->addWidget(lVFont->button(),i,2); + ++i; + + + tVFont = + addWidFont(i18n("ToDo"),i18n("ToDoView:"), + &(KOPrefs::instance()->mTodoViewFont),topFrame); + topLayout->addWidget(tVFont->label(),i,0); + topLayout->addWidget(tVFont->preview(),i,1); + topLayout->addWidget(tVFont->button(),i,2); + ++i; + + + tVFont = + addWidFont(i18n("Today"),i18n("JournalView:"), + &(KOPrefs::instance()->mJornalViewFont),topFrame); + topLayout->addWidget(tVFont->label(),i,0); + topLayout->addWidget(tVFont->preview(),i,1); + topLayout->addWidget(tVFont->button(),i,2); + ++i; + + + + + topLayout->setColStretch(1,1); + topLayout->setRowStretch(4,1); + + + + +} + +void KOPrefsDialog::setupColorsTab() +{ + QFrame *topFrame = addPage(i18n("Colors"),0,0); + // DesktopIcon("colorize",KIcon::SizeMedium)); + + QGridLayout *topLayout = new QGridLayout(topFrame,5,2); + // topLayout->setSpacing(spacingHint()); + // topLayout->setMargin(marginHint()); + + topLayout->setSpacing(2); + topLayout->setMargin(3); + + int ii = 1; + QGroupBox *categoryGroup ; + + categoryGroup = new QGroupBox(1,Vertical,i18n("Categories"), + topFrame); + topLayout->addMultiCellWidget(categoryGroup,0,0,0,1); + + mCategoryCombo = new QComboBox(categoryGroup); + mCategoryCombo->insertStringList(KOPrefs::instance()->mCustomCategories); + connect(mCategoryCombo,SIGNAL(activated(int)),SLOT(updateCategoryColor())); + + mCategoryButton = new KColorButton(categoryGroup); + connect(mCategoryButton,SIGNAL(changed(const QColor &)),SLOT(setCategoryColor())); + updateCategoryColor(); + + + // Holiday Color + + KPrefsWidColor *holidayColor = + addWidColor(i18n("Holiday color:"), + &(KOPrefs::instance()->mHolidayColor),topFrame); + topLayout->addWidget(holidayColor->label(),ii,0); + topLayout->addWidget(holidayColor->button(),ii++,1); + + // Highlight Color + KPrefsWidColor *highlightColor = + addWidColor(i18n("Highlight color:"), + &(KOPrefs::instance()->mHighlightColor),topFrame); + topLayout->addWidget(highlightColor->label(),ii,0); + topLayout->addWidget(highlightColor->button(),ii++,1); + + // Event color + KPrefsWidColor *eventColor = + addWidColor(i18n("Default event color:"), + &(KOPrefs::instance()->mEventColor),topFrame); + topLayout->addWidget(eventColor->label(),ii,0); + topLayout->addWidget(eventColor->button(),ii++,1); + + // agenda view background color + KPrefsWidColor *agendaBgColor = + addWidColor(i18n("Agenda view background color:"), + &(KOPrefs::instance()->mAgendaBgColor),topFrame); + topLayout->addWidget(agendaBgColor->label(),ii,0); + topLayout->addWidget(agendaBgColor->button(),ii++,1); + + // working hours color + KPrefsWidColor *workingHoursColor = + addWidColor(i18n("Working hours color:"), + &(KOPrefs::instance()->mWorkingHoursColor),topFrame); + topLayout->addWidget(workingHoursColor->label(),ii,0); + topLayout->addWidget(workingHoursColor->button(),ii++,1); + + KPrefsWidBool *sb = + addWidBool(i18n("Use colors for application:"), + &(KOPrefs::instance()->mUseAppColors),topFrame); + topLayout->addMultiCellWidget(sb->checkBox(), ii, ii, 0,1 ); + + ii++; + KPrefsWidColor * workingHoursColor1 = + addWidColor(i18n("Buttons, menus, etc.:"), + &(KOPrefs::instance()->mAppColor1),topFrame); + topLayout->addWidget(workingHoursColor1->label(),ii,0); + topLayout->addWidget(workingHoursColor1->button(),ii++,1); + + KPrefsWidColor * workingHoursColor2 = + addWidColor(i18n("Frames, labels, etc.:"), + &(KOPrefs::instance()->mAppColor2),topFrame); + topLayout->addWidget(workingHoursColor2->label(),ii,0); + topLayout->addWidget(workingHoursColor2->button(),ii++,1); + + + +} + +void KOPrefsDialog::setCategoryColor() +{ + mCategoryDict.replace(mCategoryCombo->currentText(), new QColor(mCategoryButton->color())); +} + +void KOPrefsDialog::updateCategoryColor() +{ + QString cat = mCategoryCombo->currentText(); + QColor *color = mCategoryDict.find(cat); + if (!color) { + color = KOPrefs::instance()->categoryColor(cat); + } + if (color) { + mCategoryButton->setColor(*color); + } +} + +void KOPrefsDialog::setupPrinterTab() +{ + mPrinterTab = addPage(i18n("Printing"),0, + DesktopIcon("fileprint",KIcon::SizeMedium)); + + QGridLayout *topLayout = new QGridLayout(mPrinterTab,5,2); + topLayout->setSpacing(spacingHint()); + topLayout->setMargin(marginHint()); + + topLayout->setRowStretch(4,1); +} + +void KOPrefsDialog::setupGroupSchedulingTab() +{ +#if 0 + QFrame *topFrame = addPage(i18n("Group Scheduling"),0, + DesktopIcon("personal",KIcon::SizeMedium)); + + QGridLayout *topLayout = new QGridLayout(topFrame,6,2); + topLayout->setSpacing(spacingHint()); + topLayout->setMargin(marginHint()); + +#if 0 + KPrefsWidRadios *schedulerGroup = + addWidRadios(i18n("Scheduler Mail Client"),&(KOPrefs::instance()->mIMIPScheduler), + topFrame); + schedulerGroup->addRadio("Dummy"); // Only for debugging + schedulerGroup->addRadio(i18n("Mail client")); + + topLayout->addMultiCellWidget(schedulerGroup->groupBox(),0,0,0,1); +#endif + + KPrefsWidRadios *sendGroup = + addWidRadios(i18n("Scheduler Mails Should Be"),&(KOPrefs::instance()->mIMIPSend), + topFrame); + sendGroup->addRadio(i18n("Send to outbox")); + sendGroup->addRadio(i18n("Send directly")); + + topLayout->addMultiCellWidget(sendGroup->groupBox(),1,1,0,1); + + topLayout->addMultiCellWidget(new QLabel(i18n("Additional email addresses:"),topFrame),2,2,0,1); + mAMails = new QListView(topFrame); + mAMails->addColumn(i18n("Email"),300); + topLayout->addMultiCellWidget(mAMails,3,3,0,1); + + topLayout->addWidget(new QLabel(i18n("Additional email address:"),topFrame),4,0); + aEmailsEdit = new QLineEdit(topFrame); + aEmailsEdit->setEnabled(false); + topLayout->addWidget(aEmailsEdit,4,1); + + QPushButton *add = new QPushButton(i18n("New"),topFrame,"new"); + topLayout->addWidget(add,5,0); + QPushButton *del = new QPushButton(i18n("Remove"),topFrame,"remove"); + topLayout->addWidget(del,5,1); + + //topLayout->setRowStretch(2,1); + connect(add, SIGNAL( clicked() ), this, SLOT(addItem()) ); + connect(del, SIGNAL( clicked() ), this, SLOT(removeItem()) ); + connect(aEmailsEdit,SIGNAL( textChanged(const QString&) ), this,SLOT(updateItem())); + connect(mAMails,SIGNAL(selectionChanged(QListViewItem *)),SLOT(updateInput())); +#endif +} + +void KOPrefsDialog::setupGroupAutomationTab() +{ + return; + QFrame *topFrame = addPage(i18n("Group Automation"),0, + DesktopIcon("personal",KIcon::SizeMedium)); + + QGridLayout *topLayout = new QGridLayout(topFrame,5,1); + topLayout->setSpacing(spacingHint()); + topLayout->setMargin(marginHint()); + + KPrefsWidRadios *autoRefreshGroup = + addWidRadios(i18n("Auto Send Refresh"), + &(KOPrefs::instance()->mIMIPAutoRefresh),topFrame); + autoRefreshGroup->addRadio(i18n("Never")); + autoRefreshGroup->addRadio(i18n("If attendee is in addressbook")); + //autoRefreshGroup->addRadio(i18n("selected emails")); + topLayout->addMultiCellWidget(autoRefreshGroup->groupBox(),0,0,0,0); + + KPrefsWidRadios *autoInsertGroup = + addWidRadios(i18n("Auto Insert IMIP Replies"), + &(KOPrefs::instance()->mIMIPAutoInsertReply),topFrame); + autoInsertGroup->addRadio(i18n("Never")); + autoInsertGroup->addRadio(i18n("If attendee is in addressbook")); + //autoInsertGroup->addRadio(i18n("selected emails")); + topLayout->addMultiCellWidget(autoInsertGroup->groupBox(),1,1,0,0); + + KPrefsWidRadios *autoRequestGroup = + addWidRadios(i18n("Auto Insert IMIP Requests"), + &(KOPrefs::instance()->mIMIPAutoInsertRequest),topFrame); + autoRequestGroup->addRadio(i18n("Never")); + autoRequestGroup->addRadio(i18n("If organizer is in addressbook")); + //autoInsertGroup->addRadio(i18n("selected emails")); + topLayout->addMultiCellWidget(autoRequestGroup->groupBox(),2,2,0,0); + + KPrefsWidRadios *autoFreeBusyGroup = + addWidRadios(i18n("Auto Send FreeBusy Information"), + &(KOPrefs::instance()->mIMIPAutoFreeBusy),topFrame); + autoFreeBusyGroup->addRadio(i18n("Never")); + autoFreeBusyGroup->addRadio(i18n("If requested from an email in addressbook")); + //autoFreeBusyGroup->addRadio(i18n("selected emails")); + topLayout->addMultiCellWidget(autoFreeBusyGroup->groupBox(),3,3,0,0); + + KPrefsWidRadios *autoFreeBusyReplyGroup = + addWidRadios(i18n("Auto Save FreeBusy Replies"), + &(KOPrefs::instance()->mIMIPAutoFreeBusyReply),topFrame); + autoFreeBusyReplyGroup->addRadio(i18n("Never")); + autoFreeBusyReplyGroup->addRadio(i18n("If attendee is in addressbook")); + //autoFreeBusyGroup->addRadio(i18n("selected emails")); + topLayout->addMultiCellWidget(autoFreeBusyReplyGroup->groupBox(),4,4,0,0); +} + +void KOPrefsDialog::showPrinterTab() +{ + showPage(pageIndex(mPrinterTab)); +} + + +void KOPrefsDialog::setCombo(QComboBox *combo, const QString & text, + const QStringList *tags) +{ + if (tags) { + int i = tags->findIndex(text); + if (i > 0) combo->setCurrentItem(i); + } else { + for(int i=0;i<combo->count();++i) { + if (combo->text(i) == text) { + combo->setCurrentItem(i); + break; + } + } + } +} + +void KOPrefsDialog::usrReadConfig() +{ + mNameEdit->setText(KOPrefs::instance()->fullName()); + mEmailEdit->setText(KOPrefs::instance()->email()); + + mAutoSaveIntervalSpin->setValue(KOPrefs::instance()->mAutoSaveInterval); + QDate current ( 2001, 1,1); + mStartDateSavingEdit->setDate(current.addDays(KOPrefs::instance()->mDaylightsavingStart-1)); + mEndDateSavingEdit->setDate(current.addDays(KOPrefs::instance()->mDaylightsavingEnd-1)); + setCombo(mTimeZoneCombo,i18n(KOPrefs::instance()->mTimeZoneId)); + //mTimezoneOffsetSpin->setValue( KOPrefs::instance()->mTimeZoneOffset); + mStartTimeSpin->setValue(KOPrefs::instance()->mStartTime); + mDefaultDurationSpin->setValue(KOPrefs::instance()->mDefaultDuration); + mAlarmTimeCombo->setCurrentItem(KOPrefs::instance()->mAlarmTime); + // if (KOPrefs::instance()->mAllDaySize > 47 ) + // KOPrefs::instance()->mAllDaySize = KOPrefs::instance()->mAllDaySize/2; + //mHourSizeSlider->setValue(KOPrefs::instance()->mAllDaySize); + + mNextXDaysSpin->setValue(KOPrefs::instance()->mNextXDays); + mWhatsNextSpin->setValue(KOPrefs::instance()->mWhatsNextDays); + mPrioSpin->setValue(KOPrefs::instance()->mWhatsNextPrios); + // mAMails->clear(); + // for ( QStringList::Iterator it = KOPrefs::instance()->mAdditionalMails.begin(); +// it != KOPrefs::instance()->mAdditionalMails.end(); ++it ) { +// QListViewItem *item = new QListViewItem(mAMails); +// item->setText(0,*it); +// mAMails->insertItem(item); +// } + + // mRemoteIPEdit->setText(KOPrefs::instance()->mRemoteIP); + //mRemoteUser->setText(KOPrefs::instance()->mRemoteUser); + //mRemotePassWd->setText(KOPrefs::instance()->mRemotePassWd); + //mRemoteFile->setText(KOPrefs::instance()->mRemoteFile); + + //that soundmLocalTempFile->setText(KOPrefs::instance()->mLocalTempFile); + mDefaultAlarmFile->setText(KOPrefs::instance()->mDefaultAlarmFile); + QString dummy = KOPrefs::instance()->mUserDateFormatLong; + mUserDateFormatLong->setText(dummy.replace( QRegExp("K"), QString(",") )); + dummy = KOPrefs::instance()->mUserDateFormatShort; + mUserDateFormatShort->setText(dummy.replace( QRegExp("K"), QString(",") )); + updateCategories(); + mAlarmPlayBeeps->setValue(KOPrefs::instance()->mAlarmPlayBeeps ); + mAlarmSuspendTime->setValue(KOPrefs::instance()->mAlarmSuspendTime ); + mAlarmSuspendCount->setValue(KOPrefs::instance()->mAlarmSuspendCount ); + mAlarmBeepInterval->setValue(KOPrefs::instance()->mAlarmBeepInterval ); +} + + +void KOPrefsDialog::usrWriteConfig() +{ + + // KOPrefs::instance()->mRemoteIP = mRemoteIPEdit->text(); + //KOPrefs::instance()->mRemoteUser = mRemoteUser->text(); + //KOPrefs::instance()->mRemotePassWd = mRemotePassWd->text(); + //KOPrefs::instance()->mRemoteFile= mRemoteFile->text(); + //KOPrefs::instance()->mLocalTempFile =mLocalTempFile->text(); + KOPrefs::instance()->mDefaultAlarmFile =mDefaultAlarmFile->text(); + + KOPrefs::instance()->mUserDateFormatShort = mUserDateFormatShort->text().replace( QRegExp(","), QString("K") ); + KOPrefs::instance()->mUserDateFormatLong = mUserDateFormatLong->text().replace( QRegExp(","), QString("K") ); + KOPrefs::instance()->setFullName(mNameEdit->text()); + KOPrefs::instance()->setEmail(mEmailEdit->text()); + + KOPrefs::instance()->mAutoSaveInterval = mAutoSaveIntervalSpin->value(); + + KOPrefs::instance()->mTimeZoneId = mTimeZoneCombo->currentText(); + QDate date; + date = mStartDateSavingEdit->date(); + int sub = 0; + if ( QDate::leapYear( date.year() ) && date.dayOfYear() > 59 ) + sub = 1; + KOPrefs::instance()->mDaylightsavingStart = date.dayOfYear()-sub; + date = mEndDateSavingEdit->date(); + if ( QDate::leapYear( date.year() ) && date.dayOfYear() > 59 ) + sub = 1; + else + sub = 0; + KOPrefs::instance()->mDaylightsavingEnd = date.dayOfYear()-sub; + // KOPrefs::instance()->mTimeZoneOffset = mTimezoneOffsetSpin->value(); + + KOPrefs::instance()->mStartTime = mStartTimeSpin->value(); + KOPrefs::instance()->mDefaultDuration = mDefaultDurationSpin->value(); + KOPrefs::instance()->mAlarmTime = mAlarmTimeCombo->currentItem(); + + //KOPrefs::instance()->mAllDaySize = mHourSizeSlider->value(); + + QDictIterator<QColor> it(mCategoryDict); + while (it.current()) { + KOPrefs::instance()->setCategoryColor(it.currentKey(),*it.current()); + ++it; + } + + KOPrefs::instance()->mNextXDays = mNextXDaysSpin->value(); + KOPrefs::instance()->mWhatsNextDays = mWhatsNextSpin->value(); + KOPrefs::instance()->mWhatsNextPrios = mPrioSpin->value(); + + KOPrefs::instance()->mAdditionalMails.clear(); + // QListViewItem *item; + // item = mAMails->firstChild(); + // while (item) + // { + // KOPrefs::instance()->mAdditionalMails.append( item->text(0) ); + // item = item->nextSibling(); + // } + KOPrefs::instance()->mAlarmPlayBeeps = mAlarmPlayBeeps->value(); + KOPrefs::instance()->mAlarmSuspendTime = mAlarmSuspendTime->value() ; + KOPrefs::instance()->mAlarmSuspendCount= mAlarmSuspendCount->value() ; + KOPrefs::instance()->mAlarmBeepInterval= mAlarmBeepInterval->value() ; + +} + +void KOPrefsDialog::updateCategories() +{ + mCategoryCombo->clear(); + mCategoryDict.clear(); + mCategoryCombo->insertStringList(KOPrefs::instance()->mCustomCategories); + updateCategoryColor(); +} + +void KOPrefsDialog::warningGroupScheduling() +{ + warningExperimental(mEnableGroupScheduling->checkBox()->isChecked()); +} + +void KOPrefsDialog::warningProjectView() +{ + warningExperimental(mEnableProjectView->checkBox()->isChecked()); +} + +void KOPrefsDialog::warningExperimental(bool on) +{ + if (on) { + KMessageBox::information(this,i18n("This is an experimental feature. " + "It may not work, it may do nothing useful and it may cause data loss. " + "Use with care.\n" + "You have to restart KOrganizer for this setting to take effect.")); + } else { + KMessageBox::information(this, + i18n("You have to restart KOrganizer for this setting to take effect.")); + } +} + +void KOPrefsDialog::toggleEmailSettings(bool on) +{ + if (on) { + mEmailEdit->setEnabled(false); + mNameEdit->setEnabled(false); + mEmailLabel->setEnabled(false); + mNameLabel->setEnabled(false); + + KEMailSettings settings; + mNameEdit->setText(settings.getSetting(KEMailSettings::RealName)); + mEmailEdit->setText(settings.getSetting(KEMailSettings::EmailAddress)); + } else { + mEmailEdit->setEnabled(true); + mNameEdit->setEnabled(true); + mEmailLabel->setEnabled(true); + mNameLabel->setEnabled(true); + } +} + +void KOPrefsDialog::addItem() +{ + // aEmailsEdit->setEnabled(true); +// QListViewItem *item = new QListViewItem(mAMails); +// mAMails->insertItem(item); +// mAMails->setSelected(item,true); +// aEmailsEdit->setText(i18n("(EmptyEmail)")); +} + +void KOPrefsDialog::removeItem() +{ +// QListViewItem *item; +// item = mAMails->selectedItem(); +// if (!item) return; +// mAMails->takeItem(item); +// item = mAMails->selectedItem(); +// if (!item) { +// aEmailsEdit->setText(""); +// aEmailsEdit->setEnabled(false); +// } +// if (mAMails->childCount() == 0) { +// aEmailsEdit->setEnabled(false); +// } +} + +void KOPrefsDialog::updateItem() +{ + // QListViewItem *item; +// item = mAMails->selectedItem(); +// if (!item) return; +// item->setText(0,aEmailsEdit->text()); +} + +void KOPrefsDialog::updateInput() +{ +// QListViewItem *item; +// item = mAMails->selectedItem(); +// if (!item) return; +// aEmailsEdit->setEnabled(true); +// aEmailsEdit->setText(item->text(0)); +} +void KOPrefsDialog::updateTimezoneOffset( int index ) +{ + /* + qDebug("updateTimezoneOffset %d ", index); + if ( index < 24 ) { + mTimezoneOffsetSpin->setEnabled ( false ); + mTimezoneOffsetSpin->setValue( ( index-11 ) * 60 ); + + + } else { + if ( index == 24 ) { + mTimezoneOffsetSpin->setEnabled ( true ); + mTimezoneOffsetSpin->setValue( KOPrefs::instance()->mTimeZoneOffset); + + } else { + mTimezoneOffsetSpin->setEnabled ( false ); + mTimezoneOffsetSpin->setValue( 0 ); + } + } + */ +} + +void KOPrefsDialog::setupTimeZoneTab() +{ + QFrame *topFrame = addPage(i18n("Time Zone"),0,0); + // DesktopIcon("clock",KIcon::SizeMedium)); + + QGridLayout *topLayout = new QGridLayout(topFrame,5,2); + topLayout->setSpacing(spacingHint()); + topLayout->setMargin(marginHint()); + + QHBox *timeZoneBox = new QHBox( topFrame ); + topLayout->addMultiCellWidget( timeZoneBox, 0, 0, 0, 1 ); + + new QLabel( i18n("Timezone:"), timeZoneBox ); + mTimeZoneCombo = new QComboBox( timeZoneBox ); + if ( QApplication::desktop()->width() < 300 ) { + mTimeZoneCombo->setMaximumWidth(150); + } + + QStringList list; + list = KGlobal::locale()->timeZoneList(); + mTimeZoneCombo->insertStringList(list); + + // find the currently set time zone and select it + QString sCurrentlySet = KOPrefs::instance()->mTimeZoneId; + int nCurrentlySet = 11; + for (int i = 0; i < mTimeZoneCombo->count(); i++) + { + if (mTimeZoneCombo->text(i) == sCurrentlySet) + { + nCurrentlySet = i; + break; + } + } + mTimeZoneCombo->setCurrentItem(nCurrentlySet); + int iii = 1; + KPrefsWidBool *sb = + addWidBool(i18n("Timezone has daylight saving"), + &(KOPrefs::instance()->mUseDaylightsaving),topFrame); + topLayout->addMultiCellWidget(sb->checkBox(), iii,iii,0,1); + ++iii; + QLabel* lab = new QLabel( i18n("Actual start/end is the\nsunday before this date."), topFrame ); + topLayout->addMultiCellWidget(lab, iii,iii,0,1); + ++iii; + lab = new QLabel( i18n("The year in the date is ignored."), topFrame ); + topLayout->addMultiCellWidget(lab, iii,iii,0,1); + ++iii; + lab = new QLabel( i18n("Daylight start:"), topFrame ); + topLayout->addWidget(lab, iii,0); + mStartDateSavingEdit = new KDateEdit(topFrame); + topLayout->addWidget(mStartDateSavingEdit, iii,1); + ++iii; + + lab = new QLabel( i18n("Daylight end:"), topFrame ); + topLayout->addWidget(lab, iii,0); + mEndDateSavingEdit = new KDateEdit(topFrame); + topLayout->addWidget(mEndDateSavingEdit, iii,1); + ++iii; + QDate current ( 2001, 1,1); + mStartDateSavingEdit->setDate(current.addDays(KOPrefs::instance()->mDaylightsavingStart-1)); + mEndDateSavingEdit->setDate(current.addDays(KOPrefs::instance()->mDaylightsavingEnd-1)); + + +} + diff --git a/korganizer/koprefsdialog.h b/korganizer/koprefsdialog.h new file mode 100644 index 0000000..fd651d0 --- a/dev/null +++ b/korganizer/koprefsdialog.h @@ -0,0 +1,161 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + 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 _KOPREFSDIALOG_H +#define _KOPREFSDIALOG_H + +#include <qframe.h> +#include <qdict.h> +#include <qcolor.h> +#include <qlistview.h> + +#include <kdialogbase.h> + +#include <libkdepim/kprefsdialog.h> +#include <libkdepim/kdateedit.h> + +class KColorButton; +class QSpinBox; +class QSlider; +class KURLRequester; +class QComboBox; +class QLineEdit; +class QStringList; + +/** Dialog to change the korganizer configuration. + */ +class KOPrefsDialog : public KPrefsDialog +{ + Q_OBJECT + public: + /** Initialize dialog and pages */ + KOPrefsDialog(QWidget *parent=0,char *name=0,bool modal=false); + ~KOPrefsDialog(); + + public slots: + void showPrinterTab(); + + /** Update controls for categories */ + void updateCategories(); + void showSyncPage(); + protected slots: + void selectSoundFile(); + void setCategoryColor(); + void updateCategoryColor(); + void updateTimezoneOffset( int ); + + + void warningExperimental(bool on); + void warningGroupScheduling(); + void warningProjectView(); + + void toggleEmailSettings(bool); + + //additional emails + void addItem(); + void removeItem(); + void updateItem(); + void updateInput(); + + protected: + void usrReadConfig(); + void usrWriteConfig(); + + void setupMainTab(); + void setupTimeTab(); + void setupTimeZoneTab(); + void setupLocaleTab(); + void setupLocaleDateTab(); + void setupFontsTab(); + void setupColorsTab(); + void setupViewsTab(); + void setupDisplayTab(); + void setupPrinterTab(); + void setupGroupSchedulingTab(); + void setupGroupAutomationTab(); + void setupSyncTab(); + void setupSyncAlgTab(); + + void setCombo(QComboBox *combo,const QString & text, const QStringList *tags = 0); + + + private: + KPrefsWidBool *mEnableGroupScheduling; + KPrefsWidBool *mEnableProjectView; + + QFrame *mPrinterTab; + + QLineEdit *nameEdit; + QLineEdit *emailEdit; + + QComboBox *timeCombo; + QComboBox *tzCombo; + + // widgets holding preferences data + QLineEdit *mNameEdit; + QLineEdit *mEmailEdit; + QLabel *mNameLabel; + QLabel *mEmailLabel; + QLineEdit *mAdditionalEdit; + QSpinBox *mAutoSaveIntervalSpin; + QSpinBox *mPrioSpin; + // QListView *mAMails; + QLineEdit *aEmailsEdit; + + QComboBox *mTimeZoneCombo; + QStringList tzonenames; + QSpinBox *mStartTimeSpin; + QSpinBox *mDefaultDurationSpin; + QComboBox *mAlarmTimeCombo; + + QComboBox *mCategoryCombo; + KColorButton *mCategoryButton; + QDict<QColor> mCategoryDict; + + QSlider *mHourSizeSlider; + + QSpinBox *mNextXDaysSpin; + QSpinBox *mWhatsNextSpin; + + QLineEdit * mRemoteIPEdit; + QLineEdit * mRemoteUser; + QLineEdit * mRemotePassWd; + QLineEdit * mRemoteFile; + QLineEdit * mLocalTempFile; + QWidget* mSetupSyncAlgTab; + QLineEdit * mUserDateFormatLong; + QLineEdit * mUserDateFormatShort; + + QSpinBox *mTimezoneOffsetSpin; + QSpinBox *mDaylightsavingStart; + QSpinBox *mDaylightsavingEnd; + KDateEdit* mStartDateSavingEdit; + KDateEdit* mEndDateSavingEdit; + QSpinBox * mAlarmPlayBeeps; + QSpinBox * mAlarmSuspendTime; + QSpinBox * mAlarmSuspendCount; + QSpinBox * mAlarmBeepInterval; + + QLineEdit * mDefaultAlarmFile; +}; + +#endif diff --git a/korganizer/koprefsdialog.moc b/korganizer/koprefsdialog.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/koprefsdialog.moc diff --git a/korganizer/korganizer.desktop b/korganizer/korganizer.desktop new file mode 100644 index 0000000..23672b2 --- a/dev/null +++ b/korganizer/korganizer.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Comment = KO/PI +Display = 640x480/144dpi,480x640/144dpi +Exec = kopi +Icon = kdepim/korganizer/korganizer +Name = KO/Pi +Type = Application +CanFastload = 1 diff --git a/korganizer/korganizer.pro b/korganizer/korganizer.pro new file mode 100644 index 0000000..fe2250e --- a/dev/null +++ b/korganizer/korganizer.pro @@ -0,0 +1,172 @@ +TEMPLATE = app +CONFIG = qt warn_on +TARGET = kopi +OBJECTS_DIR = _obj/ +MOC_DIR = _moc +DESTDIR= ../bin + +include( ../variables.pri ) + +INCLUDEPATH += ../microkde ../ interfaces ../microkde/kdecore ../microkde/kdeui ../microkde/kio/kfile +#../qtcompat +DEFINES += KORG_NODND KORG_NOPLUGINS KORG_NOARCHIVE KORG_NOMAIL +DEFINES += KORG_NODCOP KORG_NOKALARMD KORG_NORESOURCEVIEW KORG_NOSPLITTER +#KORG_NOPRINTER KORG_NOKABC +DEFINES += KORG_NOLVALTERNATION +DEFINES += DESKTOP_VERSION +unix : { +LIBS += ../bin/libmicrokdepim.so +LIBS += ../bin/libmicrokcal.so +LIBS += ../bin/libmicrokde.so +LIBS += ../bin/libmicrokabc.so +LIBS += -lldap +OBJECTS_DIR = obj/unix +MOC_DIR = moc/unix +} +win32: { +DEFINES += _WIN32_ +LIBS += ../bin/microkdepim.lib +LIBS += ../bin/microkcal.lib +LIBS += ../bin/microkde.lib +LIBS += ../bin/microkabc.lib +LIBS += ../libical/lib/ical.lib +LIBS += ../libical/lib/icalss.lib +QMAKE_LINK += /NODEFAULTLIB:LIBC +OBJECTS_DIR = obj/win +MOC_DIR = moc/win +} + + +INTERFACES = kofilterview_base.ui +# filteredit_base.ui + +# kdateedit.h \ + +HEADERS = \ + filteredit_base.h \ + alarmclient.h \ + calendarview.h \ + customlistviewitem.h \ + datenavigator.h \ + docprefs.h \ + filtereditdialog.h \ + incomingdialog.h \ + incomingdialog_base.h \ + interfaces/korganizer/baseview.h \ + interfaces/korganizer/calendarviewbase.h \ + journalentry.h \ + kdatenavigator.h \ + koagenda.h \ + koagendaitem.h \ + koagendaview.h \ + kocounterdialog.h \ + kodaymatrix.h \ + kodialogmanager.h \ + koeditordetails.h \ + koeditorgeneral.h \ + koeditorgeneralevent.h \ + koeditorgeneraltodo.h \ + koeditorrecurrence.h \ + koeventeditor.h \ + koeventpopupmenu.h \ + koeventview.h \ + koeventviewer.h \ + koeventviewerdialog.h \ + kofilterview.h \ + koglobals.h \ + koincidenceeditor.h \ + kojournalview.h \ + kolistview.h \ + kolocationbox.h \ + komonthview.h \ + koprefs.h \ + koprefsdialog.h \ + kosyncprefsdialog.h \ + kotimespanview.h \ + kotodoeditor.h \ + kotodoview.h \ + kotodoviewitem.h \ + koviewmanager.h \ + kowhatsnextview.h \ + ktimeedit.h \ + lineview.h \ + mainwindow.h \ + navigatorbar.h \ + outgoingdialog.h \ + outgoingdialog_base.h \ + publishdialog.h \ + publishdialog_base.h \ + savetemplatedialog.h \ + searchdialog.h \ + simplealarmclient.h \ + statusdialog.h \ + timeline.h \ + timespanview.h \ + version.h \ + ../kalarmd/alarmdialog.h + +SOURCES = \ +filteredit_base.cpp \ + calendarview.cpp \ + datenavigator.cpp \ + docprefs.cpp \ + filtereditdialog.cpp \ + incomingdialog.cpp \ + incomingdialog_base.cpp \ + journalentry.cpp \ + kdatenavigator.cpp \ + koagenda.cpp \ + koagendaitem.cpp \ + koagendaview.cpp \ + kocounterdialog.cpp \ + kodaymatrix.cpp \ + kodialogmanager.cpp \ + koeditordetails.cpp \ + koeditorgeneral.cpp \ + koeditorgeneralevent.cpp \ + koeditorgeneraltodo.cpp \ + koeditorrecurrence.cpp \ + koeventeditor.cpp \ + koeventpopupmenu.cpp \ + koeventview.cpp \ + koeventviewer.cpp \ + koeventviewerdialog.cpp \ + kofilterview.cpp \ + koglobals.cpp \ + koincidenceeditor.cpp \ + kojournalview.cpp \ + kolistview.cpp \ + kolocationbox.cpp \ + komonthview.cpp \ + koprefs.cpp \ + koprefsdialog.cpp \ + kosyncprefsdialog.cpp \ + kotimespanview.cpp \ + kotodoeditor.cpp \ + kotodoview.cpp \ + kotodoviewitem.cpp \ + koviewmanager.cpp \ + kowhatsnextview.cpp \ + ktimeedit.cpp \ + lineview.cpp \ + main.cpp \ + mainwindow.cpp \ + navigatorbar.cpp \ + outgoingdialog.cpp \ + outgoingdialog_base.cpp \ + publishdialog.cpp \ + publishdialog_base.cpp \ + savetemplatedialog.cpp \ + searchdialog.cpp \ + simplealarmclient.cpp \ + statusdialog.cpp \ + timeline.cpp \ + timespanview.cpp \ + ../kalarmd/alarmdialog.cpp + +HEADERS += calprintbase.h calprinter.h calprintplugins.h cellitem.h +INTERFACES += calprintdayconfig_base.ui \ + calprintmonthconfig_base.ui \ + calprinttodoconfig_base.ui \ + calprintweekconfig_base.ui +SOURCES += calprintbase.cpp calprinter.cpp calprintplugins.cpp cellitem.cpp diff --git a/korganizer/korganizer.pro.back b/korganizer/korganizer.pro.back new file mode 100644 index 0000000..8d23d66 --- a/dev/null +++ b/korganizer/korganizer.pro.back @@ -0,0 +1,133 @@ +TEMPLATE = app +CONFIG = qt warn_on release +TARGET = korganizer +OBJECTS_DIR = obj/$(PLATFORM) +MOC_DIR = moc +DESTDIR=$(QPEDIR)/bin +INCLUDEPATH += ../microkde ../qtcompat ../ interfaces +DEFINES += KORG_NODND KORG_NOPLUGINS KORG_NOKABC KORG_NOARCHIVE KORG_NOMAIL +DEFINES += KORG_NOPRINTER KORG_NOSPLITTER KORG_NODCOP KORG_NOKALARMD +DEFINES += KORG_NOLVALTERNATION +LIBS += -lkdepim +LIBS += -lkcal +LIBS += -lmicrokde +LIBS += -lqtcompat +LIBS += -lqpe +INTERFACES = \ + filteredit_base.ui \ + kofilterview_base.ui \ + +HEADERS = \ + alarmclient.h \ + calendarview.h \ + customlistviewitem.h \ + datenavigator.h \ + docprefs.h \ + filtereditdialog.h \ + incomingdialog.h \ + incomingdialog_base.h \ + interfaces/korganizer/baseview.h \ + journalentry.h \ + kdateedit.h \ + kdatenavigator.h \ + koagenda.h \ + koagendaitem.h \ + koagendaview.h \ + kocounterdialog.h \ + kodaymatrix.h \ + kodialogmanager.h \ + koeditordetails.h \ + koeditorgeneral.h \ + koeditorgeneralevent.h \ + koeditorgeneraltodo.h \ + koeditorrecurrence.h \ + koeventeditor.h \ + koeventpopupmenu.h \ + koeventview.h \ + koeventviewer.h \ + koeventviewerdialog.h \ + kofilterview.h \ + koglobals.h \ + koincidenceeditor.h \ + kojournalview.h \ + kolistview.h \ + komonthview.h \ + koprefs.h \ + koprefsdialog.h \ + kotimespanview.h \ + kotodoeditor.h \ + kotodoview.h \ + kotodoviewitem.h \ + koviewmanager.h \ + kowhatsnextview.h \ + ktimeedit.h \ + lineview.h \ + mainwindow.h \ + navigatorbar.h \ + outgoingdialog.h \ + outgoingdialog_base.h \ + publishdialog.h \ + publishdialog_base.h \ + savetemplatedialog.h \ + searchdialog.h \ + simplealarmclient.h \ + statusdialog.h \ + timeline.h \ + timespanview.h \ + version.h \ + +SOURCES = \ + calendarview.cpp \ + datenavigator.cpp \ + docprefs.cpp \ + filtereditdialog.cpp \ + incomingdialog.cpp \ + incomingdialog_base.cpp \ + journalentry.cpp \ + kdatenavigator.cpp \ + koagenda.cpp \ + koagendaitem.cpp \ + koagendaview.cpp \ + kocounterdialog.cpp \ + kodaymatrix.cpp \ + kodialogmanager.cpp \ + koeditordetails.cpp \ + koeditorgeneral.cpp \ + koeditorgeneralevent.cpp \ + koeditorgeneraltodo.cpp \ + koeditorrecurrence.cpp \ + koeventeditor.cpp \ + koeventpopupmenu.cpp \ + koeventview.cpp \ + koeventviewer.cpp \ + koeventviewerdialog.cpp \ + kofilterview.cpp \ + koglobals.cpp \ + koincidenceeditor.cpp \ + kojournalview.cpp \ + kolistview.cpp \ + komonthview.cpp \ + koprefs.cpp \ + koprefsdialog.cpp \ + kotimespanview.cpp \ + kotodoeditor.cpp \ + kotodoview.cpp \ + kotodoviewitem.cpp \ + koviewmanager.cpp \ + kowhatsnextview.cpp \ + ktimeedit.cpp \ + lineview.cpp \ + main.cpp \ + mainwindow.cpp \ + navigatorbar.cpp \ + outgoingdialog.cpp \ + outgoingdialog_base.cpp \ + publishdialog.cpp \ + publishdialog_base.cpp \ + savetemplatedialog.cpp \ + searchdialog.cpp \ + simplealarmclient.cpp \ + statusdialog.cpp \ + timeline.cpp \ + timespanview.cpp \ + diff --git a/korganizer/korganizerE.pro b/korganizer/korganizerE.pro new file mode 100644 index 0000000..c379fac --- a/dev/null +++ b/korganizer/korganizerE.pro @@ -0,0 +1,151 @@ +TEMPLATE = app +CONFIG += qt warn_on +TARGET = kopi +OBJECTS_DIR = obj/$(PLATFORM) +MOC_DIR = moc/$(PLATFORM) +DESTDIR=$(QPEDIR)/bin + +INCLUDEPATH += ../microkde ../microkde/kdecore ../microkde/kio/kfile ../microkde/kdeui ../qtcompat ../ interfaces ../kabc $(QPEDIR)/include +#../libkabcwrap +DEFINES += KORG_NODND KORG_NOPLUGINS KORG_NOARCHIVE KORG_NOMAIL +DEFINES += KORG_NOPRINTER KORG_NODCOP KORG_NOKALARMD KORG_NORESOURCEVIEW KORG_NOSPLITTER +DEFINES += KORG_NOLVALTERNATION +#KORG_NOKABC +LIBS += -lmicrokdepim +LIBS += -lmicrokcal +LIBS += -lmicrokde +LIBS += -lmicroqtcompat +LIBS += -lmicrokabc +#LIBS += -lmicrokabcwrap +LIBS += -lqpe +LIBS += -ljpeg +LIBS += $(QTOPIALIB) + + +INTERFACES = kofilterview_base.ui +#filteredit_base.ui + +HEADERS = \ + wordsgerman.h \ + filteredit_base.h \ + alarmclient.h \ + calendarview.h \ + customlistviewitem.h \ + datenavigator.h \ + docprefs.h \ + filtereditdialog.h \ + incomingdialog.h \ + incomingdialog_base.h \ + interfaces/korganizer/baseview.h \ + interfaces/korganizer/calendarviewbase.h \ + journalentry.h \ + kdateedit.h \ + kdatenavigator.h \ + koagenda.h \ + koagendaitem.h \ + koagendaview.h \ + kocounterdialog.h \ + kodaymatrix.h \ + kodialogmanager.h \ + koeditordetails.h \ + koeditorgeneral.h \ + koeditorgeneralevent.h \ + koeditorgeneraltodo.h \ + koeditorrecurrence.h \ + koeventeditor.h \ + koeventpopupmenu.h \ + koeventview.h \ + koeventviewer.h \ + koeventviewerdialog.h \ + kofilterview.h \ + koglobals.h \ + koincidenceeditor.h \ + kojournalview.h \ + kolistview.h \ + kolocationbox.h \ + komonthview.h \ + koprefs.h \ + koprefsdialog.h \ + kosyncprefsdialog.h \ + kotimespanview.h \ + kotodoeditor.h \ + kotodoview.h \ + kotodoviewitem.h \ + koviewmanager.h \ + kowhatsnextview.h \ + ktimeedit.h \ + lineview.h \ + mainwindow.h \ + navigatorbar.h \ + outgoingdialog.h \ + outgoingdialog_base.h \ + publishdialog.h \ + publishdialog_base.h \ + savetemplatedialog.h \ + searchdialog.h \ + simplealarmclient.h \ + statusdialog.h \ + timeline.h \ + timespanview.h \ + version.h \ + ../kalarmd/alarmdialog.h + +SOURCES = \ + filteredit_base.cpp \ + calendarview.cpp \ + datenavigator.cpp \ + docprefs.cpp \ + filtereditdialog.cpp \ + incomingdialog.cpp \ + incomingdialog_base.cpp \ + journalentry.cpp \ + kdatenavigator.cpp \ + koagenda.cpp \ + koagendaitem.cpp \ + koagendaview.cpp \ + kocounterdialog.cpp \ + kodaymatrix.cpp \ + kodialogmanager.cpp \ + koeditordetails.cpp \ + koeditorgeneral.cpp \ + koeditorgeneralevent.cpp \ + koeditorgeneraltodo.cpp \ + koeditorrecurrence.cpp \ + koeventeditor.cpp \ + koeventpopupmenu.cpp \ + koeventview.cpp \ + koeventviewer.cpp \ + koeventviewerdialog.cpp \ + kofilterview.cpp \ + koglobals.cpp \ + koincidenceeditor.cpp \ + kojournalview.cpp \ + kolistview.cpp \ + kolocationbox.cpp \ + komonthview.cpp \ + koprefs.cpp \ + koprefsdialog.cpp \ + kosyncprefsdialog.cpp \ + kotimespanview.cpp \ + kotodoeditor.cpp \ + kotodoview.cpp \ + kotodoviewitem.cpp \ + koviewmanager.cpp \ + kowhatsnextview.cpp \ + ktimeedit.cpp \ + lineview.cpp \ + main.cpp \ + mainwindow.cpp \ + navigatorbar.cpp \ + outgoingdialog.cpp \ + outgoingdialog_base.cpp \ + publishdialog.cpp \ + publishdialog_base.cpp \ + savetemplatedialog.cpp \ + searchdialog.cpp \ + simplealarmclient.cpp \ + statusdialog.cpp \ + timeline.cpp \ + timespanview.cpp \ + ../kalarmd/alarmdialog.cpp + diff --git a/korganizer/kosyncprefsdialog.cpp b/korganizer/kosyncprefsdialog.cpp new file mode 100644 index 0000000..2e051f2 --- a/dev/null +++ b/korganizer/kosyncprefsdialog.cpp @@ -0,0 +1,453 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2004 Lutz Rogowski <rogowski@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. +*/ + +#include <qlayout.h> +#include <qlabel.h> +#include <qgroupbox.h> +#include <qbuttongroup.h> +#include <qlineedit.h> +#include <qfont.h> +#include <qslider.h> +#include <qfile.h> +#include <qtextstream.h> +#include <qcombobox.h> +#include <qvbox.h> +#include <qhbox.h> +#include <qspinbox.h> +#include <qdatetime.h> +#include <qcheckbox.h> +#include <qradiobutton.h> +#include <qpushbutton.h> +#include <qstrlist.h> +#include <qapplication.h> + +#include <kcolorbutton.h> +#include <kdebug.h> +#include <klocale.h> +#include <kglobal.h> +#include <kfontdialog.h> +#include <kmessagebox.h> +#include <kcolordialog.h> +#include <kiconloader.h> +#include <kemailsettings.h> +#include <kstandarddirs.h> +#include <kfiledialog.h> +#include <kmessagebox.h> + +#include <kurlrequester.h> +#include <klineedit.h> +#include <libkdepim/ksyncprofile.h> + + +#include "koprefs.h" + +#include "kosyncprefsdialog.h" +#include "koglobals.h" +#include "kosyncprefsdialog.moc" + + +KOSyncPrefsDialog::KOSyncPrefsDialog(QWidget *parent, char *name, bool modal) : + KDialog(parent,name,true) +{ + + setCaption( i18n("Synchronization Preferences")); + + mSyncProfiles.setAutoDelete( true ); + setupSyncAlgTab(); +} + + +KOSyncPrefsDialog::~KOSyncPrefsDialog() +{ +} + +#include <qlayout.h> +#include <qscrollview.h> +void KOSyncPrefsDialog::setupSyncAlgTab() +{ + QLabel * lab; + //QFrame *page = addPage(i18n("Sync Prefs"),0,0); + QVBox * mainbox = new QVBox( this ); + QScrollView* sv = new QScrollView( mainbox ); + QHBoxLayout * lay = new QHBoxLayout( this ); + lay->addWidget( mainbox ); + QHBox * b_box = new QHBox( mainbox ); + + QPushButton* button = new QPushButton( i18n("Ok"), b_box ); + connect ( button, SIGNAL( clicked()), this, SLOT (slotOK() ) ); + button = new QPushButton( i18n("Cancel"), b_box ); + connect ( button, SIGNAL( clicked()), this, SLOT (reject() ) ); + //QBoxLayout * sl = new QVBoxLayout(this ); + //sl->addWidget ( sv ); + sv->setResizePolicy ( QScrollView::AutoOneFit ); + QFrame *topFrame = new QFrame ( sv ); + sv->addChild( topFrame ); + mSetupSyncAlgTab = topFrame; + QGridLayout *topLayout = new QGridLayout(topFrame,6,2); + topLayout->setSpacing(spacingHint()); + topLayout->setMargin(marginHint()); + + //lab = new QLabel(i18n("Sync settings not yet implemented. DO NOT USE!"), topFrame); + int iii = 0; + //topLayout->addMultiCellWidget(lab , iii,iii,0,1); + //++iii; + + mMyMachineName = new QLineEdit(topFrame); + lab = new QLabel(mMyMachineName, i18n("Local device name:"), topFrame); + topLayout->addWidget(lab ,iii,0); + topLayout->addWidget(mMyMachineName,iii,1); + ++iii; + + QHBox* buttonbox = new QHBox( topFrame); + topLayout->addMultiCellWidget(buttonbox, iii,iii,0,1); + ++iii; + button = new QPushButton( i18n("New profile"), buttonbox ); + connect ( button, SIGNAL( clicked()), this, SLOT (newProfile() ) ); + + button = new QPushButton( i18n("Clone profile"), buttonbox ); + connect ( button, SIGNAL( clicked()), this, SLOT ( cloneProfile() ) ); + + button = new QPushButton( i18n("Delete profile"), buttonbox ); + connect ( button, SIGNAL( clicked()), this, SLOT (deleteProfile() ) ); + + mProfileBox = new QComboBox(topFrame); + mProfileBox->setEditable ( true ); + connect ( mProfileBox, SIGNAL(activated ( int ) ), this, SLOT (profileChanged( int ) ) ); + connect ( mProfileBox, SIGNAL( textChanged ( const QString & ) ), this, SLOT (textChanged( const QString & ) ) ); + + lab = new QLabel(mProfileBox, i18n("Profile:"), topFrame); + topLayout->addWidget(lab ,iii,0); + topLayout->addWidget(mProfileBox, iii,1); + ++iii; + + mIncludeInRing = new QCheckBox( i18n("Include in multiple sync"), topFrame ); + topLayout->addMultiCellWidget(mIncludeInRing, iii,iii,0,1); + ++iii; + + mAskForPreferences = new QCheckBox( i18n("Ask for preferences before sync"), topFrame ); + topLayout->addMultiCellWidget(mAskForPreferences, iii,iii,0,1); + ++iii; + QButtonGroup* gr = new QButtonGroup ( 1, Qt::Horizontal, i18n("Sync preferences"), topFrame); + topLayout->addMultiCellWidget(gr, iii,iii,0,1); + ++iii; + loc = new QRadioButton ( i18n("Take local entry on conflict"), gr ); + rem = new QRadioButton ( i18n("Take remote entry on conflict"), gr ); + newest = new QRadioButton ( i18n("Take newest entry on conflict"), gr ); + ask = new QRadioButton ( i18n("Ask for every entry on conflict"), gr ); + f_loc= new QRadioButton ( i18n("Force: Take local entry always"), gr ); + f_rem = new QRadioButton ( i18n("Force: Take remote entry always"), gr ); + // both = new QRadioButton ( i18n("Take both on conflict"), gr ); + + mShowSummaryAfterSync = new QCheckBox( i18n("Show summary after sync"), topFrame ); + topLayout->addMultiCellWidget(mShowSummaryAfterSync, iii,iii,0,1); + ++iii; + + mWriteBackExisting= new QCheckBox( i18n("Write back existing entries only"), topFrame ); + topLayout->addMultiCellWidget(mWriteBackExisting, iii,iii,0,1); + ++iii; + + mWriteBackFile = new QCheckBox( i18n("Write back file"), topFrame ); + topLayout->addMultiCellWidget(mWriteBackFile, iii,iii,0,1); + ++iii; + + proGr = new QButtonGroup ( 1, Qt::Horizontal, i18n("Profile kind"), topFrame); + gr = proGr; + topLayout->addMultiCellWidget(gr, iii,iii,0,1); + ++iii; + mIsLocal = new QRadioButton ( i18n("Local file"), gr ); + mIsNotLocal = new QRadioButton ( i18n("Remote file (w down/upload command)"), gr ); + connect (mIsLocal, SIGNAL( toggled(bool)), this, SLOT (kindChanged(bool) ) ); + + localFileWidget = new QVBox( topFrame); + topLayout->addMultiCellWidget(localFileWidget, iii,iii,0,1); + ++iii; + QHBox* temphb = new QHBox( localFileWidget ); + lab = new QLabel( i18n("Local file:"), temphb); + mRemoteFile = new QLineEdit(localFileWidget); + + button = new QPushButton( i18n("Choose..."), temphb ); + connect ( button, SIGNAL( clicked()), this, SLOT ( chooseFile() ) ); + + + remoteFileWidget = new QVBox( topFrame); + topLayout->addMultiCellWidget(remoteFileWidget, iii,iii,0,1); + ++iii; + lab = new QLabel( i18n("Pre sync (download) command:"), remoteFileWidget); + mRemotePrecommand = new QLineEdit(remoteFileWidget); + + lab = new QLabel( i18n("Local temp file:"), remoteFileWidget); + mLocalTempFile = new QLineEdit(remoteFileWidget); + + + lab = new QLabel( i18n("Post sync (upload) command:"), remoteFileWidget); + mRemotePostcommand = new QLineEdit(remoteFileWidget); + + lab = new QLabel( i18n("Fill in default values for:"), remoteFileWidget); + temphb = new QHBox( remoteFileWidget ); + button = new QPushButton( i18n("ssh/scp"), temphb ); + connect ( button, SIGNAL( clicked()), this, SLOT (fillSSH() ) ); + button = new QPushButton( i18n("ftp"), temphb ); + connect ( button, SIGNAL( clicked()), this, SLOT (fillFTP() ) ); + lab = new QLabel( i18n("Hint: Use $PWD$ for placeholder of password!"), remoteFileWidget); + + +} +void KOSyncPrefsDialog::slotOK() +{ + if ( mMyMachineName->text() == "undefined" ) { + KMessageBox::error(this,i18n("Local device name undefined!\nPlease define device name!"),i18n("KO/Pi config error")); + return; + } + int i; + for (i = 0; i < mSyncProfileNames.count(); ++ i) { + if ( mSyncProfileNames.contains( mSyncProfileNames[i]) > 1 ) { + KMessageBox::error(this,i18n("Multiple profiles with same name!\nPlease use unique profile names!"),i18n("KO/Pi config error")); + return; + } + } + usrWriteConfig(); + QDialog::accept(); +} +void KOSyncPrefsDialog::accept() +{ + slotOK(); +} +void KOSyncPrefsDialog::chooseFile() +{ + QString fn =KOPrefs::instance()->mLastSyncedLocalFile; + + fn =KFileDialog:: getOpenFileName( fn, i18n("Sync filename(*.ics/*.vcs)"), this ); + if ( fn == "" ) + return; + mRemoteFile->setText( fn ); +} + +void KOSyncPrefsDialog::textChanged( const QString & s ) +{ + if ( mProfileBox->count() == 0 ) + return; + if ( currentSelection < 3 ) { + //KMessageBox::error(this,i18n("This profil name\ncannot be edited!\n"),i18n("KO/Pi config error")); + mProfileBox->blockSignals( true ); + mProfileBox->setCurrentItem(mProfileBox-> currentItem ()); + mProfileBox->blockSignals( false ); + return; + } + //qDebug("cur i %d ",mProfileBox-> currentItem () ); + mProfileBox->changeItem ( s, mProfileBox-> currentItem () ) ; + KSyncProfile* prof = mSyncProfiles.at(mProfileBox-> currentItem ()) ; + prof->setName( s ); + mSyncProfileNames[mProfileBox-> currentItem ()] = s; +} +void KOSyncPrefsDialog::profileChanged( int item ) +{ + //qDebug("KOSyncPrefsDialog::profileChanged %d ", item ); + KSyncProfile* prof; + saveProfile(); + currentSelection = item; + prof = mSyncProfiles.at(item) ; + mRemotePrecommand->setText(prof->getPreSyncCommand()); + mRemotePostcommand->setText(prof->getPostSyncCommand()); + mLocalTempFile->setText(prof->getLocalTempFile()); + mRemoteFile->setText(prof->getRemoteFileName()) ; + mShowSummaryAfterSync->setChecked( prof->getShowSummaryAfterSync()); + mAskForPreferences->setChecked( prof->getAskForPreferences()); + mWriteBackExisting->setChecked( prof->getWriteBackExisting() ); + mWriteBackFile->setChecked( prof->getWriteBackFile()); + mIncludeInRing->setChecked( prof->getIncludeInRingSync() ); + + switch ( prof->getSyncPrefs() ) { + case 0: + loc->setChecked( true); + break; + case 1: + rem->setChecked( true ); + break; + case 2: + newest->setChecked( true); + break; + case 3: + ask->setChecked( true); + break; + case 4: + f_loc->setChecked( true); + break; + case 5: + f_rem->setChecked( true); + break; + case 6: + //both->setChecked( true); + break; + default: + break; + } + mIsLocal->setChecked(prof->getIsLocalFileSync()) ; + mIsNotLocal->setChecked(!prof->getIsLocalFileSync()); + proGr->setEnabled( item > 2 ); + if ( item < 3 ) { + localFileWidget->setEnabled(false); + remoteFileWidget->setEnabled(false); + + } else + kindChanged( prof->getIsLocalFileSync() ); +} + +void KOSyncPrefsDialog::fillSSH() +{ + mRemotePrecommand->setText("scp zaurus@192.168.0.65:/home/zaurus/kdepim/apps/korganizer/mycalendar.ics /tmp/mycalendar.ics" ); + mLocalTempFile->setText("/tmp/mycalendar.ics" ); + mRemotePostcommand->setText("scp /tmp/mycalendar.ics zaurus@192.168.0.65:/home/zaurus/kdepim/apps/korganizer/mycalendar.ics" ); +} +void KOSyncPrefsDialog::fillFTP() +{ + mRemotePrecommand->setText("cd /tmp;ftp ftp://zaurus:a@192.168.0.65/kdepim/apps/korganizer/mycalendar.ics" ); + mLocalTempFile->setText("/tmp/mycalendar.ics" ); + mRemotePostcommand->setText("ftp -u ftp://zaurus:a@192.168.0.65/kdepim/apps/korganizer/mycalendar.ics /tmp/mycalendar.ics" ); + +} +void KOSyncPrefsDialog::kindChanged( bool b ) +{ + + localFileWidget->setEnabled(b); + remoteFileWidget->setEnabled(!b); + +} +void KOSyncPrefsDialog::deleteProfile() +{ + //qDebug("KOSyncPrefsDialog::deleteProfile() "); + if ( currentSelection >= 0 ) { + if ( currentSelection < 3 ) { + KMessageBox::error(this,i18n("This profil cannot be deleted!\n"),i18n("KO/Pi config error")); + return; + } + KSyncProfile* temp = mSyncProfiles.at(currentSelection); + mSyncProfiles.remove( temp ); + mSyncProfileNames.remove( mSyncProfileNames.at( currentSelection )); + insertProfiles(); + } +} + +void KOSyncPrefsDialog::saveProfile() +{ + KSyncProfile* prof; + if ( currentSelection >= 0 ) { + prof = mSyncProfiles.at(currentSelection) ; + prof->setPreSyncCommand( mRemotePrecommand->text()); + prof->setPostSyncCommand( mRemotePostcommand->text() ); + prof->setLocalTempFile( mLocalTempFile->text()); + prof->setRemoteFileName( mRemoteFile->text() ); + prof->setShowSummaryAfterSync( mShowSummaryAfterSync->isChecked() ); + prof->setAskForPreferences( mAskForPreferences->isChecked()); + prof->setWriteBackExisting(mWriteBackExisting->isChecked() ); + prof->setWriteBackFile( mWriteBackFile->isChecked()); + prof->setIncludeInRingSync( mIncludeInRing->isChecked() ); + int syncprefs = rem->isChecked()*1+newest->isChecked()*2+ ask->isChecked()*3+ f_loc->isChecked()*4+ f_rem->isChecked()*5 ;//+ both->isChecked()*6 ; + prof->setSyncPrefs( syncprefs); + prof->setIsLocalFileSync( mIsLocal->isChecked() ); + } + +} + +void KOSyncPrefsDialog::insertProfiles() +{ + int curItem = mProfileBox->currentItem(); + mProfileBox->blockSignals( true ); + mProfileBox->clear(); + mProfileBox->insertStringList (mSyncProfileNames ); + int item = mSyncProfileNames.count() -1; + if ( curItem >= 0 && mSyncProfileNames.count() > 0 && curItem < mSyncProfileNames.count() ) + mProfileBox->setCurrentItem( curItem ); + else if ( item >= 0 ) { + mProfileBox->setCurrentItem( item ); + } + currentSelection = -1; + if ( mSyncProfileNames.count() > 0 ) { + //qDebug(" profileChanged( mProfileBox->currentItem() "); + profileChanged( mProfileBox->currentItem() ); + currentSelection = mProfileBox->currentItem(); + } + mProfileBox->blockSignals( false ); +} + +void KOSyncPrefsDialog::addProfile ( KSyncProfile* temp ) +{ + saveProfile(); + mSyncProfiles.append( temp ); + mSyncProfileNames << temp->getName(); + insertProfiles(); + int last = mProfileBox->count() -1; + mProfileBox->blockSignals( true ); + mProfileBox->setCurrentItem( last ); + mProfileBox->blockSignals( false ); + profileChanged(last); +} +void KOSyncPrefsDialog::newProfile() +{ + addProfile ( new KSyncProfile () ); +} + +void KOSyncPrefsDialog::cloneProfile() +{ + if ( currentSelection >= 0 ) + addProfile (mSyncProfiles.at(currentSelection)->clone()) ; + else + newProfile(); +} + + +void KOSyncPrefsDialog::usrReadConfig() +{ + KConfig *config = KOGlobals::config(); + config->setGroup("SyncProfiles"); + mSyncProfileNames = KOPrefs::instance()->mSyncProfileNames; + int i; + KSyncProfile* temp ; + mSyncProfiles.clear(); + for ( i = 0; i < mSyncProfileNames.count();++i ) { + temp = new KSyncProfile (); + temp->setName( mSyncProfileNames[i] ); + temp->readConfig( config ); + mSyncProfiles.append( temp ); + } + insertProfiles(); + mMyMachineName->setText(KOPrefs::instance()->mLocalMachineName ); +} + + +void KOSyncPrefsDialog::usrWriteConfig() +{ + saveProfile(); + if ( currentSelection >= 0 ) + profileChanged(currentSelection); + KConfig *config = KOGlobals::config(); + config->setGroup("SyncProfiles"); + KSyncProfile* prof = mSyncProfiles.first(); + while ( prof ) { + prof->writeConfig(config); + prof = mSyncProfiles.next(); + } + KOPrefs::instance()->mSyncProfileNames = mSyncProfileNames; + KOPrefs::instance()->mLocalMachineName = mMyMachineName->text(); + config->writeEntry("SyncProfileNames",&mSyncProfileNames); +} + diff --git a/korganizer/kosyncprefsdialog.h b/korganizer/kosyncprefsdialog.h new file mode 100644 index 0000000..d2d8c6f --- a/dev/null +++ b/korganizer/kosyncprefsdialog.h @@ -0,0 +1,109 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + 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 _KOPREFSDIALOG_H +#define _KOPREFSDIALOG_H + +//#include <qframe.h> +//#include <qdict.h> +#include <qvbox.h> +#include <qhbox.h> +//#include <qcolor.h> +//#include <qlistview.h> + +#include <kdialogbase.h> + +#include <libkdepim/kprefsdialog.h> + +class KColorButton; +class QSpinBox;; +class QRadioButton; +class QCheckBox; +class QSlider; +class KURLRequester; +class QComboBox; +class QLineEdit; +class QStringList; +class KSyncProfile; + +/** Dialog to change the korganizer configuration. + */ +class KOSyncPrefsDialog : public KDialog +{ + Q_OBJECT + public: + /** Initialize dialog and pages */ + KOSyncPrefsDialog(QWidget *parent=0,char *name=0,bool modal=false); + ~KOSyncPrefsDialog(); + void usrReadConfig(); + + public slots: + protected slots: + void accept(); + void deleteProfile(); + void newProfile(); + void cloneProfile(); + void kindChanged(bool); + void fillSSH(); + void fillFTP(); + void textChanged( const QString & ); + void profileChanged( int ); + void chooseFile(); + void slotOK(); + + protected: + void usrWriteConfig(); + + void setupSyncAlgTab(); + + private: + int currentSelection; + QPtrList<KSyncProfile> mSyncProfiles; + QStringList mSyncProfileNames; + QLineEdit * mMyMachineName; + QComboBox * mProfileBox; + QRadioButton* mIsLocal; + QRadioButton* mIsNotLocal; + QCheckBox* mIncludeInRing; + void addProfile ( KSyncProfile* ); + void insertProfiles(); + void saveProfile(); + QButtonGroup* proGr; + + QRadioButton* loc, *rem, *newest, *ask, *f_loc,* f_rem, *both; + + + QLineEdit * mRemotePostcommand; + QLineEdit * mRemotePrecommand; + QLineEdit * mRemoteFile; + QLineEdit * mLocalTempFile; + QWidget* mSetupSyncAlgTab; + + QVBox* localFileWidget; + QVBox* remoteFileWidget; + QCheckBox* mWriteBackFile; + QCheckBox* mWriteBackExisting; + QCheckBox* mAskForPreferences; + QCheckBox* mShowSummaryAfterSync; +}; + +#endif diff --git a/korganizer/kosyncprefsdialog.moc b/korganizer/kosyncprefsdialog.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/kosyncprefsdialog.moc diff --git a/korganizer/kotimespanview.cpp b/korganizer/kotimespanview.cpp new file mode 100644 index 0000000..266a403 --- a/dev/null +++ b/korganizer/kotimespanview.cpp @@ -0,0 +1,110 @@ +#include <qlayout.h> + +#include <kconfig.h> + +#include "timespanview.h" +#include "koglobals.h" + +#include "kotimespanview.h" +#include "kotimespanview.moc" + +KOTimeSpanView::KOTimeSpanView(Calendar *calendar, QWidget *parent, + const char *name) : + KOEventView( calendar, parent, name ) +{ + QBoxLayout *topLayout = new QVBoxLayout( this ); + + mTimeSpanView = new TimeSpanView( this ); + topLayout->addWidget( mTimeSpanView ); + + connect( mTimeSpanView, SIGNAL( dateRangeChanged() ), SLOT( updateView() ) ); +} + +KOTimeSpanView::~KOTimeSpanView() +{ +} + +void KOTimeSpanView::readSettings() +{ + readSettings(KOGlobals::config()); +} + +void KOTimeSpanView::readSettings(KConfig *config) +{ +// kdDebug() << "KOTimeSpanView::readSettings()" << endl; + + config->setGroup("Views"); + + QValueList<int> sizes = config->readIntListEntry("Separator TimeSpanView"); + if (sizes.count() == 2) { + mTimeSpanView->setSplitterSizes(sizes); + } +} + +void KOTimeSpanView::writeSettings(KConfig *config) +{ +// kdDebug() << "KOTimeSpanView::writeSettings()" << endl; + + config->setGroup("Views"); + + QValueList<int> list = mTimeSpanView->splitterSizes(); + config->writeEntry("Separator TimeSpanView",list); +} + +int KOTimeSpanView::maxDatesHint() +{ + return 0; +} + +int KOTimeSpanView::currentDateCount() +{ + return 0; +} + +QPtrList<Incidence> KOTimeSpanView::selectedIncidences() +{ + QPtrList<Incidence> selected; + + return selected; +} + +void KOTimeSpanView::updateView() +{ + insertItems( mTimeSpanView->startDateTime().date(), + mTimeSpanView->endDateTime().date() ); +} + +void KOTimeSpanView::showDates(const QDate &start, const QDate &end) +{ + QDate s = start.addDays( -2 ); + QDate e = end.addDays( 2 ); + + insertItems( s, e ); +} + +void KOTimeSpanView::insertItems(const QDate &start, const QDate &end) +{ + mTimeSpanView->clear(); + mTimeSpanView->setDateRange( start, end ); + + QPtrList<Event> events = calendar()->events( start, end ); + Event *event = events.first(); + while( event ) { +// kdDebug() << "KOTimeSpanView::showDates() add event: " << event->summary() +// << endl; + + mTimeSpanView->addItem( event ); + + event = events.next(); + } + + mTimeSpanView->updateView(); +} + +void KOTimeSpanView::showEvents(QPtrList<Event> eventList) +{ +} + +void KOTimeSpanView::changeEventDisplay(Event *, int) +{ +} diff --git a/korganizer/kotimespanview.h b/korganizer/kotimespanview.h new file mode 100644 index 0000000..c682ed8 --- a/dev/null +++ b/korganizer/kotimespanview.h @@ -0,0 +1,41 @@ +#ifndef KOTIMESPANVIEW_H +#define KOTIMESPANVIEW_H + +#include "koeventview.h" + +class KConfig; +class TimeSpanView; + +class KOTimeSpanView : public KOEventView +{ + Q_OBJECT + public: + KOTimeSpanView(Calendar *calendar, QWidget *parent = 0, + const char *name = 0); + ~KOTimeSpanView(); + + virtual int maxDatesHint(); + virtual int currentDateCount(); + virtual QPtrList<Incidence> selectedIncidences(); + DateList selectedDates() + {DateList q; + return q;} + + void readSettings(); + void readSettings( KConfig * ); + void writeSettings( KConfig * ); + + public slots: + virtual void updateView(); + virtual void showDates(const QDate &start, const QDate &end); + virtual void showEvents(QPtrList<Event> eventList); + + void changeEventDisplay(Event *, int); + + private: + void insertItems( const QDate &start, const QDate & end ); + + TimeSpanView *mTimeSpanView; +}; + +#endif diff --git a/korganizer/kotimespanview.moc b/korganizer/kotimespanview.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/kotimespanview.moc diff --git a/korganizer/kotodoeditor.cpp b/korganizer/kotodoeditor.cpp new file mode 100644 index 0000000..1c44f2b --- a/dev/null +++ b/korganizer/kotodoeditor.cpp @@ -0,0 +1,373 @@ +/* + This file is part of KOrganizer. + Copyright (c) 1997, 1998 Preston Brown + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qtooltip.h> +#include <qframe.h> +#include <qpixmap.h> +#include <qlayout.h> +#include <qhbox.h> +#include <qdir.h> +#include <qdatetime.h> +#include <qapplication.h> + +#include <kiconloader.h> +#include <klocale.h> +#include <kfiledialog.h> +#include <kstandarddirs.h> +#include <kmessagebox.h> + +#include <libkdepim/categoryselectdialog.h> +#include <libkcal/calendarlocal.h> +#include <libkcal/calendarresources.h> +#include <libkcal/resourcecalendar.h> +#include <libkcal/icalformat.h> +#include <kresources/resourceselectdialog.h> + +#include "koprefs.h" + +#include "kotodoeditor.h" +#include "kotodoeditor.moc" +extern int globalFlagBlockAgenda; + +KOTodoEditor::KOTodoEditor( Calendar *calendar, QWidget *parent ) : + KOIncidenceEditor( i18n("Edit To-Do"), calendar, parent ) +{ + mTodo = 0; + mRelatedTodo = 0; + findButton(User1)->hide(); + init(); +} + +KOTodoEditor::~KOTodoEditor() +{ + emit dialogClose( mTodo ); +} + +void KOTodoEditor::init() +{ + setupGeneral(); + setupAttendeesTab(); +} +void KOTodoEditor::setCategories( QString s ) +{ + mGeneral->setCategories(s); +} +void KOTodoEditor::setSecrecy( int sec ) +{ + mGeneral->setSecrecy( sec ); +} +void KOTodoEditor::reload() +{ + if ( mTodo ) readTodo( mTodo ); +} + +void KOTodoEditor::setupGeneral() +{ + mGeneral = new KOEditorGeneralTodo(this); + connect ( mGeneral, SIGNAL ( allAccepted() ), this, SLOT ( slotOk () ) ); + + // connect(mGeneral,SIGNAL(openCategoryDialog()),mCategoryDialog,SLOT(show())); + //connect(mCategoryDialog, SIGNAL(categoriesSelected(const QString &)), + // mGeneral,SLOT(setCategories(const QString &))); + + if (KOPrefs::instance()->mCompactDialogs) { + QFrame *topFrame = addPage(i18n("General")); + + QBoxLayout *topLayout = new QVBoxLayout(topFrame); + if ( QApplication::desktop()->width() < 480 ) { + topLayout->setMargin(1); + topLayout->setSpacing(1); + } else { + topLayout->setMargin(marginHint()-1); + topLayout->setSpacing(spacingHint()-1); + } + mGeneral->initHeader(topFrame,topLayout); + mGeneral->initTime(topFrame,topLayout); + mGeneral->initAlarm(topFrame,topLayout); + mGeneral->enableAlarm( false ); + + + QBoxLayout *priorityLayout; + if ( QApplication::desktop()->width() < 500 ) + priorityLayout = new QVBoxLayout( topLayout ); + else + priorityLayout = new QHBoxLayout( topLayout ); + QWidget* prioWidget = new QWidget (topFrame); + priorityLayout->addWidget( prioWidget ); + QHBoxLayout* priorityLayout2 = new QHBoxLayout( prioWidget); + + + QIconSet icon; + if ( QApplication::desktop()->width() < 321 ) + icon = SmallIcon("fileexport16"); + else + icon = SmallIcon("fileexport"); + QPushButton * saveTemplate = new QPushButton( prioWidget); + saveTemplate->setIconSet (icon ) ; + int size = saveTemplate->sizeHint().height(); + saveTemplate->setFixedSize( size, size ); + if ( QApplication::desktop()->width() < 321 ) + icon = SmallIcon("fileimport16"); + else + icon = SmallIcon("fileimport"); + QPushButton * loadTemplate = new QPushButton( prioWidget); + loadTemplate->setIconSet (icon ) ; + loadTemplate->setFixedSize( size, size ); + + priorityLayout2->addWidget(loadTemplate); + priorityLayout2->addWidget(saveTemplate); + mGeneral->initPriority(prioWidget,priorityLayout2); + mGeneral->initCategories( topFrame, priorityLayout ); + topLayout->addStretch(1); + + QFrame *topFrame2 = addPage(i18n("Details")); + + QBoxLayout *topLayout2 = new QVBoxLayout(topFrame2); + topLayout2->setMargin(marginHint()); + topLayout2->setSpacing(spacingHint()); + + QHBoxLayout *completionLayout = new QHBoxLayout( topLayout2 ); + mGeneral->initCompletion(topFrame2,completionLayout); + + + mGeneral->initSecrecy( topFrame2, topLayout2 ); + mGeneral->initDescription(topFrame2,topLayout2); + + // QHBox * hb = new QHBox ( topFrame2 ); + // topLayout2->addWidget(hb); + // hb->setSpacing( 3 ); + + connect( saveTemplate, SIGNAL( clicked() ), this , SLOT( slotSaveTemplate() ) ); + connect( loadTemplate, SIGNAL( clicked() ), this , SLOT( slotLoadTemplate() ) ); + + } else { + QFrame *topFrame = addPage(i18n("General")); + + QBoxLayout *topLayout = new QVBoxLayout(topFrame); + topLayout->setSpacing(spacingHint()); + + mGeneral->initHeader(topFrame,topLayout); + mGeneral->initTime(topFrame,topLayout); + mGeneral->initStatus(topFrame,topLayout); + QBoxLayout *alarmLineLayout = new QHBoxLayout(topLayout); + mGeneral->initAlarm(topFrame,alarmLineLayout); + mGeneral->initDescription(topFrame,topLayout); + QBoxLayout *detailsLayout = new QHBoxLayout(topLayout); + mGeneral->initCategories( topFrame, detailsLayout ); + mGeneral->initSecrecy( topFrame, detailsLayout ); + } + mGeneral->finishSetup(); + +} + +void KOTodoEditor::editTodo(Todo *todo, bool editDescription) +{ + //init(); + + mTodo = todo; + readTodo(mTodo); + if ( editDescription ) { + showPage( 1 ); + mGeneral->setFocusOn( 1 ); + } else { + showPage( 0 ); + mGeneral->setFocusOn( 2 ); + } +} + +void KOTodoEditor::newTodo(QDateTime due,Todo *relatedTodo,bool allDay) +{ + //init(); + + mTodo = 0; + setDefaults(due,relatedTodo,allDay); +} + +void KOTodoEditor::loadDefaults() +{ + setDefaults(QDateTime::currentDateTime().addDays(7),0,false); +} + +bool KOTodoEditor::processInput( bool emitTime ) +{ + if (!validateInput()) return false; + + Todo *todo = 0; + + if (mTodo) todo = mTodo; + else { + todo = new Todo; + todo->setOrganizer(KOPrefs::instance()->email()); + } + + writeTodo(todo); + if ( emitTime ) { + globalFlagBlockAgenda = 1; + emit showAgendaView( false ); + if ( todo->hasDueDate() ) + emit jumpToTime( todo->dtDue().date() ); + globalFlagBlockAgenda = 2; + } + if (mTodo) { + todo->setRevision(todo->revision()+1); + emit todoChanged(todo); + } else { + mCalendar->addTodo(todo); + mTodo = todo; + emit todoAdded(todo); + } + + return true; +} + +void KOTodoEditor::deleteTodo() +{ + if (mTodo) { + if (KOPrefs::instance()->mConfirm) { + switch (msgItemDelete()) { + case KMessageBox::Continue: // OK + emit todoToBeDeleted(mTodo); + emit dialogClose(mTodo); + mCalendar->deleteTodo(mTodo); + emit todoDeleted(); + reject(); + break; + } + } + else { + emit todoToBeDeleted(mTodo); + emit dialogClose(mTodo); + mCalendar->deleteTodo(mTodo); + emit todoDeleted(); + reject(); + } + } else { + reject(); + } +} + +void KOTodoEditor::setDefaults(QDateTime due,Todo *relatedEvent,bool allDay) +{ + mRelatedTodo = relatedEvent; + + mGeneral->setDefaults(due,allDay); + mDetails->setDefaults(); + showPage( 0 ); + if ( mRelatedTodo ) + mGeneral->setCategories (mRelatedTodo->categoriesStr ()); + mGeneral->setFocusOn( 2 ); +} + +void KOTodoEditor::readTodo(Todo *todo) +{ + mGeneral->readTodo(todo); + mDetails->readEvent(todo); + mRelatedTodo = 0;//todo->relatedTo(); + // categories + // mCategoryDialog->setSelected(todo->categories()); + + // We should handle read-only events here. +} + +void KOTodoEditor::writeTodo(Todo *event) +{ + mGeneral->writeTodo(event); + mDetails->writeEvent(event); + + // set related event, i.e. parent to-do in this case. + if (mRelatedTodo) { + event->setRelatedTo(mRelatedTodo); + } +} + +bool KOTodoEditor::validateInput() +{ + if (!mGeneral->validateInput()) return false; + if (!mDetails->validateInput()) return false; + return true; +} + +int KOTodoEditor::msgItemDelete() +{ + return KMessageBox::warningContinueCancel(this, + i18n("This item will be permanently deleted."), + i18n("KOrganizer Confirmation"),i18n("Delete")); +} + +void KOTodoEditor::modified (int modification) +{ + if (modification == KOGlobals::CATEGORY_MODIFIED || + KOGlobals::UNKNOWN_MODIFIED == modification ) + // mCategoryDialog->setSelected (mTodo->categories ()); + mGeneral->modified (mTodo, modification); + +} + +void KOTodoEditor::slotLoadTemplate() +{ + + QString fileName =locateLocal( "templates", "todos" ); + QDir t_dir; + if ( !t_dir.exists(fileName) ) + t_dir.mkdir ( fileName ); + fileName += "/todo"; + fileName = KFileDialog::getSaveFileName( fileName , "Load Todo template", this ); + if ( fileName.length() == 0 ) + return; + CalendarLocal cal; + ICalFormat format; + if ( !format.load( &cal, fileName ) ) { + KMessageBox::error( this, i18n("Error loading template file\n '%1'.") + .arg( fileName ) ); + return ; + } + QPtrList<Todo> todos = cal.todos(); + Todo * todo = todos.first(); + if ( !todo ) { + KMessageBox::error( this, + i18n("Template does not\ncontain a valid Todo.")); + } else { + readTodo( todo ); + } + +} + +void KOTodoEditor::slotSaveTemplate() +{ + QString fileName =locateLocal( "templates", "todos" ); + QDir t_dir; + if ( !t_dir.exists(fileName) ) + t_dir.mkdir ( fileName ); + fileName += "/todo"; + fileName = KFileDialog::getSaveFileName( fileName , "Save as Todo template", this ); + if ( fileName.length() > 0 ) + saveTemplate( fileName ); +} + +void KOTodoEditor::saveTemplate( const QString &templateName ) +{ + Todo *todo = new Todo; + writeTodo( todo ); + saveAsTemplate( todo, templateName ); +} diff --git a/korganizer/kotodoeditor.h b/korganizer/kotodoeditor.h new file mode 100644 index 0000000..2657bd8 --- a/dev/null +++ b/korganizer/kotodoeditor.h @@ -0,0 +1,102 @@ +/* + This file is part of KOrganizer. + Copyright (c) 1997, 1998 Preston Brown + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ +#ifndef _KOTODOEDITOR_H +#define _KOTODOEDITOR_H + +#include <libkcal/calendar.h> + +#include "koeditorgeneraltodo.h" +#include "koeditordetails.h" +#include "koincidenceeditor.h" + +class QDateTime; + +/** + This class provides a dialog for editing a Todo. +*/ +class KOTodoEditor : public KOIncidenceEditor +{ + Q_OBJECT + public: + /** + Constructs a new todo editor. + */ + KOTodoEditor( Calendar *calendar, QWidget *parent ); + virtual ~KOTodoEditor(); + + void init(); + + void reload(); + void setSecrecy( int sec ); + /** + Clear editor for new todo, and preset the dates and times with hint. + */ + void newTodo(QDateTime due,Todo *relatedTodo=0,bool allDay=false); + + /** Edit an existing todo. */ + void editTodo(Todo * ,bool editDescription = false ); + + /** Set widgets to default values */ + void setDefaults(QDateTime due,Todo *relatedTodo,bool allDay); + /** Read event object and setup widgets accordingly */ + void readTodo(Todo *); + /** Write event settings to event object */ + void writeTodo(Todo *); + + /** Check if the input is valid. */ + bool validateInput(); + /** Process user input and create or update event. Returns false if input + * is not valid */ + bool processInput( bool ); + + /** This todo has been modified externally */ + void modified (int); + void setCategories( QString s ); + signals: + void todoChanged(Todo *); + void todoAdded(Todo *); + void todoToBeDeleted(Todo *); + void todoDeleted(); + + protected slots: + void loadDefaults(); + void deleteTodo(); + + void slotLoadTemplate(); + void slotSaveTemplate(); + void saveTemplate( const QString & ); + + protected: + void setupGeneral(); + int msgItemDelete(); + + private: + Todo *mTodo; + + Incidence *mRelatedTodo; + + KOEditorGeneralTodo *mGeneral; +}; + +#endif diff --git a/korganizer/kotodoeditor.moc b/korganizer/kotodoeditor.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/kotodoeditor.moc diff --git a/korganizer/kotodoview.cpp b/korganizer/kotodoview.cpp new file mode 100644 index 0000000..0708a69 --- a/dev/null +++ b/korganizer/kotodoview.cpp @@ -0,0 +1,1028 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + 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. +*/ + +#include <qlayout.h> +#include <qheader.h> +#include <qcursor.h> + +#include <qvbox.h> +#include <kdebug.h> +#include "koprefs.h" +#include <klocale.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <kmessagebox.h> + +#include <libkcal/icaldrag.h> +#include <libkcal/vcaldrag.h> +#include <libkcal/calfilter.h> +#include <libkcal/dndfactory.h> +#include <libkcal/calendarresources.h> +#include <libkcal/resourcecalendar.h> +#include <kresources/resourceselectdialog.h> +#ifndef DESKTOP_VERSION +#include <qpe/qpeapplication.h> +#else +#include <qapplication.h> +#endif +#ifndef KORG_NOPRINTER +#include "calprinter.h" +#endif +#include "docprefs.h" + +#include "kotodoview.h" +using namespace KOrg; +#include "kotodoview.moc" + +KOTodoListView::KOTodoListView(Calendar *calendar,QWidget *parent, + const char *name) : + KListView(parent,name) +{ + mCalendar = calendar; +#ifndef DESKTOP_VERSION + QPEApplication::setStylusOperation(viewport(), QPEApplication::RightOnHold ); +#endif + mOldCurrent = 0; + mMousePressed = false; + + setAcceptDrops(true); + viewport()->setAcceptDrops(true); + int size = 16; + if (qApp->desktop()->width() < 300 ) + size = 12; + setTreeStepSize( size + 6 ); + +} + +void KOTodoListView::contentsDragEnterEvent(QDragEnterEvent *e) +{ +#ifndef KORG_NODND +// kdDebug() << "KOTodoListView::contentsDragEnterEvent" << endl; + if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) && + !QTextDrag::canDecode( e ) ) { + e->ignore(); + return; + } + + mOldCurrent = currentItem(); +#endif +} + + +void KOTodoListView::contentsDragMoveEvent(QDragMoveEvent *e) +{ +#ifndef KORG_NODND +// kdDebug() << "KOTodoListView::contentsDragMoveEvent" << endl; + + if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) && + !QTextDrag::canDecode( e ) ) { + e->ignore(); + return; + } + + e->accept(); +#endif +} + +void KOTodoListView::contentsDragLeaveEvent(QDragLeaveEvent *) +{ +#ifndef KORG_NODND +// kdDebug() << "KOTodoListView::contentsDragLeaveEvent" << endl; + + setCurrentItem(mOldCurrent); + setSelected(mOldCurrent,true); +#endif +} + +void KOTodoListView::contentsDropEvent(QDropEvent *e) +{ +#ifndef KORG_NODND +// kdDebug() << "KOTodoListView::contentsDropEvent" << endl; + + if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) && + !QTextDrag::canDecode( e ) ) { + e->ignore(); + return; + } + + DndFactory factory( mCalendar ); + Todo *todo = factory.createDropTodo(e); + + if (todo) { + e->acceptAction(); + + KOTodoViewItem *destination = + (KOTodoViewItem *)itemAt(contentsToViewport(e->pos())); + Todo *destinationEvent = 0; + if (destination) destinationEvent = destination->todo(); + + Todo *existingTodo = mCalendar->todo(todo->uid()); + + if(existingTodo) { +// kdDebug() << "Drop existing Todo" << endl; + Incidence *to = destinationEvent; + while(to) { + if (to->uid() == todo->uid()) { + KMessageBox::sorry(this, + i18n("Cannot move To-Do to itself or a child of itself"), + i18n("Drop To-Do")); + delete todo; + return; + } + to = to->relatedTo(); + } + existingTodo->setRelatedTo(destinationEvent); + emit todoDropped(todo); + delete todo; + } else { +// kdDebug() << "Drop new Todo" << endl; + todo->setRelatedTo(destinationEvent); + mCalendar->addTodo(todo); + + emit todoDropped(todo); + } + } + else { + QString text; + if (QTextDrag::decode(e,text)) { + //QListViewItem *qlvi = itemAt( contentsToViewport(e->pos()) ); + KOTodoViewItem *todoi = static_cast<KOTodoViewItem *>(itemAt( contentsToViewport(e->pos()) )); + kdDebug() << "Dropped : " << text << endl; + QStringList emails = QStringList::split(",",text); + for(QStringList::ConstIterator it = emails.begin();it!=emails.end();++it) { + kdDebug() << " Email: " << (*it) << endl; + int pos = (*it).find("<"); + QString name = (*it).left(pos); + QString email = (*it).mid(pos); + if (!email.isEmpty() && todoi) { + todoi->todo()->addAttendee(new Attendee(name,email)); + } + } + } + else { + kdDebug() << "KOTodoListView::contentsDropEvent(): Todo from drop not decodable" << endl; + e->ignore(); + } + } +#endif +} + +void KOTodoListView::contentsMousePressEvent(QMouseEvent* e) +{ + QListView::contentsMousePressEvent(e); +#ifndef KORG_NODND + QPoint p(contentsToViewport(e->pos())); + QListViewItem *i = itemAt(p); + if (i) { + // if the user clicked into the root decoration of the item, don't + // try to start a drag! + if (p.x() > header()->sectionPos(header()->mapToIndex(0)) + + treeStepSize() * (i->depth() + (rootIsDecorated() ? 1 : 0)) + + itemMargin() || + p.x() < header()->sectionPos(header()->mapToIndex(0))) { + if (e->button()==Qt::LeftButton) { + mPressPos = e->pos(); + mMousePressed = true; + } + } + } +#endif +} + +void KOTodoListView::contentsMouseMoveEvent(QMouseEvent* e) +{ +#ifndef KORG_NODND +// kdDebug() << "KOTodoListView::contentsMouseMoveEvent()" << endl; + QListView::contentsMouseMoveEvent(e); + if (mMousePressed && (mPressPos - e->pos()).manhattanLength() > + QApplication::startDragDistance()) { + mMousePressed = false; + QListViewItem *item = itemAt(contentsToViewport(mPressPos)); + if (item) { +// kdDebug() << "Start Drag for item " << item->text(0) << endl; + DndFactory factory( mCalendar ); + ICalDrag *vd = factory.createDragTodo( + ((KOTodoViewItem *)item)->todo(),viewport()); + if (vd->drag()) { + kdDebug() << "KOTodoListView::contentsMouseMoveEvent(): Delete drag source" << endl; + } +/* + QString source = fullPath(item); + if ( QFile::exists(source) ) { + QUriDrag* ud = new QUriDrag(viewport()); + ud->setFilenames( source ); + if ( ud->drag() ) + QMessageBox::information( this, "Drag source", + QString("Delete ")+source, "Not implemented" ); +*/ + } + } +#endif +} +void KOTodoListView::keyPressEvent ( QKeyEvent * e ) +{ + + QListViewItem* cn; + if ( e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter ) { + cn = currentItem(); + if ( cn ) { + KOTodoViewItem* ci = (KOTodoViewItem*)( cn ); + if ( ci ){ + if ( e->state() == ShiftButton ) + ci->setOn( false ); + else + ci->setOn( true ); + cn = cn->nextSibling(); + if ( cn ) { + setCurrentItem ( cn ); + ensureItemVisible ( cn ); + } + + } + } + + return; + } + + // qDebug("KOTodoListView::keyPressEvent "); + if ( e->state() == Qt::ControlButton || e->state() == Qt::ShiftButton || ( height() > 150 && width() > 200 ) ) { + switch ( e->key() ) { + case Qt::Key_Down: + case Qt::Key_Up: + QListView::keyPressEvent ( e ); + break; + default: + e->ignore(); + break; + } + return; + } + e->ignore(); +} +void KOTodoListView::contentsMouseReleaseEvent(QMouseEvent *e) +{ + QListView::contentsMouseReleaseEvent(e); + mMousePressed = false; +} + +void KOTodoListView::contentsMouseDoubleClickEvent(QMouseEvent *e) +{ + if (!e) return; + + QPoint vp = contentsToViewport(e->pos()); + + QListViewItem *item = itemAt(vp); + + emit double_Clicked(item); + if (!item) return; + + emit doubleClicked(item,vp,0); +} + +///////////////////////////////////////////////////////////////////////////// + +KOQuickTodo::KOQuickTodo(QWidget *parent) : + QLineEdit(parent) +{ + setText(i18n("Click to add a new Todo")); +} + +void KOQuickTodo::focusInEvent(QFocusEvent *ev) +{ + if ( text()==i18n("Click to add a new Todo") ) + setText(""); + QLineEdit::focusInEvent(ev); +} + +void KOQuickTodo::focusOutEvent(QFocusEvent *ev) +{ + setText(i18n("Click to add a new Todo")); + QLineEdit::focusOutEvent(ev); +} + +///////////////////////////////////////////////////////////////////////////// + +KOTodoView::KOTodoView(Calendar *calendar,QWidget* parent,const char* name) : + KOrg::BaseView(calendar,parent,name) +{ + QBoxLayout *topLayout = new QVBoxLayout(this); + mName = QString ( name ); + mBlockUpdate = false; + mQuickAdd = new KOQuickTodo(this); + topLayout->addWidget(mQuickAdd); + + if ( !KOPrefs::instance()->mEnableQuickTodo ) mQuickAdd->hide(); + + mTodoListView = new KOTodoListView(calendar,this); + topLayout->addWidget(mTodoListView); + //mTodoListView->header()->setMaximumHeight(30); + mTodoListView->setRootIsDecorated(true); + mTodoListView->setAllColumnsShowFocus(true); + + mTodoListView->setShowSortIndicator(true); + + mTodoListView->addColumn(i18n("Todo")); + mTodoListView->addColumn(i18n("Prio")); + mTodoListView->setColumnAlignment(1,AlignHCenter); + mTodoListView->addColumn(i18n("Complete")); + mTodoListView->setColumnAlignment(2,AlignHCenter); + mTodoListView->addColumn(i18n("Due Date")); + mTodoListView->setColumnAlignment(3,AlignLeft); + mTodoListView->addColumn(i18n("Due Time")); + mTodoListView->setColumnAlignment(4,AlignHCenter); + mTodoListView->addColumn(i18n("Cancelled")); + mTodoListView->addColumn(i18n("Categories")); +#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 ); + mTodoListView->setColumnWidthMode(0, QListView::Manual); + mTodoListView->setColumnWidthMode(1, QListView::Manual); + mTodoListView->setColumnWidthMode(2, QListView::Manual); + mTodoListView->setColumnWidthMode(3, QListView::Manual); + mTodoListView->setColumnWidthMode(4, QListView::Manual); + mTodoListView->setColumnWidthMode(5, QListView::Manual); + mTodoListView->setColumnAlignment( 2, AlignCenter ); +#if 0 + mTodoListView->setColumnWidthMode(6, QListView::Manual); +#endif + + 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))); + + + + 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())); + mItemPopupMenu->insertItem( i18n("Beam..."), this, + SLOT (beamTodo())); + mItemPopupMenu->insertItem( i18n("Toggle Cancel"), this, + SLOT (cancelTodo())); + 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())); + mItemPopupMenu->insertSeparator(); + 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 ); + + 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 quick todo","Show Quick Todo"), + this, SLOT( toggleQuickTodo() ),0,4 ); + mDocPrefs = new DocPrefs( name ); + + mPopupMenu->setCheckable( true ); + mItemPopupMenu->setCheckable( true ); + // 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( clicked( QListViewItem * ) ), + SLOT( itemClicked( QListViewItem * ) ) ); + connect( mTodoListView, SIGNAL( double_Clicked( QListViewItem * ) ), + SLOT( itemDoubleClicked( QListViewItem * ) ) ); + connect( mTodoListView, SIGNAL( todoDropped( Todo * ) ), + SLOT( updateView() ) ); + connect( mTodoListView, SIGNAL( expanded( QListViewItem * ) ), + SLOT( itemStateChanged( QListViewItem * ) ) ); + connect( mTodoListView, SIGNAL( collapsed( QListViewItem * ) ), + SLOT( itemStateChanged( QListViewItem * ) ) ); + +#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(selectionChanged() ), + SLOT( processSelectionChange() ) ); + connect( mQuickAdd, SIGNAL( returnPressed () ), + SLOT( addQuickTodo() ) ); +// if ( QApplication::desktop()->width() < 480 ) { +// setNarrow(); + // mTodoListView->setColumnWidth( 0, 100 ); + + // } + +} + +KOTodoView::~KOTodoView() +{ + delete mDocPrefs; +} + +void KOTodoView::jumpToDate () +{ + // if (mActiveItem) { +// mActiveItem->todo()); +// if ( mActiveItem->todo()->hasDueDate() ) +// emit mActiveItem->todo()jumpToTime( mTodo->dtDue().date() ); +} + +void KOTodoView::setNarrow() +{ + //mTodoListView->setColumnWidth( 0, 120 ); + mTodoListView->setColumnWidth( 1, 35 ); + mTodoListView->setColumnWidth( 2, 40 ); + mTodoListView->setColumnWidth( 3, 80 ); + mTodoListView->setColumnWidth( 4, 40 ); + mTodoListView->setColumnWidth( 5, 90 ); + +} +void KOTodoView::updateView() +{ +// 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->type() == "Todo") { + //qDebug("related %s ",incidence->summary().latin1() ); + if ( !(todoList.contains ( ((Todo* )incidence ) ) )) { + //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(); + } +// qDebug("again .... "); +// for(todo = todoList.first(); todo; todo = todoList.next()) { + +// qDebug("yytodo %s ", todo->summary().latin1()); +// } + //qDebug("for "); + for(todo = todoList.first(); todo; todo = todoList.next()) { + if (!mTodoMap.contains(todo) && ( KOPrefs::instance()->mShowCompletedTodo || !todo->isCompleted() ) ) + { + insertTodoItem(todo); + } + } + //qDebug("for end "); + // Restore opened/closed state + mTodoListView->blockSignals( true ); + if( mDocPrefs ) restoreItemState( mTodoListView->firstChild() ); + mTodoListView->blockSignals( false ); + mTodoListView->setFocus(); + processSelectionChange(); +} + +void KOTodoView::restoreItemState( QListViewItem *item ) +{ + 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 + + + Incidence *incidence = todo->relatedTo(); + if (incidence && incidence->type() == "Todo") { + 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 ) +{ + // qDebug("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 &,int column) +{ + + 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 6: + getCategoryPopupMenu((KOTodoViewItem *)item)->popup(QCursor::pos ()); break; + default: + mItemPopupMenu->popup(QCursor::pos()); + } + } else mPopupMenu->popup(QCursor::pos()); +} +void KOTodoView::newTodo() +{ + emit newTodoSignal(); +} + +void KOTodoView::newSubTodo() +{ + if (mActiveItem) { + emit newSubTodoSignal(mActiveItem->todo()); + } +} +void KOTodoView::unparentTodo() +{ + if (mActiveItem) { + emit unparentTodoSignal(mActiveItem->todo()); + } +} +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) { + if (mActiveItem->childCount()) { + KMessageBox::sorry(this,i18n("Cannot delete To-Do which has children."), + i18n("Delete To-Do")); + } else { + 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 ); + } +} + +void KOTodoView::setNewPercentage(int index) +{ + if (mActiveItem && !mActiveItem->todo()->isReadOnly ()) { + 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 ); + } +} + + +QPopupMenu * KOTodoView::getCategoryPopupMenu (KOTodoViewItem *todoItem) +{ + QPopupMenu* tempMenu = new QPopupMenu (this); + QStringList checkedCategories = todoItem->todo()->categories (); + + tempMenu->setCheckable (true); + for (QStringList::Iterator it = KOPrefs::instance()->mCustomCategories.begin (); + it != KOPrefs::instance()->mCustomCategories.end (); + ++it) { + int index = tempMenu->insertItem (*it); + mCategory[index] = *it; + if (checkedCategories.find (*it) != checkedCategories.end ()) tempMenu->setItemChecked (index, true); + } + + connect (tempMenu, SIGNAL (activated (int)), SLOT (changedCategories (int))); + return tempMenu; + + +} +void KOTodoView::changedCategories(int index) +{ + if (mActiveItem && !mActiveItem->todo()->isReadOnly ()) { + QStringList categories = mActiveItem->todo()->categories (); + if (categories.find (mCategory[index]) != categories.end ()) + categories.remove (mCategory[index]); + else + categories.insert (categories.end(), mCategory[index]); + categories.sort (); + 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 (!item) { + newTodo(); + return; + } + if ( KOPrefs::instance()->mEditOnDoubleClick ) + editItem( item ); + else + showItem( item , QPoint(), 0 ); +} +void KOTodoView::itemClicked(QListViewItem *item) +{ + if (!item) { + return; + } + + KOTodoViewItem *todoItem = (KOTodoViewItem *)item; + int completed = todoItem->todo()->isCompleted(); // Completed or not? + + if (todoItem->isOn()) { + if (!completed) { + todoItem->todo()->setCompleted(QDateTime::currentDateTime()); + } + } else { + if (completed) { + todoItem->todo()->setCompleted(false); + } + } +} + +void KOTodoView::setDocumentId( const QString &id ) +{ + kdDebug() << "KOTodoView::setDocumentId()" << endl; + + 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 ); + } else { + emit incidenceSelected( item->todo() ); + } +} + +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::purgeCompleted() +{ + emit purgeCompletedSignal(); +} +void KOTodoView::toggleQuickTodo() +{ + if ( mQuickAdd->isVisible() ) { + mQuickAdd->hide(); + KOPrefs::instance()->mEnableQuickTodo = false; + } + else { + mQuickAdd->show(); + KOPrefs::instance()->mEnableQuickTodo = true; + } + mPopupMenu->setItemChecked(4,KOPrefs::instance()->mEnableQuickTodo); + mItemPopupMenu->setItemChecked( 34 , KOPrefs::instance()->mEnableQuickTodo ); +} +void KOTodoView::toggleCompleted() +{ + KOPrefs::instance()->mShowCompletedTodo = !KOPrefs::instance()->mShowCompletedTodo; + mPopupMenu->setItemChecked( 3,KOPrefs::instance()->mShowCompletedTodo ); + mItemPopupMenu->setItemChecked( 33 , KOPrefs::instance()->mShowCompletedTodo ); + updateView(); +} + +void KOTodoView::addQuickTodo() +{ + Todo *todo = new Todo(); + todo->setSummary(mQuickAdd->text()); + todo->setOrganizer(KOPrefs::instance()->email()); + 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; + switch ( e->key() ) { + case Qt::Key_Down: + QWidget::keyPressEvent ( e ); + break; + + case Qt::Key_Up: + QWidget::keyPressEvent ( e ); + break; + case Qt::Key_Q: + toggleQuickTodo(); + break; + + default: + e->ignore(); + } + + if ( e->state() == Qt::ControlButton || e->state() == Qt::ShiftButton || ( height() > 150 && width() > 200 ) ) { + 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; +} diff --git a/korganizer/kotodoview.h b/korganizer/kotodoview.h new file mode 100644 index 0000000..4495702 --- a/dev/null +++ b/korganizer/kotodoview.h @@ -0,0 +1,230 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000, 2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + 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 KOTODOVIEW_H +#define KOTODOVIEW_H + +#include <qfont.h> +#include <qfontmetrics.h> +#include <qlineedit.h> +#include <qptrlist.h> +#include <qstrlist.h> +#include <qlistbox.h> +#include <qpopupmenu.h> +#include <qlabel.h> +#include <qmap.h> +#include <qlistview.h> +#include <klistview.h> + +#include <libkcal/calendar.h> +#include <libkcal/todo.h> + +#include <korganizer/baseview.h> + +#include "kotodoviewitem.h" +#include "koprefs.h" +#include "koglobals.h" + +class QDragEnterEvent; +class QDragMoveEvent; +class QDragLeaveEvent; +class QDropEvent; + +class DocPrefs; + +class KOTodoListView : public KListView +{ + Q_OBJECT + public: + KOTodoListView(Calendar *,QWidget *parent=0,const char *name=0); + virtual ~KOTodoListView() {} + + signals: + void todoDropped(Todo *); + void double_Clicked(QListViewItem *item); + + protected: + void contentsDragEnterEvent(QDragEnterEvent *); + void contentsDragMoveEvent(QDragMoveEvent *); + void contentsDragLeaveEvent(QDragLeaveEvent *); + void contentsDropEvent(QDropEvent *); + + void contentsMousePressEvent(QMouseEvent *); + void contentsMouseMoveEvent(QMouseEvent *); + void contentsMouseReleaseEvent(QMouseEvent *); + void contentsMouseDoubleClickEvent(QMouseEvent *); + + private: + Calendar *mCalendar; + QPoint mPressPos; + bool mMousePressed; + QListViewItem *mOldCurrent; + void keyPressEvent ( QKeyEvent * ) ; +}; + + +/** + This is the line-edit on top of the todoview for fast addition of new todos +*/ +class KOQuickTodo : public QLineEdit +{ + public: + KOQuickTodo(QWidget *parent=0); + protected: + void focusInEvent(QFocusEvent *ev); + void focusOutEvent(QFocusEvent *ev); +}; + + +/** + This class provides a multi-column list view of todo events. + + @short multi-column list view of todo events. + @author Cornelius Schumacher <schumacher@kde.org> +*/ +class KOTodoView : public KOrg::BaseView +{ + Q_OBJECT + public: + KOTodoView(Calendar *, QWidget* parent=0, const char* name=0 ); + ~KOTodoView(); + + QPtrList<Incidence> selectedIncidences(); + QPtrList<Todo> selectedTodos(); + + DateList selectedDates() + {DateList q; + return q;} + + /** Return number of shown dates. TodoView does not show dates, */ + int currentDateCount() { return 0; } + void setNarrow(); + + void printPreview(CalPrinter *calPrinter, const QDate &fd, const QDate &td); + + void setDocumentId( const QString & ); + + void saveLayout(KConfig *config, const QString &group) const; + void restoreLayout(KConfig *config, const QString &group); + /** Create a popup menu to set categories */ + QPopupMenu *getCategoryPopupMenu (KOTodoViewItem *todoItem); + + public slots: + void updateView(); + void updateConfig(); + + void changeEventDisplay(Event *, int); + + void showDates(const QDate &start, const QDate &end); + void showEvents(QPtrList<Event> eventList); + + void clearSelection(); + void jumpToDate (); + + void editItem(QListViewItem *item); + void showItem(QListViewItem *item,const QPoint &,int); + void popupMenu(QListViewItem *item,const QPoint &,int); + void newTodo(); + void newSubTodo(); + void unparentTodo(); + void showTodo(); + void editTodo(); + void cloneTodo(); + void cancelTodo(); + void moveTodo(); + void beamTodo(); + void deleteTodo(); + + void setNewPriority(int); + void setNewPercentage(int); + void changedCategories(int); + + void purgeCompleted(); + void toggleCompleted(); + void toggleQuickTodo(); + void updateTodo( Todo *, int ); + + void itemClicked(QListViewItem *); + void itemStateChanged(QListViewItem *); + void modified(bool); + void itemDoubleClicked(QListViewItem *item); + + signals: + void newTodoSignal(); + void newSubTodoSignal(Todo *); + void unparentTodoSignal(Todo *); + void showTodoSignal(Todo *); + + void editTodoSignal(Todo *); + void deleteTodoSignal(Todo *); + void todoModifiedSignal (Todo *, int); + + void isModified(bool); + void cloneTodoSignal( Incidence * ); + void cancelTodoSignal( Incidence * ); + void moveTodoSignal( Incidence * ); + void beamTodoSignal( Incidence * ); + void purgeCompletedSignal(); + + protected slots: + void processSelectionChange(); + void addQuickTodo(); + + private: + /* + * the TodoEditor approach is rather unscaling in the long + * run. + * Korganizer keeps it in memory and we need to update + * 1. make KOTodoViewItem a QObject again? + * 2. add a public method for setting one todo modified? + * 3. add a private method for setting a todo modified + friend here? + * -- zecke 2002-07-08 + */ + friend class KOTodoViewItem; + void setTodoModified( Todo* ); + QMap<Todo *,KOTodoViewItem *>::ConstIterator insertTodoItem(Todo *todo); + void restoreItemState( QListViewItem * ); + + KOTodoListView *mTodoListView; + QPopupMenu *mItemPopupMenu; + QPopupMenu *mPopupMenu; + QPopupMenu *mPriorityPopupMenu; + QPopupMenu *mPercentageCompletedPopupMenu; + QPopupMenu *mCategoryPopupMenu; + + QMap<int, int> mPercentage; + QMap<int, int> mPriority; + QMap<int, QString> mCategory; + KOTodoViewItem *mActiveItem; + + QMap<Todo *,KOTodoViewItem *> mTodoMap; + QString mName; + + DocPrefs *mDocPrefs; + QString mCurrentDoc; + KOQuickTodo *mQuickAdd; + bool mBlockUpdate; + void todoModified(Todo *, int ); + void keyPressEvent ( QKeyEvent * ) ; +}; + +#endif diff --git a/korganizer/kotodoview.moc b/korganizer/kotodoview.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/kotodoview.moc diff --git a/korganizer/kotodoviewitem.cpp b/korganizer/kotodoviewitem.cpp new file mode 100644 index 0000000..85647b1 --- a/dev/null +++ b/korganizer/kotodoviewitem.cpp @@ -0,0 +1,432 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include <klocale.h> +#include <kdebug.h> +#include <qapp.h> + +#include <kiconloader.h> +#include "kotodoviewitem.h" +#include "kotodoview.h" +#include "koprefs.h" + +KOTodoViewItem::KOTodoViewItem( QListView *parent, Todo *todo, KOTodoView *kotodo) + : QCheckListItem( parent , "", CheckBox ), mTodo( todo ), mTodoView( kotodo ) +{ + construct(); +} + +KOTodoViewItem::KOTodoViewItem( KOTodoViewItem *parent, Todo *todo, KOTodoView *kotodo ) + : QCheckListItem( parent, "", CheckBox ), mTodo( todo ), mTodoView( kotodo ) +{ + construct(); +} + +QString KOTodoViewItem::key(int column,bool) const +{ + QMap<int,QString>::ConstIterator it = mKeyMap.find(column); + if (it == mKeyMap.end()) { + return text(column); + } else { + return *it; + } +} + +void KOTodoViewItem:: setup() +{ + + int h = 20; + if ( listView () ) { + QFontMetrics fm ( listView ()->font () ); + h = fm.height(); + } + setHeight( h ); + +} +void KOTodoViewItem::setSortKey(int column,const QString &key) +{ + mKeyMap.insert(column,key); +} + +#if QT_VERSION >= 300 +void KOTodoViewItem::paintBranches(QPainter *p,const QColorGroup & cg,int w, + int y,int h) +{ + QListViewItem::paintBranches(p,cg,w,y,h); +} +#else +#endif + +void KOTodoViewItem::construct() +{ + // qDebug("KOTodoViewItem::construct() "); + m_init = true; + QString keyd = "=="; + QString keyt = "=="; + + setOn(mTodo->isCompleted()); + setText(0,mTodo->summary()); + setText(1,QString::number(mTodo->priority())); + setText(2,i18n("%1 %").arg(QString::number(mTodo->percentComplete()))); + if (mTodo->percentComplete()<100) { + if (mTodo->isCompleted()) setSortKey(2,QString::number(999)); + else setSortKey(2,QString::number(mTodo->percentComplete())); + } + else { + if (mTodo->isCompleted()) setSortKey(2,QString::number(999)); + else setSortKey(2,QString::number(99)); + } + if (mTodo->hasDueDate()) { + setText(3, mTodo->dtDueDateStr()); + QDate d = mTodo->dtDue().date(); + keyd.sprintf("%04d%02d%02d",d.year(),d.month(),d.day()); + setSortKey(3,keyd); + if (mTodo->doesFloat()) { + setText(4,""); + } + else { + setText(4,mTodo->dtDueTimeStr()); + QTime t = mTodo->dtDue().time(); + keyt.sprintf("%02d%02d",t.hour(),t.minute()); + setSortKey(4,keyt); + } + } else { + setText(3,""); + setText(4,""); + } + setSortKey(3,keyd); + setSortKey(4,keyt); + + if (mTodo->isCompleted()) setSortKey(1,"6" + QString::number(mTodo->priority())+keyd+keyt); + else setSortKey(1,QString::number(mTodo->priority())+keyd+keyt); + + setText(5,mTodo->cancelled() ? i18n("Yes") : i18n("No")); + setText(6,mTodo->categoriesStr()); + +#if 0 + // Find sort id in description. It's the text behind the last '#' character + // found in the description. White spaces are removed from beginning and end + // of sort id. + int pos = mTodo->description().findRev('#'); + if (pos < 0) { + setText(6,""); + } else { + QString str = mTodo->description().mid(pos+1); + str.stripWhiteSpace(); + setText(6,str); + } +#endif + + m_known = false; + m_init = false; + + setMyPixmap(); + +} +void KOTodoViewItem::setMyPixmap() +{ + int size = 5; + QPixmap pixi = QPixmap( 1, 1 ); + // if ( !mTodo->isCompleted() && mTodo->hasDueDate() && mTodo->dtDue() < QDateTime::currentDateTime() ) { +// pixi = SmallIcon("redcross16"); +// } else { + QPainter p; + + int pixSize = 0; + QPixmap pPix = QPixmap( size, size ); + if ( mTodo->description().length() > 0 ) { + pixi.resize(size, pixSize+size); + pPix.fill( Qt::darkGreen ); + p.begin( &pixi ); + p. drawPixmap ( 0, pixSize, pPix); + p.end(); + pixSize += size; + } + if ( mTodo->isAlarmEnabled() ) { + pixi.resize(size, pixSize+size); + pPix.fill( Qt::red ); + p.begin( &pixi ); + p. drawPixmap ( 0, pixSize, pPix); + p.end(); + pixSize += size; + } + // } + if ( pixi.width() > 1 ) { + setPixmap ( 0,pixi ) ; + } + + +} +void KOTodoViewItem::stateChange(bool state) +{ + // qDebug("KOTodoViewItem::stateChange "); + // do not change setting on startup + if ( m_init ) return; + + kdDebug() << "State changed, modified " << state << endl; + QString keyd = "=="; + QString keyt = "=="; + + if (state) mTodo->setCompleted(state); + else mTodo->setPercentComplete(0); + if (isOn()!=state) { + setOn(state); + } + + if (mTodo->hasDueDate()) { + setText(3, mTodo->dtDueDateStr()); + QDate d = mTodo->dtDue().date(); + keyd.sprintf("%04d%02d%02d",d.year(),d.month(),d.day()); + setSortKey(3,keyd); + if (mTodo->doesFloat()) { + setText(4,""); + } + else { + setText(4,mTodo->dtDueTimeStr()); + QTime t = mTodo->dtDue().time(); + keyt.sprintf("%02d%02d",t.hour(),t.minute()); + setSortKey(4,keyt); + } + } + if (mTodo->isCompleted()) setSortKey(1,QString::number(9)+keyd+keyt); + else setSortKey(1,QString::number(mTodo->priority())+keyd+keyt); + + setText(2,i18n("%1 %").arg(QString::number(mTodo->percentComplete()))); + if (mTodo->percentComplete()<100) { + if (mTodo->isCompleted()) setSortKey(2,QString::number(999)); + else setSortKey(2,QString::number(mTodo->percentComplete())); + } + else { + if (mTodo->isCompleted()) setSortKey(2,QString::number(999)); + else setSortKey(2,QString::number(99)); + } + QListViewItem * myChild = firstChild(); + KOTodoViewItem *item; + while( myChild ) { + item = static_cast<KOTodoViewItem*>(myChild); + item->stateChange(state); + myChild = myChild->nextSibling(); + } + mTodoView->modified(true); + mTodoView->setTodoModified( mTodo ); + setMyPixmap(); +} + +bool KOTodoViewItem::isAlternate() +{ +#ifndef KORG_NOLVALTERNATION + KOTodoListView *lv = static_cast<KOTodoListView *>(listView()); + if (lv && lv->alternateBackground().isValid()) + { + KOTodoViewItem *above = 0; + above = dynamic_cast<KOTodoViewItem *>(itemAbove()); + m_known = above ? above->m_known : true; + if (m_known) + { + m_odd = above ? !above->m_odd : false; + } + else + { + KOTodoViewItem *item; + bool previous = true; + if (QListViewItem::parent()) + { + item = dynamic_cast<KOTodoViewItem *>(QListViewItem::parent()); + if (item) + previous = item->m_odd; + item = dynamic_cast<KOTodoViewItem *>(QListViewItem::parent()->firstChild()); + } + else + { + item = dynamic_cast<KOTodoViewItem *>(lv->firstChild()); + } + + while(item) + { + item->m_odd = previous = !previous; + item->m_known = true; + item = dynamic_cast<KOTodoViewItem *>(item->nextSibling()); + } + } + return m_odd; + } + return false; +#else + return false; +#endif +} + +void KOTodoViewItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment) +{ + QColorGroup _cg = cg; + QColorGroup::ColorRole role; + if ( KOPrefs::instance()->mTodoViewUsesForegroundColor ) + role = QColorGroup::Text; + else + role = QColorGroup::Base; + //#ifndef KORG_NOLVALTERNATION + // if (isAlternate()) + // _cg.setColor(QColorGroup::Base, static_cast< KOTodoListView* >(listView())->alternateBackground()); + bool setColor = KOPrefs::instance()->mTodoViewUsesCatColors; + QColor colorToSet; + if ( setColor ) { + QStringList categories = mTodo->categories(); + QString cat = categories.first(); + if ( !cat.isEmpty()) { + colorToSet = *(KOPrefs::instance()->categoryColor(cat) ); + } else + setColor = false; + } + if (mTodo->hasDueDate()) { + if (mTodo->dtDue().date()==QDate::currentDate() && + !mTodo->isCompleted()) { + //_cg.setColor( role , KOPrefs::instance()->mTodoDueTodayColor); + colorToSet = KOPrefs::instance()->mTodoDueTodayColor; + setColor = true; + } + if (mTodo->dtDue().date() < QDate::currentDate() && + !mTodo->isCompleted()) { + //_cg.setColor( role, KOPrefs::instance()->mTodoOverdueColor); + colorToSet = KOPrefs::instance()->mTodoOverdueColor; + setColor = true; + } + } + + if ( setColor ) { + _cg.setColor(role,colorToSet ); + if ( role == QColorGroup::Base) { + int rgb = colorToSet.red(); + rgb += colorToSet.blue()/2; + rgb += colorToSet.green(); + if ( rgb < 200 ) + _cg.setColor(QColorGroup::Text,Qt::white ); + } + } + //#endif + if ( column > 0 ){ + if ( column == 2 && !KOPrefs::instance()->mTodoViewShowsPercentage ) { + p->save(); + int progress = (int)(( (width-6)*mTodo->percentComplete())/100.0 + 0.5); + + p->fillRect( 0, 0, width, height(), _cg.base() ); // background + // p->setPen(Qt::black ); //border + // p->setBrush( KOPrefs::instance()->mHighlightColorKGlobalSettings::baseColor() ); //filling + QColor fc = KOPrefs::instance()->mHighlightColor; + if ( mTodo->percentComplete() == 100 ) + fc = darkGreen; + p->drawRect( 2, 2, width-4, height()-4); + p->fillRect( 3, 3, progress, height()-6, + fc ); + p->restore(); + } else { + QCheckListItem::paintCell(p, _cg, column, width, alignment); + } + return; + } + + int align = alignment; + + if ( !p ) + return; + + p->fillRect( 0, 0, width, height(), _cg.brush( QColorGroup::Base ) ); + + QListView *lv = listView(); + if ( !lv ) + return; + int marg = 2;//lv->itemMargin(); + int r = 0; + QCheckListItem::Type myType = QCheckListItem::CheckBox; + int BoxSize = 20; + int boxOffset = 2; + int xOffset = 2; + if (qApp->desktop()->width() < 300 ) { + BoxSize = 14; + boxOffset = -1; + xOffset = 1; + // marg = 0; + } + if ( height() < BoxSize ) { + boxOffset = boxOffset - ((BoxSize - height())/2) ; + // qDebug("boxOffset %d height %d", boxOffset, height() ); + BoxSize = height(); + + } + //bool winStyle = lv->style() == WindowsStyle; + + int lineStart = 5; + if ( myType == Controller ) { + if ( !pixmap( 0 ) ) + r += BoxSize + 4; + } else { + ASSERT( lv ); //### + // QFontMetrics fm( lv->font() ); + // int d = fm.height(); + int x = 0; + int y = (height() - BoxSize) / 2; + // p->setPen( QPen( _cg.text(), winStyle ? 2 : 1 ) ); + if ( myType == CheckBox ) { + if ( isEnabled() ) + p->setPen( QPen( _cg.text(), 1 ) ); + else + p->setPen( QPen( listView()->palette().color( QPalette::Disabled, QColorGroup::Text ), 1 ) ); + p->drawRect( x+marg, y+2, BoxSize-4, BoxSize-4 ); + lineStart = x+marg; + ///////////////////// + x++; + y++; + if ( isOn() ) { + QPointArray a( 7*2 ); + int i, xx, yy; + xx = x+xOffset+marg+(boxOffset/2); + yy = y+5+boxOffset; + for ( i=0; i<3; i++ ) { + a.setPoint( 2*i, xx, yy ); + a.setPoint( 2*i+1, xx, yy+2 ); + // qDebug(" "); + xx++; yy++; + } + yy -= 2; + for ( i=3; i<7; i++ ) { + a.setPoint( 2*i, xx, yy ); + a.setPoint( 2*i+1, xx, yy+2 ); + xx++; yy--; + } + p->setPen( darkGreen ); + p->drawLineSegments( a ); + } + //////////////////////// + } + r += BoxSize + 4; + } + + p->translate( r, 0 ); + p->setPen( QPen( _cg.text() ) ); + QListViewItem::paintCell( p, _cg, column, width - r, align ); + if ( mTodo->cancelled () ) { + p->setPen( black ); + QRect br = p->boundingRect( 1,1,1,1,0,mTodo->summary() ); + int wid = br.width() +lineStart; + if ( wid > width-3 ) + wid = width-3; + p->drawLine( lineStart, height()/2+1, wid, height()/2+1 ); + + } + +} diff --git a/korganizer/kotodoviewitem.h b/korganizer/kotodoviewitem.h new file mode 100644 index 0000000..74dbe98 --- a/dev/null +++ b/korganizer/kotodoviewitem.h @@ -0,0 +1,93 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000, 2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef KOTODOVIEWITEM_H +#define KOTODOVIEWITEM_H + +#include <qfont.h> +#include <qfontmetrics.h> +#include <qlineedit.h> +#include <qptrlist.h> +#include <qstrlist.h> +#include <qlistbox.h> +#include <qpopupmenu.h> +#include <qlabel.h> +#include <qmap.h> +#include <qlistview.h> +#include <qpainter.h> + +#include <libkcal/calendar.h> +#include <libkcal/todo.h> + +using namespace KCal; + +class KOTodoView; + +/** + This class provides a way of displaying a single Event of Todo-Type in a + KTodoView. + + @author Cornelius Schumacher <schumacher@kde.org> + @see KOTodoView +*/ +class KOTodoViewItem : public QCheckListItem +{ + public: + /** + Constructor. + + @param parent is the list view to which this item belongs. + @param ev is the event to have the item display information for. + */ + KOTodoViewItem(QListView *parent, Todo *todo, KOTodoView *kotodo); + KOTodoViewItem(KOTodoViewItem *parent, Todo *todo, KOTodoView *kotodo); + //~KOTodoViewItem() { qDebug("~KOTodoViewItem() %s ", text(0).latin1() );} + + void construct(); + + Todo *todo() { return mTodo; } + + QString key(int, bool) const; + + void setSortKey(int column,const QString &key); + + bool isAlternate(); + + virtual void paintCell(QPainter *p, const QColorGroup &cg, + int column, int width, int alignment); + virtual void setup(); + protected: +#if QT_VERSION >= 300 + void paintBranches(QPainter *p,const QColorGroup & cg,int w,int y,int h); +#else +#endif + virtual void stateChange(bool); + void setMyPixmap(); + + private: + Todo *mTodo; + KOTodoView *mTodoView; + + QMap<int,QString> mKeyMap; + uint m_odd : 1; + uint m_known : 1; + uint m_unused : 30; + bool m_init; +}; + +#endif diff --git a/korganizer/koviewmanager.cpp b/korganizer/koviewmanager.cpp new file mode 100644 index 0000000..88d69c6 --- a/dev/null +++ b/korganizer/koviewmanager.cpp @@ -0,0 +1,570 @@ +/* + 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. +*/ + +#include <qwidgetstack.h> + +#include <kconfig.h> +#include <kglobal.h> +#ifndef DESKTOP_VERSION +#include <qpe/qpeapplication.h> +#else +#include <qapplication.h> +#endif +#include "calendarview.h" +#include "datenavigator.h" +#include "kotodoview.h" +#include "koagendaview.h" +#include "kodialogmanager.h" +#include "komonthview.h" +#include "kolistview.h" +#include "kowhatsnextview.h" +#include "kojournalview.h" +#include "kotimespanview.h" +#include "koprefs.h" +#include "navigatorbar.h" + +#include "koviewmanager.h" +#include "koviewmanager.moc" +//extern bool externFlagMonthviewBlockPainting; + +//bool globalFlagBlockPainting = false; +int globalFlagBlockAgenda = 0; +int globalFlagBlockLabel = 0; +int globalFlagBlockAgendaItemPaint = 1; +int globalFlagBlockAgendaItemUpdate = 1; + + +KOViewManager::KOViewManager( CalendarView *mainView ) : + QObject(), mMainView( mainView ) +{ + mCurrentView = 0; + + mWhatsNextView = 0; + mTodoView = 0; + mAgendaView = 0; + mMonthView = 0; + mListView = 0; + mJournalView = 0; + mTimeSpanView = 0; + mCurrentAgendaView = 0 ; + mFlagShowNextxDays = false; +} + +KOViewManager::~KOViewManager() +{ +} + + +KOrg::BaseView *KOViewManager::currentView() +{ + return mCurrentView; +} + +void KOViewManager::readSettings(KConfig *config) +{ + config->setGroup("General"); + QString view = config->readEntry("Current View"); + if (view == "WhatsNext") showWhatsNextView(); + else if (view == "Month") showMonthView(); + else if (view == "List") showListView(); + else if (view == "Journal") showJournalView(); + else if (view == "TimeSpan") showTimeSpanView(); + else if (view == "Todo") showTodoView(); + else { + showAgendaView(); + } +} + +void KOViewManager::writeSettings(KConfig *config) +{ + config->setGroup("General"); + + QString view; + if (mCurrentView == mWhatsNextView) view = "WhatsNext"; + else if (mCurrentView == mMonthView) view = "Month"; + else if (mCurrentView == mListView) view = "List"; + else if (mCurrentView == mJournalView) view = "Journal"; + else if (mCurrentView == mTimeSpanView) view = "TimeSpan"; + else if (mCurrentView == mTodoView) view = "Todo"; + else view = "Agenda"; + + config->writeEntry("Current View",view); + + if (mAgendaView) { + mAgendaView->writeSettings(config); + } + if (mTimeSpanView) { + mTimeSpanView->writeSettings(config); + } + if (mListView) { + mListView->writeSettings(config); + } + if (mTodoView) { + mTodoView->saveLayout(config,"Todo View"); + } +} + +void KOViewManager::showView(KOrg::BaseView *view, bool fullScreen ) +{ + + //mFlagShowNextxDays = false; + //if(view == mCurrentView) return; + if ( view == 0 ) { + view = mCurrentView; + if ( view == 0 ) + return; + } + bool full = fullScreen; + if(view == mCurrentView && view != mWhatsNextView ) { + if ( mCurrentAgendaView < 0 ) + return; + full = mMainView->leftFrame()->isVisible(); + } else { + mCurrentView = view; + + // bool full = fullScreen; + bool isFull = !mMainView->leftFrame()->isVisible(); + if ( isFull && KOPrefs::instance()->mViewChangeHoldFullscreen ) + full = true; + if ( !isFull && KOPrefs::instance()->mViewChangeHoldNonFullscreen ) + full = false; + } + if ( mAgendaView ) mAgendaView->deleteSelectedDateTime(); + raiseCurrentView( full ); + mMainView->processIncidenceSelection( 0 ); + mMainView->updateView(); + mMainView->adaptNavigationUnits(); +} + +void KOViewManager::raiseCurrentView( bool fullScreen ) +{ + //qDebug("raiseCurrentView "); + mCurrentAgendaView = 0; + int wid = mMainView->width() ; + int hei = mMainView->height(); + if ( mCurrentView == mMonthView ) { + mMainView->navigatorBar()->show(); + hei -= mMainView->navigatorBar()->sizeHint().height(); + //mMainView->navigatorBar()->hide(); + } else { + mMainView->navigatorBar()->hide(); + } + if ( fullScreen ) { + mMainView->leftFrame()->hide(); + } else { + mMainView->leftFrame()->show(); + if ( KOPrefs::instance()->mVerticalScreen ) + hei -= mMainView->leftFrame()->height(); + else + wid -= mMainView->leftFrame()->width(); + } + + if ( globalFlagBlockAgenda == 5 ) { + globalFlagBlockAgenda = 4; + globalFlagBlockAgendaItemPaint = 1; + } + mMainView->viewStack()->raiseWidget(mCurrentView); + if ( globalFlagBlockAgenda == 4 ) { + if ( mCurrentView == mAgendaView ) { + //globalFlagBlockAgenda =1 ; + if ( KOPrefs::instance()->mSetTimeToDayStartAt ) + mAgendaView->setStartHour( KOPrefs::instance()->mDayBegins ); + else if ( KOPrefs::instance()->mCenterOnCurrentTime ) + mAgendaView->setStartHour( QTime::currentTime ().hour() ); + qApp->processEvents(); + //qDebug("qApp->processEvents() "); + globalFlagBlockAgenda = 0; + mAgendaView->repaintAgenda(); + + } + globalFlagBlockAgenda = 0; + } + //qDebug("raiseCurrentView ende "); +} + +void KOViewManager::updateView() +{ + // qDebug("KOViewManager::updateView() "); + // if we are updating mTodoView, we get endless recursion + if ( mTodoView == mCurrentView ) + return; + if ( mCurrentView ) mCurrentView->updateView(); + +} + +void KOViewManager::updateView(const QDate &start, const QDate &end) +{ + // kdDebug() << "KOViewManager::updateView()" << endl; + + if (mCurrentView) mCurrentView->showDates(start, end); + + if (mTodoView) mTodoView->updateView(); +} + + +void KOViewManager::showWhatsNextView() +{ + if (!mWhatsNextView) { + mWhatsNextView = new KOWhatsNextView(mMainView->calendar(),mMainView->viewStack(), + "KOViewManager::WhatsNextView"); + mWhatsNextView->setEventViewer( mMainView->getEventViewerDialog()); + connect(mMainView, SIGNAL(configChanged()), mWhatsNextView, SLOT(updateConfig())); + addView(mWhatsNextView); + } + globalFlagBlockAgenda = 1; + showView(mWhatsNextView, true ); + mWhatsNextView->updateView(); + +} + +void KOViewManager::showListView() +{ + if (!mListView) { + mListView = new KOListView(mMainView->calendar(), mMainView->viewStack(), "KOViewManager::ListView"); + addView(mListView); + + connect(mListView, SIGNAL(showIncidenceSignal(Incidence *)), + mMainView, SLOT(showIncidence(Incidence *))); + connect(mListView, SIGNAL(editIncidenceSignal(Incidence *)), + mMainView, SLOT(editIncidence(Incidence *))); + connect(mListView, SIGNAL(deleteIncidenceSignal(Incidence *)), + mMainView, SLOT(deleteIncidence(Incidence *))); + connect( mListView, SIGNAL( incidenceSelected( Incidence * ) ), + mMainView, SLOT( processMainViewSelection( Incidence * ) ) ); + connect( mListView, SIGNAL( signalNewEvent() ), + mMainView, SLOT( newEvent() ) ); + connect(mMainView, SIGNAL(configChanged()), mListView, SLOT(updateConfig())); + connect( mListView, SIGNAL( cloneIncidenceSignal( Incidence * ) ), + mMainView, SLOT ( cloneIncidence( Incidence * ) ) ); + connect( mListView, SIGNAL( cancelIncidenceSignal( Incidence * ) ), + mMainView, SLOT ( cancelIncidence( Incidence * ) ) ); + connect( mListView, SIGNAL( moveIncidenceSignal( Incidence * ) ), + mMainView, SLOT ( moveIncidence( Incidence * ) ) ); + connect( mListView, SIGNAL( beamIncidenceSignal( Incidence * ) ), + mMainView, SLOT ( beamIncidence( Incidence * ) ) ); + } + // bool temp = mFlagShowNextxDays; + //globalFlagBlockPainting = true; + globalFlagBlockAgenda = 1; + if ( KOPrefs::instance()->mListViewMonthTimespan ) + mMainView->dateNavigator()->selectMonth(); + showView(mListView, KOPrefs::instance()->mFullViewTodo); + //mFlagShowNextxDays = temp; +} + +void KOViewManager::showAgendaView( bool fullScreen ) +{ + + mMainView->dialogManager()->hideSearchDialog(); + // qDebug("KOViewManager::showAgendaView "); + bool full; + full = fullScreen; + if (!mAgendaView) { + full = false; + mAgendaView = new KOAgendaView(mMainView->calendar(), mMainView->viewStack(), "KOViewManager::AgendaView"); + addView(mAgendaView); +#ifndef DESKTOP_VERSION + QPEApplication::setStylusOperation( mAgendaView, QPEApplication::RightOnHold ); +#endif + connect( mAgendaView, SIGNAL( incidenceChanged(Incidence *, int )), + mMainView, SLOT( changeIncidenceDisplay( Incidence *, int ) )); + + // SIGNALS/SLOTS FOR DAY/WEEK VIEW + connect(mAgendaView,SIGNAL(newEventSignal(QDateTime)), + mMainView, SLOT(newEvent(QDateTime))); + // connect(mAgendaView,SIGNAL(newEventSignal(QDateTime,QDateTime)), + // mMainView, SLOT(newEvent(QDateTime,QDateTime))); + connect(mAgendaView,SIGNAL(newEventSignal(QDate)), + mMainView, SLOT(newEvent(QDate))); + + connect(mAgendaView, SIGNAL(editIncidenceSignal(Incidence *)), + mMainView, SLOT(editIncidence(Incidence *))); + connect(mAgendaView, SIGNAL(showIncidenceSignal(Incidence *)), + mMainView, SLOT(showIncidence(Incidence *))); + connect(mAgendaView, SIGNAL(deleteIncidenceSignal(Incidence *)), + mMainView, SLOT(deleteIncidence(Incidence *))); + + connect( mAgendaView, SIGNAL( incidenceSelected( Incidence * ) ), + mMainView, SLOT( processMainViewSelection( Incidence * ) ) ); + + connect(mAgendaView, SIGNAL( toggleExpand() ), + mMainView, SLOT( toggleExpand() ) ); + + connect(mMainView, SIGNAL( calendarViewExpanded( bool ) ), + mAgendaView, SLOT( setExpandedButton( bool ) ) ); + connect( mAgendaView, SIGNAL( cloneIncidenceSignal(Incidence *) ), + mMainView, SLOT(cloneIncidence(Incidence *) ) ) ; + connect( mAgendaView, SIGNAL( cancelIncidenceSignal(Incidence *) ), + mMainView, SLOT(cancelIncidence(Incidence *) ) ) ; + connect(mMainView, SIGNAL(configChanged()), mAgendaView, SLOT(updateConfig())); + connect( mMainView, SIGNAL( todoModified( Todo *, int )), mAgendaView, + SLOT( updateTodo( Todo *, int ) ) ); + connect( mAgendaView,SIGNAL( todoMoved( Todo *, int )), + mMainView, SIGNAL( todoModified( Todo *, int ))); + connect( mAgendaView, SIGNAL( moveIncidenceSignal( Incidence * ) ), + mMainView, SLOT ( moveIncidence( Incidence * ) ) ); + connect( mAgendaView, SIGNAL( beamIncidenceSignal( Incidence * ) ), + mMainView, SLOT ( beamIncidence( Incidence * ) ) ); + mAgendaView->readSettings(); + mAgendaView->updateConfig(); + } + + showView( mAgendaView, full); + +} + +void KOViewManager::showDayView() +{ + mFlagShowNextxDays = false; + globalFlagBlockLabel = 1; + globalFlagBlockAgenda = 1; + if ( mCurrentAgendaView != 1 ) + mCurrentAgendaView = -1; + showAgendaView(); + qApp->processEvents(); + globalFlagBlockAgenda = 2; + globalFlagBlockLabel = 0; + mMainView->dateNavigator()->selectDates( 1 ); + mCurrentAgendaView = 1 ; + +} + +void KOViewManager::showWorkWeekView() +{ + mFlagShowNextxDays = false; + globalFlagBlockAgenda = 1; + globalFlagBlockLabel = 1; + if ( mCurrentAgendaView != 5 ) + mCurrentAgendaView = -1; + showAgendaView(); + qApp->processEvents(); + globalFlagBlockAgenda = 2; + globalFlagBlockLabel = 0; + mMainView->dateNavigator()->selectWorkWeek(); + mCurrentAgendaView = 5 ; + +} + +void KOViewManager::showWeekView() +{ + /* + globalFlagBlockAgenda = 2; + qDebug("4globalFlagBlockAgenda = 2; "); + //globalFlagBlockPainting = true; + mMainView->dateNavigator()->selectWeek(); + showAgendaView(); + */ + + + mFlagShowNextxDays = false; + globalFlagBlockAgenda = 1; + globalFlagBlockLabel = 1; + if ( mCurrentAgendaView != 7 ) + mCurrentAgendaView = -1; + showAgendaView(); + qApp->processEvents(); + globalFlagBlockAgenda = 2; + globalFlagBlockLabel = 0; + mMainView->dateNavigator()->selectWeek(); + mCurrentAgendaView = 7 ; +} + +void KOViewManager::showNextXView() +{ + + globalFlagBlockAgenda = 1; + if ( mCurrentAgendaView != 3 ) + mCurrentAgendaView = -1; + showAgendaView(KOPrefs::instance()->mFullViewMonth); + globalFlagBlockAgenda = 2; + mMainView->dateNavigator()->selectDates( QDate::currentDate(), + KOPrefs::instance()->mNextXDays ); + mFlagShowNextxDays = true; + mCurrentAgendaView = 3 ; +} +bool KOViewManager::showsNextDays() +{ + return mFlagShowNextxDays; +} +void KOViewManager::showMonthView() +{ + if (!mMonthView) { + mMonthView = new KOMonthView(mMainView->calendar(), mMainView->viewStack(), "KOViewManager::MonthView"); + + addView(mMonthView); + // mMonthView->show(); + // SIGNALS/SLOTS FOR MONTH VIEW + connect(mMonthView, SIGNAL(newEventSignal(QDateTime)), + mMainView, SLOT(newEvent(QDateTime))); + + connect(mMonthView, SIGNAL(showIncidenceSignal(Incidence *)), + mMainView, SLOT(showIncidence(Incidence *))); + connect(mMonthView, SIGNAL(editIncidenceSignal(Incidence *)), + mMainView, SLOT(editIncidence(Incidence *))); + connect(mMonthView, SIGNAL(deleteIncidenceSignal(Incidence *)), + mMainView, SLOT(deleteIncidence(Incidence *))); + + connect( mMonthView, SIGNAL( incidenceSelected( Incidence * ) ), + mMainView, SLOT( processMainViewSelection( Incidence * ) ) ); + connect( mMonthView, SIGNAL( cloneIncidenceSignal( Incidence * ) ), + mMainView, SLOT ( cloneIncidence( Incidence * ) ) ); + connect( mMonthView, SIGNAL( cancelIncidenceSignal( Incidence * ) ), + mMainView, SLOT ( cancelIncidence( Incidence * ) ) ); + + connect( mMonthView, SIGNAL( moveIncidenceSignal( Incidence * ) ), + mMainView, SLOT ( moveIncidence( Incidence * ) ) ); + connect( mMonthView, SIGNAL( beamIncidenceSignal( Incidence * ) ), + mMainView, SLOT ( beamIncidence( Incidence * ) ) ); + connect( mMonthView, SIGNAL( selectWeekNum( int ) ), + mMainView, SLOT ( selectWeekNum( int ) ) ); + connect(mMainView, SIGNAL(configChanged()), mMonthView, SLOT(updateConfig())); + mMonthView->updateConfig(); + } + + globalFlagBlockAgenda = 1; + //mFlagShowNextxDays = false; + // if(mMonthView == mCurrentView) return; + mMainView->dateNavigator()->selectMonth(); + // DateList tmpList = mMainView->dateNavigator()->selectedDates( ); + //mMonthView->showDates(tmpList.first(), tmpList.last()); + + showView(mMonthView, true ); + +} + +void KOViewManager::showTodoView() +{ + //mFlagShowNextxDays = false; + if ( !mTodoView ) { + mTodoView = new KOTodoView( mMainView->calendar(), mMainView->viewStack(), + "KOViewManager::TodoView" ); + + addView( mTodoView ); + // QPEApplication::setStylusOperation( mTodoView, QPEApplication::RightOnHold ); + + // SIGNALS/SLOTS FOR TODO VIEW + connect( mTodoView, SIGNAL( newTodoSignal() ), + mMainView, SLOT( newTodo() ) ); + connect( mTodoView, SIGNAL( newSubTodoSignal( Todo * ) ), + mMainView, SLOT( newSubTodo( Todo *) ) ); + connect( mTodoView, SIGNAL( showTodoSignal( Todo *) ), + mMainView, SLOT( showTodo( Todo * ) ) ); + connect( mTodoView, SIGNAL( editTodoSignal( Todo * ) ), + mMainView, SLOT( editTodo( Todo * ) ) ); + connect( mTodoView, SIGNAL( deleteTodoSignal( Todo * ) ), + mMainView, SLOT( deleteTodo( Todo * ) ) ); + connect( mTodoView, SIGNAL( purgeCompletedSignal() ), + mMainView, SLOT( purgeCompleted() ) ); + + connect( mTodoView, SIGNAL( incidenceSelected( Incidence * ) ), + mMainView, SLOT( processMainViewSelection( Incidence * ) ) ); + + connect( mMainView, SIGNAL( configChanged() ), mTodoView, + SLOT( updateConfig() ) ); + connect( mMainView, SIGNAL( todoModified( Todo *, int )), mTodoView, + SLOT( updateTodo( Todo *, int ) ) ); + connect( mTodoView, SIGNAL( todoModifiedSignal( Todo *, int ) ), + mMainView, SIGNAL ( todoModified( Todo *, int ) ) ); + connect( mTodoView, SIGNAL( cloneTodoSignal( Incidence * ) ), + mMainView, SLOT ( cloneIncidence( Incidence * ) ) ); + connect( mTodoView, SIGNAL( cancelTodoSignal( Incidence * ) ), + mMainView, SLOT ( cancelIncidence( Incidence * ) ) ); + connect( mTodoView, SIGNAL( unparentTodoSignal( Todo * ) ), + mMainView, SLOT ( todo_unsub( Todo * ) ) ); + connect( mTodoView, SIGNAL( moveTodoSignal( Incidence * ) ), + mMainView, SLOT ( moveIncidence( Incidence * ) ) ); + connect( mTodoView, SIGNAL( beamTodoSignal( Incidence * ) ), + mMainView, SLOT ( beamIncidence( Incidence * ) ) ); + KConfig *config = KOGlobals::config(); + mTodoView->restoreLayout(config,"Todo View"); + } + + globalFlagBlockAgenda = 1; + showView( mTodoView, true ); + +} + +void KOViewManager::showJournalView() +{ + //mFlagShowNextxDays = false; + if (!mJournalView) { + mJournalView = new KOJournalView(mMainView->calendar(),mMainView->viewStack(), + "KOViewManager::JournalView"); + connect( mMainView, SIGNAL( configChanged() ), mJournalView, + SLOT( updateConfig() ) ); + connect(mJournalView, SIGNAL(deleteJournal(Journal *) ), mMainView,SLOT(deleteJournal(Journal *)) ); + addView(mJournalView); + } + + showView(mJournalView); +} + +void KOViewManager::showTimeSpanView() +{ + //mFlagShowNextxDays = false; + if (!mTimeSpanView) { + mTimeSpanView = new KOTimeSpanView(mMainView->calendar(),mMainView->viewStack(), + "KOViewManager::TimeSpanView"); + addView(mTimeSpanView); + + mTimeSpanView->readSettings(); + } + + showView(mTimeSpanView); +} + +Incidence *KOViewManager::currentSelection() +{ + if (!mCurrentView) return 0; + if ( mCurrentView == mListView ) { + if ( mListView->currentItem() ) + return mListView->currentItem(); + } + return mCurrentView->selectedIncidences().first(); +} + +QDate KOViewManager::currentSelectionDate() +{ + QDate qd; + if (mCurrentView) { + DateList qvl = mCurrentView->selectedDates(); + if (!qvl.isEmpty()) qd = qvl.first(); + } + return qd; +} + +void KOViewManager::addView(KOrg::BaseView *view) +{ +#if QT_VERSION >= 300 + mMainView->viewStack()->addWidget( view ); +#else + mMainView->viewStack()->addWidget( view, 1 ); +#endif +} + +void KOViewManager::setDocumentId( const QString &id ) +{ + if (mTodoView) mTodoView->setDocumentId( id ); +} diff --git a/korganizer/koviewmanager.h b/korganizer/koviewmanager.h new file mode 100644 index 0000000..f814c36 --- a/dev/null +++ b/korganizer/koviewmanager.h @@ -0,0 +1,113 @@ +/* + 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 KOVIEWMANAGER_H +#define KOVIEWMANAGER_H + +#include <qobject.h> + +#include <korganizer/baseview.h> + +class CalendarView; + +class KOListView; +class KOAgendaView; +class KOMonthView; +class KOTimeSpanView; +class KOTodoView; +class KOWhatsNextView; +class KOJournalView; + +using namespace KCal; + +/** + This class manages the views of the calendar. It owns the objects and handles + creation and selection. +*/ +class KOViewManager : public QObject +{ + Q_OBJECT + public: + KOViewManager( CalendarView * ); + virtual ~KOViewManager(); + + /** changes the view to be the currently selected view */ + void showView(KOrg::BaseView *, bool fullScreen = false ); + + void readSettings(KConfig *config); + void writeSettings(KConfig *config); + bool showsNextDays(); + /** Read which view was shown last from config file */ + void readCurrentView(KConfig *); + /** Write which view is currently shown to config file */ + void writeCurrentView(KConfig *); + + KOrg::BaseView *currentView(); + + void setDocumentId( const QString & ); + + void updateView(); + void updateView( const QDate &start, const QDate &end ); + + void raiseCurrentView( bool fullScreen = false ); + + void addView(KOrg::BaseView *); + + Incidence *currentSelection(); + QDate currentSelectionDate(); + + KOAgendaView *agendaView() const { return mAgendaView; } + + public slots: + void showWhatsNextView(); + void showListView(); + void showAgendaView( bool fullScreen = false ); + void showDayView(); + void showWorkWeekView(); + void showWeekView(); + void showNextXView(); + void showMonthView(); + void showTodoView(); + void showJournalView(); + void showTimeSpanView(); + + private: + CalendarView *mMainView; + + int mCurrentAgendaView; + KOAgendaView *mAgendaView; + KOListView *mListView; + KOMonthView *mMonthView; + KOTodoView *mTodoView; + KOWhatsNextView *mWhatsNextView; + KOJournalView *mJournalView; + KOTimeSpanView *mTimeSpanView; + + KOrg::BaseView *mCurrentView; // currently active event view + + int mAgendaViewMode; + bool mFlagShowNextxDays; + +}; + +#endif diff --git a/korganizer/koviewmanager.moc b/korganizer/koviewmanager.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/koviewmanager.moc diff --git a/korganizer/kowhatsnextview.cpp b/korganizer/kowhatsnextview.cpp new file mode 100644 index 0000000..ffaea37 --- a/dev/null +++ b/korganizer/kowhatsnextview.cpp @@ -0,0 +1,650 @@ +/* + 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. +*/ + +#include <qlayout.h> +#include <qtextbrowser.h> +#include <qtextcodec.h> +#include <qfileinfo.h> +#include <qlabel.h> + +#include <qapplication.h> + +#include <kglobal.h> +#include <klocale.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <kmessagebox.h> + +#include <libkcal/calendar.h> + +#ifndef KORG_NOPRINTER +#include "calprinter.h" +#endif +#include "koglobals.h" +#include "koprefs.h" +#include "koeventviewerdialog.h" + +#include "kowhatsnextview.h" +using namespace KOrg; +#include "kowhatsnextview.moc" + +void WhatsNextTextBrowser::setSource(const QString& n) +{ + + if (n.startsWith("event:")) { + emit showIncidence(n); + return; + } else if (n.startsWith("todo:")) { + emit showIncidence(n); + return; + } else { + QTextBrowser::setSource(n); + } +} + +KOWhatsNextView::KOWhatsNextView(Calendar *calendar, QWidget *parent, + const char *name) + : KOrg::BaseView(calendar, parent, name) +{ + // mDateLabel = + // new QLabel(KGlobal::locale()->formatDate(QDate::currentDate()),this); + // mDateLabel->setMargin(2); + // mDateLabel->setAlignment(AlignCenter); + setFont( KOPrefs::instance()->mWhatsNextFont ); + mView = new WhatsNextTextBrowser(this); + connect(mView,SIGNAL(showIncidence(const QString &)),SLOT(showIncidence(const QString &))); + + mEventViewer = 0; + + QBoxLayout *topLayout = new QVBoxLayout(this); + // topLayout->addWidget(mDateLabel); + topLayout->addWidget(mView); +} + +KOWhatsNextView::~KOWhatsNextView() +{ +} + +int KOWhatsNextView::maxDatesHint() +{ + return 0; +} + +int KOWhatsNextView::currentDateCount() +{ + return 0; +} + +QPtrList<Incidence> KOWhatsNextView::selectedIncidences() +{ + QPtrList<Incidence> eventList; + + return eventList; +} + + +void KOWhatsNextView::printPreview(CalPrinter *calPrinter, const QDate &fd, + const QDate &td) +{ +#ifndef KORG_NOPRINTER + calPrinter->preview(CalPrinter::Day, fd, td); +#endif +} +void KOWhatsNextView::updateConfig() +{ + setFont( KOPrefs::instance()->mWhatsNextFont ); + updateView(); + +} +void KOWhatsNextView::updateView() +{ + + // mDateLabel->setText(KGlobal::locale()->formatDate(QDate::currentDate())); + KIconLoader kil("korganizer"); + QString ipath;// = new QString(); + // kil.loadIcon("korganizer",KIcon::NoGroup,32,KIcon::DefaultState,&ipath); + //<big><big><strong>" + date + "</strong></big></big>\n"; + mText = "<table width=\"100%\">\n"; + //mText += "<tr bgcolor=\"#3679AD\"><td><h2>"; +#ifdef DESKTOP_VERSION + mText += "<tr bgcolor=\"#5699CD\"><td align=\"center\"><h1>"; +#else + mText += "<tr bgcolor=\"#5699CD\"><td align=\"center\"><h2>"; +#endif + // mText += "<img src=\""; + // mText += ipath; + // mText += "\">"; + mEventDate = QDate::currentDate(); +#ifdef DESKTOP_VERSION + mText += "<font color=\"#FFFFFF\"> <em>" + KGlobal::locale()->formatDate( mEventDate , false )+"</em></font></h1>"; +#else + mText += "<font color=\"#FFFFFF\"> <em>" + KGlobal::locale()->formatDate( mEventDate , false )+"</em></font></h2>"; +#endif + mText += "</td></tr>\n<tr bgcolor=\"#EAF8FA\"><td>"; + int iii; + mTodos.clear(); + QPtrList<Event> events; + QPtrList<Todo> todos = calendar()->todos(); + Todo * todo; + //mText += "<h2>" + i18n("Events: ") + "</h2>\n"; + int daysToShow = KOPrefs::instance()->mWhatsNextDays ; + bool itemAdded = false; + for ( iii = 0; iii < daysToShow; ++iii ) { + QString date; + itemAdded = false; + events = calendar()->events( mEventDate, true ); + + if ( iii == 0 ) { // today !!! + todo = todos.first(); + while(todo) { + if ( !todo->isCompleted() &&todo->hasDueDate() && todo->dtDue().date() < mEventDate ) { + if ( ! itemAdded ) { + appendDay ( iii, mEventDate ); + itemAdded = true; + + } + appendEvent(todo); + } + todo = todos.next(); + } + } + + + if (events.count() > 0) { + // mText += "<p></p>"; + // kil.loadIcon("month",KIcon::NoGroup,22,KIcon::DefaultState,&ipath); + // mText += "<h2>"; + //mText += " <img src=\""; + //mText += ipath; + //mText += "\">"; + if ( ! itemAdded ) { + appendDay ( iii, mEventDate ); + itemAdded = true; + + } + Event *ev = events.first(); + while(ev) { + //qDebug("+++++event append %s", ev->summary().latin1()); + if ( true /*!ev->recurrence()->doesRecur() || ev->recursOn( mEventDate)*/) { + appendEvent(ev, false , iii!= 0 ); + } + ev = events.next(); + } + + //mText += "</table>\n"; + } + + todo = todos.first(); + while(todo) { + if ( !todo->isCompleted() &&todo->hasDueDate() && todo->dtDue().date() == mEventDate ) { + if ( ! itemAdded ) { + appendDay ( iii, mEventDate ); + itemAdded = true; + } + appendEvent(todo); + } + todo = todos.next(); + } + if ( !itemAdded && iii == 0 ) { + // appendDay ( iii, mEventDate ); + //mText += "<table>"; + // mText += "<b><font color=\"#000080\"><em>"+i18n("No event, nothing to do.") +"</em></font></b>\n"; + mText += "<h3 align=\"center\"><font color=\"#008000\"><em>"+i18n("No event, nothing to do. ") +"</em></font></h3>\n"; + //mText +="</table>"; + } + if ( itemAdded ) + mText += "</table>\n"; + mEventDate = mEventDate.addDays( 1 ); + } + + int topmostPrios = KOPrefs::instance()->mWhatsNextPrios; + if (todos.count() > 0 && topmostPrios > 0 ) { + // kil.loadIcon("todo",KIcon::NoGroup,22,KIcon::DefaultState,&ipath); + // mText += "<h2>"; + //<img src=\""; + // mText += ipath; + // mText += "\">"; + // mText += i18n("Overdue To-Do:") + "</h2>\n"; + + //mText += "<ul>\n"; + bool gotone = false; + int priority = 1; + int priosFound = 0; +#ifdef DESKTOP_VERSION + mText +="<p></p>"; +#endif + + mText +="<big><big><strong><em><font color=\"#000080\">" + i18n("Incomplete Todo:") + "</font></em></strong></big></big>\n"; + mText += "<ul>\n"; + while (!gotone && priority<6) { + todo = todos.first(); + while(todo) { + if (!todo->isCompleted() && (todo->priority() == priority) ) { + if ( appendTodo(todo) ) + gotone = true; + } + todo = todos.next(); + } + if ( gotone ) { + gotone = false; + ++priosFound; + if ( priosFound == topmostPrios ) + break; + } + priority++; + // kdDebug() << "adding the todos..." << endl; + } + mText += "</ul>\n"; + } + + int replys = 0; + events = calendar()->events(QDate::currentDate(), QDate(2975,12,6)); + if (events.count() > 0) { + Event *ev = events.first(); + while(ev) { + Attendee *me = ev->attendeeByMails(KOPrefs::instance()->mAdditionalMails,KOPrefs::instance()->email()); + if (me!=0) { + if (me->status()==Attendee::NeedsAction && me->RSVP()) { + if (replys == 0) { + mText += "<p></p>"; + // kil.loadIcon("reply",KIcon::NoGroup,22,KIcon::DefaultState,&ipath); + mText += "<h2>"; + //<img src=\""; + // mText += ipath; + // mText += "\">"; + mText += i18n("Events and To-Dos that need a reply:") + "</h2>\n"; + mText += "<table>\n"; + } + replys++; + appendEvent(ev,true); + } + } + ev = events.next(); + } + } + todos = calendar()->todos(); + if (todos.count() > 0) { + Todo *to = todos.first(); + while(to) { + Attendee *me = to->attendeeByMails(KOPrefs::instance()->mAdditionalMails,KOPrefs::instance()->email()); + if (me!=0) { + if (me->status()==Attendee::NeedsAction && me->RSVP()) { + if (replys == 0) { + mText += "<p></p>"; + // kil.loadIcon("reply",KIcon::NoGroup,22,KIcon::DefaultState,&ipath); + mText += "<h2>"; + //<img src=\""; + // mText += ipath; + // mText += "\">"; + mText += i18n("Events and To-Dos that need a reply:") + "</h2>\n"; + mText += "<table>\n"; + } + replys++; + appendEvent(to); + } + } + kdDebug () << "check for todo-replys..." << endl; + to = todos.next(); + } + } + if (replys > 0 ) mText += "</table>\n"; + + + mText += "</td></tr>\n</table>\n"; + + kdDebug() << "KOWhatsNextView::updateView: text: " << mText << endl; + mView->setText(mText); + mView->setFocus(); + + // QPixmap bPix = SmallIcon( "back" ); + // qDebug("xxxxxxxxxxxxxxxxxxxxx "); + // QWidget* test = new QWidget(); + // test->setBackgroundMode(FixedPixmap ); + // test->setBackgroundPixmap ( bPix ); + // test->resize( 300, 400 ); + // test->show(); + // mView->setBackgroundMode(FixedPixmap ); + // mView->setBackgroundPixmap ( bPix ); +} + +void KOWhatsNextView::appendDay( int i, QDate eventDate ) +{ + QString date; + QString day = KGlobal::locale()->formatDate( eventDate , KOPrefs::instance()->mShortDateInViewer); + if ( ! KOPrefs::instance()->mShortDateInViewer && QApplication::desktop()->width() < 320 ) { + if ( i == 0 ) { + mText += "<table>\n"; + return;//date = "<em><font color=\"#008000\"><em>" + day+"</font></em>"; + } + else if ( i == 1 ) + date = "<em><font color=\"#000080\">" + day + "</font></em>" ; + else date = "<em><font color=\"#000080\">" + day + "</font></em>"; + //mText += "<h2>" + date + "</h2>\n"; + mText += "<big><big><strong>" + date + "</strong></big></big>\n"; + mText += "<table>\n"; + + + + } else { + if ( i == 0 ) { + mText += "<table>\n"; + return;// date = "<font color=\"#008000\"><em>" +i18n("Today: ") +"</em>" + day+"</font>"; + } + +#ifdef DESKTOP_VERSION + else if ( i == 1 ) { + date = "<h2><em><font color=\"#000080\">" + i18n("Tomorrow: ") + day +"</font></em></h2>" ; + } + else date = "<h2><em><font color=\"#000080\">" + i18n("In %1 days: ").arg( i ) +day + "</font></em></h2>"; +#else + else if ( i == 1 ) { + date = "<em><font color=\"#000080\">" + i18n("Tomorrow: ") + day +"</font></em>" ; + } + else date = "<em><font color=\"#000080\">" + i18n("In %1 days: ").arg( i ) +day + "</font></em>"; + +#endif + //mText += "<h2>" + date + "</h2>\n"; + mText += "<big><big><strong>" + date + "</strong></big></big>\n"; + mText += "<table>\n"; + } +} + + +void KOWhatsNextView::showDates(const QDate &, const QDate &) +{ + updateView(); +} + +void KOWhatsNextView::showEvents(QPtrList<Event>) +{ +} + +void KOWhatsNextView::changeEventDisplay(Event *, int action) +{ + switch(action) { + case KOGlobals::EVENTADDED: + updateView(); + break; + case KOGlobals::EVENTEDITED: + updateView(); + break; + case KOGlobals::EVENTDELETED: + updateView(); + break; + default: + updateView(); + kdDebug() << "KOWhatsNextView::changeEventDisplay(): Illegal action " << action << endl; + } +} + +void KOWhatsNextView::appendEvent(Incidence *ev, bool reply, bool notRed ) +{ + if ( !KOPrefs::instance()->mShowSyncEvents && ev->uid().left(21) == QString("last-syncEvent-device") ) + return; + QDateTime cdt = QDateTime::currentDateTime(); + mText += "<tr><td><b>"; + if (ev->type()=="Event") { + + if (!ev->doesFloat()) { + Event *event = static_cast<Event *>(ev); + QDateTime st,end; + if ( event->recurrence()->doesRecur() ) { + QDate recDate= mEventDate; + int days = event->dtStart().date().daysTo (event->dtEnd().date() ); + while ( ! event->recursOn( recDate ) ) { + recDate = recDate.addDays( -1 ); + + } + st = QDateTime ( recDate, event->dtStart().time() ); + end = QDateTime ( recDate.addDays( days ), event->dtEnd().time() ); + } + else { + st = event->dtStart(); + end = event->dtEnd(); + } + + if (reply) mText += "on " + event->dtStartDateStr() + ": "; + QString dateText; + // qDebug("%s %s %s %s ", mEventDate.toString().latin1(),event->summary().latin1(), st .toString().latin1(),end.toString().latin1() ); + if ( st.date() < mEventDate ) + dateText = "++:++-"; + else + dateText = event->dtStartTimeStr() + "-"; + if ( end.date() > mEventDate ) + dateText += "++:++"; + else + dateText += event->dtEndTimeStr(); + if ( notRed ) + mText += dateText; + else { + if ( end < cdt ) + mText += "<font color=\"#F00000\">" + dateText + "</font>"; + else if ( st < cdt ) + mText += "<font color=\"#008000\">" + dateText + "</font>"; + else + mText += dateText; + } + + } else { + mText += i18n("Allday:"); + + } + } else { + mTodos.append( ev ); + mText += i18n("ToDo:"); + if ( ((Todo*)ev)->dtDue().date() < QDate::currentDate() ) { + // mText +="<font color=\"#F00000\">" + i18n("O-due!") + "</font>"; + QString dfs = KGlobal::locale()->dateFormatShort(); + KGlobal::locale()->setIntDateFormat( 3 ); + KGlobal::locale()->setDateFormatShort("%d.%b"); + mText +="<font color=\"#F00000\">" + KGlobal::locale()->formatDate(((Todo*)ev)->dtDue().date(), true) + "</font>"; + + KGlobal::locale()->setDateFormatShort(dfs); + KGlobal::locale()->setIntDateFormat( KOPrefs::instance()->mPreferredDate ); + } else { + if (!ev->doesFloat() ) + if( ( (Todo*)ev)->dtDue() < cdt ) { + mText +="<font color=\"#F00000\">" + ((Todo*)ev)->dtDueTimeStr() + "</font>"; + + + } else + mText +=((Todo*)ev)->dtDueTimeStr(); + mTodos.append( ev ); + } + } + mText += "</b></td><td>"; + bool needClose = false; + if ( ev->cancelled() ) { + mText += "<font color=\"#F00000\">[c"; + needClose =true; + + } + if ( ev->isAlarmEnabled() ) { + if ( !needClose) + mText +="["; + mText += "a"; + needClose =true; + + } + if ( ev->description().length() > 0 ) { + if ( !needClose) + mText +="["; + mText += "i"; + needClose =true; + } + if ( ev->recurrence()->doesRecur() ) { + if ( !needClose) + mText +="["; + mText += "r"; + needClose =true; + } + if ( needClose ) { + mText += "] "; + } + if ( ev->cancelled() ) + mText += "</font>"; + mText += "<a "; + if (ev->type()=="Event") mText += "href=\"event:"; + if (ev->type()=="Todo") mText += "href=\"todo:"; + mText += ev->uid() + "\">"; + if ( ev->summary().length() > 0 ) + mText += ev->summary(); + else + mText += i18n("-no summary-"); + mText += "</a>"; + if ( KOPrefs::instance()->mWNViewShowLocation ) + if ( !ev->location().isEmpty() ) + mText += " ("+ev->location() +")"; + if ( ev->relatedTo() && KOPrefs::instance()->mWNViewShowsParents) + mText += " ["+ev->relatedTo()->summary() +"]"; + mText += "</td></tr>\n"; +} + +bool KOWhatsNextView::appendTodo(Incidence *ev, QString ind , bool isSub ) +{ + if ( mTodos.find( ev ) != mTodos.end() ) return false; + + mTodos.append( ev ); + if ( !isSub ) + mText += "<p>"; + else + mText += "<li>"; + mText += "[" +QString::number(ev->priority()) + "/" + QString::number(((Todo*)ev)->percentComplete())+"%] "; + + + mText += ind; + bool needClose = false; + if ( ev->cancelled() ) { + mText += "<font color=\"#F00000\">[c"; + needClose =true; + + } + if ( ev->isAlarmEnabled() ) { + if ( !needClose) + mText +="["; + mText += "a"; + needClose =true; + + } + + if ( ev->description().length() > 0 ) { + if ( !needClose) + mText +="["; + mText += "i"; + needClose =true; + } + // if ( ev->recurrence()->doesRecur() ) { + // if ( !needClose) + // mText +="("; + // mText += "r"; + // needClose =true; + // } + if ( needClose ) + mText += "] "; + if ( ev->cancelled() ) + mText += "</font>"; + mText += "<a href=\"todo:" + ev->uid() + "\">"; + mText += ev->summary(); + mText += "</a>"; + if ( ((Todo*)ev)->hasDueDate () ) { + QString year = ""; + int ye = ((Todo*)ev)->dtDue().date().year(); + if ( QDateTime::currentDateTime().date().year() != ye ) + year = QString::number( ye ); + QString dfs = KGlobal::locale()->dateFormatShort(); + KGlobal::locale()->setIntDateFormat( 3 ); + KGlobal::locale()->setDateFormatShort("%d.%b"); + mText +="<font color=\"#00A000\"> [" + KGlobal::locale()->formatDate(((Todo*)ev)->dtDue().date(), true) + "."+ year +"]</font>"; + + KGlobal::locale()->setDateFormatShort(dfs); + KGlobal::locale()->setIntDateFormat( KOPrefs::instance()->mPreferredDate ); + } + if ( KOPrefs::instance()->mWNViewShowLocation ) + if ( !ev->location().isEmpty() ) + mText += " ("+ev->location() +")"; + if ( !isSub ) { + if ( ((Todo*)ev)->relatedTo()&& KOPrefs::instance()->mWNViewShowsParents) + mText += " ["+ev->relatedTo()->summary() +"]"; + mText += "</p>\n"; + } + else { + ind += "-"; + mText += "</li>\n"; + } + QPtrList<Incidence> Relations = ev->relations(); + Incidence *to; + for (to=Relations.first();to;to=Relations.next()) { + if (!((Todo*)to)->isCompleted()) + appendTodo( to, ind , true ); + } + + return true; +} + +/* + void KOWhatsNextView::createEventViewer() + { + if (!mEventViewer) { + + mEventViewer = new KOEventViewerDialog(this); + } + } +*/ +void KOWhatsNextView::setEventViewer(KOEventViewerDialog* v ) +{ + if ( mEventViewer ) + delete mEventViewer; + mEventViewer = v; +} + +// TODO: Create this function in CalendarView and remove it from here +void KOWhatsNextView::showIncidence(const QString &uid) +{ + if ( !mEventViewer ) { + qDebug("KOWhatsNextView::showIncidence::sorry, no event viewer set "); + return; + } + //kdDebug() << "KOWhatsNextView::showIncidence(): " << uid << endl; + //qDebug("KOWhatsNextView::showIncidence %s ", uid.latin1()); + if (uid.startsWith("event:")) { +#ifdef DESKTOP_VERSION + Event *event = calendar()->event(uid.mid(8)); +#else + Event *event = calendar()->event(uid.mid(6)); +#endif + //qDebug("event %d uid %s ", event, uid.mid(6).latin1()); + if (!event) return; + //createEventViewer(); + mEventViewer->setEvent(event); + } else if (uid.startsWith("todo:")) { +#ifdef DESKTOP_VERSION + Todo *todo = calendar()->todo(uid.mid(7)); +#else + Todo *todo = calendar()->todo(uid.mid(5)); +#endif + if (!todo) return; + //createEventViewer(); + mEventViewer->setTodo(todo); + } else { + return; + + } + mEventViewer->showMe(); + mEventViewer->raise(); +} diff --git a/korganizer/kowhatsnextview.h b/korganizer/kowhatsnextview.h new file mode 100644 index 0000000..fff769a --- a/dev/null +++ b/korganizer/kowhatsnextview.h @@ -0,0 +1,91 @@ +/* + 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. +*/ +#ifndef KOWHATSNEXTVIEW_H +#define KOWHATSNEXTVIEW_H + +#include <qtextbrowser.h> + +#include <korganizer/baseview.h> + +class QListView; +class QLabel; + +class KOEventViewerDialog; + +class WhatsNextTextBrowser : public QTextBrowser { + Q_OBJECT + public: + WhatsNextTextBrowser(QWidget *parent) : QTextBrowser(parent) {} + + void setSource(const QString &); + + signals: + void showIncidence(const QString &uid); +}; + + +/** + This class provides a view of the next events and todos +*/ +class KOWhatsNextView : public KOrg::BaseView +{ + Q_OBJECT + public: + KOWhatsNextView(Calendar *calendar, QWidget *parent = 0, + const char *name = 0); + ~KOWhatsNextView(); + + virtual int maxDatesHint(); + virtual int currentDateCount(); + void setEventViewer(KOEventViewerDialog* v ); + virtual QPtrList<Incidence> selectedIncidences(); + DateList selectedDates() + {DateList q; + return q;} + virtual void printPreview(CalPrinter *calPrinter, + const QDate &, const QDate &); + + public slots: + virtual void updateView(); + virtual void showDates(const QDate &start, const QDate &end); + virtual void showEvents(QPtrList<Event> eventList); + void updateConfig(); + void changeEventDisplay(Event *, int); + + protected: + void appendEvent(Incidence *, bool reply=false, bool notRed = true); + bool appendTodo(Incidence *, QString ind = "", bool isSub = false ); + void appendDay( int i, QDate date ); + QDate mEventDate; + + private slots: + void showIncidence(const QString &); + + private: + //void createEventViewer(); + + QTextBrowser *mView; + QString mText; + // QLabel *mDateLabel; + KOEventViewerDialog *mEventViewer; + + QValueList<Incidence *> mTodos; +}; + +#endif diff --git a/korganizer/kowhatsnextview.moc b/korganizer/kowhatsnextview.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/kowhatsnextview.moc diff --git a/korganizer/kprefsdialog.moc b/korganizer/kprefsdialog.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/kprefsdialog.moc diff --git a/korganizer/ktimeedit.cpp b/korganizer/ktimeedit.cpp new file mode 100644 index 0000000..f9720f6 --- a/dev/null +++ b/korganizer/ktimeedit.cpp @@ -0,0 +1,528 @@ +/* + This file is part of KOrganizer. + Copyright (c) 1999 Preston Brown, Ian Dawes + + 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. +*/ + +#include <qkeycode.h> +#include <qcombobox.h> +#include <qdatetime.h> +#include <qlineedit.h> +#include <qapplication.h> + +#include <kmessagebox.h> +#include <kglobal.h> +#include <kdebug.h> +#include <klocale.h> + +#include "ktimeedit.h" +#include "koprefs.h" +#include <qvalidator.h> +#include "ktimeedit.moc" + +// Validator for a time value with only hours and minutes (no seconds) +// Mostly locale aware. Author: David Faure <faure@kde.org> +class KOTimeValidator : public QValidator +{ +public: + KOTimeValidator(QWidget* parent, const char* name=0) : QValidator(parent, name) {} + + virtual State validate(QString& str, int& /*cursorPos*/) const + { + return Acceptable; + bool ok = false; + // TODO use KLocale::WithoutSeconds in HEAD + /*QTime time =*/ KGlobal::locale()->readTime(str, &ok); + if ( ok ) + return Acceptable; + // readTime doesn't help knowing when the string is "Intermediate". + int length = str.length(); + if ( !str ) // empty string? + return Invalid; // there should always be a ':' in it, right? + // HACK. Not fully locale aware etc. (esp. the separator is '.' in sv_SE...) + QChar sep = ':'; + // I want to allow "HH:", ":MM" and ":" to make editing easier + if ( str[0] == sep ) + { + if ( length == 1 ) // just ":" + return Intermediate; + QString minutes = str.mid(1); + int m = minutes.toInt(&ok); + if ( ok && m >= 0 && m < 60 ) + return Intermediate; + } else if ( str.at(str.length()-1) == sep ) + { + QString hours = str.left(length-1); + int h = hours.toInt(&ok); + if ( ok && h >= 0 && h < 24 ) + return Intermediate; + } + return Invalid; + } +}; + +// KTimeWidget/QTimeEdit provide nicer editing, but don't provide a combobox. +// Difficult to get all in one... +// But Qt-3.2 will offer QLineEdit::setMask, so a "99:99" mask would help. +KOTimeEdit::KOTimeEdit(QWidget *parent, QTime qt, const char *name) + : QComboBox(TRUE, parent, name) +{ + setInsertionPolicy(NoInsertion); + setValidator( new KOTimeValidator( this ) ); + mFlagKeyPressed = false; + + if ( QApplication::desktop()->width() < 650 ) + setSizeLimit ( 6 ); + mTime = qt; + +// mNoTimeString = i18n("No Time"); +// insertItem( mNoTimeString ); + + // Fill combo box with selection of times in localized format. + QTime timeEntry(0,0,0); + do { + insertItem(KGlobal::locale()->formatTime(timeEntry)); + timeEntry = timeEntry.addSecs(60*15); + } while (!timeEntry.isNull()); + // Add end of day. + insertItem( KGlobal::locale()->formatTime( QTime( 23, 59, 59 ) ) ); + + updateText(); + setFocusPolicy(QWidget::StrongFocus); + + connect(this, SIGNAL(activated(int)), this, SLOT(activ(int))); + connect(this, SIGNAL(highlighted(int)), this, SLOT(hilit(int))); + connect(this,SIGNAL(textChanged(const QString&)),this,SLOT(changedText())); + QFontMetrics fm ( font() ); + QString timeString = "24:00"; + if ( KOPrefs::instance()->mPreferredTime == 1 ) + timeString = "02:00pm"; + int addSpace = 32; + if ( QApplication::desktop()->width() > 320 ) + timeString += ":00"; + setFixedWidth(fm.width( timeString ) + 32 ); + + // Highlight Background and Textcolor change from default + QPalette palette = QWidget::palette(); + unsigned char red, green, blue; + red = palette.color( QPalette::Normal , QColorGroup::Background ).red() - 10; + green = palette.color( QPalette::Normal , QColorGroup::Background ).green() - 10; + blue = palette.color( QPalette::Normal , QColorGroup::Background ).blue() - 10; + palette.setColor( QColorGroup::Highlight, QColor(red,green,blue) ); + palette.setColor( QColorGroup::HighlightedText, palette.color( QPalette::Normal , QColorGroup::Foreground ) ); + setPalette( palette ); +} + +KOTimeEdit::~KOTimeEdit() +{ +} + +bool KOTimeEdit::hasTime() const +{ + // Can't happen + if ( currentText().isEmpty() ) return false; + //if ( currentText() == mNoTimeString ) return false; + + return true; // always +} + +QTime KOTimeEdit::getTime() const +{ + //kdDebug(5850) << "KOTimeEdit::getTime(), currentText() = " << currentText() << endl; + // TODO use KLocale::WithoutSeconds in HEAD + QTime time = KGlobal::locale()->readTime(currentText()); + // kdDebug(5850) << "KOTimeEdit::getTime(): " << time.toString() << endl; + return time; +} +/* +QSizePolicy KOTimeEdit::sizePolicy() const +{ + // Set size policy to Fixed, because edit cannot contain more text than the + // string representing the time. It doesn't make sense to provide more space. + QSizePolicy sizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed); + + return sizePolicy; +} +*/ +void KOTimeEdit::setTime(QTime newTime) +{ + if ( mTime != newTime ) + { + kdDebug(5850) << "KOTimeEdit::setTime(): " << newTime.toString() << endl; + + mTime = newTime; + updateText(); + } + +} + +void KOTimeEdit::activ(int i) +{ + // The last entry, 23:59, is a special case + if( i == count() - 1 ) + mTime = QTime( 23, 59, 0 ); + else + mTime = QTime(0,0,0).addSecs(i*15*60); + emit timeChanged(mTime); +} + +void KOTimeEdit::hilit(int ) +{ + // we don't currently need to do anything here. +} + +void KOTimeEdit::addTime(QTime qt, bool update) +{ + // Calculate the new time. + //qDebug("add h %d min %d ", qt.hour(),qt.minute() ); + mTime = mTime.addSecs(qt.minute()*60+qt.hour()*3600); + // if ( update ) + updateText(); + emit timeChanged(mTime); +} + +void KOTimeEdit::subTime(QTime qt, bool update) +{ + int h, m; + //qDebug("sub h %d min %d ", qt.hour(),qt.minute() ); + + mTime = mTime.addSecs(-(qt.minute()*60+qt.hour()*3600)); + // store the newly calculated time. + // mTime.setHMS(h, m, 0); + //if ( update ) + updateText(); + emit timeChanged(mTime); +} + +// void KOTimeEdit::mouseReleaseEvent ( QMouseEvent * ) +// { +// qDebug("mouseReleaseEvent ( QMouseEvent * ) "); +// } + +// void KOTimeEdit::focusInEvent ( QFocusEvent * ) +// { +// qDebug("focusInEvent ( QFocusEvent * ) "); +// } + +void KOTimeEdit::keyReleaseEvent(QKeyEvent *e) +{ + if ( !e->isAutoRepeat() ) { + mFlagKeyPressed = false; + } + +} +void KOTimeEdit::setSelect( int from, int to ) +{ + if ( KOPrefs::instance()->mHightlightDateTimeEdit) + lineEdit()->setSelection( from , to ); +} + + +void KOTimeEdit::keyPressEvent(QKeyEvent *e) +{ + + qApp->processEvents(); + bool hour12Format = ( KOPrefs::instance()->mPreferredTime == 1 ); + int maxpos = hour12Format?7:5; + if ( e->isAutoRepeat() && !mFlagKeyPressed ) { + e->ignore(); + // qDebug(" ignore %d",e->isAutoRepeat() ); + return; + } + if (! e->isAutoRepeat() ) { + mFlagKeyPressed = true; + } + // Tap -> Focus Next Widget + if ( e->key() == Key_Tab ) { + QComboBox::keyPressEvent(e); + return; + } + + // save Text from QLineEdit and CursorPosition + QString text = lineEdit()->text(); + int cpos = lineEdit()->cursorPosition(); + // qDebug("cpos %d ", cpos); + + // Switch for arrows, backspace and escape + switch(e->key()) { + case Key_Escape: + lineEdit()->deselect(); + case Key_Tab: + QComboBox::keyPressEvent(e); + break; + case Key_Up: + if ( e->state () == Qt::ControlButton ) { + addTime(QTime(0,15,0), false ); + lineEdit()->setCursorPosition(3); + setSelect( 3 , 2 ); + } + else + if ( e->state () == Qt::ShiftButton ) { + addTime(QTime(1,0,0), false ); + lineEdit()->setCursorPosition(0); + setSelect( 0 , 2 ); + } + else + // switch time up, cursor location depend + switch (cpos) { + case 7: + case 6: + case 5: + if(!hour12Format) { + lineEdit()->setCursorPosition(cpos = 4); + } else { + addTime(QTime(12,0,0), false ); + setSelect ( 5 , 2 ); + break; + } + case 4: + addTime(QTime(0,1,0), false ); + setSelect ( cpos , 1 ); + break; + case 3: + addTime(QTime(0,10,0), false ); + setSelect ( cpos , 1 ); + break; + case 2: + lineEdit()->setCursorPosition(--cpos); + case 1: + case 0: + addTime(QTime(1,0,0), false ); + setSelect ( 0, 2 ); + break; + } + break; + case Key_Down: + if ( e->state () == Qt::ControlButton ) { + subTime(QTime(0,15,0), false ); + lineEdit()->setCursorPosition(3); + setSelect( 3 , 2 ); + } + else + if ( e->state () == Qt::ShiftButton ) { + subTime(QTime(1,0,0), false ); + lineEdit()->setCursorPosition(0); + setSelect( 0 , 2 ); + } + else + // switch time down, cursor location depend + switch (cpos) { + case 7: + case 6: + case 5: + if(!hour12Format) { + lineEdit()->setCursorPosition(cpos = 4); + } else { + subTime(QTime(12,0,0), false ); + setSelect ( 5 , 2 ); + break; + } + case 4: + subTime(QTime(0,1,0), false ); + setSelect ( cpos , 1 ); + break; + case 3: + subTime(QTime(0,10,0), false ); + setSelect ( cpos , 1 ); + break; + case 2: + lineEdit()->setCursorPosition(--cpos); + case 1: + case 0: + subTime(QTime(1,0,0), false ); + setSelect ( 0 , 2 ); + break; + } + break; + // set cursor to correct place + case Key_Left: + if ( cpos == 3 ) + --cpos; + if ( cpos > 0) { + lineEdit()->setCursorPosition(--cpos); + setSelect ( cpos , 1 ); + } + else + setSelect ( 0 , 1 ); + break; + // set cursor to correct place + case Key_Right: + if ( cpos == 1 ) + ++cpos; + if ( cpos < maxpos ) { + lineEdit()->setCursorPosition(++cpos); + setSelect ( cpos , 1 ); + } + break; + // rest + case Key_Prior: + subTime(QTime(1,0,0)); + break; + case Key_Next: + addTime(QTime(1,0,0)); + break; + case Key_Backspace: + if ( cpos > 0) { + if ( cpos == 3 ) + --cpos; + if ( cpos > 5) + cpos = 5; + text.at( cpos-1 ) = '0'; + lineEdit()->setText( text ); + lineEdit()->setCursorPosition(--cpos); + setSelect ( cpos , 1 ); + changedText(); + } + break; + } // switch arrows + + // if cursor at string end, alltext market and keyEvent don't ArrowLeft -> deselect and cpos + if( cpos > 4 && lineEdit()->markedText().length() == 5 && e->key() != Key_Left ) { + lineEdit()->deselect(); + cpos = 0; + lineEdit()->setCursorPosition(cpos); + setSelect(cpos , 1); + } + + if ( cpos == 2 ) { + lineEdit()->setCursorPosition(++cpos); + } + + // num keys when cursorPos preEnd + if ( cpos < 5 ) { + // switch another keys + switch(e->key()) { + case Key_Delete: + text.at( cpos ) = '0'; + lineEdit()->setText( text ); + lineEdit()->setCursorPosition(cpos); + setSelect ( cpos , 1 ); + changedText(); + break; + case Key_9: + case Key_8: + case Key_7: + case Key_6: + if ( !(cpos == 1 || cpos == 4) ) + return; + if ( cpos == 1 && text.at( 0 ) > '1') + text.at( 0 ) = '1'; + case Key_5: + case Key_4: + case Key_3: + if ( cpos < 1 ) + return; + if ( hour12Format && cpos == 1 ) + return; + case Key_2: + if ( hour12Format && cpos == 0 ) + return; + if ( cpos == 0 && text.at( 1 ) > '3') + text.at( 1 ) = '3'; + case Key_1: + case Key_0: + if ( hour12Format ) { + if ( e->key() == Key_0 && cpos == 1 && text.at( 0 ) == '0' ) + return; + if ( e->key() == Key_0 && cpos == 0 && text.at( 1 ) == '0' ) + text.at( 1 ) = '1'; + } + text.at( cpos ) = QChar ( e->key() ); + lineEdit()->setText( text ); + if ( cpos == 1 ) + ++cpos; + if ( cpos < 5) + lineEdit()->setCursorPosition(++cpos); + setSelect( cpos , 1 ); + changedText(); + break; + case Key_Home: + lineEdit()->setCursorPosition(0); + setSelect( cpos , 1 ); + break; + case Key_End: + lineEdit()->setCursorPosition(5); + lineEdit()->deselect(); + break; + default: +// QComboBox::keyPressEvent(e); + break; + } // switch num keys + } else if ( cpos == 5 ) {// if cpos < 5 + if ( hour12Format ) { + if ( e->key() == Key_A ) { + text.at( 5 ) = 'a'; + lineEdit()->setText( text ); + lineEdit()->setCursorPosition(5); + + } else if ( e->key() == Key_P ) { + text.at( 5 ) = 'p'; + lineEdit()->setText( text ); + lineEdit()->setCursorPosition(5); + + } + } + } + + +} + +void KOTimeEdit::updateText() +{ +// kdDebug(5850) << "KOTimeEdit::updateText() " << endl + QString s = KGlobal::locale()->formatTime(mTime); + // Set the text but without emitting signals, nor losing the cursor position + QLineEdit *line = lineEdit(); + line->blockSignals(true); + int pos = line->cursorPosition(); + // qDebug(" settext *%s* ", s.latin1()); + line->setText(s); + // line->setCursorPosition(pos); +// line->blockSignals(false); + +// kdDebug(5850) << "KOTimeEdit::updateText(): " << s << endl; + + if (!mTime.minute() % 15) { + setCurrentItem((mTime.hour()*4)+(mTime.minute()/15)); + } + line->setCursorPosition(pos); + line->blockSignals(false); + +} + +bool KOTimeEdit::inputIsValid() const +{ + int cursorPos = lineEdit()->cursorPosition(); + QString str = currentText(); + return validator()->validate( str, cursorPos ) == QValidator::Acceptable; +} + +void KOTimeEdit::changedText() +{ + //kdDebug(5850) << "KOTimeEdit::changedText()" << endl; + if ( inputIsValid() ) + { + int pos = lineEdit()->cursorPosition(); + mTime = getTime(); + // updateText(); + emit timeChanged(mTime); + lineEdit()->setCursorPosition(pos); + } +} diff --git a/korganizer/ktimeedit.h b/korganizer/ktimeedit.h new file mode 100644 index 0000000..7923070 --- a/dev/null +++ b/korganizer/ktimeedit.h @@ -0,0 +1,97 @@ +/* + This file is part of KOrganizer. + Copyright (c) 1999 Preston Brown, Ian Dawes + + 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 _KTIMEEDIT_H +#define _KTIMEEDIT_H + +#include <qevent.h> +#include <qkeycode.h> +#include <qstring.h> +#include <qdatetime.h> +#include <qcombobox.h> + +#include <kapplication.h> + +/** + This is a class that provides an easy, user friendly way to edit times. + up/down/ increase or decrease time, respectively. + + @short Provides a way to edit times in a user-friendly manner. + @author Preston Brown, Ian Dawes +*/ +class KOTimeEdit : public QComboBox +{ + Q_OBJECT + public: + /** constructs a new time edit. */ + KOTimeEdit(QWidget *parent=0, QTime qt=QTime(12,0), const char *name=0); + + virtual ~KOTimeEdit(); + + /** + Returns, if a time is selected. Can not return false anymore.... + */ + bool hasTime() const; + + /** returns the time that is currently set in the timeLineEdit. */ + QTime getTime() const; + + /** returns the prefered size policy of the KOTimeEdit */ + //QSizePolicy sizePolicy() const; + + /** return true if input is a valid time and false if not */ + bool inputIsValid() const; + + signals: + /** + Emitted every time the time displayed changes. "newt" is the new + time. + */ + void timeChanged(QTime newt); + + public slots: + /** used to set the time which is displayed to a specific value. */ + void setTime(QTime qt); + + protected slots: + void activ(int); + void hilit(int); + void changedText(); + + protected: + void keyPressEvent(QKeyEvent *qke); + void keyReleaseEvent(QKeyEvent *qke); + void setSelect ( int, int ); + bool mFlagKeyPressed; + void addTime(QTime qt, bool update = true ); + void subTime(QTime qt, bool update = true ); + // Update the lineedit text from mTime + void updateText(); + // void mouseReleaseEvent ( QMouseEvent * ) ; + //void focusInEvent ( QFocusEvent * ) ; + +private: + QTime mTime; // the widget's displayed time. + //QString mNoTimeString; +}; + +#endif diff --git a/korganizer/ktimeedit.moc b/korganizer/ktimeedit.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/ktimeedit.moc diff --git a/korganizer/lineview.cpp b/korganizer/lineview.cpp new file mode 100644 index 0000000..f1ff29f --- a/dev/null +++ b/korganizer/lineview.cpp @@ -0,0 +1,94 @@ +#include <qpainter.h> + +#include <kdebug.h> + +#include "koprefs.h" + +#include "lineview.h" +#include "lineview.moc" + +LineView::LineView( QWidget *parent, const char *name ) : + QScrollView( parent, name ) +{ + mPixelWidth = 1000; + + mLines.setAutoDelete( true ); + + resizeContents( mPixelWidth, contentsHeight() ); + + viewport()->setBackgroundColor(KOPrefs::instance()->mAgendaBgColor); +} + +LineView::~LineView() +{ +} + +int LineView::pixelWidth() +{ + return mPixelWidth; +} + +void LineView::addLine( int start, int end ) +{ + int count = mLines.count(); + + if( start < 0 ) start = 0; + if( end > mPixelWidth) end = mPixelWidth; + + kdDebug() << "LineView::addLine() col: " << count << " start: " << start + << " end: " << end << endl; + + mLines.append( new Line( count, start, end ) ); +} + +void LineView::clear() +{ + mLines.clear(); + update(); +} + +void LineView::drawContents(QPainter* p, int cx, int cy, int cw, int ch) +{ +// kdDebug() << "LineView::drawContents()" << endl; + + int mGridSpacingX = 10; + int mGridSpacingY = 20; + +#if 0 + // Draw vertical lines of grid + // kdDebug() << "drawContents cx: " << cx << " cy: " << cy << " cw: " << cw << " ch: " << ch << endl; + int x = ((int)(cx/mGridSpacingX))*mGridSpacingX; + while (x < cx + cw) { + p->drawLine(x,cy,x,cy+ch); + x+=mGridSpacingX; + } +#endif + + // Draw horizontal lines of grid + int y = ((int)(cy/mGridSpacingY))*mGridSpacingY + 10; + while (y < cy + ch) { +// kdDebug() << " y: " << y << endl; + p->drawLine(cx,y,cx+cw,y); + y+=mGridSpacingY; + } + + Line *line; + for( line = mLines.first(); line; line = mLines.next() ) { + int ctop = line->column * 20 + 10 - 5; + int cbottom = line->column * 20 + 10 + 5; + int s = line->start; + int e = line->end; +// kdDebug() << " LineView::drawContents(): ctop: " << ctop << " cbottom: " +// << cbottom << " s: " << s << " e: " << e << endl; + if ( ctop <= (cy+ch) && cbottom >= cy && + s <= (cx+cw) && e >= cx ) { + if ( s < cx ) s = cx; + if ( e > (cx+cw) ) e = cx+cw; + if ( ctop < cy ) ctop = cy; + if ( cbottom > (cy+ch) ) cbottom = cy+ch; +// kdDebug() << " drawContents(): ctop: " << ctop << " cbottom: " +// << cbottom << " s: " << s << " e: " << e << endl; + p->fillRect( s, ctop, e - s + 1, cbottom - ctop + 1, QBrush("red") ); + } + } +} diff --git a/korganizer/lineview.h b/korganizer/lineview.h new file mode 100644 index 0000000..aa34dbc --- a/dev/null +++ b/korganizer/lineview.h @@ -0,0 +1,36 @@ +#ifndef LINEVIEW_H +#define LINEVIEW_H + +#include <qscrollview.h> +#include <qptrlist.h> + +class LineView : public QScrollView +{ + Q_OBJECT + public: + LineView( QWidget *parent = 0, const char *name = 0 ); + virtual ~LineView(); + + int pixelWidth(); + + void addLine( int start, int end ); + + void clear(); + + protected: + void drawContents(QPainter* p, int cx, int cy, int cw, int ch); + + private: + struct Line { + Line( int c, int s, int e ) : column( c ), start( s ), end( e ) {} + int column; + int start; + int end; + }; + + QPtrList<Line> mLines; + int mPixelWidth; +}; + +#endif + diff --git a/korganizer/lineview.moc b/korganizer/lineview.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/lineview.moc diff --git a/korganizer/main.cpp b/korganizer/main.cpp new file mode 100644 index 0000000..6843595 --- a/dev/null +++ b/korganizer/main.cpp @@ -0,0 +1,107 @@ + + +#ifndef DESKTOP_VERSION +#include <qpe/qpeapplication.h> +#include <qpe/global.h> +#include <stdlib.h> +#else +#include <qapplication.h> +#include <qstring.h> +#include <qwindowsstyle.h> +#include <qplatinumstyle.h> +#include <qsgistyle.h> +#endif + +#include <qdir.h> +#include <kstandarddirs.h> +#include <kglobal.h> +#include <stdio.h> +#include "mainwindow.h" + +int main( int argc, char **argv ) +{ +#ifndef DESKTOP_VERSION + QPEApplication a( argc, argv ); + a.setKeepRunning (); +#else + QApplication a( argc, argv ); + QApplication::setStyle( new QPlatinumStyle ()); +#endif + bool exitHelp = false; + if ( argc > 1 ) { + QString command = argv[1]; + if ( command == "-help" ){ + printf("KO/Pi command line commands:\n"); + printf(" no command: Start KO/Pi in usual way\n"); + printf(" -help: This output\n"); + printf("Next Option: Open or Show after start:\n"); + printf(" -newTodo: New Todo dialog\n"); + printf(" -newEvent: New Event dialog\n"); + printf(" -showList: List view\n"); + printf(" -showDay: Day view\n"); + printf(" -showWWeek: Work Week view\n"); + printf(" -showWeek: Week view\n"); + printf(" -showTodo: Todo view\n"); + printf(" -showJournal: Journal view\n"); + printf(" -showKO: Next Days view\n"); + printf(" -showWNext: What's Next view\n"); + printf(" -showNextXView: Next X View\n"); + printf(" -new[Y] and -show[X] may be used togehther\n"); + printf(" KO/Pi is exiting now. Bye!\n"); + exitHelp = true; + } + } + if ( ! exitHelp ) { + KGlobal::setAppName( "korganizer" ); + + + QString fileName ; +#ifndef DESKTOP_VERSION + KStandardDirs::setAppDir( Global::applicationFileName( "korganizer", "" ) ); + fileName = getenv("QPEDIR"); + KGlobal::iconLoader()->setIconPath( fileName +"/pics/kdepim/korganizer/"); +#else + +#ifndef _WIN32_ + fileName = qApp->applicationDirPath () + "/kdepim/korganizer/"; +#else + fileName = qApp->applicationDirPath () + "\\kdepim\\korganizer\\"; +#endif + + KGlobal::iconLoader()->setIconPath(fileName); + + QString appdir = QDir::homeDirPath(); + //appdir = "C:\\"; + if ( appdir.right(1) == "\\" || appdir.right(1) == "/" ) + appdir += "korganizer"; + else + appdir += "/korganizer"; + KStandardDirs::setAppDir( QDir::convertSeparators( appdir )); + // qDebug(" %s ",KStandardDirs::appDir().latin1() ); +#endif + QDir app_dir; + if ( !app_dir.exists(KStandardDirs::appDir()) ) + app_dir.mkdir (KStandardDirs::appDir()); + MainWindow m; +#ifndef DESKTOP_VERSION + QObject::connect( &a, SIGNAL (appMessage ( const QCString &, const QByteArray & )),&m, SLOT(recieve( const QCString&, const QByteArray& ))); + a.showMainWidget(&m ); +#else + a.setMainWidget(&m ); + m.show(); + //m.resize( 800, 600 ); + QObject::connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit())); +#endif + if ( argc > 1 ) { + QCString command = argv[1]; + if ( argc > 2 ) + command += argv[2]; + qApp->processEvents(); + m.recieve(command, QByteArray() ); + + } + a.exec(); + + } + qDebug("KO: Bye! "); +} diff --git a/korganizer/mainwindow.cpp b/korganizer/mainwindow.cpp new file mode 100644 index 0000000..40f2cf4 --- a/dev/null +++ b/korganizer/mainwindow.cpp @@ -0,0 +1,1974 @@ +#include <stdlib.h> + +#include <qaction.h> +#include <qpopupmenu.h> +#include <qpainter.h> +#include <qwhatsthis.h> +#include <qmessagebox.h> +#include <qlineedit.h> +#include <qfile.h> +#include <qdir.h> +#include <qapp.h> +#include <qfileinfo.h> +#include <qlabel.h> +#include <qwmatrix.h> +#include <qtextbrowser.h> +#include <qtextstream.h> +#ifndef DESKTOP_VERSION +#include <qpe/global.h> +#include <qpe/qpemenubar.h> +#include <qpe/qpetoolbar.h> +#include <qpe/resource.h> +#include <qpe/qpeapplication.h> +#include <qtopia/alarmserver.h> +#include <qtopia/qcopenvelope_qws.h> +#else +#include <qmenubar.h> +#include <qtoolbar.h> +#include <qapplication.h> +//#include <resource.h> + +#endif +#include <libkcal/calendarlocal.h> +#include <libkcal/todo.h> +#include <libkdepim/ksyncprofile.h> +#include <libkdepim/kincidenceformatter.h> + +#include "calendarview.h" +#include "koviewmanager.h" +#include "datenavigator.h" +#include "koagendaview.h" +#include "koagenda.h" +#include "kodialogmanager.h" +#include "kdialogbase.h" +#include "kstandarddirs.h" +#include "koprefs.h" +#include "kfiledialog.h" +#include "koglobals.h" +#include "kglobal.h" +#include "klocale.h" +#include "kconfig.h" +#include "simplealarmclient.h" + +using namespace KCal; +#ifndef _WIN32_ +#include <unistd.h> +#endif +#include "mainwindow.h" + +int globalFlagBlockStartup; +MainWindow::MainWindow( QWidget *parent, const char *name, QString msg) : + QMainWindow( parent, name ) +{ + +#ifdef DESKTOP_VERSION + setFont( QFont("Arial"), 14 ); +#endif + + //QString confFile = KStandardDirs::appDir() + "config/korganizerrc"; + QString confFile = locateLocal("config","korganizerrc"); + QFileInfo finf ( confFile ); + bool showWarning = !finf.exists(); + setIcon(SmallIcon( "ko24" ) ); + mBlockAtStartup = true; + mFlagKeyPressed = false; + setCaption("KOrganizer/Pi"); + KOPrefs *p = KOPrefs::instance(); + // if ( QApplication::desktop()->height() > 480 ) { +// if ( p->mHourSize == 4 ) +// p->mHourSize = 6; +// } + if ( p->mHourSize > 18 ) + p->mHourSize = 18; + QMainWindow::ToolBarDock tbd; + if ( p->mToolBarHor ) { + if ( p->mToolBarUp ) + tbd = Bottom; + else + tbd = Top; + } + else { + if ( p->mToolBarUp ) + tbd = Right; + else + tbd = Left; + } + if ( KOPrefs::instance()->mUseAppColors ) + QApplication::setPalette( QPalette (KOPrefs::instance()->mAppColor1, KOPrefs::instance()->mAppColor2), true ); + globalFlagBlockStartup = 1; + iconToolBar = new QPEToolBar( this ); + addToolBar (iconToolBar , tbd ); + mBlockSaveFlag = false; + mCalendarModifiedFlag = false; + + QLabel* splash = new QLabel(i18n("KO/Pi is starting ... "), this ); + splash->setAlignment ( AlignCenter ); + setCentralWidget( splash ); +#ifndef DESKTOP_VERSION + showMaximized(); +#endif + //qDebug("Mainwidget x %d y %d w %d h %d", x(), y(), width(), height ()); + setDefaultPreferences(); + mCalendar = new CalendarLocal(); + mView = new CalendarView( mCalendar, this,"mCalendar " ); + mView->hide(); + //mView->resize(splash->size() ); + initActions(); +#ifndef DESKTOP_VERSION + iconToolBar->show(); + qApp->processEvents(); +#endif + //qDebug("Splashwidget x %d y %d w %d h %d", splash-> x(), splash->y(), splash->width(),splash-> height ()); + int vh = height() ; + int vw = width(); + //qDebug("Toolbar hei %d ",iconToolBar->height() ); + if ( iconToolBar->orientation () == Qt:: Horizontal ) { + vh -= iconToolBar->height(); + } else { + vw -= iconToolBar->height(); + } + //mView->setMaximumSize( splash->size() ); + //mView->resize( splash->size() ); + //qDebug("MainView x %d y %d w %d h %d", mView->x(),mView-> y(), mView->width(), mView->height ()); + mView->readSettings(); + bool oldOpened = false; + bool newFile = false; + if( !QFile::exists( defaultFileName() ) ) { + QFileInfo finfo ( defaultFileName() ); + QString oldFile = QDir::convertSeparators( QDir::homeDirPath()+"/Applications/korganizer/mycalendar.ics"); + qDebug("oldfile %s ", oldFile.latin1()); + QString message = "You are starting KO/Pi for the\nfirst time after updating to a\nversion >= 1.9.1. The location of the\ndefault calendar file has changed.\nA mycalendar.ics file was detected\nat the old location.\nThis file will be loaded now\nand stored at the new location!\n(Config file location has changed, too!)\nPlease read menu Help-What's New!\n"; + finfo.setFile( oldFile ); + if (finfo.exists() ) { + KMessageBox::information( this, message); + mView->openCalendar( oldFile ); + qApp->processEvents(); + } else { + oldFile = QDir::convertSeparators( QDir::homeDirPath()+"/korganizer/mycalendar.ics"); + finfo.setFile( oldFile ); + if (finfo.exists() ) { + KMessageBox::information( this, message); + mView->openCalendar( oldFile ); + qApp->processEvents(); + } + } + mView->saveCalendar( defaultFileName() ); + newFile = true; + } + + QTime neededSaveTime = QDateTime::currentDateTime().time(); + if ( ! oldOpened ) + mView->openCalendar( defaultFileName() ); + int msNeeded = neededSaveTime.msecsTo( QDateTime::currentDateTime().time() ); + qDebug("KO: Calendar loading time: %d ms",msNeeded ); + + if ( KOPrefs::instance()->mLanguageChanged ) { + KOPrefs::instance()->setCategoryDefaults(); + int count = mView->addCategories(); + KOPrefs::instance()->mLanguageChanged = false; + } + processIncidenceSelection( 0 ); + connect( mView, SIGNAL( incidenceSelected( Incidence * ) ), + SLOT( processIncidenceSelection( Incidence * ) ) ); + connect( mView, SIGNAL( modifiedChanged( bool ) ), + SLOT( slotModifiedChanged( bool ) ) ); + + + connect( &mSaveTimer, SIGNAL( timeout() ), SLOT( save() ) ); + mView->setModified( false ); + mBlockAtStartup = false; + mView->setModified( false ); + setCentralWidget( mView ); + globalFlagBlockStartup = 0; + mView->show(); + delete splash; + if ( newFile ) + mView->updateConfig(); + // qApp->processEvents(); + //qDebug("MainView x %d y %d w %d h %d", mView->x(),mView-> y(), mView->width(), mView->height ()); + fillSyncMenu(); + mView->viewManager()->agendaView()->setStartHour( KOPrefs::instance()->mDayBegins ); + if ( showWarning ) { + KMessageBox::information( this, + "You are starting KO/Pi for the first time.\nPlease read menu: Help-What's New,\nif you did an update!\nPlease choose your timezone in the \nConfigure Dialog TAB Time Zone!\nPlease choose your language\nin the TAB Locale!\nYou get the Configure Dialog\nvia Menu: Actions - Configure....\nClick OK to show the Configure Dialog!\n", "KO/Pi information"); + qApp->processEvents(); + mView->dialogManager()->showSyncOptions(); + } +} +MainWindow::~MainWindow() +{ + //qDebug("MainWindow::~MainWindow() "); + //save toolbar location + + delete mCalendar; + delete KOPrefs::instance(); + delete KIncidenceFormatter::instance(); + + +} +void MainWindow::closeEvent( QCloseEvent* ce ) +{ + + + + if ( ! KOPrefs::instance()->mAskForQuit ) { + saveOnClose(); + ce->accept(); + return; + + } + + switch( QMessageBox::information( this, "KO/Pi", + i18n("Do you really want\nto close KO/Pi?"), + i18n("Close"), i18n("No"), + 0, 0 ) ) { + case 0: + saveOnClose(); + ce->accept(); + break; + case 1: + ce->ignore(); + break; + case 2: + + default: + break; + } + + +} + +void MainWindow::recieve( const QCString& cmsg, const QByteArray& data ) +{ + QDataStream stream( data, IO_ReadOnly ); + // QMessageBox::about( this, "About KOrganizer/Pi", "*" +msg +"*" ); + //QString datamess; + //qDebug("message "); + qDebug("KO: QCOP message received: %s ", cmsg.data() ); + if ( cmsg == "-writeFile" ) { + // I made from the "-writeFile" an "-writeAlarm" + mView->viewManager()->showWhatsNextView(); + mCalendar->checkAlarmForIncidence( 0, true); + showMaximized(); + raise(); + return; + + } + if ( cmsg == "-writeFileSilent" ) { + // I made from the "-writeFile" an "-writeAlarm" + // mView->viewManager()->showWhatsNextView(); + mCalendar->checkAlarmForIncidence( 0, true); + //showMaximized(); + //raise(); + hide(); + return; + } + if ( cmsg == "-newCountdown" ) { + qDebug("newCountdown "); + + } + QString msg ; + QString allmsg = cmsg; + while ( allmsg.length() > 0 ) { + int nextC = allmsg.find( "-", 1 ); + if ( nextC == -1 ) { + msg = allmsg; + allmsg = ""; + } else{ + msg = allmsg.left( nextC ); + allmsg = allmsg.mid( nextC, allmsg.length()-nextC ); + } + //qDebug("msg: %s all: %s ", msg.latin1(), allmsg.latin1() ); + if ( msg == "-newEvent" ) { + mView->newEvent(); + } + if ( msg == "-newTodo" ) { + mView->newTodo(); + + } + if ( msg == "-showWN" ) { + mView->viewManager()->showWhatsNextView(); + } + if ( msg == "-showTodo" ) { + mView->viewManager()->showTodoView(); + } + if ( msg == "-showList" ) { + mView->viewManager()->showListView(); + } + else if ( msg == "-showDay" ) { + mView->viewManager()->showDayView(); + } + else if ( msg == "-showWWeek" ) { + mView->viewManager()->showWorkWeekView(); + } + else if ( msg == "-ringSync" ) { + multiSync( false ); + } + else if ( msg == "-showWeek" ) { + mView->viewManager()->showWeekView(); + } + else if ( msg == "-showTodo" ) { + mView->viewManager()->showTodoView(); + } + else if ( msg == "-showJournal" ) { + mView->dateNavigator()->selectDates( 1 ); + mView->dateNavigator()->selectToday(); + mView->viewManager()->showJournalView(); + } + else if ( msg == "-showKO" ) { + mView->viewManager()->showNextXView(); + } + else if ( msg == "-showWNext" || msg == "nextView()" ) { + mView->viewManager()->showWhatsNextView(); + } + else if ( msg == "-showNextXView" ) { + mView->viewManager()->showNextXView(); + } + + + } + + showMaximized(); + raise(); +} + +QPixmap MainWindow::loadPixmap( QString name ) +{ + return SmallIcon( name ); + +} +void MainWindow::initActions() +{ + //KOPrefs::instance()->mShowFullMenu + iconToolBar->clear(); + KOPrefs *p = KOPrefs::instance(); + //QPEMenuBar *menuBar1;// = new QPEMenuBar( iconToolBar ); + + QPopupMenu *viewMenu = new QPopupMenu( this ); + QPopupMenu *actionMenu = new QPopupMenu( this ); + QPopupMenu *importMenu = new QPopupMenu( this ); + + syncMenu = new QPopupMenu( this ); + configureAgendaMenu = new QPopupMenu( this ); + configureToolBarMenu = new QPopupMenu( this ); + QPopupMenu *helpMenu = new QPopupMenu( this ); + if ( KOPrefs::instance()->mShowFullMenu ) { + QMenuBar *menuBar1; + menuBar1 = menuBar(); + menuBar1->insertItem( i18n("File"), importMenu ); + menuBar1->insertItem( i18n("View"), viewMenu ); + menuBar1->insertItem( i18n("Actions"), actionMenu ); + menuBar1->insertItem( i18n("Synchronize"), syncMenu ); + menuBar1->insertItem( i18n("AgendaSize"),configureAgendaMenu ); + //menuBar1->insertItem( i18n("Toolbar"),configureToolBarMenu ); + menuBar1->insertItem( i18n("Help"), helpMenu ); + } else { + QPEMenuBar *menuBar1; + menuBar1 = new QPEMenuBar( iconToolBar ); + QPopupMenu *menuBar = new QPopupMenu( this ); + menuBar1->insertItem( i18n("ME"), menuBar); + menuBar->insertItem( i18n("File"), importMenu ); + menuBar->insertItem( i18n("View"), viewMenu ); + menuBar->insertItem( i18n("Actions"), actionMenu ); + menuBar->insertItem( i18n("Synchronize"), syncMenu ); + menuBar->insertItem( i18n("AgendaSize"),configureAgendaMenu ); + menuBar->insertItem( i18n("Toolbar"),configureToolBarMenu ); + menuBar->insertItem( i18n("Help"), helpMenu ); + //menuBar1->setMaximumWidth( menuBar1->sizeHint().width() ); + menuBar1->setMaximumSize( menuBar1->sizeHint( )); + } + connect ( syncMenu, SIGNAL( activated ( int ) ), this, SLOT (slotSyncMenu( int ) ) ); + // ****************** + QAction *action; + QIconSet icon; + // QPopupMenu *configureMenu= new QPopupMenu( menuBar ); + configureToolBarMenu->setCheckable( true ); + + QString pathString = ""; + if ( !p->mToolBarMiniIcons ) { + if ( QApplication::desktop()->width() < 480 ) + pathString += "icons16/"; + } else + pathString += "iconsmini/"; + configureAgendaMenu->setCheckable( true ); + configureAgendaMenu->insertItem(i18n("Toggle Allday"), 1 ); + configureAgendaMenu->insertSeparator(); + configureAgendaMenu->insertItem(i18n("Tiny"), 4 ); + configureAgendaMenu->insertItem(i18n("Small"), 6 ); + configureAgendaMenu->insertItem(i18n("Medium"), 8 ); + configureAgendaMenu->insertItem(i18n("Normal"), 10 ); + configureAgendaMenu->insertItem(i18n("Large"), 12 ); + configureAgendaMenu->insertItem(i18n("Big"), 14 ); + configureAgendaMenu->insertItem(i18n("Bigger"), 16 ); + configureAgendaMenu->insertItem(i18n("Biggest"), 18 ); + //configureMenu->insertItem( "AgendaSize",configureAgendaMenu ); + + icon = loadPixmap( pathString + "configure" ); + action = new QAction( i18n("Configure"),icon, i18n("Configure..."), 0, this ); + action->addTo( actionMenu ); + connect( action, SIGNAL( activated() ), + mView, SLOT( edit_options() ) ); + actionMenu->insertSeparator(); + icon = loadPixmap( pathString + "newevent" ); + configureToolBarMenu->insertItem(i18n("Stretched TB"), 5 ); + configureToolBarMenu->insertSeparator(); + configureToolBarMenu->insertItem(icon, i18n("New Event..."), 10 ); + QAction* ne_action = new QAction( i18n("New Event..."), icon, i18n("New Event..."), 0, this ); + ne_action->addTo( actionMenu ); + connect( ne_action, SIGNAL( activated() ), + mView, SLOT( newEvent() ) ); + icon = loadPixmap( pathString + "newtodo" ); + configureToolBarMenu->insertItem(icon, i18n("New Todo..."), 20 ); + QAction* nt_action = new QAction( i18n("New Todo..."), icon, i18n("New Todo..."), 0, this ); + nt_action->addTo( actionMenu ); + connect( nt_action, SIGNAL( activated() ), + mView, SLOT( newTodo() ) ); + icon = loadPixmap( pathString + "navi" ); + action = new QAction( i18n("Toggle DateNavigator"), icon, i18n("Toggle DateNavigator"), 0, this ); + action->addTo( viewMenu ); + connect( action, SIGNAL( activated() ), + mView, SLOT( toggleDateNavigatorWidget() ) ); + icon = loadPixmap( pathString + "filter" ); + action = new QAction( i18n("Toggle FilterView"), icon, i18n("Toggle FilterView"), 0, this ); + action->addTo( viewMenu ); + connect( action, SIGNAL( activated() ), + mView, SLOT( toggleFilter() ) ); + + + viewMenu->insertSeparator(); + icon = loadPixmap( pathString + "picker" ); + action = new QAction( i18n("Date Picker"), icon, i18n("Date Picker"), 0, this ); + action->addTo( viewMenu ); + connect( action, SIGNAL( activated() ), + mView, SLOT( showDatePicker() ) ); + action->addTo( iconToolBar ); + viewMenu->insertSeparator(); + icon = loadPixmap( pathString + "list" ); + configureToolBarMenu->insertItem(icon, i18n("List View"), 30 ); + QAction* showlist_action = new QAction( i18n("List View"), icon, i18n("List View"), 0, this ); + showlist_action->addTo( viewMenu ); + connect( showlist_action, SIGNAL( activated() ), + mView->viewManager(), SLOT( showListView() ) ); + + + icon = loadPixmap( pathString + "day" ); + configureToolBarMenu->insertItem(icon, i18n("Day View"), 40 ); + QAction* day1_action = new QAction( i18n("Day View"), icon, i18n("Day View"), 0, this ); + day1_action->addTo( viewMenu ); + // action->addTo( toolBar ); + connect( day1_action, SIGNAL( activated() ), + mView->viewManager(), SLOT( showDayView() ) ); + + icon = loadPixmap( pathString + "workweek" ); + configureToolBarMenu->insertItem(icon, i18n("Work Week"), 50 ); + QAction* day5_action = new QAction( i18n("Work Week"), icon, i18n("Work Week"), 0, this ); + day5_action->addTo( viewMenu ); + connect( day5_action, SIGNAL( activated() ), + mView->viewManager(), SLOT( showWorkWeekView() ) ); + + icon = loadPixmap( pathString + "week" ); + configureToolBarMenu->insertItem(icon, i18n("Week"), 60 ); + QAction* day7_action = new QAction( i18n("Week"), icon, i18n("Week"), 0, this ); + day7_action->addTo( viewMenu ); + connect( day7_action, SIGNAL( activated() ), + mView->viewManager(), SLOT( showWeekView() ) ); + + icon = loadPixmap( pathString + "month" ); + configureToolBarMenu->insertItem(icon, i18n("Month"), 70 ); + QAction* month_action = new QAction( i18n("Month"), icon, i18n("Month"), 0, this ); + month_action->addTo( viewMenu ); + connect( month_action, SIGNAL( activated() ), + mView->viewManager(), SLOT( showMonthView() ) ); + + icon = loadPixmap( pathString + "todo" ); + configureToolBarMenu->insertItem(icon, i18n("Todo View"), 80 ); + QAction* todoview_action = new QAction( i18n("Todo View"), icon, i18n("Todo View"), 0, this ); + todoview_action->addTo( viewMenu ); + connect( todoview_action, SIGNAL( activated() ), + mView->viewManager(), SLOT( showTodoView() ) ); + + icon = loadPixmap( pathString + "journal" ); + configureToolBarMenu->insertItem(icon, i18n("Journal"), 90 ); + QAction* viewjournal_action = new QAction( i18n("Journal"), icon, i18n("Journal"), 0, this ); + viewjournal_action->addTo( viewMenu ); + connect( viewjournal_action, SIGNAL( activated() ), + mView->viewManager(), SLOT( showJournalView() ) ); + + icon = loadPixmap( pathString + "xdays" ); + configureToolBarMenu->insertItem(icon, i18n("Next days"), 100,4 ); + QAction* xdays_action = new QAction( i18n("Next days"), icon, i18n("Next days"), 0, this ); + xdays_action->addTo( viewMenu ); + connect( xdays_action, SIGNAL( activated() ), + mView->viewManager(), SLOT( showNextXView() ) ); + + icon = loadPixmap( pathString + "whatsnext" ); + configureToolBarMenu->insertItem(icon, i18n("What's Next"), 110, 4 ); + QAction* whatsnext_action = new QAction( i18n("What's Next"), icon, i18n("What's Next"), 0, this ); + whatsnext_action->addTo( viewMenu ); + connect( whatsnext_action, SIGNAL( activated() ), + mView->viewManager(), SLOT( showWhatsNextView() ) ); + +#if 0 + action = new QAction( "view_timespan", "Time Span", 0, this ); + action->addTo( viewMenu ); + connect( action, SIGNAL( activated() ), + mView->viewManager(), SLOT( showTimeSpanView() ) ); +#endif + + mNewSubTodoAction = new QAction( "new_subtodo", i18n("New Sub-Todo..."), 0, + this ); + mNewSubTodoAction->addTo( actionMenu ); + connect( mNewSubTodoAction, SIGNAL( activated() ), + mView, SLOT( newSubTodo() ) ); + + actionMenu->insertSeparator(); + + mShowAction = new QAction( "show_incidence", i18n("Show..."), 0, this ); + mShowAction->addTo( actionMenu ); + connect( mShowAction, SIGNAL( activated() ), + mView, SLOT( showIncidence() ) ); + + mEditAction = new QAction( "edit_incidence", i18n("Edit..."), 0, this ); + mEditAction->addTo( actionMenu ); + connect( mEditAction, SIGNAL( activated() ), + mView, SLOT( editIncidence() ) ); + + mDeleteAction = new QAction( "delete_incidence", i18n("Delete..."), 0, this ); + mDeleteAction->addTo( actionMenu ); + connect( mDeleteAction, SIGNAL( activated() ), + mView, SLOT( deleteIncidence() ) ); + + actionMenu->insertSeparator(); + + action = new QAction( "purge_completed", i18n("Purge Completed"), 0, + this ); + action->addTo( actionMenu ); + connect( action, SIGNAL( activated() ), mView, SLOT( purgeCompleted() ) ); + + icon = loadPixmap( pathString + "search" ); + QAction* search_action = new QAction( i18n("Search"), icon, i18n("Search..."), 0, this ); + configureToolBarMenu->insertItem(icon, i18n("Search"), 120 , 4); + search_action->addTo( actionMenu ); + connect( search_action, SIGNAL( activated() ), + mView->dialogManager(), SLOT( showSearchDialog() ) ); + + icon = loadPixmap( pathString + "today" ); + configureToolBarMenu->insertItem(icon, i18n("Go to Today"), 130); + QAction* today_action = new QAction( i18n("Go to Today"), icon, i18n("Go to Today"), 0, this ); + today_action->addTo( actionMenu ); + connect( today_action, SIGNAL( activated() ), + mView, SLOT( goToday() ) ); + + if ( KOPrefs::instance()->mShowFullMenu ) { + actionMenu->insertSeparator(); + actionMenu->insertItem( i18n("Configure Toolbar"),configureToolBarMenu ); + + } + // actionMenu->insertSeparator(); + action = new QAction( "import_qtopia", i18n("Import (*.ics/*.vcs) file"), 0, + this ); + action->addTo( importMenu ); + connect( action, SIGNAL( activated() ), SLOT( importIcal() ) ); + action = new QAction( "import_quick", i18n("Import last file"), 0, + this ); + action->addTo( importMenu ); + connect( action, SIGNAL( activated() ), SLOT( quickImportIcal() ) ); + importMenu->insertSeparator(); + action = new QAction( "import_bday", i18n("Import Birthdays (KA/Pi)"), 0, + this ); + action->addTo( importMenu ); + connect( action, SIGNAL( activated() ), SLOT( importBday() ) ); +#ifndef DESKTOP_VERSION + importMenu->insertSeparator(); + action = new QAction( "import_qtopia", i18n("Import Opie/Qtopia Cal."), 0, + this ); + action->addTo( importMenu ); + connect( action, SIGNAL( activated() ), SLOT( importQtopia() ) ); +#endif + + importMenu->insertSeparator(); + action = new QAction( "load_cal", i18n("Load Calendar Backup"), 0, + this ); + action->addTo( importMenu ); + connect( action, SIGNAL( activated() ), SLOT( loadCalendar() ) ); + + action = new QAction( "save_cal", i18n("Save Calendar Backup"), 0, + this ); + action->addTo( importMenu ); + connect( action, SIGNAL( activated() ), SLOT( saveCalendar() ) ); + + importMenu->insertSeparator(); + action = new QAction( "import_qtopia", i18n("Export VCalendar"), 0, + this ); + action->addTo( importMenu ); connect( action, SIGNAL( activated() ), SLOT( exportVCalendar() ) ); + importMenu->insertSeparator(); + action = new QAction( "manage cat", i18n("Manage new categories..."), 0, + this ); + action->addTo( importMenu ); + connect( action, SIGNAL( activated() ), mView, SLOT( manageCategories() ) ); +#ifndef DESKTOP_VERSION + importMenu->insertSeparator(); + action = new QAction( "beam all", i18n("Beam complete calendar..."), 0, + this ); + action->addTo( importMenu ); + connect( action, SIGNAL( activated() ), mView, SLOT( beamCalendar() ) ); + + action = new QAction( "beam all", i18n("Beam filtered calendar..."), 0, + this ); + action->addTo( importMenu ); + connect( action, SIGNAL( activated() ), mView, SLOT( beamFilteredCalendar()) ); +#else + importMenu->insertSeparator(); + icon = loadPixmap( pathString + "print" ); + action = new QAction( i18n("Print calendar..."),icon,i18n("Print calendar..."), 0, this ); + action->addTo( importMenu ); + connect( action, SIGNAL( activated() ), + this, SLOT( printCal() ) ); + + icon = loadPixmap( pathString + "print" ); + action = new QAction( i18n("Print agenda selection..."),icon,i18n("Print agenda selection..."), 0, this ); + action->addTo( importMenu ); + connect( action, SIGNAL( activated() ), + this, SLOT( printSel() ) ); +#endif + importMenu->insertSeparator(); + action = new QAction( "beam all", i18n("Save"), 0, + this ); + action->addTo( importMenu ); + connect( action, SIGNAL( activated() ), this, SLOT( save() ) ); + action = new QAction( "beam all", i18n("Exit (+save)"), 0, + this ); + action->addTo( importMenu ); + connect( action, SIGNAL( activated() ), this, SLOT( close() ) ); + + //menuBar->insertItem( "Configure",configureMenu ); + //configureMenu->insertItem( "Toolbar",configureToolBarMenu ); + icon = loadPixmap( "korganizer/korganizer" ); + action = new QAction( "Keys + Colors", i18n("Keys + Colors..."), 0, this ); + action->addTo( helpMenu ); + connect( action, SIGNAL( activated() ), + SLOT( keyBindings() ) ); + action = new QAction( "featureHowto", i18n("Features + hints..."), 0,this ); + action->addTo( helpMenu ); + connect( action, SIGNAL( activated() ), + SLOT( features() ) ); + action = new QAction( "Auto saving", i18n("Auto saving..."), 0, this ); + action->addTo( helpMenu ); + connect( action, SIGNAL( activated() ), + SLOT( aboutAutoSaving() ) ); + action = new QAction( "Problemd", i18n("Known Problems..."), 0,this ); + action->addTo( helpMenu ); + connect( action, SIGNAL( activated() ), + SLOT( aboutKnownBugs() ) ); + action = new QAction( "Translate Howto", i18n("User translation..."), 0,this ); + action->addTo( helpMenu ); + connect( action, SIGNAL( activated() ), + SLOT( usertrans() ) ); + action = new QAction( "Sync Howto", i18n("Sync HowTo..."), 0,this ); + action->addTo( helpMenu ); + connect( action, SIGNAL( activated() ), + SLOT( synchowto() ) ); + action = new QAction( "Whats New", i18n("What's new?"), 0,this ); + action->addTo( helpMenu ); + connect( action, SIGNAL( activated() ), + SLOT( whatsNew() ) ); + action = new QAction( "Frequently asked questions", i18n("FAQ..."), 0,this ); + action->addTo( helpMenu ); + connect( action, SIGNAL( activated() ), + SLOT( faq() ) ); + + + action = new QAction( "about", i18n("About..."), 0, this ); + action->addTo( helpMenu ); + connect( action, SIGNAL( activated() ), + SLOT( about() ) ); + //menuBar->insertSeparator(); + + // ****************************************************** + // menubar icons + + + iconToolBar->setHorizontalStretchable (true ); + //menuBar->insertItem( iconToolBar ); + //xdays_action + if (p-> mShowIconNewEvent) + ne_action->addTo( iconToolBar ); + if (p->mShowIconNewTodo ) + nt_action->addTo( iconToolBar ); + if (p-> mShowIconSearch) + search_action->addTo( iconToolBar ); + if (p-> mShowIconNext) + whatsnext_action->addTo( iconToolBar ); + if (p-> mShowIconNextDays) + xdays_action->addTo( iconToolBar ); + if (p-> mShowIconList) + showlist_action->addTo( iconToolBar ); + if (p-> mShowIconDay1) + day1_action->addTo( iconToolBar ); + if (p-> mShowIconDay5) + day5_action->addTo( iconToolBar ); + if (p-> mShowIconDay7) + day7_action->addTo( iconToolBar ); + if (p-> mShowIconMonth) + month_action->addTo( iconToolBar ); + if (p-> mShowIconTodoview) + todoview_action->addTo( iconToolBar ); + if (p-> mShowIconJournal) + viewjournal_action->addTo( iconToolBar ); + icon = loadPixmap( pathString + "2leftarrowB" ); + configureToolBarMenu->insertItem(icon, i18n("Prev. month"), 200, 14); + if (p-> mShowIconBackFast) { + action = new QAction( i18n("Prev. month"), icon, i18n("Prev. month"),0 , this ); + connect( action, SIGNAL( activated() ), + mView, SLOT( goPreviousMonth() ) ); + action->addTo( iconToolBar ); + } + icon = loadPixmap( pathString + "1leftarrowB" ); + configureToolBarMenu->insertItem(icon, i18n("Go backward"), 210,15); + if (p-> mShowIconBack) { + action = new QAction( i18n("Go backward"), icon, i18n("Go backward"),0 , this ); + connect( action, SIGNAL( activated() ), + mView, SLOT( goPrevious() ) ); + action->addTo( iconToolBar ); + } + if (p-> mShowIconToday) + today_action->addTo( iconToolBar ); + icon = loadPixmap( pathString + "1rightarrowB" ); + configureToolBarMenu->insertItem(icon, i18n("Go forward"), 220); + if (p-> mShowIconForward) { + action = new QAction( i18n("Go forward"), icon, i18n("Go forward"),0 , this ); + connect( action, SIGNAL( activated() ), + mView, SLOT( goNext() ) ); + action->addTo( iconToolBar ); + } + icon = loadPixmap( pathString + "2rightarrowB" ); + configureToolBarMenu->insertItem(icon, i18n("Next month"), 230); + if (p-> mShowIconForwardFast) { + action = new QAction( i18n("Next month"), icon, i18n("Next month"),0 , this ); + connect( action, SIGNAL( activated() ), + mView, SLOT( goNextMonth() ) ); + action->addTo( iconToolBar ); + } + + + configureToolBarMenu->insertItem(i18n("What's This?"), 300); + + if (p-> mShowIconNewEvent) + configureToolBarMenu->setItemChecked( 10, true ); + if (p->mShowIconNewTodo ) + configureToolBarMenu->setItemChecked( 20, true ); + if (p-> mShowIconSearch) + configureToolBarMenu->setItemChecked( 120, true ); + if (p-> mShowIconList) + configureToolBarMenu->setItemChecked( 30, true ); + if (p-> mShowIconDay1) + configureToolBarMenu->setItemChecked( 40, true ); + if (p-> mShowIconDay5) + configureToolBarMenu->setItemChecked( 50, true ); + if (p-> mShowIconDay7) + configureToolBarMenu->setItemChecked( 60, true ); + if (p-> mShowIconMonth) + configureToolBarMenu->setItemChecked( 70, true ); + if (p-> mShowIconTodoview) + configureToolBarMenu->setItemChecked( 80, true ); + if (p-> mShowIconBackFast) + configureToolBarMenu->setItemChecked( 200, true ); + if (p-> mShowIconBack) + configureToolBarMenu->setItemChecked( 210, true ); + if (p-> mShowIconToday) + configureToolBarMenu->setItemChecked( 130, true ); + if (p-> mShowIconForward) + configureToolBarMenu->setItemChecked( 220, true ); + if (p-> mShowIconForwardFast) + configureToolBarMenu->setItemChecked( 230, true ); + if (p-> mShowIconNextDays) + configureToolBarMenu->setItemChecked( 100, true ); + if (p-> mShowIconNext) + configureToolBarMenu->setItemChecked( 110, true ); + if (p-> mShowIconJournal) + configureToolBarMenu->setItemChecked( 90, true ); + if (p-> mShowIconWhatsThis) + configureToolBarMenu->setItemChecked( 300, true ); + + QLabel* dummy = new QLabel( iconToolBar ); + dummy->setBackgroundColor( iconToolBar->backgroundColor() ); + if (!p-> mShowIconStretch) + iconToolBar->setStretchableWidget ( dummy ) ; + else + configureToolBarMenu->setItemChecked( 5, true ); + if (p-> mShowIconWhatsThis) + QWhatsThis::whatsThisButton ( iconToolBar ); + connect( configureToolBarMenu, SIGNAL( activated( int ) ),this, SLOT(configureToolBar( int ) ) ); + configureAgenda( p->mHourSize ); + connect( configureAgendaMenu, SIGNAL( activated( int ) ),this, SLOT(configureAgenda( int ) ) ); +} +void MainWindow::fillSyncMenu() +{ + syncMenu->clear(); + syncMenu->insertItem( i18n("Configure..."), 0 ); + syncMenu->insertSeparator(); + syncMenu->insertItem( i18n("Multiple sync"), 1 ); + syncMenu->insertSeparator(); + + QStringList prof = KOPrefs::instance()->mSyncProfileNames; + + if ( prof.count() < 3 ) { + KConfig *config = KOGlobals::config(); + prof.clear(); + prof << i18n("Sharp-DTM"); + prof << i18n("Local file"); + prof << i18n("Last file"); + KSyncProfile* temp = new KSyncProfile (); + temp->setName( prof[0] ); + temp->writeConfig(config); + temp->setName( prof[1] ); + temp->writeConfig(config); + temp->setName( prof[2] ); + temp->writeConfig(config); + config->sync(); + delete temp; + KOPrefs::instance()->mSyncProfileNames = prof; + } + + int i; + for ( i = 0; i < prof.count(); ++i ) { + + syncMenu->insertItem( prof[i], 1000+i ); + if ( i == 2 ) + syncMenu->insertSeparator(); + } + QDir app_dir; + if ( !app_dir.exists(QDir::homeDirPath()+"/Applications/dtm" ) ) { + syncMenu->setItemEnabled( false , 1000 ); + } +} + +int MainWindow::ringSync() +{ + int syncedProfiles = 0; + int i; + QTime timer; + KConfig *config = KOGlobals::config(); + QStringList syncProfileNames = KOPrefs::instance()->mSyncProfileNames; + KSyncProfile* temp = new KSyncProfile (); + KOPrefs::instance()->mAskForPreferences = false; + for ( i = 0; i < syncProfileNames.count(); ++i ) { + mCurrentSyncProfile = i; + temp->setName(syncProfileNames[mCurrentSyncProfile]); + temp->readConfig(config); + if ( temp->getIncludeInRingSync() && ( i < 1 || i > 2 )) { + setCaption(i18n("Profile ")+syncProfileNames[mCurrentSyncProfile]+ i18n(" is synced ... ")); + ++syncedProfiles; + // KOPrefs::instance()->mAskForPreferences = temp->getAskForPreferences(); + KOPrefs::instance()->mWriteBackFile = temp->getWriteBackFile(); + KOPrefs::instance()->mWriteBackExistingOnly = temp->getWriteBackExisting(); + KOPrefs::instance()->mShowSyncSummary = false; + mView->setSyncDevice(syncProfileNames[i] ); + mView->setSyncName( KOPrefs::instance()->mLocalMachineName ); + if ( i == 0 ) { + syncSharp(); + } else { + if ( temp->getIsLocalFileSync() ) { + if ( syncWithFile( temp->getRemoteFileName( ), true ) ) + KOPrefs::instance()->mLastSyncedLocalFile = temp->getRemoteFileName(); + } else { + syncRemote( temp, false ); + + } + } + timer.start(); + setCaption(i18n("Multiple sync in progress ... please wait!") ); + while ( timer.elapsed () < 2000 ) { + qApp->processEvents(); +#ifndef _WIN32_ + sleep (1); +#endif + } + + } + + } + delete temp; + return syncedProfiles; +} + +void MainWindow::multiSync( bool askforPrefs ) +{ + if (mBlockSaveFlag) + return; + mBlockSaveFlag = true; + QString question = i18n("Do you really want\nto multiple sync\nwith all checked profiles?\nSyncing takes some\ntime - all profiles\nare synced twice!"); + if ( QMessageBox::information( this, i18n("KO/Pi Sync"), + question, + i18n("Yes"), i18n("No"), + 0, 0 ) != 0 ) { + mBlockSaveFlag = false; + setCaption(i18n("Aborted! Nothing synced!")); + return; + } + mView->setSyncDevice(i18n("Multiple profiles") ); + KOPrefs::instance()->mSyncAlgoPrefs = KOPrefs::instance()->mRingSyncAlgoPrefs; + if ( askforPrefs ) { + mView->edit_sync_options(); + KOPrefs::instance()->mRingSyncAlgoPrefs = KOPrefs::instance()->mSyncAlgoPrefs; + } + setCaption(i18n("Multiple sync started.") ); + qApp->processEvents(); + int num = ringSync() ; + if ( num > 1 ) + ringSync(); + mBlockSaveFlag = false; + if ( num ) + save(); + if ( num ) + setCaption(i18n("%1 profiles synced. Multiple sync completed!").arg(num) ); + else + setCaption(i18n("Nothing synced! No profiles defined for multisync!")); + return; +} +void MainWindow::slotSyncMenu( int action ) +{ + //qDebug("syncaction %d ", action); + if ( action == 0 ) { + confSync(); + return; + } + if ( action == 1 ) { + multiSync( true ); + return; + } + + if (mBlockSaveFlag) + return; + mBlockSaveFlag = true; + mCurrentSyncProfile = action - 1000 ; + mView->setSyncDevice(KOPrefs::instance()->mSyncProfileNames[mCurrentSyncProfile] ); + mView->setSyncName( KOPrefs::instance()->mLocalMachineName ); + KConfig *config = KOGlobals::config(); + KSyncProfile* temp = new KSyncProfile (); + temp->setName(KOPrefs::instance()->mSyncProfileNames[mCurrentSyncProfile]); + temp->readConfig(config); + KOPrefs::instance()->mAskForPreferences = temp->getAskForPreferences(); + KOPrefs::instance()->mSyncAlgoPrefs = temp->getSyncPrefs(); + KOPrefs::instance()->mWriteBackFile = temp->getWriteBackFile(); + KOPrefs::instance()->mWriteBackExistingOnly = temp->getWriteBackExisting(); + KOPrefs::instance()->mShowSyncSummary = temp->getShowSummaryAfterSync(); + if ( action == 1000 ) { + syncSharp(); + + } else if ( action == 1001 ) { + syncLocalFile(); + + } else if ( action == 1002 ) { + quickSyncLocalFile(); + + } else if ( action >= 1003 ) { + if ( temp->getIsLocalFileSync() ) { + if ( syncWithFile( temp->getRemoteFileName( ), false ) ) + KOPrefs::instance()->mLastSyncedLocalFile = temp->getRemoteFileName(); + } else { + syncRemote( temp ); + + } + } + delete temp; + mBlockSaveFlag = false; +} +void MainWindow::setDefaultPreferences() +{ + KOPrefs *p = KOPrefs::instance(); + + p->mCompactDialogs = true; + p->mConfirm = true; + // p->mEnableQuickTodo = false; +} + +QString MainWindow::resourcePath() +{ + return KGlobal::iconLoader()->iconPath(); +} + +void MainWindow::displayText( QString text ,QString cap ) +{ + QDialog dia( this, "name", true ); ; + dia.setCaption( cap ); + QVBoxLayout* lay = new QVBoxLayout( &dia ); + lay->setSpacing( 3 ); + lay->setMargin( 3 ); + QTextBrowser tb ( &dia ); + lay->addWidget( &tb ); + tb.setText( text ); +#ifdef DESKTOP_VERSION + dia.resize( 640, 480); +#else + dia.showMaximized(); +#endif + dia.exec(); +} +void MainWindow::displayFile( QString fn, QString cap ) +{ + QString fileName = resourcePath() + fn; + QString text; + QFile file( fileName ); + if (!file.open( IO_ReadOnly ) ) { + return ; + + } + QTextStream ts( &file ); + text = ts.read(); + file.close(); + displayText( text, cap); +} +void MainWindow::features() +{ + + displayFile( "featuresKOPI.txt",i18n("KO/Pi Features and hints") ); +} + +void MainWindow::usertrans() +{ + + displayFile( "usertranslationHOWTO.txt",i18n("KO/Pi User translation HowTo") ); +} +void MainWindow::synchowto() +{ + + displayFile( "howtoSYNC.txt",i18n("KO/Pi Synchronization HowTo") ); +} +void MainWindow::faq() +{ + displayFile( "kopiFAQ.txt",i18n("KO/Pi FAQ") ); + +} +void MainWindow::whatsNew() +{ + displayFile( "kopiWhatsNew.txt",i18n("KO/Pi Version Info") ); + +} +void MainWindow::about() +{ + QString version; +#include <../version> + QMessageBox::about( this, i18n("About KOrganizer/Pi"), + i18n("KOrganizer/Platform-independent\n") + + "(KO/Pi) " + version + " - " + + +#ifdef DESKTOP_VERSION + i18n("Desktop Edition\n") + +#else + i18n("PDA-Edition\nfor: Zaurus 5x00 / 7x0 / 8x0\n") + +#endif + i18n("(c) 2004 Lutz Rogowski\nEmail:lutz@pi-sync.net\nKO/Pi is based on KOrganizer\n(c) 2002,2003 Cornelius Schumacher\nEmail: schumacher@kde.org\nKOrganizer/Pi is licensed\nunder the GPL.\nKO/Pi can be compiled for\nLinux, Zaurus-PDA and Windows\nwww.korganizer.org\nwww.pi-sync.net\n") ); +} +void MainWindow::keyBindings() +{ + QString cap = i18n("Key bindings KOrganizer/Pi"); + QString text = i18n("<p><h2>KO/Pi key shortcuts:</h2></p>\n") + + i18n("<p><b>H</b>: This help dialog | <b>S</b>: Search dialog</p>\n")+ + i18n("<p><b>I</b>: Show info for selected event/todo</p>\n") + + i18n("<p><b>Space</b>: Toggle fullscreen | <b>P</b>: Date picker</p>\n")+ + i18n("<p><b>F</b>: Toggle filterview |<b>F+ctrl</b>: Edit filter </p>\n")+ + i18n("<p><b>O</b>: Filter On/Off | <b>J</b>: Journal view</p>\n")+ + i18n("<p><b>1-0</b> (+<b>ctrl</b>): Select filter 1-10 (11-20)</p>\n")+ + i18n("<p><b>N</b>: Next days view| <b>W</b>: What's next view\n ")+ + i18n("<p><b>V</b>: Todo view | <b>L</b>: Event list view</p>\n")+ + i18n("<p><b>Z,Y</b>: Work week view | <b>U</b>: Week view</p>\n")+ + i18n("<p><b>D</b>: One day view | <b>M</b>: Month view</p>\n")+ + i18n("<p><b>E</b>: Edit selected item |<b> E+ctrl</b>: New Event</p>\n")+ + i18n("<p><b>T</b>: Goto today | <b>T+ctrl</b>: New Todo</p>\n")+ + i18n("<p><b>S+ctrl</b>: Add sub-todo | <b>X</b>: Toggle datenavigator</p>\n")+ + i18n("<p><b>+,-</b> : Zoom in/out agenda | <b>A</b>: Toggle allday agenda height</p>\n")+ + i18n("<p><b>C</b>: Show current time in agenda view</p>\n")+ + i18n("<p><b>B</b>: Edit description (details) of selected item</p>\n")+ + i18n("<p><b>right</b>: Next week | <b>right+ctrl</b>: Next month</p>\n")+ + i18n("<p><b>left</b>: Prev. week | <b>left+ctrl</b>: Prev. month</p>\n")+ + i18n("<p><b>del,backspace</b>: Delete selected item</p>\n")+ + i18n("<p><h3>In agenda view:</h3></p>\n") + + i18n("<p><b>up/down</b>: Scroll agenda view</p>\n")+ + i18n("<p><b>ctrl+up/down</b>: Scroll small todo view</p>\n")+ + i18n("<p><h3>In todo view:</h3></p>\n") + + i18n("<p><b>Q</b>: Toggle quick todo line edit.</p>\n")+ + i18n("<p><b>I</b>: Show info of current item+one step down.</p>\n")+ + i18n("<p><b>return</b>: Mark item as completed+one step down.</p>\n")+ + i18n("<p><b>return+shift</b>: Mark item as not completed+one step down</p>\n")+ + i18n("<p><h3>In list view:</h3></p>\n") + + i18n("<p><b>I</b>: Show info of current item+one step down.</p>\n")+ + i18n("<p><b>return</b>: Select item+one step down</p>\n")+ + i18n("<p><b>return+shift</b>: Deselect item+one step down</p>\n")+ + i18n("<p><b>up/down</b>: Next/prev item</p>\n")+ + i18n("<p><b>ctrl+up/down</b>: Goto up/down by 20% of items</p>\n")+ + i18n("<p><b>shift+up/down</b>: Goto first/last item</p>\n")+ + i18n("<p><h3>In event/todo viewer:</h3></p>\n") + + i18n("<p><b>I,C</b>: Close dialog.</p>\n")+ + i18n("<p><b>A</b>: Show agenda view.</p>\n")+ + i18n("<p><b>E</b>: Edit item</p>\n") + + i18n("<p><h2>KO/Pi icon colors:</h2></p>\n") + + i18n("<p><b>(for square icons in agenda and month view)</b></p>\n") + + i18n("<p><b>Cross</b>: Item cancelled.([c] in Whats'Next view)</p>\n")+ + i18n("<p><b>Red</b>: Alarm set.([a] in Whats'Next view)</p>\n")+ + i18n("<p><b>Blue</b>: Recurrent event.([r] in Whats'Next view)</p>\n")+ + i18n("<p><b>Dark green</b>: Information(description) available.([i] in WN view)</p>\n")+ + i18n("<p><b>Black</b>: Event/todo with attendees. You are the organizer!</p>\n")+ + i18n("<p><b>Dark yellow</b>: Event/todo with attendees.</p>\n") + + i18n("<p><b>White</b>: Item readonly</p>\n"); + displayText( text, cap); + +} +void MainWindow::aboutAutoSaving() +{ + QMessageBox* msg; + msg = new QMessageBox( i18n("Auto Saving in KOrganizer/Pi"), + i18n("After changing something, the data is\nautomatically saved to the file\n~/Applications/korganizer/calendar/mycalendar.ics\nafter (configureable) three minutes.\nFor safety reasons there is one autosaving\nafter 10 minutes (of idle time) again. The \ndata is saved automatically when closing KO/Pi\nYou can create a backup file \nwith: File - Save Calendar Backup\n"), QMessageBox::NoIcon, + QMessageBox::Ok, + QMessageBox::NoButton, + QMessageBox::NoButton); + msg->exec(); + delete msg; + + +} +void MainWindow::aboutKnownBugs() +{ + QMessageBox* msg; + msg = new QMessageBox( i18n("Known Problems in KOrganizer/Pi"), + i18n("1) Importing *.vcs or *.ics files from\nother applications may not work properly,\nif there are events with properties\nKO/Pi does not support.\n")+ + i18n("2) Audio alarm daemon\nfor Zaurus is available!\nas an additional small application\n")+ + i18n("\nPlease report unexpected behaviour to\nlutz@pi-sync.net\n") + + i18n("\nor report them in the bugtracker on\n") + + i18n("\nhttp://sourceforge.net/projects/kdepimpi\n"), + QMessageBox::NoIcon, + QMessageBox::Ok, + QMessageBox::NoButton, + QMessageBox::NoButton); + msg->exec(); + delete msg; + +} + +QString MainWindow::defaultFileName() +{ + return locateLocal( "data", "korganizer/mycalendar.ics" ); +} + +void MainWindow::processIncidenceSelection( Incidence *incidence ) +{ + if ( !incidence ) { + enableIncidenceActions( false ); + + mNewSubTodoAction->setEnabled( false ); + setCaptionToDates(); + return; + + } + + //KGlobal::locale()->formatDateTime(nextA, true); + QString startString = ""; + if ( incidence->type() != "Todo" ) { + if ( incidence->dtStart().date() < incidence->dtEnd().date() ) { + if ( incidence->doesFloat() ) { + startString += ": "+incidence->dtStartDateStr( true ); + startString += " --- "+((Event*)incidence)->dtEndDateStr( true ); + + } else { + startString = ": "+incidence->dtStartStr(true); + startString += " --- "+((Event*)incidence)->dtEndStr(true); + + } + + } else { + if ( incidence->dtStart().time() != incidence->dtEnd().time() ) + startString = ": "+KGlobal::locale()->formatTime(incidence->dtStart().time())+ + "-"+KGlobal::locale()->formatTime(incidence->dtEnd().time()); + startString +=" "+KGlobal::locale()->formatDate( incidence->dtStart().date(), true); + } + + } + else + startString = i18n(": (Prio ") +QString::number( (( KCal::Todo*)incidence)->priority() ) +") "+QString::number( (( KCal::Todo*)incidence)->percentComplete() ) +i18n("\% completed"); + if ( !incidence->location().isEmpty() ) + startString += " (" +incidence->location()+")"; + setCaption( incidence->summary()+startString); + + enableIncidenceActions( true ); + + if ( incidence->type() == "Event" ) { + mShowAction->setText( i18n("Show Event...") ); + mEditAction->setText( i18n("Edit Event...") ); + mDeleteAction->setText( i18n("Delete Event...") ); + + mNewSubTodoAction->setEnabled( false ); + } else if ( incidence->type() == "Todo" ) { + mShowAction->setText( i18n("Show Todo...") ); + mEditAction->setText( i18n("Edit Todo...") ); + mDeleteAction->setText( i18n("Delete Todo...") ); + + mNewSubTodoAction->setEnabled( true ); + } else { + mShowAction->setText( i18n("Show...") ); + mShowAction->setText( i18n("Edit...") ); + mShowAction->setText( i18n("Delete...") ); + + mNewSubTodoAction->setEnabled( false ); + } +} + +void MainWindow::enableIncidenceActions( bool enabled ) +{ + mShowAction->setEnabled( enabled ); + mEditAction->setEnabled( enabled ); + mDeleteAction->setEnabled( enabled ); +} + +void MainWindow::importBday() +{ + int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"), + i18n("When importing birthdays twice\nduplicated events will be ignored,\nif the event has not been\nchanged in KO/Pi!\n"), + i18n("Import!"), i18n("Cancel"), 0, + 0, 1 ); + if ( result == 0 ) { + mView->importBday(); + + } + + +} +void MainWindow::importQtopia() +{ +#ifndef DESKTOP_VERSION + int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"), + i18n("When importing a calendar twice\nduplicated events will be ignored!\nYou can create a backup file with\nFile - Save Calendar Backup\nto revert importing"), + i18n("Import!"), i18n("Cancel"), 0, + 0, 1 ); + if ( result == 0 ) { + QString datebook = Global::applicationFileName( "datebook", "datebook.xml"); + QString todolist = Global::applicationFileName( "todolist", "todolist.xml"); + QString categories = QString( getenv( "HOME" ) ) + "/Settings/Categories.xml"; + mView->importQtopia( categories, datebook, todolist ); + } +#else + int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"), + i18n("Not supported \non desktop!\n"), + i18n("Ok"), i18n("Cancel"), 0, + 0, 1 ); + +#endif +} + +void MainWindow::saveOnClose() +{ + KOPrefs *p = KOPrefs::instance(); + p->mToolBarHor = ( iconToolBar->orientation () == Qt:: Horizontal ); + p->mToolBarUp = iconToolBar->x() > width()/2 || + iconToolBar->y() > height()/2; + mView->writeSettings(); + if ( mCalendarModifiedFlag || mView->checkFileChanged( defaultFileName())) + save(); +} +void MainWindow::slotModifiedChanged( bool changed ) +{ + if ( mBlockAtStartup ) + return; + int msec; + // we store the changes after 1 minute, + // and for safety reasons after 10 minutes again + if ( !mBlockSaveFlag ) + msec = (1000 * 60*KOPrefs::instance()->mAutoSaveInterval) +1000; + else + msec = 1000 * 600; + mSaveTimer.start( msec, true ); // 1 minute + qDebug("KO: Saving File in %d secs!", msec/1000); + mCalendarModifiedFlag = true; +} +#include <qfileinfo.h> +void MainWindow::save() +{ + if ( mBlockSaveFlag ) + return; + bool store = mBlockSaveFlag; + mBlockSaveFlag = true; + if ( mView->checkFileVersion( defaultFileName()) ) { + + QTime neededSaveTime = QDateTime::currentDateTime().time(); + setCaption(i18n("KO/Pi:Saving Data to File ..." )); + qDebug("KO: Start saving data to file!"); + mView->saveCalendar( defaultFileName() ); + + int msNeeded = neededSaveTime.msecsTo( QDateTime::currentDateTime().time() ); + mView->setLoadedFileVersion(QDateTime::currentDateTime()); + qDebug("KO: Needed %d ms for saving.",msNeeded ); + QString savemes; + savemes.sprintf(i18n("KO/Pi:File Saved. Needed %d sec, %d ms"),(msNeeded/1000)%100,msNeeded%1000 ); + setCaption(savemes); + } else + setCaption(i18n("Saving cancelled!")); + mCalendarModifiedFlag = false; + mBlockSaveFlag = store; +} + +void MainWindow::keyReleaseEvent ( QKeyEvent * e) +{ + if ( !e->isAutoRepeat() ) { + mFlagKeyPressed = false; + } +} +void MainWindow::keyPressEvent ( QKeyEvent * e ) +{ + qApp->processEvents(); + if ( e->isAutoRepeat() && !mFlagKeyPressed ) { + e->ignore(); + // qDebug(" ignore %d",e->isAutoRepeat() ); + return; + } + if (! e->isAutoRepeat() ) + mFlagKeyPressed = true; + KOPrefs *p = KOPrefs::instance(); + bool showSelectedDates = false; + int size; + int pro = 0; + //qDebug("MainWindow::keyPressEvent "); + switch ( e->key() ) { + case Qt::Key_Right: + if ( e->state() == Qt::ControlButton || e->state() == Qt::ShiftButton) + mView->goNextMonth(); + else + mView->goNext(); + showSelectedDates = true; + break; + case Qt::Key_Left: + if ( e->state() == Qt::ControlButton|| e->state() == Qt::ShiftButton ) + mView->goPreviousMonth(); + else + mView->goPrevious(); + showSelectedDates = true; + break; + case Qt::Key_Down: + mView->viewManager()->agendaView()->scrollOneHourDown(); + break; + case Qt::Key_Up: + mView->viewManager()->agendaView()->scrollOneHourUp(); + break; + case Qt::Key_I: + mView->showIncidence(); + break; + case Qt::Key_Delete: + case Qt::Key_Backspace: + mView->deleteIncidence(); + break; + case Qt::Key_D: + mView->viewManager()->showDayView(); + showSelectedDates = true; + break; + case Qt::Key_O: + mView->toggleFilerEnabled( ); + break; + case Qt::Key_0: + case Qt::Key_1: + case Qt::Key_2: + case Qt::Key_3: + case Qt::Key_4: + case Qt::Key_5: + case Qt::Key_6: + case Qt::Key_7: + case Qt::Key_8: + case Qt::Key_9: + pro = e->key()-48; + if ( pro == 0 ) + pro = 10; + if ( e->state() == Qt::ControlButton) + pro += 10; + break; + case Qt::Key_M: + mView->viewManager()->showMonthView(); + showSelectedDates = true; + break; + case Qt::Key_Insert: + mView->newEvent(); + break; + case Qt::Key_S : + if ( e->state() == Qt::ControlButton || e->state() == Qt::ShiftButton) + mView->newSubTodo(); + else + mView->dialogManager()->showSearchDialog(); + break; + case Qt::Key_Y : + case Qt::Key_Z : + mView->viewManager()->showWorkWeekView(); + showSelectedDates = true; + break; + case Qt::Key_U : + mView->viewManager()->showWeekView(); + showSelectedDates = true; + break; + case Qt::Key_H : + keyBindings(); + break; + case Qt::Key_W: + mView->viewManager()->showWhatsNextView(); + break; + case Qt::Key_L: + mView->viewManager()->showListView(); + break; + case Qt::Key_N: + mView->viewManager()->showNextXView(); + showSelectedDates = true; + break; + case Qt::Key_V: + mView->viewManager()->showTodoView(); + break; + case Qt::Key_C: + mView->viewManager()->agendaView()->setStartHour( QTime::currentTime ().hour() ); + break; + case Qt::Key_P: + mView->showDatePicker( ); + break; + case Qt::Key_F: + if ( e->state() == Qt::ControlButton|| e->state() == Qt::ShiftButton ) + mView->editFilters(); + else + mView->toggleFilter(); + break; + case Qt::Key_X: + mView->toggleDateNavigatorWidget(); + break; + case Qt::Key_Space: + mView->toggleExpand(); + break; + case Qt::Key_A: + mView->toggleAllDaySize(); + break; + case Qt::Key_T: + if ( e->state() == Qt::ControlButton|| e->state() == Qt::ShiftButton ) + mView->newTodo(); + else { + mView->goToday(); + showSelectedDates = true; + } + break; + case Qt::Key_J: + mView->viewManager()->showJournalView(); + break; + case Qt::Key_B: + mView->editIncidenceDescription();; + break; + // case Qt::Key_Return: + case Qt::Key_E: + if ( e->state() == Qt::ControlButton|| e->state() == Qt::ShiftButton ) + mView->newEvent(); + else + mView->editIncidence(); + break; + case Qt::Key_Plus: + size = p->mHourSize +2; + if ( size <= 18 ) + configureAgenda( size ); + break; + case Qt::Key_Minus: + size = p->mHourSize - 2; + if ( size >= 4 ) + configureAgenda( size ); + break; + + + default: + e->ignore(); + } + if ( pro > 0 ) { + mView->selectFilter( pro-1 ); + } + if ( showSelectedDates ) { + ;// setCaptionToDates(); + } + +} + +void MainWindow::configureToolBar( int item ) +{ + + configureToolBarMenu->setItemChecked( item, !configureToolBarMenu-> isItemChecked ( item ) ); + KOPrefs *p = KOPrefs::instance(); + p-> mShowIconStretch= configureToolBarMenu->isItemChecked( 5 ); + p-> mShowIconNewEvent= configureToolBarMenu->isItemChecked( 10 ); + p->mShowIconNewTodo = configureToolBarMenu->isItemChecked( 20 ); + p-> mShowIconSearch= configureToolBarMenu->isItemChecked( 120 ); + p-> mShowIconList= configureToolBarMenu->isItemChecked( 30 ); + p-> mShowIconDay1= configureToolBarMenu->isItemChecked( 40 ); + p-> mShowIconDay5= configureToolBarMenu->isItemChecked( 50 ); + p-> mShowIconDay7= configureToolBarMenu->isItemChecked( 60 ); + p-> mShowIconMonth= configureToolBarMenu->isItemChecked( 70 ); + p-> mShowIconTodoview= configureToolBarMenu->isItemChecked( 80 ); + p-> mShowIconBackFast= configureToolBarMenu->isItemChecked( 200 ); + p-> mShowIconBack = configureToolBarMenu->isItemChecked( 210 ); + p-> mShowIconToday= configureToolBarMenu->isItemChecked( 130 ); + p-> mShowIconForward= configureToolBarMenu->isItemChecked( 220 ); + p-> mShowIconForwardFast= configureToolBarMenu->isItemChecked( 230 ); + p-> mShowIconNextDays= configureToolBarMenu->isItemChecked( 100 ); + p-> mShowIconNext= configureToolBarMenu->isItemChecked( 110 ); + p-> mShowIconJournal= configureToolBarMenu->isItemChecked( 90 ); + p-> mShowIconWhatsThis= configureToolBarMenu->isItemChecked( 300 ); + // initActions(); +} + +void MainWindow::setCaptionToDates() +{ + QString selDates; + selDates = KGlobal::locale()->formatDate(mView->startDate(), true); + if (mView->startDate() < mView->endDate() ) + selDates += " - " + KGlobal::locale()->formatDate(mView->endDate(), true); + setCaption( i18n("Dates: ") + selDates ); + +} +// parameter item == 0: reinit +void MainWindow::configureAgenda( int item ) +{ + + KOPrefs *p = KOPrefs::instance(); + + int i; + if ( item == 1 ) { + mView->toggleAllDaySize(); + return; + } + // do not allow 4 for widgets higher than 480 + // if ( QApplication::desktop()->height() > 480 ) { +// if ( item == 4 ) +// item = 6; +// } + for ( i = 4; i <= 18; i= i+2 ) + configureAgendaMenu->setItemChecked( i, false ); + configureAgendaMenu->setItemChecked( item, true ); + if ( p->mHourSize == item ) + return; + p->mHourSize=item; + mView->viewManager()->agendaView()->updateConfig(); +} + +void MainWindow::saveCalendar() +{ + QString fn = KOPrefs::instance()->mLastSaveFile; + fn = KFileDialog::getSaveFileName( fn, i18n("Save backup filename"), this ); + + if ( fn == "" ) + return; + QFileInfo info; + info.setFile( fn ); + QString mes; + bool createbup = true; + if ( info. exists() ) { + mes = i18n("Backup file\nalready exists!\nOld backup file from:\n%1\nOverwrite?\n").arg(KGlobal::locale()->formatDateTime(info.lastModified (), true, false )) ; + int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"),mes, + i18n("Overwrite!"), i18n("Cancel"), 0, + 0, 1 ); + if ( result != 0 ) { + createbup = false; + } + } + if ( createbup ) { + mView->saveCalendar( fn ); + mes = i18n("KO/Pi:Saved %1").arg(fn); + KOPrefs::instance()->mLastSaveFile = fn; + setCaption(mes); + } +} +void MainWindow::loadCalendar() +{ + + QString fn = KOPrefs::instance()->mLastLoadFile; + fn = KFileDialog::getOpenFileName( fn, i18n("Load backup filename"), this ); + + if ( fn == "" ) + return; + QFileInfo info; + info.setFile( fn ); + QString mess; + bool loadbup = true; + if ( info. exists() ) { + mess = i18n("Backup file from:\n%1\nLoading backup\nfile will delete\nyour current Data!\n").arg(KGlobal::locale()->formatDateTime(info.lastModified (), true, false )); + int result = QMessageBox::warning( this, "KO/Pi: Warning!", + mess, + i18n("Load!"), i18n("Cancel"), 0, + 0, 1 ); + if ( result != 0 ) { + loadbup = false; + } + } else { + QMessageBox::warning( this, i18n("KO/Pi: Warning!"), + i18n("Backup file\ndoes not exist!\nNothing loaded!"), 0, 0, + 0, 1 ); + + return; + } + if ( loadbup ) { + mView->openCalendar( fn ); + KOPrefs::instance()->mLastLoadFile = fn; + mess = i18n("KO/Pi:Loaded %1").arg(fn) ; + setCaption(mess); + } + +} +void MainWindow::quickImportIcal() +{ + importFile( KOPrefs::instance()->mLastImportFile, false ); +} +void MainWindow::importFile( QString fn, bool quick ) +{ + QFileInfo info; + info.setFile( fn ); + QString mess; + bool loadbup = true; + if ( !info. exists() ) { + mess = i18n("Import file \n...%1\ndoes not exist!\nNothing imported!\n").arg(fn.right( 30)); + int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"), + mess ); + return; + } + int result = 0; + if ( !quick ) { + mess = i18n( "Import file \n...%1\nfrom:\n%2\nDuplicated entries\nwill not be imported!\n").arg(fn.right( 25)).arg(KGlobal::locale()->formatDateTime(info.lastModified (), true, false )); + result = QMessageBox::warning( this, "KO/Pi: Warning!", + mess, + "Import", "Cancel", 0, + 0, 1 ); + } + if ( result == 0 ) { + if ( mView->openCalendar( fn, true )) { + KOPrefs::instance()->mLastImportFile = fn; + setCaption(i18n("Imported file successfully")); + } else { + setCaption(i18n("Error importing file")); + } + } +} + +void MainWindow::importIcal() +{ + + QString fn =KOPrefs::instance()->mLastImportFile; + + fn =KFileDialog:: getOpenFileName( fn, i18n("Import filename(*.ics/*.vcs)"), this ); + if ( fn == "" ) + return; + importFile( fn, true ); + +} + +void MainWindow::exportVCalendar() +{ + QString fn = KOPrefs::instance()->mLastVcalFile; + fn = KFileDialog::getSaveFileName( fn, i18n("Export vcal filename(*.vcs)"), this ); + if ( fn == "" ) + return; + QFileInfo info; + info.setFile( fn ); + QString mes; + bool createbup = true; + if ( info. exists() ) { + mes = i18n("Save file\nalready exists!\nOld save file from:\n%1\nOverwrite?\n").arg (KGlobal::locale()->formatDateTime(info.lastModified (), true, false ) ); + int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"),mes, + i18n("Overwrite!"), i18n("Cancel"), 0, + 0, 1 ); + if ( result != 0 ) { + createbup = false; + } + } + if ( createbup ) { + if ( mView->exportVCalendar( fn ) ) { + KOPrefs::instance()->mLastVcalFile = fn; + if ( fn.length() > 20 ) + mes = i18n("KO/Pi:Exported to ...%1").arg(fn.right(20)) ; + else + mes = i18n("KO/Pi:Exported to %1").arg(fn ); + setCaption(mes); + } + } + +} +#include <qpushbutton.h> +QString MainWindow::getPassword( ) +{ + QString retfile = ""; + QDialog dia ( this, "input-dialog", true ); + QLineEdit lab ( &dia ); + lab.setEchoMode( QLineEdit::Password ); + QVBoxLayout lay( &dia ); + lay.setMargin(7); + lay.setSpacing(7); + lay.addWidget( &lab); + dia.setFixedSize( 230,50 ); + dia.setCaption( i18n("Enter password") ); + QPushButton pb ( "OK", &dia); + lay.addWidget( &pb ); + connect(&pb, SIGNAL( clicked() ), &dia, SLOT ( accept() ) ); + dia.show(); + int res = dia.exec(); + if ( res ) + retfile = lab.text(); + dia.hide(); + qApp->processEvents(); + return retfile; + +} + +void MainWindow::syncLocalFile() +{ + + QString fn =KOPrefs::instance()->mLastSyncedLocalFile; + + fn =KFileDialog:: getOpenFileName( fn, i18n("Sync filename(*.ics/*.vcs)"), this ); + if ( fn == "" ) + return; + //mView->setSyncDevice("local-file" ); + if ( syncWithFile( fn, false ) ) { + // Event* e = mView->getLastSyncEvent(); +// e->setReadOnly( false ); +// e->setLocation( i18n("Local file: ")+ KOPrefs::instance()->mLastSyncedLocalFile); +// e->setReadOnly( true ); + } + +} + +bool MainWindow::syncWithFile( QString fn , bool quick ) +{ + bool ret = false; + QFileInfo info; + info.setFile( fn ); + QString mess; + bool loadbup = true; + if ( !info. exists() ) { + mess = i18n( "Sync file \n...%1\ndoes not exist!\nNothing synced!\n").arg(fn.right( 30) ); + int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"), + mess ); + return ret; + } + int result = 0; + if ( !quick ) { + mess = i18n("Sync with file \n...%1\nfrom:\n%2\n").arg(fn.right( 25)).arg(KGlobal::locale()->formatDateTime(info.lastModified (), true, false )); + result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"), + mess, + i18n("Sync"), i18n("Cancel"), 0, + 0, 1 ); + if ( result ) + return false; + } + if ( KOPrefs::instance()->mAskForPreferences ) + mView->edit_sync_options(); + if ( result == 0 ) { + //qDebug("Now sycing ... "); + if ( ret = mView->syncCalendar( fn, KOPrefs::instance()->mSyncAlgoPrefs ) ) + setCaption( i18n("Synchronization successful") ); + else + setCaption( i18n("Sync cancelled or failed. Nothing synced.") ); + if ( ! quick ) + KOPrefs::instance()->mLastSyncedLocalFile = fn; + slotModifiedChanged( true ); + } + return ret; +} +void MainWindow::quickSyncLocalFile() +{ + //mView->setSyncDevice("local-file" ); + //qDebug("quickSyncLocalFile() "); + if ( syncWithFile( KOPrefs::instance()->mLastSyncedLocalFile, false ) ) { + // Event* e = mView->getLastSyncEvent(); +// e->setReadOnly( false ); +// e->setLocation( i18n("Quick with file: ")+ KOPrefs::instance()->mLastSyncedLocalFile); +// e->setReadOnly( true ); + + } +} + +void MainWindow::confSync() +{ + mView->confSync(); + fillSyncMenu(); + mView->writeSettings(); + + +} +void MainWindow::syncRemote( KSyncProfile* prof, bool ask) +{ + QString question; + if ( ask ) { + question = i18n("Do you really want\nto remote sync\nwith profile \n")+ prof->getName()+" ?\n"; + if ( QMessageBox::information( this, i18n("KO/Pi Sync"), + question, + i18n("Yes"), i18n("No"), + 0, 0 ) != 0 ) + return; + } + QString command = prof->getPreSyncCommand(); + int fi; + if ( (fi = command.find("$PWD$")) > 0 ) { + QString pwd = getPassword(); + command = command.left( fi )+ pwd + command.mid( fi+5 ); + + } + int maxlen = 30; + if ( QApplication::desktop()->width() > 320 ) + maxlen += 25; + setCaption ( i18n( "Copy remote file to local machine..." ) ); + int fileSize = 0; + int result = system ( command ); + // 0 : okay + // 256: no such file or dir + // + qDebug("KO: Remote copy result(0 = okay): %d ",result ); + if ( result != 0 ) { + int len = maxlen; + while ( len < command.length() ) { + command.insert( len , "\n" ); + len += maxlen +2; + } + question = i18n("Sorry, the copy command failed!\nCommand was:\n%1\n \nTry command on console to get more\ndetailed info about the reason.\n").arg (command) ; + QMessageBox::information( this, i18n("KO/Pi Sync - ERROR"), + question, + i18n("Okay!")) ; + setCaption ("KO/Pi"); + return; + } + setCaption ( i18n( "Copying succeed." ) ); + //qDebug(" file **%s** ",prof->getLocalTempFile().latin1() ); + if ( syncWithFile( prof->getLocalTempFile(), true ) ) { +// Event* e = mView->getLastSyncEvent(); +// e->setReadOnly( false ); +// e->setLocation( KOPrefs::instance()->mSyncProfileNames[mCurrentSyncProfile]); +// e->setReadOnly( true ); + if ( KOPrefs::instance()->mWriteBackFile ) { + command = prof->getPostSyncCommand(); + setCaption ( i18n( "Writing back file ..." ) ); + result = system ( command ); + qDebug("KO: Writing back file result: %d ", result); + if ( result != 0 ) { + setCaption ( i18n( "Writing back file result: " )+QString::number( result ) ); + return; + } else { + setCaption ( i18n( "Syncronization sucessfully completed" ) ); + } + } + } + return; +} +void MainWindow::syncSSH() +{ + // not used anymore + QTime timer; + timer.start(); + //qDebug("MainWindow::syncssh() "); + KOPrefs *p = KOPrefs::instance(); + QString localFile = p->mLocalTempFile; + QString remoteIP = p->mRemoteIP; + QString remoteUser = p->mRemoteUser; + QString remoteFile = p->mRemoteFile; + if ( p->mUsePassWd && p->mRemotePassWd.length() > 0 ) + remoteUser += ":" + p->mRemotePassWd; + + QString question = i18n("Do you really want\nto remote sync?\n \n") + + i18n("IP: " ) +remoteIP +"\n" + + i18n("User: " ) + remoteUser +"\n" ; + int maxlen = 30; + if ( QApplication::desktop()->width() > 320 ) + maxlen += 25; + if ( remoteFile.length() > maxlen ) + question += i18n("Remote file:\n..." ) + remoteFile.right(maxlen) +"\n"; + else + question += i18n("Remote file:\n " ) + remoteFile +"\n"; + if ( localFile.length() > maxlen ) + question += i18n("Local temp file:\n..." ) + localFile.right(maxlen) +"\n"; + else + question += i18n("Local temp file:\n " ) + localFile +"\n"; + + if ( QMessageBox::information( this, i18n("KO/Pi Sync"), + question, + i18n("Yes"), i18n("No"), + 0, 0 ) != 0 ) + return; + // if ( !p->mUsePassWd ) { + // QString pass = getPassword(); + // if ( pass.length() > 0 ) + // remoteUser += ":" + pass; + // } + QString command = "scp " + remoteUser + "@" + remoteIP +":" + remoteFile +" " +localFile; + setCaption ( i18n( "Copy remote file to local machine..." ) ); + int fileSize = 0; + int result = system ( command ); + // 0 : okay + // 256: no such file or dir + // + qDebug("KO: Remote copy result(0 = okay): %d ",result ); + if ( result != 0 ) { + int len = maxlen; + while ( len < command.length() ) { + command.insert( len , "\n" ); + len += maxlen +2; + } + question = i18n("Sorry, the copy command failed!\nCommand was:\n%1\n \nTry command on console to get more\ndetailed info about the reason.\n").arg (command) ; + QMessageBox::information( this, i18n("KO/Pi Sync - ERROR"), + question, + i18n("Okay!")) ; + setCaption ("KO/Pi"); + return; + } + + + setCaption ( i18n( "Copying succeed." ) ); + //mView->setSyncDevice("ssh-scp" ); + if ( syncWithFile(localFile , true ) ) { +// Event* e = mView->getLastSyncEvent(); +// e->setReadOnly( false ); +// e->setLocation( KOPrefs::instance()->mSyncProfileNames[mCurrentSyncProfile]); +// e->setReadOnly( true ); + if ( KOPrefs::instance()->mWriteBackFile ) { + command = "scp " + localFile +" " +remoteUser + "@" + remoteIP +":" + remoteFile ; + setCaption ( i18n( "Writing back file ..." ) ); + result = system ( command ); + if ( result != 0 ) { + int len = maxlen; + while ( len < command.length() ) { + command.insert( len , "\n" ); + len += maxlen +2; + } + question = i18n("Sorry, the copy back command failed!\nCommand was:\n%1\n \nTry command on console to get more\ndetailed info about the reason.\n").arg (command) ; + QMessageBox::information( this, i18n("KO/Pi Sync - ERROR"), + question, + i18n("Okay!")) ; + setCaption ("KO/Pi"); + return; + } else { + setCaption ( i18n( "Syncronization sucessfully completed" ) ); + } + } + } + return; +#if 0 + system ("scp zaurus@192.168.0.65:/home/zaurus/Applications/korganizer/mycalendar.ics /home/polo/Applications/korganizer/z_sync.ics"); + while ( timer.elapsed() < 5000 ) + qApp->processEvents(); + + qDebug("MainWindow::merging) "); + mView->syncCalendar( "/home/polo/Applications/korganizer/z_sync.ics", 0 ); + while ( mBlockSaveFlag ) + qApp->processEvents(); + save(); + system ("scp /home/polo/Applications/korganizer/mycalendar.ics zaurus@192.168.0.65:/home/zaurus/Applications/korganizer/mycalendar.ics"); +#endif + +} + + +void MainWindow::syncSharp() +{ + if ( mCalendarModifiedFlag ) + save(); + mView->syncSharp(); + slotModifiedChanged( true ); + +} + +void MainWindow::printSel( ) +{ + mView->viewManager()->agendaView()->agenda()->printSelection(); +} + +void MainWindow::printCal() +{ + mView->print();//mCp->showDialog(); +} diff --git a/korganizer/mainwindow.h b/korganizer/mainwindow.h new file mode 100644 index 0000000..ee4aaa6 --- a/dev/null +++ b/korganizer/mainwindow.h @@ -0,0 +1,115 @@ +#ifndef KORGE_MAINWINDOW_H +#define KORGE_MAINWINDOW_H + +#include <qmainwindow.h> +#include <qtimer.h> +#include <qdict.h> + +#include <libkcal/incidence.h> +#include "simplealarmclient.h" + +class QAction; +class CalendarView; +class KSyncProfile; +#ifdef DESKTOP_VERSION + +#define QPEToolBar QToolBar +#define QPEMenuBar QMenuBar +#endif +class QPEToolBar; + +namespace KCal { +class CalendarLocal; +} + +using namespace KCal; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + public: + MainWindow( QWidget *parent = 0, const char *name = 0, QString command = ""); + ~MainWindow(); + public slots: + void configureAgenda( int ); + void recieve( const QCString& msg, const QByteArray& data ); + static QString defaultFileName(); + static QString resourcePath(); + protected slots: + void setCaptionToDates(); + int ringSync(); + void multiSync( bool askforPrefs = false ); + void about(); + void faq(); + void usertrans(); + void features(); + void synchowto(); + void whatsNew(); + void keyBindings(); + void aboutAutoSaving();; + void aboutKnownBugs(); + + void processIncidenceSelection( Incidence * ); + + void importQtopia(); + void importBday(); + void importIcal(); + void importFile( QString, bool ); + void quickImportIcal(); + + void slotModifiedChanged( bool ); + + void save(); + void configureToolBar( int ); + void printSel(); + void printCal(); + void saveCalendar(); + void loadCalendar(); + void exportVCalendar(); + + void slotSyncMenu( int ); + void syncSSH(); + void confSync(); + void syncSharp(); + void syncLocalFile(); + bool syncWithFile( QString, bool ); + void quickSyncLocalFile(); + + + protected: + void displayText( QString, QString); + void displayFile( QString, QString); + + void enableIncidenceActions( bool ); + + private: + void saveOnClose(); + int mCurrentSyncProfile; + void syncRemote( KSyncProfile* , bool ask = true); + void fillSyncMenu(); + bool mFlagKeyPressed; + bool mBlockAtStartup; + QPEToolBar *iconToolBar; + void initActions(); + void setDefaultPreferences(); + void keyPressEvent ( QKeyEvent * ) ; + void keyReleaseEvent ( QKeyEvent * ) ; + QPopupMenu *configureToolBarMenu; + QPopupMenu *configureAgendaMenu, *syncMenu; + CalendarLocal *mCalendar; + CalendarView *mView; + QString getPassword(); + QAction *mNewSubTodoAction; + + QAction *mShowAction; + QAction *mEditAction; + QAction *mDeleteAction; + void closeEvent( QCloseEvent* ce ); + SimpleAlarmClient mAlarmClient; + QTimer mSaveTimer; + bool mBlockSaveFlag; + bool mCalendarModifiedFlag; + QPixmap loadPixmap( QString ); +}; + +#endif diff --git a/korganizer/navigatorbar.cpp b/korganizer/navigatorbar.cpp new file mode 100644 index 0000000..1052a99 --- a/dev/null +++ b/korganizer/navigatorbar.cpp @@ -0,0 +1,199 @@ +/* + This file is part of KOrganizer. + + Copyright (c) 2003 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. +*/ + +#include <qstring.h> +#include <qtooltip.h> +#include <qpushbutton.h> +#include <qlayout.h> +#include <qframe.h> +#include <qlabel.h> +#include <qapplication.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kglobal.h> +#include <kiconloader.h> +#include "libkdepim/kdatepicker.h" +#include <knotifyclient.h> +#include "kdatetbl.h" + +#include "koglobals.h" +#include "koprefs.h" +#ifndef KORG_NOPLUGINS +#include "kocore.h" +#endif + +#include <kcalendarsystem.h> + +#include "navigatorbar.h" + +NavigatorBar::NavigatorBar( const QDate & date, QWidget *parent, const char *name ) + : QWidget( parent, name ) +{ + QBoxLayout *topLayout = new QHBoxLayout( this ); + + // Set up the control buttons and date label + mCtrlFrame = new QFrame( this ); + mCtrlFrame->setFrameStyle(QFrame::Panel|QFrame::Raised); + mCtrlFrame->setLineWidth(1); + + topLayout->addWidget( mCtrlFrame ); + + QFont tfont = font(); + if ( QApplication::desktop()->width() >= 480 ) + tfont.setPointSize(tfont.pointSize()+2); + tfont.setBold(true); + + bool isRTL = KOGlobals::self()->reverseLayout(); +#ifndef DESKTOP_VERSION + bool isDesktop = false; +#else + bool isDesktop = true; +#endif + if ( QString ( name ) == QString("useBigPixmaps") && QApplication::desktop()->width() > 320 ) + isDesktop = true; + // Create backward navigation buttons + mPrevYear = new QPushButton( mCtrlFrame ); + mPrevYear->setPixmap( SmallIcon( isDesktop ? "2leftarrowB" : "2leftarrow" ) ); + QToolTip::add( mPrevYear, i18n("Previous Year") ); + + mPrevMonth = new QPushButton( mCtrlFrame ); + mPrevMonth->setPixmap( SmallIcon( isDesktop ? "1leftarrowB" : "1leftarrow") ); + QToolTip::add( mPrevMonth, i18n("Previous Month") ); + + // Create forward navigation buttons + mNextMonth = new QPushButton( mCtrlFrame ); + mNextMonth->setPixmap( SmallIcon( isDesktop ? "1rightarrowB" : "1rightarrow") ); + QToolTip::add( mNextMonth, i18n("Next Month") ); + + mNextYear = new QPushButton( mCtrlFrame ); + mNextYear->setPixmap( SmallIcon( isDesktop ? "2rightarrowB": "2rightarrow") ); + QToolTip::add( mNextYear, i18n("Next Year") ); + mSelectMonth = new QPushButton( mCtrlFrame ); + // Create month name label + //selectMonth->setFont( tfont ); + // selectMonth->setAlignment( AlignCenter ); + //mDateLabel = new QLabel( selectMonth ); + //mDateLabel->setFont( tfont ); + //mDateLabel->setAlignment( AlignCenter ); + if ( QString ( name ) == QString("useBigPixmaps") ) { + mNextMonth->setFlat( true); + mNextYear->setFlat( true); + mSelectMonth->setFlat( true); + mPrevYear->setFlat( true); + mPrevMonth->setFlat( true); + } + mSelectMonth->setFont( tfont ); + // Set minimum width to width of widest month name label + int i; + int maxwidth = 0; + QFontMetrics fm ( mSelectMonth->font() ); + int width = fm.width("September '00" ); +// for( i = 1; i <= KOGlobals::self()->calendarSystem()->monthsInYear(date); +// ++i ) { +// //int width = fm.width( KOGlobals::self()->calendarSystem()->monthName(i, +// // KOGlobals::self()->calendarSystem()->year(date) ) + " 2000" ); +// int width = fm.width("September 2000" ); +// if ( width > maxwidth ) maxwidth = width; +// } + maxwidth = width+2; + int size = fm.height()+2; + if ( QApplication::desktop()->width() >= 480 ) { + size += 6; + maxwidth+= 6; + } + mSelectMonth->setFixedWidth( maxwidth ); + mSelectMonth->setFixedHeight( size ); + mPrevYear->setFixedHeight( size ); + mPrevMonth->setFixedHeight( size ); + mNextMonth->setFixedHeight( size ); + mNextYear->setFixedHeight ( size ); + // set up control frame layout + QBoxLayout *ctrlLayout = new QHBoxLayout( mCtrlFrame, 1 ); + ctrlLayout->addWidget( mPrevYear, 3 ); + ctrlLayout->addWidget( mPrevMonth, 3 ); + //ctrlLayout->addStretch( 1 ); + // ctrlLayout->addSpacing( 1 ); + // ctrlLayout->addWidget( mDateLabel ); + ctrlLayout->addWidget( mSelectMonth ); + // ctrlLayout->addSpacing( 1 ); + // ctrlLayout->addStretch( 1 ); + ctrlLayout->addWidget( mNextMonth, 3 ); + ctrlLayout->addWidget( mNextYear, 3 ); + + connect( mPrevYear, SIGNAL( clicked() ), SIGNAL( goPrevYear() ) ); + connect( mPrevMonth, SIGNAL( clicked() ), SIGNAL( goPrevMonth() ) ); + connect( mNextMonth, SIGNAL( clicked() ), SIGNAL( goNextMonth() ) ); + connect( mNextYear, SIGNAL( clicked() ), SIGNAL( goNextYear() ) ); + connect( mSelectMonth, SIGNAL( clicked() ),SLOT( selectMonth() ) ); + mPrevYear->setFocusPolicy(NoFocus); + mPrevMonth->setFocusPolicy(NoFocus); + mNextMonth->setFocusPolicy(NoFocus); + mNextYear->setFocusPolicy(NoFocus); + mSelectMonth->setFocusPolicy(NoFocus); +} + +NavigatorBar::~NavigatorBar() +{ +} + +void NavigatorBar::selectMonth() +{ + + int month; + KPopupFrame* popup = new KPopupFrame(this); + int size = 12; + if ( QApplication::desktop()->width() >= 480 ) + size = 18; + KDateInternalMonthPicker* picker = new KDateInternalMonthPicker(size, popup); + // ----- + picker->resize(picker->sizeHint()); + popup->setMainWidget(picker); + picker->setFocus(); + connect(picker, SIGNAL(closeMe(int)), popup, SLOT(close(int))); + if(popup->exec(mSelectMonth->mapToGlobal(QPoint(0, mSelectMonth->height())))) + { + month = picker->getResult(); + emit monthSelected ( month ); + } else { + KNotifyClient::beep(); + } + delete popup; +} +void NavigatorBar::selectDates( const KCal::DateList &dateList ) +{ + if (dateList.count() > 0) { + QDate date = dateList.first(); + + const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem(); + + // compute the label at the top of the navigator + QString dtstr = i18n(calSys->monthName( date )) + " '" + + QString::number( calSys->year( date ) ).right(2); + + mSelectMonth->setText( dtstr ); + } +} + +#include "navigatorbar.moc" diff --git a/korganizer/navigatorbar.h b/korganizer/navigatorbar.h new file mode 100644 index 0000000..9c5c0cf --- a/dev/null +++ b/korganizer/navigatorbar.h @@ -0,0 +1,66 @@ +/* + This file is part of KOrganizer. + + Copyright (c) 2003 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 NAVIGATORBAR_H +#define NAVIGATORBAR_H + +#include <libkcal/incidencebase.h> + +#include <qwidget.h> + +class QPushButton; +class QFrame; +class QLabel; + +class NavigatorBar: public QWidget +{ + Q_OBJECT + public: + NavigatorBar( const QDate & date, QWidget *parent = 0, const char *name = 0 ); + ~NavigatorBar(); + + public slots: + void selectDates( const KCal::DateList & ); + void selectMonth(); + + signals: + void goNextMonth(); + void goPrevMonth(); + void goNextYear(); + void goPrevYear(); + void monthSelected( int ); + + + private: + QFrame *mCtrlFrame; + + QPushButton *mPrevYear; + QPushButton *mPrevMonth; + QPushButton *mNextMonth; + QPushButton *mNextYear; + QPushButton *mSelectMonth; + + //QLabel *mDateLabel; +}; + +#endif diff --git a/korganizer/navigatorbar.moc b/korganizer/navigatorbar.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/navigatorbar.moc diff --git a/korganizer/outgoingdialog.cpp b/korganizer/outgoingdialog.cpp new file mode 100644 index 0000000..4eb64f3 --- a/dev/null +++ b/korganizer/outgoingdialog.cpp @@ -0,0 +1,394 @@ +/* + 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. +*/ + +#include <kdebug.h> + +#include <qfile.h> +#include <qdir.h> +#include <qtextstream.h> + +#include <kglobal.h> +#include <klocale.h> +#include <ktempfile.h> +#include <kstandarddirs.h> + +#include <libkcal/event.h> +#include <libkcal/freebusy.h> +//#include <libkcal/imipscheduler.h> +#include <libkcal/dummyscheduler.h> +#include <libkcal/icalformat.h> +#include <libkcal/calendar.h> + +#ifndef KORG_NOMAIL +#include "mailscheduler.h" +#endif + +#include "koprefs.h" +#include "outgoingdialog.h" +#include "koeventviewerdialog.h" +#include "docprefs.h" + +ScheduleItemOut::ScheduleItemOut(QListView *parent,IncidenceBase *ev, + Scheduler::Method method, + const QString &recipients) + : QListViewItem(parent) +{ + mIncidence = ev; + mMethod = method; + mRecipients = recipients; + +// kdDebug() << "ScheduleItemOut: setting the summary" << endl; + //Set the summary + if(ev->type() != "FreeBusy") { + Incidence *incidence = static_cast<Incidence *>(ev); + setText(0,incidence->summary()); + } else { + setText(0,i18n("Free Busy Object")); + } + +// kdDebug() << "ScheduleItemOut: checking if the object is an event" << endl; + //If the object is an event + if(ev->type()=="Event") { + Event *event = static_cast<Event *>(ev); + + setText(1,event->dtStartDateStr()); + if (event->doesFloat()) { //If the event floats set the start and end times to no time + setText(2,i18n("no time")); + setText(4,i18n("no time")); + } else { //If it does not float + setText(2,event->dtStartTimeStr()); + if (event->hasDuration()) { + setText(4,event->dtEndTimeStr()); + } else { + setText(4,i18n("no time")); + } + } + if (event->hasEndDate()) { + setText(3,event->dtEndDateStr()); + } + else { + setText(3,i18n("no time")); + } + } + + //If the object is an Todo + if(ev->type()=="Todo") { + Todo *event = static_cast<Todo *>(ev); + if (event->hasStartDate()) { + setText(1,event->dtStartDateStr()); + if (!event->doesFloat()) { + setText(2,event->dtStartTimeStr()); + } + } + if (event->hasDueDate()) { + setText(3,event->dtDueDateStr()); + if (!event->doesFloat()) { + setText(4,event->dtDueTimeStr()); + } + } + } + +// kdDebug() << "ScheduleItemOut: checking if the object is a FreeBusy object" << endl; + //If the object is a freebusy object + if(ev->type() == "FreeBusy") { + FreeBusy *freebusy = static_cast<FreeBusy *>(ev); + + setText(1,freebusy->dtStartDateStr()); + setText(2,freebusy->dtStartTimeStr()); + //Must try and get this to the users local settings + setText(3,KGlobal::locale()->formatDate( freebusy->dtEnd().date() ) ); + setText(4,KGlobal::locale()->formatTime( freebusy->dtEnd().time() ) ); + } + +// kdDebug() << "ScheduleItemOut: Setting the method" << endl; + //Set the Method + setText(5,Scheduler::translatedMethodName(mMethod)); +} + +OutgoingDialog::OutgoingDialog(Calendar *calendar,QWidget* parent, + const char* name,bool modal, + WFlags fl) + : OutgoingDialog_base(parent,name,modal,fl) +{ + mCalendar = calendar; + + mFormat = new ICalFormat; + + if (KOPrefs::instance()->mIMIPScheduler == KOPrefs::IMIPDummy ) { + mScheduler = new DummyScheduler(mCalendar); + } else { +#ifndef KORG_NOMAIL + mScheduler = new MailScheduler(mCalendar); +#else + mScheduler = new DummyScheduler(mCalendar); +#endif + } + mMessageListView->setColumnAlignment(1,AlignHCenter); + mMessageListView->setColumnAlignment(2,AlignHCenter); + mMessageListView->setColumnAlignment(3,AlignHCenter); + mMessageListView->setColumnAlignment(4,AlignHCenter); + QObject::connect(mMessageListView,SIGNAL(doubleClicked(QListViewItem *)), + this,SLOT(showEvent(QListViewItem *))); + mDocPrefs = new DocPrefs("groupschedule"); + loadMessages(); +} + +OutgoingDialog::~OutgoingDialog() +{ + delete mDocPrefs; + delete mFormat; +} + +bool OutgoingDialog::addMessage(IncidenceBase *incidence,Scheduler::Method method) +{ + kdDebug() << "Outgoing::addMessage" << "Method:" << method << endl; + if (method == Scheduler::Publish) return false; + if( mDocPrefs ) { + if (method != Scheduler::Cancel) { + mDocPrefs->writeEntry( incidence->uid()+"-scheduled", true ); + } else { + if (!mDocPrefs->readBoolEntry(incidence->uid()+"-scheduled") ) + return true; + } + } + + if (KOPrefs::instance()->mIMIPSend == KOPrefs::IMIPOutbox) { + new ScheduleItemOut(mMessageListView,incidence,method); + saveMessage(incidence,method); + emit numMessagesChanged(mMessageListView->childCount()); + } + else { + mScheduler->performTransaction(incidence,method); + } + return true; +} + +bool OutgoingDialog::addMessage(IncidenceBase *incidence,Scheduler::Method method, + const QString &recipients) +{ + //if (method != Scheduler::Publish) return false; + if( mDocPrefs ) { + if (method != Scheduler::Cancel) { + mDocPrefs->writeEntry( incidence->uid()+"-scheduled", true ); + } else { + if (!mDocPrefs->readBoolEntry(incidence->uid()+"-scheduled") ) + return true; + } + } + if (KOPrefs::instance()->mIMIPSend == KOPrefs::IMIPOutbox) { + new ScheduleItemOut(mMessageListView,incidence,method,recipients); + saveMessage(incidence,method,recipients); + emit numMessagesChanged(mMessageListView->childCount()); + } + else { + mScheduler->performTransaction(incidence,method,recipients); + } + return true; +} + +void OutgoingDialog::send() +{ + kdDebug() << "OutgoingDialog::send" << endl; + ScheduleItemOut *item = (ScheduleItemOut *)(mMessageListView->firstChild()); + while(item) { + bool success; + if (item->method() == Scheduler::Publish) { + success = mScheduler->publish(item->event(),item->recipients()); + } else { + success = mScheduler->performTransaction(item->event(),item->method()); + } + ScheduleItemOut *oldItem = item; + item = (ScheduleItemOut *)(item->nextSibling()); + if (success) { + deleteMessage(oldItem->event()); + delete (oldItem->event()); + delete oldItem; + } + } + + emit numMessagesChanged(mMessageListView->childCount()); +} + +void OutgoingDialog::deleteItem() +{ + ScheduleItemOut *item = (ScheduleItemOut *)(mMessageListView->selectedItem()); + if(!item) + return; + deleteMessage(item->event()); + delete(item->event()); + mMessageListView->takeItem(item); + emit numMessagesChanged(mMessageListView->childCount()); +} + +void OutgoingDialog::showEvent(QListViewItem *qitem) +{ + ScheduleItemOut *item = (ScheduleItemOut *)qitem; + Event *event = 0; + Todo *todo = 0; + if ( item->event()->type()=="Event" ) { + event = static_cast<Event *>(item->event()); + } + if ( item->event()->type()=="Todo" ) { + todo = static_cast<Todo *>(item->event()); + } + QString sendText; + if (event || todo) { + KOEventViewerDialog *eventViewer = new KOEventViewerDialog(this); + if (event) eventViewer->setEvent(event); + if (todo) eventViewer->setTodo(todo); + sendText = "<hr><h4>"+i18n("Event will be sent to:")+"</h4>"; + switch (item->method()) { + case Scheduler::Publish: { + sendText += item->recipients(); + break; } + case Scheduler::Request: { + sendText += i18n("All attendees"); + break; } + case Scheduler::Refresh: { + sendText += i18n("All attendees"); + break; } + case Scheduler::Cancel: { + sendText += i18n("All attendees"); + break; } + case Scheduler::Add: { + sendText += i18n("All attendees"); + break; } + case Scheduler::Reply: { + sendText += i18n("The organizer %1").arg(item->event()->organizer()); + break; } + case Scheduler::Counter: { + sendText += i18n("The organizer %1").arg(item->event()->organizer()); + break; } + case Scheduler::Declinecounter: { + sendText += i18n("All attendees"); + break; } + case Scheduler::NoMethod: { + sendText += ""; + break; } + default: + sendText = ""; + } + eventViewer->addText(sendText); + eventViewer->show(); + } +} + +bool OutgoingDialog::saveMessage(IncidenceBase *incidence,Scheduler::Method method, + const QString &recipients) +{ + KTempFile ktfile(locateLocal("data","korganizer/outgoing/"),"ics"); + QString messageText = mFormat->createScheduleMessage(incidence,method); + QTextStream *qts = ktfile.textStream(); + *qts << messageText; + *qts << "METHOD-BEGIN:" << endl << method << endl << ":METHOD-END" << endl; + *qts << "RECIPIENTS-BEGIN:" << endl << recipients << endl << ":RECIPIENTS-END" << endl; + mMessageMap[incidence]=ktfile.name(); + + return true; +} + +bool OutgoingDialog::deleteMessage(IncidenceBase *incidence) +{ + QFile f( mMessageMap[incidence] ); + mMessageMap.remove(incidence); + if ( !f.exists() ) return false; + else + return f.remove(); +} + +void OutgoingDialog::loadMessages() +{ + Scheduler::Method method; + QString recipients; + + QString outgoingDirName = locateLocal("data","korganizer/outgoing"); + QDir outgoingDir(outgoingDirName); + QStringList outgoing = outgoingDir.entryList(QDir::Files); + QStringList::ConstIterator it; + for(it = outgoing.begin(); it != outgoing.end(); ++it) { + kdDebug() << "-- File: " << (*it) << endl; + QFile f(outgoingDirName + "/" + (*it)); + bool inserted = false; + QMap<IncidenceBase*, QString>::Iterator iter; + for ( iter = mMessageMap.begin(); iter != mMessageMap.end(); ++iter ) { + if (iter.data() == outgoingDirName + "/" + (*it)) inserted = true; + } + if (!inserted) { + if (!f.open(IO_ReadOnly)) { + kdDebug() << "OutgoingDialog::loadMessage(): Can't open file'" + << (*it) << "'" << endl; + } else { + QTextStream t(&f); + QString messageString = t.read(); + ScheduleMessage *message = mFormat->parseScheduleMessage(mCalendar, + messageString); + int begin_pos = messageString.find("METHOD-BEGIN:"); + begin_pos = messageString.find('\n',begin_pos)+1; + QString meth = messageString.mid(begin_pos,1); + switch (meth.toInt()) { + case 0:method=Scheduler::Publish; break; + case 1:method=Scheduler::Request; break; + case 2:method=Scheduler::Refresh; break; + case 3:method=Scheduler::Cancel; break; + case 4:method=Scheduler::Add; break; + case 5:method=Scheduler::Reply; break; + case 6:method=Scheduler::Counter; break; + case 7:method=Scheduler::Declinecounter; break; + default :method=Scheduler::NoMethod; break; + } + begin_pos = messageString.find("RECIPIENTS-BEGIN:"); + begin_pos = messageString.find('\n',begin_pos)+1; + int end_pos = messageString.find(":RECIPIENTS-END",begin_pos)-1; + recipients = messageString.mid(begin_pos, end_pos-begin_pos); + kdDebug() << "Outgoing::loadMessage(): Recipients: " << recipients << endl; + + if (message) { + bool inserted = false; + QMap<IncidenceBase*, QString>::Iterator iter; + for ( iter = mMessageMap.begin(); iter != mMessageMap.end(); ++iter ) { + if (iter.data() == outgoingDirName + "/" + (*it)) inserted = true; + } + if (!inserted) { + kdDebug() << "OutgoingDialog::loadMessage(): got message '" + << (*it) << "'" << endl; + IncidenceBase *inc = message->event(); + new ScheduleItemOut(mMessageListView,inc,method,recipients); + mMessageMap[message->event()]=outgoingDirName + "/" + (*it); + } + } else { + QString errorMessage; + if (mFormat->exception()) { + errorMessage = mFormat->exception()->message(); + } + kdDebug() << "OutgoingDialog::loadMessage(): Error parsing " + "message: " << errorMessage << endl; + } + f.close(); + } + } + } + emit numMessagesChanged(mMessageListView->childCount()); +} + +void OutgoingDialog::setDocumentId( const QString &id ) +{ + mDocPrefs->setDoc( id ); +} + +#include "outgoingdialog.moc" diff --git a/korganizer/outgoingdialog.h b/korganizer/outgoingdialog.h new file mode 100644 index 0000000..a3d561a --- a/dev/null +++ b/korganizer/outgoingdialog.h @@ -0,0 +1,88 @@ +/* + 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 OUTGOINGDIALOG_H +#define OUTGOINGDIALOG_H + +#include <qlistview.h> +#include <qmap.h> +#include <qstring.h> + +#include <libkcal/scheduler.h> + +#include "docprefs.h" +#include "outgoingdialog_base.h" + +using namespace KCal; + +class ScheduleItemOut : public QListViewItem +{ + public: + ScheduleItemOut(QListView *parent,IncidenceBase *ev, + Scheduler::Method method, const QString &recipients=QString::null); + virtual ~ScheduleItemOut() {} + + IncidenceBase *event() { return mIncidence; } + Scheduler::Method method() { return mMethod; } + QString recipients() { return mRecipients; } + + private: + IncidenceBase *mIncidence; + Scheduler::Method mMethod; + QString mRecipients; +}; + +class OutgoingDialog : public OutgoingDialog_base +{ + Q_OBJECT + public: + OutgoingDialog(Calendar *,QWidget* parent=0,const char* name=0, + bool modal=false,WFlags fl=0); + ~OutgoingDialog(); + + bool addMessage(IncidenceBase *,Scheduler::Method); + bool addMessage(IncidenceBase *,Scheduler::Method,const QString &recipients); + void setDocumentId( const QString &id ); + + public slots: + void loadMessages(); + + signals: + void numMessagesChanged(int); + + protected slots: + void send(); + void deleteItem(); + void showEvent(QListViewItem *); + + private: + bool saveMessage(IncidenceBase *,Scheduler::Method,const QString &recipients=0); + bool deleteMessage(IncidenceBase *); + + Calendar *mCalendar; + ICalFormat *mFormat; + Scheduler *mScheduler; + QMap<IncidenceBase*, QString> mMessageMap; + DocPrefs *mDocPrefs; +}; + +#endif // OUTGOINGDIALOG_H diff --git a/korganizer/outgoingdialog.moc b/korganizer/outgoingdialog.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/outgoingdialog.moc diff --git a/korganizer/outgoingdialog_base.cpp b/korganizer/outgoingdialog_base.cpp new file mode 100644 index 0000000..e5b913a --- a/dev/null +++ b/korganizer/outgoingdialog_base.cpp @@ -0,0 +1,109 @@ +#include <klocale.h> +/**************************************************************************** +** Form implementation generated from reading ui file '/build/kde/cvs/korge/kdepim/korganizer/outgoingdialog_base.ui' +** +** Created: Sat Mar 29 22:31:21 2003 +** by: The User Interface Compiler () +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#include "outgoingdialog_base.h" + +#include <qvariant.h> +#include <qheader.h> +#include <qlistview.h> +#include <qpushbutton.h> +#include <qlayout.h> +#include <qtooltip.h> +#include <qwhatsthis.h> + +/* + * Constructs a OutgoingDialog_base as a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +OutgoingDialog_base::OutgoingDialog_base( QWidget* parent, const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, fl ) + +{ + if ( !name ) + setName( "OutgoingDialog_base" ); + OutgoingDialog_baseLayout = new QGridLayout( this, 1, 1, 11, 6, "OutgoingDialog_baseLayout"); + + mMessageListView = new QListView( this, "mMessageListView" ); + mMessageListView->addColumn( tr2i18n( "Summary" ) ); + mMessageListView->addColumn( tr2i18n( "Start Date" ) ); + mMessageListView->addColumn( tr2i18n( "Start Time" ) ); + mMessageListView->addColumn( tr2i18n( "End Date" ) ); + mMessageListView->addColumn( tr2i18n( "End Time" ) ); + mMessageListView->addColumn( tr2i18n( "Method" ) ); + mMessageListView->setFrameShape( QListView::StyledPanel ); + mMessageListView->setFrameShadow( QListView::Sunken ); + mMessageListView->setAllColumnsShowFocus( TRUE ); + + OutgoingDialog_baseLayout->addMultiCellWidget( mMessageListView, 0, 3, 0, 0 ); + + PushButton5 = new QPushButton( this, "PushButton5" ); + PushButton5->setDefault( FALSE ); + + OutgoingDialog_baseLayout->addWidget( PushButton5, 0, 1 ); + + PushButton7 = new QPushButton( this, "PushButton7" ); + + OutgoingDialog_baseLayout->addWidget( PushButton7, 1, 1 ); + + PushButton6 = new QPushButton( this, "PushButton6" ); + PushButton6->setDefault( TRUE ); + + OutgoingDialog_baseLayout->addWidget( PushButton6, 3, 1 ); + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding ); + OutgoingDialog_baseLayout->addItem( spacer, 2, 1 ); + languageChange(); + resize( QSize(582, 274).expandedTo(minimumSizeHint()) ); + + // signals and slots connections + connect( PushButton6, SIGNAL( clicked() ), this, SLOT( accept() ) ); + connect( PushButton5, SIGNAL( clicked() ), this, SLOT( send() ) ); + connect( PushButton7, SIGNAL( clicked() ), this, SLOT( deleteItem() ) ); +} + +/* + * Destroys the object and frees any allocated resources + */ +OutgoingDialog_base::~OutgoingDialog_base() +{ + // no need to delete child widgets, Qt does it all for us +} + +/* + * Sets the strings of the subwidgets using the current + * language. + */ +void OutgoingDialog_base::languageChange() +{ + setCaption( tr2i18n( "Scheduler - Outgoing Messages" ) ); + mMessageListView->header()->setLabel( 0, tr2i18n( "Summary" ) ); + mMessageListView->header()->setLabel( 1, tr2i18n( "Start Date" ) ); + mMessageListView->header()->setLabel( 2, tr2i18n( "Start Time" ) ); + mMessageListView->header()->setLabel( 3, tr2i18n( "End Date" ) ); + mMessageListView->header()->setLabel( 4, tr2i18n( "End Time" ) ); + mMessageListView->header()->setLabel( 5, tr2i18n( "Method" ) ); + PushButton5->setText( tr2i18n( "&Send Messages" ) ); + PushButton7->setText( tr2i18n( "&Remove" ) ); + PushButton6->setText( tr2i18n( "&Close" ) ); +} + +void OutgoingDialog_base::send() +{ + qWarning( "OutgoingDialog_base::send(): Not implemented yet" ); +} + +void OutgoingDialog_base::deleteItem() +{ + qWarning( "OutgoingDialog_base::deleteItem(): Not implemented yet" ); +} + +#include "outgoingdialog_base.moc" diff --git a/korganizer/outgoingdialog_base.h b/korganizer/outgoingdialog_base.h new file mode 100644 index 0000000..af71bb1 --- a/dev/null +++ b/korganizer/outgoingdialog_base.h @@ -0,0 +1,47 @@ +/**************************************************************************** +** Form interface generated from reading ui file '/build/kde/cvs/korge/kdepim/korganizer/outgoingdialog_base.ui' +** +** Created: Sat Mar 29 22:24:26 2003 +** by: The User Interface Compiler () +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#ifndef OUTGOINGDIALOG_BASE_H +#define OUTGOINGDIALOG_BASE_H + +#include <qvariant.h> +#include <qdialog.h> + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QListView; +class QListViewItem; +class QPushButton; + +class OutgoingDialog_base : public QDialog +{ + Q_OBJECT + +public: + OutgoingDialog_base( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~OutgoingDialog_base(); + + QListView* mMessageListView; + QPushButton* PushButton5; + QPushButton* PushButton7; + QPushButton* PushButton6; + +protected: + QGridLayout* OutgoingDialog_baseLayout; + +protected slots: + virtual void languageChange(); + + virtual void send(); + virtual void deleteItem(); + +}; + +#endif // OUTGOINGDIALOG_BASE_H diff --git a/korganizer/outgoingdialog_base.moc b/korganizer/outgoingdialog_base.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/outgoingdialog_base.moc diff --git a/korganizer/publishdialog.cpp b/korganizer/publishdialog.cpp new file mode 100644 index 0000000..176595a --- a/dev/null +++ b/korganizer/publishdialog.cpp @@ -0,0 +1,152 @@ +/* + 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. +*/ + +#include <qlineedit.h> +#include <kdebug.h> + +#include <kglobal.h> +#include <klocale.h> +#ifndef KORG_NOKABC +#include <kabc/addresseedialog.h> +#endif + +#include "koprefs.h" +#include "publishdialog.h" + +PublishDialog::PublishDialog(QWidget* parent, const char* name, + bool modal, WFlags fl) + : PublishDialog_base(parent,name,modal,fl) +{ + setCaption(i18n("Select Addresses")); + mNameLineEdit->setEnabled(false); + mEmailLineEdit->setEnabled(false); + connect(mAddressListView,SIGNAL(selectionChanged(QListViewItem *)), + SLOT(updateInput())); +} + +PublishDialog::~PublishDialog() +{ +} + +void PublishDialog::addAttendee(Attendee *attendee) +{ + mNameLineEdit->setEnabled(true); + mEmailLineEdit->setEnabled(true); + QListViewItem *item = new QListViewItem(mAddressListView); + item->setText(0,attendee->name()); + item->setText(1,attendee->email()); + mAddressListView->insertItem(item); +} + +QString PublishDialog::addresses() +{ + QString to = ""; + QListViewItem *item; + int i, count; + count = mAddressListView->childCount(); + for (i=0;i<count;i++) { + item = mAddressListView->firstChild(); + mAddressListView->takeItem(item); + to += item->text(1); + if (i<count-1) { + to += ", "; + } + } + return to; +} + +void PublishDialog::addItem() +{ + mNameLineEdit->setEnabled(true); + mEmailLineEdit->setEnabled(true); + QListViewItem *item = new QListViewItem(mAddressListView); + mAddressListView->insertItem(item); + mAddressListView->setSelected(item,true); + mNameLineEdit->setText(i18n("(EmptyName)")); + mEmailLineEdit->setText(i18n("(EmptyEmail)")); +} + +void PublishDialog::removeItem() +{ + QListViewItem *item; + item = mAddressListView->selectedItem(); + if (!item) return; + mAddressListView->takeItem(item); + item = mAddressListView->selectedItem(); + if (!item) { + mNameLineEdit->setText(""); + mEmailLineEdit->setText(""); + mNameLineEdit->setEnabled(false); + mEmailLineEdit->setEnabled(false); + } + if (mAddressListView->childCount() == 0) { + mNameLineEdit->setEnabled(false); + mEmailLineEdit->setEnabled(false); + } +} + +void PublishDialog::openAddressbook() +{ +#ifndef KORG_NOKABC + KABC::Addressee::List addressList; + addressList = KABC::AddresseeDialog::getAddressees(this); + //KABC::Addressee a = KABC::AddresseeDialog::getAddressee(this); + KABC::Addressee a = addressList.first(); + if (!a.isEmpty()) { + uint i; + for (i=0;i<addressList.count();i++) { + a = addressList[i]; + mNameLineEdit->setEnabled(true); + mEmailLineEdit->setEnabled(true); + QListViewItem *item = new QListViewItem(mAddressListView); + mAddressListView->setSelected(item,true); + mNameLineEdit->setText(a.realName()); + mEmailLineEdit->setText(a.preferredEmail()); + mAddressListView->insertItem(item); + } + } +#endif +} + +void PublishDialog::updateItem() +{ + QListViewItem *item; + item = mAddressListView->selectedItem(); + if (!item) return; + item->setText(0,mNameLineEdit->text()); + item->setText(1,mEmailLineEdit->text()); +} + +void PublishDialog::updateInput() +{ + QListViewItem *item; + item = mAddressListView->selectedItem(); + if (!item) return; + mNameLineEdit->setEnabled(true); + mEmailLineEdit->setEnabled(true); + QString mail = item->text(1); + mNameLineEdit->setText(item->text(0)); + mEmailLineEdit->setText(mail); +} + +#include "publishdialog.moc" diff --git a/korganizer/publishdialog.h b/korganizer/publishdialog.h new file mode 100644 index 0000000..338603c --- a/dev/null +++ b/korganizer/publishdialog.h @@ -0,0 +1,55 @@ +/* + 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 PUBLISHDIALOG_H +#define PUBLISHDIALOG_H + +#include <qlistview.h> +#include <libkcal/attendee.h> + +#include "publishdialog_base.h" + +using namespace KCal; + +class PublishDialog : public PublishDialog_base +{ + Q_OBJECT + public: + PublishDialog(QWidget* parent=0,const char* name=0, + bool modal=true,WFlags fl=0); + ~PublishDialog(); + + void addAttendee(Attendee *attendee); + QString addresses(); + + signals: + void numMessagesChanged(int); + + protected slots: + void addItem(); + void removeItem(); + void openAddressbook(); + void updateItem(); + void updateInput(); +}; + +#endif // OUTGOINGDIALOG_H diff --git a/korganizer/publishdialog.moc b/korganizer/publishdialog.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/publishdialog.moc diff --git a/korganizer/publishdialog_base.cpp b/korganizer/publishdialog_base.cpp new file mode 100644 index 0000000..75e4746 --- a/dev/null +++ b/korganizer/publishdialog_base.cpp @@ -0,0 +1,162 @@ +#include <klocale.h> +/**************************************************************************** +** Form implementation generated from reading ui file '/build/kde/cvs/korge/kdepim/korganizer/publishdialog_base.ui' +** +** Created: Sat Mar 29 22:31:35 2003 +** by: The User Interface Compiler () +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#include "publishdialog_base.h" + +#include <qvariant.h> +#include <qframe.h> +#include <qheader.h> +#include <qlabel.h> +#include <qlineedit.h> +#include <qlistview.h> +#include <qpushbutton.h> +#include <qlayout.h> +#include <qtooltip.h> +#include <qwhatsthis.h> + +/* + * Constructs a PublishDialog_base as a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +PublishDialog_base::PublishDialog_base( QWidget* parent, const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, fl ) + +{ + if ( !name ) + setName( "PublishDialog_base" ); + PublishDialog_baseLayout = new QGridLayout( this, 1, 1, 11, 6, "PublishDialog_baseLayout"); + + mAddressListView = new QListView( this, "mAddressListView" ); + mAddressListView->addColumn( tr2i18n( "Name" ) ); + mAddressListView->addColumn( tr2i18n( "Email" ) ); + + PublishDialog_baseLayout->addMultiCellWidget( mAddressListView, 0, 3, 0, 1 ); + + TextLabel1 = new QLabel( this, "TextLabel1" ); + + PublishDialog_baseLayout->addWidget( TextLabel1, 4, 0 ); + + TextLabel2 = new QLabel( this, "TextLabel2" ); + + PublishDialog_baseLayout->addWidget( TextLabel2, 5, 0 ); + + mEmailLineEdit = new QLineEdit( this, "mEmailLineEdit" ); + + PublishDialog_baseLayout->addWidget( mEmailLineEdit, 5, 1 ); + + mNameLineEdit = new QLineEdit( this, "mNameLineEdit" ); + + PublishDialog_baseLayout->addWidget( mNameLineEdit, 4, 1 ); + + PushButton10 = new QPushButton( this, "PushButton10" ); + + PublishDialog_baseLayout->addWidget( PushButton10, 0, 2 ); + + PushButton12 = new QPushButton( this, "PushButton12" ); + + PublishDialog_baseLayout->addWidget( PushButton12, 2, 2 ); + + PushButton11 = new QPushButton( this, "PushButton11" ); + + PublishDialog_baseLayout->addWidget( PushButton11, 1, 2 ); + QSpacerItem* spacer = new QSpacerItem( 20, 241, QSizePolicy::Minimum, QSizePolicy::Expanding ); + PublishDialog_baseLayout->addMultiCell( spacer, 3, 5, 2, 2 ); + + Line2 = new QFrame( this, "Line2" ); + Line2->setFrameShape( QFrame::HLine ); + Line2->setFrameShadow( QFrame::Sunken ); + Line2->setFrameShape( QFrame::HLine ); + + PublishDialog_baseLayout->addMultiCellWidget( Line2, 6, 6, 0, 2 ); + + layout95 = new QHBoxLayout( 0, 0, 6, "layout95"); + QSpacerItem* spacer_2 = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + layout95->addItem( spacer_2 ); + + PushButton9 = new QPushButton( this, "PushButton9" ); + PushButton9->setDefault( TRUE ); + layout95->addWidget( PushButton9 ); + + PushButton8 = new QPushButton( this, "PushButton8" ); + layout95->addWidget( PushButton8 ); + + PublishDialog_baseLayout->addMultiCellLayout( layout95, 7, 7, 0, 2 ); + languageChange(); + resize( QSize(420, 379).expandedTo(minimumSizeHint()) ); + + // signals and slots connections + connect( PushButton10, SIGNAL( clicked() ), this, SLOT( addItem() ) ); + connect( PushButton11, SIGNAL( clicked() ), this, SLOT( removeItem() ) ); + connect( PushButton12, SIGNAL( clicked() ), this, SLOT( openAddressbook() ) ); + connect( PushButton9, SIGNAL( clicked() ), this, SLOT( accept() ) ); + connect( mNameLineEdit, SIGNAL( textChanged(const QString&) ), this, SLOT( updateItem() ) ); + connect( mEmailLineEdit, SIGNAL( textChanged(const QString&) ), this, SLOT( updateItem() ) ); + connect( PushButton8, SIGNAL( clicked() ), this, SLOT( reject() ) ); + + // tab order + setTabOrder( mAddressListView, mNameLineEdit ); + setTabOrder( mNameLineEdit, mEmailLineEdit ); + setTabOrder( mEmailLineEdit, PushButton10 ); + setTabOrder( PushButton10, PushButton11 ); + setTabOrder( PushButton11, PushButton12 ); + setTabOrder( PushButton12, PushButton9 ); + setTabOrder( PushButton9, PushButton8 ); +} + +/* + * Destroys the object and frees any allocated resources + */ +PublishDialog_base::~PublishDialog_base() +{ + // no need to delete child widgets, Qt does it all for us +} + +/* + * Sets the strings of the subwidgets using the current + * language. + */ +void PublishDialog_base::languageChange() +{ + setCaption( tr2i18n( "Form1" ) ); + mAddressListView->header()->setLabel( 0, tr2i18n( "Name" ) ); + mAddressListView->header()->setLabel( 1, tr2i18n( "Email" ) ); + TextLabel1->setText( tr2i18n( "Name:" ) ); + TextLabel2->setText( tr2i18n( "Email:" ) ); + PushButton10->setText( tr2i18n( "&New" ) ); + PushButton12->setText( tr2i18n( "&Addressbook" ) ); + PushButton11->setText( tr2i18n( "&Remove" ) ); + PushButton9->setText( tr2i18n( "&OK" ) ); + PushButton8->setText( tr2i18n( "&Cancel" ) ); +} + +void PublishDialog_base::addItem() +{ + qWarning( "PublishDialog_base::addItem(): Not implemented yet" ); +} + +void PublishDialog_base::removeItem() +{ + qWarning( "PublishDialog_base::removeItem(): Not implemented yet" ); +} + +void PublishDialog_base::openAddressbook() +{ + qWarning( "PublishDialog_base::openAddressbook(): Not implemented yet" ); +} + +void PublishDialog_base::updateItem() +{ + qWarning( "PublishDialog_base::updateItem(): Not implemented yet" ); +} + +#include "publishdialog_base.moc" diff --git a/korganizer/publishdialog_base.h b/korganizer/publishdialog_base.h new file mode 100644 index 0000000..932474e --- a/dev/null +++ b/korganizer/publishdialog_base.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** Form interface generated from reading ui file '/build/kde/cvs/korge/kdepim/korganizer/publishdialog_base.ui' +** +** Created: Sat Mar 29 22:24:27 2003 +** by: The User Interface Compiler () +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#ifndef PUBLISHDIALOG_BASE_H +#define PUBLISHDIALOG_BASE_H + +#include <qvariant.h> +#include <qdialog.h> + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QFrame; +class QLabel; +class QLineEdit; +class QListView; +class QListViewItem; +class QPushButton; + +class PublishDialog_base : public QDialog +{ + Q_OBJECT + +public: + PublishDialog_base( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~PublishDialog_base(); + + QListView* mAddressListView; + QLabel* TextLabel1; + QLabel* TextLabel2; + QLineEdit* mEmailLineEdit; + QLineEdit* mNameLineEdit; + QPushButton* PushButton10; + QPushButton* PushButton12; + QPushButton* PushButton11; + QFrame* Line2; + QPushButton* PushButton9; + QPushButton* PushButton8; + +protected: + QGridLayout* PublishDialog_baseLayout; + QHBoxLayout* layout95; + +protected slots: + virtual void languageChange(); + + virtual void addItem(); + virtual void removeItem(); + virtual void openAddressbook(); + virtual void updateItem(); + +}; + +#endif // PUBLISHDIALOG_BASE_H diff --git a/korganizer/publishdialog_base.moc b/korganizer/publishdialog_base.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/publishdialog_base.moc diff --git a/korganizer/resourceview.h b/korganizer/resourceview.h new file mode 100644 index 0000000..0cac495 --- a/dev/null +++ b/korganizer/resourceview.h @@ -0,0 +1,8 @@ +#ifndef MICRO_KORG_RESOURCEVIEW_H +#define MICRO_KORG_RESOURCEVIEW_H + +class ResourceView +{ +}; + +#endif diff --git a/korganizer/savetemplatedialog.cpp b/korganizer/savetemplatedialog.cpp new file mode 100644 index 0000000..0da524f --- a/dev/null +++ b/korganizer/savetemplatedialog.cpp @@ -0,0 +1,76 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2002 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. +*/ + +#include <qlayout.h> + +#include <keditlistbox.h> +#include <klocale.h> + +#include "koprefs.h" + +#include "savetemplatedialog.h" +#include "savetemplatedialog.moc" + +SaveTemplateDialog::SaveTemplateDialog( IncidenceType type, QWidget *parent ) + : KDialogBase( Plain, i18n("Save Template"), Ok | Cancel, Ok, parent, 0, + true, false ), + mType( type ) +{ + QFrame *topFrame = plainPage(); + QVBoxLayout *topLayout = new QVBoxLayout( topFrame, 0, spacingHint() ); + + mEditListBox = new KEditListBox( i18n("Select Template Name"), topFrame, + 0, false, KEditListBox::Add | + KEditListBox::Remove ); + topLayout->addWidget( mEditListBox ); + connect( mEditListBox, SIGNAL( changed() ), SLOT( slotChanged() ) ); + + QStringList templates; + + if ( mType == EventType ) { + templates = KOPrefs::instance()->mEventTemplates; + } else if( mType == TodoType ) { + templates = KOPrefs::instance()->mTodoTemplates; + } + + mEditListBox->insertStringList( templates ); +} + +SaveTemplateDialog::~SaveTemplateDialog() +{ +} + +void SaveTemplateDialog::slotOk() +{ + emit templateSelected( mEditListBox->currentText() ); + accept(); +} + +void SaveTemplateDialog::slotChanged() +{ + if ( mType == EventType ) { + KOPrefs::instance()->mEventTemplates = mEditListBox->items(); + } else if( mType == TodoType ) { + KOPrefs::instance()->mTodoTemplates = mEditListBox->items(); + } +} diff --git a/korganizer/savetemplatedialog.h b/korganizer/savetemplatedialog.h new file mode 100644 index 0000000..7e54bee --- a/dev/null +++ b/korganizer/savetemplatedialog.h @@ -0,0 +1,53 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2002 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 SAVETEMPLATEDIALOG_H +#define SAVETEMPLATEDIALOG_H + +#include <kdialogbase.h> + +class KEditListBox; + +class SaveTemplateDialog : public KDialogBase +{ + Q_OBJECT + public: + enum IncidenceType { EventType, TodoType }; + + SaveTemplateDialog( IncidenceType type, QWidget *parent = 0 ); + virtual ~SaveTemplateDialog(); + + signals: + void templateSelected( const QString & ); + + protected slots: + void slotOk(); + + void slotChanged(); + + private: + IncidenceType mType; + + KEditListBox *mEditListBox; +}; + +#endif diff --git a/korganizer/savetemplatedialog.moc b/korganizer/savetemplatedialog.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/savetemplatedialog.moc diff --git a/korganizer/searchdialog.cpp b/korganizer/searchdialog.cpp new file mode 100644 index 0000000..74d48b9 --- a/dev/null +++ b/korganizer/searchdialog.cpp @@ -0,0 +1,396 @@ +/* + This file is part of KOrganizer. + Copyright (c) 1998 Preston Brown + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qlayout.h> +#include <qcheckbox.h> +#include <qgroupbox.h> +#include <qlabel.h> +#include <qlineedit.h> +#include <qpushbutton.h> + +#include <klocale.h> +#include <kmessagebox.h> + +#include <libkdepim/kdateedit.h> + +#include "koglobals.h" +#include "koprefs.h" + +#include "calendarview.h" +#include "koviewmanager.h" +#include "searchdialog.h" +#include "searchdialog.moc" + +SearchDialog::SearchDialog(Calendar *calendar,CalendarView *parent) + : KDialogBase(Plain,i18n("KO/Pi Find "),User1|Close,User1,parent,0,false,false, + i18n("&Find")) +{ + mCalendar = calendar; + QFrame *topFrame = plainPage(); + QVBoxLayout *layout = new QVBoxLayout(topFrame,0,spacingHint()); + + // Search expression + QHBoxLayout *subLayout = new QHBoxLayout(); + layout->addLayout(subLayout); + + searchLabel = new QLabel(topFrame); + searchLabel->setText(i18n("Search for:")); + subLayout->addWidget(searchLabel); + + searchEdit = new QLineEdit(topFrame); + subLayout->addWidget(searchEdit); + searchEdit->setText("*"); // Find all events by default + searchEdit->setFocus(); + connect(searchEdit, SIGNAL(textChanged ( const QString & )),this,SLOT(searchTextChanged( const QString & ))); + connect(searchEdit, SIGNAL( returnPressed () ),this,SLOT(doSearch())); + // Subjects to search + // QGroupBox *subjectGroup = new QGroupBox(1,Vertical,i18n("Search In"), + // topFrame); + + + + QHBox *incidenceGroup = new QHBox( topFrame ); + layout->addWidget(incidenceGroup); + + mSearchEvent = new QCheckBox(i18n("Events"),incidenceGroup); + mSearchEvent->setChecked(true); + mSearchTodo = new QCheckBox(i18n("Todos"),incidenceGroup); + mSearchJournal = new QCheckBox(i18n("Journals"),incidenceGroup); + + QHBox *subjectGroup = new QHBox( topFrame ); + layout->addWidget(subjectGroup); + + mSummaryCheck = new QCheckBox(i18n("Summaries"),subjectGroup); + mSummaryCheck->setChecked(true); + mDescriptionCheck = new QCheckBox(i18n("Descriptions"),subjectGroup); + mCategoryCheck = new QCheckBox(i18n("Categories"),subjectGroup); + + QHBox *attendeeGroup = new QHBox( topFrame ); + layout->addWidget(attendeeGroup ); + new QLabel( i18n("Attendee:"),attendeeGroup ); + mSearchAName = new QCheckBox(i18n("Name"),attendeeGroup ); + mSearchAEmail = new QCheckBox(i18n("Email"), attendeeGroup ); + // Date range + // QGroupBox *rangeGroup = new QGroupBox(1,Horizontal,i18n("Date Range"), + // topFrame); + // layout->addWidget(rangeGroup); + + QWidget *rangeWidget = new QWidget(topFrame); + QHBoxLayout *rangeLayout = new QHBoxLayout(rangeWidget,0,spacingHint()); + + rangeLayout->addWidget(new QLabel(i18n("From:"),rangeWidget)); + mStartDate = new KDateEdit(rangeWidget); + rangeLayout->addWidget(mStartDate); + rangeLayout->addWidget(new QLabel(i18n("To:"),rangeWidget)); + mEndDate = new KDateEdit(rangeWidget); + mEndDate->setDate(QDate::currentDate().addDays(365)); + rangeLayout->addWidget(mEndDate); + + // mInclusiveCheck = new QCheckBox(i18n("Events have to be completely included"), topFrame); + //mInclusiveCheck->setChecked(false); + layout->addWidget(rangeWidget); + //layout->addWidget(mInclusiveCheck); + // Subjects to search + + + // Results list view + listView = new KOListView(mCalendar,topFrame); + //listView->showDates(); + + + layout->addWidget(listView); + + // if ( KOPrefs::instance()->mCompactDialogs ) { + // KOGlobals::fitDialogToScreen( this, true ); + // } + + listView->readSettings(KOGlobals::config(),"SearchListView Layout"); + connect(this,SIGNAL(user1Clicked()),SLOT(doSearch())); + QPushButton *CloseButton = findButton( Close ); + //connect(CloseButton,SIGNAL(clicked()),listView, SLOT(clear())); + +#ifndef DESKTOP_VERSION + setCaption(i18n("Click OK to search ->")); + hideButtons(); +#endif +} + +SearchDialog::~SearchDialog() +{ + +} +void SearchDialog::accept() +{ + doSearch(); +} +void SearchDialog::updateList() +{ + //listView->updateList(); + if ( isVisible() ) { + updateView(); + //qDebug("SearchDialog::updated "); + } + else { + listView->clear(); + //qDebug("SearchDialog::cleared "); + + } +} +void SearchDialog::searchTextChanged( const QString &_text ) +{ + enableButton( KDialogBase::User1, !_text.isEmpty() ); +} + +void SearchDialog::doSearch() +{ + QRegExp re; + + re.setWildcard(true); // most people understand these better. + re.setCaseSensitive(false); + re.setPattern(searchEdit->text()); + if (!re.isValid() ) { + KMessageBox::sorry(this, + i18n("Invalid search expression,\ncannot perform " + "the search.\nPlease enter a search expression\n" + "using the wildcard characters\n '*' and '?'" + "where needed.")); + return; + } + + search(re); + + listView->setStartDate( mStartDate->date() ); + listView->showEvents(mMatchedEvents); + listView->addTodos(mMatchedTodos); + listView->addJournals(mMatchedJournals); + + if (mMatchedEvents.count() + mMatchedJournals.count() + mMatchedTodos.count() == 0) { + KMessageBox::information(this, + i18n("No event/todo were found matching\nyour search expression.\nUse the wildcard characters\n ' * ' and ' ? ' where needed.")); +#ifndef DESKTOP_VERSION + setCaption(i18n("Click OK to search ->")); +#else + setCaption(i18n("KO/Pi Find ")); +#endif + } else { + QString mess; + mess = mess.sprintf( i18n("%d item(s) found."), mMatchedEvents.count()+ mMatchedJournals.count() + mMatchedTodos.count() ); + setCaption( i18n("KO/Pi Find: ") + mess); + + } +} +void SearchDialog::updateConfig() +{ + listView->updateConfig(); +} +void SearchDialog::updateView() +{ + + QRegExp re; + re.setWildcard(true); // most people understand these better. + re.setCaseSensitive(false); + re.setPattern(searchEdit->text()); + if (re.isValid()) { + search(re); + } else { + mMatchedEvents.clear(); + mMatchedTodos.clear(); + mMatchedJournals.clear(); + } + listView->setStartDate( mStartDate->date() ); + listView->showEvents(mMatchedEvents); + listView->addTodos(mMatchedTodos); + listView->addJournals(mMatchedJournals); +} + +void SearchDialog::search(const QRegExp &re) +{ + QPtrList<Event> events = mCalendar->events( mStartDate->date(), + mEndDate->date(), + false /*mInclusiveCheck->isChecked()*/ ); + + mMatchedEvents.clear(); + if ( mSearchEvent->isChecked() ) { + Event *ev; + for(ev=events.first();ev;ev=events.next()) { + if (mSummaryCheck->isChecked()) { +#if QT_VERSION >= 300 + if (re.search(ev->summary()) != -1) +#else + if (re.match(ev->summary()) != -1) +#endif + { + mMatchedEvents.append(ev); + continue; + } + } + if (mDescriptionCheck->isChecked()) { +#if QT_VERSION >= 300 + if (re.search(ev->description()) != -1) +#else + if (re.match(ev->description()) != -1) +#endif + { + mMatchedEvents.append(ev); + continue; + } + } + if (mCategoryCheck->isChecked()) { +#if QT_VERSION >= 300 + if (re.search(ev->categoriesStr()) != -1) +#else + if (re.match(ev->categoriesStr()) != -1) +#endif + { + mMatchedEvents.append(ev); + continue; + } + } + if ( mSearchAName->isChecked() || mSearchAEmail->isChecked() ) { + QPtrList<Attendee> tmpAList = ev->attendees(); + Attendee *a; + for (a = tmpAList.first(); a; a = tmpAList.next()) { + if (mSearchAName->isChecked()) { +#if QT_VERSION >= 300 + if (re.search(a->name()) != -1) +#else + if (re.match(a->name()) != -1) +#endif + { + mMatchedEvents.append(ev); + break; + } + } + if (mSearchAEmail->isChecked()) { +#if QT_VERSION >= 300 + if (re.search(a->email()) != -1) +#else + if (re.match(a->email()) != -1) +#endif + { + mMatchedEvents.append(ev); + break; + } + } + } + } + } + } + QPtrList<Todo> todos = mCalendar->todos( ); + mMatchedTodos.clear(); + if ( mSearchTodo->isChecked() ) { + Todo *tod; + for(tod=todos.first();tod;tod=todos.next()) { + if (mSummaryCheck->isChecked()) { +#if QT_VERSION >= 300 + if (re.search(tod->summary()) != -1) +#else + if (re.match(tod->summary()) != -1) +#endif + { + mMatchedTodos.append(tod); + continue; + } + } + if (mDescriptionCheck->isChecked()) { +#if QT_VERSION >= 300 + if (re.search(tod->description()) != -1) +#else + if (re.match(tod->description()) != -1) +#endif + { + mMatchedTodos.append(tod); + continue; + } + } + if (mCategoryCheck->isChecked()) { +#if QT_VERSION >= 300 + if (re.search(tod->categoriesStr()) != -1) +#else + if (re.match(tod->categoriesStr()) != -1) +#endif + { + mMatchedTodos.append(tod); + continue; + } + } + if ( mSearchAName->isChecked() || mSearchAEmail->isChecked() ) { + QPtrList<Attendee> tmpAList = tod->attendees(); + Attendee *a; + for (a = tmpAList.first(); a; a = tmpAList.next()) { + if (mSearchAName->isChecked()) { +#if QT_VERSION >= 300 + if (re.search(a->name()) != -1) +#else + if (re.match(a->name()) != -1) +#endif + { + mMatchedTodos.append(tod); + break; + } + } + if (mSearchAEmail->isChecked()) { +#if QT_VERSION >= 300 + if (re.search(a->email()) != -1) +#else + if (re.match(a->email()) != -1) +#endif + { + mMatchedTodos.append(tod); + break; + } + } + } + } + } + } + mMatchedJournals.clear(); + if (mSearchJournal->isChecked() ) { + QPtrList<Journal> journals = mCalendar->journals( ); + Journal* journ; + + for(journ=journals.first();journ;journ=journals.next()) { + if ( journ->dtStart().date() <= mEndDate->date() + &&journ->dtStart().date() >= mStartDate->date()) { +#if QT_VERSION >= 300 + if (re.search(journ->description()) != -1) +#else + if (re.match(journ->description()) != -1) +#endif + { + mMatchedJournals.append(journ); + continue; + } + } + } + } + +} +void SearchDialog::keyPressEvent ( QKeyEvent *e) +{ + + e->ignore(); + +} +//mMatchedJournals; diff --git a/korganizer/searchdialog.h b/korganizer/searchdialog.h new file mode 100644 index 0000000..a03c586 --- a/dev/null +++ b/korganizer/searchdialog.h @@ -0,0 +1,93 @@ +/* + This file is part of KOrganizer. + Copyright (c) 1998 Preston Brown + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ +#ifndef SEARCHDIALOG_H +#define SEARCHDIALOG_H + +#include <qregexp.h> + +#include <kdialogbase.h> + +#include <libkcal/calendar.h> + +#include "kolistview.h" + +class KDateEdit; +class QCheckBox; +class QLineEdit; +class QLabel; +class CalendarView; + +using namespace KCal; + +class SearchDialog : public KDialogBase +{ + Q_OBJECT + public: + SearchDialog(Calendar *calendar,CalendarView *parent=0); + virtual ~SearchDialog(); + KOListView *listview(){ return listView;} + void updateView(); + + public slots: + void changeEventDisplay(Event *, int) { updateView(); } + void updateConfig(); + void updateList(); + protected slots: + void accept(); + void doSearch(); + void searchTextChanged( const QString &_text ); + + signals: + void showEventSignal(Event *); + void editEventSignal(Event *); + void deleteEventSignal(Event *); + + private: + void search(const QRegExp &); + + Calendar *mCalendar; + + QPtrList<Event> mMatchedEvents; + QPtrList<Todo> mMatchedTodos; + QPtrList<Journal> mMatchedJournals; + + QLabel *searchLabel; + QLineEdit *searchEdit; + KOListView *listView; + + KDateEdit *mStartDate; + KDateEdit *mEndDate; + // QCheckBox *mInclusiveCheck; + QCheckBox *mSummaryCheck; + QCheckBox *mDescriptionCheck; + QCheckBox *mCategoryCheck; + QCheckBox *mSearchEvent; + QCheckBox *mSearchTodo; + QCheckBox *mSearchJournal; + QCheckBox *mSearchAName; + QCheckBox *mSearchAEmail; + void keyPressEvent ( QKeyEvent *e) ; +}; + +#endif diff --git a/korganizer/searchdialog.moc b/korganizer/searchdialog.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/searchdialog.moc diff --git a/korganizer/simplealarmclient.cpp b/korganizer/simplealarmclient.cpp new file mode 100644 index 0000000..4882a27 --- a/dev/null +++ b/korganizer/simplealarmclient.cpp @@ -0,0 +1,111 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2002,2003 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. +*/ + +#include "simplealarmclient.h" + +#include <kprocess.h> +#include <kdebug.h> +#include <kstandarddirs.h> + +#include <qfile.h> +#include <qtextstream.h> + +SimpleAlarmClient::SimpleAlarmClient() + : mProcess( 0 ) +{ + //mCalendarsFile = locateLocal( "data", "simplealarmdaemon/calendars" ); + + +} + +SimpleAlarmClient::~SimpleAlarmClient() +{ + delete mProcess; +} + +void SimpleAlarmClient::startDaemon() +{ + + qDebug("SimpleAlarmClient::startDaemon() "); + if ( !mProcess ) { + mProcess = new KProcess; + *mProcess << "simplealarmdaemon"; + if ( !mProcess->start() ) { + kdDebug() << "Failed to start process." << endl; + } + } +} + +bool SimpleAlarmClient::setCalendars( const QStringList &calendars ) +{ + + + QFile f( mCalendarsFile ); + if ( !f.open( IO_WriteOnly ) ) { + kdDebug() << "Unable to open file '" << mCalendarsFile << "'" << endl; + return false; + } + QTextStream ts( &f ); + QStringList::ConstIterator it; + for ( it = calendars.begin(); it != calendars.end(); ++it ) { + kdDebug() << "CAL: " << *it << endl; + ts << *it << "\n"; + } + f.close(); + + return true; +} + +bool SimpleAlarmClient::addCalendar( const QString &calendar ) +{ + QFile f( mCalendarsFile ); + if ( !f.open( IO_WriteOnly | IO_Append ) ) return false; + QTextStream ts( &f ); + ts << calendar << "\n"; + f.close(); + + return true; +} + +bool SimpleAlarmClient::removeCalendar( const QString &calendar ) +{ + QStringList calendars; + + QFile f( mCalendarsFile ); + if ( !f.open( IO_ReadOnly ) ) return false; + QTextStream ts( &f ); + bool found = false; + QString line; + while ( !( line = ts.readLine() ).isNull() ) { + if ( line != calendar ) calendars.append( line ); + else found = true; + } + + if ( found ) return setCalendars( calendars ); + else return true; +} + +bool SimpleAlarmClient::reloadCalendar( const QString & ) +{ + return true; +} diff --git a/korganizer/simplealarmclient.h b/korganizer/simplealarmclient.h new file mode 100644 index 0000000..6ad8d52 --- a/dev/null +++ b/korganizer/simplealarmclient.h @@ -0,0 +1,57 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2002 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 SIMPLEALARMCLIENT_H +#define SIMPLEALARMCLIENT_H + +#include "alarmclient.h" + +class KProcess; + +/** + This class implements the client interface for the SimpleAlarmDaemon. +*/ +class SimpleAlarmClient : public AlarmClient +{ + public: + SimpleAlarmClient(); + virtual ~SimpleAlarmClient(); + + /** + Start alarm daemon. + */ + void startDaemon(); + + bool setCalendars( const QStringList & ); + + bool addCalendar( const QString & ); + + bool removeCalendar( const QString & ); + + bool reloadCalendar( const QString & ); + + private: + QString mCalendarsFile; + KProcess *mProcess; +}; + +#endif diff --git a/korganizer/statusdialog.cpp b/korganizer/statusdialog.cpp new file mode 100644 index 0000000..78efeb0 --- a/dev/null +++ b/korganizer/statusdialog.cpp @@ -0,0 +1,67 @@ +/* + 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. +*/ + +#include <qlabel.h> +#include <qpushbutton.h> +#include <qstringlist.h> +#include <qlayout.h> + +#include <kdebug.h> +#include <klocale.h> + +#include "statusdialog.h" +#include "statusdialog.moc" + +StatusDialog::StatusDialog(QWidget* parent, const char* name) : + KDialog(parent,name,true) +{ + setCaption(i18n("Set Your Status")); + + QBoxLayout *topLayout = new QVBoxLayout( this ); + topLayout->setSpacing( spacingHint() ); + topLayout->setMargin( marginHint() ); + + QBoxLayout *statusLayout = new QHBoxLayout( topLayout ); + + QLabel *text = new QLabel(i18n("Set your status"),this); + statusLayout->addWidget( text ); + + mStatus = new QComboBox(false,this); + mStatus->insertStringList(Attendee::statusList()); + statusLayout->addWidget( mStatus ); + + QBoxLayout *buttonLayout = new QHBoxLayout( topLayout ); + + QPushButton *ok = new QPushButton(i18n("&OK"), this); + connect ( ok,SIGNAL(clicked()), this,SLOT(accept()) ); + buttonLayout->addWidget( ok ); + + QPushButton *cancel = new QPushButton(i18n("&Cancel"), this); + connect ( cancel,SIGNAL(clicked()), this,SLOT(reject()) ); + buttonLayout->addWidget( cancel ); +} + +StatusDialog::~StatusDialog() +{ +} + +Attendee::PartStat StatusDialog::status() +{ + return Attendee::PartStat( mStatus->currentItem() ) ; +} diff --git a/korganizer/statusdialog.h b/korganizer/statusdialog.h new file mode 100644 index 0000000..be6b5e8 --- a/dev/null +++ b/korganizer/statusdialog.h @@ -0,0 +1,43 @@ +/* + 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. +*/ +#ifndef STATUSDIALOG_H +#define STATUSDIALOG_H + +#include <qcombobox.h> + +#include <kdialog.h> + +#include <libkcal/attendee.h> + +using namespace KCal; + +class StatusDialog : public KDialog +{ + Q_OBJECT + public: + StatusDialog(QWidget* parent=0,const char* name=0); + ~StatusDialog(); + + Attendee::PartStat status(); + + private: + QComboBox *mStatus; +}; + +#endif diff --git a/korganizer/statusdialog.moc b/korganizer/statusdialog.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/statusdialog.moc diff --git a/korganizer/timeline.cpp b/korganizer/timeline.cpp new file mode 100644 index 0000000..6f9c8dd --- a/dev/null +++ b/korganizer/timeline.cpp @@ -0,0 +1,63 @@ +#include <qpainter.h> + +#include <kdebug.h> + +#include "timeline.h" +#include "timeline.moc" + +TimeLine::TimeLine( QWidget *parent, const char *name ) : + QScrollView( parent, name ) +{ + mPixelWidth = 1000; + + resizeContents( mPixelWidth, 20 ); + + viewport()->setBackgroundMode( PaletteBackground ); + + setHScrollBarMode(AlwaysOff); + setVScrollBarMode(AlwaysOff); +} + +TimeLine::~TimeLine() +{ +} + +void TimeLine::drawContents(QPainter* p, int cx, int cy, int cw, int ch) +{ + int spacingX = mDaySpacing; + int offsetX = mDayOffset; + + // Draw vertical lines of grid +// kdDebug() << "drawContents cx: " << cx << " cy: " << cy << " cw: " << cw << " ch: " << ch << endl; + int cell = int( (cx - ( spacingX - offsetX ) ) / spacingX ); + int x = cell * spacingX + ( spacingX - offsetX ); +// kdDebug() << " x: " << x << endl; + while (x < cx + cw) { +// kdDebug() << " x: " << x << endl; + p->drawLine(x,cy,x,cy+ch); + p->drawText( x + 5, 15, QString::number( mStartDate.addDays( cell + 1 ).date().day() ) ); + + x += spacingX; + cell++; + } +} + +void TimeLine::setDateRange( const QDateTime &start, const QDateTime &end ) +{ + mStartDate = start; + mEndDate = end; + + mSecsPerPixel = mStartDate.secsTo( mEndDate ) / mPixelWidth; + + mDaySpacing = 60 * 60 * 24 / mSecsPerPixel; + + mDayOffset = QDateTime( mStartDate.date() ).secsTo( mStartDate ) / mSecsPerPixel; + + kdDebug() << "TimeLines::setDateRange(): mDaySpacing: " << mDaySpacing << " mDayOffset: " + << mDayOffset << " mSecsPerPixel: " << mSecsPerPixel << endl; +} + +void TimeLine::setContentsPos( int pos ) +{ + QScrollView::setContentsPos ( pos, 0 ); +} diff --git a/korganizer/timeline.h b/korganizer/timeline.h new file mode 100644 index 0000000..ab3e5d3 --- a/dev/null +++ b/korganizer/timeline.h @@ -0,0 +1,33 @@ +#ifndef TIMELINE_H +#define TIMELINE_H + +#include <qscrollview.h> +#include <qdatetime.h> + +class TimeLine : public QScrollView +{ + Q_OBJECT + public: + TimeLine( QWidget *parent = 0, const char *name = 0 ); + virtual ~TimeLine(); + + void setDateRange( const QDateTime &start, const QDateTime &end ); + + public slots: + void setContentsPos( int pos ); + + protected: + void drawContents(QPainter* p, int cx, int cy, int cw, int ch); + + private: + QDateTime mStartDate; + QDateTime mEndDate; + + int mPixelWidth; + int mDaySpacing; + int mDayOffset; + int mSecsPerPixel; +}; + +#endif + diff --git a/korganizer/timeline.moc b/korganizer/timeline.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/timeline.moc diff --git a/korganizer/timespanview.cpp b/korganizer/timespanview.cpp new file mode 100644 index 0000000..f8314e7 --- a/dev/null +++ b/korganizer/timespanview.cpp @@ -0,0 +1,158 @@ + +#ifndef DESKTOP_VERSION +#include <qksplitter.h> +#else +#include <qsplitter.h> +#endif +#include <qlistview.h> +#include <qlayout.h> +#include <qheader.h> +#include <qpushbutton.h> + +#include <klocale.h> +#include <kdebug.h> + +#include "lineview.h" +#include "timeline.h" + +#include "timespanview.h" +#include "timespanview.moc" + + +TimeSpanView::TimeSpanView( QWidget *parent, const char *name ) : + QWidget( parent, name ) +{ + QBoxLayout *topLayout = new QVBoxLayout( this ); +#ifndef DESKTOP_VERSION + mSplitter = new QKSplitter( this ); +#else + mSplitter = new QSplitter( this ); +#endif + topLayout->addWidget( mSplitter ); + + mList = new QListView( mSplitter ); + mList->addColumn( i18n("Summary") ); + + QWidget *rightPane = new QWidget( mSplitter ); + QBoxLayout *rightPaneLayout = new QVBoxLayout( rightPane ); + + mTimeLine = new TimeLine( rightPane ); + mTimeLine->setFixedHeight( mList->header()->height() ); + rightPaneLayout->addWidget( mTimeLine ); + + mLineView = new LineView( rightPane ); + rightPaneLayout->addWidget( mLineView ); + + QBoxLayout *buttonLayout = new QHBoxLayout( rightPaneLayout ); + + QPushButton *zoomInButton = new QPushButton( i18n("Zoom In"), rightPane ); + connect( zoomInButton, SIGNAL( clicked() ), SLOT( zoomIn() ) ); + buttonLayout->addWidget( zoomInButton ); + + QPushButton *zoomOutButton = new QPushButton( i18n("Zoom Out"), rightPane ); + connect( zoomOutButton, SIGNAL( clicked() ), SLOT( zoomOut() ) ); + buttonLayout->addWidget( zoomOutButton ); + + QPushButton *centerButton = new QPushButton( i18n("Center View"), rightPane ); + connect( centerButton, SIGNAL( clicked() ), SLOT( centerView() ) ); + buttonLayout->addWidget( centerButton ); + + connect(mLineView->horizontalScrollBar(),SIGNAL(valueChanged(int)), + mTimeLine,SLOT(setContentsPos(int))); +} + +TimeSpanView::~TimeSpanView() +{ +} + +QValueList<int> TimeSpanView::splitterSizes() +{ + return mSplitter->sizes(); +} + +void TimeSpanView::setSplitterSizes( QValueList<int> sizes ) +{ + mSplitter->setSizes( sizes ); +} + +void TimeSpanView::addItem( KCal::Event *event ) +{ + new QListViewItem( mList, event->summary() ); + + QDateTime startDt = event->dtStart(); + QDateTime endDt = event->dtEnd(); + +// kdDebug() << "TimeSpanView::addItem(): start: " << startDt.toString() +// << " end: " << endDt.toString() << endl; + + int startSecs = mStartDate.secsTo( startDt ); + int durationSecs = startDt.secsTo( endDt ); + +// kdDebug() << "--- startSecs: " << startSecs << " dur: " << durationSecs << endl; + + int startX = mStartDate.secsTo( startDt ) / mSecsPerPixel; + int endX = startX + startDt.secsTo( endDt ) / mSecsPerPixel; + +// kdDebug() << "TimeSpanView::addItem(): s: " << startX << " e: " << endX << endl; + + mLineView->addLine( startX, endX ); +} + +void TimeSpanView::clear() +{ + mList->clear(); + mLineView->clear(); +} + +void TimeSpanView::updateView() +{ +#if QT_VERSION >= 300 + mLineView->updateContents(); + mTimeLine->updateContents(); +#else +#endif +} + +void TimeSpanView::setDateRange( const QDateTime &start, const QDateTime &end ) +{ + mStartDate = start; + mEndDate = end; + + mTimeLine->setDateRange( start, end ); + + mSecsPerPixel = mStartDate.secsTo( mEndDate ) / mLineView->pixelWidth(); +} + +QDateTime TimeSpanView::startDateTime() +{ + return mStartDate; +} + +QDateTime TimeSpanView::endDateTime() +{ + return mEndDate; +} + +void TimeSpanView::zoomIn() +{ + int span = mStartDate.daysTo( mEndDate ); + setDateRange( mStartDate.addDays( span / 4 ), mEndDate.addDays( span / -4 ) ); + + emit dateRangeChanged(); +} + +void TimeSpanView::zoomOut() +{ + int span = mStartDate.daysTo( mEndDate ); + setDateRange( mStartDate.addDays( span / -4 ), mEndDate.addDays( span / 4 ) ); + + emit dateRangeChanged(); +} + +void TimeSpanView::centerView() +{ + QScrollBar *scrollBar = mLineView->horizontalScrollBar(); + int min = scrollBar->minValue(); + int max = scrollBar->maxValue(); + scrollBar->setValue( min + (max-min) / 2 ); +} diff --git a/korganizer/timespanview.h b/korganizer/timespanview.h new file mode 100644 index 0000000..34cb1f7 --- a/dev/null +++ b/korganizer/timespanview.h @@ -0,0 +1,60 @@ +#ifndef TIMESPANVIEW_H +#define TIMESPANVIEW_H + +#include <qwidget.h> + +#include <libkcal/event.h> + +//class QSplitter; +#ifndef DESKTOP_VERSION +class QKSplitter; +#else +class QSplitter; +#define QKSplitter QSplitter +#endif +class QListView; +class LineView; +class TimeLine; + + +class TimeSpanView : public QWidget +{ + Q_OBJECT + public: + TimeSpanView( QWidget *parent=0, const char *name=0 ); + virtual ~TimeSpanView(); + + void addItem( KCal::Event * ); + + QValueList<int> splitterSizes(); + void setSplitterSizes( QValueList<int> ); + + void clear(); + + void setDateRange( const QDateTime &start, const QDateTime &end ); + + QDateTime startDateTime(); + QDateTime endDateTime(); + + public slots: + void updateView(); + + void zoomIn(); + void zoomOut(); + void centerView(); + + signals: + void dateRangeChanged(); + + private: + QKSplitter *mSplitter; + QListView *mList; + TimeLine *mTimeLine; + LineView *mLineView; + + QDateTime mStartDate; + QDateTime mEndDate; + int mSecsPerPixel; +}; + +#endif diff --git a/korganizer/timespanview.moc b/korganizer/timespanview.moc new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/korganizer/timespanview.moc diff --git a/korganizer/version.h b/korganizer/version.h new file mode 100644 index 0000000..2f47c90 --- a/dev/null +++ b/korganizer/version.h @@ -0,0 +1,29 @@ +#ifndef KORG_VERSION_H +#define KORG_VERSION_H + +/* + Version scheme: "x.y.z build". + + "x.y.z" follow the kdelibs version KOrganizer is released with. + + If "z" is 0, it the version is "x.y" + + "build" is empty for final versions. For developer version "build" is + something like "alpha1", "alpha2", "beta1", "beta2", "rc1", "rc2". + + Examples in chronological order: + + 3.0 + 3.0.1 + 3.1 alpha1 + 3.1 beta1 + 3.1 beta2 + 3.1 rc1 + 3.1 + 3.1.1 + 3.2 alpha1 +*/ + +static const char *korgVersion = "3.1"; + +#endif diff --git a/korganizer/wordsgerman.h b/korganizer/wordsgerman.h new file mode 100644 index 0000000..4b53ecb --- a/dev/null +++ b/korganizer/wordsgerman.h @@ -0,0 +1,840 @@ +{ "10 minutes","10 Minuten", }, +{ "10th","10." }, +{ "11th","11." }, +{ "12 pm Format","12 AM/PM Format" }, +{ "12th","12." }, +{ "13th","13." }, +{ "14th","14." }, +{ "15th","15." }, +{ "16th","16." }, +{ "17th","17." }, +{ "18th","18." }, +{ "19th","19." }, +{ "1 Day","1 Tag" }, +{ "1 h","1 Std" }, +{ "1 (high)","1 (hoch)" }, +{ "5 (low)","5" }, +{ "1st","1." }, +{ "20th","20." }, +{ "21st","21." }, +{ "22nd","22." }, +{ "23rd","23." }, +{ "24:00 Hour Format","24:00 Stunden Format" }, +{ "24th","24." }, +{ "25th","25." }, +{ "26th","26." }, +{ "27th","27." }, +{ "28th","28." }, +{ "29th","29." }, +{ "2nd","2." }, +{ "30 minutes","30 Minuten" }, +{ "30th","30." }, +{ "31st","31." }, +{ "3rd","3." }, +{ "4th","4." }, +{ "5 (lowest)","5 (Niedrigster)" }, +{ "5th","5." }, +{ "6th","6." }, +{ "7th","7." }, +{ "8th","8." }, +{ "9th","9." }, +{ "About...","�ber..." }, +{ "&Accept","&Akzeptieren" }, +{ "Accept","Akzeptieren" }, +{ "Accept A&ll","A&lles Akzepieren" }, +{ "Access:","Zugriff:" }, +{ "A corresponding event is missing in your calendar!","Ein zugeh�riger Termin fehlt in ihrem Kalender!" }, +{ "Actions","Aktionen" }, +{ "Add Filter","Filter Hinzuf�gen" }, +{ "&Add","Hinzuf�gen" }, +{ "Add","Hinzuf�gen" }, +{ "Additional email addresses:","Zus�tzliche E-Mail Adressen:" }, +{ "Additional email address:","Zus�tzliche E-Mail Adresse:" }, +{ "&Addressbook","&Adressbuch" }, +{ "Address &Book...","Adress&buch..." }, +{ "Agenda Size","Agende Gr��e" }, +{ "Agenda Size:","Gr��e der Agenda:" }, +{ "Agenda view:","Agenda Ansicht:" }, +{ "Agenda view background color:","Hintergrund der Agenda Ansicht:" }, +{ "All attendees","Alle Teilnehmer" }, +{ "AllDayAgenda Height:","H�he Ganztages Agenda:" }, +{ "Allday","Ganzt�gig" }, +{ "Anonymous","Anonym" }, +{ "Apply","Anwenden" }, +{ "Apr","Apr" }, +{ "April","April" }, +{"Ask for every entry on conflict","Frage bei Konflikten nach"}, +{ "Ask for preferences before syncing","Vor dem Syncronisieren nachfragen" }, +{ "Ask for quit when closing KO/Pi","Vor dem Beenden von KO/Pi nachfragen" }, +{ "Attendees","Teilnehmer" }, +{ "Aug","Aug" }, +{ "August","August" }, +{ "Auto-Save","Automatisches Abspeichern" }, +{ "Auto save delay in minutes:","Verz�g.autom.Speichern in Min" }, +{ "Auto saving...","Automatische Sicherung..." }, +{ "Begin on:","Starte mit:" }, +{ "Begins on: %1","Starte mit: %1" }, +{ "<b>From:</b> %1 <b>To:</b> %2","<b>Vom:</b> %1 <b>Zum:</b> %2" }, +{ "Bigger","Gr��er" }, +{ "Biggest","Riesig" }, +{ "Big","Gro�" }, +{ "<b>On:</b> %1","<b>Am:</b> %1" }, +{ "<b>On:</b> %1 <b>From:S</b> %2 <b>To:</b> %3","<b>Am:</b> %1 <b>Vom:S</b> %2 <b>Zum:</b> %3" }, +{ "<b>Original event:</b><p>","<b>Original Termin:</b><p>" }, +{ " - both are modified after last sync"," - beide wurden nach der letzten Syncronisation ver�ndert" }, +{ "Busy","Belegt" }, +{ "&Cancel","Abbre&chen" }, +{ "Cancel","Abbrechen" }, +{ "Cannot delete To-Do\nwhich has children.","Kann Todo nicht l�schen,\n da noch Eintr�ge vorhanden sind" }, +{ "Cannot delete To-Do which has children.","Kann Todo nicht l�schen, da noch Eintr�ge vorhanden sind" }, +{ "Can't generate mail:\nNo event selected.","Kann e-Mail nicht erstellen:\nKein Termin ausgew�hlt." }, +{ "Categories...","Kategorien..." }, +{ "Categories","Kategorien" }, +{ "Category","Kategorie" }, +{ "Center View","Zentriere Ansicht" }, +{ "Change","�ndere" }, +{ "Cinema","Kino" }, +{ "Click to add a new Todo","Hier klicken, um ein neues Todo anzulegen" }, +{ "Clone Item","Klone Eintrag" }, +{ "&Close","S&chlie�en" }, +{ "Close","Schlie�en" }, +{ "Close this dialog to abort deletion!","Zum Abbrechen des L�schvorganges Dialog schlie�en!" }, +{ "Colors","Farben" }, +{ "completed","erledigt" }, +{ "completed on %1","erledigt am %1" }, +{ "Complete","Erledigt" }, +{ "Confidential","Vertraulich" }, +{ "Configure...","Einstellungen..." }, +{ "Confirm &deletes","L�schvogang best�tigen" }, +{ "Couldn't load calendar\n '%1'.","Kann Kalender\n '%1' nicht laden." }, +{ "Counter-event Viewer","Terminz�hler Ansicht" }, +{ "Daily ending hour:","Feierabend:" }, +{ "Daily starting hour:","Anfangszeit:" }, +{ "Daily","T�glich" }, +{ "Date Format","Datums Format" }, +{ "Date Format:","Datums Format:" }, +{ "DateNavigator:(nr)","Datums Navigator" }, +{ "Dates: ","Datum: " }, +{ "Date && Time","Datum && Zeit" }, +{ "Day begins at:","Der Tag beginnt um:" }, +{ "Days in Next-X-Days:","Tage in N�chste-X-Tage:" }, +{ "Days in What's Next:","Tage in What's Next:" }, +{ "day(s)","Tag(e)" }, +{ "Days to show in Next-X-Days view:","Welche Tage in N�chste-X-Tagen anzeigen:" }, +{ "day","Tag" }, +{ "Dec","Dez" }, +{ "December","Dezember" }, +{ "Default alarm time:","Standard Alarmzeit:" }, +{ "Default appointment time:","Standard Termin Startzeit:" }, +{ "Default event color:","Standard Terminfarbe:" }, +{ "Default","Standard" }, +{ "Def. duration of new app.:","Standard Termin L�nge:" }, +{ "Delete all completed To-Dos?","Alle bereits erledigten Todos l�schen?" }, +{ "Delete All","L�sche alles" }, +{ "Delete all selected","L�sche alle Selektierten" }, +{ "Delete Current","Aktuellen l�schen" }, +{ "Delete Event...","L�sche Termin..." }, +{ "Delete Event","L�sche Termin" }, +{ "&Delete","L�schen" }, +{ "Delete...","L�schen..." }, +{ "Delete","L�schen" }, +{ "Delete Todo...","L�sche Todo..." }, +{ "Delete To-Do","L�sche Todo" }, +{ "Deleting item %d ...","L�sche Eintrag %d..." }, +{ "Descriptions","Beschreibungen" }, +{ "Deselect All","Deselektiere Alle" }, +{ "Details","Details" }, +{ "Dinner","Abendessen" }, +{ "Do you really want\nto close KO/Pi?","M�chten Sie wirklich\nKO/PI verlassen?" }, +{ "Due Date","F�llig am" }, +{ "Due: ","F�llig: "}, +{ "Due Time","F�llig um" }, +{ "Due:","F�llig:"}, +{ "Duration: ","Dauer: " }, +{ "Edit...","Bearbeite..." }, +{ "Edit","Bearbeite" }, +{ "Edit Event...","Bearbeite Termin..." }, +{ "Edit Event","Bearbeite Termin" }, +{ "Edit exceptions","Bearbeite Ausnahmen" }, +{ "EditorBox:","Editor Fenster:" }, +{ "Edit Recurrence Range","Bearbeite Wiederholung" }, +{ "Edit Todo...","Berabeite Todo..." }, +{ "Edit To-Do","Todo bearbeiten" }, +{ "E&mail address:","E&mail Adresse:" }, +{ "(EmptyEmail)","(KeineEmail)" }, +{ "(EmptyName)","(KeinName)" }, +{ "Enable Recurrence","Wiederholender Termin" }, +{ "End after","Endet nach"}, +{ "End by:","Endet am"}, +{ "End Date","End Datum" }, +{ "End:","Ende:" }, +{ "End Time","End Zeit" }, +{ "English","Englisch" }, +{ "Event","Termin" }, +{ "Event list","Termin Liste" }, +{ "Events","Termine" }, +{ "Event Viewer:","Termin �bersicht:" }, +{ "every","jede" }, +{ "Exceptions...","Ausnahmen..." }, +{ "Exceptions","Ausnahmen" }, +{ "Exclude holidays","Ohne freie Tage" }, +{ "Exclude Saturdays","Ohne Samstage" }, +{ "Feb","Feb" }, +{ "February","Februar" }, +{ "&Find","Suche!" }, +{ "Fonts","Schriftart" }, +{ "Force take local entry always","Erzwinge:Nimm immer lokalen Eintrag" }, +{ "Force take remote entry always","Erzwinge:Nimm immer fernen Eintrag"}, +{ "Free","Frei" }, +{ "Friday","Freitag" }, +{ "Fri","Fr" }, +{ "From:","Vom:" }, +{ "Full &name:","Vor- und &Nachname:" }, +{ "General","Allgemein" }, +{ "German","Deutsch" }, +{ "Gifts","Geschenke" }, +{ "Go to Today","Heute anzeigen" }, +{ "Help","Hilfe" }, +{ "Hide Dates","Daten ausblenden" }, +{ "Highlight color:","Markierungen:" }, +{ "Holiday color:","Freie Tage:" }, +{ "hour(s)","Stunde(n)" }, +{ "In %1 days: ","In %1 Tagen: " }, +{ "Incomplete Todo:","Unerledigte Aufgaben:" }, +{ "Information","Information" }, +{ "Invalid search expression,\ncannot perform ","Kann Suche nicht ausf�hren" }, +{ "Jan","Jan" }, +{ "January","Januar" }, +{ "JournalView:","Journal Ansicht:" }, +{ "Journals","Journale" }, +{ "Jul","Jul" }, +{ "July","Juli" }, +{ "Jump to date","Springe zum Datum" }, +{ "June","Juni" }, +{ "Jun","Jun" }, +{ "Key Bindings...","Tastenzuordnung..." }, +{ "Kids","Kinder" }, +{ "Known Problems...","Bekannte Probleme..." }, +{ "KO/Pi Find ","KO/Pi Suchdialog " }, +{ "KO/Pi Find: ","KO/Pi Suchen: " }, +{ "KO/Pi is starting ... "," KO/Pi startet ... \n... Zeit f�r eine Kaffeepause ..." }, +{ "Language:(needs restart)","Sprache (Neustart!)" }, +{ "Language:","Sprache" }, +{ "Large","Etwas mehr" }, +{ "List View:","Listenansicht:" }, +{ "List View","Listenansicht" }, +{ "Load/Save","Laden/Speichern" }, +{ "Load Template","Lade Vorlage" }, +{ "Locale","Localisation" }, +{ "Local temp file:","Lokale temp. Datei:" }, +{ "Location: ","Ort: " }, +{ "Location:","Ort:" }, +{ "Mail client","Mail Programm" }, +{ "Mail Client","Mail Programm" }, +{ "March","M�rz" }, +{ "Mar","M�r" }, +{ "May","Mai" }, +{ "M. Bains line:","M. Bains Linie:" }, +{ "Medium","Medium" }, +{ "Method","Methode" }, +{ "minute(s)","Minute(n)" }, +{ "Monday","Montag" }, +{ "Mon","Mo" }, +{ "Monthly","Monatlich" }, +{ "Month not long enough","Monat ist nicht lang genug" }, +{ "month(s)","Monat(e)" }, +{ "Month view:","Monatsansicht:" }, +{ "Month view uses category colors","Monatsansicht zeigt Kategorie Farben" }, +{ "Todo view uses category colors","To-Do Ansicht zeigt Kategorie Farben" }, +{ "Move &Down","Nach unten verschieben" }, +{ "Move &Up","Nach oben verschieben" }, +{ "Name:","Name:" }, +{ "Name","Name" }, +{ "\nAre you sure you want\nto delete this event?","\nSind Sie sicher, dass Sie\nden Termin l�schen m�chten?" }, +{ "%n Days","%n Tage" }, +{ "Never","Nie" }, +{ "New event...","Neuer Termin..." }, +{ "New event","Neuer Termin" }, +{ "New Event...","Neuer Termin..." }, +{ "New Events/Todos should","Neue Termine/Todos sollten" }, +{ "&New","&Neu" }, +{ "New","Neu", }, +{ "New Sub-Todo...","Neues Sub-Todo..." }, +{ "New Todo...","Neues Todo..." }, +{ "Next Alarm: ","N�chster Alarm: ", }, +{ "&Next Day","&N�chster Tag", }, +{ "Next days view uses full window","N�chste-X-Tage nutzt Vollbild" }, +{ "Next month","N�chster Monat" }, +{ "&Next Week","&N�chste Woche" }, +{ "Next year","N�chstes Jahr" }, +{ "Next Year","N�chstes Jahr" }, +{ "%n h","%n Std" }, +{ "No ending date","Kein End-Datum", }, +{ "No event, nothing to do.","Kein Termin, nichts zu tun.", }, +{ "No event selected.","Kein Termin selektiert" }, +{ "No","Nein" }, +{ "No program set","Kein Programm ausgew�hlt", }, +{ "Normal","Normal" }, +{ "[No selection]","Keine Selektion", }, +{ "No sound set","Kein Sound ausgew�hlt", }, +{ "no time ","keine Zeit ", }, +{ "no time","keine Zeit", }, +{ "No Time","Keine Zeit" }, +{ "November","November" }, +{ "Nov","Nov", }, +{ "\nThis event recurs\nover multiple dates.\n","\nDieser Termin wiederholt sich an mehreren Tagen.\n" }, +{ "occurrence(s)","Vorkommen" }, +{ "October","Oktober" }, +{ "Oct","Okt", }, +{ "O-due!","�-f�llig! " }, +{ "&OK","&OK" }, +{ "Ok+Show!","Ok+Anzeigen" }, +{ "Organizer: %1","Organisator %1" }, +{ "Organizer","Organisator" }, +{ "Owner: ","Besitzer: " }, +{ "Owner:","Besitzer:" }, +{ "<p><b>Priority:</b> %2</p>","<p><b>Priorit�t:</b> %2</p>" }, +{ "Pick a date to display","W�hle einen Tag zum anzeigen aus" }, +{ "Please specify a valid due date.","Bitte g�ltiges F�lligkeitsdatum angeben."}, +{ "Please specify a valid end date, for example '%1'.","Bitte g�ltiges Enddatum angeben, z.B.'%1'." }, +{ "Please specify a valid start date.","Bitte g�ltiges Startdatum angeben." }, +{ "Please specify a valid start date, for example '%1'.","Bitte g�ltiges Startdatum angeben, z.B. '%1'." }, +{ "Please specify a valid start time.","Bitte g�ltige Startzeit angeben."}, +{ "Please specify a valid start time, for example '%1'.","Bitte g�ltige Startzeit angeben, z.B. '%1'." }, +{ "Preferences - some settings need a restart (nr)","Einstellungen - teilweise Neustart erforderlich (bn)" }, +{ "&Previous Day","Vorheriger Tag" }, +{ "Previous month","Vorheriger Monat" }, +{ "Previous Month","Vorheriger Monat" }, +{ "&Previous Week","Vorherige Woche" }, +{ "Previous year","Vorheriges Jahr" }, +{ "Previous Year","Vorheriges Jahr" }, +{ "Printing","Drucken" }, +{ "Priority:","Priorit�t:" }, +{ "Private","Privat" }, +{ "Proceed","Weiter" }, +{ "Public","�ffentlich" }, +{ "Purge","Entferne" }, +{ "Purge Completed","Entferne erledigte ToDos" }, +{ "Purge To-Dos","Todos bereinigen" }, +{ "read-only","schreibgesch�tzt" }, +{ "Recur every","Wiederh. alle" }, +{ "Recur in the month of","Wiederh. im Monat" }, +{ "Recur on the","Wiederh. am" }, +{ "Recur on this day","Wiederh. am diesen Tag" }, +{ "Recurrence Range...","Wiederholungs Zeitraum..." }, +{ "Recurrence Range","Wiederholungs Zeitraum" }, +{ "Recurrence Rule","Wiederholungs Regel" }, +{ "Recurrence","Wiederholung" }, +{ "Recurs","Wiederholung" }, +{"&Reject","Abweisen"}, +{ "Reminder:","Alarm:" }, +{ "Rem.:","Alarm:" }, +{ "Rem.","Alarm:" }, +{ "Remote file:","Remote Datei:"}, +{ "Remote IP:","Remote (ferne) IP:" }, +{ "Remote syncing (via ssh/scp) network settings ","Remote Sync (via ssh/scp) Netzwerk Einstellungen " }, +{ "Remote user:","Remote Benutzer"}, +{ "&Remove","Entfe&rnen" }, +{ "Remove","Entfernen" }, +{ "Request response","Bemerkung anfordern" }, +{ "Role:","Rolle:" }, +{ "Role","Rolle" }, +{ "Sat","Sa" }, +{ "Saturday","Samstag" }, +{ "Search for:","Suche nach:" }, +{ "Search In","Suche in" }, +{ "Search...","Suche..." }, +{ "Search","Suche" }, +{ "Select Addresses","W�hle Adressen" }, +{ "Select all","Selektiere Alle" }, +{ "Select a month","W�hle Monat" }, +{ "Select a week","W�hle Woche" }, +{ "Select a year","W�hle Jahr" }, +{ "Send directly","Sende direkt" }, +{ "&Send Messages","&Sende Nachrichten", }, +{ "Sep","Sep" }, +{ "September","September" }, +{ "Shopping","Einkaufen" }, +{ "Use short date in (WN/E) view","Kurzdatum in (WN/Termin) Ansicht" }, +{ "Show Dates","Zeige Daten" }, +{ "Show events that recur daily in date nav.","Zeige t�gl.wiederh.Term.in Datums Nav." }, +{ "Show Event...","Zeige Termin..." }, +{ "Show ev. that recur weekly in date nav.","Zeige w�ch.wiederh.Term.in Datums Nav." }, +{ "Show Marcus Bains line","Zeige Marcus Bains Linie" }, +{ "Show summary after syncing","Zeige Zusammenfassung nach Sync." }, +{ "Show time as:","Zeige Zeit als" }, +{ "Show Todo...","Zeige To-Do" }, +{ "Show topmost todo prios in What's N.:","Anz. h�chster Prios in What's N.:"}, +{ "Show topmost todo prios in What's Next:","Anz. h�chster Prios in What's Next:"}, +{ "Show vertical screen (Needs restart)","Vertikaler Bildschirm-Layout (Neustart!)" }, +{ "&Show","Zeige" }, +{ "Show...","Zeige..." }, +{ "Show","Zeige" }, +{ "Small","Klein" }, +{ "Sorry","Entschuldigung" }, +{"Sorry, the copy command failed!\nCommand was:\n","Der Kopierbefehl schlug fehl!\nBefehl war:\n"}, +{ "Start:","Start:" }, +{ "Start Date","Start Datum" }, +{ "Start date: %1","Start Datum: %1" }, +{ "Start Time","Start Zeit" }, +{ "Status:","Status:" }, +{ "Status","Status:" }, +{ "Summaries","Titel" }, +{ "Summary:","Titel:" }, +{ "Summary","Titel" }, +{ "Sunday","Sonntag" }, +{ "Sun","So" }, +{ "Sync preferences:","Sync Einstellungen" }, +{ "Sync Prefs","Sync Einstellungen" }, +{ "Syncronize","Daten abgleich" }, +{ "Take local entry on conflict","Nimm lokalen Eintrag beim Konflikt" }, +{ "Take newest entry on conflict","Nimm neuesten Eintrag beim Konflikt" }, +{ "Take remote entry on conflict","Nimm fernen Eintrag beim Konflikt" }, +{ "Template '%1' does not contain a valid Todo.","Template '%1' enth�lt kein g�ltiges To-Do" }, +{ "Template does not contain a valid Event.","Template '%1' enth�lt keinen g�ltigen Termin" }, +{ "Template...","Vorlage..." }, +{ "This day","Dieser Tag" }, +{ "This is an experimental feature. ","Dieses Feature ist experimentel" }, +{ "This item will be\npermanently deleted.","Dieser Eintrag wird\nkomplett gel�scht." }, +{ "This item will be permanently deleted.", "Dieser Eintrag wird komplett gel�scht." }, +{ "Thu","Do" }, +{ "Thursday","Donnerstag" }, +{ "Time associated","Mit Zeit" }, +{ "Time bar:","Uhrzeit Zeile:" }, +{ "Time && Date","Zeit und Datum" }, +{ "Time Format","Zeit Format" }, +{ "Time Format(nr):","Zeit Format(Neustart!)" }, +{ "Date Labels:","Datumsleiste:" }, +{ "Time: ","Zeit: " }, +{ "Timezone:","Zeitzone:" }, +{ "Tiny","Sehr klein" }, +{ "To: ","Bis: " }, +{ "To:","Bis:" }, +{ "Today: ","Heute: " }, +{ "Todo due today color:","Heute f�llige To-Do's" }, +{ "To-do items:","To-Do items:" }, +{ "Todo overdue color:","�berf�llige To-Do's" }, +{ "Todo","Todo" }, +{ "To-do view shows completed Todos","To-do Ansicht zeigt erledigte To-dos" }, +{ "ToDoView:","Todo Ansicht:" }, +{ "Toggle Alarm","Wechsle Alarm" }, +{ "Toggle Allday","Umschalten Ganztag" }, +{ "Tomorrow: ","Morgen: " }, +{ "Tue","Di" }, +{ "Tuesday","Dienstag" }, +{ "Two entries are in conflict, if: ","Zwei Eintr�ge haben einen Konflikt, wenn:" }, +{ "Unable to find template '%1'.","Kann Vorlage '%1' nicht finden." }, +{ "Unknown","Unbekannt" }, +{ "Up","Hinauf" }, +{ "Use password (if not, ask when syncing)","Passwort: (sonst jedesmal anfragen)" }, +{ "User defined","Benutzerdefiniert" }, +{ "User long date:","Format langes Datum:" }, +{ "User short date:","Forma kurzes Datum:" }, +{ "View","Ansicht" }, +{ "View Fonts","Schriftarten Ansichten" }, +{ "Views","Ansichten" }, +{ "Wed","Mi" }, +{ "Wednesday","Mittwoch" }, +{ "Week %1","Woche %1" }, +{ "Weekly","W�chentlich" }, +{ "Week starts on Sunday","Woche beginnt Sonntags" }, +{ "What's Next View:","What's Next Anz." }, +{ "What's next ?","Was kommt als n�chstes?(What's Next)" }, +{ "Working Hours","T�gliche Arbeitszeit" }, +{ "Working hours color:","Arbeitszeit in der Agenda Ansicht:" }, +{ "Write back existing entries only","Nur exisitierende Eintr�ge zur�ckschreiben" }, +{ "Write back synced file","Syncronisierte Datei zur�ckschreiben" }, +{ "Yearly","J�hrlich" }, +{ "year(s)","Jahr(e)" }, +{ "Yes","Ja" }, +{ "You have %d item(s) selected.\n","Sie haben %d Eintr�ge ausgew�hlt.\n" }, +{ "You have to restart KOrganizer for this setting to take effect.","Sie m�ssem Korganizer neu starten, damit diese Einstellung aktiviert wird." }, +{ "week(s) on:","Woche(n) am: " }, +{ "Full menu bar(nr)","Volle Menuleiste(bn)" }, +{ "Timezone has daylight saving","Zeitzone hat Sommerzeit" }, +{ "Actual start/end is the\nsunday before this date.","Tats�chlicher Beginn/Ende ist der Sonntag\nvor diesem Datum!" }, +{ "The year in the date is ignored.","Das Jahr vom Datum wird ignoriert." }, +{ "Daylight start:","Sommerzeit Beginn:" }, +{ "Daylight end:","Sommerzeit Ende:" }, +{ "Time Zone","Zeitzone" }, +{ "Monday 19 April 2004: %A %d %B %Y","Montag 19 April 2004: %A %d %B %Y" }, +{ "%A: Monday --- %a: Mon","%A: Montag --- %a: Mon" }, +{ "minutely","min�tlich" }, +{ "hourly","st�ndlich" }, +{ "daily","t�glich" }, +{ "weekly","w�chentlich" }, +{ "monthly","monatlich" }, +{ "day-monthly","tag-monatlich" }, +{ "month-yearly","monat-j�hrlich" }, +{ "day-yearly","tag-j�hrlich" }, +{ "position-yearly","pos-j�hrlich" }, +{ "Edit item on doubleclick (if not, show)","Editiere mit Doppelklick(wenn nicht, zeige)" }, +{ "Highlight current day in agenda","Hebe >>heute<< in Agenda hervor" }, +{ "Use light color for highlight current day","Helle Farbe f�r >>heute<< Hervorhebung" }, +{ "Highlight selection in Time Edit","Hebe Auswahl in Zeit Edit hervor" }, +{ "Hold fullscreen on view change","Behalte Vollbild bei Ansichswechsel" }, +{ "Hold non-fullscreen on view change","Behalte Nicht-Vollbild bei Ansichtsw." }, +{ "Event list view uses full window","Listenansicht nutzt Vollbild" }, +{ "Set agenda to DayBeginsAt on change","Setze Agenda auf TagBeginntUm bei Wechsel" }, +{ "Set agenda to current time on change","Setze Agenda auf gegenw.Zeit bei Wechsel" }, +{ "Listview uses monthly timespan","Listenansicht zeigt monatliche Zeitspanne" }, +{ "ViewChange","Ansichtswechsel" }, +{ "Default alarm *.wav file:","Standard Alarm *.wav Datei:" }, +{ "This setting is useless for 5500 user!","Diese Einst. ist nutzlos f�r 5500 Nutzer" }, +{ "File","Datei" }, +{ "Clone...","Dupliziere.." }, +{ "Move...","Bewege..." }, +{ "Beam...","Sende via IR..." }, +{ "&Clone...","Dupliziere.." }, +{ "&Move...","Bewege..." }, +{ "&Beam...","Sende via IR..." }, +{ "Show Completed","Zeige erledigte Todos" }, +{ "Show Quick Todo","Zeige Quick Todo" }, +{ "Unparent Todo","Un-sub Todo" }, +{ "Save selected to file...","Speichere Selektierte..." }, +{ "Add Categ. to selected...","F�ge zu Selekt. Kateg. hinzu..." }, +{ "Set Categ. for selected...","Setze Kateg. f�r Selekt." }, +{ "Beam selected via IR","Sende Selekt. via IR..." }, +{ "Search","Suchen" }, +{ "Date Picker","Datum ausw�hlen" }, +{ "Day View","Tagesansicht" }, +{ "Work Week","Arbeitswoche" }, +{ "Week","Wochenansicht" }, +{ "Month","Monatsansicht" }, +{ "Todo View","Todo Liste" }, +{ "Journal","Journal Ansicht" }, +{ "Next days","N�chste Tage" }, +{ "Print agenda selection...","Drucke Agendaselektion..." }, +{ "Toggle DateNavigator","Navigator umschalten" }, +{ "Toggle FilterView","Filteransicht umschalten" }, +{ "Prev. month","Vorheriger Monat" }, +{ "Go backward","Gehe zur�ck" }, +{ "Go forward","Gehe weiter" }, +{ "Synchronize","Synchronisieren" }, +{ "AgendaSize","Agendagr��e" }, +{ "Import (*.ics/*.vcs) file","Importiere (*.ics/*.vcs) Datei" }, +{ "Import last file","Importiere letzte Datei" }, +{ "Import Opie/Qtopia Cal.","Importiere Opie/Qtopia Kal." }, +{ "Load Calendar Backup","Lade Kalender Backup" }, +{ "Save Calendar Backup","Speichere Kalender Backup" }, +{ "Export VCalendar","Exportiere VCalendar" }, +{ "Manage new categories...","Verwalte neue Kategorien..." }, +{ "Beam complete calendar...","Sende kompletten Kalender via IR" }, +{ "Beam filtered calendar...","Sende gefilterten Kalender via IR" }, +{ "Remote via ssh","�ber Netzwerk via ssh" }, +{ "With local file","Mit lokaler Datei" }, +{ "With last file","Mit letzter Datei" }, +{ "KO/Pi: Ready for beaming","KO/Pi: Bereit zum Senden" }, +{ "KO/Pi:Beaming done","KO/Pi: Senden erfolgt" }, +{ "Save filename","Speichern: Dateinamen w�hlen" }, +{ "File already exists!\nOld file from:\n%1\nOverwrite?\n","Dateiname existiert bereits!\nAlte Datei vom:\n%1\n�berschreiben?\n" }, +{ "KO/Pi: Warning!","KO/Pi: Warnung!" }, +{ "Overwrite!","�berschreibe!" }, +{ "KO/Pi:Saved %1","KO/Pi:Gespeichert %1" }, +{ "All selected items will be\npermanently deleted.\n(Deleting items will take\nsome time on a PDA)\n","Alle selektierten Eintr�ge werden\nunwiederbringlich gel�scht.\n(L�schen kann auf dem\nPDA einige Zeit dauern)\n" }, +{ "KO/Pi Confirmation","KO/Pi Best�tigung" }, +{ "Close dialog to abort deletion!","Schlie�e Dialog um das L�schen abzubrechen!" }, +{ "Deleting item %d ...","L�sche Eintrag %d ..." }, +{ "%d items remaining in list.","%d Eintr�ge sind in der Liste verblieben." }, +{ "Size","Gr��e" }, +{ "Date","Datum" }, +{ "Mime Type","Datei Typ" }, +{ "All Files","Alle Dateien" }, +{ "Files","Dateien" }, +{ "Documents","DoKumente" }, +{ "Select Categories","Selektiere Kategorien" }, +{ " &Deselect All "," Auswahl aufheben " }, +{ "A&dd","Hinzu" }, +{ "&Modify","�ndern" }, +{ "Edit Categories","Editiere Kategorien" }, +{ " &Edit Categories "," &Editiere Kategorien " }, +{ "Beam Options","Beam Einstellungen" }, +{ " With timezone "," Mit Zeitzone " }, +{ " Local time ", " Lokale Zeit " }, +{ "Manage new Categories","Verwalte neue Kategorien" }, +{ "Add to category list","F�ge zur Kategorieliste hinzu" }, +{ "Remove from Events/Todos","Entferne von Terminen/Todos" }, +{ "After importing/loading/syncing\nthere may be new categories in\nevents or todos\nwhich are not in the category list.\nPlease choose what to do:\n ","Nach dem Importieren/Laden/Syncen\nkann es neue Kategorien in den \nTerminen oder Todos geben, die nicht\nin der Kategorieliste enthalten sind.\nBitte w�hlen Sie, was passieren soll:\n " }, +{ "New categories not in list:","Kategorien, die nicht in der Liste sind:" }, +{ "File format","Datei Format" }, +{ "Time format","Zeit Format" }, +{ "Delete all\ncompleted To-Dos?","L�sche alle\nerledigten To-Dos?" }, +{ "KO/Pi:Saving Data to File ...","KO/Pi: Speichere Kalender in Datei ..." }, +{ "KO/Pi:File Saved. Needed %d sec, %d ms","KO/Pi: Abgespeichert in %d sec, %d ms" }, +{ "h","Std" }, +{ "min","Min" }, +{ "hou","Std" }, +{ "day","Tag" }, +{ "French(nyi)","Franz�sich (noch nicht implementiert)" }, +{ "Time","Zeit" }, +{ "Event Viewer","Termin Ansicht" }, +{ "Cancel Sync","Sync Abbrechen" }, +{ "Remote","Fern" }, +{ "Local","Lokal" }, +{ "Conflict! Please choose entry","Konflikt! Bitte Eintrag w�hlen" }, +{ "Local: ","Lokal: " }, +{ "Remote: ","Fern: " }, +{ "Last modified: ","Zuletzt ge�ndert: " }, +{ "Location: ","Ort: " }, +{ "<p><b>From:</b> %1 </p><p><b>To:</b> %2</p>","<p><b>Von:</b> %1 </p><p><b>Bis:</b> %2</p>" }, +{ "<p><b>On:</b> %1</p>","<p><b>Am:</b> %1</p>" }, +{ "<p><b>From:</b> %1</p> ","<p><b>Von:</b> %1</p> " }, +{ "<p><b>To:</b> %1</p>","<p><b>Bis:</b> %1</p>" }, +{ "<p><b>On:</b> %1</p> ","<p><b>Am:</b> %1</p> " }, +{ "<p><b>From:</b> %1 <b>To:</b> %2</p>","<p><b>Von:</b> %1 <b>Bis:</b> %2</p>" }, +{ "This is a %1 recurring event.","Das ist ein %1 wiederholender Termin." }, +{ "<b>Next recurrence is on:</b>","<b>N�chste Wiederholung ist am:</b>" }, +{ "<b>Last recurrence was on:</b>","<b>Letzte Wiederholung war am:</b>" }, +{ "( %1 min before )","( %1 min vorher )" }, +{ "<b>Alarm on: ","<b>Alarm am: " }, +{ "<b>Details: </b>","<b>Details: </b>" }, +{ "<p><b>Priority:</b> %2</p>","<p><b>Priorit�t:</b> %2</p>" }, +{ "<p><i>%1 % completed</i></p>","<p><i>%1 % erledigt</i></p>" }, +{ "Organizer","Organisator" }, +{ "Save","Speichern" }, +{ "Exit (+save)","Beenden (+ speichern)" }, +{ "Home","Zuhause" }, +{ "Office","B�ro" }, +{ "Libary","B�cherei" }, +{ "Doctor","Arzt" }, +{ "Beach","Strand" }, +{ "Conference room","Konferenzraum" }, +{ "Drive Home","Heimfahrt" }, +{ "Watch TV","Tv gucken" }, +{ "Phone call","Telefonanruf" }, +{ "Pay bill","Rechnung bezahlen" }, +{ "Read book","Buch lesen" }, +{ "Watering plants","Pflanzen giessen" }, +{"Appointment","Verabredung" }, +{"Birthday","Geburtstag" }, +{"Business","Gesch�ft" }, +{"Business Travel","Gesch�ftsreise" }, +{"Cinema","Kino" }, +{"Customer","Kunde" }, +{"Break","Pause" }, +{"Breakfast","Fr�hst�ck" }, +{"Competition","Wettkampf" }, +{"Dinner","Abendessen" }, +{"Education","Erziehung" }, +{"Family","Familie" }, +{"Favorites","Favoriten" }, +{"Festival","Festival" }, +{"Fishing","Angeln" }, +{"Flight","Flug" }, +{"Gifts","Geschenk" }, +{"Holiday","Feiertag" }, +{"Holiday Cards","Ansichtskarten" }, +{"Hot Contacts","Heisse Kontakte" }, +{"Hiking","Wandern" }, +{"Hunting","Jagen" }, +{"Key Customer","Wichtiger Kunde" }, +{"Kids","Kinder" }, +{"Lunch","Mittagessen" }, +{"Meeting","Treffen" }, +{"Miscellaneous","Verschiedenes" }, +{"Partner","Partner" }, +{"Party","Partie" }, +{"Personal","Privat" }, +{"Personal Travel","Privatreise"}, +{"PHB","PHB" }, +{"Phone Calls","Telefonanruf" }, +{"Projects","Projekt" }, +{"Recurring","Wiederholend" }, +{"School","Schule" }, +{"Shopping","Einkaufen" }, +{"Speach","Rede" }, +{"Special Occasion","Spez.Gelegenheit" }, +{"Sports","Sport" }, +{"Talk","Vortrag" }, +{"Travel","Reise" }, +{"TV","TV" }, +{"Germany","Deutschland" }, +{"Sweden","Schweden" }, +{"Forest","Wald" }, +{ "Desert","W�ste" }, +{ "Kitchen","K�che" }, +{ "Lake","See" }, +{"University","Universit�t"}, +{"Vacation","Urlaub" }, +{"VIP","VIP" }, +{ "Import Sharp Calendar","Importiere Sharp Kalender" }, +{ "This todo has been cancelled!","Dieses Todo wurde gecancelt!" }, +{ "This event has been cancelled!","Dieser Termin wurde gecancelt!" }, +{ "Cancelled","Gecancelt" }, +{ "Multiple sync","Mehrfach Sync" }, +{ "Local file","Lokale Datei" }, +{ "Last file","Letzte Datei" }, +{ "Keys + Colors...","Tasten + Farben..." }, +{ "Mini icons in toolbar(nr)","Mini Icons in ToolBar(bn)" }, +{ "Quick load/save (w/o Unicode)","Schnelles Laden/Speichern (o Unicode)" }, +{ "Choose...","W�hle..." }, +{ "Use colors for application:","Setze Farben f�r Programm:" }, +{ "Buttons, menus, etc.:","Kn�pfe, Menu, etc.:" }, +{ "Frames, labels, etc.:","Rahmen, Label, etc.:" }, +{ "Show parent To-Do's in What's Next view","Zeige Ober-Todo in What's Next Anz." }, +{ "Show location in What's Next view","Zeige Ort in What's Next Anz." }, +{ "Show events that recur ","Zeige Termine, die sich wiederholen:" }, +{ "Show in every cell ","Zeige in jeder Zelle " }, +{ "short month","kurzen Monat" }, +{ "icons","Icons" }, +{ "Show Sat/Sun together","Zeige Sam/Son zusammen" }, +{ "Categorie colors are applied to text","Kategorie Farben f�rben Text" }, +{ "Month view uses day colors","Monatsansicht zeigt Tagesfarben" }, +{ "Day color odd months","Tagesfarbe ungerade Monate" }, +{ "Day color even months","Tagesfarbe gerade Monate" }, +{ "Color for Sundays + category \"Holiday\"","Farbe f�r Sonntag + Kateg.\" Feiertag\"" }, +{ "To-do view shows complete as 'xx %'","Zeige Prozent erledigt als 'xx %'" }, +{ "Small To-do view uses smaller font","Kleine To-do Ansicht nutzt kleineren Font" }, +{ "Colors are applied to text","Farben werden auf Text angewendet" }, +{ "Use internal alarm notification","Nutze interne Alarm Benachrichtigung" }, +{ "Note: KO/Pi must be running to notify you about an alarm. Recommended for use on Zaurus: Disable this option and install KO/Pi alarm applet.\n","Achtung: KO/Pi mu� ausgef�hrt werden damit die Benachrichtigung funktioniert. Empfehlung f�r Zaurus: Diese Option nicht w�hlen und KO/Pi Alarm Applet installieren.\n" }, +{ "Play beeps count:","Anzahl der Alarmpiepse: " }, +{ "Beeps interval in sec:","Zeitintervall der Alarmpiepse: " }, +{ "Default suspend time in min:","Standard Supendierungs Zeit: " }, +{ "Auto suspend count:","Anzahl der auto Suspendierungen" }, +{ "Alarm *.wav file for newly created alarm:","Alarm *.wav Datei f�r neu angelegte Alarme:" }, +{ "New profile","Neues Profil" }, +{ "Clone profile","Klone Profil" }, +{ "Delete profile","L�sche Profil" }, +{ "Profile:","Profil:" }, +{ "Include in multiple sync","Beziehe Profil in mehrfach Sync mit ein" }, +{ "Force: Take local entry always","Erzwinge: Nimm immer lokalen Eintrag" }, +{ "Force: Take remote entry always","Erzwinge: Nimm immer fernen Eintrag" }, +{ "Show summary after sync","Zeige Zusammenfassung nach dem Synchronisieren" }, +{ "Write back file","Schreibe Datei zur�ck" }, +{ "Remote file (w down/upload command)","Entfernte Datei (via down/upload Kommando)" }, +{ "Pre sync (download) command:","Bevor Sync (download) Kommando:" }, +{ "Local device name:","Name dieses Ger�tes:" }, +{ "Ask for preferences before sync","Frage nach Synchronisationseinstellungen vor dem Syncen" }, +{ "Sync preferences","Synchronisations Einstellungen" }, +{ "Profile kind","Profil Art" }, +{ "Local file","Lokale Datei" }, +{ "Local file:","Lokale Datei:" }, +{ "Post sync (upload) command:","Nach Sync (upload) Kommando:" }, +{ "Fill in default values for:","Setze Beispiel Werte ein f�r:" }, +{ "Hint: Use $PWD$ for placeholder of password!","Hinweis: Benutze $PWD$ als Platzhalter f�r ein Passwort!" }, +{ "Synchronization Preferences","Einstellungen der Synchronisationsprofile"}, +{ "Device","Ger�t:" }, +{ "Sync with file \n...%1\nfrom:\n%2\n","Sync mit Datei \n...%1\nvom:\n%2\n" }, +{ "Synchronization summary:\n\n %d items added to local\n %d items added to remote\n %d items updated on local\n %d items updated on remote\n %d items deleted on local\n %d items deleted on remote\n","Synchronisations�bersicht:\n\n %d items lokal hinzugef�gt\n %d items entfernt hinzugef�gt\n %d items lokal ge�ndert\n %d items entfernt ge�ndert\n %d items lokal gel�scht\n %d items entfernt gel�scht\n" }, +{ "Synchronization successful","Synchronisation erfolgreich" }, +{ "Sync cancelled or failed. Nothing synced.","Sync abgebrochen oder fehlgeschlagen. Nichts wurde gesynced." }, +{ "Sync file \n...%1\ndoes not exist!\nNothing synced!\n","Sync Datei \n...%1\nexistiert nicht!\nNichts wurde gesynced!\n" }, +{ "Sync filename(*.ics/*.vcs)","Sync Dateiname(*.ics/*.vcs)" }, +{ "Enter password","Passwort eingeben" }, +{ "Do you really want\nto remote sync\nwith profile \n","Wollen Sie wirklich\nmit dem entfernten\nProfil syncen: \n" }, +{ "Copy remote file to local machine...","Kopiere entfernte Datei auf lokalen Rechner..." }, +{ "Sorry, the copy command failed!\nCommand was:\n%1\n \nTry command on console to get more\ndetailed info about the reason.\n","Sorry, das Kopierkommando schlug fehl!\nKommando war:\n%1\n \nVersuche Kommando von Kosole um\nDetails f�r das Fehlschlagen\nzu erfahren.\n" }, +{ "Writing back file result: ","Resultat des Dateizur�ckschreibens: " }, +{ "Syncronization sucessfully completed","Synchronisation erfolgreich abgeschlossen" }, +{ "Edit Calendar Filters","Editiere Kalendar Filter" }, +{ "Enter filter name:","Neuer Filter Name:" }, +{ "Add Filter","Filter hinzuf�gen" }, +{ "Question","Frage" }, +{ "Filter position: ","Filter Position: " }, +{ "Month View","Monatsansicht" }, +{ "This profil cannot be deleted!\n","Dieses Profil kann\nnicht gel�scht werden!" }, +{ "KO/Pi config error","KO/Pi Konfig. Fehler" }, +{ "Local device name undefined!\nPlease define device name!","Name dieses Ger�tes undefiniert!\nBitte Namen angeben!" }, +{ "Multiple profiles with same name!\nPlease use unique profile names!","Mehrere Profile haben denselben Namen!\nBitte unterschiedliche Namen w�hlen!" }, +{ "Access: ","Zugriff: " }, +{ "Needs Action","Aktion notwendig" }, +{ "Accepted","Akzeptiert" }, +{ "Declined","Abgelehnt" }, +{ "Tentative","Vorl�ufig" }, +{ "Delegated","Beauftragt" }, +{ "Completed","Vollst�ndig" }, +{ "In Process","In Bearbeitung" }, +{ "Participant","Teilnehmer" }, +{ "Optional Participant","M�glicher Teilnehmer" }, +{ "Observer","Beobachter" }, +{ "Chair","Vorsitzender" }, +{ "Not supported \non desktop!\n","" }, +{ "Nothing selected!\n\nThis prints the full width of the Agenda view as you see it!\n\nTo determine the vertical range of the printing, please select\na vertical range (with the left mouse button down) in one column. ","Es ist nichts selektiert!\nDieses druckt die volle Breite der Agenda View, so wie man sie sieht.\nUm die verticale Auswahl zum Drucken zu bestimmen,\nbitte einen verticalen Zeitraum (mit gedr�ckter linker Maustaste)\nin einer Spalte ausw�hlen. " }, +{ "Date range: ","Datums Zeitspanne: " }, +{ "Not supported \non PDA!\n","Nicht verf�gbar\nauf dem PDA. " }, +{ "Syncing - close to abort!","Syncing-schlie�e um abzubrechen." }, +{ "Add / remove events","Add./entferne Termine" }, +{ "File does not exist:\n '%1'.","Datei existiert nicht:\n '%1'." }, +{ "Couldn't load calendar\n '%1'.","Kann Kalender nicht laden:\n '%1'." }, +{ "\nThe file on disk has changed!\nFile size: %1 bytes.\nLast modified: %2\nDo you want to:\n\n - Save and overwrite file?\n - Sync with file, then save?\n - Cancel without saving? \n","\nDie gepeicherte Datei wurde ver�ndert!\nDatei Gr�sse: %1 Bytes.\nZuletzt ge�ndert: %2\nM�chten Sie:\n\n - Speichern und die Datei �berschreiben?\n - Mit Datei Synchronisieren, dann speichern?\n - Abbrechen ohne zu speichern? \n" }, +{ "Overwrite","�berschreiben" }, +{ "Sync+save","Syncen+speichern" }, +{ "Default","Standard" }, +{ " Categories added to list! "," Kategorien zur Liste hinzugef�gt! " }, +{ " %d items?"," %d Eintr�ge?" }, +{ "\nThis event recurs\nover multiple dates.\nAre you sure you want\nto delete this event\nand all its recurrences?","\nDieses ist ein\nwiederholender Termin!.\nSind Sie sicher, dass Sie\ndiesen Termin und alle\nWiederholungen l�schen m�chten?" }, +{ " ?\n\nDelete:\n"," ?\n\nL�sche:\n" }, +{ "Current","Aktuelle" }, +{ "\nThis event recurs\nover multiple dates.\nDo you want to delete\nall it's recurrences,\nor only the current one on:\n","\nDieses ist ein\nwiederholender Termin!\nM�chten sie alle Wiederholungen\nl�schen, oder nur die aktuelle am:\n" }, +{ "All","Alle" }, +{ "Data Loss Warning","Datenverlust Warnung" }, +{ "Proceed","Weitermachen" }, +{ "The journal entries can not be\nexported to a vCalendar file.","Die Journal Eintr�ge k�nnen\nnicht in eine vCalendar\nDatei exportiert werden!" }, +{ "Filter disabled ","Filter abgeschaltet" }, +{ "Filter selected: ","Gew�hlter Filter: " }, +{ "Toggle Cancel","Gecancelt �ndern" }, +{ "&Toggle Cancel","Gecancel&t �ndern" }, +{ "Configure Toolbar","Konfiguriere Toolbar" }, +{ "Stretched TB","Gedehnte TB" }, +{ "Import file \n...%1\ndoes not exist!\nNothing imported!\n","Import Datei \n...%1\nexistiert nicht!\nNichts importiert!\n" }, +{ "Import filename(*.ics/*.vcs)","Import Dateiname(*.ics/*.vcs)" }, +{ "When importing a calendar twice\nduplicated events will be ignored!\nYou can create a backup file with\nFile - Save Calendar Backup\nto revert importing","Wenn ein Kalender doppelt importiert\nwird, werden doppelte Eintr�ge ignoriert!\nSie k�nnen eine Backup Datei anlegen unter\nDatei - Speichere Kalender Backup\num den Import r�ckg�ngig machen zu k�nnen.\n" }, +{ "Not supported \non desktop!\n","Nur verf�gbar auf PDA!" }, +{ "Imported file successfully","Datei erfolgreich importiert" }, +{ "Error importing file","Fehler beim Importieren der Datei" }, +{ "Export vcal filename(*.vcs)","Export vcal Dateiname(*.vcs)" }, +{ "Save file\nalready exists!\nOld save file from:\n%1\nOverwrite?\n","Zu speichernde Datei\existiert bereits!\nExist. Datei vom:\n%1\n�berschreiben?\n" }, +{ "Overwrite!","�berschreiben!" }, +{ "Import file \n...%1\nfrom:\n%2\nDuplicated entries\nwill not be imported!\n","Import Datei \n...%1\nvom:\n%2\nDuplizierte Eintr�ge\nwerden nicht importiert!\n" }, +{ "Load backup filename","Lade Backup Dateiname" }, +{ "Backup file\ndoes not exist!\nNothing loaded!","Backup Datei\nexistiert nicht!\nNichts geladen!" }, +{ "KO/Pi:Loaded %1","KO/Pi:Geladen %1" }, +{ "Save backup filename","Speichere Backup Dateiname" }, +{ "Backup file\nalready exists!\nOld backup file from:\n%1\nOverwrite?\n","Backup Datei\nexistiert bereits!\nAlte Backup Datei vom:\n%1\n�berschreiben?\n" }, +{ "KO/Pi:Saved %1","KO/Pi:Gespeichert %1" }, +{ "Details of attendee","Teilnehmerdetails" }, +{ "Work phone:\n","Telefon Arbeit:\n" }, +{ "Work mobile phone:\n","Mobiltelefon Arbeit:\n" }, +{ "Home phone:\n","Telefon privat:\n" }, +{ "Mobile home phone:\n","Mobiltelefon privat:\n" }, +{ "Email:\n","Email:\n" }, +{ "Alarm disabled","Alarm deaktiviert" }, +{ "Audio.Al.: ","Audio Al.: " }, +{ "Proc.Al.: ","Proc.Al.: " }, +{ "No sound set","Kein Sound definiert" }, +{ "*.wav|Wav Files","*.wav|Wav Dateien" }, +{ "No program set","Kein Programm definiert" }, +{ "Running '%1'","Ausf�hren '%1'" }, +{ "Playing '%1'","Abspielen '%1'" }, +{ "Show Sync Events in WN/Agenda view","Zeige Sync Events in WN/Agenda Ansicht" }, +{ "User defined (usertranslation.txt)","Benutzerdefiniert (usertranslation.txt)" }, +{ "Load!","Laden!" }, +{ "Backup file from:\n%1\nLoading backup\nfile will delete\nyour current Data!\n","Backup Datei vom:\n%1\nDas Laden der Backup Datei\nl�scht die aktuellen Daten!\n" }, +{ "KO/Pi Features and hints","KO/Pi Eigenschaften und Tipps" }, +{ "KO/Pi User translation HowTo","KO/Pi Benutzer-�bersetzung HowTo" }, +{ "KO/Pi Synchronization HowTo","KO/Pi Synchronisation HowTo" }, +{ "Features + hints...","Eigenschaften + Tipps..." }, +{ "User translation...","Benutzer �bersetzung..." }, +{ "Sync HowTo...","Synchronisation HowTo..." }, +{ "Print calendar...","Drucke Kalender..." }, +{ "Anniversary","Jahrestag" }, +{ "When importing birthdays twice\nduplicated events will be ignored,\nif the event has not been\nchanged in KO/Pi!\n","Wenn Geburtstage mehrfach importiert\nwerden, werden doppelte Eintr�ge ignoriert\nwenn sie nicht ver�ndert wurden.\n" }, +{ "Import Birthdays (KA/Pi)","Importiere Geburtstage (KA/Pi)" }, +{ "Next recurrence is on: ","N�chste Wiederholung ist am:" }, +{ "<b>Alarm on: </b>","<b>Alarm am: </b>" }, +{ "<b>Access: </b>","<b>Zugriff: </b>" }, +{ "(%1 min before)","(%1 min vorher)" }, +{ "<b>Categories: </b>","<b>Kategorien: </b>" }, +{ "Save Journal/Description...","Speichere Journal/Details..." }, +{ "This saves the text/details of selected\nJournals and Events/Todos\nto a text file.","Das speichert den Text bzw.\ndie Details von selektierten\nJournalen und Events/Todos\nin eine Textdatei." }, +{ "Continue","Weitermachen" }, +{ " birthdays/anniversaries added!"," Geburts-/Jahrestage hinzugef�gt" }, +{ "Attendee:","Teilnehmer:" }, +{ "Click OK to search ->","Klicke zum Suchen auf OK ->" }, +{ "","" }, +{ "","" }, +{ "","" }, +{ "","" }, +{ "","" }, +{ "","" }, |